[cfe-commits] r63737 - in /cfe/trunk: include/clang/Parse/Action.h include/clang/Parse/Parser.h lib/Parse/MinimalAction.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/Parser.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/member-name-lookup.cpp
Douglas Gregor
dgregor at apple.com
Wed Feb 4 09:00:24 PST 2009
Author: dgregor
Date: Wed Feb 4 11:00:24 2009
New Revision: 63737
URL: http://llvm.org/viewvc/llvm-project?rev=63737&view=rev
Log:
Diagnose ambiguities in getTypeName. Fixes http://llvm.org/bugs/show_bug.cgi?id=3475
Modified:
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/MinimalAction.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaCXX/member-name-lookup.cpp
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Wed Feb 4 11:00:24 2009
@@ -135,8 +135,8 @@
/// 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 @@
/// 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.
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Feb 4 11:00:24 2009
@@ -695,7 +695,7 @@
return false;
IdentifierInfo *II = Tok.getIdentifierInfo();
- if (Actions.getTypeName(*II, CurScope))
+ if (Actions.getTypeName(*II, Tok.getLocation(), CurScope))
return true;
return II == Ident_super;
Modified: cfe/trunk/lib/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/MinimalAction.cpp?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/lib/Parse/MinimalAction.cpp Wed Feb 4 11:00:24 2009
@@ -80,8 +80,8 @@
///
/// 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;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Feb 4 11:00:24 2009
@@ -484,8 +484,9 @@
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 @@
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 @@
// 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 @@
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.
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Feb 4 11:00:24 2009
@@ -232,7 +232,8 @@
}
// 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;
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Wed Feb 4 11:00:24 2009
@@ -758,7 +758,7 @@
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);
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Feb 4 11:00:24 2009
@@ -281,8 +281,8 @@
//===--------------------------------------------------------------------===//
// 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);
}
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Feb 4 11:00:24 2009
@@ -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;
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Feb 4 11:00:24 2009
@@ -691,7 +691,7 @@
}
// 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);
Modified: cfe/trunk/test/SemaCXX/member-name-lookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-name-lookup.cpp?rev=63737&r1=63736&r2=63737&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/member-name-lookup.cpp (original)
+++ cfe/trunk/test/SemaCXX/member-name-lookup.cpp Wed Feb 4 11:00:24 2009
@@ -133,13 +133,18 @@
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}}
+};
More information about the cfe-commits
mailing list