From 39c3aadd7d2a166b6a0d698be33f185020b9ab22 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 27 Nov 2018 02:21:51 +0000 Subject: [PATCH] [MS] Push fewer DeclContexts for delayed template parsing Only push the outermost record as a DeclContext when parsing a function body. See the comments in Sema::getContainingDC about the way the parser pushes contexts. This is intended to match the behavior the parser normally displays where it parses all method bodies from all nested classes at the end of the outermost class, when all nested classes are complete. Fixes PR38460. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@347627 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Parse/ParseTemplate.cpp | 9 +++++++-- test/Parser/DelayedTemplateParsing.cpp | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 26709a5aaa..55f80f231f 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -1382,7 +1382,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { SmallVector TemplateParamScopeStack; // Get the list of DeclContexts to reenter. - SmallVector DeclContextsToReenter; + SmallVector DeclContextsToReenter; DeclContext *DD = FunD; while (DD && !DD->isTranslationUnit()) { DeclContextsToReenter.push_back(DD); @@ -1398,7 +1398,12 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { unsigned NumParamLists = Actions.ActOnReenterTemplateScope(getCurScope(), cast(*II)); CurTemplateDepthTracker.addDepth(NumParamLists); - if (*II != FunD) { + // If we find a class in a class, we need to push the context of the + // outermost class to match up with how we would parse a regular C++ class + // inline method. + if (*II != FunD && + !(isa(*II) && isa(Actions.CurContext) && + Actions.CurContext == (*II)->getLexicalParent())) { TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope)); Actions.PushDeclContext(Actions.getCurScope(), *II); } diff --git a/test/Parser/DelayedTemplateParsing.cpp b/test/Parser/DelayedTemplateParsing.cpp index 6ea245c2d4..301eacfabb 100644 --- a/test/Parser/DelayedTemplateParsing.cpp +++ b/test/Parser/DelayedTemplateParsing.cpp @@ -181,3 +181,20 @@ static void h() { } } + +struct PR38460 { + template + struct T { + static void foo() { + struct U { + void dummy() { + use_delayed_identifier(); + } + }; + } + }; +}; +void use_delayed_identifier(); +void trigger_PR38460() { + PR38460::T::foo(); +} -- 2.40.0