[cfe-commits] r165609 - in /cfe/trunk: include/clang/Basic/TargetInfo.h lib/AST/ASTContext.cpp lib/Basic/Targets.cpp test/CodeGenCXX/mangle-valist.cpp test/Sema/builtins-arm.c
Logan Chien
tzuhsiang.chien at gmail.com
Tue Oct 9 23:56:20 PDT 2012
Author: logan
Date: Wed Oct 10 01:56:20 2012
New Revision: 165609
URL: http://llvm.org/viewvc/llvm-project?rev=165609&view=rev
Log:
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.
Added:
cfe/trunk/test/CodeGenCXX/mangle-valist.cpp
Modified:
cfe/trunk/include/clang/Basic/TargetInfo.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/Basic/Targets.cpp
cfe/trunk/test/Sema/builtins-arm.c
Modified: cfe/trunk/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=165609&r1=165608&r2=165609&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TargetInfo.h (original)
+++ cfe/trunk/include/clang/Basic/TargetInfo.h Wed Oct 10 01:56:20 2012
@@ -151,7 +151,12 @@
/// __builtin_va_list as defined by the x86-64 ABI:
/// http://www.x86-64.org/documentation/abi.pdf
- X86_64ABIBuiltinVaList
+ X86_64ABIBuiltinVaList,
+
+ /// __builtin_va_list as defined by ARM AAPCS ABI
+ /// http://infocenter.arm.com
+ // /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
+ AAPCSABIBuiltinVaList
};
protected:
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=165609&r1=165608&r2=165609&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Oct 10 01:56:20 2012
@@ -5521,6 +5521,65 @@
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 @@
return CreateX86_64ABIBuiltinVaListDecl(Context);
case TargetInfo::PNaClABIBuiltinVaList:
return CreatePNaClABIBuiltinVaListDecl(Context);
+ case TargetInfo::AAPCSABIBuiltinVaList:
+ return CreateAAPCSABIBuiltinVaListDecl(Context);
}
llvm_unreachable("Unhandled __builtin_va_list type kind");
Modified: cfe/trunk/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=165609&r1=165608&r2=165609&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Targets.cpp (original)
+++ cfe/trunk/lib/Basic/Targets.cpp Wed Oct 10 01:56:20 2012
@@ -2864,6 +2864,7 @@
unsigned FPU : 4;
+ unsigned IsAAPCS : 1;
unsigned IsThumb : 1;
// Initialized via features.
@@ -2874,7 +2875,7 @@
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 @@
/// 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 @@
// 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 @@
}
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;
Added: cfe/trunk/test/CodeGenCXX/mangle-valist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-valist.cpp?rev=165609&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-valist.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-valist.cpp Wed Oct 10 01:56:20 2012
@@ -0,0 +1,44 @@
+#include "stdarg.h"
+
+namespace test1 {
+ void test1(const char *fmt, va_list ap) {
+ }
+}
+
+class Test2 {
+public:
+ void test2(const char *fmt, va_list ap);
+};
+
+void Test2::test2(const char *fmt, va_list ap) {
+}
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple armv7-unknown-linux \
+// RUN: | FileCheck -check-prefix=MANGLE-ARM-AAPCS %s
+// CHECK-MANGLE-ARM-AAPCS: @_ZN5test15test1EPKcSt9__va_list
+// CHECK-MANGLE-ARM-AAPCS: @_ZN5Test25test2EPKcSt9__va_list
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple armv7-unknown-linux -target-abi apcs-gnu \
+// RUN: | FileCheck -check-prefix=MANGLE-ARM-APCS %s
+// CHECK-MANGLE-ARM-APCS: @_ZN5test15test1EPKcPv
+// CHECK-MANGLE-ARM-APCS: @_ZN5Test25test2EPKcPv
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple mipsel-unknown-linux \
+// RUN: | FileCheck -check-prefix=MANGLE-MIPSEL %s
+// CHECK-MANGLE-MIPSEL: @_ZN5test15test1EPKcPv
+// CHECK-MANGLE-MIPSEL: @_ZN5Test25test2EPKcPv
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple i686-unknown-linux \
+// RUN: | FileCheck -check-prefix=MANGLE-X86 %s
+// CHECK-MANGLE-X86: @_ZN5test15test1EPKcPc
+// CHECK-MANGLE-X86: @_ZN5Test25test2EPKcPc
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple x86_64-unknown-linux \
+// RUN: | FileCheck -check-prefix=MANGLE-X86-64 %s
+// CHECK-MANGLE-X86-64: @_ZN5test15test1EPKcP13__va_list_tag
+// CHECK-MANGLE-X86-64: @_ZN5Test25test2EPKcP13__va_list_tag
Modified: cfe/trunk/test/Sema/builtins-arm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtins-arm.c?rev=165609&r1=165608&r2=165609&view=diff
==============================================================================
--- cfe/trunk/test/Sema/builtins-arm.c (original)
+++ cfe/trunk/test/Sema/builtins-arm.c Wed Oct 10 01:56:20 2012
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify -DTEST0 %s
// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify -DTEST1 %s
+// RUN: %clang_cc1 -triple armv7 -target-abi apcs-gnu \
+// RUN: -fsyntax-only -verify -DTEST1 %s
#ifdef TEST0
void __clear_cache(char*, char*);
@@ -9,8 +11,24 @@
void __clear_cache(void*, void*);
#endif
-// va_list on ARM is void*.
+#if defined(__ARM_PCS) || defined(__ARM_EABI__)
+// va_list on ARM AAPCS is struct { void* __ap }.
+void test1() {
+ __builtin_va_list ptr;
+ ptr.__ap = "x";
+ *(ptr.__ap) = '0'; // expected-error {{incomplete type 'void' is not assignable}}
+}
+#else
+// va_list on ARM apcs-gnu is void*.
+void test1() {
+ __builtin_va_list ptr;
+ ptr.__ap = "x"; // expected-error {{member reference base type '__builtin_va_list' is not a structure or union}}
+ *(ptr.__ap) = '0';// expected-error {{member reference base type '__builtin_va_list' is not a structure or union}}
+}
+
void test2() {
__builtin_va_list ptr = "x";
*ptr = '0'; // expected-error {{incomplete type 'void' is not assignable}}
}
+
+#endif
More information about the cfe-commits
mailing list