diff options
| author | Logan Chien <tzuhsiang.chien@gmail.com> | 2012-10-10 06:56:20 +0000 |
|---|---|---|
| committer | Logan Chien <tzuhsiang.chien@gmail.com> | 2012-10-10 06:56:20 +0000 |
| commit | 57086ce24895f9a53a3d0eafa32117a6edc4194e (patch) | |
| tree | f89375526e6f599152b608120c60e9b93789337d /clang/lib | |
| parent | 05fee08dfa9821279b2d3f805a6303dcb8d86c03 (diff) | |
| download | bcm5719-llvm-57086ce24895f9a53a3d0eafa32117a6edc4194e.tar.gz bcm5719-llvm-57086ce24895f9a53a3d0eafa32117a6edc4194e.zip | |
Fix PR 11709: Change the definition of va_list to meet AAPCS requirement
AAPCS ABI Section 7.1.4 [1] specifies that va_list
should be defined as struct __va_list { void *__ap;};
And in C++, it is defined in namespace std.
[1] http://infocenter.arm.com/help/topic
/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
Patch by Weiming Zhao.
llvm-svn: 165609
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 61 | ||||
| -rw-r--r-- | clang/lib/Basic/Targets.cpp | 10 |
2 files changed, 68 insertions, 3 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a90f0733496..874861872a6 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5521,6 +5521,65 @@ static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) { return VaListTypedefDecl; } +static TypedefDecl * +CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { + RecordDecl *VaListDecl; + if (Context->getLangOpts().CPlusPlus) { + // namespace std { struct __va_list { + NamespaceDecl *NS; + NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context), + Context->getTranslationUnitDecl(), + /*Inline*/false, SourceLocation(), + SourceLocation(), &Context->Idents.get("std"), + /*PrevDecl*/0); + + VaListDecl = CXXRecordDecl::Create(*Context, TTK_Struct, + Context->getTranslationUnitDecl(), + SourceLocation(), SourceLocation(), + &Context->Idents.get("__va_list")); + + VaListDecl->setDeclContext(NS); + + } else { + // struct __va_list { + VaListDecl = CreateRecordDecl(*Context, TTK_Struct, + Context->getTranslationUnitDecl(), + &Context->Idents.get("__va_list")); + } + + VaListDecl->startDefinition(); + + // void * __ap; + FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), + VaListDecl, + SourceLocation(), + SourceLocation(), + &Context->Idents.get("__ap"), + Context->getPointerType(Context->VoidTy), + /*TInfo=*/0, + /*BitWidth=*/0, + /*Mutable=*/false, + ICIS_NoInit); + Field->setAccess(AS_public); + VaListDecl->addDecl(Field); + + // }; + VaListDecl->completeDefinition(); + + // typedef struct __va_list __builtin_va_list; + TypeSourceInfo *TInfo + = Context->getTrivialTypeSourceInfo(Context->getRecordType(VaListDecl)); + + TypedefDecl *VaListTypeDecl + = TypedefDecl::Create(const_cast<ASTContext &>(*Context), + Context->getTranslationUnitDecl(), + SourceLocation(), SourceLocation(), + &Context->Idents.get("__builtin_va_list"), + TInfo); + + return VaListTypeDecl; +} + static TypedefDecl *CreateVaListDecl(const ASTContext *Context, TargetInfo::BuiltinVaListKind Kind) { switch (Kind) { @@ -5534,6 +5593,8 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context, return CreateX86_64ABIBuiltinVaListDecl(Context); case TargetInfo::PNaClABIBuiltinVaList: return CreatePNaClABIBuiltinVaListDecl(Context); + case TargetInfo::AAPCSABIBuiltinVaList: + return CreateAAPCSABIBuiltinVaListDecl(Context); } llvm_unreachable("Unhandled __builtin_va_list type kind"); diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 6469c465747..17f1a615f1e 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -2864,6 +2864,7 @@ class ARMTargetInfo : public TargetInfo { unsigned FPU : 4; + unsigned IsAAPCS : 1; unsigned IsThumb : 1; // Initialized via features. @@ -2874,7 +2875,7 @@ class ARMTargetInfo : public TargetInfo { public: ARMTargetInfo(const std::string &TripleStr) - : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s") + : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s"), IsAAPCS(true) { BigEndian = false; SizeType = UnsignedInt; @@ -2937,6 +2938,8 @@ public: /// gcc. ZeroLengthBitfieldBoundary = 32; + IsAAPCS = false; + if (IsThumb) { // Thumb1 add sp, #imm requires the immediate value be multiple of 4, // so set preferred for small types to 32. @@ -2951,9 +2954,10 @@ public: // FIXME: Override "preferred align" for double and long long. } else if (Name == "aapcs") { + IsAAPCS = true; // FIXME: Enumerated types are variable width in straight AAPCS. } else if (Name == "aapcs-linux") { - ; + IsAAPCS = true; } else return false; @@ -3133,7 +3137,7 @@ public: } virtual bool isCLZForZeroUndef() const { return false; } virtual BuiltinVaListKind getBuiltinVaListKind() const { - return TargetInfo::VoidPtrBuiltinVaList; + return IsAAPCS ? AAPCSABIBuiltinVaList : TargetInfo::VoidPtrBuiltinVaList; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; |

