make -frewrite-includes also rewrite conditions in #if/#elif
authorLubos Lunak <l.lunak@centrum.cz>
Wed, 18 Sep 2019 19:09:41 +0000 (19:09 +0000)
committerLubos Lunak <l.lunak@centrum.cz>
Wed, 18 Sep 2019 19:09:41 +0000 (19:09 +0000)
Those conditions may use __has_include, which needs to be rewritten.
The existing code has already tried to rewrite just __has_include,
but it didn't work with macro expansion, so e.g. Qt's
"#define QT_HAS_INCLUDE(x) __has_include(x)" didn't get handled
properly. Since the preprocessor run knows what each condition evaluates
to, just rewrite the entire condition. This of course requires that
the -frewrite-include pass has the same setup as the following
compilation, but that has always been the requirement.

Differential Revision: https://reviews.llvm.org/D63508

llvm-svn: 372248

clang/lib/Frontend/Rewrite/InclusionRewriter.cpp
clang/test/Frontend/rewrite-includes-conditions.c [new file with mode: 0644]
clang/test/Frontend/rewrite-includes.c
clang/test/Modules/preprocess-module.cpp

index 984b638..dcf645f 100644 (file)
@@ -49,6 +49,8 @@ class InclusionRewriter : public PPCallbacks {
   std::map<unsigned, const Module *> ModuleIncludes;
   /// Tracks where inclusions that enter modules (in a module build) are found.
   std::map<unsigned, const Module *> ModuleEntryIncludes;
+  /// Tracks where #if and #elif directives get evaluated and whether to true.
+  std::map<unsigned, bool> IfConditions;
   /// Used transitively for building up the FileIncludes mapping over the
   /// various \c PPCallbacks callbacks.
   SourceLocation LastInclusionLocation;
@@ -78,6 +80,10 @@ private:
                           StringRef SearchPath, StringRef RelativePath,
                           const Module *Imported,
                           SrcMgr::CharacteristicKind FileType) override;
+  void If(SourceLocation Loc, SourceRange ConditionRange,
+          ConditionValueKind ConditionValue) override;
+  void Elif(SourceLocation Loc, SourceRange ConditionRange,
+            ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
   void WriteLineInfo(StringRef Filename, int Line,
                      SrcMgr::CharacteristicKind FileType,
                      StringRef Extra = StringRef());
@@ -89,12 +95,10 @@ private:
   void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken,
                            const MemoryBuffer &FromFile, StringRef EOL,
                            unsigned &NextToWrite, int &Lines);
-  bool HandleHasInclude(FileID FileId, Lexer &RawLex,
-                        const DirectoryLookup *Lookup, Token &Tok,
-                        bool &FileExists);
   const IncludedFile *FindIncludeAtLocation(SourceLocation Loc) const;
   const Module *FindModuleAtLocation(SourceLocation Loc) const;
   const Module *FindEnteredModule(SourceLocation Loc) const;
+  bool IsIfAtLocationTrue(SourceLocation Loc) const;
   StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken);
 };
 
@@ -203,6 +207,23 @@ void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
     LastInclusionLocation = HashLoc;
 }
 
+void InclusionRewriter::If(SourceLocation Loc, SourceRange ConditionRange,
+                           ConditionValueKind ConditionValue) {
+  auto P = IfConditions.insert(
+      std::make_pair(Loc.getRawEncoding(), ConditionValue == CVK_True));
+  (void)P;
+  assert(P.second && "Unexpected revisitation of the same if directive");
+}
+
+void InclusionRewriter::Elif(SourceLocation Loc, SourceRange ConditionRange,
+                             ConditionValueKind ConditionValue,
+                             SourceLocation IfLoc) {
+  auto P = IfConditions.insert(
+      std::make_pair(Loc.getRawEncoding(), ConditionValue == CVK_True));
+  (void)P;
+  assert(P.second && "Unexpected revisitation of the same elif directive");
+}
+
 /// Simple lookup for a SourceLocation (specifically one denoting the hash in
 /// an inclusion directive) in the map of inclusion information, FileChanges.
 const InclusionRewriter::IncludedFile *
