diff options
author | Meador Inge <meadori@codesourcery.com> | 2012-07-01 15:57:25 +0000 |
---|---|---|
committer | Meador Inge <meadori@codesourcery.com> | 2012-07-01 15:57:25 +0000 |
commit | fb40e3f10ccef93c4f8fb6bd4fe5a108fa6cd369 (patch) | |
tree | c01ff6ec9c70a847d3db47e9554ca152fe8e1ac6 | |
parent | e7e9332a0cd468c477e387a74a53114f1f1c10e6 (diff) |
PR13189: va_list broken with precompiled headers
For some targets a structure named __va_list_tag is built to help define
the __builtin_va_list type. However, __va_list_tag was not being treated as a
predefined type thus causing problems when serializing the AST. This commit
fixes that oversight by adding the necessary support to treat __va_list_tag
as a predefined type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159508 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ASTContext.h | 9 | ||||
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 4 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 14 | ||||
-rw-r--r-- | lib/Serialization/ASTCommon.h | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 3 | ||||
-rw-r--r-- | test/PCH/Inputs/__va_list_tag.h | 5 | ||||
-rw-r--r-- | test/PCH/__va_list_tag.c | 12 |
7 files changed, 48 insertions, 1 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 7c13907bfe..a2177273dd 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -599,6 +599,10 @@ public: mutable QualType AutoDeductTy; // Deduction against 'auto'. mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'. + // Type used to help define __builtin_va_list for some targets. + // The type is built when constructing 'BuiltinVaListDecl'. + mutable QualType VaListTagTy; + ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins, @@ -1185,6 +1189,11 @@ public: return getTypeDeclType(getBuiltinVaListDecl()); } + /// \brief Retrieve the C type declaration corresponding to the predefined + /// __va_list_tag type used to help define the __builtin_va_list type for + /// some targets. + QualType getVaListTagType() const; + /// getCVRQualifiedType - Returns a type with additional const, /// volatile, or restrict qualifiers. QualType getCVRQualifiedType(QualType T, unsigned CVR) const { diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index fbcc5c6cf7..dbe6e5a314 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -640,7 +640,9 @@ namespace clang { /// \brief ARC's unbridged-cast placeholder type. PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34, /// \brief The pseudo-object placeholder type. - PREDEF_TYPE_PSEUDO_OBJECT = 35 + PREDEF_TYPE_PSEUDO_OBJECT = 35, + /// \brief The __va_list_tag placeholder type. + PREDEF_TYPE_VA_LIST_TAG = 36 }; /// \brief The number of predefined type IDs that are reserved for diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 248698f45a..140687f425 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -607,6 +607,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { // half type (OpenCL 6.1.1.1) / ARM NEON __fp16 InitBuiltinType(HalfTy, BuiltinType::Half); + + // Builtin type used to help define __builtin_va_list. + VaListTagTy = QualType(); } DiagnosticsEngine &ASTContext::getDiagnostics() const { @@ -5115,6 +5118,7 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { } VaListTagDecl->completeDefinition(); QualType VaListTagType = Context->getRecordType(VaListTagDecl); + Context->VaListTagTy = VaListTagType; // } __va_list_tag; TypedefDecl *VaListTagTypedefDecl @@ -5188,6 +5192,7 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { } VaListTagDecl->completeDefinition(); QualType VaListTagType = Context->getRecordType(VaListTagDecl); + Context->VaListTagTy = VaListTagType; // } __va_list_tag; TypedefDecl *VaListTagTypedefDecl @@ -5257,6 +5262,15 @@ TypedefDecl *ASTContext::getBuiltinVaListDecl() const { return BuiltinVaListDecl; } +QualType ASTContext::getVaListTagType() const { + // Force the creation of VaListTagTy by building the __builtin_va_list + // declaration. + if (VaListTagTy.isNull()) + (void) getBuiltinVaListDecl(); + + return VaListTagTy; +} + void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) { assert(ObjCConstantStringType.isNull() && "'NSConstantString' type already set!"); diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h index 16db8e3695..eacb39d86e 100644 --- a/lib/Serialization/ASTCommon.h +++ b/lib/Serialization/ASTCommon.h @@ -50,6 +50,8 @@ TypeID MakeTypeID(ASTContext &Context, QualType T, IdxForTypeTy IdxForType) { return TypeIdx(PREDEF_TYPE_AUTO_DEDUCT).asTypeID(FastQuals); if (T == Context.AutoRRefDeductTy) return TypeIdx(PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals); + if (T == Context.VaListTagTy) + return TypeIdx(PREDEF_TYPE_VA_LIST_TAG).asTypeID(FastQuals); return IdxForType(T).asTypeID(FastQuals); } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 8b354f3557..b118685b9b 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -4461,6 +4461,9 @@ QualType ASTReader::GetType(TypeID ID) { T = Context.ARCUnbridgedCastTy; break; + case PREDEF_TYPE_VA_LIST_TAG: + T = Context.getVaListTagType(); + break; } assert(!T.isNull() && "Unknown predefined type"); diff --git a/test/PCH/Inputs/__va_list_tag.h b/test/PCH/Inputs/__va_list_tag.h new file mode 100644 index 0000000000..e3266039a9 --- /dev/null +++ b/test/PCH/Inputs/__va_list_tag.h @@ -0,0 +1,5 @@ +// Header for PCH test __va_list_tag.h + +typedef __builtin_va_list va_list; + +extern int myvfprintf(const char * , va_list); diff --git a/test/PCH/__va_list_tag.c b/test/PCH/__va_list_tag.c new file mode 100644 index 0000000000..23c54ea8fb --- /dev/null +++ b/test/PCH/__va_list_tag.c @@ -0,0 +1,12 @@ +// PR13189 +// rdar://problem/11741429 +// Test this without pch. +// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -include %S/Inputs/__va_list_tag.h %s -emit-llvm -o - + +// Test with pch. +// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -emit-pch -x c-header -o %t %S/Inputs/__va_list_tag.h +// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -include-pch %t %s -verify + +int myvprintf(const char *fmt, va_list args) { + return myvfprintf(fmt, args); +} |