aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-04-25 12:11:36 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-04-25 12:11:36 +0000
commit65dfa2b31794ff4013cb3f9a8178305b56a3d549 (patch)
treef6fc856cbd8fbbeef292a3ee8cc9d4712403f82d /lib/AST
parent2972d049637349bb82f52a27ad3337cf4ab769b4 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180258 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/Decl.cpp17
1 files changed, 10 insertions, 7 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 4a3e8781de..cb375eb4e2 100644
--- a/lib/AST/Decl.cpp
+++ b/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