SourceManager.h revision 5330ee071743b8a896aa46979b020e6c3ca9b1cc
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===// 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// The LLVM Compiler Infrastructure 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// This file is distributed under the University of Illinois Open Source 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// License. See LICENSE.TXT for details. 7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang// 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===// 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// This file defines the SourceManager interface. 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===// 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef LLVM_CLANG_SOURCEMANAGER_H 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define LLVM_CLANG_SOURCEMANAGER_H 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "clang/Basic/LLVM.h" 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "clang/Basic/SourceLocation.h" 19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/Support/Allocator.h" 20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/Support/DataTypes.h" 21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/ADT/PointerIntPair.h" 22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/ADT/PointerUnion.h" 23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/ADT/IntrusiveRefCntPtr.h" 24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/ADT/DenseMap.h" 25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/Support/MemoryBuffer.h" 26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <map> 27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <vector> 28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <cassert> 29a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Projectnamespace clang { 31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass Diagnostic; 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass SourceManager; 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass FileManager; 35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass FileEntry; 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass LineTableInfo; 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass LangOptions; 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass ASTWriter; 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass ASTReader; 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// There are three different types of locations in a file: a spelling 42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// location, an expansion location, and a presumed location. 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// Given an example of: 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// #define min(x, y) x < y ? x : y 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// and then later on a use of min: 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// #line 17 49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// return min(a, b); 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// The expansion location is the line in the source code where the macro 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// was expanded (the return statement), the spelling location is the 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// location in the source where the macro was originally defined, 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// and the presumed location is where the line directive states that 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// the line is 17, or any other line. 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// SrcMgr - Public enums and private classes that are part of the 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// SourceManager implementation. 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectnamespace SrcMgr { 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// CharacteristicKind - This is used to represent whether a file or directory 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// holds normal user code, system code, or system code which is implicitly 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 'extern "C"' in C++ mode. Entire directories can be tagged with this 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// (this is maintained by DirectoryLookup and friends) as can specific 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// FileInfos when a #pragma system_header is seen or various other cases. 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project enum CharacteristicKind { 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project C_User, C_System, C_ExternCSystem 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// ContentCache - One instance of this struct is kept for every file 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// loaded or used. This object owns the MemoryBuffer object. 73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project class ContentCache { 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project enum CCFlags { 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Whether the buffer is invalid. 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project InvalidFlag = 0x01, 77a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// \brief Whether the buffer should not be freed on destruction. 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project DoNotFreeFlag = 0x02 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Buffer - The actual buffer containing the characters from the input 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// file. This is owned by the ContentCache object. 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// The bits indicate indicates whether the buffer is invalid. 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer; 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project public: 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Reference to the file entry representing this ContentCache. 880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// This reference does not own the FileEntry object. 890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// It is possible for this to be NULL if 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// the ContentCache encapsulates an imaginary text buffer. 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const FileEntry *OrigEntry; 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief References the file which the contents were actually loaded from. 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Can be different from 'Entry' if we overridden the contents of one file 950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// with the contents of another file. 960a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project const FileEntry *ContentsEntry; 970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// SourceLineCache - A bump pointer allocated array of offsets for each 990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// source line. This is lazily computed. This is owned by the 1000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// SourceManager BumpPointerAllocator object. 1010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project unsigned *SourceLineCache; 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// NumLines - The number of lines in this ContentCache. This is only valid 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// if SourceLineCache is non-null. 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned NumLines; 1060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Lazily computed map of macro argument chunks to their expanded 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// source location. 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef std::map<unsigned, SourceLocation> MacroArgsMap; 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project MacroArgsMap *MacroArgsCache; 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getBuffer - Returns the memory buffer for the associated content. 113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param Diag Object through which diagnostics will be emitted if the 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// buffer cannot be retrieved. 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param Loc If specified, is the location that invalid file diagnostics 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// will be emitted at. 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param Invalid If non-NULL, will be set \c true if an error occurred. 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag, 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SourceManager &SM, 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation Loc = SourceLocation(), 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool *Invalid = 0) const; 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getSize - Returns the size of the content encapsulated by this 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// ContentCache. This can be the size of the source file or the size of an 128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// arbitrary scratch buffer. If the ContentCache encapsulates a source 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// file this size is retrieved from the file's FileEntry. 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getSize() const; 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getSizeBytesMapped - Returns the number of bytes actually mapped for 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// this ContentCache. This can be 0 if the MemBuffer was not actually 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// expanded. 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getSizeBytesMapped() const; 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// Returns the kind of memory used to back the memory buffer for 1380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// this content cache. This is used for performance analysis. 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const; 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void setBuffer(const llvm::MemoryBuffer *B) { 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(!Buffer.getPointer() && "MemoryBuffer already set."); 143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Buffer.setPointer(B); 144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Buffer.setInt(false); 145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Get the underlying buffer, returning NULL if the buffer is not 148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// yet available. 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const llvm::MemoryBuffer *getRawBuffer() const { 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Buffer.getPointer(); 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Replace the existing buffer (which will be deleted) 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// with the given buffer. 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree = false); 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Determine whether the buffer itself is invalid. 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isBufferInvalid() const { 1590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project return Buffer.getInt() & InvalidFlag; 1600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Determine whether the buffer should be freed. 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool shouldFreeBuffer() const { 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return (Buffer.getInt() & DoNotFreeFlag) == 0; 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ContentCache(const FileEntry *Ent = 0) 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent), 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLineCache(0), NumLines(0), MacroArgsCache(0) {} 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ContentCache(const FileEntry *Ent, const FileEntry *contentEnt) 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : Buffer(0, false), OrigEntry(Ent), ContentsEntry(contentEnt), 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLineCache(0), NumLines(0), MacroArgsCache(0) {} 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ~ContentCache(); 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// The copy ctor does not allow copies where source object has either 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// is not transferred, so this is a logical error. 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ContentCache(const ContentCache &RHS) 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : Buffer(0, false), SourceLineCache(0), MacroArgsCache(0) 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project OrigEntry = RHS.OrigEntry; 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ContentsEntry = RHS.ContentsEntry; 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 && 1870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project RHS.MacroArgsCache == 0 1880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project && "Passed ContentCache object cannot own a buffer."); 1890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 1900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project NumLines = RHS.NumLines; 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project private: 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Disable assignments. 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ContentCache &operator=(const ContentCache& RHS); 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// FileInfo - Information about a FileID, basically just the logical file 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// that it represents and include stack information. 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Each FileInfo has include stack information, indicating where it came 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// from. This information encodes the #include chain that a token was 2030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// expanded from. The main include file has an invalid IncludeLoc. 2040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// 2050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// FileInfos contain a "ContentCache *", with the contents of the file. 2060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project class FileInfo { 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// IncludeLoc - The location of the #include that brought in this file. 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// This is an invalid SLOC for the main file (top of the #include chain). 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned IncludeLoc; // Really a SourceLocation 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Number of FileIDs (files and macros) that were created during 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// preprocessing of this #include, including this SLocEntry. 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Zero means the preprocessor didn't provide such info for this SLocEntry. 2150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project unsigned NumCreatedFIDs; 2160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 2170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// Data - This contains the ContentCache* and the bits indicating the 2180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// characteristic of the file and whether it has #line info, all bitmangled 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// together. 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project uintptr_t Data; 221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class clang::SourceManager; 223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class clang::ASTWriter; 224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class clang::ASTReader; 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project public: 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// get - Return a FileInfo object. 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FileInfo get(SourceLocation IL, const ContentCache *Con, 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CharacteristicKind FileCharacter) { 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileInfo X; 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project X.IncludeLoc = IL.getRawEncoding(); 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project X.NumCreatedFIDs = 0; 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project X.Data = (uintptr_t)Con; 233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned"); 2340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project assert((unsigned)FileCharacter < 4 && "invalid file character"); 2350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project X.Data |= (unsigned)FileCharacter; 2360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project return X; 2370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 2380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation getIncludeLoc() const { 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SourceLocation::getFromRawEncoding(IncludeLoc); 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ContentCache* getContentCache() const { 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return reinterpret_cast<const ContentCache*>(Data & ~7UL); 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getCharacteristic - Return whether this is a system header or not. 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CharacteristicKind getFileCharacteristic() const { 2480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project return (CharacteristicKind)(Data & 3); 2490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 2500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 2510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// hasLineDirectives - Return true if this FileID has #line directives in 2520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// it. 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool hasLineDirectives() const { return (Data & 4) != 0; } 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// setHasLineDirectives - Set the flag that indicates that this FileID has 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// line table entries associated with it. 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void setHasLineDirectives() { 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Data |= 4; 2590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 2600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project }; 2610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 2620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// ExpansionInfo - Each ExpansionInfo encodes the expansion location - where 2630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// the token was ultimately expanded, and the SpellingLoc - where the actual 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// character data for the token came from. 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project class ExpansionInfo { 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Really these are all SourceLocations. 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// SpellingLoc - Where the spelling for the token can be found. 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned SpellingLoc; 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// ExpansionLocStart/ExpansionLocEnd - In a macro expansion, these 2720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project /// indicate the start and end of the expansion. In object-like macros, 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// these will be the same. In a function-like macro expansion, the start 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// will be the identifier and the end will be the ')'. Finally, in 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// macro-argument instantitions, the end will be 'SourceLocation()', an 276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// invalid location. 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned ExpansionLocStart, ExpansionLocEnd; 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project public: 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation getSpellingLoc() const { 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SourceLocation::getFromRawEncoding(SpellingLoc); 2820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 2830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project SourceLocation getExpansionLocStart() const { 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SourceLocation::getFromRawEncoding(ExpansionLocStart); 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project SourceLocation getExpansionLocEnd() const { 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation EndLoc = 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation::getFromRawEncoding(ExpansionLocEnd); 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return EndLoc.isInvalid() ? getExpansionLocStart() : EndLoc; 290a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::pair<SourceLocation,SourceLocation> getExpansionLocRange() const { 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return std::make_pair(getExpansionLocStart(), getExpansionLocEnd()); 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isMacroArgExpansion() const { 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Note that this needs to return false for default constructed objects. 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getExpansionLocStart().isValid() && 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid(); 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// create - Return a ExpansionInfo for an expansion. Start and End specify 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// the expansion range (where the macro is expanded), and SpellingLoc 304a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// specifies the spelling location (where the characters from the token 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// come from). All three can refer to normal File SLocs or expansion 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// locations. 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static ExpansionInfo create(SourceLocation SpellingLoc, 308a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang SourceLocation Start, SourceLocation End) { 309a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ExpansionInfo X; 310a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang X.SpellingLoc = SpellingLoc.getRawEncoding(); 311a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang X.ExpansionLocStart = Start.getRawEncoding(); 312a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang X.ExpansionLocEnd = End.getRawEncoding(); 313a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return X; 314a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } 315295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 316aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich /// createForMacroArg - Return a special ExpansionInfo for the expansion of 317aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich /// a macro argument into a function-like macro's body. ExpansionLoc 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// specifies the expansion location (where the macro is expanded). This 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// doesn't need to be a range because a macro is always expanded at 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// a macro parameter reference, and macro parameters are always exactly 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// one token. SpellingLoc specifies the spelling location (where the 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// characters from the token come from). ExpansionLoc and SpellingLoc can 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// both refer to normal File SLocs or expansion locations. 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Given the code: 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \code 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// #define F(x) f(x) 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// F(42); 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \endcode 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// When expanding '\c F(42)', the '\c x' would call this with an 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// SpellingLoc pointing at '\c 42' anad an ExpansionLoc pointing at its 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// location in the definition of '\c F'. 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc, 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation ExpansionLoc) { 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // We store an intentionally invalid source location for the end of the 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // expansion range to mark that this is a macro argument ion rather than 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // a normal one. 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return create(SpellingLoc, ExpansionLoc, SourceLocation()); 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 343a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// SLocEntry - This is a discriminated union of FileInfo and 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// ExpansionInfo. SourceManager keeps an array of these objects, and 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// they are uniquely identified by the FileID datatype. 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project class SLocEntry { 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned Offset; // low bit is set for expansion info. 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project union { 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileInfo File; 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExpansionInfo Expansion; 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project public: 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getOffset() const { return Offset >> 1; } 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isExpansion() const { return Offset & 1; } 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isFile() const { return !isExpansion(); } 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const FileInfo &getFile() const { 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(isFile() && "Not a file SLocEntry!"); 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return File; 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ExpansionInfo &getExpansion() const { 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(isExpansion() && "Not a macro expansion SLocEntry!"); 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Expansion; 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static SLocEntry get(unsigned Offset, const FileInfo &FI) { 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SLocEntry E; 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project E.Offset = Offset << 1; 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project E.File = FI; 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return E; 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static SLocEntry get(unsigned Offset, const ExpansionInfo &Expansion) { 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SLocEntry E; 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project E.Offset = (Offset << 1) | 1; 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project E.Expansion = Expansion; 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return E; 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project} // end SrcMgr namespace. 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// \brief External source of source location entries. 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass ExternalSLocEntrySource { 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project virtual ~ExternalSLocEntrySource(); 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Read the source location entry with index ID, which will always be 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// less than -1. 391a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \returns true if an error occurred that prevented the source-location 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// entry from being loaded. 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project virtual bool ReadSLocEntry(int ID) = 0; 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// IsBeforeInTranslationUnitCache - This class holds the cache used by 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// isBeforeInTranslationUnit. The cache structure is complex enough to be 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// worth breaking out of SourceManager. 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass IsBeforeInTranslationUnitCache { 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// L/R QueryFID - These are the FID's of the cached query. If these match up 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// with a subsequent query, the result can be reused. 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID LQueryFID, RQueryFID; 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief True if LQueryFID was created before RQueryFID. This is used 407a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// to compare macro expansion locations. 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool IsLQFIDBeforeRQFID; 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// CommonFID - This is the file found in common between the two #include 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// traces. It is the nearest common ancestor of the #include tree. 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID CommonFID; 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// L/R CommonOffset - This is the offset of the previous query in CommonFID. 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Usually, this represents the location of the #include for QueryFID, but if 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// LQueryFID is a parent of RQueryFID (or vise versa) then these can be a 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// random token in the parent. 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned LCommonOffset, RCommonOffset; 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// isCacheValid - Return true if the currently cached values match up with 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// the specified LHS/RHS query. If not, we can't use the cache. 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isCacheValid(FileID LHS, FileID RHS) const { 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return LQueryFID == LHS && RQueryFID == RHS; 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getCachedResult - If the cache is valid, compute the result given the 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// specified offsets in the LHS/RHS FID's. 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool getCachedResult(unsigned LOffset, unsigned ROffset) const { 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // If one of the query files is the common file, use the offset. Otherwise, 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // use the #include loc in the common file. 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (LQueryFID != CommonFID) LOffset = LCommonOffset; 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (RQueryFID != CommonFID) ROffset = RCommonOffset; 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // It is common for multiple macro expansions to be "included" from the same 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // location (expansion location), in which case use the order of the FileIDs 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // to determine which came first. 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (LOffset == ROffset && LQueryFID != CommonFID && RQueryFID != CommonFID) 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return IsLQFIDBeforeRQFID; 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return LOffset < ROffset; 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Set up a new query. 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) { 446a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang assert(LHS != RHS); 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project LQueryFID = LHS; 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project RQueryFID = RHS; 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project IsLQFIDBeforeRQFID = isLFIDBeforeRFID; 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void clear() { 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project LQueryFID = RQueryFID = FileID(); 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project IsLQFIDBeforeRQFID = false; 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void setCommonLoc(FileID commonFID, unsigned lCommonOffset, 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned rCommonOffset) { 459a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang CommonFID = commonFID; 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project LCommonOffset = lCommonOffset; 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project RCommonOffset = rCommonOffset; 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// \brief This class handles loading and caching of source files into memory. 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// This object owns the MemoryBuffer objects for all of the loaded 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// files and assigns unique FileID's for each unique #include chain. 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// The SourceManager can be queried for information about SourceLocation 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// objects, turning them into either spelling or expansion locations. Spelling 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// locations represent where the bytes corresponding to a token came from and 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// expansion locations represent where the location is in the user's view. In 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// the case of a macro expansion, for example, the spelling location indicates 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// where the expanded token came from and the expansion location specifies 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// where it was expanded. 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass SourceManager : public llvm::RefCountedBase<SourceManager> { 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Diagnostic object. 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Diagnostic &Diag; 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileManager &FileMgr; 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable llvm::BumpPtrAllocator ContentCacheAlloc; 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// FileInfos - Memoized information about all of the files tracked by this 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// SourceManager. This set allows us to merge ContentCache entries based 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// on their FileEntry*. All ContentCache objects will thus have unique, 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// non-null, FileEntry pointers. 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos; 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief True if the ContentCache for files that are overriden by other 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// files, should report the original file name. Defaults to true. 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool OverridenFilesKeepOriginalName; 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Files that have been overriden with the contents from another file. 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles; 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// MemBufferInfos - Information about various memory buffers that we have 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// read in. All FileEntry* within the stored ContentCache objects are NULL, 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// as they do not refer to a file. 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::vector<SrcMgr::ContentCache*> MemBufferInfos; 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief The table of SLocEntries that are local to this module. 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// expansion. 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::vector<SrcMgr::SLocEntry> LocalSLocEntryTable; 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief The table of SLocEntries that are loaded from other modules. 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Negative FileIDs are indexes into this table. To get from ID to an index, 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// use (-ID - 2). 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::vector<SrcMgr::SLocEntry> LoadedSLocEntryTable; 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief The starting offset of the next local SLocEntry. 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// This is LocalSLocEntryTable.back().Offset + the size of that entry. 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned NextLocalOffset; 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief The starting offset of the latest batch of loaded SLocEntries. 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// This is LoadedSLocEntryTable.back().Offset, except that that entry might 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// not have been loaded, so that value would be unknown. 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned CurrentLoadedOffset; 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief The highest possible offset is 2^31-1, so CurrentLoadedOffset 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// starts at 2^31. 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const unsigned MaxLoadedOffset = 1U << 31U; 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief A bitmap that indicates whether the entries of LoadedSLocEntryTable 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// have already been loaded from the external source. 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Same indexing as LoadedSLocEntryTable. 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::vector<bool> SLocEntryLoaded; 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief An external source for source location entries. 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExternalSLocEntrySource *ExternalSLocEntries; 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// LastFileIDLookup - This is a one-entry cache to speed up getFileID. 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// LastFileIDLookup records the last FileID looked up or created, because it 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// is very common to look up many tokens from the same file. 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable FileID LastFileIDLookup; 544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// LineTable - This holds information for #line directives. It is referenced 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// by indices from SLocEntryTable. 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project LineTableInfo *LineTable; 548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// LastLineNo - These ivars serve as a cache used in the getLineNumber 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// method which is used to speedup getLineNumber calls to nearby locations. 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable FileID LastLineNoFileIDQuery; 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable SrcMgr::ContentCache *LastLineNoContentCache; 553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable unsigned LastLineNoFilePos; 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable unsigned LastLineNoResult; 555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// MainFileID - The file ID for the main source file of the translation unit. 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID MainFileID; 558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Statistics for -print-stats. 560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable unsigned NumLinearScans, NumBinaryProbes; 561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Cache results for the isBeforeInTranslationUnit method. 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache; 564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Cache for the "fake" buffer used for error-recovery purposes. 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mutable llvm::MemoryBuffer *FakeBufferForRecovery; 567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // SourceManager doesn't support copy construction. 569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project explicit SourceManager(const SourceManager&); 570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void operator=(const SourceManager&); 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceManager(Diagnostic &Diag, FileManager &FileMgr); 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ~SourceManager(); 574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void clearIDTables(); 576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Diagnostic &getDiagnostics() const { return Diag; } 578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileManager &getFileManager() const { return FileMgr; } 580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Set true if the SourceManager should report the original file name 582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// for contents of files that were overriden by other files.Defaults to true. 583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void setOverridenFilesKeepOriginalName(bool value) { 584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project OverridenFilesKeepOriginalName = value; 585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// createMainFileIDForMembuffer - Create the FileID for a memory buffer 588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// that will represent the FileID for the main source. One example 589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// of when this would be used is when the main source is read from STDIN. 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(MainFileID.isInvalid() && "MainFileID already set!"); 592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project MainFileID = createFileIDForMemBuffer(Buffer); 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return MainFileID; 594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // MainFileID creation and querying methods. 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getMainFileID - Returns the FileID of the main source file. 601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID getMainFileID() const { return MainFileID; } 602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// createMainFileID - Create the FileID for the main source file. 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID createMainFileID(const FileEntry *SourceFile) { 605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(MainFileID.isInvalid() && "MainFileID already set!"); 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project MainFileID = createFileID(SourceFile, SourceLocation(), SrcMgr::C_User); 6070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project return MainFileID; 608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Set the file ID for the precompiled preamble, which is also the 611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// main file. 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void SetPreambleFileID(FileID Preamble) { 613a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang assert(MainFileID.isInvalid() && "MainFileID already set!"); 614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project MainFileID = Preamble; 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 616a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Methods to create new FileID's and macro expansions. 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// createFileID - Create a new FileID that represents the specified file 622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// being #included from the specified IncludePosition. This translates NULL 623a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// into standard input. 624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, 625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SrcMgr::CharacteristicKind FileCharacter, 626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project int LoadedID = 0, unsigned LoadedOffset = 0) { 627a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile); 628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(IR && "getOrCreateContentCache() cannot return NULL"); 629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset); 630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// createFileIDForMemBuffer - Create a new FileID that represents the 633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// specified memory buffer. This does no caching of the buffer and takes 634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once. 635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer, 636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project int LoadedID = 0, unsigned LoadedOffset = 0) { 637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return createFileID(createMemBufferContentCache(Buffer), SourceLocation(), 6380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project SrcMgr::C_User, LoadedID, LoadedOffset); 639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// createMacroArgExpansionLoc - Return a new SourceLocation that encodes the 642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// fact that a token from SpellingLoc should actually be referenced from 643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// ExpansionLoc, and that it represents the expansion of a macro argument 644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// into the function-like macro body. 645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation createMacroArgExpansionLoc(SourceLocation Loc, 646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation ExpansionLoc, 647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned TokLength); 648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// createExpansionLoc - Return a new SourceLocation that encodes the fact 650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// that a token from SpellingLoc should actually be referenced from 651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// ExpansionLoc. 652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation createExpansionLoc(SourceLocation Loc, 653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation ExpansionLocStart, 654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation ExpansionLocEnd, 655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned TokLength, 656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project int LoadedID = 0, 657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned LoadedOffset = 0); 658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Retrieve the memory buffer associated with the given file. 660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 661a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// \param Invalid If non-NULL, will be set \c true if an error 662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// occurs while retrieving the memory buffer. 663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File, 664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool *Invalid = 0); 665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Override the contents of the given source file by providing an 667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// already-allocated buffer. 668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param SourceFile the source file whose contents will be overriden. 670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param Buffer the memory buffer whose contents will be used as the 672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// data in the given source file. 673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param DoNotFree If true, then the buffer will not be freed when the 675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// source manager is destroyed. 676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void overrideFileContents(const FileEntry *SourceFile, 677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const llvm::MemoryBuffer *Buffer, 678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool DoNotFree = false); 679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Override the the given source file with another one. 681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param SourceFile the source file which will be overriden. 683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param NewFile the file whose contents will be used as the 685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// data instead of the contents of the given source file. 686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void overrideFileContents(const FileEntry *SourceFile, 687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const FileEntry *NewFile); 688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // FileID manipulation methods. 691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getBuffer - Return the buffer for the specified FileID. If there is an 694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// error opening this buffer the first time, this manufactures a temporary 695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// buffer and returns a non-empty error string. 696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc, 697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool *Invalid = 0) const { 698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool MyInvalid = false; 699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); 700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (MyInvalid || !Entry.isFile()) { 701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Invalid) 702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *Invalid = true; 703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getFakeBufferForRecovery(); 705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc, 708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Invalid); 709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const { 712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool MyInvalid = false; 713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); 714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (MyInvalid || !Entry.isFile()) { 715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Invalid) 716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *Invalid = true; 717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getFakeBufferForRecovery(); 719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Entry.getFile().getContentCache()->getBuffer(Diag, *this, 722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation(), 723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Invalid); 724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getFileEntryForID - Returns the FileEntry record for the provided FileID. 727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const FileEntry *getFileEntryForID(FileID FID) const { 728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool MyInvalid = false; 729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); 730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (MyInvalid || !Entry.isFile()) 731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Entry.getFile().getContentCache()->OrigEntry; 734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Returns the FileEntry record for the provided SLocEntry. 737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const 738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return sloc.getFile().getContentCache()->OrigEntry; 740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getBufferData - Return a StringRef to the source buffer data for the 743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// specified FileID. 744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param FID The file ID whose contents will be returned. 746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \param Invalid If non-NULL, will be set true if an error occurred. 747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project StringRef getBufferData(FileID FID, bool *Invalid = 0) const; 748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Get the number of FileIDs (files and macros) that were created 750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// during preprocessing of \arg FID, including it. 751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getNumCreatedFIDsForFileID(FileID FID) const { 752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool Invalid = false; 753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); 754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Invalid || !Entry.isFile()) 755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Entry.getFile().NumCreatedFIDs; 758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Set the number of FileIDs (files and macros) that were created 761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// during preprocessing of \arg FID, including it. 762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const { 763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool Invalid = false; 764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); 765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Invalid || !Entry.isFile()) 766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(Entry.getFile().NumCreatedFIDs == 0 && "Already set!"); 769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const_cast<SrcMgr::FileInfo &>(Entry.getFile()).NumCreatedFIDs = NumFIDs; 770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // SourceLocation manipulation methods. 774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getFileID - Return the FileID for a SourceLocation. This is a very 777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// hot method that is used for all SourceManager queries that start with a 778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// SourceLocation object. It is responsible for finding the entry in 779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// SLocEntryTable which contains the specified location. 780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID getFileID(SourceLocation SpellingLoc) const { 782e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang unsigned SLocOffset = SpellingLoc.getOffset(); 783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // If our one-entry cache covers this offset, just return it. 785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (isOffsetInFileID(LastFileIDLookup, SLocOffset)) 786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return LastFileIDLookup; 787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getFileIDSlow(SLocOffset); 789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getLocForStartOfFile - Return the source location corresponding to the 792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// first byte of the specified file. 793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation getLocForStartOfFile(FileID FID) const { 794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool Invalid = false; 795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); 796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Invalid || !Entry.isFile()) 797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SourceLocation(); 798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned FileOffset = Entry.getOffset(); 800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SourceLocation::getFileLoc(FileOffset); 801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Returns the include location if \arg FID is a #include'd file 804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// otherwise it returns an invalid location. 805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation getIncludeLoc(FileID FID) const { 806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool Invalid = false; 807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); 808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Invalid || !Entry.isFile()) 809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return SourceLocation(); 810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Entry.getFile().getIncludeLoc(); 812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getExpansionLoc - Given a SourceLocation object, return the expansion 815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// location referenced by the ID. 816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation getExpansionLoc(SourceLocation Loc) const { 817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Handle the non-mapped case inline, defer to out of line code to handle 818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // expansions. 819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Loc.isFileID()) return Loc; 820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getExpansionLocSlowCase(Loc); 821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getImmediateExpansionRange - Loc is required to be an expansion location. 824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Return the start/end of the expansion information. 825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::pair<SourceLocation,SourceLocation> 826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project getImmediateExpansionRange(SourceLocation Loc) const; 827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getExpansionRange - Given a SourceLocation object, return the range of 829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// tokens covered by the expansion the ultimate file. 830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::pair<SourceLocation,SourceLocation> 831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project getExpansionRange(SourceLocation Loc) const; 832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getSpellingLoc - Given a SourceLocation object, return the spelling 835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// location referenced by the ID. This is the place where the characters 836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// that make up the lexed token can be found. 837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation getSpellingLoc(SourceLocation Loc) const { 838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Handle the non-mapped case inline, defer to out of line code to handle 839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // expansions. 840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Loc.isFileID()) return Loc; 841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getSpellingLocSlowCase(Loc); 842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getImmediateSpellingLoc - Given a SourceLocation object, return the 845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// spelling location referenced by the ID. This is the first level down 846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// towards the place where the characters that make up the lexed token can be 847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// found. This should not generally be used by clients. 848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const; 849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getDecomposedLoc - Decompose the specified location into a raw FileID + 851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Offset pair. The first element is the FileID, the second is the 852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// offset from the start of the buffer of the location. 853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const { 854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID FID = getFileID(Loc); 855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset()); 856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getDecomposedExpansionLoc - Decompose the specified location into a raw 859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// FileID + Offset pair. If the location is an expansion record, walk 860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// through it until we find the final location expanded. 861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::pair<FileID, unsigned> 862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project getDecomposedExpansionLoc(SourceLocation Loc) const { 863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID FID = getFileID(Loc); 864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry *E = &getSLocEntry(FID); 865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned Offset = Loc.getOffset()-E->getOffset(); 867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Loc.isFileID()) 868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return std::make_pair(FID, Offset); 869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getDecomposedExpansionLocSlowCase(E); 871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getDecomposedSpellingLoc - Decompose the specified location into a raw 874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// FileID + Offset pair. If the location is an expansion record, walk 875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// through it until we find its spelling record. 876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project std::pair<FileID, unsigned> 877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project getDecomposedSpellingLoc(SourceLocation Loc) const { 878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FileID FID = getFileID(Loc); 879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SrcMgr::SLocEntry *E = &getSLocEntry(FID); 880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned Offset = Loc.getOffset()-E->getOffset(); 882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Loc.isFileID()) 883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return std::make_pair(FID, Offset); 884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getDecomposedSpellingLocSlowCase(E, Offset); 885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getFileOffset - This method returns the offset from the start 888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// of the file that the specified SourceLocation represents. This is not very 889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// meaningful for a macro ID. 890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getFileOffset(SourceLocation SpellingLoc) const { 891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getDecomposedLoc(SpellingLoc).second; 892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 893a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 894a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// isMacroArgExpansion - This method tests whether the given source location 895a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// represents a macro argument's expansion into the function-like macro 896a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// definition. Such source locations only appear inside of the expansion 897a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// locations representing where a particular function-like macro was 898a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// expanded. 899a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang bool isMacroArgExpansion(SourceLocation Loc) const; 900a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 901a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// \brief Returns true if \arg Loc is inside the [\arg Start, +\arg Length) 902a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// chunk of the source location address space. 903a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// If it's true and \arg RelativeOffset is non-null, it will be set to the 904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// relative offset of \arg Loc inside the chunk. 905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isInSLocAddrSpace(SourceLocation Loc, 906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SourceLocation Start, unsigned Length, 907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned *RelativeOffset = 0) const { 908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(((Start.getOffset() < NextLocalOffset && 909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Start.getOffset()+Length <= NextLocalOffset) || 910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (Start.getOffset() >= CurrentLoadedOffset && 911a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang Start.getOffset()+Length < MaxLoadedOffset)) && 912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project "Chunk is not valid SLoc address space"); 913a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned LocOffs = Loc.getOffset(); 914a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned BeginOffs = Start.getOffset(); 915a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned EndOffs = BeginOffs + Length; 916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (LocOffs >= BeginOffs && LocOffs < EndOffs) { 917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (RelativeOffset) 918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *RelativeOffset = LocOffs - BeginOffs; 919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return true; 920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 922a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return false; 923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Return true if both \arg LHS and \arg RHS are in the local source 926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// location address space or the loaded one. If it's true and 927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \arg RelativeOffset is non-null, it will be set to the offset of \arg RHS 928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// relative to \arg LHS. 929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isInSameSLocAddrSpace(SourceLocation LHS, SourceLocation RHS, 930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project int *RelativeOffset) const { 931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned LHSOffs = LHS.getOffset(), RHSOffs = RHS.getOffset(); 932a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang bool LHSLoaded = LHSOffs >= CurrentLoadedOffset; 933a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang bool RHSLoaded = RHSOffs >= CurrentLoadedOffset; 934a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (LHSLoaded == RHSLoaded) { 936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (RelativeOffset) 937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *RelativeOffset = RHSOffs - LHSOffs; 938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return true; 939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 941a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return false; 942a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } 943a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 944a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang //===--------------------------------------------------------------------===// 945a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang // Queries about the code at a SourceLocation. 946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 947a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 948a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// getCharacterData - Return a pointer to the start of the specified location 949a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// in the appropriate spelling MemoryBuffer. 950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 951a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// \param Invalid If non-NULL, will be set \c true if an error occurs. 952a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang const char *getCharacterData(SourceLocation SL, bool *Invalid = 0) const; 953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getColumnNumber - Return the column # for the specified file position. 955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// This is significantly cheaper to compute than the line number. This 956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// returns zero if the column number isn't known. This may only be called 957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// on a file sloc, so you must choose a spelling or expansion location 958a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// before calling this method. 959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getColumnNumber(FileID FID, unsigned FilePos, 960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool *Invalid = 0) const; 961a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid = 0) const; 962a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned getExpansionColumnNumber(SourceLocation Loc, 963a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang bool *Invalid = 0) const; 964a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid = 0) const; 965a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 966a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getLineNumber - Given a SourceLocation, return the spelling line number 968a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// for the position indicated. This requires building and caching a table of 969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// line offsets for the MemoryBuffer, so this is not cheap: use only when 970a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// about to emit a diagnostic. 971a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const; 972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const; 973a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = 0) const; 974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = 0) const; 975a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 976a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// Return the filename or buffer identifier of the buffer the location is in. 977a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// Note that this name does not respect #line directives. Use getPresumedLoc 978a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// for normal clients. 979a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang const char *getBufferName(SourceLocation Loc, bool *Invalid = 0) const; 980a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 981a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// getFileCharacteristic - return the file characteristic of the specified 982a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// source location, indicating whether this is a normal file, a system 983a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// header, or an "implicit extern C" system header. 984a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// 985a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// This state can be modified with flags on GNU linemarker directives like: 986a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// # 4 "foo.h" 3 987a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// which changes all source locations in the current file after that to be 988a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// considered to be from a system header. 989a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const; 990a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 991a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// getPresumedLoc - This method returns the "presumed" location of a 992a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// SourceLocation specifies. A "presumed location" can be modified by #line 993a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// or GNU line marker directives. This provides a view on the data that a 994a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// user should see in diagnostics, for example. 995a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// 996a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// Note that a presumed location is always given as the expansion point of 997a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// an expansion location, not at the spelling location. 998a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// 999a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// \returns The presumed location of the specified SourceLocation. If the 1000a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// presumed location cannot be calculate (e.g., because \p Loc is invalid 1001a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// or the file containing \p Loc has changed on disk), returns an invalid 1002a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// presumed location. 1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project PresumedLoc getPresumedLoc(SourceLocation Loc) const; 1004a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1005a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// isFromSameFile - Returns true if both SourceLocations correspond to 1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// the same file. 1007a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const { 1008a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return getFileID(Loc1) == getFileID(Loc2); 1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1010a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1011a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// isFromMainFile - Returns true if the file of provided SourceLocation is 1012a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// the main file. 1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isFromMainFile(SourceLocation Loc) const { 1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getFileID(Loc) == getMainFileID(); 1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// isInSystemHeader - Returns if a SourceLocation is in a system header. 1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isInSystemHeader(SourceLocation Loc) const { 1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getFileCharacteristic(Loc) != SrcMgr::C_User; 1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// isInExternCSystemHeader - Returns if a SourceLocation is in an "extern C" 1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// system header. 1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isInExternCSystemHeader(SourceLocation Loc) const { 1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem; 1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1027a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1028a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// \brief The size of the SLocEnty that \arg FID represents. 1029a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang unsigned getFileIDSize(FileID FID) const; 1030a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1031a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// \brief Given a specific FileID, returns true if \arg Loc is inside that 1032a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// FileID chunk and sets relative offset (offset of \arg Loc from beginning 1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// of FileID) to \arg relativeOffset. 1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isInFileID(SourceLocation Loc, FileID FID, 1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned *RelativeOffset = 0) const { 1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned Offs = Loc.getOffset(); 1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (isOffsetInFileID(FID, Offs)) { 1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (RelativeOffset) 1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *RelativeOffset = Offs - getSLocEntry(FID).getOffset(); 1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return true; 1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1043a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return false; 1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1045a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1046a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang //===--------------------------------------------------------------------===// 1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Line Table Manipulation Routines 1048a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang //===--------------------------------------------------------------------===// 1049a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getLineTableFilenameID - Return the uniqued ID for the specified filename. 1051a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// 1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getLineTableFilenameID(StringRef Str); 1053a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1054a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// AddLineNote - Add a line note to the line table for the FileID and offset 1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// specified by Loc. If FilenameID is -1, it is considered to be 1056a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// unspecified. 1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID); 1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, 1059a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang bool IsFileEntry, bool IsFileExit, 1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool IsSystemHeader, bool IsExternCHeader); 1061a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Determine if the source manager has a line table. 1063a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang bool hasLineTable() const { return LineTable != 0; } 1064a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1065a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// \brief Retrieve the stored line table. 1066a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang LineTableInfo &getLineTable(); 1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 1069a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang // Queries for performance analysis. 1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project //===--------------------------------------------------------------------===// 1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1072a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// Return the total amount of physical memory allocated by the 1073a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /// ContentCache allocator. 1074a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang size_t getContentCacheSize() const { 1075a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return ContentCacheAlloc.getTotalMemory(); 1076a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang } 1077a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project struct MemoryBufferSizes { 1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const size_t malloc_bytes; 1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const size_t mmap_bytes; 1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1082 MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes) 1083 : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} 1084 }; 1085 1086 /// Return the amount of memory used by memory buffers, breaking down 1087 /// by heap-backed versus mmap'ed memory. 1088 MemoryBufferSizes getMemoryBufferSizes() const; 1089 1090 // Return the amount of memory used for various side tables and 1091 // data structures in the SourceManager. 1092 size_t getDataStructureSizes() const; 1093 1094 //===--------------------------------------------------------------------===// 1095 // Other miscellaneous methods. 1096 //===--------------------------------------------------------------------===// 1097 1098 /// \brief Get the source location for the given file:line:col triplet. 1099 /// 1100 /// If the source file is included multiple times, the source location will 1101 /// be based upon the first inclusion. 1102 /// 1103 /// If the location points inside a function macro argument, the returned 1104 /// location will be the macro location in which the argument was expanded. 1105 /// \sa getMacroArgExpandedLocation 1106 SourceLocation getLocation(const FileEntry *SourceFile, 1107 unsigned Line, unsigned Col) { 1108 SourceLocation Loc = translateFileLineCol(SourceFile, Line, Col); 1109 return getMacroArgExpandedLocation(Loc); 1110 } 1111 1112 /// \brief Get the source location for the given file:line:col triplet. 1113 /// 1114 /// If the source file is included multiple times, the source location will 1115 /// be based upon the first inclusion. 1116 SourceLocation translateFileLineCol(const FileEntry *SourceFile, 1117 unsigned Line, unsigned Col); 1118 1119 /// \brief If \arg Loc points inside a function macro argument, the returned 1120 /// location will be the macro location in which the argument was expanded. 1121 /// If a macro argument is used multiple times, the expanded location will 1122 /// be at the first expansion of the argument. 1123 /// e.g. 1124 /// MY_MACRO(foo); 1125 /// ^ 1126 /// Passing a file location pointing at 'foo', will yield a macro location 1127 /// where 'foo' was expanded into. 1128 SourceLocation getMacroArgExpandedLocation(SourceLocation Loc); 1129 1130 /// \brief Determines the order of 2 source locations in the translation unit. 1131 /// 1132 /// \returns true if LHS source location comes before RHS, false otherwise. 1133 bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const; 1134 1135 /// \brief Comparison function class. 1136 class LocBeforeThanCompare : public std::binary_function<SourceLocation, 1137 SourceLocation, bool> { 1138 SourceManager &SM; 1139 1140 public: 1141 explicit LocBeforeThanCompare(SourceManager &SM) : SM(SM) { } 1142 1143 bool operator()(SourceLocation LHS, SourceLocation RHS) const { 1144 return SM.isBeforeInTranslationUnit(LHS, RHS); 1145 } 1146 }; 1147 1148 /// \brief Determines the order of 2 source locations in the "source location 1149 /// address space". 1150 bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const { 1151 return isBeforeInSLocAddrSpace(LHS, RHS.getOffset()); 1152 } 1153 1154 /// \brief Determines the order of a source location and a source location 1155 /// offset in the "source location address space". 1156 /// 1157 /// Note that we always consider source locations loaded from 1158 bool isBeforeInSLocAddrSpace(SourceLocation LHS, unsigned RHS) const { 1159 unsigned LHSOffset = LHS.getOffset(); 1160 bool LHSLoaded = LHSOffset >= CurrentLoadedOffset; 1161 bool RHSLoaded = RHS >= CurrentLoadedOffset; 1162 if (LHSLoaded == RHSLoaded) 1163 return LHSOffset < RHS; 1164 1165 return LHSLoaded; 1166 } 1167 1168 // Iterators over FileInfos. 1169 typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> 1170 ::const_iterator fileinfo_iterator; 1171 fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); } 1172 fileinfo_iterator fileinfo_end() const { return FileInfos.end(); } 1173 bool hasFileInfo(const FileEntry *File) const { 1174 return FileInfos.find(File) != FileInfos.end(); 1175 } 1176 1177 /// PrintStats - Print statistics to stderr. 1178 /// 1179 void PrintStats() const; 1180 1181 /// \brief Get the number of local SLocEntries we have. 1182 unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); } 1183 1184 /// \brief Get a local SLocEntry. This is exposed for indexing. 1185 const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index, 1186 bool *Invalid = 0) const { 1187 assert(Index < LocalSLocEntryTable.size() && "Invalid index"); 1188 return LocalSLocEntryTable[Index]; 1189 } 1190 1191 /// \brief Get the number of loaded SLocEntries we have. 1192 unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();} 1193 1194 /// \brief Get a loaded SLocEntry. This is exposed for indexing. 1195 const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index, bool *Invalid=0) const { 1196 assert(Index < LoadedSLocEntryTable.size() && "Invalid index"); 1197 if (!SLocEntryLoaded[Index]) 1198 ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2)); 1199 return LoadedSLocEntryTable[Index]; 1200 } 1201 1202 const SrcMgr::SLocEntry &getSLocEntry(FileID FID, bool *Invalid = 0) const { 1203 return getSLocEntryByID(FID.ID); 1204 } 1205 1206 unsigned getNextLocalOffset() const { return NextLocalOffset; } 1207 1208 void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) { 1209 assert(LoadedSLocEntryTable.empty() && 1210 "Invalidating existing loaded entries"); 1211 ExternalSLocEntries = Source; 1212 } 1213 1214 /// \brief Allocate a number of loaded SLocEntries, which will be actually 1215 /// loaded on demand from the external source. 1216 /// 1217 /// NumSLocEntries will be allocated, which occupy a total of TotalSize space 1218 /// in the global source view. The lowest ID and the base offset of the 1219 /// entries will be returned. 1220 std::pair<int, unsigned> 1221 AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize); 1222 1223private: 1224 const llvm::MemoryBuffer *getFakeBufferForRecovery() const; 1225 1226 /// \brief Get the entry with the given unwrapped FileID. 1227 const SrcMgr::SLocEntry &getSLocEntryByID(int ID) const { 1228 assert(ID != -1 && "Using FileID sentinel value"); 1229 if (ID < 0) 1230 return getLoadedSLocEntryByID(ID); 1231 return getLocalSLocEntry(static_cast<unsigned>(ID)); 1232 } 1233 1234 const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID) const { 1235 return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2)); 1236 } 1237 1238 /// createExpansionLoc - Implements the common elements of storing an 1239 /// expansion info struct into the SLocEntry table and producing a source 1240 /// location that refers to it. 1241 SourceLocation createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion, 1242 unsigned TokLength, 1243 int LoadedID = 0, 1244 unsigned LoadedOffset = 0); 1245 1246 /// isOffsetInFileID - Return true if the specified FileID contains the 1247 /// specified SourceLocation offset. This is a very hot method. 1248 inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const { 1249 const SrcMgr::SLocEntry &Entry = getSLocEntry(FID); 1250 // If the entry is after the offset, it can't contain it. 1251 if (SLocOffset < Entry.getOffset()) return false; 1252 1253 // If this is the very last entry then it does. 1254 if (FID.ID == -2) 1255 return true; 1256 1257 // If it is the last local entry, then it does if the location is local. 1258 if (static_cast<unsigned>(FID.ID+1) == LocalSLocEntryTable.size()) { 1259 return SLocOffset < NextLocalOffset; 1260 } 1261 1262 // Otherwise, the entry after it has to not include it. This works for both 1263 // local and loaded entries. 1264 return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset(); 1265 } 1266 1267 /// createFileID - Create a new fileID for the specified ContentCache and 1268 /// include position. This works regardless of whether the ContentCache 1269 /// corresponds to a file or some other input source. 1270 FileID createFileID(const SrcMgr::ContentCache* File, 1271 SourceLocation IncludePos, 1272 SrcMgr::CharacteristicKind DirCharacter, 1273 int LoadedID, unsigned LoadedOffset); 1274 1275 const SrcMgr::ContentCache * 1276 getOrCreateContentCache(const FileEntry *SourceFile); 1277 1278 /// createMemBufferContentCache - Create a new ContentCache for the specified 1279 /// memory buffer. 1280 const SrcMgr::ContentCache* 1281 createMemBufferContentCache(const llvm::MemoryBuffer *Buf); 1282 1283 FileID getFileIDSlow(unsigned SLocOffset) const; 1284 FileID getFileIDLocal(unsigned SLocOffset) const; 1285 FileID getFileIDLoaded(unsigned SLocOffset) const; 1286 1287 SourceLocation getExpansionLocSlowCase(SourceLocation Loc) const; 1288 SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; 1289 1290 std::pair<FileID, unsigned> 1291 getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const; 1292 std::pair<FileID, unsigned> 1293 getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, 1294 unsigned Offset) const; 1295 void computeMacroArgsCache(SrcMgr::ContentCache *Content, FileID FID); 1296}; 1297 1298 1299} // end namespace clang 1300 1301#endif 1302