diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-12-18 04:18:55 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-12-18 04:18:55 +0000 |
| commit | 74a133fa9a11d6ac366c7825681b2d4c5ad31f35 (patch) | |
| tree | e1a3bc649ead73c0f1f87b4a9c9f3c5e1bd18bc1 /clang | |
| parent | 8522ba845f8a824e2142e21ee71b2900c42f929e (diff) | |
| download | bcm5719-llvm-74a133fa9a11d6ac366c7825681b2d4c5ad31f35.tar.gz bcm5719-llvm-74a133fa9a11d6ac366c7825681b2d4c5ad31f35.zip | |
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
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/Decl.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 3 | ||||
| -rw-r--r-- | 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 4e4bc0ec809..a2c6da67f04 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<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); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4bccc1c9870..7f98c3359cf 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 41a1fbdd71c..ab006590b61 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 |

