diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 26709a5aaa65..55f80f231f38 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/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/clang/test/Parser/DelayedTemplateParsing.cpp b/clang/test/Parser/DelayedTemplateParsing.cpp index 6ea245c2d4e4..301eacfabba3 100644 --- a/clang/test/Parser/DelayedTemplateParsing.cpp +++ b/clang/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(); +}