]> granicus.if.org Git - clang/commitdiff
From Vassil Vassilev:
authorAxel Naumann <Axel.Naumann@cern.ch>
Fri, 16 Mar 2012 10:40:17 +0000 (10:40 +0000)
committerAxel Naumann <Axel.Naumann@cern.ch>
Fri, 16 Mar 2012 10:40:17 +0000 (10:40 +0000)
Enable incremental parsing by the Preprocessor,
where more code can be provided after an EOF.
It mainly prevents the tearing down of the topmost lexer.
To be used like this:
PP.enableIncrementalProcessing();
while (getMoreSource()) {
  while (Parser.ParseTopLevelDecl(ADecl)) {...}
}
PP.enableIncrementalProcessing(false);

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152914 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/Preprocessor.h
lib/Lex/PPLexerChange.cpp
lib/Lex/Preprocessor.cpp
lib/Parse/Parser.cpp

index 508c168f998fd7981680a9b54105bb0bded3e2ec..2abf74ed0a0936b4c9c2c4f59ecc3d24c213ddb9 100644 (file)
@@ -148,6 +148,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
   /// with this preprocessor.
   std::vector<CommentHandler *> CommentHandlers;
 
+  /// \brief True if we want to ignore EOF token and continue later on (thus 
+  /// avoid tearing the Lexer and etc. down).
+  bool IncrementalProcessing;
+
   /// \brief The code-completion handler.
   CodeCompletionHandler *CodeComplete;
 
@@ -344,7 +348,8 @@ public:
                ModuleLoader &TheModuleLoader,
                IdentifierInfoLookup *IILookup = 0,
                bool OwnsHeaderSearch = false,
-               bool DelayInitialization = false);
+               bool DelayInitialization = false,
+               bool IncrProcessing = false);
 
   ~Preprocessor();
 
@@ -691,6 +696,14 @@ public:
   /// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
   /// CurTokenLexer pointers.
   void recomputeCurLexerKind();
+
+  /// \brief Returns true if incremental processing is enabled
+  bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
+
+  /// \brief Enables the incremental processing
+  void enableIncrementalProcessing(bool value = true) {
+    IncrementalProcessing = value;
+  }
   
   /// \brief Specify the point at which code-completion will be performed.
   ///
index 3056e0c41a0608638f47b3c28d22421c9fa0668c..b6689df18684788a661884b94287c8364fc7878b 100644 (file)
@@ -328,15 +328,17 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
     CurLexer->BufferPtr = EndPos;
     CurLexer->FormTokenWithChars(Result, EndPos, tok::eof);
 
-    // We're done with the #included file.
-    CurLexer.reset();
+    if (!isIncrementalProcessingEnabled())
+      // We're done with lexing.
+      CurLexer.reset();
   } else {
     assert(CurPTHLexer && "Got EOF but no current lexer set!");
     CurPTHLexer->getEOF(Result);
     CurPTHLexer.reset();
   }
-
-  CurPPLexer = 0;
+  
+  if (!isIncrementalProcessingEnabled())
+    CurPPLexer = 0;
 
   // This is the end of the top-level file. 'WarnUnusedMacroLocs' has collected
   // all macro locations that we need to warn because they are not used.
index 6142436e6d194e03cb50ace76c1ab6942decabb6..f7f63ee01fbf3a767dbf6a2dbadc6f284f3c475e 100644 (file)
@@ -54,18 +54,19 @@ Preprocessor::Preprocessor(DiagnosticsEngine &diags, LangOptions &opts,
                            HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
                            IdentifierInfoLookup* IILookup,
                            bool OwnsHeaders,
-                           bool DelayInitialization)
+                           bool DelayInitialization,
+                           bool IncrProcessing)
   : Diags(&diags), LangOpts(opts), Target(target),FileMgr(Headers.getFileMgr()),
     SourceMgr(SM), HeaderInfo(Headers), TheModuleLoader(TheModuleLoader),
-    ExternalSource(0), 
-    Identifiers(opts, IILookup), CodeComplete(0),
+    ExternalSource(0), Identifiers(opts, IILookup), 
+    IncrementalProcessing(IncrProcessing), CodeComplete(0), 
     CodeCompletionFile(0), CodeCompletionOffset(0), CodeCompletionReached(0),
     SkipMainFilePreamble(0, true), CurPPLexer(0), 
     CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0), MacroArgCache(0), 
     Record(0), MIChainHead(0), MICache(0) 
 {
   OwnsHeaderSearch = OwnsHeaders;
-  
+
   if (!DelayInitialization) {
     assert(Target && "Must provide target information for PP initialization");
     Initialize(*Target);
index 9613ad0f85387ab5f493e5e815dad3963329943c..dd339f53948b4d650a5ccd290d12af5e423920d3 100644 (file)
@@ -475,6 +475,11 @@ void Parser::Initialize() {
 bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
   DelayedCleanupPoint CleanupRAII(TopLevelDeclCleanupPool);
 
+  // Skip over the EOF token, flagging end of previous input for incremental 
+  // processing
+  if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))
+    ConsumeToken();
+
   while (Tok.is(tok::annot_pragma_unused))
     HandlePragmaUnused();
 
@@ -483,15 +488,17 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
     // Late template parsing can begin.
     if (getLangOpts().DelayedTemplateParsing)
       Actions.SetLateTemplateParser(LateTemplateParserCallback, this);
+    if (!PP.isIncrementalProcessingEnabled())
+      Actions.ActOnEndOfTranslationUnit();
+    //else don't tell Sema that we ended parsing: more input might come.
 
-    Actions.ActOnEndOfTranslationUnit();
     return true;
   }
 
   ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX0XAttributes(attrs);
   MaybeParseMicrosoftAttributes(attrs);
-  
+
   Result = ParseExternalDeclaration(attrs);
   return false;
 }