summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/Sema.h6
-rw-r--r--clang/lib/Sema/SemaDecl.cpp45
-rw-r--r--clang/test/SemaCXX/using-decl-1.cpp11
3 files changed, 54 insertions, 8 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index a992fb16a25..be5e551579f 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -528,7 +528,7 @@ public:
void DiagnoseFunctionSpecifiers(Declarator& D);
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
- Decl* PrevDecl, bool &Redeclaration);
+ NamedDecl* PrevDecl, bool &Redeclaration);
NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
NamedDecl* PrevDecl,
@@ -725,9 +725,7 @@ public:
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
/// true if 'D' belongs to the given declaration context.
- bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) {
- return IdResolver.isDeclInScope(D, Ctx, Context, S);
- }
+ bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0);
/// Finds the scope corresponding to the given decl context, if it
/// happens to be an enclosing scope. Otherwise return NULL.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8751fb9c9b..d0463c658ea 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -311,9 +311,10 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
IdentifierResolver::iterator
I = IdResolver.begin(TD->getDeclName()),
IEnd = IdResolver.end();
- if (I != IEnd && isDeclInScope(*I, CurContext, S)) {
+ NamedDecl *ID = *I;
+ if (I != IEnd && isDeclInScope(ID, CurContext, S)) {
NamedDecl *PrevDecl = *I;
- for (; I != IEnd && isDeclInScope(*I, CurContext, S);
+ for (; I != IEnd && isDeclInScope(ID, CurContext, S);
PrevDecl = *I, ++I) {
if (TD->declarationReplaces(*I)) {
// This is a redeclaration. Remove it from the chain and
@@ -374,6 +375,41 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
IdResolver.AddDecl(D);
}
+bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S) {
+ if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) {
+ // Look inside the overload set to determine if any of the declarations
+ // are in scope. (Possibly) build a new overload set containing only
+ // those declarations that are in scope.
+ OverloadedFunctionDecl *NewOvl = 0;
+ bool FoundInScope = false;
+ for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
+ FEnd = Ovl->function_end();
+ F != FEnd; ++F) {
+ NamedDecl *FD = F->get();
+ if (!isDeclInScope(FD, Ctx, S)) {
+ if (!NewOvl && F != Ovl->function_begin()) {
+ NewOvl = OverloadedFunctionDecl::Create(Context,
+ F->get()->getDeclContext(),
+ F->get()->getDeclName());
+ D = NewOvl;
+ for (OverloadedFunctionDecl::function_iterator
+ First = Ovl->function_begin();
+ First != F; ++First)
+ NewOvl->addOverload(*First);
+ }
+ } else {
+ FoundInScope = true;
+ if (NewOvl)
+ NewOvl->addOverload(*F);
+ }
+ }
+
+ return FoundInScope;
+ }
+
+ return IdResolver.isDeclInScope(D, Ctx, Context, S);
+}
+
void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
if (S->decl_empty()) return;
assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) &&
@@ -1971,7 +2007,7 @@ void Sema::DiagnoseFunctionSpecifiers(Declarator& D) {
NamedDecl*
Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
- Decl* PrevDecl, bool &Redeclaration) {
+ NamedDecl* PrevDecl, bool &Redeclaration) {
// Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
if (D.getCXXScopeSpec().isSet()) {
Diag(D.getIdentifierLoc(), diag::err_qualified_typedef_declarator)
@@ -4411,7 +4447,8 @@ CreateNewDecl:
if (Lookup.getKind() == LookupResult::Found)
PrevTypedef = dyn_cast<TypedefDecl>(Lookup.getAsDecl());
- if (PrevTypedef && isDeclInScope(PrevTypedef, SearchDC, S) &&
+ NamedDecl *PrevTypedefNamed = PrevTypedef;
+ if (PrevTypedef && isDeclInScope(PrevTypedefNamed, SearchDC, S) &&
Context.getCanonicalType(Context.getTypeDeclType(PrevTypedef)) !=
Context.getCanonicalType(Context.getTypeDeclType(New))) {
Diag(Loc, diag::err_tag_definition_of_typedef)
diff --git a/clang/test/SemaCXX/using-decl-1.cpp b/clang/test/SemaCXX/using-decl-1.cpp
index 2459f251deb..37e101e221e 100644
--- a/clang/test/SemaCXX/using-decl-1.cpp
+++ b/clang/test/SemaCXX/using-decl-1.cpp
@@ -6,3 +6,14 @@ namespace std {
using ::f;
inline void f() { return f(true); }
}
+
+namespace M {
+ void f(float);
+}
+
+namespace N {
+ using M::f;
+ void f(int) { } // expected-note{{previous}}
+
+ void f(int) { } // expected-error{{redefinition}}
+}
OpenPOWER on IntegriCloud