From f664d369841a1a625fca39ecda7abb78d9bef4b1 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <v.g.vassilev@gmail.com>
Date: Fri, 3 May 2019 18:38:18 +0300
Subject: [PATCH] [cling] Support recursive lookup helper calls.

The implementation of class->library mapping makes a call to the
LookupHelper::findScope. This makes the recursive invocations to
LookupHelper::findScope -> ... -> LookupHelper::findScope happen more often.
---
 .../cling/include/cling/Interpreter/LookupHelper.h |  2 ++
 .../cling/include/cling/Utils/ParserStateRAII.h    |  1 +
 interpreter/cling/lib/Interpreter/LookupHelper.cpp | 14 +++++++++-----
 interpreter/cling/lib/Utils/ParserStateRAII.cpp    |  4 +++-
 4 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/interpreter/cling/include/cling/Interpreter/LookupHelper.h b/interpreter/cling/include/cling/Interpreter/LookupHelper.h
index 5c344223c66..8d44500af1a 100644
--- a/interpreter/cling/include/cling/Interpreter/LookupHelper.h
+++ b/interpreter/cling/include/cling/Interpreter/LookupHelper.h
@@ -71,6 +71,8 @@ namespace cling {
     unsigned m_CacheHits = 0;
     /// Number of times we missed the cache.
     unsigned m_TotalParseRequests = 0;
+    /// If we are called recursively.
+    bool IsRecursivelyRunning = false;
 
   public:
     LookupHelper(clang::Parser* P, Interpreter* interp);
diff --git a/interpreter/cling/include/cling/Utils/ParserStateRAII.h b/interpreter/cling/include/cling/Utils/ParserStateRAII.h
index 11d37f6a6e3..8ecb1a5a28b 100644
--- a/interpreter/cling/include/cling/Utils/ParserStateRAII.h
+++ b/interpreter/cling/include/cling/Utils/ParserStateRAII.h
@@ -36,6 +36,7 @@ namespace cling {
     bool OldSuppressAllDiagnostics;
     bool OldPPSuppressAllDiagnostics;
     bool OldSpellChecking;
+    clang::Token OldTok;
     clang::SourceLocation OldPrevTokLocation;
     unsigned short OldParenCount, OldBracketCount, OldBraceCount;
     unsigned OldTemplateParameterDepth;
diff --git a/interpreter/cling/lib/Interpreter/LookupHelper.cpp b/interpreter/cling/lib/Interpreter/LookupHelper.cpp
index 2f27e5d9ac0..794d6532052 100644
--- a/interpreter/cling/lib/Interpreter/LookupHelper.cpp
+++ b/interpreter/cling/lib/Interpreter/LookupHelper.cpp
@@ -37,17 +37,20 @@ namespace cling {
 
   class StartParsingRAII {
     LookupHelper& m_LH;
+    llvm::SaveAndRestore<bool> SaveIsRecursivelyRunning;
     ParserStateRAII ResetParserState;
-
     void prepareForParsing(llvm::StringRef code, llvm::StringRef bufferName,
                            LookupHelper::DiagSetting diagOnOff);
   public:
     StartParsingRAII(LookupHelper& LH, llvm::StringRef code,
                      llvm::StringRef bufferName,
                      LookupHelper::DiagSetting diagOnOff)
-      : m_LH(LH), ResetParserState(*LH.m_Parser.get(), true /*skipToEOF*/) {
-    prepareForParsing(code, bufferName, diagOnOff);
-  }
+        : m_LH(LH), SaveIsRecursivelyRunning(LH.IsRecursivelyRunning),
+          ResetParserState(*LH.m_Parser.get(),
+                           !LH.IsRecursivelyRunning /*skipToEOF*/) {
+      LH.IsRecursivelyRunning = true;
+      prepareForParsing(code, bufferName, diagOnOff);
+    }
 
     ~StartParsingRAII() { pop(); }
     void pop() const {}
@@ -84,7 +87,8 @@ namespace cling {
     if (!PP.isIncrementalProcessingEnabled()) {
       PP.enableIncrementalProcessing();
     }
-    assert(!code.empty()&&"prepareForParsing should only be called when needd");
+    assert(!code.empty() &&
+           "prepareForParsing should only be called when need");
 
     // Create a fake file to parse the type name.
     FileID FID;
diff --git a/interpreter/cling/lib/Utils/ParserStateRAII.cpp b/interpreter/cling/lib/Utils/ParserStateRAII.cpp
index 8c7df78c438..2f4c9326c7f 100644
--- a/interpreter/cling/lib/Utils/ParserStateRAII.cpp
+++ b/interpreter/cling/lib/Utils/ParserStateRAII.cpp
@@ -24,7 +24,7 @@ cling::ParserStateRAII::ParserStateRAII(Parser& p, bool skipToEOF)
     OldPPSuppressAllDiagnostics(p.getPreprocessor().getDiagnostics()
                                 .getSuppressAllDiagnostics()),
     OldSpellChecking(p.getPreprocessor().getLangOpts().SpellChecking),
-  OldPrevTokLocation(p.PrevTokLocation),
+  OldTok(p.Tok), OldPrevTokLocation(p.PrevTokLocation),
   OldParenCount(p.ParenCount), OldBracketCount(p.BracketCount),
   OldBraceCount(p.BraceCount),
   OldTemplateParameterDepth(p.TemplateParameterDepth),
@@ -54,6 +54,8 @@ cling::ParserStateRAII::~ParserStateRAII() {
   P->TemplateIds.swap(OldTemplateIds);
   if (SkipToEOF)
     P->SkipUntil(tok::eof);
+  else
+    P->Tok = OldTok;
   PP.enableIncrementalProcessing(ResetIncrementalProcessing);
   if (!SemaDiagHadErrors) {
     // Doesn't reset the diagnostic mappings
-- 
GitLab