r293004 - Use filename in linemarker when compiling preprocessed source

David Callahan via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 24 17:55:29 PST 2017


Author: david2050
Date: Tue Jan 24 19:55:28 2017
New Revision: 293004

URL: http://llvm.org/viewvc/llvm-project?rev=293004&view=rev
Log:
Use filename in linemarker when compiling preprocessed source

Summary:
Clang appears to always use name as specified on the command
line, whereas gcc uses the name as specified in the linemarker at the
first line when compiling a preprocessed source. This results mismatch
between two compilers in FILE symbol table entry. This patch makes clang
to resemble gcc's behavior in finding the original source file name and
use it as an input file name.

Even with this patch, values of FILE symbol table entry may still be
different because clang uses dirname+basename for the entry whlie gcc
uses basename only. I'll write a patch for that once this patch is
committed.

Reviewers: dblaikie, inglorion

Reviewed By: inglorion

Subscribers: inglorion, aprantl, bruno

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

Added:
    cfe/trunk/test/Frontend/preprocessed-input.c
Modified:
    cfe/trunk/include/clang/Frontend/FrontendOptions.h
    cfe/trunk/lib/Frontend/FrontendAction.cpp

Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=293004&r1=293003&r2=293004&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Tue Jan 24 19:55:28 2017
@@ -81,7 +81,7 @@ enum InputKind {
   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 @@ public:
   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());

Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=293004&r1=293003&r2=293004&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp Tue Jan 24 19:55:28 2017
@@ -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 @@ FrontendAction::CreateWrappedASTConsumer
   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!");
@@ -335,6 +372,13 @@ bool FrontendAction::BeginSourceFile(Com
     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)
@@ -421,9 +465,9 @@ bool FrontendAction::BeginSourceFile(Com
 
   // 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);

Added: cfe/trunk/test/Frontend/preprocessed-input.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/preprocessed-input.c?rev=293004&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/preprocessed-input.c (added)
+++ cfe/trunk/test/Frontend/preprocessed-input.c Tue Jan 24 19:55:28 2017
@@ -0,0 +1,4 @@
+// RUN: %clang -E -o %t.i %s
+// RUN: %clang -Xclang -triple -Xclang i686-linux-gnu -c -o %t.o %t.i
+// RUN: llvm-objdump -t %t.o | FileCheck %s
+// CHECK: l{{ +}}df{{ +}}*ABS*{{ +}}{{0+}}{{.+}}preprocessed-input.c{{$}}




More information about the cfe-commits mailing list