[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