зеркало из https://github.com/microsoft/clang-1.git
Diagnose ambiguities in getTypeName. Fixes http://llvm.org/bugs/show_bug.cgi?id=3475
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63737 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
f680a0fe2d
Коммит
b696ea3a06
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче