diff options
-rw-r--r-- | include/clang/Parse/Action.h | 8 | ||||
-rw-r--r-- | include/clang/Parse/Parser.h | 2 | ||||
-rw-r--r-- | lib/Parse/MinimalAction.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 12 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 3 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/member-name-lookup.cpp | 9 |
10 files changed, 33 insertions, 25 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index ffbb346380..7d5bf4579e 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -135,8 +135,8 @@ public: /// An optional CXXScopeSpec can be passed to indicate the C++ scope (class or /// namespace) that the identifier must be a member of. /// i.e. for "foo::bar", 'II' will be "bar" and 'SS' will be "foo::". - virtual TypeTy *getTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS = 0) = 0; + virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc, + Scope *S, const CXXScopeSpec *SS = 0) = 0; /// isCurrentClassName - Return true if the specified name is the /// name of the innermost C++ class type currently being defined. @@ -1331,8 +1331,8 @@ public: /// getTypeName - This looks at the IdentifierInfo::FETokenInfo field to /// determine whether the name is a typedef or not in this scope. - virtual TypeTy *getTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS); + virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc, + Scope *S, const CXXScopeSpec *SS); /// isCurrentClassName - Always returns false, because MinimalAction /// does not support C++ classes with constructors. diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index e19100dc10..c34ac3478c 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -695,7 +695,7 @@ private: return false; IdentifierInfo *II = Tok.getIdentifierInfo(); - if (Actions.getTypeName(*II, CurScope)) + if (Actions.getTypeName(*II, Tok.getLocation(), CurScope)) return true; return II == Ident_super; diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp index 6fd5fc0315..2d6c9a6ba5 100644 --- a/lib/Parse/MinimalAction.cpp +++ b/lib/Parse/MinimalAction.cpp @@ -80,8 +80,8 @@ void MinimalAction::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { /// /// FIXME: Use the passed CXXScopeSpec for accurate C++ type checking. Action::TypeTy * -MinimalAction::getTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS) { +MinimalAction::getTypeName(IdentifierInfo &II, SourceLocation Loc, + Scope *S, const CXXScopeSpec *SS) { if (TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>()) if (TI->isTypeName) return TI; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index cc1e9970e9..114f4cb570 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -484,8 +484,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, GetLookAheadToken(2).is(tok::l_paren)) goto DoneWithDeclSpec; - TypeTy *TypeRep = Actions.getTypeName(*NextToken().getIdentifierInfo(), - CurScope, &SS); + Token Next = NextToken(); + TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), + Next.getLocation(), CurScope, &SS); if (TypeRep == 0) goto DoneWithDeclSpec; @@ -538,7 +539,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, goto DoneWithDeclSpec; // It has to be available as a typedef too! - TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), CurScope); + TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), + Tok.getLocation(), CurScope); if (TypeRep == 0) goto DoneWithDeclSpec; @@ -1737,7 +1739,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { // constructor name. else if (Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope)) D.setConstructor(Actions.getTypeName(*Tok.getIdentifierInfo(), - CurScope), + Tok.getLocation(), CurScope), Tok.getLocation()); // This is a normal identifier. else @@ -2191,7 +2193,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc, IdentifierInfo *ParmII = Tok.getIdentifierInfo(); // Reject 'typedef int y; int test(x, y)', but continue parsing. - if (Actions.getTypeName(*ParmII, CurScope)) + if (Actions.getTypeName(*ParmII, Tok.getLocation(), CurScope)) Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII; // Verify that the argument identifier has not already been mentioned. diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 628331fd1d..1fbe32a459 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -232,7 +232,8 @@ Parser::TypeTy *Parser::ParseClassName(const CXXScopeSpec *SS) { } // We have an identifier; check whether it is actually a type. - TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(), CurScope, SS); + TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(), + Tok.getLocation(), CurScope, SS); if (!Type) { Diag(Tok, diag::err_expected_class_name); return 0; diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 8685a599d2..c5c7dd4733 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -758,7 +758,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { if (Tok.is(tok::identifier)) { // Determine whether the identifier is a type name. if (TypeTy *Ty = Actions.getTypeName(*Tok.getIdentifierInfo(), - CurScope, &SS)) { + Tok.getLocation(), CurScope, &SS)) { // This is a typename. Replace the current token in-place with an // annotation type token. Tok.setKind(tok::annot_typename); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 724a57ed42..9810ba0cb5 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -281,8 +281,8 @@ public: //===--------------------------------------------------------------------===// // Symbol table / Decl tracking callbacks: SemaDecl.cpp. // - virtual TypeTy *getTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS); + virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc, + Scope *S, const CXXScopeSpec *SS); virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) { return ActOnDeclarator(S, D, LastInGroup, false); } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 66b72ecad4..fbf4be79eb 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -30,21 +30,21 @@ using namespace clang; -Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS) { +Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, + Scope *S, const CXXScopeSpec *SS) { Decl *IIDecl = 0; LookupResult Result = LookupParsedName(S, SS, &II, LookupOrdinaryName, false); switch (Result.getKind()) { case LookupResult::NotFound: case LookupResult::FoundOverloaded: + return 0; + case LookupResult::AmbiguousBaseSubobjectTypes: case LookupResult::AmbiguousBaseSubobjects: - // FIXME: In the event of an ambiguous lookup, we could visit all of - // the entities found to determine whether they are all types. This - // might provide better diagnostics. case LookupResult::AmbiguousReference: - // FIXME: We need source location of identifier to diagnose more correctly. + DiagnoseAmbiguousLookup(Result, DeclarationName(&II), NameLoc); return 0; + case LookupResult::Found: IIDecl = Result.getAsDecl(); break; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 201d8b3ca8..2175ad3b93 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -691,7 +691,7 @@ Sema::ActOnMemInitializer(DeclTy *ConstructorD, } // It didn't name a member, so see if it names a class. - TypeTy *BaseTy = getTypeName(*MemberOrBase, S, 0/*SS*/); + TypeTy *BaseTy = getTypeName(*MemberOrBase, IdLoc, S, 0/*SS*/); if (!BaseTy) return Diag(IdLoc, diag::err_mem_init_not_member_or_class) << MemberOrBase << SourceRange(IdLoc, RParenLoc); diff --git a/test/SemaCXX/member-name-lookup.cpp b/test/SemaCXX/member-name-lookup.cpp index f48a99add4..9e4b51fd74 100644 --- a/test/SemaCXX/member-name-lookup.cpp +++ b/test/SemaCXX/member-name-lookup.cpp @@ -133,13 +133,18 @@ void G::test_virtual_lookup() { struct HasMemberType1 { - struct type { }; + struct type { }; // expected-note{{member found by ambiguous name lookup}} }; struct HasMemberType2 { - struct type { }; + struct type { }; // expected-note{{member found by ambiguous name lookup}} }; struct HasAnotherMemberType : HasMemberType1, HasMemberType2 { struct type { }; }; + +struct UsesAmbigMemberType : HasMemberType1, HasMemberType2 { + type t; // expected-error{{member 'type' found in multiple base classes of different types}} \ + // expected-error{{expected ';' at end of declaration list}} +}; |