From 414cb64f09ce48a36377458ce5e5a90c3ad41d00 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 30 Nov 2010 05:23:00 +0000 Subject: [PATCH] When loading a precompiled preamble, use the file ID of the precompiled preamble as the "main" source file's file ID within the source manager. This makes compiling with a precompiled preamble produce the same source locations as when compiling without the precompiled preamble; prior to this change, we ended up with different file IDs for source locations within the precompiled preamble vs. those after the precompiled preamble, even for entities (e.g., preprocessing entities) in the same file. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120390 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/SourceManager.h | 7 +++++++ lib/Frontend/CompilerInstance.cpp | 7 +++++-- lib/Serialization/ASTReader.cpp | 12 ++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index b8811b42c4..a19272f29d 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -452,6 +452,13 @@ public: return MainFileID; } + /// \brief Set the file ID for the precompiled preamble, which is also the + /// main file. + void SetPreambleFileID(FileID Preamble) { + assert(MainFileID.isInvalid() && "MainFileID already set!"); + MainFileID = Preamble; + } + //===--------------------------------------------------------------------===// // Methods to create new FileID's and instantiations. //===--------------------------------------------------------------------===// diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index b5feadb96d..30c3b62c19 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -474,8 +474,11 @@ bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile, FileManager &FileMgr, SourceManager &SourceMgr, const FrontendOptions &Opts) { - // Figure out where to get and map in the main file. - if (InputFile != "-") { + // Figure out where to get and map in the main file, unless it's already + // been created (e.g., by a precompiled preamble). + if (!SourceMgr.getMainFileID().isInvalid()) { + // Do nothing: the main file has already been set. + } else if (InputFile != "-") { const FileEntry *File = FileMgr.getFile(InputFile); if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 86732484bc..1cac948d03 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2239,6 +2239,18 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, if (DeserializationListener) DeserializationListener->ReaderInitialized(this); + // If this AST file is a precompiled preamble, then set the main file ID of + // the source manager to the file source file from which the preamble was + // built. This is the only valid way to use a precompiled preamble. + if (Type == Preamble) { + SourceLocation Loc + = SourceMgr.getLocation(FileMgr.getFile(getOriginalSourceFile()), 1, 1); + if (Loc.isValid()) { + std::pair Decomposed = SourceMgr.getDecomposedLoc(Loc); + SourceMgr.SetPreambleFileID(Decomposed.first); + } + } + return Success; } -- 2.50.1