]> granicus.if.org Git - clang/commitdiff
Mangle based on the declaration we're given, not the canonical
authorDouglas Gregor <dgregor@apple.com>
Wed, 28 Oct 2009 16:31:34 +0000 (16:31 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 28 Oct 2009 16:31:34 +0000 (16:31 +0000)
declaration, since attributes that affect mangling may have been added
to subsequent declarations. However, to determine the linkage of the
declaration, we need to look at the canonical declaration. Fixes PR4412.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85400 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Redeclarable.h
lib/CodeGen/Mangle.cpp
test/CodeGen/mangle.c

index 458af1f14423dba485f49e847aaebb88800fc3ca..1e6871ff3b9c5e7d736787e6aaf91f0c538cbfcc 100644 (file)
@@ -88,6 +88,11 @@ public:
     return D;
   }
 
+  /// \brief Returns the most recent (re)declaration of this declaration.
+  const decl_type *getMostRecentDeclaration() const {
+    return getFirstDeclaration()->RedeclLink.getNext();
+  }
+  
   /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
   /// first and only declaration.
   void setPreviousDeclaration(decl_type *PrevDecl) {
index b0015956be2d7a6bb55ad6b7bc999703dde470de..40c11a574435ed3e52c6ab2be5fc051da9d94513 100644 (file)
@@ -115,6 +115,7 @@ namespace {
 }
 
 static bool isInCLinkageSpecification(const Decl *D) {
+  D = D->getCanonicalDecl();
   for (const DeclContext *DC = D->getDeclContext();
        !DC->isTranslationUnit(); DC = DC->getParent()) {
     if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
@@ -1362,7 +1363,7 @@ namespace clang {
                                    "Mangling declaration");
     
     CXXNameMangler Mangler(Context, os);
-    if (!Mangler.mangle(cast<NamedDecl>(D->getCanonicalDecl())))
+    if (!Mangler.mangle(D))
       return false;
 
     os.flush();
index 17d74ba71f0c55f55d0319c4eec9df3eb2fdd2e5..6f42f6f6496ccf033c18e6ddc063c201977110d1 100644 (file)
@@ -1,22 +1,20 @@
-// RUN: clang-cc -triple i386-pc-linux-gnu -emit-llvm -o %t %s &&
-// RUN: grep '@_Z2f0i' %t &&
-// RUN: grep '@_Z2f0l' %t &&
+// RUN: clang-cc -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
-// Make sure we mangle overloadable, even in C system headers.
+// CHECK: @"\01foo"
 
+// Make sure we mangle overloadable, even in C system headers.
 # 1 "somesystemheader.h" 1 3 4
+// CHECK: @_Z2f0i
 void __attribute__((__overloadable__)) f0(int a) {}
+// CHECK: @_Z2f0l
 void __attribute__((__overloadable__)) f0(long b) {}
 
-
+// CHECK: @"\01bar"
 
 // These should get merged.
 void foo() __asm__("bar");
 void foo2() __asm__("bar");
 
-// RUN: grep '@"\\01foo"' %t &&
-// RUN: grep '@"\\01bar"' %t
-
 int nux __asm__("foo");
 extern float nux2 __asm__("foo");
 
@@ -52,3 +50,12 @@ void foo6() {
 
 int foo7 __asm__("foo7") __attribute__((used));
 float foo8 __asm__("foo7") = 42;
+
+// PR4412
+int func(void);
+extern int func (void) __asm__ ("FUNC");
+
+// CHECK: @"\01FUNC"
+int func(void) {
+  return 42;
+}