]> granicus.if.org Git - clang/commitdiff
[MS] Push fewer DeclContexts for delayed template parsing
authorReid Kleckner <rnk@google.com>
Tue, 27 Nov 2018 02:21:51 +0000 (02:21 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 27 Nov 2018 02:21:51 +0000 (02:21 +0000)
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
test/Parser/DelayedTemplateParsing.cpp

index 26709a5aaa659c62eec6e015693378dc3a251507..55f80f231f3803926ec9f683a2b3392bc43d2a87 100644 (file)
@@ -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);
     }
index 6ea245c2d4e4260a44c7bd3fd20fc417bddebbae..301eacfabba3f75b28ae703dc16a8b7f9d02077f 100644 (file)
@@ -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();
+}