SourceManager.h revision f6ac97b101c8840efa92bf29166077ce4049e293
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file defines the SourceManager interface. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_SOURCEMANAGER_H 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_SOURCEMANAGER_H 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/SourceLocation.h" 180d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner#include "llvm/Support/Allocator.h" 199f8eb2032030482b1d3de86e9bee725d93564302Chandler Carruth#include "llvm/System/DataTypes.h" 20aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor#include "llvm/ADT/PointerUnion.h" 210d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner#include "llvm/ADT/DenseMap.h" 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <vector> 239dc62f044a6ba21f503bd56607d94b32704e7945Chris Lattner#include <cassert> 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace llvm { 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass MemoryBuffer; 27aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregorclass StringRef; 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 32aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregorclass Diagnostic; 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass SourceManager; 34099b4747042352f69184481a48508b599a8d3f73Ted Kremenekclass FileManager; 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileEntry; 365b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattnerclass LineTableInfo; 37aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 380b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner/// SrcMgr - Public enums and private classes that are part of the 390b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner/// SourceManager implementation. 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace SrcMgr { 429d72851fec9e9c62570a027d42701562bbf29751Chris Lattner /// CharacteristicKind - This is used to represent whether a file or directory 430b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner /// holds normal user code, system code, or system code which is implicitly 440b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner /// 'extern "C"' in C++ mode. Entire directories can be tagged with this 450b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner /// (this is maintained by DirectoryLookup and friends) as can specific 460b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner /// FileIDInfos when a #pragma system_header is seen or various other cases. 470b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner /// 489d72851fec9e9c62570a027d42701562bbf29751Chris Lattner enum CharacteristicKind { 490b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner C_User, C_System, C_ExternCSystem 500b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner }; 511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5278d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// ContentCache - Once instance of this struct is kept for every file 5306a062dc784c609b75dca15fd97f468d0d846596Chris Lattner /// loaded or used. This object owns the MemoryBuffer object. 54c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek class ContentCache { 55c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// Buffer - The actual buffer containing the characters from the input 56c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// file. This is owned by the ContentCache object. 5705816591ec488a933dfecc9ff9f3cbf3c32767c2Chris Lattner mutable const llvm::MemoryBuffer *Buffer; 58c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek 59c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek public: 6078d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// Reference to the file entry. This reference does not own 6178d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// the FileEntry object. It is possible for this to be NULL if 6278d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// the ContentCache encapsulates an imaginary text buffer. 6305816591ec488a933dfecc9ff9f3cbf3c32767c2Chris Lattner const FileEntry *Entry; 641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 650d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner /// SourceLineCache - A bump pointer allocated array of offsets for each 660d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner /// source line. This is lazily computed. This is owned by the 670d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner /// SourceManager BumpPointerAllocator object. 6805816591ec488a933dfecc9ff9f3cbf3c32767c2Chris Lattner unsigned *SourceLineCache; 691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 70b6427f821de8cce1566fb6e755143ea0918d5543Ted Kremenek /// NumLines - The number of lines in this ContentCache. This is only valid 71b6427f821de8cce1566fb6e755143ea0918d5543Ted Kremenek /// if SourceLineCache is non-null. 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumLines; 7310b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis 7436c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor /// getBuffer - Returns the memory buffer for the associated content. 7536c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor /// 7636c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor /// \param Diag Object through which diagnostics will be emitted it the 7736c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor /// buffer cannot be retrieved. 7836c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor /// 7936c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor /// \param Invalid If non-NULL, will be set \c true if an error occurred. 8036c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag, 8136c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor bool *Invalid = 0) const; 821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 83c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// getSize - Returns the size of the content encapsulated by this 84c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// ContentCache. This can be the size of the source file or the size of an 85c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// arbitrary scratch buffer. If the ContentCache encapsulates a source 86c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// file this size is retrieved from the file's FileEntry. 87c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek unsigned getSize() const; 881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 89c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// getSizeBytesMapped - Returns the number of bytes actually mapped for 90c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// this ContentCache. This can be 0 if the MemBuffer was not actually 91c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek /// instantiated. 92c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek unsigned getSizeBytesMapped() const; 931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9405816591ec488a933dfecc9ff9f3cbf3c32767c2Chris Lattner void setBuffer(const llvm::MemoryBuffer *B) { 95c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek assert(!Buffer && "MemoryBuffer already set."); 96c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek Buffer = B; 97c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek } 981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 992968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// \brief Replace the existing buffer (which will be deleted) 1002968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// with the given buffer. 1012968442603b029949246467253eeac8139a5b6d8Douglas Gregor void replaceBuffer(const llvm::MemoryBuffer *B); 1022968442603b029949246467253eeac8139a5b6d8Douglas Gregor 1030d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner ContentCache(const FileEntry *Ent = 0) 1042968442603b029949246467253eeac8139a5b6d8Douglas Gregor : Buffer(0), Entry(Ent), SourceLineCache(0), NumLines(0) {} 10578d85f53b093867bbb0123f016956178eea7343eTed Kremenek 10678d85f53b093867bbb0123f016956178eea7343eTed Kremenek ~ContentCache(); 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1080d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek /// The copy ctor does not allow copies where source object has either 1090d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory 1100d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek /// is not transfered, so this is a logical error. 1112968442603b029949246467253eeac8139a5b6d8Douglas Gregor ContentCache(const ContentCache &RHS) : Buffer(0), SourceLineCache(0) { 1120d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek Entry = RHS.Entry; 1130d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek 1140d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner assert (RHS.Buffer == 0 && RHS.SourceLineCache == 0 1150d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek && "Passed ContentCache object cannot own a buffer."); 1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump NumLines = RHS.NumLines; 1180d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek } 1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1200d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek private: 1210d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek // Disable assignments. 1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ContentCache &operator=(const ContentCache& RHS); 1231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump }; 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 125de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// FileInfo - Information about a FileID, basically just the logical file 126de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// that it represents and include stack information. 1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 128de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// Each FileInfo has include stack information, indicating where it came 129de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// from. This information encodes the #include chain that a token was 130de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// instantiated from. The main include file has an invalid IncludeLoc. 1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 132de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// FileInfos contain a "ContentCache *", with the contents of the file. 1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 134de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner class FileInfo { 1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IncludeLoc - The location of the #include that brought in this file. 136de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// This is an invalid SLOC for the main file (top of the #include chain). 137de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned IncludeLoc; // Really a SourceLocation 1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1396e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner /// Data - This contains the ContentCache* and the bits indicating the 1406e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner /// characteristic of the file and whether it has #line info, all bitmangled 1416e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner /// together. 1426e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner uintptr_t Data; 14378d85f53b093867bbb0123f016956178eea7343eTed Kremenek public: 144de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// get - Return a FileInfo object. 145de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner static FileInfo get(SourceLocation IL, const ContentCache *Con, 146de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner CharacteristicKind FileCharacter) { 147de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileInfo X; 148de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner X.IncludeLoc = IL.getRawEncoding(); 1496e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner X.Data = (uintptr_t)Con; 15000282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned"); 1516e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner assert((unsigned)FileCharacter < 4 && "invalid file character"); 1526e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner X.Data |= (unsigned)FileCharacter; 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return X; 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 156de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation getIncludeLoc() const { 157de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return SourceLocation::getFromRawEncoding(IncludeLoc); 158de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 1596e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner const ContentCache* getContentCache() const { 16000282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner return reinterpret_cast<const ContentCache*>(Data & ~7UL); 1616e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner } 1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1630b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner /// getCharacteristic - Return whether this is a system header or not. 1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CharacteristicKind getFileCharacteristic() const { 1656e1aff2f586025f2d385ee49239f626b0fc63fd7Chris Lattner return (CharacteristicKind)(Data & 3); 1660b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner } 167ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 168ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner /// hasLineDirectives - Return true if this FileID has #line directives in 169ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner /// it. 170ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner bool hasLineDirectives() const { return (Data & 4) != 0; } 1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 172ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner /// setHasLineDirectives - Set the flag that indicates that this FileID has 173ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner /// line table entries associated with it. 174ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner void setHasLineDirectives() { 175ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner Data |= 4; 176ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner } 1779dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner }; 1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 179de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation 180de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// location - where the token was ultimately instantiated, and the 181de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// SpellingLoc - where the actual character data for the token came from. 182de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner class InstantiationInfo { 183e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner // Really these are all SourceLocations. 1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 185e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// SpellingLoc - Where the spelling for the token can be found. 186e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner unsigned SpellingLoc; 1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 188e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these 18914f79002e58556798e86168c63e48d533287eda5Douglas Gregor /// indicate the start and end of the instantiation. In object-like macros, 190e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// these will be the same. In a function-like macro instantiation, the 191e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// start will be the identifier and the end will be the ')'. 192e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner unsigned InstantiationLocStart, InstantiationLocEnd; 1939dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner public: 194de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation getSpellingLoc() const { 195de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return SourceLocation::getFromRawEncoding(SpellingLoc); 196de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 197e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner SourceLocation getInstantiationLocStart() const { 198e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner return SourceLocation::getFromRawEncoding(InstantiationLocStart); 199e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner } 200e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner SourceLocation getInstantiationLocEnd() const { 201e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner return SourceLocation::getFromRawEncoding(InstantiationLocEnd); 202e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner } 2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 204e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const { 205e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner return std::make_pair(getInstantiationLocStart(), 206e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner getInstantiationLocEnd()); 207e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner } 2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 209e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// get - Return a InstantiationInfo for an expansion. IL specifies 210df7c17a8d02fe09a3466786bae3e40fc3252687aChris Lattner /// the instantiation location (where the macro is expanded), and SL 211df7c17a8d02fe09a3466786bae3e40fc3252687aChris Lattner /// specifies the spelling location (where the characters from the token 212e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// come from). IL and PL can both refer to normal File SLocs or 213e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// instantiation locations. 214e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner static InstantiationInfo get(SourceLocation ILStart, SourceLocation ILEnd, 215e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner SourceLocation SL) { 216de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner InstantiationInfo X; 217de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner X.SpellingLoc = SL.getRawEncoding(); 218e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner X.InstantiationLocStart = ILStart.getRawEncoding(); 219e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner X.InstantiationLocEnd = ILEnd.getRawEncoding(); 2209dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner return X; 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 222de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner }; 2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 224de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// SLocEntry - This is a discriminated union of FileInfo and 225de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// InstantiationInfo. SourceManager keeps an array of these objects, and 226de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// they are uniquely identified by the FileID datatype. 227de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner class SLocEntry { 228de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned Offset; // low bit is set for instantiation info. 229de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner union { 230de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileInfo File; 231de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner InstantiationInfo Instantiation; 232de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner }; 233de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner public: 234de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned getOffset() const { return Offset >> 1; } 2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 236de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner bool isInstantiation() const { return Offset & 1; } 237de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner bool isFile() const { return !isInstantiation(); } 2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 239de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner const FileInfo &getFile() const { 240de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner assert(isFile() && "Not a file SLocEntry!"); 241de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return File; 242de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 243de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 244de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner const InstantiationInfo &getInstantiation() const { 245de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner assert(isInstantiation() && "Not an instantiation SLocEntry!"); 246de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return Instantiation; 247de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 249de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner static SLocEntry get(unsigned Offset, const FileInfo &FI) { 250de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SLocEntry E; 251de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner E.Offset = Offset << 1; 252de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner E.File = FI; 253de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return E; 254de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 255de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 256de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner static SLocEntry get(unsigned Offset, const InstantiationInfo &II) { 257de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SLocEntry E; 258de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner E.Offset = (Offset << 1) | 1; 259de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner E.Instantiation = II; 260de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return E; 261de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer }; 2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end SrcMgr namespace. 2647f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 2657f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor/// \brief External source of source location entries. 2667f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregorclass ExternalSLocEntrySource { 2677f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregorpublic: 2687f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor virtual ~ExternalSLocEntrySource(); 2697f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 2707f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor /// \brief Read the source location entry with index ID. 2717f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor virtual void ReadSLocEntry(unsigned ID) = 0; 2727f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor}; 2737f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// SourceManager - This file handles loading and caching of source files into 2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// memory. This object owns the MemoryBuffer objects for all of the loaded 2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// files and assigns unique FileID's for each unique #include chain. 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// The SourceManager can be queried for information about SourceLocation 279f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner/// objects, turning them into either spelling or instantiation locations. 280f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner/// Spelling locations represent where the bytes corresponding to a token came 281f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner/// from and instantiation locations represent where the location is in the 282f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner/// user's view. In the case of a macro expansion, for example, the spelling 283f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner/// location indicates where the expanded token came from and the instantiation 284f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner/// location specifies where it was expanded. 2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass SourceManager { 286f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor /// \brief Diagnostic object. 287f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor Diagnostic &Diag; 288f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor 2890d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner mutable llvm::BumpPtrAllocator ContentCacheAlloc; 2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// FileInfos - Memoized information about all of the files tracked by this 2920d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek /// SourceManager. This set allows us to merge ContentCache entries based 2930d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek /// on their FileEntry*. All ContentCache objects will thus have unique, 2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// non-null, FileEntry pointers. 2950d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos; 2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// MemBufferInfos - Information about various memory buffers that we have 2980d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner /// read in. All FileEntry* within the stored ContentCache objects are NULL, 2990d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner /// as they do not refer to a file. 3000d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner std::vector<SrcMgr::ContentCache*> MemBufferInfos; 3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 302de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// SLocEntryTable - This is an array of SLocEntry's that we have created. 303de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// FileID is an index into this vector. This array is sorted by the offset. 304de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::vector<SrcMgr::SLocEntry> SLocEntryTable; 305de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// NextOffset - This is the next available offset that a new SLocEntry can 306de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// start at. It is SLocEntryTable.back().getOffset()+size of back() entry. 307de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned NextOffset; 3087f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 3097f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor /// \brief If source location entries are being lazily loaded from 3107f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor /// an external source, this vector indicates whether the Ith source 3117f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor /// location entry has already been loaded from the external storage. 3127f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor std::vector<bool> SLocEntryLoaded; 3137f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 3147f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor /// \brief An external source for source location entries. 3157f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor ExternalSLocEntrySource *ExternalSLocEntries; 3167f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 317de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// LastFileIDLookup - This is a one-entry cache to speed up getFileID. 318de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// LastFileIDLookup records the last FileID looked up or created, because it 319de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// is very common to look up many tokens from the same file. 320de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner mutable FileID LastFileIDLookup; 3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3225b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner /// LineTable - This holds information for #line directives. It is referenced 3235b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner /// by indices from SLocEntryTable. 3245b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LineTableInfo *LineTable; 3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3265e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner /// LastLineNo - These ivars serve as a cache used in the getLineNumber 3275e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner /// method which is used to speedup getLineNumber calls to nearby locations. 3282b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner mutable FileID LastLineNoFileIDQuery; 329f812a45dd93634c9300ed5533bd26b56374714a1Chris Lattner mutable SrcMgr::ContentCache *LastLineNoContentCache; 330f812a45dd93634c9300ed5533bd26b56374714a1Chris Lattner mutable unsigned LastLineNoFilePos; 331f812a45dd93634c9300ed5533bd26b56374714a1Chris Lattner mutable unsigned LastLineNoResult; 3321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 33376edd0e4ae0592a7225d50d0bad6732ac64dca2aTed Kremenek /// MainFileID - The file ID for the main source file of the translation unit. 3342b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner FileID MainFileID; 33549c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff 336de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Statistics for -print-stats. 337de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner mutable unsigned NumLinearScans, NumBinaryProbes; 3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3392aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis // Cache results for the isBeforeInTranslationUnit method. 3402aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis mutable FileID LastLFIDForBeforeTUCheck; 3412aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis mutable FileID LastRFIDForBeforeTUCheck; 3422aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis mutable bool LastResForBeforeTUCheck; 3431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 34449c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff // SourceManager doesn't support copy construction. 34549c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff explicit SourceManager(const SourceManager&); 3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump void operator=(const SourceManager&); 3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 348f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor SourceManager(Diagnostic &Diag) 349f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor : Diag(Diag), ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), 3502968442603b029949246467253eeac8139a5b6d8Douglas Gregor NumBinaryProbes(0) { 351de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner clearIDTables(); 352de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 3535b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner ~SourceManager(); 3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3555b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner void clearIDTables(); 3561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 35706a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 35806a062dc784c609b75dca15fd97f468d0d846596Chris Lattner // MainFileID creation and querying methods. 35906a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 36006a062dc784c609b75dca15fd97f468d0d846596Chris Lattner 36176edd0e4ae0592a7225d50d0bad6732ac64dca2aTed Kremenek /// getMainFileID - Returns the FileID of the main source file. 3622b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner FileID getMainFileID() const { return MainFileID; } 3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 36406a062dc784c609b75dca15fd97f468d0d846596Chris Lattner /// createMainFileID - Create the FileID for the main source file. 36506a062dc784c609b75dca15fd97f468d0d846596Chris Lattner FileID createMainFileID(const FileEntry *SourceFile, 36606a062dc784c609b75dca15fd97f468d0d846596Chris Lattner SourceLocation IncludePos) { 36706a062dc784c609b75dca15fd97f468d0d846596Chris Lattner assert(MainFileID.isInvalid() && "MainFileID already set!"); 36806a062dc784c609b75dca15fd97f468d0d846596Chris Lattner MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User); 36906a062dc784c609b75dca15fd97f468d0d846596Chris Lattner return MainFileID; 37006a062dc784c609b75dca15fd97f468d0d846596Chris Lattner } 3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 37206a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 373de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Methods to create new FileID's and instantiations. 37406a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 3751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// createFileID - Create a new FileID that represents the specified file 3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// being #included from the specified IncludePosition. This returns 0 on 3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// error and translates NULL into standard input. 3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// PreallocateID should be non-zero to specify which a pre-allocated, 3807f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor /// lazily computed source location is being filled in by this operation. 3812b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, 3827f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor SrcMgr::CharacteristicKind FileCharacter, 3837f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned PreallocatedID = 0, 3847f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned Offset = 0) { 385de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile); 3862b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner if (IR == 0) return FileID(); // Error opening file? 3877f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset); 3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// createFileIDForMemBuffer - Create a new FileID that represents the 3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// specified memory buffer. This does no caching of the buffer and takes 3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once. 3937f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer, 3947f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned PreallocatedID = 0, 3957f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned Offset = 0) { 3967bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber return createFileID(createMemBufferContentCache(Buffer), SourceLocation(), 3977f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor SrcMgr::C_User, PreallocatedID, Offset); 3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4001036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek /// createMainFileIDForMembuffer - Create the FileID for a memory buffer 4011036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek /// that will represent the FileID for the main source. One example 4021036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek /// of when this would be used is when the main source is read from STDIN. 4032b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { 4042b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner assert(MainFileID.isInvalid() && "MainFileID already set!"); 4057697b5c5a918729718da9ecd9e374bbd973a69e9Chris Lattner MainFileID = createFileIDForMemBuffer(Buffer); 4061036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek return MainFileID; 4071036b68525f39cb69ac22c679ed440acd8392a16Ted Kremenek } 40806a062dc784c609b75dca15fd97f468d0d846596Chris Lattner 409de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// createInstantiationLoc - Return a new SourceLocation that encodes the fact 410de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// that a token at Loc should actually be referenced from InstantiationLoc. 411de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// TokLength is the length of the token being instantiated. 412de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation createInstantiationLoc(SourceLocation Loc, 413e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner SourceLocation InstantiationLocStart, 414e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner SourceLocation InstantiationLocEnd, 4157f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned TokLength, 4167f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned PreallocatedID = 0, 4177f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned Offset = 0); 4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4192968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// \brief Retrieve the memory buffer associated with the given file. 42050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor /// 42150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor /// \param Invalid If non-NULL, will be set \c true if an error 42250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor /// occurs while retrieving the memory buffer. 42350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File, 42450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid = 0); 4252968442603b029949246467253eeac8139a5b6d8Douglas Gregor 4262968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// \brief Override the contents of the given source file by providing an 4272968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// already-allocated buffer. 4282968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// 4292968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// \param SourceFile the source file whose contents will be override. 4302968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// 4312968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// \param Buffer the memory buffer whose contents will be used as the 4322968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// data in the given source file. 4332968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// 4342968442603b029949246467253eeac8139a5b6d8Douglas Gregor /// \returns true if an error occurred, false otherwise. 4352968442603b029949246467253eeac8139a5b6d8Douglas Gregor bool overrideFileContents(const FileEntry *SourceFile, 4362968442603b029949246467253eeac8139a5b6d8Douglas Gregor const llvm::MemoryBuffer *Buffer); 4372968442603b029949246467253eeac8139a5b6d8Douglas Gregor 43806a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 43906a062dc784c609b75dca15fd97f468d0d846596Chris Lattner // FileID manipulation methods. 44006a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 4411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4422ffb14f004affc363d86d6c7c63c356190db3679Daniel Dunbar /// getBuffer - Return the buffer for the specified FileID. If there is an 4432ffb14f004affc363d86d6c7c63c356190db3679Daniel Dunbar /// error opening this buffer the first time, this manufactures a temporary 4442ffb14f004affc363d86d6c7c63c356190db3679Daniel Dunbar /// buffer and returns a non-empty error string. 44550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const { 44650f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Diag, 44750f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor Invalid); 44806a062dc784c609b75dca15fd97f468d0d846596Chris Lattner } 4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 45006a062dc784c609b75dca15fd97f468d0d846596Chris Lattner /// getFileEntryForID - Returns the FileEntry record for the provided FileID. 45106a062dc784c609b75dca15fd97f468d0d846596Chris Lattner const FileEntry *getFileEntryForID(FileID FID) const { 452de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return getSLocEntry(FID).getFile().getContentCache()->Entry; 45306a062dc784c609b75dca15fd97f468d0d846596Chris Lattner } 4541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 45506a062dc784c609b75dca15fd97f468d0d846596Chris Lattner /// getBufferData - Return a pointer to the start and end of the source buffer 45606a062dc784c609b75dca15fd97f468d0d846596Chris Lattner /// data for the specified FileID. 457aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor /// 458f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor /// \param FID The file ID whose contents will be returned. 459f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor /// \param Invalid If non-NULL, will be set true if an error occurred. 460f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer llvm::StringRef getBufferData(FileID FID, bool *Invalid = 0) const; 461f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer 4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 46306a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 46406a062dc784c609b75dca15fd97f468d0d846596Chris Lattner // SourceLocation manipulation methods. 46506a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 467668ab1a36d6a5731c71a75a5f388ecafd538a896Chris Lattner /// getFileID - Return the FileID for a SourceLocation. This is a very 468de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// hot method that is used for all SourceManager queries that start with a 469de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// SourceLocation object. It is responsible for finding the entry in 470de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// SLocEntryTable which contains the specified location. 471de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// 472de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID getFileID(SourceLocation SpellingLoc) const { 473de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned SLocOffset = SpellingLoc.getOffset(); 4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 475de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // If our one-entry cache covers this offset, just return it. 476de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (isOffsetInFileID(LastFileIDLookup, SLocOffset)) 477de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return LastFileIDLookup; 478de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 479de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return getFileIDSlow(SLocOffset); 480de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 4811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4822b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner /// getLocForStartOfFile - Return the source location corresponding to the 4832b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner /// first byte of the specified file. 4842b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner SourceLocation getLocForStartOfFile(FileID FID) const { 4857f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor assert(FID.ID < SLocEntryTable.size() && "FileID out of range"); 4867f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor assert(getSLocEntry(FID).isFile() && "FileID is not a file"); 4877f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned FileOffset = getSLocEntry(FID).getOffset(); 488de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return SourceLocation::getFileLoc(FileOffset); 4892b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner } 4901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4916678133b8ce642f93e5141f056fa643112041ad0Chris Lattner /// getInstantiationLoc - Given a SourceLocation object, return the 4926678133b8ce642f93e5141f056fa643112041ad0Chris Lattner /// instantiation location referenced by the ID. 493de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation getInstantiationLoc(SourceLocation Loc) const { 494addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner // Handle the non-mapped case inline, defer to out of line code to handle 495addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner // instantiations. 496de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (Loc.isFileID()) return Loc; 497addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner return getInstantiationLocSlowCase(Loc); 498de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 4991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 500e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// getImmediateInstantiationRange - Loc is required to be an instantiation 501e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner /// location. Return the start/end of the instantiation information. 502e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner std::pair<SourceLocation,SourceLocation> 503e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner getImmediateInstantiationRange(SourceLocation Loc) const; 5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5056678133b8ce642f93e5141f056fa643112041ad0Chris Lattner /// getInstantiationRange - Given a SourceLocation object, return the 5066678133b8ce642f93e5141f056fa643112041ad0Chris Lattner /// range of tokens covered by the instantiation in the ultimate file. 5076678133b8ce642f93e5141f056fa643112041ad0Chris Lattner std::pair<SourceLocation,SourceLocation> 5086678133b8ce642f93e5141f056fa643112041ad0Chris Lattner getInstantiationRange(SourceLocation Loc) const; 5091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 511de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// getSpellingLoc - Given a SourceLocation object, return the spelling 512de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// location referenced by the ID. This is the place where the characters 513de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// that make up the lexed token can be found. 514de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation getSpellingLoc(SourceLocation Loc) const { 515addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner // Handle the non-mapped case inline, defer to out of line code to handle 516addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner // instantiations. 517de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (Loc.isFileID()) return Loc; 518addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner return getSpellingLocSlowCase(Loc); 519de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 521387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner /// getImmediateSpellingLoc - Given a SourceLocation object, return the 522387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner /// spelling location referenced by the ID. This is the first level down 523387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner /// towards the place where the characters that make up the lexed token can be 524387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner /// found. This should not generally be used by clients. 5251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const; 526de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 527de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// getDecomposedLoc - Decompose the specified location into a raw FileID + 528de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// Offset pair. The first element is the FileID, the second is the 529de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// offset from the start of the buffer of the location. 530de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const { 531de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID FID = getFileID(Loc); 532de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset()); 533de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 5341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 535de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// getDecomposedInstantiationLoc - Decompose the specified location into a 536de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// raw FileID + Offset pair. If the location is an instantiation record, 537de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// walk through it until we find the final location instantiated. 538de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::pair<FileID, unsigned> 539de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner getDecomposedInstantiationLoc(SourceLocation Loc) const { 540de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID FID = getFileID(Loc); 541de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner const SrcMgr::SLocEntry *E = &getSLocEntry(FID); 5421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 543de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned Offset = Loc.getOffset()-E->getOffset(); 544de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (Loc.isFileID()) 545de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return std::make_pair(FID, Offset); 5461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 547de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return getDecomposedInstantiationLocSlowCase(E, Offset); 548de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 549de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 550de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// getDecomposedSpellingLoc - Decompose the specified location into a raw 551de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// FileID + Offset pair. If the location is an instantiation record, walk 552de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// through it until we find its spelling record. 553de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::pair<FileID, unsigned> 554de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner getDecomposedSpellingLoc(SourceLocation Loc) const { 555de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID FID = getFileID(Loc); 556de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner const SrcMgr::SLocEntry *E = &getSLocEntry(FID); 5571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 558de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned Offset = Loc.getOffset()-E->getOffset(); 559de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (Loc.isFileID()) 560de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return std::make_pair(FID, Offset); 561de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return getDecomposedSpellingLocSlowCase(E, Offset); 5621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 5631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 56452c29081281955d3db9e11d10573b2d38f709099Chris Lattner /// getFileOffset - This method returns the offset from the start 56552c29081281955d3db9e11d10573b2d38f709099Chris Lattner /// of the file that the specified SourceLocation represents. This is not very 56652c29081281955d3db9e11d10573b2d38f709099Chris Lattner /// meaningful for a macro ID. 56752c29081281955d3db9e11d10573b2d38f709099Chris Lattner unsigned getFileOffset(SourceLocation SpellingLoc) const { 568de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return getDecomposedLoc(SpellingLoc).second; 5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 572de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner //===--------------------------------------------------------------------===// 573de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Queries about the code at a SourceLocation. 574de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner //===--------------------------------------------------------------------===// 5751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getCharacterData - Return a pointer to the start of the specified location 577de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// in the appropriate spelling MemoryBuffer. 57850f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor /// 57950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor /// \param Invalid If non-NULL, will be set \c true if an error occurs. 58050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor const char *getCharacterData(SourceLocation SL, bool *Invalid = 0) const; 5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5829dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner /// getColumnNumber - Return the column # for the specified file position. 5839dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner /// This is significantly cheaper to compute than the line number. This 5849dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner /// returns zero if the column number isn't known. This may only be called on 585f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner /// a file sloc, so you must choose a spelling or instantiation location 586f7cf85b330bedd2877e1371fb0a83e99751ae162Chris Lattner /// before calling this method. 58750f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor unsigned getColumnNumber(FileID FID, unsigned FilePos, 58850f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid = 0) const; 58950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor unsigned getSpellingColumnNumber(SourceLocation Loc, 59050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid = 0) const; 59150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor unsigned getInstantiationColumnNumber(SourceLocation Loc, 59250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid = 0) const; 5931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 595df7c17a8d02fe09a3466786bae3e40fc3252687aChris Lattner /// getLineNumber - Given a SourceLocation, return the spelling line number 5965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// for the position indicated. This requires building and caching a table of 5975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// line offsets for the MemoryBuffer, so this is not cheap: use only when 5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// about to emit a diagnostic. 59950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const; 6001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 60150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor unsigned getInstantiationLineNumber(SourceLocation Loc, 60250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid = 0) const; 60350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const; 6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 605bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner /// Return the filename or buffer identifier of the buffer the location is in. 606bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner /// Note that this name does not respect #line directives. Use getPresumedLoc 607bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner /// for normal clients. 60850f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor const char *getBufferName(SourceLocation Loc, bool *Invalid = 0) const; 6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6106b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner /// getFileCharacteristic - return the file characteristic of the specified 6111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// source location, indicating whether this is a normal file, a system 6126b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner /// header, or an "implicit extern C" system header. 6136b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner /// 6146b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner /// This state can be modified with flags on GNU linemarker directives like: 6156b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner /// # 4 "foo.h" 3 6166b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner /// which changes all source locations in the current file after that to be 6176b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner /// considered to be from a system header. 6186b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const; 6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 620b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner /// getPresumedLoc - This method returns the "presumed" location of a 621b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner /// SourceLocation specifies. A "presumed location" can be modified by #line 622b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner /// or GNU line marker directives. This provides a view on the data that a 623b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner /// user should see in diagnostics, for example. 624b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner /// 625b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner /// Note that a presumed location is always given as the instantiation point 626b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner /// of an instantiation location, not at the spelling location. 627b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner PresumedLoc getPresumedLoc(SourceLocation Loc) const; 6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6299fd87b1db485e2f31d0e5687f9168b370d546847Ted Kremenek /// isFromSameFile - Returns true if both SourceLocations correspond to 6309fd87b1db485e2f31d0e5687f9168b370d546847Ted Kremenek /// the same file. 6319fd87b1db485e2f31d0e5687f9168b370d546847Ted Kremenek bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const { 632a11d61793341fea195c29a0dab3fbd74f2b39a8cChris Lattner return getFileID(Loc1) == getFileID(Loc2); 6339fd87b1db485e2f31d0e5687f9168b370d546847Ted Kremenek } 6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6359fd87b1db485e2f31d0e5687f9168b370d546847Ted Kremenek /// isFromMainFile - Returns true if the file of provided SourceLocation is 6369fd87b1db485e2f31d0e5687f9168b370d546847Ted Kremenek /// the main file. 6379fd87b1db485e2f31d0e5687f9168b370d546847Ted Kremenek bool isFromMainFile(SourceLocation Loc) const { 638a11d61793341fea195c29a0dab3fbd74f2b39a8cChris Lattner return getFileID(Loc) == getMainFileID(); 6391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 6401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6417bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber /// isInSystemHeader - Returns if a SourceLocation is in a system header. 6427bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber bool isInSystemHeader(SourceLocation Loc) const { 6430b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner return getFileCharacteristic(Loc) != SrcMgr::C_User; 644721818304ac462d8c6ce05eecd02884033db78f1Chris Lattner } 6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6460d456588acac0713a7c33063922d35a8cc8c658eChris Lattner /// isInExternCSystemHeader - Returns if a SourceLocation is in an "extern C" 6470d456588acac0713a7c33063922d35a8cc8c658eChris Lattner /// system header. 6480d456588acac0713a7c33063922d35a8cc8c658eChris Lattner bool isInExternCSystemHeader(SourceLocation Loc) const { 6490d456588acac0713a7c33063922d35a8cc8c658eChris Lattner return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem; 6500d456588acac0713a7c33063922d35a8cc8c658eChris Lattner } 6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 65206a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 6535b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner // Line Table Manipulation Routines 6545b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner //===--------------------------------------------------------------------===// 6551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6565b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner /// getLineTableFilenameID - Return the uniqued ID for the specified filename. 6571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// 6585b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner unsigned getLineTableFilenameID(const char *Ptr, unsigned Len); 6591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6604c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner /// AddLineNote - Add a line note to the line table for the FileID and offset 6614c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner /// specified by Loc. If FilenameID is -1, it is considered to be 6624c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner /// unspecified. 6634c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID); 6649d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, 6651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool IsFileEntry, bool IsFileExit, 6669d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner bool IsSystemHeader, bool IsExternCHeader); 667bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor 668bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor /// \brief Determine if the source manager has a line table. 669bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor bool hasLineTable() const { return LineTable != 0; } 670bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor 671bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor /// \brief Retrieve the stored line table. 672bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor LineTableInfo &getLineTable(); 673bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor 6745b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner //===--------------------------------------------------------------------===// 67506a062dc784c609b75dca15fd97f468d0d846596Chris Lattner // Other miscellaneous methods. 67606a062dc784c609b75dca15fd97f468d0d846596Chris Lattner //===--------------------------------------------------------------------===// 67710b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis 67810b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis /// \brief Get the source location for the given file:line:col triplet. 67910b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis /// 68010b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis /// If the source file is included multiple times, the source location will 68110b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis /// be based upon the first inclusion. 68210b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis SourceLocation getLocation(const FileEntry *SourceFile, 68310b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis unsigned Line, unsigned Col) const; 6841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6852aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis /// \brief Determines the order of 2 source locations in the translation unit. 6862aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis /// 6872aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis /// \returns true if LHS source location comes before RHS, false otherwise. 6882aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const; 6892aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis 690c6fe32a91c7372caf09152ee31a24c4b5d24deedChris Lattner // Iterators over FileInfos. 6910d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> 6920d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner ::const_iterator fileinfo_iterator; 693c6fe32a91c7372caf09152ee31a24c4b5d24deedChris Lattner fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); } 694c6fe32a91c7372caf09152ee31a24c4b5d24deedChris Lattner fileinfo_iterator fileinfo_end() const { return FileInfos.end(); } 695d93256e55673a17d18543397ec462416acb13792Douglas Gregor bool hasFileInfo(const FileEntry *File) const { 696d93256e55673a17d18543397ec462416acb13792Douglas Gregor return FileInfos.find(File) != FileInfos.end(); 697d93256e55673a17d18543397ec462416acb13792Douglas Gregor } 698c6fe32a91c7372caf09152ee31a24c4b5d24deedChris Lattner 6995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// PrintStats - Print statistics to stderr. 7005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 7015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats() const; 70278d85f53b093867bbb0123f016956178eea7343eTed Kremenek 70314f79002e58556798e86168c63e48d533287eda5Douglas Gregor unsigned sloc_entry_size() const { return SLocEntryTable.size(); } 7042d684c2499bd80e28451c1db0e2e040ef00c53bcKovarththanan Rajaratnam 70516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // FIXME: Exposing this is a little gross; what we want is a good way 70616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // to iterate the entries that were not defined in a PCH file (or 70716b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // any other external source). 70816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); } 70914f79002e58556798e86168c63e48d533287eda5Douglas Gregor 710bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const { 711bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor assert(ID < SLocEntryTable.size() && "Invalid id"); 7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (ExternalSLocEntries && 713bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor ID < SLocEntryLoaded.size() && 714bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor !SLocEntryLoaded[ID]) 715bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor ExternalSLocEntries->ReadSLocEntry(ID); 716bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor return SLocEntryTable[ID]; 717bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor } 7182d684c2499bd80e28451c1db0e2e040ef00c53bcKovarththanan Rajaratnam 7192d684c2499bd80e28451c1db0e2e040ef00c53bcKovarththanan Rajaratnam const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const { 720bdfe48ac80573e026595af91e541474dbf02565fDouglas Gregor return getSLocEntry(FID.ID); 721bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor } 722bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor 723f60e9918690fcf02974bc1ebecd42c99d561855eDouglas Gregor unsigned getNextOffset() const { return NextOffset; } 724f60e9918690fcf02974bc1ebecd42c99d561855eDouglas Gregor 7257f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor /// \brief Preallocate some number of source location entries, which 7267f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor /// will be loaded as needed from the given external source. 7277f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor void PreallocateSLocEntries(ExternalSLocEntrySource *Source, 7287f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned NumSLocEntries, 7297f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned NextOffset); 7307f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 7312bf1eb09f06a9792fa94dff0703f2aa2c4bace2aDouglas Gregor /// \brief Clear out any preallocated source location entries that 7322bf1eb09f06a9792fa94dff0703f2aa2c4bace2aDouglas Gregor /// haven't already been loaded. 7332bf1eb09f06a9792fa94dff0703f2aa2c4bace2aDouglas Gregor void ClearPreallocatedSLocEntries(); 7342bf1eb09f06a9792fa94dff0703f2aa2c4bace2aDouglas Gregor 7355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate: 736de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// isOffsetInFileID - Return true if the specified FileID contains the 737de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner /// specified SourceLocation offset. This is a very hot method. 738de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const { 739de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner const SrcMgr::SLocEntry &Entry = getSLocEntry(FID); 740de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // If the entry is after the offset, it can't contain it. 741de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (SLocOffset < Entry.getOffset()) return false; 7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 743de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // If this is the last entry than it does. Otherwise, the entry after it 744de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // has to not include it. 745de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (FID.ID+1 == SLocEntryTable.size()) return true; 7467f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 7477f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset(); 748de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 75078d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// createFileID - Create a new fileID for the specified ContentCache and 75178d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// include position. This works regardless of whether the ContentCache 75278d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// corresponds to a file or some other input source. 7532b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner FileID createFileID(const SrcMgr::ContentCache* File, 7542b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner SourceLocation IncludePos, 7557f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor SrcMgr::CharacteristicKind DirCharacter, 7567f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned PreallocatedID = 0, 7577f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor unsigned Offset = 0); 7581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 759de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner const SrcMgr::ContentCache * 760de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner getOrCreateContentCache(const FileEntry *SourceFile); 761c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek 76278d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// createMemBufferContentCache - Create a new ContentCache for the specified 76378d85f53b093867bbb0123f016956178eea7343eTed Kremenek /// memory buffer. 7641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const SrcMgr::ContentCache* 7652b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner createMemBufferContentCache(const llvm::MemoryBuffer *Buf); 7661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 767de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID getFileIDSlow(unsigned SLocOffset) const; 768de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 769addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const; 770addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; 771addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 772de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::pair<FileID, unsigned> 773de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, 7741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned Offset) const; 775de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::pair<FileID, unsigned> 776de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, 777de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned Offset) const; 7785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 7795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end namespace clang 7825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 784