diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-25 12:11:36 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-25 12:11:36 +0000 |
commit | bff5956cfaf1cb80b5736e5ee550889775ac185d (patch) | |
tree | 13d968857e15b6c7e1739bb7b76da9606c4ce4c7 /clang/lib/AST/Decl.cpp | |
parent | 5c383832052081252a2bb178a08ffefc14698c2b (diff) | |
download | bcm5719-llvm-bff5956cfaf1cb80b5736e5ee550889775ac185d.tar.gz bcm5719-llvm-bff5956cfaf1cb80b5736e5ee550889775ac185d.zip |
Don't mark 'extern "C" void f(void)' as having extern storage class.
Instead, we check for one line extern "C" context in linkage computation and
when deciding if a variable is a definition.
This hopefully completes the transition to having "as written" semantics for
hasExternalStorage.
llvm-svn: 180258
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 4a3e8781dee..cb375eb4e26 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1572,17 +1572,20 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition( // initializer, the declaration is an external definition for the identifier if (hasInit()) return Definition; - // AST for 'extern "C" int foo;' is annotated with 'extern'. + if (hasExternalStorage()) return DeclarationOnly; - if (hasExternalStorage()) { - for (const VarDecl *PrevVar = getPreviousDecl(); - PrevVar; PrevVar = PrevVar->getPreviousDecl()) { - if (PrevVar->getLinkage() == InternalLinkage) - return DeclarationOnly; - } + // [dcl.link] p7: + // A declaration directly contained in a linkage-specification is treated + // as if it contains the extern specifier for the purpose of determining + // the linkage of the declared name and whether it is a definition. + const DeclContext *DC = getDeclContext(); + if (const LinkageSpecDecl *SD = dyn_cast<LinkageSpecDecl>(DC)) { + if (SD->getLanguage() == LinkageSpecDecl::lang_c && !SD->hasBraces()) + return DeclarationOnly; } + // C99 6.9.2p2: // A declaration of an object that has file scope without an initializer, // and without a storage class specifier or the scs 'static', constitutes |