@@ -233,6 +254,13 @@ InclusionRewriter::FindEnteredModule(SourceLocation Loc) const {
   return nullptr;
 }
 
+bool InclusionRewriter::IsIfAtLocationTrue(SourceLocation Loc) const {
+  const auto I = IfConditions.find(Loc.getRawEncoding());
+  if (I != IfConditions.end())
+    return I->second;
+  return false;
+}
+
 /// Detect the likely line ending style of \p FromFile by examining the first
 /// newline found within it.
 static StringRef DetectEOL(const MemoryBuffer &FromFile) {
@@ -346,80 +374,6 @@ StringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex,
   return StringRef();
 }
 
-// Expand __has_include and __has_include_next if possible. If there's no
-// definitive answer return false.
-bool InclusionRewriter::HandleHasInclude(
-    FileID FileId, Lexer &RawLex, const DirectoryLookup *Lookup, Token &Tok,
-    bool &FileExists) {
-  // Lex the opening paren.
-  RawLex.LexFromRawLexer(Tok);
-  if (Tok.isNot(tok::l_paren))
-    return false;
-
-  RawLex.LexFromRawLexer(Tok);
-
-  SmallString<128> FilenameBuffer;
-  StringRef Filename;
-  // Since the raw lexer doesn't give us angle_literals we have to parse them
-  // ourselves.
-  // FIXME: What to do if the file name is a macro?
-  if (Tok.is(tok::less)) {
-    RawLex.LexFromRawLexer(Tok);
-
-    FilenameBuffer += '<';
-    do {
-      if (Tok.is(tok::eod)) // Sanity check.
-        return false;
-
-      if (Tok.is(tok::raw_identifier))
-        PP.LookUpIdentifierInfo(Tok);
-
-      // Get the string piece.
-      SmallVector<char, 128> TmpBuffer;
-      bool Invalid = false;
-      StringRef TmpName = PP.getSpelling(Tok, TmpBuffer, &Invalid);
-      if (Invalid)
-        return false;
-
-      FilenameBuffer += TmpName;
-
-      RawLex.LexFromRawLexer(Tok);
-    } while (Tok.isNot(tok::greater));
-
-    FilenameBuffer += '>';
-    Filename = FilenameBuffer;
-  } else {
-    if (Tok.isNot(tok::string_literal))
-      return false;
-
-    bool Invalid = false;
-    Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
-    if (Invalid)
-      return false;
-  }
-
-  // Lex the closing paren.
-  RawLex.LexFromRawLexer(Tok);
-  if (Tok.isNot(tok::r_paren))
-    return false;
-
-  // Now ask HeaderInfo if it knows about the header.
-  // FIXME: Subframeworks aren't handled here. Do we care?
-  bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename);
-  const DirectoryLookup *CurDir;
-  const FileEntry *FileEnt = PP.getSourceManager().getFileEntryForID(FileId);
-  SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 1>
-      Includers;
-  Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir()));
-  // FIXME: Why don't we call PP.LookupFile here?
-  Optional<FileEntryRef> File = PP.getHeaderSearchInfo().LookupFile(
-      Filename, SourceLocation(), isAngled, Lookup, CurDir, Includers, nullptr,
-      nullptr, nullptr, nullptr, nullptr, nullptr);
-
-  FileExists = File.hasValue();
-  return true;
-}
-
 /// Use a raw lexer to analyze \p FileId, incrementally copying parts of it
 /// and including content of included files recursively.
 void InclusionRewriter::Process(FileID FileId,
@@ -519,53 +473,33 @@ void InclusionRewriter::Process(FileID FileId,
           case tok::pp_elif: {
             bool elif = (RawToken.getIdentifierInfo()->getPPKeywordID() ==
                          tok::pp_elif);
-            // Rewrite special builtin macros to avoid pulling in host details.
+            bool isTrue = IsIfAtLocationTrue(RawToken.getLocation());
+            OutputContentUpTo(FromFile, NextToWrite,
+                              SM.getFileOffset(HashToken.getLocation()),
+                              LocalEOL, Line, /*EnsureNewline=*/true);
             do {
-              // Walk over the directive.
               RawLex.LexFromRawLexer(RawToken);
-              if (RawToken.is(tok::raw_identifier))
-                PP.LookUpIdentifierInfo(RawToken);
-
-              if (RawToken.is(tok::identifier)) {
-                bool HasFile;
-                SourceLocation Loc = RawToken.getLocation();
-
-                // Rewrite __has_include(x)
-                if (RawToken.getIdentifierInfo()->isStr("__has_include")) {
-                  if (!HandleHasInclude(FileId, RawLex, nullptr, RawToken,
-                                        HasFile))
-                    continue;
-                  // Rewrite __has_include_next(x)
-                } else if (RawToken.getIdentifierInfo()->isStr(
-                               "__has_include_next")) {
-                  if (DirLookup)
-                    ++DirLookup;
-
-                  if (!HandleHasInclude(FileId, RawLex, DirLookup, RawToken,
-                                        HasFile))
-                    continue;
-                } else {
-                  continue;
-                }
-                // Replace the macro with (0) or (1), followed by the commented
-                // out macro for reference.
-                OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(Loc),
-                                  LocalEOL, Line, false);
-                OS << '(' << (int) HasFile << ")/*";
-                OutputContentUpTo(FromFile, NextToWrite,
-                                  SM.getFileOffset(RawToken.getLocation()) +
-                                      RawToken.getLength(),
-                                  LocalEOL, Line, false);
-                OS << "*/";
-              }
-            } while (RawToken.isNot(tok::eod));
+            } while (!RawToken.is(tok::eod) && RawToken.isNot(tok::eof));
+            // We need to disable the old condition, but that is tricky.
+            // Trying to comment it out can easily lead to comment nesting.
+            // So instead make the condition harmless by making it enclose
+            // and empty block. Moreover, put it itself inside an #if 0 block
+            // to disable it from getting evaluated (e.g. __has_include_next
+            // warns if used from the primary source file).
+            OS << "#if 0 /* disabled by -frewrite-includes */" << MainEOL;
             if (elif) {
-              OutputContentUpTo(FromFile, NextToWrite,
-                                SM.getFileOffset(RawToken.getLocation()) +
-                                    RawToken.getLength(),
-                                LocalEOL, Line, /*EnsureNewline=*/ true);
-              WriteLineInfo(FileName, Line, FileType);
+              OS << "#if 0" << MainEOL;
             }
+            OutputContentUpTo(FromFile, NextToWrite,
+                              SM.getFileOffset(RawToken.getLocation()) +
+                                  RawToken.getLength(),
+                              LocalEOL, Line, /*EnsureNewline=*/true);
+            // Close the empty block and the disabling block.
+            OS << "#endif" << MainEOL;
+            OS << "#endif /* disabled by -frewrite-includes */" << MainEOL;
+            OS << (elif ? "#elif " : "#if ") << (isTrue ? "1" : "0")
+               << " /* evaluated by -frewrite-includes */" << MainEOL;
+            WriteLineInfo(FileName, Line, FileType);
             break;
           }
           case tok::pp_endif:
