summaryrefslogtreecommitdiffstats
path: root/include/clang/Basic/SourceManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Basic/SourceManager.h')
-rw-r--r--include/clang/Basic/SourceManager.h158
1 files changed, 96 insertions, 62 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index db6bfd2..00c96c3 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -10,7 +10,7 @@
/// \file
/// \brief Defines the SourceManager interface.
///
-/// There are three different types of locations in a file: a spelling
+/// There are three different types of locations in a %file: a spelling
/// location, an expansion location, and a presumed location.
///
/// Given an example of:
@@ -35,21 +35,22 @@
#ifndef LLVM_CLANG_SOURCEMANAGER_H
#define LLVM_CLANG_SOURCEMANAGER_H
-#include "clang/Basic/LLVM.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MemoryBuffer.h"
+#include <cassert>
#include <map>
#include <vector>
-#include <cassert>
namespace clang {
@@ -78,7 +79,7 @@ namespace SrcMgr {
};
/// \brief One instance of this struct is kept for every file loaded or used.
- ////
+ ///
/// This object owns the MemoryBuffer object.
class ContentCache {
enum CCFlags {
@@ -270,7 +271,7 @@ namespace SrcMgr {
return SourceLocation::getFromRawEncoding(IncludeLoc);
}
const ContentCache* getContentCache() const {
- return reinterpret_cast<const ContentCache*>(Data & ~7UL);
+ return reinterpret_cast<const ContentCache*>(Data & ~uintptr_t(7));
}
/// \brief Return whether this is a system header or not.
@@ -328,6 +329,11 @@ namespace SrcMgr {
SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid();
}
+ bool isMacroBodyExpansion() const {
+ return getExpansionLocStart().isValid() &&
+ SourceLocation::getFromRawEncoding(ExpansionLocEnd).isValid();
+ }
+
bool isFunctionMacroExpansion() const {
return getExpansionLocStart().isValid() &&
getExpansionLocStart() != getExpansionLocEnd();
@@ -429,6 +435,11 @@ public:
/// \returns true if an error occurred that prevented the source-location
/// entry from being loaded.
virtual bool ReadSLocEntry(int ID) = 0;
+
+ /// \brief Retrieve the module import location and name for the given ID, if
+ /// in fact it was loaded from a module (rather than, say, a precompiled
+ /// header).
+ virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) = 0;
};
@@ -436,7 +447,7 @@ public:
///
/// The cache structure is complex enough to be worth breaking out of
/// SourceManager.
-class IsBeforeInTranslationUnitCache {
+class InBeforeInTUCacheEntry {
/// \brief The FileID's of the cached query.
///
/// If these match up with a subsequent query, the result can be reused.
@@ -458,7 +469,6 @@ class IsBeforeInTranslationUnitCache {
/// random token in the parent.
unsigned LCommonOffset, RCommonOffset;
public:
-
/// \brief Return true if the currently cached values match up with
/// the specified LHS/RHS query.
///
@@ -508,6 +518,11 @@ public:
};
+/// \brief The stack used when building modules on demand, which is used
+/// to provide a link between the source managers of the different compiler
+/// instances.
+typedef ArrayRef<std::pair<std::string, FullSourceLoc> > ModuleBuildStack;
+
/// \brief This class handles loading and caching of source files into memory.
///
/// This object owns the MemoryBuffer objects for all of the loaded
@@ -572,13 +587,13 @@ class SourceManager : public RefCountedBase<SourceManager> {
///
/// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid
/// expansion.
- std::vector<SrcMgr::SLocEntry> LocalSLocEntryTable;
+ SmallVector<SrcMgr::SLocEntry, 0> LocalSLocEntryTable;
/// \brief The table of SLocEntries that are loaded from other modules.
///
/// Negative FileIDs are indexes into this table. To get from ID to an index,
/// use (-ID - 2).
- mutable std::vector<SrcMgr::SLocEntry> LoadedSLocEntryTable;
+ mutable SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
/// \brief The starting offset of the next local SLocEntry.
///
@@ -631,8 +646,21 @@ class SourceManager : public RefCountedBase<SourceManager> {
// Statistics for -print-stats.
mutable unsigned NumLinearScans, NumBinaryProbes;
- // Cache results for the isBeforeInTranslationUnit method.
- mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache;
+ /// The key value into the IsBeforeInTUCache table.
+ typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
+
+ /// The IsBeforeInTranslationUnitCache is a mapping from FileID pairs
+ /// to cache results.
+ typedef llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>
+ InBeforeInTUCache;
+
+ /// Cache results for the isBeforeInTranslationUnit method.
+ mutable InBeforeInTUCache IBTUCache;
+ mutable InBeforeInTUCacheEntry IBTUCacheOverflow;
+
+ /// Return the cache entry for comparing the given file IDs
+ /// for isBeforeInTranslationUnit.
+ InBeforeInTUCacheEntry &getInBeforeInTUCache(FileID LFID, FileID RFID) const;
// Cache for the "fake" buffer used for error-recovery purposes.
mutable llvm::MemoryBuffer *FakeBufferForRecovery;
@@ -645,6 +673,15 @@ class SourceManager : public RefCountedBase<SourceManager> {
mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap;
+ /// \brief The stack of modules being built, which is used to detect
+ /// cycles in the module dependency graph as modules are being built, as
+ /// well as to describe why we're rebuilding a particular module.
+ ///
+ /// There is no way to set this value from the command line. If we ever need
+ /// to do so (e.g., if on-demand module construction moves out-of-process),
+ /// we can add a cc1-level option to do so.
+ SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack;
+
// SourceManager doesn't support copy construction.
explicit SourceManager(const SourceManager&) LLVM_DELETED_FUNCTION;
void operator=(const SourceManager&) LLVM_DELETED_FUNCTION;
@@ -669,6 +706,22 @@ public:
/// (likely to change while trying to use them).
bool userFilesAreVolatile() const { return UserFilesAreVolatile; }
+ /// \brief Retrieve the module build stack.
+ ModuleBuildStack getModuleBuildStack() const {
+ return StoredModuleBuildStack;
+ }
+
+ /// \brief Set the module build stack.
+ void setModuleBuildStack(ModuleBuildStack stack) {
+ StoredModuleBuildStack.clear();
+ StoredModuleBuildStack.append(stack.begin(), stack.end());
+ }
+
+ /// \brief Push an entry to the module build stack.
+ void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc) {
+ StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc));
+ }
+
/// \brief Create the FileID for a memory buffer that will represent the
/// FileID for the main source.
///
@@ -959,6 +1012,21 @@ public:
return Entry.getFile().getIncludeLoc();
}
+ // \brief Returns the import location if the given source location is
+ // located within a module, or an invalid location if the source location
+ // is within the current translation unit.
+ std::pair<SourceLocation, StringRef>
+ getModuleImportLoc(SourceLocation Loc) const {
+ FileID FID = getFileID(Loc);
+
+ // Positive file IDs are in the current translation unit, and -1 is a
+ // placeholder.
+ if (FID.ID >= -1)
+ return std::make_pair(SourceLocation(), "");
+
+ return ExternalSLocEntries->getModuleImportLoc(FID.ID);
+ }
+
/// \brief Given a SourceLocation object \p Loc, return the expansion
/// location referenced by the ID.
SourceLocation getExpansionLoc(SourceLocation Loc) const {
@@ -1075,6 +1143,13 @@ public:
/// expanded.
bool isMacroArgExpansion(SourceLocation Loc) const;
+ /// \brief Tests whether the given source location represents the expansion of
+ /// a macro body.
+ ///
+ /// This is equivalent to testing whether the location is part of a macro
+ /// expansion but not the expansion of an argument to a function-like macro.
+ bool isMacroBodyExpansion(SourceLocation Loc) const;
+
/// \brief Returns true if \p Loc is inside the [\p Start, +\p Length)
/// chunk of the source location address space.
///
@@ -1187,7 +1262,8 @@ public:
/// presumed location cannot be calculate (e.g., because \p Loc is invalid
/// or the file containing \p Loc has changed on disk), returns an invalid
/// presumed location.
- PresumedLoc getPresumedLoc(SourceLocation Loc) const;
+ PresumedLoc getPresumedLoc(SourceLocation Loc,
+ bool UseLineDirectives = true) const;
/// \brief Returns true if both SourceLocations correspond to the same file.
bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
@@ -1421,40 +1497,13 @@ public:
return !isLoadedFileID(FID);
}
- /// Get a presumed location suitable for displaying in a diagnostic message,
- /// taking into account macro arguments and expansions.
- PresumedLoc getPresumedLocForDisplay(SourceLocation Loc) const {
- // This is a condensed form of the algorithm used by emitCaretDiagnostic to
- // walk to the top of the macro call stack.
- while (Loc.isMacroID()) {
- Loc = skipToMacroArgExpansion(Loc);
- Loc = getImmediateMacroCallerLoc(Loc);
- }
-
- return getPresumedLoc(Loc);
- }
-
- /// Look through spelling locations for a macro argument expansion, and if
- /// found skip to it so that we can trace the argument rather than the macros
- /// in which that argument is used. If no macro argument expansion is found,
- /// don't skip anything and return the starting location.
- SourceLocation skipToMacroArgExpansion(SourceLocation StartLoc) const {
- for (SourceLocation L = StartLoc; L.isMacroID();
- L = getImmediateSpellingLoc(L)) {
- if (isMacroArgExpansion(L))
- return L;
- }
- // Otherwise just return initial location, there's nothing to skip.
- return StartLoc;
- }
-
/// Gets the location of the immediate macro caller, one level up the stack
/// toward the initial macro typed into the source.
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const {
if (!Loc.isMacroID()) return Loc;
// When we have the location of (part of) an expanded parameter, its
- // spelling location points to the argument as typed into the macro call,
+ // spelling location points to the argument as expanded in the macro call,
// and therefore is used to locate the macro caller.
if (isMacroArgExpansion(Loc))
return getImmediateSpellingLoc(Loc);
@@ -1464,22 +1513,6 @@ public:
return getImmediateExpansionRange(Loc).first;
}
- /// Gets the location of the immediate macro callee, one level down the stack
- /// toward the leaf macro.
- SourceLocation getImmediateMacroCalleeLoc(SourceLocation Loc) const {
- if (!Loc.isMacroID()) return Loc;
-
- // When we have the location of (part of) an expanded parameter, its
- // expansion location points to the unexpanded parameter reference within
- // the macro definition (or callee).
- if (isMacroArgExpansion(Loc))
- return getImmediateExpansionRange(Loc).first;
-
- // Otherwise, the callee of the macro is located where this location was
- // spelled inside the macro definition.
- return getImmediateSpellingLoc(Loc);
- }
-
private:
const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
@@ -1599,4 +1632,5 @@ public:
} // end namespace clang
+
#endif
OpenPOWER on IntegriCloud