Author: rnk Date: Tue Nov 27 13:20:42 2018 New Revision: 347713 URL: http://llvm.org/viewvc/llvm-project?rev=347713&view=rev Log: [MS] Push outermost class DeclContexts only in -fdelayed-template-parsing
This is more or less a complete rewrite of r347627, and it fixes PR38460 I added a reduced test case to DelayedTemplateParsing.cpp. Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp cfe/trunk/test/Parser/DelayedTemplateParsing.cpp Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=347713&r1=347712&r2=347713&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseTemplate.cpp (original) +++ cfe/trunk/lib/Parse/ParseTemplate.cpp Tue Nov 27 13:20:42 2018 @@ -1381,26 +1381,37 @@ void Parser::ParseLateTemplatedFuncDef(L SmallVector<ParseScope*, 4> TemplateParamScopeStack; - // Get the list of DeclContexts to reenter. - SmallVector<DeclContext*, 4> DeclContextsToReenter; + // Get the list of DeclContexts to reenter. For inline methods, we only want + // to push the DeclContext of the outermost class. This matches the way the + // parser normally parses bodies of inline methods when the outermost class is + // complete. + struct ContainingDC { + ContainingDC(DeclContext *DC, bool ShouldPush) : Pair(DC, ShouldPush) {} + llvm::PointerIntPair<DeclContext *, 1, bool> Pair; + DeclContext *getDC() { return Pair.getPointer(); } + bool shouldPushDC() { return Pair.getInt(); } + }; + SmallVector<ContainingDC, 4> DeclContextsToReenter; DeclContext *DD = FunD; + DeclContext *NextContaining = Actions.getContainingDC(DD); while (DD && !DD->isTranslationUnit()) { - DeclContextsToReenter.push_back(DD); + bool ShouldPush = DD == NextContaining; + DeclContextsToReenter.push_back({DD, ShouldPush}); + if (ShouldPush) + NextContaining = Actions.getContainingDC(DD); DD = DD->getLexicalParent(); } // Reenter template scopes from outermost to innermost. - SmallVectorImpl<DeclContext *>::reverse_iterator II = - DeclContextsToReenter.rbegin(); - for (; II != DeclContextsToReenter.rend(); ++II) { - TemplateParamScopeStack.push_back(new ParseScope(this, - Scope::TemplateParamScope)); - unsigned NumParamLists = - Actions.ActOnReenterTemplateScope(getCurScope(), cast<Decl>(*II)); + for (ContainingDC CDC : reverse(DeclContextsToReenter)) { + TemplateParamScopeStack.push_back( + new ParseScope(this, Scope::TemplateParamScope)); + unsigned NumParamLists = Actions.ActOnReenterTemplateScope( + getCurScope(), cast<Decl>(CDC.getDC())); CurTemplateDepthTracker.addDepth(NumParamLists); - if (*II != FunD) { + if (CDC.shouldPushDC()) { TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope)); - Actions.PushDeclContext(Actions.getCurScope(), *II); + Actions.PushDeclContext(Actions.getCurScope(), CDC.getDC()); } } Modified: cfe/trunk/test/Parser/DelayedTemplateParsing.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/DelayedTemplateParsing.cpp?rev=347713&r1=347712&r2=347713&view=diff ============================================================================== --- cfe/trunk/test/Parser/DelayedTemplateParsing.cpp (original) +++ cfe/trunk/test/Parser/DelayedTemplateParsing.cpp Tue Nov 27 13:20:42 2018 @@ -181,3 +181,33 @@ static void h() { } } + +struct PR38460 { + template <typename> + struct T { + static void foo() { + struct U { + void dummy() { + use_delayed_identifier(); + } + }; + } + }; +}; +void use_delayed_identifier(); +void trigger_PR38460() { + PR38460::T<int>::foo(); +} + +template <typename> struct PR38460_2 { + struct p { + struct G { + bool operator()(int) {} + }; + }; + static void as() { + typename p::G g; + g(0); + } +}; +template struct PR38460_2<int>; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits