From: Sebastian Redl Date: Tue, 31 Aug 2010 00:36:30 +0000 (+0000) Subject: Rename DeclContext::getLookupContext to getRedeclContext and change its semantics... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7a126a474fdde06382b315b4e3d8ef0a21d4dc31;p=clang Rename DeclContext::getLookupContext to getRedeclContext and change its semantics slightly. No functionality change in the absence of inline namespaces. Also, change a few places where inline namespaces actually make a difference to be prepared for them. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112563 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 407ee3d123..3a93193211 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -267,6 +267,11 @@ public: return !getIdentifier(); } + /// \brief Returns true if this is a C++0x inline namespace. + bool isInline() const { + return false; + } + /// \brief Return the next extended namespace declaration or null if there /// is none. NamespaceDecl *getNextNamespace() { return NextNamespace; } @@ -628,7 +633,7 @@ public: if (getKind() != Decl::Var) return false; if (const DeclContext *DC = getDeclContext()) - return DC->getLookupContext()->isFunctionOrMethod(); + return DC->getRedeclContext()->isFunctionOrMethod(); return false; } @@ -637,10 +642,8 @@ public: bool isFunctionOrMethodVarDecl() const { if (getKind() != Decl::Var) return false; - if (const DeclContext *DC = getDeclContext()) - return DC->getLookupContext()->isFunctionOrMethod() && - DC->getLookupContext()->getDeclKind() != Decl::Block; - return false; + const DeclContext *DC = getDeclContext()->getRedeclContext(); + return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block; } /// \brief Determines whether this is a static data member. @@ -702,7 +705,7 @@ public: if (getKind() != Decl::Var) return false; - if (getDeclContext()->getLookupContext()->isFileContext()) + if (getDeclContext()->getRedeclContext()->isFileContext()) return true; if (isStaticDataMember()) diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index d973a1d108..d5b183b6a5 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -453,10 +453,10 @@ public: void setLexicalDeclContext(DeclContext *DC); - // isDefinedOutsideFunctionOrMethod - This predicate returns true if this - // scoped decl is defined outside the current function or method. This is - // roughly global variables and functions, but also handles enums (which could - // be defined inside or outside a function etc). + /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this + /// scoped decl is defined outside the current function or method. This is + /// roughly global variables and functions, but also handles enums (which + /// could be defined inside or outside a function etc). bool isDefinedOutsideFunctionOrMethod() const; /// \brief Retrieves the "canonical" declaration of the given declaration. @@ -808,13 +808,13 @@ public: /// \brief Determine whether this declaration context is equivalent /// to the declaration context DC. - bool Equals(DeclContext *DC) { + bool Equals(const DeclContext *DC) const { return DC && this->getPrimaryContext() == DC->getPrimaryContext(); } /// \brief Determine whether this declaration context encloses the /// declaration context DC. - bool Encloses(DeclContext *DC); + bool Encloses(const DeclContext *DC) const; /// getPrimaryContext - There may be many different /// declarations of the same entity (including forward declarations @@ -827,13 +827,13 @@ public: return const_cast(this)->getPrimaryContext(); } - /// getLookupContext - Retrieve the innermost non-transparent - /// context of this context, which corresponds to the innermost - /// location from which name lookup can find the entities in this - /// context. - DeclContext *getLookupContext(); - const DeclContext *getLookupContext() const { - return const_cast(this)->getLookupContext(); + /// getRedeclContext - Retrieve the context in which an entity conflicts with + /// other entities of the same name, or where it is a redeclaration if the + /// two entities are compatible. This skips through transparent contexts, + /// except inline namespaces. + DeclContext *getRedeclContext(); + const DeclContext *getRedeclContext() const { + return const_cast(this)->getRedeclContext(); } /// \brief Retrieve the nearest enclosing namespace context. @@ -842,6 +842,14 @@ public: return const_cast(this)->getEnclosingNamespaceContext(); } + /// \brief Test if this context is part of the enclosing namespace set of + /// the context NS, as defined in C++0x [namespace.def]p9. If either context + /// isn't a namespace, this is equivalent to Equals(). + /// + /// The enclosing namespace set of a namespace is the namespace and, if it is + /// inline, its enclosing namespace, recursively. + bool InEnclosingNamespaceSetOf(const DeclContext *NS) const; + /// getNextContext - If this is a DeclContext that may have other /// DeclContexts that are semantically connected but syntactically /// different, such as C++ namespaces, this routine retrieves the diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index bef6194e26..9d9f27e1a0 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -104,7 +104,7 @@ getLinkageForTemplateArgumentList(const TemplateArgumentList &TArgs) { } static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { - assert(D->getDeclContext()->getLookupContext()->isFileContext() && + assert(D->getDeclContext()->getRedeclContext()->isFileContext() && "Not a name having namespace scope"); ASTContext &Context = D->getASTContext(); @@ -345,7 +345,7 @@ Linkage NamedDecl::getLinkage() const { } // Handle linkage for namespace-scope names. - if (getDeclContext()->getLookupContext()->isFileContext()) + if (getDeclContext()->getRedeclContext()->isFileContext()) if (Linkage L = getLinkageForNamespaceScopeDecl(this)) return L; @@ -969,7 +969,7 @@ void FunctionDecl::setBody(Stmt *B) { bool FunctionDecl::isMain() const { ASTContext &Context = getASTContext(); return !Context.getLangOptions().Freestanding && - getDeclContext()->getLookupContext()->isTranslationUnit() && + getDeclContext()->getRedeclContext()->isTranslationUnit() && getIdentifier() && getIdentifier()->isStr("main"); } diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 9463b6cc73..0316124fbe 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -471,8 +471,8 @@ DeclContext::~DeclContext() { } DeclContext *DeclContext::getLookupParent() { // FIXME: Find a better way to identify friends if (isa(this)) - if (getParent()->getLookupContext()->isFileContext() && - getLexicalParent()->getLookupContext()->isRecord()) + if (getParent()->getRedeclContext()->isFileContext() && + getLexicalParent()->getRedeclContext()->isRecord()) return getLexicalParent(); return getParent(); @@ -515,7 +515,7 @@ bool DeclContext::isTransparentContext() const { return false; } -bool DeclContext::Encloses(DeclContext *DC) { +bool DeclContext::Encloses(const DeclContext *DC) const { if (getPrimaryContext() != this) return getPrimaryContext()->Encloses(DC); @@ -847,10 +847,10 @@ DeclContext::lookup(DeclarationName Name) const { return const_cast(this)->lookup(Name); } -DeclContext *DeclContext::getLookupContext() { +DeclContext *DeclContext::getRedeclContext() { DeclContext *Ctx = this; - // Skip through transparent contexts. - while (Ctx->isTransparentContext()) + // Skip through transparent contexts, except inline namespaces. + while (Ctx->isTransparentContext() && !Ctx->isNamespace()) Ctx = Ctx->getParent(); return Ctx; } @@ -863,6 +863,24 @@ DeclContext *DeclContext::getEnclosingNamespaceContext() { return Ctx->getPrimaryContext(); } +bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const { + // For non-file contexts, this is equivalent to Equals. + if (!isFileContext()) + return O->Equals(this); + + do { + if (O->Equals(this)) + return true; + + const NamespaceDecl *NS = dyn_cast(O); + if (!NS || !NS->isInline()) + break; + O = NS->getParent(); + } while (O); + + return false; +} + void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) { // FIXME: This feels like a hack. Should DeclarationName support // template-ids, or is there a better way to keep specializations diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 97ee76cebd..61831543b4 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -347,7 +347,7 @@ static bool IsPlacementOperatorNewArray(ASTContext &Ctx, const FunctionDecl *Fn) { // Must be in global scope. Note that allocation functions can't be // declared in namespaces. - if (!Fn->getDeclContext()->getLookupContext()->isFileContext()) + if (!Fn->getDeclContext()->getRedeclContext()->isFileContext()) return false; // Signature must be void *operator new[](size_t, void*). diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index c4e7bb4269..c772a6fd77 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -388,7 +388,7 @@ unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) { return CCP_Unlikely; // Context-based decisions. - DeclContext *DC = ND->getDeclContext()->getLookupContext(); + DeclContext *DC = ND->getDeclContext()->getRedeclContext(); if (DC->isFunctionOrMethod() || isa(DC)) return CCP_LocalDeclaration; if (DC->isRecord() || isa(DC)) diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp index 384fbec676..3f16ed7723 100644 --- a/lib/Sema/IdentifierResolver.cpp +++ b/lib/Sema/IdentifierResolver.cpp @@ -105,7 +105,7 @@ IdentifierResolver::~IdentifierResolver() { /// true if 'D' belongs to the given declaration context. bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context, Scope *S) const { - Ctx = Ctx->getLookupContext(); + Ctx = Ctx->getRedeclContext(); if (Ctx->isFunctionOrMethod()) { // Ignore the scopes associated within transparent declaration contexts. @@ -135,7 +135,7 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, return false; } - return D->getDeclContext()->getLookupContext()->Equals(Ctx); + return D->getDeclContext()->getRedeclContext()->Equals(Ctx); } /// AddDecl - Link the decl to its shadowed decl chain. diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index d7ef79304f..631308eebb 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -626,7 +626,7 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { case NestedNameSpecifier::Namespace: // These are always namespace scopes. We never want to enter a // namespace scope from anything but a file context. - return CurContext->getLookupContext()->isFileContext(); + return CurContext->getRedeclContext()->isFileContext(); case NestedNameSpecifier::Identifier: case NestedNameSpecifier::TypeSpec: diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index c154364505..25de61a3f5 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -501,13 +501,13 @@ bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext, if (!SemaRef.getLangOptions().CPlusPlus) return true; - DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext(); + DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext(); // There is no way to qualify a name declared in a function or method. if (HiddenCtx->isFunctionOrMethod()) return true; - if (HiddenCtx == Hiding->getDeclContext()->getLookupContext()) + if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext()) return true; // We can refer to the result with the appropriate qualification. Do it. @@ -786,7 +786,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext, } else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass && isa(R.Declaration->getDeclContext() - ->getLookupContext())) + ->getRedeclContext())) R.QualifierIsInformative = true; // If this result is supposed to have an informative qualifier, add one. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cd64175a51..fdffa04037 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2288,7 +2288,7 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, IsLinkageLookup = true; } else if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern) IsLinkageLookup = true; - else if (CurContext->getLookupContext()->isTranslationUnit() && + else if (CurContext->getRedeclContext()->isTranslationUnit() && D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) IsLinkageLookup = true; @@ -2588,7 +2588,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, // If this is the C FILE type, notify the AST context. if (IdentifierInfo *II = NewTD->getIdentifier()) if (!NewTD->isInvalidDecl() && - NewTD->getDeclContext()->getLookupContext()->isTranslationUnit()) { + NewTD->getDeclContext()->getRedeclContext()->isTranslationUnit()) { if (II->isStr("FILE")) Context.setFILEDecl(NewTD); else if (II->isStr("jmp_buf")) @@ -2622,7 +2622,7 @@ static bool isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC, ASTContext &Context) { if (!PrevDecl) - return 0; + return false; if (!PrevDecl->hasLinkage()) return false; @@ -2634,7 +2634,7 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC, // outside the innermost enclosing namespace scope, the block // scope declaration declares that same entity and receives the // linkage of the previous declaration. - DeclContext *OuterContext = DC->getLookupContext(); + DeclContext *OuterContext = DC->getRedeclContext(); if (!OuterContext->isFunctionOrMethod()) // This rule only applies to block-scope declarations. return false; @@ -2646,10 +2646,8 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC, // Find the innermost enclosing namespace for the new and // previous declarations. - while (!OuterContext->isFileContext()) - OuterContext = OuterContext->getParent(); - while (!PrevOuterContext->isFileContext()) - PrevOuterContext = PrevOuterContext->getParent(); + OuterContext = OuterContext->getEnclosingNamespaceContext(); + PrevOuterContext = PrevOuterContext->getEnclosingNamespaceContext(); // The previous declaration is in a different namespace, so it // isn't the same function. @@ -3160,7 +3158,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, case DeclSpec::SCS_unspecified: SC = SC_None; break; case DeclSpec::SCS_extern: SC = SC_Extern; break; case DeclSpec::SCS_static: { - if (CurContext->getLookupContext()->isFunctionOrMethod()) { + if (CurContext->getRedeclContext()->isFunctionOrMethod()) { // C99 6.7.1p5: // The declaration of an identifier for a function that has // block scope shall have no explicit storage-class specifier @@ -5514,8 +5512,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, if (const TagType *TT = TD->getUnderlyingType()->getAs()) { TagDecl *Tag = TT->getDecl(); if (Tag->getDeclName() == Name && - Tag->getDeclContext()->getLookupContext() - ->Equals(TD->getDeclContext()->getLookupContext())) { + Tag->getDeclContext()->getRedeclContext() + ->Equals(TD->getDeclContext()->getRedeclContext())) { PrevDecl = Tag; Previous.clear(); Previous.addDecl(Tag); @@ -5793,7 +5791,7 @@ CreateNewDecl: if (PrevDecl) New->setAccess(PrevDecl->getAccess()); - DeclContext *DC = New->getDeclContext()->getLookupContext(); + DeclContext *DC = New->getDeclContext()->getRedeclContext(); DC->makeDeclVisibleInContext(New, /* Recoverable = */ false); if (Name) // can be null along some error paths if (Scope *EnclosingScope = getScopeForDeclContext(S, DC)) @@ -5808,7 +5806,7 @@ CreateNewDecl: // If this is the C FILE type, notify the AST context. if (IdentifierInfo *II = New->getIdentifier()) if (!New->isInvalidDecl() && - New->getDeclContext()->getLookupContext()->isTranslationUnit() && + New->getDeclContext()->getRedeclContext()->isTranslationUnit() && II->isStr("FILE")) Context.setFILEDecl(New); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index b920fcd4ff..f987067a31 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -557,13 +557,11 @@ static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { // static int a __attribute__((weakref ("v2"))); // } // we reject them - if (const DeclContext *Ctx = d->getDeclContext()) { - Ctx = Ctx->getLookupContext(); - if (!isa(Ctx) && !isa(Ctx) ) { - S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << - dyn_cast(d)->getNameAsString(); - return; - } + const DeclContext *Ctx = d->getDeclContext()->getRedeclContext(); + if (!Ctx->isFileContext()) { + S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << + dyn_cast(d)->getNameAsString(); + return; } // The GCC manual says diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 35920c2792..0ffc639816 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1151,7 +1151,7 @@ Sema::ActOnMemInitializer(Decl *ConstructorD, CorrectTypo(R, S, &SS, ClassDecl, 0, CTC_NoKeywords) && R.isSingleResult()) { if (FieldDecl *Member = R.getAsSingle()) { - if (Member->getDeclContext()->getLookupContext()->Equals(ClassDecl)) { + if (Member->getDeclContext()->getRedeclContext()->Equals(ClassDecl)) { // We have found a non-static data member with a similar // name to what was typed; complain and initialize that // member. @@ -3329,7 +3329,7 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, Namespc->setInvalidDecl(); // Continue on to push Namespc as current DeclContext and return it. } else if (II->isStr("std") && - CurContext->getLookupContext()->isTranslationUnit()) { + CurContext->getRedeclContext()->isTranslationUnit()) { // This is the first "real" definition of the namespace "std", so update // our cache of the "std" namespace to point at this definition. if (NamespaceDecl *StdNS = getStdNamespace()) { @@ -3352,7 +3352,7 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, // Link the anonymous namespace into its parent. NamespaceDecl *PrevDecl; - DeclContext *Parent = CurContext->getLookupContext(); + DeclContext *Parent = CurContext->getRedeclContext(); if (TranslationUnitDecl *TU = dyn_cast(Parent)) { PrevDecl = TU->getAnonymousNamespace(); TU->setAnonymousNamespace(Namespc); @@ -4022,7 +4022,7 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc, // allowed. // // That's in non-member contexts. - if (!CurContext->getLookupContext()->isRecord()) + if (!CurContext->getRedeclContext()->isRecord()) return false; NestedNameSpecifier *Qual @@ -5652,7 +5652,7 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, static inline bool CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef, const FunctionDecl *FnDecl) { - const DeclContext *DC = FnDecl->getDeclContext()->getLookupContext(); + const DeclContext *DC = FnDecl->getDeclContext()->getRedeclContext(); if (isa(DC)) { return SemaRef.Diag(FnDecl->getLocation(), diag::err_operator_new_delete_declared_in_namespace) @@ -6457,7 +6457,8 @@ Decl *Sema::ActOnFriendFunctionDecl(Scope *S, LookupResult::Filter F = Previous.makeFilter(); while (F.hasNext()) { NamedDecl *D = F.next(); - if (!D->getDeclContext()->getLookupContext()->Equals(DC)) + if (!DC->InEnclosingNamespaceSetOf( + D->getDeclContext()->getRedeclContext())) F.erase(); } F.done(); @@ -6538,7 +6539,7 @@ Decl *Sema::ActOnFriendFunctionDecl(Scope *S, // Also update the scope-based lookup if the target context's // lookup context is in lexical scope. if (!CurContext->isDependentContext()) { - DC = DC->getLookupContext(); + DC = DC->getRedeclContext(); DC->makeDeclVisibleInContext(ND, /* Recoverable=*/ false); if (Scope *EnclosingScope = getScopeForDeclContext(S, DC)) PushOnScopeChains(ND, EnclosingScope, /*AddToContext=*/ false); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index ac9d076863..3c6f224398 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1626,7 +1626,7 @@ Decl *Sema::ActOnMethodDeclaration( } bool Sema::CheckObjCDeclScope(Decl *D) { - if (isa(CurContext->getLookupContext())) + if (isa(CurContext->getRedeclContext())) return false; Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope); diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index a719590d6a..a28fd7fe12 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -1365,7 +1365,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl(), false, Sema::CTC_NoKeywords) && (ReplacementField = R.getAsSingle()) && - ReplacementField->getDeclContext()->getLookupContext() + ReplacementField->getDeclContext()->getRedeclContext() ->Equals(RT->getDecl())) { SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown_suggest) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 2cbf3073a4..47356bc248 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -940,7 +940,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // Friend templates are visible in fairly strange ways. if (!CurContext->isDependentContext()) { - DeclContext *DC = SemanticContext->getLookupContext(); + DeclContext *DC = SemanticContext->getRedeclContext(); DC->makeDeclVisibleInContext(NewTemplate, /* Recoverable = */ false); if (Scope *EnclosingScope = getScopeForDeclContext(S, DC)) PushOnScopeChains(NewTemplate, EnclosingScope, @@ -3415,7 +3415,7 @@ static bool CheckTemplateSpecializationScope(Sema &S, // the explicit specialization was declared, or in a namespace // that encloses the one in which the explicit specialization was // declared. - if (S.CurContext->getLookupContext()->isFunctionOrMethod()) { + if (S.CurContext->getRedeclContext()->isFunctionOrMethod()) { S.Diag(Loc, diag::err_template_spec_decl_function_scope) << Specialized; return true; @@ -4234,12 +4234,13 @@ Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, LookupResult &Previous) { // Remove anything from Previous that isn't a function template in // the correct context. - DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext(); + DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext(); LookupResult::Filter F = Previous.makeFilter(); while (F.hasNext()) { NamedDecl *D = F.next()->getUnderlyingDecl(); if (!isa(D) || - !FDLookupContext->Equals(D->getDeclContext()->getLookupContext())) + !FDLookupContext->InEnclosingNamespaceSetOf( + D->getDeclContext()->getRedeclContext())) F.erase(); } F.done(); @@ -4278,14 +4279,15 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, // explicit function template specialization. UnresolvedSet<8> Candidates; - DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext(); + DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext(); for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); I != E; ++I) { NamedDecl *Ovl = (*I)->getUnderlyingDecl(); if (FunctionTemplateDecl *FunTmpl = dyn_cast(Ovl)) { // Only consider templates found within the same semantic lookup scope as // FD. - if (!FDLookupContext->Equals(Ovl->getDeclContext()->getLookupContext())) + if (!FDLookupContext->InEnclosingNamespaceSetOf( + Ovl->getDeclContext()->getRedeclContext())) continue; // C++ [temp.expl.spec]p11: @@ -4564,9 +4566,8 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, SourceLocation InstLoc, bool WasQualifiedName) { - DeclContext *ExpectedContext - = D->getDeclContext()->getEnclosingNamespaceContext()->getLookupContext(); - DeclContext *CurContext = S.CurContext->getLookupContext(); + DeclContext *OrigContext= D->getDeclContext()->getEnclosingNamespaceContext(); + DeclContext *CurContext = S.CurContext->getRedeclContext(); if (CurContext->isRecord()) { S.Diag(InstLoc, diag::err_explicit_instantiation_in_class) @@ -4580,8 +4581,8 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, // // This is DR275, which we do not retroactively apply to C++98/03. if (S.getLangOptions().CPlusPlus0x && - !CurContext->Encloses(ExpectedContext)) { - if (NamespaceDecl *NS = dyn_cast(ExpectedContext)) + !CurContext->Encloses(OrigContext)) { + if (NamespaceDecl *NS = dyn_cast(OrigContext)) S.Diag(InstLoc, S.getLangOptions().CPlusPlus0x? diag::err_explicit_instantiation_out_of_scope @@ -4596,7 +4597,7 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); return false; } - + // C++0x [temp.explicit]p2: // If the name declared in the explicit instantiation is an unqualified // name, the explicit instantiation shall appear in the namespace where @@ -4604,15 +4605,15 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, // namespace from its enclosing namespace set. if (WasQualifiedName) return false; - - if (CurContext->Equals(ExpectedContext)) + + if (CurContext->InEnclosingNamespaceSetOf(OrigContext)) return false; - + S.Diag(InstLoc, S.getLangOptions().CPlusPlus0x? diag::err_explicit_instantiation_unqualified_wrong_namespace : diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x) - << D << ExpectedContext; + << D << OrigContext; S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); return false; } diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 2566d04308..e3b6614faa 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -529,7 +529,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { } if (CXXRecordDecl *Parent= dyn_cast(Field->getDeclContext())) { if (Parent->isAnonymousStructOrUnion() && - Parent->getLookupContext()->isFunctionOrMethod()) + Parent->getRedeclContext()->isFunctionOrMethod()) SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field); } @@ -946,7 +946,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { // Make sure that anonymous structs and unions are recorded. if (D->isAnonymousStructOrUnion()) { Record->setAnonymousStructOrUnion(true); - if (Record->getDeclContext()->getLookupContext()->isFunctionOrMethod()) + if (Record->getDeclContext()->getRedeclContext()->isFunctionOrMethod()) SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record); }