diff options
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 9 | ||||
-rw-r--r-- | clang/test/Parser/DelayedTemplateParsing.cpp | 17 |
2 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 26709a5aaa6..55f80f231f3 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1382,7 +1382,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { SmallVector<ParseScope*, 4> TemplateParamScopeStack; // Get the list of DeclContexts to reenter. - SmallVector<DeclContext*, 4> DeclContextsToReenter; + SmallVector<DeclContext *, 4> 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<Decl>(*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<CXXRecordDecl>(*II) && isa<CXXRecordDecl>(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 6ea245c2d4e..301eacfabba 100644 --- a/clang/test/Parser/DelayedTemplateParsing.cpp +++ b/clang/test/Parser/DelayedTemplateParsing.cpp @@ -181,3 +181,20 @@ 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(); +} |