aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMeador Inge <meadori@codesourcery.com>2012-07-01 15:57:25 +0000
committerMeador Inge <meadori@codesourcery.com>2012-07-01 15:57:25 +0000
commitfb40e3f10ccef93c4f8fb6bd4fe5a108fa6cd369 (patch)
treec01ff6ec9c70a847d3db47e9554ca152fe8e1ac6
parente7e9332a0cd468c477e387a74a53114f1f1c10e6 (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.h9
-rw-r--r--include/clang/Serialization/ASTBitCodes.h4
-rw-r--r--lib/AST/ASTContext.cpp14
-rw-r--r--lib/Serialization/ASTCommon.h2
-rw-r--r--lib/Serialization/ASTReader.cpp3
-rw-r--r--test/PCH/Inputs/__va_list_tag.h5
-rw-r--r--test/PCH/__va_list_tag.c12
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);
+}