This revision was automatically updated to reflect the committed changes.
Closed by commit rL297194: Use filename in linemarker when compiling 
preprocessed source (Revised) (authored by twoh).

Changed prior to commit:
  https://reviews.llvm.org/D30663?vs=90735&id=90912#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D30663

Files:
  cfe/trunk/include/clang/Frontend/FrontendOptions.h
  cfe/trunk/lib/Frontend/FrontendAction.cpp
  cfe/trunk/test/Frontend/preprocessed-input.i

Index: cfe/trunk/include/clang/Frontend/FrontendOptions.h
===================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h
@@ -81,7 +81,7 @@
   IK_LLVM_IR
 };
 
-  
+
 /// \brief An input file for the front end.
 class FrontendInputFile {
   /// \brief The file name, or "-" to read from standard input.
@@ -109,6 +109,13 @@
   bool isEmpty() const { return File.empty() && Buffer == nullptr; }
   bool isFile() const { return !isBuffer(); }
   bool isBuffer() const { return Buffer != nullptr; }
+  bool isPreprocessed() const {
+    return Kind == IK_PreprocessedC ||
+           Kind == IK_PreprocessedCXX ||
+           Kind == IK_PreprocessedObjC ||
+           Kind == IK_PreprocessedObjCXX ||
+           Kind == IK_PreprocessedCuda;
+  }
 
   StringRef getFile() const {
     assert(isFile());
Index: cfe/trunk/test/Frontend/preprocessed-input.i
===================================================================
--- cfe/trunk/test/Frontend/preprocessed-input.i
+++ cfe/trunk/test/Frontend/preprocessed-input.i
@@ -0,0 +1,10 @@
+# 1 "preprocessed-input.c"
+# 1 "<built-in>" 1
+# 1 "<built-in>" 3
+# 318 "<built-in>" 3
+# 1 "<command line>" 1
+# 1 "<built-in>" 2
+# 1 "preprocessed-input.c" 2
+
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+// CHECK: source_filename = "preprocessed-input.c"{{$}}
Index: cfe/trunk/lib/Frontend/FrontendAction.cpp
===================================================================
--- cfe/trunk/lib/Frontend/FrontendAction.cpp
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp
@@ -19,6 +19,7 @@
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/LiteralSupport.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Parse/ParseAST.h"
@@ -187,6 +188,42 @@
   return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
 }
 
+// For preprocessed files, if the first line is the linemarker and specifies
+// the original source file name, use that name as the input file name.
+static bool ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile)
+{
+  bool Invalid = false;
+  auto &SourceMgr = CI.getSourceManager();
+  auto MainFileID = SourceMgr.getMainFileID();
+  const auto *MainFileBuf = SourceMgr.getBuffer(MainFileID, &Invalid);
+  if (Invalid)
+    return false;
+
+  std::unique_ptr<Lexer> RawLexer(
+      new Lexer(MainFileID, MainFileBuf, SourceMgr, CI.getLangOpts()));
+
+  // If the first line has the syntax of
+  //
+  // # NUM "FILENAME"
+  //
+  // we use FILENAME as the input file name.
+  Token T;
+  if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
+    return false;
+  if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
+      T.getKind() != tok::numeric_constant)
+    return false;
+  RawLexer->LexFromRawLexer(T);
+  if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
+    return false;
+
+  StringLiteralParser Literal(T, CI.getPreprocessor());
+  if (Literal.hadError)
+    return false;
+  InputFile = Literal.GetString().str();
+  return true;
+}
+
 bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                      const FrontendInputFile &Input) {
   assert(!Instance && "Already processing a source file!");
@@ -338,6 +375,13 @@
     if (!isModelParsingAction())
       CI.createASTContext();
 
+    // For preprocessed files, check if the first line specifies the original
+    // source file name with a linemarker.
+    std::string OrigFile;
+    if (Input.isPreprocessed())
+      if (ReadOriginalFileName(CI, OrigFile))
+        InputFile = OrigFile;
+
     std::unique_ptr<ASTConsumer> Consumer =
         CreateWrappedASTConsumer(CI, InputFile);
     if (!Consumer)
@@ -430,9 +474,9 @@
 
   // If there is a layout overrides file, attach an external AST source that
   // provides the layouts from that file.
-  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 
+  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
       CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
-    IntrusiveRefCntPtr<ExternalASTSource> 
+    IntrusiveRefCntPtr<ExternalASTSource>
       Override(new LayoutOverrideSource(
                      CI.getFrontendOpts().OverrideRecordLayoutsFile));
     CI.getASTContext().setExternalSource(Override);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to