//===- SourceManager.h - Track and cache source files -----------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // /// \file /// Defines the SourceManager interface. /// /// There are three different types of locations in a %file: a spelling /// location, an expansion location, and a presumed location. /// /// Given an example of: /// \code /// #define min(x, y) x < y ? x : y /// \endcode /// /// and then later on a use of min: /// \code /// #line 17 /// return min(a, b); /// \endcode /// /// The expansion location is the line in the source code where the macro /// was expanded (the return statement), the spelling location is the /// location in the source where the macro was originally defined, /// and the presumed location is where the line directive states that /// the line is 17, or any other line. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_SOURCEMANAGER_H #define LLVM_CLANG_BASIC_SOURCEMANAGER_H #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileEntry.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/PagedVector.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" #include <cassert> #include <cstddef> #include <map> #include <memory> #include <optional> #include <string> #include <utility> #include <vector> namespace clang { class ASTReader; class ASTWriter; class FileManager; class LineTableInfo; class SourceManager; /// Public enums and private classes that are part of the /// SourceManager implementation. namespace SrcMgr { /// Indicates whether a file or directory holds normal user code, /// system code, or system code which is implicitly 'extern "C"' in C++ mode. /// /// Entire directories can be tagged with this (this is maintained by /// DirectoryLookup and friends) as can specific FileInfos when a \#pragma /// system_header is seen or in various other cases. /// enum CharacteristicKind { … }; /// Determine whether a file / directory characteristic is for system code. inline bool isSystem(CharacteristicKind CK) { … } /// Determine whether a file characteristic is for a module map. inline bool isModuleMap(CharacteristicKind CK) { … } /// Mapping of line offsets into a source file. This does not own the storage /// for the line numbers. class LineOffsetMapping { … }; /// One instance of this struct is kept for every file loaded or used. /// /// This object owns the MemoryBuffer object. class alignas(8) ContentCache { … }; // Assert that the \c ContentCache objects will always be 8-byte aligned so // that we can pack 3 bits of integer into pointers to such objects. static_assert …; /// Information about a FileID, basically just the logical file /// that it represents and include stack information. /// /// Each FileInfo has include stack information, indicating where it came /// from. This information encodes the \#include chain that a token was /// expanded from. The main include file has an invalid IncludeLoc. /// /// FileInfo should not grow larger than ExpansionInfo. Doing so will /// cause memory to bloat in compilations with many unloaded macro /// expansions, since the two data structurs are stored in a union in /// SLocEntry. Extra fields should instead go in "ContentCache *", which /// stores file contents and other bits on the side. /// class FileInfo { … }; /// Each ExpansionInfo encodes the expansion location - where /// the token was ultimately expanded, and the SpellingLoc - where the actual /// character data for the token came from. class ExpansionInfo { … }; // Assert that the \c FileInfo objects are no bigger than \c ExpansionInfo // objects. This controls the size of \c SLocEntry, of which we have one for // each macro expansion. The number of (unloaded) macro expansions can be // very large. Any other fields needed in FileInfo should go in ContentCache. static_assert …; /// This is a discriminated union of FileInfo and ExpansionInfo. /// /// SourceManager keeps an array of these objects, and they are uniquely /// identified by the FileID datatype. class SLocEntry { … }; } // namespace SrcMgr /// External source of source location entries. class ExternalSLocEntrySource { … }; /// Holds the cache used by isBeforeInTranslationUnit. /// /// The cache structure is complex enough to be worth breaking out of /// SourceManager. class InBeforeInTUCacheEntry { … }; /// The stack used when building modules on demand, which is used /// to provide a link between the source managers of the different compiler /// instances. ModuleBuildStack; /// This class handles loading and caching of source files into memory. /// /// This object owns the MemoryBuffer objects for all of the loaded /// files and assigns unique FileID's for each unique \#include chain. /// /// The SourceManager can be queried for information about SourceLocation /// objects, turning them into either spelling or expansion locations. Spelling /// locations represent where the bytes corresponding to a token came from and /// expansion locations represent where the location is in the user's view. In /// the case of a macro expansion, for example, the spelling location indicates /// where the expanded token came from and the expansion location specifies /// where it was expanded. class SourceManager : public RefCountedBase<SourceManager> { … }; /// Comparison function object. template<typename T> class BeforeThanCompare; /// Compare two source locations. template<> class BeforeThanCompare<SourceLocation> { … }; /// Compare two non-overlapping source ranges. template<> class BeforeThanCompare<SourceRange> { … }; /// SourceManager and necessary dependencies (e.g. VFS, FileManager) for a /// single in-memorty file. class SourceManagerForFile { … }; } // namespace clang #endif // LLVM_CLANG_BASIC_SOURCEMANAGER_H