r347713 - [MS] Push outermost class DeclContexts only in -fdelayed-template-parsing

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 27 13:20:43 PST 2018


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>;




More information about the cfe-commits mailing list