From: Steve Naroff Date: Thu, 29 Jan 2009 00:07:50 +0000 (+0000) Subject: Refactor Sema::LookupDecl() into 2 functions: LookupDeclInScope() and LookupDeclInCon... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e8ffd2e96e7842245f1ae0cb631eba75da1a6f7;p=clang Refactor Sema::LookupDecl() into 2 functions: LookupDeclInScope() and LookupDeclInContext(). The previous interface was very confusing. This is much more explicit, which will be easier to understand/optimize/convert. The plan is to eventually deprecate both of these functions. For now, I'm focused on performance. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63256 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 9a4ab86871..406eb26450 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -783,8 +783,10 @@ public: LookupCriteria Criteria); LookupResult LookupParsedName(Scope *S, const CXXScopeSpec &SS, DeclarationName Name, LookupCriteria Criteria); - LookupResult LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, - const DeclContext *LookupCtx = 0, + LookupResult LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S, + bool LookInParent = true); + LookupResult LookupDeclInContext(DeclarationName Name, unsigned NSI, + const DeclContext *LookupCtx, bool LookInParent = true); bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 79efc7df9c..54f84cf40e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -34,13 +34,16 @@ using namespace clang; Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS) { DeclContext *DC = 0; + if (SS) { if (SS->isInvalid()) return 0; DC = static_cast(SS->getScopeRep()); } - LookupResult Result = LookupDecl(&II, Decl::IDNS_Ordinary, S, DC); - + LookupResult Result = DC ? + LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC) : + LookupDeclInScope(&II, Decl::IDNS_Ordinary, S); + Decl *IIDecl = 0; switch (Result.getKind()) { case LookupResult::NotFound: @@ -215,7 +218,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) { // The third "scope" argument is 0 since we aren't enabling lazy built-in // creation from this context. - Decl *IDecl = LookupDecl(Id, Decl::IDNS_Ordinary, 0); + Decl *IDecl = LookupDeclInScope(Id, Decl::IDNS_Ordinary, 0); return dyn_cast_or_null(IDecl); } @@ -252,7 +255,7 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) { return S; } -/// LookupDecl - Look up the inner-most declaration in the specified +/// LookupDeclInScope - Look up the inner-most declaration in the specified /// namespace. NamespaceNameOnly - during lookup only namespace names /// are considered as required in C++ [basic.lookup.udir] 3.4.6.p1 /// 'When looking up a namespace-name in a using-directive or @@ -261,9 +264,8 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) { /// Note: The use of this routine is deprecated. Please use /// LookupName, LookupQualifiedName, or LookupParsedName instead. Sema::LookupResult -Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, - const DeclContext *LookupCtx, - bool LookInParent) { +Sema::LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S, + bool LookInParent) { LookupCriteria::NameKind Kind; if (NSI == Decl::IDNS_Ordinary) { Kind = LookupCriteria::Ordinary; @@ -273,24 +275,37 @@ Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument"); Kind = LookupCriteria::Member; } - - if (LookupCtx) - return LookupQualifiedName(const_cast(LookupCtx), Name, - LookupCriteria(Kind, !LookInParent, - getLangOptions().CPlusPlus)); - // Unqualified lookup return LookupName(S, Name, LookupCriteria(Kind, !LookInParent, getLangOptions().CPlusPlus)); } +Sema::LookupResult +Sema::LookupDeclInContext(DeclarationName Name, unsigned NSI, + const DeclContext *LookupCtx, + bool LookInParent) { + assert(LookupCtx && "LookupDeclInContext(): Missing DeclContext"); + LookupCriteria::NameKind Kind; + if (NSI == Decl::IDNS_Ordinary) { + Kind = LookupCriteria::Ordinary; + } else if (NSI == Decl::IDNS_Tag) + Kind = LookupCriteria::Tag; + else { + assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument"); + Kind = LookupCriteria::Member; + } + return LookupQualifiedName(const_cast(LookupCtx), Name, + LookupCriteria(Kind, !LookInParent, + getLangOptions().CPlusPlus)); +} + void Sema::InitBuiltinVaListType() { if (!Context.getBuiltinVaListType().isNull()) return; IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list"); - Decl *VaDecl = LookupDecl(VaIdent, Decl::IDNS_Ordinary, TUScope); + Decl *VaDecl = LookupDeclInScope(VaIdent, Decl::IDNS_Ordinary, TUScope); TypedefDecl *VaTypedef = cast(VaDecl); Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef)); } @@ -339,7 +354,7 @@ NamespaceDecl *Sema::GetStdNamespace() { if (!StdNamespace) { IdentifierInfo *StdIdent = &PP.getIdentifierTable().get("std"); DeclContext *Global = Context.getTranslationUnitDecl(); - Decl *Std = LookupDecl(StdIdent, Decl::IDNS_Ordinary, 0, Global); + Decl *Std = LookupDeclInContext(StdIdent, Decl::IDNS_Ordinary, Global); StdNamespace = dyn_cast_or_null(Std); } return StdNamespace; @@ -783,8 +798,8 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner, FEnd = AnonRecord->field_end(); F != FEnd; ++F) { if ((*F)->getDeclName()) { - Decl *PrevDecl = LookupDecl((*F)->getDeclName(), Decl::IDNS_Ordinary, - S, Owner, false); + Decl *PrevDecl = LookupDeclInContext((*F)->getDeclName(), + Decl::IDNS_Ordinary, Owner, false); if (PrevDecl && !isa(PrevDecl)) { // C++ [class.union]p2: // The names of the members of an anonymous union shall be @@ -1235,10 +1250,11 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl, // See if this is a redefinition of a variable in the same scope. if (!D.getCXXScopeSpec().isSet()) { DC = CurContext; - PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S); + PrevDecl = LookupDeclInScope(Name, Decl::IDNS_Ordinary, S); } else { // Something like "int foo::x;" DC = static_cast(D.getCXXScopeSpec().getScopeRep()); - PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC); + PrevDecl = DC ? LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC) + : LookupDeclInScope(Name, Decl::IDNS_Ordinary, S); // C++ 7.3.1.2p2: // Members (including explicit specializations of templates) of a named @@ -1727,7 +1743,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, << D.getCXXScopeSpec().getRange(); InvalidDecl = true; - PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC); + PrevDecl = LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC); if (!PrevDecl) { // Nothing to suggest. } else if (OverloadedFunctionDecl *Ovl @@ -2582,7 +2598,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { // among each other. Here they can only shadow globals, which is ok. IdentifierInfo *II = D.getIdentifier(); if (II) { - if (Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S)) { + if (Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, S)) { if (PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); @@ -2873,8 +2889,8 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, DC = static_cast(SS.getScopeRep()); // Look-up name inside 'foo::'. - PrevDecl = dyn_cast_or_null(LookupDecl(Name, Decl::IDNS_Tag,S,DC) - .getAsDecl()); + PrevDecl = dyn_cast_or_null( + LookupDeclInContext(Name, Decl::IDNS_Tag, DC).getAsDecl()); // A tag 'foo::bar' must already exist. if (PrevDecl == 0) { @@ -2885,7 +2901,8 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, } else if (Name) { // If this is a named struct, check to see if there was a previous forward // declaration or definition. - PrevDecl = dyn_cast_or_null(LookupDecl(Name, Decl::IDNS_Tag,S) + PrevDecl = dyn_cast_or_null(LookupDeclInScope(Name, + Decl::IDNS_Tag,S) .getAsDecl()); if (!getLangOptions().CPlusPlus && TK != TK_Reference) { @@ -3273,7 +3290,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD, if (II) { Decl *PrevDecl - = LookupDecl(II, Decl::IDNS_Member, S, 0, false); + = LookupDeclInScope(II, Decl::IDNS_Member, S, false); if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S) && !isa(PrevDecl)) { Diag(Loc, diag::err_duplicate_member) << II; @@ -3365,8 +3382,7 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S, (Expr *)BitfieldWidth); if (II) { - Decl *PrevDecl - = LookupDecl(II, Decl::IDNS_Member, S, 0, false); + Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Member, S, false); if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S) && !isa(PrevDecl)) { Diag(Loc, diag::err_duplicate_member) << II; @@ -3542,7 +3558,7 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl, // Verify that there isn't already something declared with this name in this // scope. - Decl *PrevDecl = LookupDecl(Id, Decl::IDNS_Ordinary, S); + Decl *PrevDecl = LookupDeclInScope(Id, Decl::IDNS_Ordinary, S); if (PrevDecl && PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(IdLoc, PrevDecl); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 0e08eb3fd8..a61184f669 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1376,9 +1376,8 @@ Sema::DeclTy *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, // original-namespace-definition is the name of the namespace. Subsequently // in that declarative region, it is treated as an original-namespace-name. - Decl *PrevDecl = - LookupDecl(II, Decl::IDNS_Ordinary, DeclRegionScope, 0, - /*LookupInParent=*/false); + Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, DeclRegionScope, + /*LookupInParent=*/false); if (NamespaceDecl *OrigNS = dyn_cast_or_null(PrevDecl)) { // This is an extended namespace definition. @@ -2181,7 +2180,7 @@ Sema::DeclTy *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) // FIXME: Need to check for abstract classes. IdentifierInfo *II = D.getIdentifier(); - if (Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S)) { + if (Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, S)) { // The scope should be freshly made just for us. There is just no way // it contains any previous declaration. assert(!S->isDeclScope(PrevDecl)); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index b636e29945..fcf9a92aca 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -65,7 +65,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc, assert(ClassName && "Missing class identifier"); // Check for another declaration kind with the same name. - Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope); + Decl *PrevDecl = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope); if (PrevDecl && PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl); @@ -108,7 +108,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc, if (SuperName) { ObjCInterfaceDecl* SuperClassEntry = 0; // Check if a different kind of symbol declared in this scope. - PrevDecl = LookupDecl(SuperName, Decl::IDNS_Ordinary, TUScope); + PrevDecl = LookupDeclInScope(SuperName, Decl::IDNS_Ordinary, TUScope); if (PrevDecl && !isa(PrevDecl)) { Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName; Diag(PrevDecl->getLocation(), diag::note_previous_definition); @@ -150,7 +150,7 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc, IdentifierInfo *ClassName, SourceLocation ClassLocation) { // Look for previous declaration of alias name - Decl *ADecl = LookupDecl(AliasName, Decl::IDNS_Ordinary, TUScope); + Decl *ADecl = LookupDeclInScope(AliasName, Decl::IDNS_Ordinary, TUScope); if (ADecl) { if (isa(ADecl)) Diag(AliasLocation, diag::warn_previous_alias_decl); @@ -160,13 +160,13 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc, return 0; } // Check for class declaration - Decl *CDeclU = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope); + Decl *CDeclU = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope); if (const TypedefDecl *TDecl = dyn_cast_or_null(CDeclU)) { QualType T = TDecl->getUnderlyingType(); if (T->isObjCInterfaceType()) { if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl()) { ClassName = IDecl->getIdentifier(); - CDeclU = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope); + CDeclU = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope); } } } @@ -536,7 +536,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation( SourceLocation SuperClassLoc) { ObjCInterfaceDecl* IDecl = 0; // Check for another declaration kind with the same name. - Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope); + Decl *PrevDecl = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope); if (PrevDecl && !isa(PrevDecl)) { Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; Diag(PrevDecl->getLocation(), diag::note_previous_definition); @@ -552,7 +552,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation( ObjCInterfaceDecl* SDecl = 0; if (SuperClassname) { // Check if a different kind of symbol declared in this scope. - PrevDecl = LookupDecl(SuperClassname, Decl::IDNS_Ordinary, TUScope); + PrevDecl = LookupDeclInScope(SuperClassname, Decl::IDNS_Ordinary, TUScope); if (PrevDecl && !isa(PrevDecl)) { Diag(SuperClassLoc, diag::err_redefinition_different_kind) << SuperClassname; @@ -910,7 +910,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, for (unsigned i = 0; i != NumElts; ++i) { // Check for another declaration kind with the same name. - Decl *PrevDecl = LookupDecl(IdentList[i], Decl::IDNS_Ordinary, TUScope); + Decl *PrevDecl = LookupDeclInScope(IdentList[i], Decl::IDNS_Ordinary, TUScope); if (PrevDecl && PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 064b8517f7..2eb4605623 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -561,9 +561,9 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, DeclContext *DC = static_cast(SS->getScopeRep()); if (DC == 0) return ExprError(); - Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC); + Lookup = LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC); } else - Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S); + Lookup = LookupDeclInScope(Name, Decl::IDNS_Ordinary, S); if (Lookup.isAmbiguous()) { DiagnoseAmbiguousLookup(Lookup, Name, Loc, @@ -4031,9 +4031,9 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, // Get the decl corresponding to this. RecordDecl *RD = RC->getDecl(); FieldDecl *MemberDecl - = dyn_cast_or_null(LookupDecl(OC.U.IdentInfo, + = dyn_cast_or_null(LookupDeclInContext(OC.U.IdentInfo, Decl::IDNS_Ordinary, - S, RD, false).getAsDecl()); + RD, false).getAsDecl()); if (!MemberDecl) return Diag(BuiltinLoc, diag::err_typecheck_no_member) << OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 55317db502..743fa12b18 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -61,7 +61,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, return Diag(OpLoc, diag::err_need_header_before_typeid); IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); - Decl *TypeInfoDecl = LookupDecl(TypeInfoII, Decl::IDNS_Tag, 0, StdNs); + Decl *TypeInfoDecl = LookupDeclInContext(TypeInfoII, Decl::IDNS_Tag, StdNs); RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null(TypeInfoDecl); if (!TypeInfoRecordDecl) return Diag(OpLoc, diag::err_need_header_before_typeid); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index eff259d8fa..a19a1d16d0 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -53,7 +53,7 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, // Initialize the constant string interface lazily. This assumes // the NSConstantString interface is seen in this translation unit. IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString"); - Decl *IFace = LookupDecl(NSIdent, Decl::IDNS_Ordinary, TUScope); + Decl *IFace = LookupDeclInScope(NSIdent, Decl::IDNS_Ordinary, TUScope); ObjCInterfaceDecl *strIFace = dyn_cast_or_null(IFace); if (strIFace) Context.setObjCConstantStringInterface(strIFace); @@ -210,7 +210,7 @@ Sema::ExprResult Sema::ActOnClassMessage( } else { // 'super' has been used outside a method context. If a variable named // 'super' has been declared, redirect. If not, produce a diagnostic. - Decl *SuperDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, S); + Decl *SuperDecl = LookupDeclInScope(receiverName, Decl::IDNS_Ordinary, S); ValueDecl *VD = dyn_cast_or_null(SuperDecl); if (VD) { ExprResult ReceiverExpr = new DeclRefExpr(VD, VD->getType(), @@ -235,7 +235,7 @@ Sema::ExprResult Sema::ActOnClassMessage( // // If necessary, the following lookup could move to getObjCInterfaceDecl(). if (!ClassDecl) { - Decl *IDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, 0); + Decl *IDecl = LookupDeclInScope(receiverName, Decl::IDNS_Ordinary, 0); if (TypedefDecl *OCTD = dyn_cast_or_null(IDecl)) { const ObjCInterfaceType *OCIT; OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType(); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index f448664615..7ecac00277 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -26,12 +26,15 @@ using namespace clang; Sema::DeclTy *Sema::isTemplateName(IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS) { DeclContext *DC = 0; + if (SS) { if (SS->isInvalid()) return 0; DC = static_cast(SS->getScopeRep()); } - Decl *IIDecl = LookupDecl(&II, Decl::IDNS_Ordinary, S, DC, false); + Decl *IIDecl = DC ? + LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC, false) : + LookupDeclInScope(&II, Decl::IDNS_Ordinary, S, false); if (IIDecl) { // FIXME: We need to represent templates via some kind of @@ -93,7 +96,7 @@ Sema::DeclTy *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Invalid = false; if (ParamName) { - Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S); + Decl *PrevDecl = LookupDeclInScope(ParamName, Decl::IDNS_Tag, S); if (PrevDecl && PrevDecl->isTemplateParameter()) Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc, PrevDecl); @@ -129,7 +132,7 @@ Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, IdentifierInfo *ParamName = D.getIdentifier(); if (ParamName) { - Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S); + Decl *PrevDecl = LookupDeclInScope(ParamName, Decl::IDNS_Tag, S); if (PrevDecl && PrevDecl->isTemplateParameter()) Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);