r297194 - Use filename in linemarker when compiling preprocessed source (Revised)
Taewook Oh via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 7 12:20:23 PST 2017
Author: twoh
Date: Tue Mar 7 14:20:23 2017
New Revision: 297194
URL: http://llvm.org/viewvc/llvm-project?rev=297194&view=rev
Log:
Use filename in linemarker when compiling preprocessed source (Revised)
Summary:
This is a revised version of D28796. Included test is changed to
resolve the target compatibility issue reported (rL293032).
Reviewers: inglorion, dblaikie, echristo, aprantl, probinson
Reviewed By: inglorion
Subscribers: mehdi_amini, cfe-commits
Differential Revision: https://reviews.llvm.org/D30663
Added:
cfe/trunk/test/Frontend/preprocessed-input.i
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=297194&r1=297193&r2=297194&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Tue Mar 7 14:20:23 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=297194&r1=297193&r2=297194&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp Tue Mar 7 14:20:23 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!");
@@ -338,6 +375,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)
@@ -430,9 +474,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.i
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/preprocessed-input.i?rev=297194&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/preprocessed-input.i (added)
+++ cfe/trunk/test/Frontend/preprocessed-input.i Tue Mar 7 14:20:23 2017
@@ -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"{{$}}
More information about the cfe-commits
mailing list