forked from OSchip/llvm-project
Audit uses of Sema::LookupSingleName for those lookups that are
intended for redeclarations, fixing those that need it. Fixes PR6831. This uncovered an issue where the C++ type-specifier-seq parsing logic would try to perform name lookup on an identifier after it already had a type-specifier, which could also lead to spurious ambiguity errors (as in PR6831, but with a different test case). llvm-svn: 101419
This commit is contained in:
parent
1d3ee607b3
commit
b8eaf2944b
|
@ -1437,6 +1437,11 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
|
|||
|
||||
switch (Tok.getKind()) {
|
||||
case tok::identifier: // foo::bar
|
||||
// If we already have a type specifier, this identifier is not a type.
|
||||
if (DS.getTypeSpecType() != DeclSpec::TST_unspecified ||
|
||||
DS.getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
|
||||
DS.getTypeSpecSign() != DeclSpec::TSS_unspecified)
|
||||
return false;
|
||||
// Check for need to substitute AltiVec keyword tokens.
|
||||
if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
|
||||
break;
|
||||
|
|
|
@ -4937,7 +4937,8 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
|
|||
bool Invalid = D.isInvalidType();
|
||||
IdentifierInfo *II = D.getIdentifier();
|
||||
if (NamedDecl *PrevDecl = LookupSingleName(S, II, D.getIdentifierLoc(),
|
||||
LookupOrdinaryName)) {
|
||||
LookupOrdinaryName,
|
||||
ForRedeclaration)) {
|
||||
// The scope should be freshly made just for us. There is just no way
|
||||
// it contains any previous declaration.
|
||||
assert(!S->isDeclScope(DeclPtrTy::make(PrevDecl)));
|
||||
|
|
|
@ -67,13 +67,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
|
||||
// Check for another declaration kind with the same name.
|
||||
NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
|
||||
LookupOrdinaryName);
|
||||
if (PrevDecl && PrevDecl->isTemplateParameter()) {
|
||||
// Maybe we will complain about the shadowed template parameter.
|
||||
DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
|
||||
// Just pretend that we didn't see the previous declaration.
|
||||
PrevDecl = 0;
|
||||
}
|
||||
LookupOrdinaryName, ForRedeclaration);
|
||||
|
||||
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
|
||||
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
|
||||
|
@ -202,7 +196,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
|
|||
SourceLocation ClassLocation) {
|
||||
// Look for previous declaration of alias name
|
||||
NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
|
||||
LookupOrdinaryName);
|
||||
LookupOrdinaryName, ForRedeclaration);
|
||||
if (ADecl) {
|
||||
if (isa<ObjCCompatibleAliasDecl>(ADecl))
|
||||
Diag(AliasLocation, diag::warn_previous_alias_decl);
|
||||
|
@ -213,14 +207,14 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
|
|||
}
|
||||
// Check for class declaration
|
||||
NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
|
||||
LookupOrdinaryName);
|
||||
LookupOrdinaryName, ForRedeclaration);
|
||||
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
|
||||
QualType T = TDecl->getUnderlyingType();
|
||||
if (T->isObjCInterfaceType()) {
|
||||
if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl()) {
|
||||
ClassName = IDecl->getIdentifier();
|
||||
CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
|
||||
LookupOrdinaryName);
|
||||
LookupOrdinaryName, ForRedeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -547,7 +541,8 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
|
|||
ObjCInterfaceDecl* IDecl = 0;
|
||||
// Check for another declaration kind with the same name.
|
||||
NamedDecl *PrevDecl
|
||||
= LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName);
|
||||
= LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
|
||||
ForRedeclaration);
|
||||
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
|
||||
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
|
@ -1013,7 +1008,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
|
|||
// Check for another declaration kind with the same name.
|
||||
NamedDecl *PrevDecl
|
||||
= LookupSingleName(TUScope, IdentList[i], IdentLocs[i],
|
||||
LookupOrdinaryName);
|
||||
LookupOrdinaryName, ForRedeclaration);
|
||||
if (PrevDecl && PrevDecl->isTemplateParameter()) {
|
||||
// Maybe we will complain about the shadowed template parameter.
|
||||
DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);
|
||||
|
|
|
@ -456,7 +456,8 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
|
|||
|
||||
if (ParamName) {
|
||||
NamedDecl *PrevDecl = LookupSingleName(S, ParamName, ParamNameLoc,
|
||||
LookupTagName);
|
||||
LookupOrdinaryName,
|
||||
ForRedeclaration);
|
||||
if (PrevDecl && PrevDecl->isTemplateParameter())
|
||||
Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
|
||||
PrevDecl);
|
||||
|
@ -578,7 +579,8 @@ Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
|
|||
IdentifierInfo *ParamName = D.getIdentifier();
|
||||
if (ParamName) {
|
||||
NamedDecl *PrevDecl = LookupSingleName(S, ParamName, D.getIdentifierLoc(),
|
||||
LookupTagName);
|
||||
LookupOrdinaryName,
|
||||
ForRedeclaration);
|
||||
if (PrevDecl && PrevDecl->isTemplateParameter())
|
||||
Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
|
||||
PrevDecl);
|
||||
|
|
|
@ -26,3 +26,15 @@ template<class T, T i> struct X2 {
|
|||
// expected-error{{no viable conversion}}
|
||||
}
|
||||
};
|
||||
|
||||
namespace PR6831 {
|
||||
namespace NA { struct S; }
|
||||
namespace NB { struct S; }
|
||||
|
||||
using namespace NA;
|
||||
using namespace NB;
|
||||
|
||||
template <typename S> void foo();
|
||||
template <int S> void bar();
|
||||
template <template<typename> class S> void baz();
|
||||
}
|
||||
|
|
|
@ -107,3 +107,16 @@ public:
|
|||
}
|
||||
virtual void test () = 0; // expected-note{{pure virtual function 'test'}}
|
||||
};
|
||||
|
||||
namespace PR6831 {
|
||||
namespace NA { struct S; }
|
||||
namespace NB { struct S; }
|
||||
|
||||
void f() {
|
||||
using namespace NA;
|
||||
using namespace NB;
|
||||
try {
|
||||
} catch (int S) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue