]> granicus.if.org Git - clang/commitdiff
Merge storage classes even when contexts don't match.
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 18 Dec 2012 04:18:55 +0000 (04:18 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 18 Dec 2012 04:18:55 +0000 (04:18 +0000)
This fixes the storage class of extern decls that are merged with file level
statics. The patch also fixes the linkage computation so that they are
considered internal.

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

lib/AST/Decl.cpp
lib/Sema/SemaDecl.cpp
test/Index/linkage.c

index 4e4bc0ec809587fa8734dc5fc9d4b7a402f69773..a2c6da67f04e376ac1fef3bc6395bb418ab4720f 100644 (file)
@@ -786,12 +786,16 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
     }
 
     if (const VarDecl *Var = dyn_cast<VarDecl>(D))
-      if (Var->getStorageClass() == SC_Extern ||
-          Var->getStorageClass() == SC_PrivateExtern) {
+      if (Var->getStorageClassAsWritten() == SC_Extern ||
+          Var->getStorageClassAsWritten() == SC_PrivateExtern) {
         if (Var->isInAnonymousNamespace() &&
             !Var->getDeclContext()->isExternCContext())
           return LinkageInfo::uniqueExternal();
 
+        // This is an "extern int foo;" which got merged with a file static.
+        if (Var->getStorageClass() == SC_Static)
+          return LinkageInfo::internal();
+
         LinkageInfo LV;
         if (Var->getStorageClass() == SC_PrivateExtern)
           LV.mergeVisibility(HiddenVisibility, true);
index 4bccc1c987041f600a68d0df9498cd98145ba1a7..7f98c3359cf7b22baf02d3e480764bfcc5c06b8e 100644 (file)
@@ -2616,8 +2616,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
   // specified at the prior declaration.
   // FIXME. revisit this code.
   if (New->hasExternalStorage() &&
-      Old->getLinkage() == InternalLinkage &&
-      New->getDeclContext() == Old->getDeclContext())
+      Old->getLinkage() == InternalLinkage)
     New->setStorageClass(Old->getStorageClass());
 
   // Merge "used" flag.
index 41a1fbdd71c9d8796dc1327befe85a70bbb4d5a4..ab006590b61c0992694d1b23fdb6bfb2302df6cf 100644 (file)
@@ -13,6 +13,12 @@ static int wibble(int);
 
 void ena(int (*dio)(int tria));
 
+static int test2;
+void f16(void) {
+  extern int test2;
+}
+
+
 // CHECK: EnumDecl=Baz:3:6 (Definition)linkage=External
 // CHECK: EnumConstantDecl=Qux:3:12 (Definition)linkage=External
 // CHECK: VarDecl=x:4:5linkage=External
@@ -28,3 +34,5 @@ void ena(int (*dio)(int tria));
 // CHECK: FunctionDecl=ena:14:6linkage=External
 // CHECK: ParmDecl=dio:14:16 (Definition)linkage=NoLinkage
 // CHECK: ParmDecl=tria:14:25 (Definition)linkage=NoLinkage
+// CHECK: VarDecl=test2{{.*}}linkage=Internal
+// CHECK: VarDecl=test2{{.*}}linkage=Internal