aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-24 20:03:32 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-24 20:03:32 +0000
commitd6f7e9dccd0fa8a5a15d7478324c0ae229fc5e1e (patch)
tree905485f4efead47bee847b4e8f2a36444d7406f3 /lib/Sema/SemaDecl.cpp
parent8f30105fda579f8e6db339cb88cdec2bef6350bd (diff)
When we're declaring an object or function with linkage, teach name
lookup to skip over names without linkage. This finishes <rdar://problem/6127293>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65386 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp49
1 files changed, 27 insertions, 22 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9ffc680bcb..a728757adb 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1334,10 +1334,29 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
NamedDecl *New;
bool InvalidDecl = false;
+ QualType R = GetTypeForDeclarator(D, S);
+ if (R.isNull()) {
+ InvalidDecl = true;
+ R = Context.IntTy;
+ }
+
// See if this is a redefinition of a variable in the same scope.
if (!D.getCXXScopeSpec().isSet() && !D.getCXXScopeSpec().isInvalid()) {
+ LookupNameKind NameKind = LookupOrdinaryName;
+
+ // If the declaration we're planning to build will be a function
+ // or object with linkage, then look for another declaration with
+ // linkage (C99 6.2.2p4-5 and C++ [basic.link]p6).
+ if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
+ /* Do nothing*/;
+ else if (R->isFunctionType()) {
+ if (CurContext->isFunctionOrMethod())
+ NameKind = LookupRedeclarationWithLinkage;
+ } else if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern)
+ NameKind = LookupRedeclarationWithLinkage;
+
DC = CurContext;
- PrevDecl = LookupName(S, Name, LookupOrdinaryName, true,
+ PrevDecl = LookupName(S, Name, NameKind, true,
D.getDeclSpec().getStorageClassSpec() !=
DeclSpec::SCS_static,
D.getIdentifierLoc());
@@ -1402,17 +1421,11 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef)
PrevDecl = 0;
- QualType R = GetTypeForDeclarator(D, S);
- if (R.isNull()) {
- InvalidDecl = true;
- R = Context.IntTy;
- }
-
bool Redeclaration = false;
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
New = ActOnTypedefDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
InvalidDecl, Redeclaration);
- } else if (R.getTypePtr()->isFunctionType()) {
+ } else if (R->isFunctionType()) {
New = ActOnFunctionDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
IsFunctionDefinition, InvalidDecl,
Redeclaration);
@@ -1561,6 +1574,8 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
// FIXME: PrevDecl could be an OverloadedFunctionDecl, in which
// case we need to check each of the overloaded functions.
+ if (!PrevDecl->hasLinkage())
+ return false;
if (Context.getLangOptions().CPlusPlus) {
// C++ [basic.link]p6:
@@ -1595,13 +1610,6 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
}
}
- // If the declaration we've found has no linkage, ignore it.
- if (VarDecl *VD = dyn_cast<VarDecl>(PrevDecl)) {
- if (!VD->hasGlobalStorage())
- return false;
- } else if (!isa<FunctionDecl>(PrevDecl))
- return false;
-
return true;
}
@@ -1755,9 +1763,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// same scope as the new declaration, this may still be an
// acceptable redeclaration.
if (PrevDecl && !isDeclInScope(PrevDecl, DC, S) &&
- !((NewVD->hasExternalStorage() ||
- (NewVD->isFileVarDecl() &&
- NewVD->getStorageClass() != VarDecl::Static)) &&
+ !(NewVD->hasLinkage() &&
isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
PrevDecl = 0;
@@ -1788,7 +1794,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// declaration into translation unit scope so that all external
// declarations are visible.
if (!getLangOptions().CPlusPlus && CurContext->isFunctionOrMethod() &&
- NewVD->hasExternalStorage())
+ NewVD->hasLinkage())
InjectLocallyScopedExternalDeclaration(NewVD);
return NewVD;
@@ -2006,9 +2012,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// same scope as the new declaration, this may still be an
// acceptable redeclaration.
if (PrevDecl && !isDeclInScope(PrevDecl, DC, S) &&
- (isa<CXXMethodDecl>(NewFD) ||
- NewFD->getStorageClass() == FunctionDecl::Static ||
- !isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
+ !(NewFD->hasLinkage() &&
+ isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
PrevDecl = 0;
// Merge or overload the declaration with an existing declaration of