diff --git a/clang/test/Frontend/rewrite-includes-conditions.c b/clang/test/Frontend/rewrite-includes-conditions.c
new file mode 100644 (file)
index 0000000..ec05805
--- /dev/null
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -verify -E -frewrite-includes -I %S/Inputs %s -o - | FileCheck -strict-whitespace %s
+// expected-no-diagnostics
+
+#define value1 1
+#if value1
+line1
+#else
+line2
+#endif
+
+#define value2 2
+
+#if value1 == value2
+line3
+#elif value1 > value2
+line4
+#elif value1 < value2
+line5
+#else
+line6
+#endif
+
+#if __has_include(<rewrite-includes1.h>)
+#endif
+
+#define HAS_INCLUDE(x) __has_include(x)
+
+#if HAS_INCLUDE(<rewrite-includes1.h>)
+#endif
+
+/*
+#if value1
+commented out
+*/
+
+#if value1 < value2 \
+|| value1 != value2
+line7
+#endif
+
+#if value1 /*
+*/
+#endif
+
+// ENDCOMPARE
+
+// CHECK: #if 0 /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if value1
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #endif /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if 1 /* evaluated by -frewrite-includes */
+// CHECK-NEXT: # 6 "{{.*}}rewrite-includes-conditions.c"
+
+// CHECK: #if 0 /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if value1 == value2
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #endif /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if 0 /* evaluated by -frewrite-includes */
+// CHECK-NEXT: # 14 "{{.*}}rewrite-includes-conditions.c"
+
+// CHECK: #if 0 /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if 0
+// CHECK-NEXT: #elif value1 > value2
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #endif /* disabled by -frewrite-includes */
+// CHECK-NEXT: #elif 0 /* evaluated by -frewrite-includes */
+// CHECK-NEXT: # 16 "{{.*}}rewrite-includes-conditions.c"
+
+// CHECK: #if 0 /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if 0
+// CHECK-NEXT: #elif value1 < value2
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #endif /* disabled by -frewrite-includes */
+// CHECK-NEXT: #elif 1 /* evaluated by -frewrite-includes */
+// CHECK-NEXT: # 18 "{{.*}}rewrite-includes-conditions.c"
+
+// CHECK: #if 0 /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if __has_include(<rewrite-includes1.h>)
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #endif /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if 1 /* evaluated by -frewrite-includes */
+// CHECK-NEXT: # 24 "{{.*}}rewrite-includes-conditions.c"
+
+// CHECK: #if 0 /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if HAS_INCLUDE(<rewrite-includes1.h>)
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #endif /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if 1 /* evaluated by -frewrite-includes */
+// CHECK-NEXT: # 29 "{{.*}}rewrite-includes-conditions.c"
+
+// CHECK: #if 0 /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if value1 < value2 \
+// CHECK-NEXT: || value1 != value2
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #endif /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if 1 /* evaluated by -frewrite-includes */
+// CHECK-NEXT: # 38 "{{.*}}rewrite-includes-conditions.c"
+
+// CHECK: #if 0 /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if value1 /*
+// CHECK-NEXT: */
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #endif /* disabled by -frewrite-includes */
+// CHECK-NEXT: #if 1 /* evaluated by -frewrite-includes */
+// CHECK-NEXT: # 43 "{{.*}}rewrite-includes-conditions.c"
+
+// CHECK: {{^}}// ENDCOMPARE{{$}}
index 630e761..ec8c413 100644 (file)
@@ -110,12 +110,27 @@ A(1,2)
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}# 22 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h" 1{{$}}
-// CHECK-NEXT: {{^}}#if (0)/*__has_include_next(<rewrite-includes8.h>)*/{{$}}
-// CHECK-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* disabled by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#if __has_include_next(<rewrite-includes8.h>){{$}}
+// CHECK-NEXT: {{^}}#endif{{$}}
+// CHECK-NEXT: {{^}}#endif /* disabled by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* evaluated by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 2 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h"{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* disabled by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#if 0{{$}}
+// CHECK-NEXT: {{^}}#elif __has_include(<rewrite-includes8.hfail>){{$}}
+// CHECK-NEXT: {{^}}#endif{{$}}
+// CHECK-NEXT: {{^}}#endif /* disabled by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#elif 0 /* evaluated by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}# 3 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h"{{$}}
 // CHECK-NEXT: {{^}}#endif{{$}}
 // CHECK-NEXT: {{^}}# 4 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h"{{$}}
