15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- SourceManager.cpp - Track and cache source files -----------------===// 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 implements the SourceManager interface. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/SourceManager.h" 15aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor#include "clang/Basic/Diagnostic.h" 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/FileManager.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceManagerInternals.h" 1886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor#include "llvm/ADT/Optional.h" 19d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis#include "llvm/ADT/STLExtras.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringSwitch.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Capacity.h" 225e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner#include "llvm/Support/Compiler.h" 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/MemoryBuffer.h" 2403013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h" 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <algorithm> 27f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor#include <cstring> 2855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include <string> 2986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor#include <sys/stat.h> 30aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace SrcMgr; 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::MemoryBuffer; 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3523b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 36de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// SourceManager Helper Classes 3723b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 38de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 3978d85f53b093867bbb0123f016956178eea7343eTed KremenekContentCache::~ContentCache() { 40f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (shouldFreeBuffer()) 41f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor delete Buffer.getPointer(); 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 443201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// getSizeBytesMapped - Returns the number of bytes actually mapped for this 453201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// ContentCache. This can be 0 if the MemBuffer was not actually expanded. 46c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenekunsigned ContentCache::getSizeBytesMapped() const { 47c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0; 48c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek} 49c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek 50f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek/// Returns the kind of memory used to back the memory buffer for 51f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek/// this content cache. This is used for performance analysis. 52f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenekllvm::MemoryBuffer::BufferKind ContentCache::getMemoryBufferKind() const { 53f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek assert(Buffer.getPointer()); 54f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 55f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek // Should be unreachable, but keep for sanity. 56f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek if (!Buffer.getPointer()) 57f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek return llvm::MemoryBuffer::MemoryBuffer_Malloc; 58f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 59f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek const llvm::MemoryBuffer *buf = Buffer.getPointer(); 60f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek return buf->getBufferKind(); 61f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek} 62f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 63c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek/// getSize - Returns the size of the content encapsulated by this ContentCache. 64c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek/// This can be the size of the source file or the size of an arbitrary 65c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek/// scratch buffer. If the ContentCache encapsulates a source file, that 662968442603b029949246467253eeac8139a5b6d8Douglas Gregor/// file is not lazily brought in from disk to satisfy this query. 67c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenekunsigned ContentCache::getSize() const { 68c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor return Buffer.getPointer() ? (unsigned) Buffer.getPointer()->getBufferSize() 69b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis : (unsigned) ContentsEntry->getSize(); 70c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek} 71c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek 72f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregorvoid ContentCache::replaceBuffer(const llvm::MemoryBuffer *B, 73f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor bool DoNotFree) { 74d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (B && B == Buffer.getPointer()) { 75a4288c4aa05075cd45fd4de61d95ffe920fe6441Argyrios Kyrtzidis assert(0 && "Replacing with the same buffer"); 76a4288c4aa05075cd45fd4de61d95ffe920fe6441Argyrios Kyrtzidis Buffer.setInt(DoNotFree? DoNotFreeFlag : 0); 77a4288c4aa05075cd45fd4de61d95ffe920fe6441Argyrios Kyrtzidis return; 78a4288c4aa05075cd45fd4de61d95ffe920fe6441Argyrios Kyrtzidis } 792968442603b029949246467253eeac8139a5b6d8Douglas Gregor 80f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (shouldFreeBuffer()) 81f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor delete Buffer.getPointer(); 82c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor Buffer.setPointer(B); 83f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor Buffer.setInt(DoNotFree? DoNotFreeFlag : 0); 842968442603b029949246467253eeac8139a5b6d8Douglas Gregor} 852968442603b029949246467253eeac8139a5b6d8Douglas Gregor 86d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikieconst llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, 875c5db4e94bd1243ba92563acba51ba66afa94917Chris Lattner const SourceManager &SM, 88e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner SourceLocation Loc, 8936c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregor bool *Invalid) const { 90b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // Lazily create the Buffer for ContentCaches that wrap files. If we already 91fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner // computed it, just return what we have. 92b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (Buffer.getPointer() || ContentsEntry == 0) { 93b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Invalid) 94b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner *Invalid = isBufferInvalid(); 95b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner 96b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner return Buffer.getPointer(); 97b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner } 9893ea5cb0edf8e509c5113e70cb05ee247c9bdf6bDouglas Gregor 99b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner std::string ErrorStr; 100ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool isVolatile = SM.userFilesAreVolatile() && !IsSystemFile; 101ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis Buffer.setPointer(SM.getFileManager().getBufferForFile(ContentsEntry, 102ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis &ErrorStr, 103ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis isVolatile)); 10493ea5cb0edf8e509c5113e70cb05ee247c9bdf6bDouglas Gregor 105b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // If we were unable to open the file, then we are in an inconsistent 106b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // situation where the content cache referenced a file which no longer 107b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // exists. Most likely, we were using a stat cache with an invalid entry but 108b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // the file could also have been removed during processing. Since we can't 109b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // really deal with this situation, just create an empty buffer. 110b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // 111b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // FIXME: This is definitely not ideal, but our immediate clients can't 112b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // currently handle returning a null entry here. Ideally we should detect 113b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // that we are in an inconsistent situation and error out as quickly as 114b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // possible. 115b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (!Buffer.getPointer()) { 1165f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner const StringRef FillStr("<<<MISSING SOURCE FILE>>>\n"); 117b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Buffer.setPointer(MemoryBuffer::getNewMemBuffer(ContentsEntry->getSize(), 118b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner "<invalid>")); 119b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart()); 120b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis for (unsigned i = 0, e = ContentsEntry->getSize(); i != e; ++i) 121b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Ptr[i] = FillStr[i % FillStr.size()]; 1220b3c773bdc4f5d5f3aaf882b2f7a5f14df6041e0Daniel Dunbar 123b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Diag.isDiagnosticInFlight()) 124b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, 125b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis ContentsEntry->getName(), ErrorStr); 126b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner else 127b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.Report(Loc, diag::err_cannot_open_file) 128b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << ContentsEntry->getName() << ErrorStr; 12993ea5cb0edf8e509c5113e70cb05ee247c9bdf6bDouglas Gregor 130b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Buffer.setInt(Buffer.getInt() | InvalidFlag); 13138caec48bc1c9816ca59b8d164a64447ee208c2eChris Lattner 132b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Invalid) *Invalid = true; 133b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner return Buffer.getPointer(); 134b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner } 135b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner 136b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // Check that the file's size is the same as in the file entry (which may 137b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // have come from a stat cache). 138b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (getRawBuffer()->getBufferSize() != (size_t)ContentsEntry->getSize()) { 139b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Diag.isDiagnosticInFlight()) 140b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.SetDelayedDiagnostic(diag::err_file_modified, 141b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis ContentsEntry->getName()); 142b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner else 143b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.Report(Loc, diag::err_file_modified) 144b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << ContentsEntry->getName(); 145b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner 146b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Buffer.setInt(Buffer.getInt() | InvalidFlag); 147b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Invalid) *Invalid = true; 148b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner return Buffer.getPointer(); 149b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner } 150156119df1d076b63609618976281961283f871dbEric Christopher 151b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // If the buffer is valid, check to see if it has a UTF Byte Order Mark 152156119df1d076b63609618976281961283f871dbEric Christopher // (BOM). We only support UTF-8 with and without a BOM right now. See 153b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // http://en.wikipedia.org/wiki/Byte_order_mark for more information. 1545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef BufStr = Buffer.getPointer()->getBuffer(); 155156119df1d076b63609618976281961283f871dbEric Christopher const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr) 156b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xFE\xFF", "UTF-16 (BE)") 157b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xFF\xFE", "UTF-16 (LE)") 158b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\x00\x00\xFE\xFF", "UTF-32 (BE)") 159b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xFF\xFE\x00\x00", "UTF-32 (LE)") 160b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\x2B\x2F\x76", "UTF-7") 161b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xF7\x64\x4C", "UTF-1") 162b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC") 163b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\x0E\xFE\xFF", "SDSU") 164b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xFB\xEE\x28", "BOCU-1") 165b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\x84\x31\x95\x33", "GB-18030") 166b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .Default(0); 1675807d9cce3f0ab4366bed9470355433c7b562c8dBenjamin Kramer 168156119df1d076b63609618976281961283f871dbEric Christopher if (InvalidBOM) { 169b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.Report(Loc, diag::err_unsupported_bom) 170156119df1d076b63609618976281961283f871dbEric Christopher << InvalidBOM << ContentsEntry->getName(); 171b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Buffer.setInt(Buffer.getInt() | InvalidFlag); 1725b034ad3ec0aa1ad6bcb3624390f030038670705Ted Kremenek } 173aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 174c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor if (Invalid) 175f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor *Invalid = isBufferInvalid(); 176c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor 177c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor return Buffer.getPointer(); 178c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek} 179c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek 1805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerunsigned LineTableInfo::getLineTableFilenameID(StringRef Name) { 1815b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner // Look up the filename in the string table, returning the pre-existing value 1825b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner // if it exists. 1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::StringMapEntry<unsigned> &Entry = 18465aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad FilenameIDs.GetOrCreateValue(Name, ~0U); 1855b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner if (Entry.getValue() != ~0U) 1865b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner return Entry.getValue(); 1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1885b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner // Otherwise, assign this the next available ID. 1895b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner Entry.setValue(FilenamesByID.size()); 1905b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner FilenamesByID.push_back(&Entry); 1915b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner return FilenamesByID.size()-1; 1925b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner} 1935b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 194ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner/// AddLineNote - Add a line note to the line table that indicates that there 1957285a06a0655ed93e313305182f67edb73890247James Dennett/// is a \#line at the specified FID/Offset location which changes the presumed 196ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner/// location to LineNo/FilenameID. 19747d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregorvoid LineTableInfo::AddLineNote(FileID FID, unsigned Offset, 198ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner unsigned LineNo, int FilenameID) { 19923b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner std::vector<LineEntry> &Entries = LineEntries[FID]; 2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20123b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner assert((Entries.empty() || Entries.back().FileOffset < Offset) && 20223b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner "Adding line entries out of order!"); 2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2049d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner SrcMgr::CharacteristicKind Kind = SrcMgr::C_User; 205137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner unsigned IncludeOffset = 0; 2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2079d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (!Entries.empty()) { 2089d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember 2099d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // that we are still in "foo.h". 2109d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (FilenameID == -1) 2119d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner FilenameID = Entries.back().FilenameID; 2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 213137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner // If we are after a line marker that switched us to system header mode, or 214137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner // that set #include information, preserve it. 2159d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner Kind = Entries.back().FileKind; 216137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = Entries.back().IncludeOffset; 2179d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner } 2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 219137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind, 220137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset)); 2219d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner} 2229d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner 2239d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// AddLineNote This is the same as the previous version of AddLineNote, but is 2249d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// used for GNU line markers. If EntryExit is 0, then this doesn't change the 225b8950b8e11272a3b9776568ea423bff016bc996dJames Dennett/// presumed \#include stack. If it is 1, this is a file entry, if it is 2 then 2269d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// this is a file exit. FileKind specifies whether this is a system header or 2279d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// extern C system header. 22847d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregorvoid LineTableInfo::AddLineNote(FileID FID, unsigned Offset, 2299d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner unsigned LineNo, int FilenameID, 2309d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner unsigned EntryExit, 2319d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner SrcMgr::CharacteristicKind FileKind) { 2329d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner assert(FilenameID != -1 && "Unspecified filename should use other accessor"); 2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2349d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner std::vector<LineEntry> &Entries = LineEntries[FID]; 2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2369d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner assert((Entries.empty() || Entries.back().FileOffset < Offset) && 2379d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner "Adding line entries out of order!"); 2389d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner 239137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner unsigned IncludeOffset = 0; 240137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner if (EntryExit == 0) { // No #include stack change. 241137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset; 242137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner } else if (EntryExit == 1) { 243137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = Offset-1; 244137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner } else if (EntryExit == 2) { 245137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner assert(!Entries.empty() && Entries.back().IncludeOffset && 246137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner "PPDirectives should have caught case when popping empty include stack"); 2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 248137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner // Get the include loc of the last entries' include loc as our include loc. 249137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = 0; 250137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner if (const LineEntry *PrevEntry = 251137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner FindNearestLineEntry(FID, Entries.back().IncludeOffset)) 252137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = PrevEntry->IncludeOffset; 253137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner } 2541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 255137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind, 256137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset)); 257ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner} 258ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 2599d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner 2603cd949c27c63f544a081b9a750740064ddef181bChris Lattner/// FindNearestLineEntry - Find the line entry nearest to FID that is before 2613cd949c27c63f544a081b9a750740064ddef181bChris Lattner/// it. If there is no line entry before Offset in FID, return null. 26247d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregorconst LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID, 2633cd949c27c63f544a081b9a750740064ddef181bChris Lattner unsigned Offset) { 2643cd949c27c63f544a081b9a750740064ddef181bChris Lattner const std::vector<LineEntry> &Entries = LineEntries[FID]; 2653cd949c27c63f544a081b9a750740064ddef181bChris Lattner assert(!Entries.empty() && "No #line entries for this FID after all!"); 2663cd949c27c63f544a081b9a750740064ddef181bChris Lattner 2676c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner // It is very common for the query to be after the last #line, check this 2686c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner // first. 2696c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner if (Entries.back().FileOffset <= Offset) 2706c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner return &Entries.back(); 2713cd949c27c63f544a081b9a750740064ddef181bChris Lattner 2726c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner // Do a binary search to find the maximal element that is still before Offset. 2736c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner std::vector<LineEntry>::const_iterator I = 2746c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner std::upper_bound(Entries.begin(), Entries.end(), Offset); 2756c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner if (I == Entries.begin()) return 0; 2766c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner return &*--I; 2773cd949c27c63f544a081b9a750740064ddef181bChris Lattner} 278ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 279bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor/// \brief Add a new line entry that has already been encoded into 280bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor/// the internal representation of the line table. 28147d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregorvoid LineTableInfo::AddEntry(FileID FID, 282bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor const std::vector<LineEntry> &Entries) { 283bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor LineEntries[FID] = Entries; 284bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor} 285ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 2865b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner/// getLineTableFilenameID - Return the uniqued ID for the specified filename. 2871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 2885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerunsigned SourceManager::getLineTableFilenameID(StringRef Name) { 2895b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner if (LineTable == 0) 2905b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LineTable = new LineTableInfo(); 29165aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad return LineTable->getLineTableFilenameID(Name); 2925b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner} 2935b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 2945b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 2954c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner/// AddLineNote - Add a line note to the line table for the FileID and offset 2964c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner/// specified by Loc. If FilenameID is -1, it is considered to be 2974c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner/// unspecified. 2984c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattnervoid SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, 2994c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner int FilenameID) { 300e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 302e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 303e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); 304e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!Entry.isFile() || Invalid) 305e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return; 306e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 307e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::FileInfo &FileInfo = Entry.getFile(); 308ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 309ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner // Remember that this file has #line directives now if it doesn't already. 310ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives(); 3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 312ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner if (LineTable == 0) 313ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner LineTable = new LineTableInfo(); 31447d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregor LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID); 3154c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner} 3164c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner 3179d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// AddLineNote - Add a GNU line marker to the line table. 3189d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattnervoid SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, 3199d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner int FilenameID, bool IsFileEntry, 3209d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner bool IsFileExit, bool IsSystemHeader, 3219d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner bool IsExternCHeader) { 3229d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // If there is no filename and no flags, this is treated just like a #line, 3239d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // which does not change the flags of the previous line marker. 3249d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (FilenameID == -1) { 3259d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader && 3269d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner "Can't set flags without setting the filename!"); 3279d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner return AddLineNote(Loc, LineNo, FilenameID); 3289d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner } 3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 330e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 331e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 332e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 333e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); 334e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!Entry.isFile() || Invalid) 335e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return; 336e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 337e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::FileInfo &FileInfo = Entry.getFile(); 3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3399d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // Remember that this file has #line directives now if it doesn't already. 3409d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives(); 3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3429d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (LineTable == 0) 3439d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner LineTable = new LineTableInfo(); 3441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3459d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner SrcMgr::CharacteristicKind FileKind; 3469d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (IsExternCHeader) 3479d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner FileKind = SrcMgr::C_ExternCSystem; 3489d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner else if (IsSystemHeader) 3499d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner FileKind = SrcMgr::C_System; 3509d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner else 3519d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner FileKind = SrcMgr::C_User; 3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3539d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner unsigned EntryExit = 0; 3549d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (IsFileEntry) 3559d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner EntryExit = 1; 3569d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner else if (IsFileExit) 3579d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner EntryExit = 2; 3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 35947d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregor LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID, 3609d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner EntryExit, FileKind); 3619d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner} 3629d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner 363bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas GregorLineTableInfo &SourceManager::getLineTable() { 364bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor if (LineTable == 0) 365bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor LineTable = new LineTableInfo(); 366bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor return *LineTable; 367bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor} 3684c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner 36923b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 370de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// Private 'Create' methods. 37123b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 372c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek 373ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios KyrtzidisSourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, 374ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool UserFilesAreVolatile) 375299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true), 376ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis UserFilesAreVolatile(UserFilesAreVolatile), 37733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), 378a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis NumBinaryProbes(0), FakeBufferForRecovery(0), 379a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis FakeContentCacheForRecovery(0) { 38033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis clearIDTables(); 38133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis Diag.setSourceManager(this); 38233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis} 38333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis 3845b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris LattnerSourceManager::~SourceManager() { 3855b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner delete LineTable; 3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3870d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner // Delete FileEntry objects corresponding to content caches. Since the actual 3880d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner // content cache objects are bump pointer allocated, we just have to run the 3890d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner // dtors, but we call the deallocate method for completeness. 3900d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) { 39199ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis if (MemBufferInfos[i]) { 39299ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis MemBufferInfos[i]->~ContentCache(); 39399ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis ContentCacheAlloc.Deallocate(MemBufferInfos[i]); 39499ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis } 3950d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner } 3960d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator 3970d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) { 39899ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis if (I->second) { 39999ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis I->second->~ContentCache(); 40099ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis ContentCacheAlloc.Deallocate(I->second); 40199ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis } 4020d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner } 403e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 404e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor delete FakeBufferForRecovery; 405a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis delete FakeContentCacheForRecovery; 406fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis 407fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis for (llvm::DenseMap<FileID, MacroArgsMap *>::iterator 408fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis I = MacroArgsCacheMap.begin(),E = MacroArgsCacheMap.end(); I!=E; ++I) { 409fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis delete I->second; 410fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis } 4115b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner} 4125b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 4135b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattnervoid SourceManager::clearIDTables() { 4145b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner MainFileID = FileID(); 415f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocalSLocEntryTable.clear(); 416f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LoadedSLocEntryTable.clear(); 417f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocEntryLoaded.clear(); 4185b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LastLineNoFileIDQuery = FileID(); 4195b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LastLineNoContentCache = 0; 4205b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LastFileIDLookup = FileID(); 4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4225b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner if (LineTable) 4235b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LineTable->clear(); 4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4253201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // Use up FileID #0 as an invalid expansion. 426f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset = 0; 427ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis CurrentLoadedOffset = MaxLoadedOffset; 428bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth createExpansionLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1); 4295b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner} 4305b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 431de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner/// getOrCreateContentCache - Create or return a cached ContentCache for the 432de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner/// specified file. 433de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattnerconst ContentCache * 434ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios KyrtzidisSourceManager::getOrCreateContentCache(const FileEntry *FileEnt, 435ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis bool isSystemFile) { 4365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(FileEnt && "Didn't specify a file entry to use?"); 4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Do we already have information about this file? 4390d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner ContentCache *&Entry = FileInfos[FileEnt]; 4400d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner if (Entry) return Entry; 4411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 44200282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // Nope, create a new Cache entry. Make sure it is at least 8-byte aligned 44300282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // so that FileInfo can use the low 3 bits of the pointer for its own 44400282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // nefarious purposes. 44500282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment; 44600282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner EntryAlign = std::max(8U, EntryAlign); 44700282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign); 448b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 449d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (OverriddenFilesInfo) { 450d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis // If the file contents are overridden with contents from another file, 451d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis // pass that file to ContentCache. 452d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator 453d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt); 454d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (overI == OverriddenFilesInfo->OverriddenFiles.end()) 455d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis new (Entry) ContentCache(FileEnt); 456d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis else 457d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt 458d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis : overI->second, 459d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis overI->second); 460d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis } else { 461b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis new (Entry) ContentCache(FileEnt); 462d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis } 463b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 464ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis Entry->IsSystemFile = isSystemFile; 465ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis 4660d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner return Entry; 4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 470d1c0eee9aa30926839184b657b9e21be4a2ebdb8Ted Kremenek/// createMemBufferContentCache - Create a new ContentCache for the specified 471d1c0eee9aa30926839184b657b9e21be4a2ebdb8Ted Kremenek/// memory buffer. This does no caching. 47278d85f53b093867bbb0123f016956178eea7343eTed Kremenekconst ContentCache* 47378d85f53b093867bbb0123f016956178eea7343eTed KremenekSourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { 47400282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // Add a new ContentCache to the MemBufferInfos list and return it. Make sure 47500282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of 47600282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // the pointer for its own nefarious purposes. 47700282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment; 47800282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner EntryAlign = std::max(8U, EntryAlign); 47900282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign); 4800d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner new (Entry) ContentCache(); 4810d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner MemBufferInfos.push_back(Entry); 4820d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner Entry->setBuffer(Buffer); 4830d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner return Entry; 4845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 486a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidisconst SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index, 487a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis bool *Invalid) const { 488a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis assert(!SLocEntryLoaded[Index]); 489a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis if (ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2))) { 490a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis if (Invalid) 491a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis *Invalid = true; 492a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis // If the file of the SLocEntry changed we could still have loaded it. 493a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis if (!SLocEntryLoaded[Index]) { 494a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis // Try to recover; create a SLocEntry so the rest of clang can handle it. 495a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis LoadedSLocEntryTable[Index] = SLocEntry::get(0, 496a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis FileInfo::get(SourceLocation(), 497a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis getFakeContentCacheForRecovery(), 498a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis SrcMgr::C_User)); 499a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis } 500a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis } 501a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis 502a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis return LoadedSLocEntryTable[Index]; 503a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis} 504a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis 505f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorstd::pair<int, unsigned> 506f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas GregorSourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries, 507f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned TotalSize) { 508f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(ExternalSLocEntries && "Don't have an external sloc source"); 509f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries); 510f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocEntryLoaded.resize(LoadedSLocEntryTable.size()); 511f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor CurrentLoadedOffset -= TotalSize; 512f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(CurrentLoadedOffset >= NextLocalOffset && "Out of source locations"); 513f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor int ID = LoadedSLocEntryTable.size(); 514f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return std::make_pair(-ID - 1, CurrentLoadedOffset); 5152bf1eb09f06a9792fa94dff0703f2aa2c4bace2aDouglas Gregor} 5162bf1eb09f06a9792fa94dff0703f2aa2c4bace2aDouglas Gregor 517e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor/// \brief As part of recovering from missing or changed content, produce a 518e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor/// fake, non-empty buffer. 519e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregorconst llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const { 520e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!FakeBufferForRecovery) 521e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor FakeBufferForRecovery 522e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor = llvm::MemoryBuffer::getMemBuffer("<<<INVALID BUFFER>>"); 523e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 524e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return FakeBufferForRecovery; 525e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor} 5267f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 527a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis/// \brief As part of recovering from missing or changed content, produce a 528a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis/// fake content cache. 529a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidisconst SrcMgr::ContentCache * 530a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios KyrtzidisSourceManager::getFakeContentCacheForRecovery() const { 531a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis if (!FakeContentCacheForRecovery) { 532a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis FakeContentCacheForRecovery = new ContentCache(); 533a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(), 534a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis /*DoNotFree=*/true); 535a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis } 536a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis return FakeContentCacheForRecovery; 537a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis} 538a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis 539de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 5403201f382956ed9beee9fb31229c2835c1208889cChandler Carruth// Methods to create new FileID's and macro expansions. 541de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 5425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5433f86b789f5b98731937f90b3941104a313766953Dan Gohman/// createFileID - Create a new FileID for the specified ContentCache and 5440d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek/// include position. This works regardless of whether the ContentCache 5450d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek/// corresponds to a file or some other input source. 5462b2453a7d8fe732561795431f39ceb2b2a832d84Chris LattnerFileID SourceManager::createFileID(const ContentCache *File, 547de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation IncludePos, 5487f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor SrcMgr::CharacteristicKind FileCharacter, 549f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor int LoadedID, unsigned LoadedOffset) { 550f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LoadedID < 0) { 551f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(LoadedID != -1 && "Loading sentinel FileID"); 552f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned Index = unsigned(-LoadedID) - 2; 553f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(Index < LoadedSLocEntryTable.size() && "FileID out of range"); 554f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(!SLocEntryLoaded[Index] && "FileID already loaded"); 555f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, 556f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileInfo::get(IncludePos, File, FileCharacter)); 557f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocEntryLoaded[Index] = true; 558f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return FileID::get(LoadedID); 5597f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor } 560f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, 561f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileInfo::get(IncludePos, File, 562f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileCharacter))); 563c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek unsigned FileSize = File->getSize(); 564f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(NextLocalOffset + FileSize + 1 > NextLocalOffset && 565f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset && 566f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor "Ran out of source locations!"); 567f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // We do a +1 here because we want a SourceLocation that means "the end of the 568f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // file", e.g. for the "no newline at the end of the file" diagnostic. 569f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset += FileSize + 1; 5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 571de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Set LastFileIDLookup to the newly created file. The next getFileID call is 572de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // almost guaranteed to be from that file. 573f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID FID = FileID::get(LocalSLocEntryTable.size()-1); 574ea703f1218971511181765c37073c03e1437c5ccArgyrios Kyrtzidis return LastFileIDLookup = FID; 5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 577c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler CarruthSourceLocation 578bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler CarruthSourceManager::createMacroArgExpansionLoc(SourceLocation SpellingLoc, 579bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth SourceLocation ExpansionLoc, 580bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned TokLength) { 58178df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc, 58278df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth ExpansionLoc); 58378df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth return createExpansionLocImpl(Info, TokLength); 584c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth} 585c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth 586bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler CarruthSourceLocation 587bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler CarruthSourceManager::createExpansionLoc(SourceLocation SpellingLoc, 588bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth SourceLocation ExpansionLocStart, 589bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth SourceLocation ExpansionLocEnd, 590bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned TokLength, 591bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth int LoadedID, 592bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned LoadedOffset) { 59378df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth ExpansionInfo Info = ExpansionInfo::create(SpellingLoc, ExpansionLocStart, 59478df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth ExpansionLocEnd); 59578df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset); 596c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth} 597c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth 598c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler CarruthSourceLocation 59978df836808aee22c3157e1bc23bc4ec569b80568Chandler CarruthSourceManager::createExpansionLocImpl(const ExpansionInfo &Info, 600bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned TokLength, 601bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth int LoadedID, 602bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned LoadedOffset) { 603f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LoadedID < 0) { 604f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(LoadedID != -1 && "Loading sentinel FileID"); 605f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned Index = unsigned(-LoadedID) - 2; 606f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(Index < LoadedSLocEntryTable.size() && "FileID out of range"); 607f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(!SLocEntryLoaded[Index] && "FileID already loaded"); 60878df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info); 609f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocEntryLoaded[Index] = true; 610f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return SourceLocation::getMacroLoc(LoadedOffset); 6117f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor } 61278df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info)); 613f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(NextLocalOffset + TokLength + 1 > NextLocalOffset && 614f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset && 615f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor "Ran out of source locations!"); 616f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // See createFileID for that +1. 617f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset += TokLength + 1; 618f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1)); 6195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 62136c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregorconst llvm::MemoryBuffer * 62250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas GregorSourceManager::getMemoryBufferForFile(const FileEntry *File, 62350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) { 6242968442603b029949246467253eeac8139a5b6d8Douglas Gregor const SrcMgr::ContentCache *IR = getOrCreateContentCache(File); 625aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor assert(IR && "getOrCreateContentCache() cannot return NULL"); 626e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner return IR->getBuffer(Diag, *this, SourceLocation(), Invalid); 6272968442603b029949246467253eeac8139a5b6d8Douglas Gregor} 6282968442603b029949246467253eeac8139a5b6d8Douglas Gregor 6290d06e998910934e5ef070f53f4c272e7c6b846c6Dan Gohmanvoid SourceManager::overrideFileContents(const FileEntry *SourceFile, 630f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const llvm::MemoryBuffer *Buffer, 631f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor bool DoNotFree) { 6322968442603b029949246467253eeac8139a5b6d8Douglas Gregor const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile); 6330d06e998910934e5ef070f53f4c272e7c6b846c6Dan Gohman assert(IR && "getOrCreateContentCache() cannot return NULL"); 6342968442603b029949246467253eeac8139a5b6d8Douglas Gregor 635f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree); 636a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor const_cast<SrcMgr::ContentCache *>(IR)->BufferOverridden = true; 637d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 638d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile); 6392968442603b029949246467253eeac8139a5b6d8Douglas Gregor} 6402968442603b029949246467253eeac8139a5b6d8Douglas Gregor 641b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidisvoid SourceManager::overrideFileContents(const FileEntry *SourceFile, 642b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *NewFile) { 643b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis assert(SourceFile->getSize() == NewFile->getSize() && 644b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis "Different sizes, use the FileManager to create a virtual file with " 645b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis "the correct size"); 646b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis assert(FileInfos.count(SourceFile) == 0 && 647b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis "This function should be called at the initialization stage, before " 648b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis "any parsing occurs."); 649d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile; 650d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis} 651d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 652d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidisvoid SourceManager::disableFileContentsOverride(const FileEntry *File) { 653d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (!isFileOverridden(File)) 654d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis return; 655d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 656d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis const SrcMgr::ContentCache *IR = getOrCreateContentCache(File); 657d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(0); 658d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis const_cast<SrcMgr::ContentCache *>(IR)->ContentsEntry = IR->OrigEntry; 659d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 660d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis assert(OverriddenFilesInfo); 661d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis OverriddenFilesInfo->OverriddenFiles.erase(File); 662d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File); 663b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis} 664b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 6655f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { 666aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor bool MyInvalid = false; 667f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SLocEntry &SLoc = getSLocEntry(FID, &MyInvalid); 668e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!SLoc.isFile() || MyInvalid) { 6693de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor if (Invalid) 6703de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor *Invalid = true; 6713de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor return "<<<<<INVALID SOURCE LOCATION>>>>>"; 6723de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor } 6733de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor 6743de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor const llvm::MemoryBuffer *Buf 6753de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor = SLoc.getFile().getContentCache()->getBuffer(Diag, *this, SourceLocation(), 6763de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor &MyInvalid); 677f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor if (Invalid) 678aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor *Invalid = MyInvalid; 679aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor 680aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor if (MyInvalid) 6813de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor return "<<<<<INVALID SOURCE LOCATION>>>>>"; 682aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor 683f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer return Buf->getBuffer(); 684aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor} 6852b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner 68623b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 687de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// SourceLocation manipulation methods. 68823b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 689de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 690f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// \brief Return the FileID for a SourceLocation. 691de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner/// 692f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// This is the cache-miss path of getFileID. Not as hot as that function, but 693f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// still very important. It is responsible for finding the entry in the 694f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// SLocEntry tables that contains the specified location. 695de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris LattnerFileID SourceManager::getFileIDSlow(unsigned SLocOffset) const { 696e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!SLocOffset) 697e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return FileID::get(0); 6981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 699f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Now it is time to search for the correct file. See where the SLocOffset 700f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // sits in the global view and consult local or loaded buffers for it. 701f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (SLocOffset < NextLocalOffset) 702f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return getFileIDLocal(SLocOffset); 703f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return getFileIDLoaded(SLocOffset); 704f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 705f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 706f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// \brief Return the FileID for a SourceLocation with a low offset. 707f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// 708f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// This function knows that the SourceLocation is in a local buffer, not a 709f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// loaded one. 710f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas GregorFileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { 711f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(SLocOffset < NextLocalOffset && "Bad function choice"); 712f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 713de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // After the first and second level caches, I see two common sorts of 7143201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // behavior: 1) a lot of searched FileID's are "near" the cached file 7153201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // location or are "near" the cached expansion location. 2) others are just 716de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // completely random and may be a very long way away. 717de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // 718de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // To handle this, we do a linear search for up to 8 steps to catch #1 quickly 719de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // then we fall back to a less cache efficient, but more scalable, binary 720de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // search to find the location. 7211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 722de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // See if this is near the file point - worst case we start scanning from the 723de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // most newly created FileID. 724f512acee01617c9da8079ed88ded3bb9f2418349Benjamin Kramer const SrcMgr::SLocEntry *I; 7251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 726f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LastFileIDLookup.ID < 0 || 727f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) { 728de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Neither loc prunes our search. 729f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I = LocalSLocEntryTable.end(); 730de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } else { 731de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Perhaps it is near the file point. 732f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID; 733de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 734de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 735de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Find the FileID that contains this. "I" is an iterator that points to a 736de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // FileID whose offset is known to be larger than SLocOffset. 737de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned NumProbes = 0; 738de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner while (1) { 739de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner --I; 740de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (I->getOffset() <= SLocOffset) { 741f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin())); 7427f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 7433201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // If this isn't an expansion, remember it. We have good locality across 7443201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // FileID lookups. 7451728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (!I->isExpansion()) 746de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner LastFileIDLookup = Res; 747de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner NumLinearScans += NumProbes+1; 748de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return Res; 749de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 750de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (++NumProbes == 8) 751de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner break; 752de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 7531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 754de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Convert "I" back into an index. We know that it is an entry whose index is 755de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // larger than the offset we are looking for. 756f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned GreaterIndex = I - LocalSLocEntryTable.begin(); 757de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // LessIndex - This is the lower bound of the range that we're searching. 758de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // We know that the offset corresponding to the FileID is is less than 759de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // SLocOffset. 760de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned LessIndex = 0; 761de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner NumProbes = 0; 762de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner while (1) { 763e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 764de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; 765f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset(); 766e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 767e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return FileID::get(0); 768e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 769de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner ++NumProbes; 7701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 771de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // If the offset of the midpoint is too large, chop the high side of the 772de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // range to the midpoint. 773de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (MidOffset > SLocOffset) { 774de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner GreaterIndex = MiddleIndex; 775de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner continue; 776de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 7771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 778de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // If the middle index contains the value, succeed and return. 779f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // FIXME: This could be made faster by using a function that's aware of 780f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // being in the local area. 781de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) { 782de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID Res = FileID::get(MiddleIndex); 783de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 7841728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth // If this isn't a macro expansion, remember it. We have good locality 785de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // across FileID lookups. 7861728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (!LocalSLocEntryTable[MiddleIndex].isExpansion()) 787de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner LastFileIDLookup = Res; 788de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner NumBinaryProbes += NumProbes; 789de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return Res; 790de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 7911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 792de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Otherwise, move the low-side up to the middle index. 793de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner LessIndex = MiddleIndex; 794de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 795de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner} 796de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 797f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// \brief Return the FileID for a SourceLocation with a high offset. 798f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// 799f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// This function knows that the SourceLocation is in a loaded buffer, not a 800f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// local one. 801f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas GregorFileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { 802c3b4575b77164fdf008cd4acc330884d56ca500fArgyrios Kyrtzidis // Sanity checking, otherwise a bug may lead to hanging in release build. 80382ccbe759b716f1747e03f54a4cd6eb164bb3427Argyrios Kyrtzidis if (SLocOffset < CurrentLoadedOffset) { 80482ccbe759b716f1747e03f54a4cd6eb164bb3427Argyrios Kyrtzidis assert(0 && "Invalid SLocOffset or bad function choice"); 805c3b4575b77164fdf008cd4acc330884d56ca500fArgyrios Kyrtzidis return FileID(); 80682ccbe759b716f1747e03f54a4cd6eb164bb3427Argyrios Kyrtzidis } 807c3b4575b77164fdf008cd4acc330884d56ca500fArgyrios Kyrtzidis 808f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Essentially the same as the local case, but the loaded array is sorted 809f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // in the other direction. 810f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 811f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // First do a linear scan from the last lookup position, if possible. 812f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned I; 813f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor int LastID = LastFileIDLookup.ID; 814f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset) 815f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I = 0; 816f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor else 817f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I = (-LastID - 2) + 1; 818f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 819f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned NumProbes; 820f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) { 821f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Make sure the entry is loaded! 822f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I); 823f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (E.getOffset() <= SLocOffset) { 824f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID Res = FileID::get(-int(I) - 2); 825f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 8261728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (!E.isExpansion()) 827f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LastFileIDLookup = Res; 828f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NumLinearScans += NumProbes + 1; 829f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return Res; 830f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 831f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 832f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 833f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Linear scan failed. Do the binary search. Note the reverse sorting of the 834f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // table: GreaterIndex is the one where the offset is greater, which is 835f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // actually a lower index! 836f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned GreaterIndex = I; 837f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned LessIndex = LoadedSLocEntryTable.size(); 838f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NumProbes = 0; 839f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor while (1) { 840f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ++NumProbes; 841f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex; 842f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex); 8437db4bb9226f303392934c91869afdeb4d153ca95Argyrios Kyrtzidis if (E.getOffset() == 0) 8447db4bb9226f303392934c91869afdeb4d153ca95Argyrios Kyrtzidis return FileID(); // invalid entry. 845f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 846f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ++NumProbes; 847f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 848f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (E.getOffset() > SLocOffset) { 8497db4bb9226f303392934c91869afdeb4d153ca95Argyrios Kyrtzidis // Sanity checking, otherwise a bug may lead to hanging in release build. 8507db4bb9226f303392934c91869afdeb4d153ca95Argyrios Kyrtzidis if (GreaterIndex == MiddleIndex) { 8517db4bb9226f303392934c91869afdeb4d153ca95Argyrios Kyrtzidis assert(0 && "binary search missed the entry"); 8527db4bb9226f303392934c91869afdeb4d153ca95Argyrios Kyrtzidis return FileID(); 8537db4bb9226f303392934c91869afdeb4d153ca95Argyrios Kyrtzidis } 854f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor GreaterIndex = MiddleIndex; 855f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor continue; 856f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 857f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 858f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) { 859f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID Res = FileID::get(-int(MiddleIndex) - 2); 8601728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (!E.isExpansion()) 861f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LastFileIDLookup = Res; 862f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NumBinaryProbes += NumProbes; 863f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return Res; 864f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 865f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 866838a920fda4408d1b12faca704da2b848a6efcc1Argyrios Kyrtzidis // Sanity checking, otherwise a bug may lead to hanging in release build. 867838a920fda4408d1b12faca704da2b848a6efcc1Argyrios Kyrtzidis if (LessIndex == MiddleIndex) { 868838a920fda4408d1b12faca704da2b848a6efcc1Argyrios Kyrtzidis assert(0 && "binary search missed the entry"); 869838a920fda4408d1b12faca704da2b848a6efcc1Argyrios Kyrtzidis return FileID(); 870838a920fda4408d1b12faca704da2b848a6efcc1Argyrios Kyrtzidis } 871f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LessIndex = MiddleIndex; 872f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 873f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 874f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 875addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris LattnerSourceLocation SourceManager:: 876f84ef95ecec34f27fd05eb4e0392ca6bd3bd0be0Chandler CarruthgetExpansionLocSlowCase(SourceLocation Loc) const { 877addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner do { 878a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // Note: If Loc indicates an offset into a token that came from a macro 879a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // expansion (e.g. the 5th character of the token) we do not want to add 8801728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth // this offset when going to the expansion location. The expansion 881a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // location is the macro invocation, which the offset has nothing to do 882a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // with. This is unlike when we get the spelling loc, because the offset 883a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // directly correspond to the token whose spelling we're inspecting. 8841728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = getSLocEntry(getFileID(Loc)).getExpansion().getExpansionLocStart(); 885addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner } while (!Loc.isFileID()); 886addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 887addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner return Loc; 888addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner} 889addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 890addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris LattnerSourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const { 891addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner do { 892addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc); 8931728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc(); 894a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis Loc = Loc.getLocWithOffset(LocInfo.second); 895addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner } while (!Loc.isFileID()); 896addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner return Loc; 897addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner} 898addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 899796dbfb6c43336f58c026137c438e53eadc381f7Argyrios KyrtzidisSourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const { 900796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis do { 901796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis if (isMacroArgExpansion(Loc)) 902796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis Loc = getImmediateSpellingLoc(Loc); 903796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis else 904796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis Loc = getImmediateExpansionRange(Loc).first; 905796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis } while (!Loc.isFileID()); 906796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis return Loc; 907796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis} 908796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis 909addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 910de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattnerstd::pair<FileID, unsigned> 911e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler CarruthSourceManager::getDecomposedExpansionLocSlowCase( 9128b86ef0b71900c64c0c2cfca54cac08a203a16a4Argyrios Kyrtzidis const SrcMgr::SLocEntry *E) const { 9133201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // If this is an expansion record, walk through all the expansion points. 914de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID FID; 915de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation Loc; 9168b86ef0b71900c64c0c2cfca54cac08a203a16a4Argyrios Kyrtzidis unsigned Offset; 917de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner do { 9181728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = E->getExpansion().getExpansionLocStart(); 9191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 920de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FID = getFileID(Loc); 921de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner E = &getSLocEntry(FID); 9228b86ef0b71900c64c0c2cfca54cac08a203a16a4Argyrios Kyrtzidis Offset = Loc.getOffset()-E->getOffset(); 923bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner } while (!Loc.isFileID()); 9241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 925de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return std::make_pair(FID, Offset); 926de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner} 927de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 928de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattnerstd::pair<FileID, unsigned> 929de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris LattnerSourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, 930de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned Offset) const { 9313201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // If this is an expansion record, walk through all the expansion points. 932bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner FileID FID; 933bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner SourceLocation Loc; 934bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner do { 9351728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = E->getExpansion().getSpellingLoc(); 936a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis Loc = Loc.getLocWithOffset(Offset); 9371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 938bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner FID = getFileID(Loc); 939bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner E = &getSLocEntry(FID); 940b6c465e17ec37390667223a18a340e8652c212ffArgyrios Kyrtzidis Offset = Loc.getOffset()-E->getOffset(); 941bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner } while (!Loc.isFileID()); 9421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 943de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return std::make_pair(FID, Offset); 944de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner} 945de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 946387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner/// getImmediateSpellingLoc - Given a SourceLocation object, return the 947387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner/// spelling location referenced by the ID. This is the first level down 948387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner/// towards the place where the characters that make up the lexed token can be 949387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner/// found. This should not generally be used by clients. 950387616edf98739f4a0dd234c907e2b913e6a535dChris LattnerSourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{ 951387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner if (Loc.isFileID()) return Loc; 952387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc); 9531728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc(); 954a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return Loc.getLocWithOffset(LocInfo.second); 955387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner} 956387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner 957387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner 9583201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// getImmediateExpansionRange - Loc is required to be an expansion location. 9593201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// Return the start/end of the expansion information. 960e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattnerstd::pair<SourceLocation,SourceLocation> 961999f739404edf2078cf9f9c28b4dc45c19765842Chandler CarruthSourceManager::getImmediateExpansionRange(SourceLocation Loc) const { 9623201f382956ed9beee9fb31229c2835c1208889cChandler Carruth assert(Loc.isMacroID() && "Not a macro expansion loc!"); 9631728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth const ExpansionInfo &Expansion = getSLocEntry(getFileID(Loc)).getExpansion(); 96478df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth return Expansion.getExpansionLocRange(); 965e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner} 966e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner 967edc3dccece244a584f8ebdb81da6c962c08e79beChandler Carruth/// getExpansionRange - Given a SourceLocation object, return the range of 968edc3dccece244a584f8ebdb81da6c962c08e79beChandler Carruth/// tokens covered by the expansion in the ultimate file. 9696678133b8ce642f93e5141f056fa643112041ad0Chris Lattnerstd::pair<SourceLocation,SourceLocation> 970edc3dccece244a584f8ebdb81da6c962c08e79beChandler CarruthSourceManager::getExpansionRange(SourceLocation Loc) const { 9716678133b8ce642f93e5141f056fa643112041ad0Chris Lattner if (Loc.isFileID()) return std::make_pair(Loc, Loc); 9721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9736678133b8ce642f93e5141f056fa643112041ad0Chris Lattner std::pair<SourceLocation,SourceLocation> Res = 974999f739404edf2078cf9f9c28b4dc45c19765842Chandler Carruth getImmediateExpansionRange(Loc); 9751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9763201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // Fully resolve the start and end locations to their ultimate expansion 9776678133b8ce642f93e5141f056fa643112041ad0Chris Lattner // points. 9786678133b8ce642f93e5141f056fa643112041ad0Chris Lattner while (!Res.first.isFileID()) 979999f739404edf2078cf9f9c28b4dc45c19765842Chandler Carruth Res.first = getImmediateExpansionRange(Res.first).first; 9806678133b8ce642f93e5141f056fa643112041ad0Chris Lattner while (!Res.second.isFileID()) 981999f739404edf2078cf9f9c28b4dc45c19765842Chandler Carruth Res.second = getImmediateExpansionRange(Res.second).second; 9826678133b8ce642f93e5141f056fa643112041ad0Chris Lattner return Res; 9836678133b8ce642f93e5141f056fa643112041ad0Chris Lattner} 9846678133b8ce642f93e5141f056fa643112041ad0Chris Lattner 98596d3589e523a04f4ff2058a7919226ce60696ae8Chandler Carruthbool SourceManager::isMacroArgExpansion(SourceLocation Loc) const { 986c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth if (!Loc.isMacroID()) return false; 987c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth 988c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth FileID FID = getFileID(Loc); 989c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gay const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion(); 99078df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth return Expansion.isMacroArgExpansion(); 991c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth} 992e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner 993c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gaybool SourceManager::isMacroBodyExpansion(SourceLocation Loc) const { 994c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gay if (!Loc.isMacroID()) return false; 995c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gay 996c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gay FileID FID = getFileID(Loc); 997c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gay const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion(); 998c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gay return Expansion.isMacroBodyExpansion(); 999c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gay} 1000c3cd6f7a5d33ad44f6c9cf4faa7046c77baa128eMatt Beaumont-Gay 1001de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 1002de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 1003de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// Queries about the code at a SourceLocation. 1004de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 10055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getCharacterData - Return a pointer to the start of the specified location 10075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// in the appropriate MemoryBuffer. 100850f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorconst char *SourceManager::getCharacterData(SourceLocation SL, 100950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 10105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Note that this is a hot function in the getSpelling() path, which is 10115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // heavily used by -E mode. 1012de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL); 10131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1014c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek // Note that calling 'getBuffer()' may lazily page in a source file. 101550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool CharDataInvalid = false; 1016e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(LocInfo.first, &CharDataInvalid); 1017e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (CharDataInvalid || !Entry.isFile()) { 1018e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1019e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor *Invalid = true; 1020e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1021e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return "<<<<INVALID BUFFER>>>>"; 1022e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor } 102350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor const llvm::MemoryBuffer *Buffer 1024e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor = Entry.getFile().getContentCache() 1025e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor ->getBuffer(Diag, *this, SourceLocation(), &CharDataInvalid); 102650f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Invalid) 102750f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor *Invalid = CharDataInvalid; 102850f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second); 10295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 10305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10329dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner/// getColumnNumber - Return the column # for the specified file position. 10337da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner/// this is significantly cheaper to compute than the line number. 103450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorunsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, 103550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 103650f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool MyInvalid = false; 1037d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis const llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid); 103850f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Invalid) 103950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor *Invalid = MyInvalid; 104050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor 104150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (MyInvalid) 104250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return 1; 10431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10442e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose // It is okay to request a position just past the end of the buffer. 10452e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose if (FilePos > MemBuf->getBufferSize()) { 1046d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis if (Invalid) 10472e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose *Invalid = true; 1048d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis return 1; 1049d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis } 1050d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis 1051d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper // See if we just calculated the line number for this FilePos and can use 1052d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper // that to lookup the start of the line instead of searching for it. 1053d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper if (LastLineNoFileIDQuery == FID && 1054d53c2d30cf89eca5c165d682f6cc1261f54674fdCraig Topper LastLineNoContentCache->SourceLineCache != 0 && 1055d53c2d30cf89eca5c165d682f6cc1261f54674fdCraig Topper LastLineNoResult < LastLineNoContentCache->NumLines) { 1056d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper unsigned *SourceLineCache = LastLineNoContentCache->SourceLineCache; 1057d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper unsigned LineStart = SourceLineCache[LastLineNoResult - 1]; 1058d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper unsigned LineEnd = SourceLineCache[LastLineNoResult]; 1059d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper if (FilePos >= LineStart && FilePos < LineEnd) 1060d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper return FilePos - LineStart + 1; 1061d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper } 1062d9cad403c0f76cbbcc53efbfeee3d59f9f0b6e09Craig Topper 1063098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith const char *Buf = MemBuf->getBufferStart(); 10645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned LineStart = FilePos; 10655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r') 10665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer --LineStart; 10675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FilePos-LineStart+1; 10685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 10695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10701f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan// isInvalid - Return the result of calling loc.isInvalid(), and 10711f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan// if Invalid is not null, set its value to same. 10721f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wanstatic bool isInvalid(SourceLocation Loc, bool *Invalid) { 10731f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan bool MyInvalid = Loc.isInvalid(); 10741f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (Invalid) 10751f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan *Invalid = MyInvalid; 10761f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan return MyInvalid; 10771f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan} 10781f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan 107950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorunsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc, 108050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 10811f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return 0; 10827da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc); 108350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return getColumnNumber(LocInfo.first, LocInfo.second, Invalid); 10847da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner} 10857da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner 1086a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruthunsigned SourceManager::getExpansionColumnNumber(SourceLocation Loc, 1087a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth bool *Invalid) const { 10881f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return 0; 1089e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 109050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return getColumnNumber(LocInfo.first, LocInfo.second, Invalid); 10917da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner} 10927da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner 10935ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruthunsigned SourceManager::getPresumedColumnNumber(SourceLocation Loc, 10945ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth bool *Invalid) const { 10955ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth if (isInvalid(Loc, Invalid)) return 0; 10965ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth return getPresumedLoc(Loc).getColumn(); 10975ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth} 10985ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth 1099d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#ifdef __SSE2__ 1100d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#include <emmintrin.h> 1101d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#endif 1102d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 110314bd96571ef6f0e97dc79ec4d01b547d60e8fa68Chandler Carruthstatic LLVM_ATTRIBUTE_NOINLINE void 1104d6471f7c1921c7802804ce3ff6fe9768310f72b9David BlaikieComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, 1105e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner llvm::BumpPtrAllocator &Alloc, 1106e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner const SourceManager &SM, bool &Invalid); 1107d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikiestatic void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, 1108e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner llvm::BumpPtrAllocator &Alloc, 1109e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner const SourceManager &SM, bool &Invalid) { 1110c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek // Note that calling 'getBuffer()' may lazily page in the file. 1111e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner const MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(), 1112e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner &Invalid); 111350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Invalid) 111450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return; 11151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11165e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Find the file offsets of all of the *physical* source lines. This does 11175e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // not look at trigraphs, escaped newlines, or anything else tricky. 11185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 256> LineOffsets; 11191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11205e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Line #1 starts at char 0. 11215e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner LineOffsets.push_back(0); 11221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11235e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart(); 11245e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd(); 11255e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner unsigned Offs = 0; 11265e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner while (1) { 11275e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Skip over the contents of the line. 11285e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner const unsigned char *NextBuf = (const unsigned char *)Buf; 1129d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1130d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#ifdef __SSE2__ 1131d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // Try to skip to the next newline using SSE instructions. This is very 1132d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // performance sensitive for programs with lots of diagnostics and in -E 1133d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // mode. 1134d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer __m128i CRs = _mm_set1_epi8('\r'); 1135d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer __m128i LFs = _mm_set1_epi8('\n'); 1136d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1137d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // First fix up the alignment to 16 bytes. 1138d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer while (((uintptr_t)NextBuf & 0xF) != 0) { 1139d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer if (*NextBuf == '\n' || *NextBuf == '\r' || *NextBuf == '\0') 1140d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer goto FoundSpecialChar; 1141d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer ++NextBuf; 1142d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer } 1143d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1144d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // Scan 16 byte chunks for '\r' and '\n'. Ignore '\0'. 1145d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer while (NextBuf+16 <= End) { 114631ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky const __m128i Chunk = *(const __m128i*)NextBuf; 1147d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer __m128i Cmp = _mm_or_si128(_mm_cmpeq_epi8(Chunk, CRs), 1148d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer _mm_cmpeq_epi8(Chunk, LFs)); 1149d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer unsigned Mask = _mm_movemask_epi8(Cmp); 1150d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1151d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // If we found a newline, adjust the pointer and jump to the handling code. 1152d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer if (Mask != 0) { 1153d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer NextBuf += llvm::CountTrailingZeros_32(Mask); 1154d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer goto FoundSpecialChar; 1155d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer } 1156d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer NextBuf += 16; 1157d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer } 1158d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#endif 1159d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 11605e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0') 11615e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner ++NextBuf; 1162d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1163d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#ifdef __SSE2__ 1164d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin KramerFoundSpecialChar: 1165d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#endif 11665e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner Offs += NextBuf-Buf; 11675e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner Buf = NextBuf; 11681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11695e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (Buf[0] == '\n' || Buf[0] == '\r') { 11705e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // If this is \n\r or \r\n, skip both characters. 11715e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1]) 11725e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner ++Offs, ++Buf; 11735e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner ++Offs, ++Buf; 11745e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner LineOffsets.push_back(Offs); 11755e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } else { 11765e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Otherwise, this is a null. If end of file, exit. 11775e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (Buf == End) break; 11785e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Otherwise, skip the null. 11795e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner ++Offs, ++Buf; 11805e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 11815e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 11821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11835e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Copy the offsets into the FileInfo structure. 11845e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner FI->NumLines = LineOffsets.size(); 11850d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner FI->SourceLineCache = Alloc.Allocate<unsigned>(LineOffsets.size()); 11865e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache); 11875e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner} 11885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1189df7c17a8d02fe09a3466786bae3e40fc3252687aChris Lattner/// getLineNumber - Given a SourceLocation, return the spelling line number 11905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for the position indicated. This requires building and caching a table of 11915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// line offsets for the MemoryBuffer, so this is not cheap: use only when 11925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// about to emit a diagnostic. 119350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorunsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, 119450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 11955adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis if (FID.isInvalid()) { 11965adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis if (Invalid) 11975adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis *Invalid = true; 11985adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis return 1; 11995adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis } 12005adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis 1201de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner ContentCache *Content; 120230fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner if (LastLineNoFileIDQuery == FID) 120378d85f53b093867bbb0123f016956178eea7343eTed Kremenek Content = LastLineNoContentCache; 1204e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor else { 1205e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool MyInvalid = false; 1206e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); 1207e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (MyInvalid || !Entry.isFile()) { 1208e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1209e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor *Invalid = true; 1210e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return 1; 1211e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor } 1212e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1213e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor Content = const_cast<ContentCache*>(Entry.getFile().getContentCache()); 1214e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor } 1215e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 12165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is the first use of line information for this buffer, compute the 12175e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner /// SourceLineCache for it on demand. 121850f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Content->SourceLineCache == 0) { 121950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool MyInvalid = false; 1220e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid); 122150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Invalid) 122250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor *Invalid = MyInvalid; 122350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (MyInvalid) 122450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return 1; 122550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor } else if (Invalid) 122650f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor *Invalid = false; 12275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 12285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Okay, we know we have a line number table. Do a binary search to find the 12295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // line number that this character position lands on. 123078d85f53b093867bbb0123f016956178eea7343eTed Kremenek unsigned *SourceLineCache = Content->SourceLineCache; 12315e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner unsigned *SourceLineCacheStart = SourceLineCache; 123278d85f53b093867bbb0123f016956178eea7343eTed Kremenek unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines; 12331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 123430fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner unsigned QueriedFilePos = FilePos+1; 12355e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner 12364106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // FIXME: I would like to be convinced that this code is worth being as 12371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // complicated as it is, binary search isn't that slow. 12384106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // 12394106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // If it is worth being optimized, then in my opinion it could be more 12404106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // performant, simpler, and more obviously correct by just "galloping" outward 12414106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // from the queried file position. In fact, this could be incorporated into a 12424106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // generic algorithm such as lower_bound_with_hint. 12434106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // 12444106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // If someone gives me a test case where this matters, and I will do it! - DWD 12454106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar 12465e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // If the previous query was to the same file, we know both the file pos from 12475e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // that query and the line number returned. This allows us to narrow the 12485e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // search space from the entire file to something near the match. 124930fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner if (LastLineNoFileIDQuery == FID) { 12505e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (QueriedFilePos >= LastLineNoFilePos) { 12514106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // FIXME: Potential overflow? 12525e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner SourceLineCache = SourceLineCache+LastLineNoResult-1; 12531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12545e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // The query is likely to be nearby the previous one. Here we check to 12555e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // see if it is within 5, 10 or 20 lines. It can be far away in cases 12565e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // where big comment blocks and vertical whitespace eat up lines but 12575e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // contribute no tokens. 12585e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (SourceLineCache+5 < SourceLineCacheEnd) { 12595e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (SourceLineCache[5] > QueriedFilePos) 12605e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner SourceLineCacheEnd = SourceLineCache+5; 12615e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner else if (SourceLineCache+10 < SourceLineCacheEnd) { 12625e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (SourceLineCache[10] > QueriedFilePos) 12635e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner SourceLineCacheEnd = SourceLineCache+10; 12645e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner else if (SourceLineCache+20 < SourceLineCacheEnd) { 12655e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (SourceLineCache[20] > QueriedFilePos) 12665e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner SourceLineCacheEnd = SourceLineCache+20; 12675e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12685e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12695e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12705e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } else { 12714106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar if (LastLineNoResult < Content->NumLines) 12724106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1; 12735e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12745e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12761cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // If the spread is large, do a "radix" test as our initial guess, based on 12771cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // the assumption that lines average to approximately the same length. 12781cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // NOTE: This is currently disabled, as it does not appear to be profitable in 12791cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // initial measurements. 12801cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner if (0 && SourceLineCacheEnd-SourceLineCache > 20) { 128178d85f53b093867bbb0123f016956178eea7343eTed Kremenek unsigned FileLen = Content->SourceLineCache[Content->NumLines-1]; 12821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12831cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // Take a stab at guessing where it is. 128478d85f53b093867bbb0123f016956178eea7343eTed Kremenek unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen; 12851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12861cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // Check for -10 and +10 lines. 12871cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner unsigned LowerBound = std::max(int(ApproxPos-10), 0); 12881cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner unsigned UpperBound = std::min(ApproxPos+10, FileLen); 12891cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner 12901cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // If the computed lower bound is less than the query location, move it in. 12911cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner if (SourceLineCache < SourceLineCacheStart+LowerBound && 12921cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner SourceLineCacheStart[LowerBound] < QueriedFilePos) 12931cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner SourceLineCache = SourceLineCacheStart+LowerBound; 12941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12951cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // If the computed upper bound is greater than the query location, move it. 12961cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound && 12971cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner SourceLineCacheStart[UpperBound] >= QueriedFilePos) 12981cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner SourceLineCacheEnd = SourceLineCacheStart+UpperBound; 12991cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner } 13001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13011cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner unsigned *Pos 13021cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos); 13035e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner unsigned LineNo = Pos-SourceLineCacheStart; 13041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 130530fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner LastLineNoFileIDQuery = FID; 130678d85f53b093867bbb0123f016956178eea7343eTed Kremenek LastLineNoContentCache = Content; 13075e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner LastLineNoFilePos = QueriedFilePos; 13085e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner LastLineNoResult = LineNo; 13095e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner return LineNo; 13105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 13115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 13125ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruthunsigned SourceManager::getSpellingLineNumber(SourceLocation Loc, 13135ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth bool *Invalid) const { 13145ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth if (isInvalid(Loc, Invalid)) return 0; 13155ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc); 13165ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth return getLineNumber(LocInfo.first, LocInfo.second); 13175ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth} 1318642116259e8df6286063a17361c20e95b5017a0aChandler Carruthunsigned SourceManager::getExpansionLineNumber(SourceLocation Loc, 1319642116259e8df6286063a17361c20e95b5017a0aChandler Carruth bool *Invalid) const { 13201f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return 0; 1321e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 132230fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner return getLineNumber(LocInfo.first, LocInfo.second); 132330fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner} 13245ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruthunsigned SourceManager::getPresumedLineNumber(SourceLocation Loc, 132550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 13261f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return 0; 13275ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth return getPresumedLoc(Loc).getLine(); 132830fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner} 132930fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner 13306b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// getFileCharacteristic - return the file characteristic of the specified 13311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// source location, indicating whether this is a normal file, a system 13326b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// header, or an "implicit extern C" system header. 13336b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// 13346b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// This state can be modified with flags on GNU linemarker directives like: 13356b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// # 4 "foo.h" 3 13366b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// which changes all source locations in the current file after that to be 13376b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// considered to be from a system header. 13381eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpSrcMgr::CharacteristicKind 13396b3066780bda02e3117d71a18ca2f430ed1454afChris LattnerSourceManager::getFileCharacteristic(SourceLocation Loc) const { 13406b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!"); 1341e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 1342e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1343e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &SEntry = getSLocEntry(LocInfo.first, &Invalid); 1344e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid || !SEntry.isFile()) 1345e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return C_User; 1346e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1347e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::FileInfo &FI = SEntry.getFile(); 13486b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner 13496b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner // If there are no #line directives in this file, just return the whole-file 13506b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner // state. 13516b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner if (!FI.hasLineDirectives()) 13526b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner return FI.getFileCharacteristic(); 13531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13546b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner assert(LineTable && "Can't have linetable entries without a LineTable!"); 13556b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner // See if there is a #line directive before the location. 13566b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner const LineEntry *Entry = 135747d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregor LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second); 13581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13596b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner // If this is before the first line marker, use the file characteristic. 13606b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner if (!Entry) 13616b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner return FI.getFileCharacteristic(); 13626b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner 13636b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner return Entry->FileKind; 13646b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner} 13656b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner 1366bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner/// Return the filename or buffer identifier of the buffer the location is in. 1367b8950b8e11272a3b9776568ea423bff016bc996dJames Dennett/// Note that this name does not respect \#line directives. Use getPresumedLoc 1368bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner/// for normal clients. 136950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorconst char *SourceManager::getBufferName(SourceLocation Loc, 137050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 13711f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return "<invalid loc>"; 13721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 137350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return getBuffer(getFileID(Loc), Invalid)->getBufferIdentifier(); 1374bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner} 1375bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner 137630fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner 1377b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// getPresumedLoc - This method returns the "presumed" location of a 1378b8950b8e11272a3b9776568ea423bff016bc996dJames Dennett/// SourceLocation specifies. A "presumed location" can be modified by \#line 1379b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// or GNU line marker directives. This provides a view on the data that a 1380b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// user should see in diagnostics, for example. 1381b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// 13823201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// Note that a presumed location is always given as the expansion point of an 13833201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// expansion location, not at the spelling location. 138462221b17c90457df9ca0ff20bb54d634e8951defRichard SmithPresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, 138562221b17c90457df9ca0ff20bb54d634e8951defRichard Smith bool UseLineDirectives) const { 1386b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner if (Loc.isInvalid()) return PresumedLoc(); 13871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13883201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // Presumed locations are always for expansion points. 1389e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 13901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1391e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1392e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); 1393e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid || !Entry.isFile()) 1394e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return PresumedLoc(); 1395e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1396e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::FileInfo &FI = Entry.getFile(); 1397b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner const SrcMgr::ContentCache *C = FI.getContentCache(); 13981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13993cd949c27c63f544a081b9a750740064ddef181bChris Lattner // To get the source name, first consult the FileEntry (if one exists) 14003cd949c27c63f544a081b9a750740064ddef181bChris Lattner // before the MemBuffer as this will avoid unnecessarily paging in the 14013cd949c27c63f544a081b9a750740064ddef181bChris Lattner // MemBuffer. 1402e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner const char *Filename; 1403b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (C->OrigEntry) 1404b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Filename = C->OrigEntry->getName(); 1405e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner else 1406e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner Filename = C->getBuffer(Diag, *this)->getBufferIdentifier(); 1407e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1408c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second, &Invalid); 1409c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor if (Invalid) 1410c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor return PresumedLoc(); 1411c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor unsigned ColNo = getColumnNumber(LocInfo.first, LocInfo.second, &Invalid); 1412c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor if (Invalid) 1413c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor return PresumedLoc(); 1414c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor 14153cd949c27c63f544a081b9a750740064ddef181bChris Lattner SourceLocation IncludeLoc = FI.getIncludeLoc(); 14161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14173cd949c27c63f544a081b9a750740064ddef181bChris Lattner // If we have #line directives in this file, update and overwrite the physical 14183cd949c27c63f544a081b9a750740064ddef181bChris Lattner // location info if appropriate. 141962221b17c90457df9ca0ff20bb54d634e8951defRichard Smith if (UseLineDirectives && FI.hasLineDirectives()) { 14203cd949c27c63f544a081b9a750740064ddef181bChris Lattner assert(LineTable && "Can't have linetable entries without a LineTable!"); 14213cd949c27c63f544a081b9a750740064ddef181bChris Lattner // See if there is a #line directive before this. If so, get it. 14223cd949c27c63f544a081b9a750740064ddef181bChris Lattner if (const LineEntry *Entry = 142347d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregor LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) { 1424fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // If the LineEntry indicates a filename, use it. 14253cd949c27c63f544a081b9a750740064ddef181bChris Lattner if (Entry->FilenameID != -1) 14263cd949c27c63f544a081b9a750740064ddef181bChris Lattner Filename = LineTable->getFilename(Entry->FilenameID); 1427fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner 1428fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // Use the line number specified by the LineEntry. This line number may 1429fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // be multiple lines down from the line entry. Add the difference in 1430fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // physical line numbers from the query point and the line marker to the 1431fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // total. 1432fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset); 1433fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1); 14341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14350e0e5da00e92a9ee97b2469009355926ee8d94bfChris Lattner // Note that column numbers are not molested by line markers. 14361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1437137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner // Handle virtual #include manipulation. 1438137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner if (Entry->IncludeOffset) { 1439137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeLoc = getLocForStartOfFile(LocInfo.first); 1440a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis IncludeLoc = IncludeLoc.getLocWithOffset(Entry->IncludeOffset); 1441137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner } 14423cd949c27c63f544a081b9a750740064ddef181bChris Lattner } 14433cd949c27c63f544a081b9a750740064ddef181bChris Lattner } 14443cd949c27c63f544a081b9a750740064ddef181bChris Lattner 14453cd949c27c63f544a081b9a750740064ddef181bChris Lattner return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc); 1446de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner} 1447de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 1448984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis/// \brief The size of the SLocEnty that \arg FID represents. 1449984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidisunsigned SourceManager::getFileIDSize(FileID FID) const { 1450984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis bool Invalid = false; 1451984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); 1452984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis if (Invalid) 1453984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis return 0; 1454984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis 1455984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis int ID = FID.ID; 1456984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis unsigned NextOffset; 1457984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis if ((ID > 0 && unsigned(ID+1) == local_sloc_entry_size())) 1458984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis NextOffset = getNextLocalOffset(); 1459984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis else if (ID+1 == -1) 1460984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis NextOffset = MaxLoadedOffset; 1461984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis else 1462984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis NextOffset = getSLocEntry(FileID::get(ID+1)).getOffset(); 1463984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis 1464984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis return NextOffset - Entry.getOffset() - 1; 1465984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis} 1466984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis 1467de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 1468de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// Other miscellaneous methods. 1469de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 1470de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 147186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor/// \brief Retrieve the inode for the given file entry, if possible. 147286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor/// 147386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor/// This routine involves a system call, and therefore should only be used 147486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor/// in non-performance-critical code. 1475dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikiestatic Optional<ino_t> getActualFileInode(const FileEntry *File) { 147686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (!File) 147766874fb18afbffb8b2ca05576851a64534be3352David Blaikie return None; 147886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 147986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor struct stat StatBuf; 148086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (::stat(File->getName(), &StatBuf)) 148166874fb18afbffb8b2ca05576851a64534be3352David Blaikie return None; 148286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 148386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return StatBuf.st_ino; 148486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor} 148586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 148610b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis/// \brief Get the source location for the given file:line:col triplet. 148710b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis/// 148810b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis/// If the source file is included multiple times, the source location will 1489f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// be based upon an arbitrary inclusion. 1490ac836e442cbd17f33533bd0b4879258945bc1723Argyrios KyrtzidisSourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile, 1491507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Line, 1492507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Col) const { 149310b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis assert(SourceFile && "Null source file!"); 149410b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis assert(Line && Col && "Line and column should start from 1!"); 149510b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis 1496b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis FileID FirstFID = translateFile(SourceFile); 1497b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return translateLineCol(FirstFID, Line, Col); 1498b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis} 1499b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis 1500b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis/// \brief Get the FileID for the given file. 1501b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis/// 1502b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis/// If the source file is included multiple times, the FileID will be the 1503b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis/// first inclusion. 1504b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios KyrtzidisFileID SourceManager::translateFile(const FileEntry *SourceFile) const { 1505b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis assert(SourceFile && "Null source file!"); 1506b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis 15074a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor // Find the first file ID that corresponds to the given file. 15084a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor FileID FirstFID; 15094a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor 15104a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor // First, check the main file ID, since it is common to look for a 15114a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor // location in the main file. 1512dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<ino_t> SourceFileInode; 1513dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<StringRef> SourceFileName; 15144a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor if (!MainFileID.isInvalid()) { 1515e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1516e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid); 1517e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1518b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return FileID(); 1519e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 152086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (MainSLoc.isFile()) { 152186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor const ContentCache *MainContentCache 152286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor = MainSLoc.getFile().getContentCache(); 1523b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor if (!MainContentCache) { 1524b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor // Can't do anything 1525b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else if (MainContentCache->OrigEntry == SourceFile) { 152686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor FirstFID = MainFileID; 1527b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor } else { 152886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // Fall back: check whether we have the same base name and inode 152986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // as the main file. 1530b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *MainFile = MainContentCache->OrigEntry; 153186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor SourceFileName = llvm::sys::path::filename(SourceFile->getName()); 153286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) { 153386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor SourceFileInode = getActualFileInode(SourceFile); 153437c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor if (SourceFileInode) { 1535dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<ino_t> MainFileInode = getActualFileInode(MainFile)) { 153637c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor if (*SourceFileInode == *MainFileInode) { 153737c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor FirstFID = MainFileID; 153837c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor SourceFile = MainFile; 153937c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor } 154037c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor } 154186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 154286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 154386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 154486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 15454a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor } 15464a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor 15474a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor if (FirstFID.isInvalid()) { 15484a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor // The location we're looking for isn't in the main file; look 1549f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // through all of the local source locations. 1550f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { 1551e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1552f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid); 1553e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1554b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return FileID(); 1555e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 155686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (SLoc.isFile() && 155786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor SLoc.getFile().getContentCache() && 1558b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis SLoc.getFile().getContentCache()->OrigEntry == SourceFile) { 15594a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor FirstFID = FileID::get(I); 15604a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor break; 15614a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor } 15624a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor } 1563f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // If that still didn't help, try the modules. 1564f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (FirstFID.isInvalid()) { 1565f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) { 1566f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SLocEntry &SLoc = getLoadedSLocEntry(I); 1567f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (SLoc.isFile() && 1568f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLoc.getFile().getContentCache() && 1569f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLoc.getFile().getContentCache()->OrigEntry == SourceFile) { 1570f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FirstFID = FileID::get(-int(I) - 2); 1571f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor break; 1572f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1573f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1574f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 15754a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor } 157686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 157786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // If we haven't found what we want yet, try again, but this time stat() 157886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // each of the files in case the files have changed since we originally 157986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // parsed the file. 158086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (FirstFID.isInvalid() && 158186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor (SourceFileName || 158286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor (SourceFileName = llvm::sys::path::filename(SourceFile->getName()))) && 158386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor (SourceFileInode || 158486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor (SourceFileInode = getActualFileInode(SourceFile)))) { 1585e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1586f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { 1587f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID IFileID; 1588f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor IFileID.ID = I; 1589f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SLocEntry &SLoc = getSLocEntry(IFileID, &Invalid); 1590e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1591b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return FileID(); 1592e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 159386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (SLoc.isFile()) { 159486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor const ContentCache *FileContentCache 159586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor = SLoc.getFile().getContentCache(); 1596b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *Entry =FileContentCache? FileContentCache->OrigEntry : 0; 159786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (Entry && 1598b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor *SourceFileName == llvm::sys::path::filename(Entry->getName())) { 1599dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<ino_t> EntryInode = getActualFileInode(Entry)) { 1600b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor if (*SourceFileInode == *EntryInode) { 1601b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor FirstFID = FileID::get(I); 1602b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor SourceFile = Entry; 1603b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor break; 1604b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor } 1605b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor } 160686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 160786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 160886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 160986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 1610b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis 1611186ec9c2e6db6fd5827f2078d2a6b82085be54d3Ted Kremenek (void) SourceFile; 1612b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return FirstFID; 1613efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis} 1614efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis 1615efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis/// \brief Get the source location in \arg FID for the given line:col. 1616efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis/// Returns null location if \arg FID is not a file SLocEntry. 1617efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios KyrtzidisSourceLocation SourceManager::translateLineCol(FileID FID, 1618507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Line, 1619507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Col) const { 1620efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis if (FID.isInvalid()) 1621efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis return SourceLocation(); 1622efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis 1623efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis bool Invalid = false; 1624efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis const SLocEntry &Entry = getSLocEntry(FID, &Invalid); 1625efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis if (Invalid) 1626efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis return SourceLocation(); 1627efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis 1628efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis if (!Entry.isFile()) 16294a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor return SourceLocation(); 16304a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor 16315e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis SourceLocation FileLoc = SourceLocation::getFileLoc(Entry.getOffset()); 16325e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis 163386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (Line == 1 && Col == 1) 16345e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc; 163586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 163686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor ContentCache *Content 1637efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis = const_cast<ContentCache *>(Entry.getFile().getContentCache()); 163886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (!Content) 163986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return SourceLocation(); 164086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 164186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // If this is the first use of line information for this buffer, compute the 1642f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // SourceLineCache for it on demand. 164386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (Content->SourceLineCache == 0) { 164486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor bool MyInvalid = false; 164586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid); 164686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (MyInvalid) 164786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return SourceLocation(); 164886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 164986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 1650d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor if (Line > Content->NumLines) { 1651e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner unsigned Size = Content->getBuffer(Diag, *this)->getBufferSize(); 1652d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor if (Size > 0) 1653d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor --Size; 16545e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc.getLocWithOffset(Size); 1655d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor } 1656d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor 1657098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this); 1658d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor unsigned FilePos = Content->SourceLineCache[Line - 1]; 1659098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith const char *Buf = Buffer->getBufferStart() + FilePos; 1660098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith unsigned BufLength = Buffer->getBufferSize() - FilePos; 16615e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis if (BufLength == 0) 16625e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc.getLocWithOffset(FilePos); 16635e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis 1664d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor unsigned i = 0; 1665d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor 1666d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor // Check that the given column is valid. 1667d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r') 1668d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor ++i; 1669d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor if (i < Col-1) 16705e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc.getLocWithOffset(FilePos + i); 1671d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor 16725e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc.getLocWithOffset(FilePos + Col - 1); 167310b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis} 167410b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis 1675d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// \brief Compute a map of macro argument chunks to their expanded source 1676d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// location. Chunks that are not part of a macro argument will map to an 1677d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// invalid source location. e.g. if a file contains one macro argument at 1678d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// offset 100 with length 10, this is how the map will be formed: 1679d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// 0 -> SourceLocation() 1680d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// 100 -> Expanded macro arg location 1681d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// 110 -> SourceLocation() 1682fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidisvoid SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr, 1683507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis FileID FID) const { 1684d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis assert(!FID.isInvalid()); 1685fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis assert(!CachePtr); 1686d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1687fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis CachePtr = new MacroArgsMap(); 1688fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis MacroArgsMap &MacroArgsCache = *CachePtr; 1689d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // Initially no macro argument chunk is present. 1690d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis MacroArgsCache.insert(std::make_pair(0, SourceLocation())); 1691ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis 1692ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis int ID = FID.ID; 1693ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis while (1) { 1694ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis ++ID; 1695ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis // Stop if there are no more FileIDs to check. 1696ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis if (ID > 0) { 1697ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis if (unsigned(ID) >= local_sloc_entry_size()) 1698d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return; 1699ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis } else if (ID == -1) { 1700d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return; 1701ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis } 1702ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis 1703ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID); 1704ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis if (Entry.isFile()) { 1705d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc(); 1706d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (IncludeLoc.isInvalid()) 1707d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis continue; 1708d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (!isInFileID(IncludeLoc, FID)) 1709d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return; // No more files/macros that may be "contained" in this file. 1710d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1711d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // Skip the files/macros of the #include'd file, we only care about macros 1712d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // that lexed macro arguments from our file. 1713d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (Entry.getFile().NumCreatedFIDs) 1714d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis ID += Entry.getFile().NumCreatedFIDs - 1/*because of next ++ID*/; 1715ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis continue; 1716ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis } 1717d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1718cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const ExpansionInfo &ExpInfo = Entry.getExpansion(); 1719cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 1720cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (ExpInfo.getExpansionLocStart().isFileID()) { 1721cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (!isInFileID(ExpInfo.getExpansionLocStart(), FID)) 1722cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis return; // No more files/macros that may be "contained" in this file. 1723cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis } 1724cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 1725cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (!ExpInfo.isMacroArgExpansion()) 1726ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis continue; 1727cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 17280872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis associateFileChunkWithMacroArgExp(MacroArgsCache, FID, 17290872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis ExpInfo.getSpellingLoc(), 17300872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis SourceLocation::getMacroLoc(Entry.getOffset()), 17310872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis getFileIDSize(FileID::get(ID))); 17320872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis } 17330872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis} 17340872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17350872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidisvoid SourceManager::associateFileChunkWithMacroArgExp( 17360872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis MacroArgsMap &MacroArgsCache, 17370872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis FileID FID, 17380872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis SourceLocation SpellLoc, 17390872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis SourceLocation ExpansionLoc, 17400872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned ExpansionLength) const { 17410872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis if (!SpellLoc.isFileID()) { 17420872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned SpellBeginOffs = SpellLoc.getOffset(); 17430872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength; 17440872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17450872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // The spelling range for this macro argument expansion can span multiple 17460872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // consecutive FileID entries. Go through each entry contained in the 17470872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // spelling range and if one is itself a macro argument expansion, recurse 17480872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // and associate the file chunk that it represents. 17490872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17500872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis FileID SpellFID; // Current FileID in the spelling range. 17510872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned SpellRelativeOffs; 17520872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis llvm::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc); 17530872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis while (1) { 17540872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis const SLocEntry &Entry = getSLocEntry(SpellFID); 17550872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned SpellFIDBeginOffs = Entry.getOffset(); 17560872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned SpellFIDSize = getFileIDSize(SpellFID); 17570872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize; 17580872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis const ExpansionInfo &Info = Entry.getExpansion(); 17590872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis if (Info.isMacroArgExpansion()) { 17600872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned CurrSpellLength; 17610872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis if (SpellFIDEndOffs < SpellEndOffs) 17620872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis CurrSpellLength = SpellFIDSize - SpellRelativeOffs; 17630872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis else 17640872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis CurrSpellLength = ExpansionLength; 17650872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis associateFileChunkWithMacroArgExp(MacroArgsCache, FID, 17660872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis Info.getSpellingLoc().getLocWithOffset(SpellRelativeOffs), 17670872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis ExpansionLoc, CurrSpellLength); 17680872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis } 17690872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17700872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis if (SpellFIDEndOffs >= SpellEndOffs) 17710872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis return; // we covered all FileID entries in the spelling range. 17720872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17730872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // Move to the next FileID entry in the spelling range. 17740872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned advance = SpellFIDSize - SpellRelativeOffs + 1; 17750872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis ExpansionLoc = ExpansionLoc.getLocWithOffset(advance); 17760872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis ExpansionLength -= advance; 17770872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis ++SpellFID.ID; 17780872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis SpellRelativeOffs = 0; 1779cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis } 1780cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 1781ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis } 17820872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17830872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis assert(SpellLoc.isFileID()); 17840872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17850872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned BeginOffs; 17860872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis if (!isInFileID(SpellLoc, FID, &BeginOffs)) 17870872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis return; 17880872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17890872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis unsigned EndOffs = BeginOffs + ExpansionLength; 17900872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 17910872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // Add a new chunk for this macro argument. A previous macro argument chunk 17920872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // may have been lexed again, so e.g. if the map is 17930872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 0 -> SourceLocation() 17940872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 100 -> Expanded loc #1 17950872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 110 -> SourceLocation() 17960872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // and we found a new macro FileID that lexed from offet 105 with length 3, 17970872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // the new map will be: 17980872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 0 -> SourceLocation() 17990872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 100 -> Expanded loc #1 18000872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 105 -> Expanded loc #2 18010872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 108 -> Expanded loc #1 18020872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 110 -> SourceLocation() 18030872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // 18040872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // Since re-lexed macro chunks will always be the same size or less of 18050872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // previous chunks, we only need to find where the ending of the new macro 18060872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis // chunk is mapped to and update the map with new begin/end mappings. 18070872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis 18080872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs); 18090872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis --I; 18100872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis SourceLocation EndOffsMappedLoc = I->second; 18110872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis MacroArgsCache[BeginOffs] = ExpansionLoc; 18120872a06d1ee1a3b62ef833f955051418d18006a1Argyrios Kyrtzidis MacroArgsCache[EndOffs] = EndOffsMappedLoc; 1813ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis} 1814ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis 1815d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// \brief If \arg Loc points inside a function macro argument, the returned 1816d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// location will be the macro location in which the argument was expanded. 1817d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// If a macro argument is used multiple times, the expanded location will 1818d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// be at the first expansion of the argument. 1819d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// e.g. 1820d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// MY_MACRO(foo); 1821d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// ^ 1822d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// Passing a file location pointing at 'foo', will yield a macro location 1823d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// where 'foo' was expanded into. 1824507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceLocation 1825507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { 1826d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (Loc.isInvalid() || !Loc.isFileID()) 1827d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return Loc; 1828d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1829d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis FileID FID; 1830d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis unsigned Offset; 1831d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis llvm::tie(FID, Offset) = getDecomposedLoc(Loc); 1832d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (FID.isInvalid()) 1833d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return Loc; 1834d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1835fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis MacroArgsMap *&MacroArgsCache = MacroArgsCacheMap[FID]; 1836fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis if (!MacroArgsCache) 1837fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis computeMacroArgsCache(MacroArgsCache, FID); 1838fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis 1839fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis assert(!MacroArgsCache->empty()); 1840fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset); 1841d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis --I; 1842d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1843d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis unsigned MacroArgBeginOffs = I->first; 1844d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis SourceLocation MacroArgExpandedLoc = I->second; 1845d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (MacroArgExpandedLoc.isValid()) 1846a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return MacroArgExpandedLoc.getLocWithOffset(Offset - MacroArgBeginOffs); 1847d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1848d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return Loc; 1849d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis} 1850d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 18513201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// Given a decomposed source location, move it up the include/expansion stack 18523201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// to the parent source location. If this is possible, return the decomposed 18533201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// version of the parent in Loc and return false. If Loc is the top-level 18543201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// entry, return true and don't modify it. 1855d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattnerstatic bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc, 1856d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner const SourceManager &SM) { 1857d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner SourceLocation UpperLoc; 1858d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(Loc.first); 18591728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (Entry.isExpansion()) 1860d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis UpperLoc = Entry.getExpansion().getExpansionLocStart(); 1861d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner else 1862d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner UpperLoc = Entry.getFile().getIncludeLoc(); 1863d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner 1864d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner if (UpperLoc.isInvalid()) 1865d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner return true; // We reached the top. 1866d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner 1867d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner Loc = SM.getDecomposedLoc(UpperLoc); 1868d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner return false; 1869d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner} 18702564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek 18712564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek/// Return the cache entry for comparing the given file IDs 18722564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek/// for isBeforeInTranslationUnit. 18732564f811ba107cb314a594d730aa3357b6181b62Ted KremenekInBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID, 18742564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek FileID RFID) const { 18752564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // This is a magic number for limiting the cache size. It was experimentally 18762564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // derived from a small Objective-C project (where the cache filled 18772564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // out to ~250 items). We can make it larger if necessary. 18782564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek enum { MagicCacheSize = 300 }; 18792564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek IsBeforeInTUCacheKey Key(LFID, RFID); 18802564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek 18812564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // If the cache size isn't too large, do a lookup and if necessary default 18822564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // construct an entry. We can then return it to the caller for direct 18832564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // use. When they update the value, the cache will get automatically 18842564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // updated as well. 18852564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek if (IBTUCache.size() < MagicCacheSize) 18862564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek return IBTUCache[Key]; 18872564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek 18882564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // Otherwise, do a lookup that will not construct a new value. 18892564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek InBeforeInTUCache::iterator I = IBTUCache.find(Key); 18902564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek if (I != IBTUCache.end()) 18912564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek return I->second; 18922564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek 18932564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // Fall back to the overflow value. 18942564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek return IBTUCacheOverflow; 18952564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek} 1896d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner 18972aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis/// \brief Determines the order of 2 source locations in the translation unit. 18982aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis/// 18992aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis/// \returns true if LHS source location comes before RHS, false otherwise. 19002aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidisbool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, 19012aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis SourceLocation RHS) const { 19022aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis assert(LHS.isValid() && RHS.isValid() && "Passed invalid source location!"); 19032aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis if (LHS == RHS) 19042aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis return false; 19051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19062aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS); 19072aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS); 19081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19092aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis // If the source locations are in the same file, just compare offsets. 19102aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis if (LOffs.first == ROffs.first) 19112aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis return LOffs.second < ROffs.second; 19122aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis 19132aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis // If we are comparing a source location with multiple locations in the same 19142aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis // file, we get a big win by caching the result. 19152564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek InBeforeInTUCacheEntry &IsBeforeInTUCache = 19162564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek getInBeforeInTUCache(LOffs.first, ROffs.first); 19172564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek 19182564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // If we are comparing a source location with multiple locations in the same 19192564f811ba107cb314a594d730aa3357b6181b62Ted Kremenek // file, we get a big win by caching the result. 192066a915fbd73a0e404ed28f58e4a3f1b8d0f8fb94Chris Lattner if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first)) 192166a915fbd73a0e404ed28f58e4a3f1b8d0f8fb94Chris Lattner return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); 19221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1923dcb1d68f6ffa183f3919aee6b554aec3793bf13eChris Lattner // Okay, we missed in the cache, start updating the cache for this query. 192437e59a10a7a537428e5997fd5896f5b89fd34e6bArgyrios Kyrtzidis IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first, 192537e59a10a7a537428e5997fd5896f5b89fd34e6bArgyrios Kyrtzidis /*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID); 19261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1927f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // We need to find the common ancestor. The only way of doing this is to 1928f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // build the complete include chain for one and then walking up the chain 1929f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // of the other looking for a match. 1930f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // We use a map from FileID to Offset to store the chain. Easier than writing 1931f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // a custom set hash info that only depends on the first part of a pair. 1932f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor typedef llvm::DenseMap<FileID, unsigned> LocSet; 1933f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocSet LChain; 193448296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner do { 1935f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LChain.insert(LOffs); 1936f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // We catch the case where LOffs is in a file included by ROffs and 1937f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // quit early. The other way round unfortunately remains suboptimal. 1938f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this)); 1939f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocSet::iterator I; 1940f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor while((I = LChain.find(ROffs.first)) == LChain.end()) { 1941f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (MoveUpIncludeHierarchy(ROffs, *this)) 1942f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor break; // Met at topmost file. 1943f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1944f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (I != LChain.end()) 1945f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LOffs = *I; 19461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 194748296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner // If we exited because we found a nearest common ancestor, compare the 194848296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner // locations within the common file and cache them. 194948296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner if (LOffs.first == ROffs.first) { 195048296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second); 195148296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); 19522aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis } 19531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1954f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // This can happen if a location is in a built-ins buffer. 1955f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // But see PR5662. 1956f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Clear the lookup cache, it depends on a common location. 195737e59a10a7a537428e5997fd5896f5b89fd34e6bArgyrios Kyrtzidis IsBeforeInTUCache.clear(); 1958f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor bool LIsBuiltins = strcmp("<built-in>", 1959f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getBuffer(LOffs.first)->getBufferIdentifier()) == 0; 1960f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor bool RIsBuiltins = strcmp("<built-in>", 1961f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getBuffer(ROffs.first)->getBufferIdentifier()) == 0; 1962f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // built-in is before non-built-in 1963f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LIsBuiltins != RIsBuiltins) 1964f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return LIsBuiltins; 1965f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(LIsBuiltins && RIsBuiltins && 1966f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor "Non-built-in locations must be rooted in the main file"); 1967f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Both are in built-in buffers, but from different files. We just claim that 1968f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // lower IDs come first. 1969dcb1d68f6ffa183f3919aee6b554aec3793bf13eChris Lattner return LOffs.first < ROffs.first; 19702aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis} 1971de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 19725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid SourceManager::PrintStats() const { 19736cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "\n*** Source Manager Stats:\n"; 19746cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size() 19756cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer << " mem buffers mapped.\n"; 1976f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntry's allocated (" 19776e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek << llvm::capacity_in_bytes(LocalSLocEntryTable) 1978d410e741e8085e109c1dc5886c0acea88a4ca0f4Argyrios Kyrtzidis << " bytes of capacity), " 1979f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor << NextLocalOffset << "B of Sloc address space used.\n"; 1980f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor llvm::errs() << LoadedSLocEntryTable.size() 1981f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor << " loaded SLocEntries allocated, " 1982ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis << MaxLoadedOffset - CurrentLoadedOffset 1983f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor << "B of Sloc address space used.\n"; 1984f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 19855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumLineNumsComputed = 0; 19865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumFileBytesMapped = 0; 19870d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){ 19880d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner NumLineNumsComputed += I->second->SourceLineCache != 0; 19890d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner NumFileBytesMapped += I->second->getSizeBytesMapped(); 19905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1991fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis unsigned NumMacroArgsComputed = MacroArgsCacheMap.size(); 19921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19936cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << NumFileBytesMapped << " bytes of files mapped, " 1994d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis << NumLineNumsComputed << " files with line #'s computed, " 1995d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis << NumMacroArgsComputed << " files with macro args computed.\n"; 19966cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "FileID scans: " << NumLinearScans << " linear, " 19976cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer << NumBinaryProbes << " binary.\n"; 19985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 19997f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 20007f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas GregorExternalSLocEntrySource::~ExternalSLocEntrySource() { } 2001f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 2002f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek/// Return the amount of memory used by memory buffers, breaking down 2003f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek/// by heap-backed versus mmap'ed memory. 2004f61b831d7f6a15676b07647f507de80324cb7056Ted KremenekSourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const { 2005f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek size_t malloc_bytes = 0; 2006f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek size_t mmap_bytes = 0; 2007f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 2008f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) 2009f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek if (size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped()) 2010f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek switch (MemBufferInfos[i]->getMemoryBufferKind()) { 2011f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek case llvm::MemoryBuffer::MemoryBuffer_MMap: 2012f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek mmap_bytes += sized_mapped; 2013f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek break; 2014f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek case llvm::MemoryBuffer::MemoryBuffer_Malloc: 2015f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek malloc_bytes += sized_mapped; 2016f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek break; 2017f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek } 2018f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 2019f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek return MemoryBufferSizes(malloc_bytes, mmap_bytes); 2020f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek} 2021f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 2022ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremeneksize_t SourceManager::getDataStructureSizes() const { 2023d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis size_t size = llvm::capacity_in_bytes(MemBufferInfos) 20246e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek + llvm::capacity_in_bytes(LocalSLocEntryTable) 20256e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek + llvm::capacity_in_bytes(LoadedSLocEntryTable) 20266e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek + llvm::capacity_in_bytes(SLocEntryLoaded) 2027d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis + llvm::capacity_in_bytes(FileInfos); 2028d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 2029d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (OverriddenFilesInfo) 2030d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles); 2031d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 2032d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis return size; 2033ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek} 2034