[cfe-commits] r140060 - in /cfe/trunk: include/clang/Basic/SourceManager.h include/clang/Frontend/ASTUnit.h lib/Basic/SourceManager.cpp lib/Frontend/ASTUnit.cpp lib/Frontend/CompilerInstance.cpp lib/Serialization/ASTReader.cpp test/PCH/preamble.c tools/libclang/CIndex.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Mon Sep 19 13:40:35 PDT 2011
Author: akirtzidis
Date: Mon Sep 19 15:40:35 2011
New Revision: 140060
URL: http://llvm.org/viewvc/llvm-project?rev=140060&view=rev
Log:
[libclang] When getting a source location from a file:line:col triplet
check whether the requested location points inside the precompiled preamble,
in which case the returned source location will be a "loaded" one.
Modified:
cfe/trunk/include/clang/Basic/SourceManager.h
cfe/trunk/include/clang/Frontend/ASTUnit.h
cfe/trunk/lib/Basic/SourceManager.cpp
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Frontend/CompilerInstance.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/test/PCH/preamble.c
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=140060&r1=140059&r2=140060&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Mon Sep 19 15:40:35 2011
@@ -559,6 +559,9 @@
/// MainFileID - The file ID for the main source file of the translation unit.
FileID MainFileID;
+ /// \brief The file ID for the precompiled preamble there is one.
+ FileID PreambleFileID;
+
// Statistics for -print-stats.
mutable unsigned NumLinearScans, NumBinaryProbes;
@@ -610,13 +613,15 @@
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;
+ /// \brief Set the file ID for the precompiled preamble.
+ void setPreambleFileID(FileID Preamble) {
+ assert(PreambleFileID.isInvalid() && "PreambleFileID already set!");
+ PreambleFileID = Preamble;
}
+ /// \brief Get the file ID for the precompiled preamble if there is one.
+ FileID getPreambleFileID() const { return PreambleFileID; }
+
//===--------------------------------------------------------------------===//
// Methods to create new FileID's and macro expansions.
//===--------------------------------------------------------------------===//
@@ -1117,11 +1122,12 @@
/// If the source file is included multiple times, the source location will
/// be based upon the first inclusion.
SourceLocation translateFileLineCol(const FileEntry *SourceFile,
- unsigned Line, unsigned Col);
+ unsigned Line, unsigned Col) const;
/// \brief Get the source location in \arg FID for the given line:col.
/// Returns null location if \arg FID is not a file SLocEntry.
- SourceLocation translateLineCol(FileID FID, unsigned Line, unsigned Col);
+ SourceLocation translateLineCol(FileID FID,
+ unsigned Line, unsigned Col) const;
/// \brief If \arg Loc points inside a function macro argument, the returned
/// location will be the macro location in which the argument was expanded.
@@ -1132,7 +1138,7 @@
/// ^
/// Passing a file location pointing at 'foo', will yield a macro location
/// where 'foo' was expanded into.
- SourceLocation getMacroArgExpandedLocation(SourceLocation Loc);
+ SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const;
/// \brief Determines the order of 2 source locations in the translation unit.
///
@@ -1309,7 +1315,7 @@
std::pair<FileID, unsigned>
getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
unsigned Offset) const;
- void computeMacroArgsCache(SrcMgr::ContentCache *Content, FileID FID);
+ void computeMacroArgsCache(SrcMgr::ContentCache *Content, FileID FID) const;
friend class ASTReader;
friend class ASTWriter;
Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=140060&r1=140059&r2=140060&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Mon Sep 19 15:40:35 2011
@@ -196,9 +196,41 @@
/// \brief The file in which the precompiled preamble is stored.
std::string PreambleFile;
+ class PreambleData {
+ const FileEntry *File;
+ std::vector<char> Buffer;
+ mutable unsigned NumLines;
+
+ public:
+ PreambleData() : File(0), NumLines(0) { }
+
+ void assign(const FileEntry *F, const char *begin, const char *end) {
+ File = F;
+ Buffer.assign(begin, end);
+ NumLines = 0;
+ }
+
+ void clear() { Buffer.clear(); File = 0; NumLines = 0; }
+
+ size_t size() const { return Buffer.size(); }
+ bool empty() const { return Buffer.empty(); }
+
+ const char *getBufferStart() const { return &Buffer[0]; }
+
+ unsigned getNumLines() const {
+ if (NumLines)
+ return NumLines;
+ countLines();
+ return NumLines;
+ }
+
+ private:
+ void countLines() const;
+ };
+
/// \brief The contents of the preamble that has been precompiled to
/// \c PreambleFile.
- std::vector<char> Preamble;
+ PreambleData Preamble;
/// \brief Whether the preamble ends at the start of a new line.
///
@@ -515,6 +547,21 @@
PreprocessedEntitiesByFileMap &getPreprocessedEntitiesByFile() {
return PreprocessedEntitiesByFile;
}
+
+ /// \brief Get the source location for the given file:line:col triplet.
+ ///
+ /// The difference with SourceManager::getLocation is that this method checks
+ /// whether the requested location points inside the precompiled preamble
+ /// in which case the returned source location will be a "loaded" one.
+ SourceLocation getLocation(const FileEntry *File,
+ unsigned Line, unsigned Col) const;
+
+ /// \brief Get the source location for the given file:offset pair.
+ ///
+ /// The difference with SourceManager::getLocation is that this method checks
+ /// whether the requested location points inside the precompiled preamble
+ /// in which case the returned source location will be a "loaded" one.
+ SourceLocation getLocation(const FileEntry *File, unsigned Offset) const;
// Retrieve the diagnostics associated with this AST
typedef const StoredDiagnostic *stored_diag_iterator;
Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=140060&r1=140059&r2=140060&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Mon Sep 19 15:40:35 2011
@@ -1324,7 +1324,8 @@
/// If the source file is included multiple times, the source location will
/// be based upon an arbitrary inclusion.
SourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile,
- unsigned Line, unsigned Col) {
+ unsigned Line,
+ unsigned Col) const {
assert(SourceFile && "Null source file!");
assert(Line && Col && "Line and column should start from 1!");
@@ -1439,7 +1440,8 @@
/// \brief Get the source location in \arg FID for the given line:col.
/// Returns null location if \arg FID is not a file SLocEntry.
SourceLocation SourceManager::translateLineCol(FileID FID,
- unsigned Line, unsigned Col) {
+ unsigned Line,
+ unsigned Col) const {
if (FID.isInvalid())
return SourceLocation();
@@ -1496,7 +1498,8 @@
/// 0 -> SourceLocation()
/// 100 -> Expanded macro arg location
/// 110 -> SourceLocation()
-void SourceManager::computeMacroArgsCache(ContentCache *Content, FileID FID) {
+void SourceManager::computeMacroArgsCache(ContentCache *Content,
+ FileID FID) const {
assert(!Content->MacroArgsCache);
assert(!FID.isInvalid());
@@ -1575,7 +1578,8 @@
/// ^
/// Passing a file location pointing at 'foo', will yield a macro location
/// where 'foo' was expanded into.
-SourceLocation SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) {
+SourceLocation
+SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const {
if (Loc.isInvalid() || !Loc.isFileID())
return Loc;
Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=140060&r1=140059&r2=140060&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Mon Sep 19 15:40:35 2011
@@ -1200,7 +1200,7 @@
if (Preamble.size() == NewPreamble.second.first &&
PreambleEndsAtStartOfLine == NewPreamble.second.second &&
NewPreamble.first->getBufferSize() < PreambleReservedSize-2 &&
- memcmp(&Preamble[0], NewPreamble.first->getBufferStart(),
+ memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(),
NewPreamble.second.first) == 0) {
// The preamble has not changed. We may be able to re-use the precompiled
// preamble.
@@ -1332,7 +1332,9 @@
// Save the preamble text for later; we'll need to compare against it for
// subsequent reparses.
- Preamble.assign(NewPreamble.first->getBufferStart(),
+ StringRef MainFilename = PreambleInvocation->getFrontendOpts().Inputs[0].second;
+ Preamble.assign(FileMgr->getFile(MainFilename),
+ NewPreamble.first->getBufferStart(),
NewPreamble.first->getBufferStart()
+ NewPreamble.second.first);
PreambleEndsAtStartOfLine = NewPreamble.second.second;
@@ -2396,3 +2398,41 @@
}
Result.swap(Out);
}
+
+SourceLocation ASTUnit::getLocation(const FileEntry *File,
+ unsigned Line, unsigned Col) const {
+ const SourceManager &SM = getSourceManager();
+ SourceLocation Loc;
+ if (!Preamble.empty() && Line <= Preamble.getNumLines())
+ Loc = SM.translateLineCol(SM.getPreambleFileID(), Line, Col);
+ else
+ Loc = SM.translateFileLineCol(File, Line, Col);
+
+ return SM.getMacroArgExpandedLocation(Loc);
+}
+
+SourceLocation ASTUnit::getLocation(const FileEntry *File,
+ unsigned Offset) const {
+ const SourceManager &SM = getSourceManager();
+ SourceLocation FileLoc;
+ if (!Preamble.empty() && Offset < Preamble.size())
+ FileLoc = SM.getLocForStartOfFile(SM.getPreambleFileID());
+ else
+ FileLoc = SM.translateFileLineCol(File, 1, 1);
+
+ return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));
+}
+
+void ASTUnit::PreambleData::countLines() const {
+ NumLines = 0;
+ if (empty())
+ return;
+
+ for (std::vector<char>::const_iterator
+ I = Buffer.begin(), E = Buffer.end(); I != E; ++I) {
+ if (*I == '\n')
+ ++NumLines;
+ }
+ if (Buffer.back() != '\n')
+ ++NumLines;
+}
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=140060&r1=140059&r2=140060&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Mon Sep 19 15:40:35 2011
@@ -539,11 +539,8 @@
FileManager &FileMgr,
SourceManager &SourceMgr,
const FrontendOptions &Opts) {
- // 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 != "-") {
+ // Figure out where to get and map in the main file.
+ if (InputFile != "-") {
const FileEntry *File = FileMgr.getFile(InputFile);
if (!File) {
Diags.Report(diag::err_fe_error_reading) << InputFile;
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=140060&r1=140059&r2=140060&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Sep 19 15:40:35 2011
@@ -2508,23 +2508,15 @@
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 this AST file is a precompiled preamble, then set the preamble file ID
+ // of the source manager to the file source file from which the preamble was
+ // built.
if (Type == MK_Preamble) {
- if (OriginalFileID.isInvalid()) {
- SourceLocation Loc
- = SourceMgr.getLocation(FileMgr.getFile(getOriginalSourceFile()), 1, 1);
- if (Loc.isValid())
- OriginalFileID = SourceMgr.getDecomposedLoc(Loc).first;
- }
- else {
+ if (!OriginalFileID.isInvalid()) {
OriginalFileID = FileID::get(ModuleMgr.getPrimaryModule().SLocEntryBaseID
+ OriginalFileID.getOpaqueValue() - 1);
+ SourceMgr.setPreambleFileID(OriginalFileID);
}
-
- if (!OriginalFileID.isInvalid())
- SourceMgr.SetPreambleFileID(OriginalFileID);
}
return Success;
Modified: cfe/trunk/test/PCH/preamble.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/preamble.c?rev=140060&r1=140059&r2=140060&view=diff
==============================================================================
--- cfe/trunk/test/PCH/preamble.c (original)
+++ cfe/trunk/test/PCH/preamble.c Mon Sep 19 15:40:35 2011
@@ -1,7 +1,7 @@
// Check that using the preamble option actually skips the preamble.
-// RUN: %clang_cc1 -emit-pch -o %t %S/Inputs/preamble.h
-// RUN: %clang_cc1 -include-pch %t -preamble-bytes=278,1 -DFOO=f -verify %s
+// RUN: %clang_cc1 -emit-pch -o %t %S/Inputs/preamble.h -DFOO=f
+// RUN: %clang_cc1 -include-pch %t -preamble-bytes=317,1 -DFOO=f -verify %s -emit-llvm -o - | FileCheck %s
float f(int); // Not an error, because we skip this via the preamble!
@@ -19,3 +19,5 @@
int g(int x) {
return FOO(x);
}
+
+// CHECK: call {{.*}} @f(
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=140060&r1=140059&r2=140060&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Sep 19 15:40:35 2011
@@ -2750,8 +2750,7 @@
bool Logging = ::getenv("LIBCLANG_LOGGING");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
const FileEntry *File = static_cast<const FileEntry *>(file);
- SourceLocation SLoc
- = CXXUnit->getSourceManager().getLocation(File, line, column);
+ SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
if (SLoc.isInvalid()) {
if (Logging)
llvm::errs() << "clang_getLocation(\"" << File->getName()
@@ -2774,14 +2773,8 @@
return clang_getNullLocation();
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
- SourceLocation Start
- = CXXUnit->getSourceManager().getLocation(
- static_cast<const FileEntry *>(file),
- 1, 1);
- if (Start.isInvalid()) return clang_getNullLocation();
-
- SourceLocation SLoc = Start.getLocWithOffset(offset);
-
+ SourceLocation SLoc
+ = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
if (SLoc.isInvalid()) return clang_getNullLocation();
return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
More information about the cfe-commits
mailing list