-// CHECK-NEXT: {{^}}#if !(1)/*__has_include("rewrite-includes8.h")*/{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* disabled by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#if !__has_include("rewrite-includes8.h"){{$}}
+// CHECK-NEXT: {{^}}#endif{{$}}
+// CHECK-NEXT: {{^}}#endif /* disabled by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* evaluated by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 5 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h"{{$}}
 // CHECK-NEXT: {{^}}#endif{{$}}
 // CHECK-NEXT: {{^}}# 6 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h"{{$}}
 // CHECK-NEXT: {{^}}# 23 "{{.*}}rewrite-includes.c" 2{{$}}
@@ -124,7 +139,12 @@ A(1,2)
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}# 23 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes9.h" 1{{$}}
-// CHECK-NEXT: {{^}}#if (1)/*__has_include_next(<rewrite-includes9.h>)*/{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* disabled by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#if __has_include_next(<rewrite-includes9.h>){{$}}
+// CHECK-NEXT: {{^}}#endif{{$}}
+// CHECK-NEXT: {{^}}#endif /* disabled by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#if 1 /* evaluated by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 2 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes9.h"{{$}}
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include_next <rewrite-includes9.h>{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
@@ -193,15 +213,32 @@ A(1,2)
 // CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECKNL-NEXT: {{^}}#include "rewrite-includes8.h"{{$}}
 // CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
-// CHECKNL-NEXT: {{^}}#if (0)/*__has_include_next(<rewrite-includes8.h>)*/{{$}}
-// CHECKNL-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}}
+// CHECKNL-NEXT: {{^}}#if 0 /* disabled by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if __has_include_next(<rewrite-includes8.h>){{$}}
 // CHECKNL-NEXT: {{^}}#endif{{$}}
-// CHECKNL-NEXT: {{^}}#if !(1)/*__has_include("rewrite-includes8.h")*/{{$}}
+// CHECKNL-NEXT: {{^}}#endif /* disabled by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if 0 /* evaluated by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if 0 /* disabled by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if 0{{$}}
+// CHECKNL-NEXT: {{^}}#elif __has_include(<rewrite-includes8.hfail>){{$}}
+// CHECKNL-NEXT: {{^}}#endif{{$}}
+// CHECKNL-NEXT: {{^}}#endif /* disabled by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#elif 0 /* evaluated by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#endif{{$}}
+// CHECKNL-NEXT: {{^}}#if 0 /* disabled by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if !__has_include("rewrite-includes8.h"){{$}}
+// CHECKNL-NEXT: {{^}}#endif{{$}}
+// CHECKNL-NEXT: {{^}}#endif /* disabled by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if 0 /* evaluated by -frewrite-includes */{{$}}
 // CHECKNL-NEXT: {{^}}#endif{{$}}
 // CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECKNL-NEXT: {{^}}#include "rewrite-includes9.h"{{$}}
 // CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
-// CHECKNL-NEXT: {{^}}#if (1)/*__has_include_next(<rewrite-includes9.h>)*/{{$}}
+// CHECKNL-NEXT: {{^}}#if 0 /* disabled by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if __has_include_next(<rewrite-includes9.h>){{$}}
+// CHECKNL-NEXT: {{^}}#endif{{$}}
+// CHECKNL-NEXT: {{^}}#endif /* disabled by -frewrite-includes */{{$}}
+// CHECKNL-NEXT: {{^}}#if 1 /* evaluated by -frewrite-includes */{{$}}
 // CHECKNL-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECKNL-NEXT: {{^}}#include_next <rewrite-includes9.h>{{$}}
 // CHECKNL-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
index b0cbac1..ee909a8 100644 (file)
@@ -51,7 +51,7 @@
 // RUN: %clang_cc1 -fmodules -fmodule-file=%t/file.rewrite.pcm %s -I%t -verify -fno-modules-error-recovery -DFILE_REWRITE -DINCLUDE -I%S/Inputs/preprocess
 //
 // Check that we can preprocess this user of the .pcm file.
-// RUN: %clang_cc1 -fmodules -fmodule-file=%t/file.pcm %s -I%t -E -frewrite-imports -o %t/preprocess-module.ii
+// RUN: %clang_cc1 -fmodules -fmodule-file=%t/file.pcm %s -I%t -E -frewrite-imports -DFILE_REWRITE_FULL -o %t/preprocess-module.ii
 // RUN: %clang_cc1 -fmodules %t/preprocess-module.ii -verify -fno-modules-error-recovery -DFILE_REWRITE_FULL
 //
 // Check that language / header search options are ignored when preprocessing from a .pcm file.