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"{{$}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits