diff options
-rw-r--r-- | lib/AST/Decl.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 43 | ||||
-rw-r--r-- | test/Modules/Inputs/redecl-merge-left.h | 3 | ||||
-rw-r--r-- | test/Modules/Inputs/redecl-merge-right.h | 3 | ||||
-rw-r--r-- | test/Modules/redecl-merge.m | 9 |
6 files changed, 43 insertions, 23 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 31a9b3b292..479f80f1dd 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -938,6 +938,12 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { cast<UsingDecl>(OldD)->getQualifier()); } + // A typedef of an Objective-C class type can replace an Objective-C class + // declaration or definition, and vice versa. + if ((isa<TypedefNameDecl>(this) && isa<ObjCInterfaceDecl>(OldD)) || + (isa<ObjCInterfaceDecl>(this) && isa<TypedefNameDecl>(OldD))) + return true; + // For non-function declarations, if the declarations are of the // same kind then this must be a redeclaration, or semantic analysis // would not have given us the new declaration. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9583ab6327..43c9af58bc 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -8010,8 +8010,6 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // lookup. This is only actually possible in C++, where a few // things like templates still live in the tag namespace. } else { - assert(getLangOptions().CPlusPlus); - // Use a better diagnostic if an elaborated-type-specifier // found the wrong kind of type on the first // (non-redeclaration) lookup. diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 4f53487dcd..f836a077b6 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1177,30 +1177,31 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) { R.addDecl(D); - if ((*I)->getAttr<OverloadableAttr>()) { - // If this declaration has the "overloadable" attribute, we - // might have a set of overloaded functions. - - // Figure out what scope the identifier is in. - while (!(S->getFlags() & Scope::DeclScope) || - !S->isDeclScope(*I)) - S = S->getParent(); - - // Find the last declaration in this scope (with the same - // name, naturally). - IdentifierResolver::iterator LastI = I; - for (++LastI; LastI != IEnd; ++LastI) { - if (!S->isDeclScope(*LastI)) - break; - - D = getVisibleDecl(*LastI); - if (D) - R.addDecl(D); - } + // Check whether there are any other declarations with the same name + // and in the same scope. + + // Figure out what scope the identifier is in. + while (S->getParent() && + (!(S->getFlags() & Scope::DeclScope) || + !S->isDeclScope(*I))) + S = S->getParent(); + + // Find the last declaration in this scope (with the same + // name, naturally). + IdentifierResolver::iterator LastI = I; + for (++LastI; LastI != IEnd; ++LastI) { + if (!S->isDeclScope(*LastI)) + break; + + if (!(*LastI)->isInIdentifierNamespace(IDNS)) + continue; + + D = getVisibleDecl(*LastI); + if (D) + R.addDecl(D); } R.resolveKind(); - return true; } } else { diff --git a/test/Modules/Inputs/redecl-merge-left.h b/test/Modules/Inputs/redecl-merge-left.h index b21271b146..47f3492f30 100644 --- a/test/Modules/Inputs/redecl-merge-left.h +++ b/test/Modules/Inputs/redecl-merge-left.h @@ -56,6 +56,9 @@ struct S4 { struct S3 *produce_S3(void); void consume_S4(struct S4*); +typedef int T1; +typedef float T2; + #ifdef __cplusplus template<typename T> class Vector; diff --git a/test/Modules/Inputs/redecl-merge-right.h b/test/Modules/Inputs/redecl-merge-right.h index 686a96228a..315a9c37ff 100644 --- a/test/Modules/Inputs/redecl-merge-right.h +++ b/test/Modules/Inputs/redecl-merge-right.h @@ -59,6 +59,9 @@ struct S4; void consume_S3(struct S3*); struct S4 *produce_S4(void); +typedef int T1; +typedef double T2; + #ifdef __cplusplus template<typename T> class Vector { public: diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m index c0e83e8a86..44d427c4c7 100644 --- a/test/Modules/redecl-merge.m +++ b/test/Modules/redecl-merge.m @@ -55,6 +55,15 @@ void testTagMerge() { s3.s3_field = 0; } +void testTypedefMerge(int i, double d) { + T1 *ip = &i; + // in other file: expected-note{{candidate found by name lookup is 'T2'}} + // FIXME: Typedefs aren't actually merged in the sense of other merges, because + // we should only merge them when the types are identical. + // in other file: expected-note{{candidate found by name lookup is 'T2'}} + T2 *dp = &d; // expected-error{{reference to 'T2' is ambiguous}} +} + // Test redeclarations of entities in explicit submodules, to make // sure we're maintaining the declaration chains even when normal name // lookup can't see what we're looking for. |