From 74a133fa9a11d6ac366c7825681b2d4c5ad31f35 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 18 Dec 2012 04:18:55 +0000 Subject: [PATCH] Merge storage classes even when contexts don't match. 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. llvm-svn: 170406 --- clang/lib/AST/Decl.cpp | 8 ++++++-- clang/lib/Sema/SemaDecl.cpp | 3 +-- clang/test/Index/linkage.c | 8 ++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 4e4bc0e..a2c6da67 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -786,12 +786,16 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) { } if (const VarDecl *Var = dyn_cast(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); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4bccc1c..7f98c33 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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. diff --git a/clang/test/Index/linkage.c b/clang/test/Index/linkage.c index 41a1fbd..ab00659 100644 --- a/clang/test/Index/linkage.c +++ b/clang/test/Index/linkage.c @@ -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 -- 2.7.4