]> granicus.if.org Git - clang/commitdiff
Entering the main source file in the preprocessor can fail if the
authorDouglas Gregor <dgregor@apple.com>
Wed, 17 Mar 2010 15:44:30 +0000 (15:44 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 17 Mar 2010 15:44:30 +0000 (15:44 +0000)
source file has been changed. Handle that failure more gracefully.

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

include/clang/Lex/Preprocessor.h
lib/Frontend/CacheTokens.cpp
lib/Frontend/FrontendActions.cpp
lib/Frontend/PrintPreprocessedOutput.cpp
lib/Frontend/RewriteMacros.cpp
lib/Lex/Preprocessor.cpp
lib/Sema/ParseAST.cpp
test/Misc/changed-files.c [new file with mode: 0644]

index 3ef1fcdbda38a12f3d00a283242d8a99b476c98b..a4910f714fdcd1bf318b596efbfc79ca39d3e861 100644 (file)
@@ -350,7 +350,7 @@ public:
 
   /// EnterMainSourceFile - Enter the specified FileID as the main source file,
   /// which implicitly adds the builtin defines etc.
-  void EnterMainSourceFile();
+  bool EnterMainSourceFile();
 
   /// EnterSourceFile - Add a source file to the top of the include stack and
   /// start lexing tokens from it instead of the current buffer.  Return true
index 02d6cec8fcab37228b871cf0b8053cdb138d2cdc..199be3d543839df7d6c7500c6cbc157f22d89928 100644 (file)
@@ -549,7 +549,8 @@ void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) {
   // Lex through the entire file.  This will populate SourceManager with
   // all of the header information.
   Token Tok;
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
   do { PP.Lex(Tok); } while (Tok.isNot(tok::eof));
 
   // Generate the PTH file.
index 1e210b42e6d16dc3d1b422ac23ec075e86b461f7..1077f9eb3415ba301c2c88b536b80732622caec1 100644 (file)
@@ -185,7 +185,8 @@ void DumpTokensAction::ExecuteAction() {
   Preprocessor &PP = getCompilerInstance().getPreprocessor();
   // Start preprocessing the specified input file.
   Token Tok;
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
   do {
     PP.Lex(Tok);
     PP.DumpToken(Tok, true);
@@ -213,7 +214,8 @@ void ParseOnlyAction::ExecuteAction() {
   llvm::OwningPtr<Action> PA(new MinimalAction(PP));
 
   Parser P(PP, *PA);
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
   P.ParseTranslationUnit();
 }
 
@@ -222,7 +224,8 @@ void PreprocessOnlyAction::ExecuteAction() {
 
   Token Tok;
   // Start parsing the specified input file.
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
   do {
     PP.Lex(Tok);
   } while (Tok.isNot(tok::eof));
@@ -237,7 +240,8 @@ void PrintParseAction::ExecuteAction() {
   llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS));
 
   Parser P(PP, *PA);
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
   P.ParseTranslationUnit();
 }
 
index 44e0e139060476b6b1203e92c925c8bf70f274ab..02afd24c246edd028ce46c908c9a76784c16920c 100644 (file)
@@ -448,7 +448,8 @@ static int MacroIDCompare(const void* a, const void* b) {
 static void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
   // -dM mode just scans and ignores all tokens in the files, then dumps out
   // the macro table at the end.
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
 
   Token Tok;
   do PP.Lex(Tok);
@@ -495,7 +496,8 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
   PP.addPPCallbacks(Callbacks);
 
   // After we have configured the preprocessor, enter the main file.
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
 
   // Consume all of the tokens that come from the predefines buffer.  Those
   // should not be emitted into the output and are guaranteed to be at the
index 954e8e23cac79728c1a0805767df235e774d75b3..4ffb2978db7a334203b192f0ebe2a9442312e244 100644 (file)
@@ -101,7 +101,8 @@ void clang::RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream *OS) {
 
 
   // Get the first preprocessing token.
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
   Token PPTok;
   PP.Lex(PPTok);
 
index a86799aafae41f4fbe01e009b14a4d97689a7534..917a2e7412ffee42bb339de0ca29104dc438872f 100644 (file)
@@ -488,7 +488,7 @@ SourceLocation Preprocessor::getLocForEndOfToken(SourceLocation Loc,
 
 /// EnterMainSourceFile - Enter the specified FileID as the main source file,
 /// which implicitly adds the builtin defines etc.
-void Preprocessor::EnterMainSourceFile() {
+bool Preprocessor::EnterMainSourceFile() {
   // We do not allow the preprocessor to reenter the main file.  Doing so will
   // cause FileID's to accumulate information from both runs (e.g. #line
   // information) and predefined macros aren't guaranteed to be set properly.
@@ -497,8 +497,8 @@ void Preprocessor::EnterMainSourceFile() {
 
   // Enter the main file source buffer.
   std::string ErrorStr;
-  bool Res = EnterSourceFile(MainFileID, 0, ErrorStr);
-  assert(!Res && "Entering main file should not fail!");
+  if (EnterSourceFile(MainFileID, 0, ErrorStr))
+    return true;
 
   // Tell the header info that the main file was entered.  If the file is later
   // #imported, it won't be re-entered.
@@ -515,8 +515,7 @@ void Preprocessor::EnterMainSourceFile() {
   assert(!FID.isInvalid() && "Could not create FileID for predefines?");
 
   // Start parsing the predefines.
-  Res = EnterSourceFile(FID, 0, ErrorStr);
-  assert(!Res && "Entering predefines should not fail!");
+  return EnterSourceFile(FID, 0, ErrorStr);
 }
 
 
index 898b3c230e873ca1a4ba26c962abf875c3462289..7cd39895f6fde9d3b2c9ce4e321f809d325afaa4 100644 (file)
@@ -44,7 +44,8 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
 
   Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer);
   Parser P(PP, S);
-  PP.EnterMainSourceFile();
+  if (PP.EnterMainSourceFile())
+    return;
 
   // Initialize the parser.
   P.Initialize();
diff --git a/test/Misc/changed-files.c b/test/Misc/changed-files.c
new file mode 100644 (file)
index 0000000..deeb02a
--- /dev/null
@@ -0,0 +1,3 @@
+// RUN: touch %t.c
+// RUN: not %clang -E %t.c -o %t.c 2> %t.stderr
+// RUN: grep "modified" %t.stderr