From 277a6e752512cff286190d35cb353ce717e86b18 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Wed, 23 Feb 2011 21:16:44 +0000 Subject: [PATCH] Preserve what the user passed to -include when emitting .d files. Fixes PR8974! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126334 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/Utils.h | 4 +++- include/clang/Serialization/ASTReader.h | 6 ++++-- lib/Frontend/ASTUnit.cpp | 3 ++- lib/Frontend/InitPreprocessor.cpp | 24 +++++++++++++++--------- lib/Serialization/ASTReader.cpp | 9 +++++---- test/Frontend/dependency-gen.c | 7 +++++++ 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index 485161b1bc..02342c1a47 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -28,6 +28,7 @@ class Decl; class DependencyOutputOptions; class Diagnostic; class DiagnosticOptions; +class FileManager; class HeaderSearch; class HeaderSearchOptions; class IdentifierTable; @@ -42,7 +43,8 @@ class FrontendOptions; /// Normalize \arg File for use in a user defined #include directive (in the /// predefines buffer). -std::string NormalizeDashIncludePath(llvm::StringRef File); +std::string NormalizeDashIncludePath(llvm::StringRef File, + FileManager &FileMgr); /// Apply the header search options to get given HeaderSearch object. void ApplyHeaderSearchOptions(HeaderSearch &HS, diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 9799b8d852..94b65cc299 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -116,7 +116,8 @@ public: /// \returns true to indicate the predefines are invalid or false otherwise. virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, llvm::StringRef OriginalFileName, - std::string &SuggestedPredefines) { + std::string &SuggestedPredefines, + FileManager &FileMgr) { return false; } @@ -143,7 +144,8 @@ public: virtual bool ReadTargetTriple(llvm::StringRef Triple); virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, llvm::StringRef OriginalFileName, - std::string &SuggestedPredefines); + std::string &SuggestedPredefines, + FileManager &FileMgr); virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID); virtual void ReadCounter(unsigned Value); diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 4a5a51d9f1..a7942e6090 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -389,7 +389,8 @@ public: virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, llvm::StringRef OriginalFileName, - std::string &SuggestedPredefines) { + std::string &SuggestedPredefines, + FileManager &FileMgr) { Predefines = Buffers[0].Data; for (unsigned I = 1, N = Buffers.size(); I != N; ++I) { Predefines += Buffers[I].Data; diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index d0111a5d26..90ca65746d 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -48,12 +48,13 @@ static void DefineBuiltinMacro(MacroBuilder &Builder, llvm::StringRef Macro, } } -std::string clang::NormalizeDashIncludePath(llvm::StringRef File) { +std::string clang::NormalizeDashIncludePath(llvm::StringRef File, + FileManager &FileMgr) { // Implicit include paths should be resolved relative to the current // working directory first, and then use the regular header search // mechanism. The proper way to handle this is to have the // predefines buffer located at the current working directory, but - // it has not file entry. For now, workaround this by using an + // it has no file entry. For now, workaround this by using an // absolute path if we find the file here, and otherwise letting // header search handle it. llvm::SmallString<128> Path(File); @@ -61,21 +62,25 @@ std::string clang::NormalizeDashIncludePath(llvm::StringRef File) { bool exists; if (llvm::sys::fs::exists(Path.str(), exists) || !exists) Path = File; + else if (exists) + FileMgr.getFile(File); return Lexer::Stringify(Path.str()); } /// AddImplicitInclude - Add an implicit #include of the specified file to the /// predefines buffer. -static void AddImplicitInclude(MacroBuilder &Builder, llvm::StringRef File) { +static void AddImplicitInclude(MacroBuilder &Builder, llvm::StringRef File, + FileManager &FileMgr) { Builder.append("#include \"" + - llvm::Twine(NormalizeDashIncludePath(File)) + "\""); + llvm::Twine(NormalizeDashIncludePath(File, FileMgr)) + "\""); } static void AddImplicitIncludeMacros(MacroBuilder &Builder, - llvm::StringRef File) { + llvm::StringRef File, + FileManager &FileMgr) { Builder.append("#__include_macros \"" + - llvm::Twine(NormalizeDashIncludePath(File)) + "\""); + llvm::Twine(NormalizeDashIncludePath(File, FileMgr)) + "\""); // Marker token to stop the __include_macros fetch loop. Builder.append("##"); // ##? } @@ -94,7 +99,7 @@ static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP, return; } - AddImplicitInclude(Builder, OriginalFile); + AddImplicitInclude(Builder, OriginalFile, PP.getFileManager()); } /// PickFP - This is used to pick a value based on the FP semantics of the @@ -590,7 +595,8 @@ void clang::InitializePreprocessor(Preprocessor &PP, // If -imacros are specified, include them now. These are processed before // any -include directives. for (unsigned i = 0, e = InitOpts.MacroIncludes.size(); i != e; ++i) - AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i]); + AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i], + PP.getFileManager()); // Process -include directives. for (unsigned i = 0, e = InitOpts.Includes.size(); i != e; ++i) { @@ -598,7 +604,7 @@ void clang::InitializePreprocessor(Preprocessor &PP, if (Path == InitOpts.ImplicitPTHInclude) AddImplicitIncludePTH(Builder, PP, Path); else - AddImplicitInclude(Builder, Path); + AddImplicitInclude(Builder, Path, PP.getFileManager()); } // Exit the command line and go back to (2 is LC_LEAVE). diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 150ad17901..2e8e8ca67b 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -244,14 +244,15 @@ FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) { bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, llvm::StringRef OriginalFileName, - std::string &SuggestedPredefines) { + std::string &SuggestedPredefines, + FileManager &FileMgr) { // We are in the context of an implicit include, so the predefines buffer will // have a #include entry for the PCH file itself (as normalized by the // preprocessor initialization). Find it and skip over it in the checking // below. llvm::SmallString<256> PCHInclude; PCHInclude += "#include \""; - PCHInclude += NormalizeDashIncludePath(OriginalFileName); + PCHInclude += NormalizeDashIncludePath(OriginalFileName, FileMgr); PCHInclude += "\"\n"; std::pair Split = llvm::StringRef(PP.getPredefines()).split(PCHInclude.str()); @@ -961,7 +962,8 @@ bool ASTReader::CheckPredefinesBuffers() { if (Listener) return Listener->ReadPredefinesBuffer(PCHPredefinesBuffers, ActualOriginalFileName, - SuggestedPredefines); + SuggestedPredefines, + FileMgr); return false; } @@ -4934,4 +4936,3 @@ ASTReader::PerFileData::~PerFileData() { delete static_cast(HeaderFileInfoTable); delete static_cast(SelectorLookupTable); } - diff --git a/test/Frontend/dependency-gen.c b/test/Frontend/dependency-gen.c index c85d60be73..75b9dd4485 100644 --- a/test/Frontend/dependency-gen.c +++ b/test/Frontend/dependency-gen.c @@ -6,3 +6,10 @@ // RUN: %clang -S -M -x c %s -o %t.d // RUN: grep '.*dependency-gen.*:' %t.d // RUN: grep 'dependency-gen.c' %t.d + +// PR8974 +// RUN: mkdir %t.dir +// RUN: echo > %t.dir/x.h +// RUN: %clang -include %t.dir/x.h -MD -MF %t.d -S -x c -o %t.o %s +// RUN: grep ' %t.dir/x.h' %t.d +