aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorMeador Inge <meadori@codesourcery.com>2012-06-16 03:34:49 +0000
committerMeador Inge <meadori@codesourcery.com>2012-06-16 03:34:49 +0000
commitc5613b26a24a33d7450e3d0bf315c6ccc920ce7b (patch)
treefb0bf936909135582b7dfb9ebb4d7300ec0fddf8 /lib/AST/ASTContext.cpp
parent860a319e62b0e256817a458396d191aa91c0787a (diff)
Explicitly build __builtin_va_list.
The target specific __builtin_va_list types are now explicitly built instead of injecting strings into the preprocessor input. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158592 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp233
1 files changed, 225 insertions, 8 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index af2adb5f7b..9ad3a7f2e7 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -229,6 +229,7 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,
SubstTemplateTemplateParmPacks(this_()),
GlobalNestedNameSpecifier(0),
Int128Decl(0), UInt128Decl(0),
+ BuiltinVaListDecl(0),
ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0),
CFConstantStringTypeDecl(0), ObjCInstanceTypeDecl(0),
FILEDecl(0),
@@ -478,8 +479,6 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {
DoubleComplexTy = getComplexType(DoubleTy);
LongDoubleComplexTy = getComplexType(LongDoubleTy);
- BuiltinVaListType = QualType();
-
// Builtin types for 'id', 'Class', and 'SEL'.
InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
@@ -4870,12 +4869,6 @@ void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
S += 'V';
}
-void ASTContext::setBuiltinVaListType(QualType T) {
- assert(BuiltinVaListType.isNull() && "__builtin_va_list type already set!");
-
- BuiltinVaListType = T;
-}
-
TypedefDecl *ASTContext::getObjCIdDecl() const {
if (!ObjCIdDecl) {
QualType T = getObjCObjectType(ObjCBuiltinIdTy, 0, 0);
@@ -4929,6 +4922,230 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const {
return ObjCProtocolClassDecl;
}
+//===----------------------------------------------------------------------===//
+// __builtin_va_list Construction Functions
+//===----------------------------------------------------------------------===//
+
+static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) {
+ // typedef char* __builtin_va_list;
+ QualType CharPtrType = Context->getPointerType(Context->CharTy);
+ TypeSourceInfo *TInfo
+ = Context->getTrivialTypeSourceInfo(CharPtrType);
+
+ TypedefDecl *VaListTypeDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__builtin_va_list"),
+ TInfo);
+ return VaListTypeDecl;
+}
+
+static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) {
+ // typedef void* __builtin_va_list;
+ QualType VoidPtrType = Context->getPointerType(Context->VoidTy);
+ TypeSourceInfo *TInfo
+ = Context->getTrivialTypeSourceInfo(VoidPtrType);
+
+ TypedefDecl *VaListTypeDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__builtin_va_list"),
+ TInfo);
+ return VaListTypeDecl;
+}
+
+static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
+ // typedef struct __va_list_tag {
+ RecordDecl *VaListTagDecl;
+
+ VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
+ Context->getTranslationUnitDecl(),
+ &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl->startDefinition();
+
+ const size_t NumFields = 5;
+ QualType FieldTypes[NumFields];
+ const char *FieldNames[NumFields];
+
+ // unsigned char gpr;
+ FieldTypes[0] = Context->UnsignedCharTy;
+ FieldNames[0] = "gpr";
+
+ // unsigned char fpr;
+ FieldTypes[1] = Context->UnsignedCharTy;
+ FieldNames[1] = "fpr";
+
+ // unsigned short reserved;
+ FieldTypes[2] = Context->UnsignedShortTy;
+ FieldNames[2] = "reserved";
+
+ // void* overflow_arg_area;
+ FieldTypes[3] = Context->getPointerType(Context->VoidTy);
+ FieldNames[3] = "overflow_arg_area";
+
+ // void* reg_save_area;
+ FieldTypes[4] = Context->getPointerType(Context->VoidTy);
+ FieldNames[4] = "reg_save_area";
+
+ // Create fields
+ for (unsigned i = 0; i < NumFields; ++i) {
+ FieldDecl *Field = FieldDecl::Create(*Context, VaListTagDecl,
+ SourceLocation(),
+ SourceLocation(),
+ &Context->Idents.get(FieldNames[i]),
+ FieldTypes[i], /*TInfo=*/0,
+ /*BitWidth=*/0,
+ /*Mutable=*/false,
+ ICIS_NoInit);
+ Field->setAccess(AS_public);
+ VaListTagDecl->addDecl(Field);
+ }
+ VaListTagDecl->completeDefinition();
+ QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+
+ // } __va_list_tag;
+ TypedefDecl *VaListTagTypedefDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__va_list_tag"),
+ Context->getTrivialTypeSourceInfo(VaListTagType));
+ QualType VaListTagTypedefType =
+ Context->getTypedefType(VaListTagTypedefDecl);
+
+ // typedef __va_list_tag __builtin_va_list[1];
+ llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
+ QualType VaListTagArrayType
+ = Context->getConstantArrayType(VaListTagTypedefType,
+ Size, ArrayType::Normal, 0);
+ TypeSourceInfo *TInfo
+ = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
+ TypedefDecl *VaListTypedefDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__builtin_va_list"),
+ TInfo);
+
+ return VaListTypedefDecl;
+}
+
+static TypedefDecl *
+CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
+ // typedef struct __va_list_tag {
+ RecordDecl *VaListTagDecl;
+ VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
+ Context->getTranslationUnitDecl(),
+ &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl->startDefinition();
+
+ const size_t NumFields = 4;
+ QualType FieldTypes[NumFields];
+ const char *FieldNames[NumFields];
+
+ // unsigned gp_offset;
+ FieldTypes[0] = Context->UnsignedIntTy;
+ FieldNames[0] = "gp_offset";
+
+ // unsigned fp_offset;
+ FieldTypes[1] = Context->UnsignedIntTy;
+ FieldNames[1] = "fp_offset";
+
+ // void* overflow_arg_area;
+ FieldTypes[2] = Context->getPointerType(Context->VoidTy);
+ FieldNames[2] = "overflow_arg_area";
+
+ // void* reg_save_area;
+ FieldTypes[3] = Context->getPointerType(Context->VoidTy);
+ FieldNames[3] = "reg_save_area";
+
+ // Create fields
+ for (unsigned i = 0; i < NumFields; ++i) {
+ FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
+ VaListTagDecl,
+ SourceLocation(),
+ SourceLocation(),
+ &Context->Idents.get(FieldNames[i]),
+ FieldTypes[i], /*TInfo=*/0,
+ /*BitWidth=*/0,
+ /*Mutable=*/false,
+ ICIS_NoInit);
+ Field->setAccess(AS_public);
+ VaListTagDecl->addDecl(Field);
+ }
+ VaListTagDecl->completeDefinition();
+ QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+
+ // } __va_list_tag;
+ TypedefDecl *VaListTagTypedefDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__va_list_tag"),
+ Context->getTrivialTypeSourceInfo(VaListTagType));
+ QualType VaListTagTypedefType =
+ Context->getTypedefType(VaListTagTypedefDecl);
+
+ // typedef __va_list_tag __builtin_va_list[1];
+ llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
+ QualType VaListTagArrayType
+ = Context->getConstantArrayType(VaListTagTypedefType,
+ Size, ArrayType::Normal,0);
+ TypeSourceInfo *TInfo
+ = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
+ TypedefDecl *VaListTypedefDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__builtin_va_list"),
+ TInfo);
+
+ return VaListTypedefDecl;
+}
+
+static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {
+ // typedef int __builtin_va_list[4];
+ llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 4);
+ QualType IntArrayType
+ = Context->getConstantArrayType(Context->IntTy,
+ Size, ArrayType::Normal, 0);
+ TypedefDecl *VaListTypedefDecl
+ = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
+ Context->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ &Context->Idents.get("__builtin_va_list"),
+ Context->getTrivialTypeSourceInfo(IntArrayType));
+
+ return VaListTypedefDecl;
+}
+
+static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
+ TargetInfo::BuiltinVaListKind Kind) {
+ switch (Kind) {
+ case TargetInfo::CharPtrBuiltinVaList:
+ return CreateCharPtrBuiltinVaListDecl(Context);
+ case TargetInfo::VoidPtrBuiltinVaList:
+ return CreateVoidPtrBuiltinVaListDecl(Context);
+ case TargetInfo::PowerABIBuiltinVaList:
+ return CreatePowerABIBuiltinVaListDecl(Context);
+ case TargetInfo::X86_64ABIBuiltinVaList:
+ return CreateX86_64ABIBuiltinVaListDecl(Context);
+ case TargetInfo::PNaClABIBuiltinVaList:
+ return CreatePNaClABIBuiltinVaListDecl(Context);
+ }
+
+ llvm_unreachable("Unhandled __builtin_va_list type kind");
+}
+
+TypedefDecl *ASTContext::getBuiltinVaListDecl() const {
+ if (!BuiltinVaListDecl)
+ BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind());
+
+ return BuiltinVaListDecl;
+}
+
void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
assert(ObjCConstantStringType.isNull() &&
"'NSConstantString' type already set!");