SourceManager.cpp revision 7285a06a0655ed93e313305182f67edb73890247
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" 15d4f77aa7c276be49aee5e59ef509cb91e26aa79fDouglas Gregor#include "clang/Basic/SourceManagerInternals.h" 16aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor#include "clang/Basic/Diagnostic.h" 175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/FileManager.h" 185807d9cce3f0ab4366bed9470355433c7b562c8dBenjamin Kramer#include "llvm/ADT/StringSwitch.h" 1986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor#include "llvm/ADT/Optional.h" 20d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis#include "llvm/ADT/STLExtras.h" 215e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner#include "llvm/Support/Compiler.h" 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/MemoryBuffer.h" 23d57a7ef9252964bc6c8471451d7bd395b0520cb8Chris Lattner#include "llvm/Support/raw_ostream.h" 2403013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h" 256e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek#include "llvm/Support/Capacity.h" 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <algorithm> 27aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor#include <string> 28f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor#include <cstring> 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; 100b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Buffer.setPointer(SM.getFileManager().getBufferForFile(ContentsEntry, &ErrorStr)); 10193ea5cb0edf8e509c5113e70cb05ee247c9bdf6bDouglas Gregor 102b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // If we were unable to open the file, then we are in an inconsistent 103b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // situation where the content cache referenced a file which no longer 104b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // exists. Most likely, we were using a stat cache with an invalid entry but 105b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // the file could also have been removed during processing. Since we can't 106b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // really deal with this situation, just create an empty buffer. 107b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // 108b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // FIXME: This is definitely not ideal, but our immediate clients can't 109b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // currently handle returning a null entry here. Ideally we should detect 110b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // that we are in an inconsistent situation and error out as quickly as 111b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // possible. 112b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (!Buffer.getPointer()) { 1135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner const StringRef FillStr("<<<MISSING SOURCE FILE>>>\n"); 114b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Buffer.setPointer(MemoryBuffer::getNewMemBuffer(ContentsEntry->getSize(), 115b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner "<invalid>")); 116b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart()); 117b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis for (unsigned i = 0, e = ContentsEntry->getSize(); i != e; ++i) 118b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Ptr[i] = FillStr[i % FillStr.size()]; 1190b3c773bdc4f5d5f3aaf882b2f7a5f14df6041e0Daniel Dunbar 120b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Diag.isDiagnosticInFlight()) 121b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, 122b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis ContentsEntry->getName(), ErrorStr); 123b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner else 124b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.Report(Loc, diag::err_cannot_open_file) 125b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << ContentsEntry->getName() << ErrorStr; 12693ea5cb0edf8e509c5113e70cb05ee247c9bdf6bDouglas Gregor 127b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Buffer.setInt(Buffer.getInt() | InvalidFlag); 12838caec48bc1c9816ca59b8d164a64447ee208c2eChris Lattner 129b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Invalid) *Invalid = true; 130b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner return Buffer.getPointer(); 131b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner } 132b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner 133b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // Check that the file's size is the same as in the file entry (which may 134b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // have come from a stat cache). 135b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (getRawBuffer()->getBufferSize() != (size_t)ContentsEntry->getSize()) { 136b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Diag.isDiagnosticInFlight()) 137b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.SetDelayedDiagnostic(diag::err_file_modified, 138b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis ContentsEntry->getName()); 139b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner else 140b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.Report(Loc, diag::err_file_modified) 141b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis << ContentsEntry->getName(); 142b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner 143b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Buffer.setInt(Buffer.getInt() | InvalidFlag); 144b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner if (Invalid) *Invalid = true; 145b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner return Buffer.getPointer(); 146b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner } 147156119df1d076b63609618976281961283f871dbEric Christopher 148b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // If the buffer is valid, check to see if it has a UTF Byte Order Mark 149156119df1d076b63609618976281961283f871dbEric Christopher // (BOM). We only support UTF-8 with and without a BOM right now. See 150b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner // http://en.wikipedia.org/wiki/Byte_order_mark for more information. 1515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef BufStr = Buffer.getPointer()->getBuffer(); 152156119df1d076b63609618976281961283f871dbEric Christopher const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr) 153b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xFE\xFF", "UTF-16 (BE)") 154b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xFF\xFE", "UTF-16 (LE)") 155b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\x00\x00\xFE\xFF", "UTF-32 (BE)") 156b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xFF\xFE\x00\x00", "UTF-32 (LE)") 157b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\x2B\x2F\x76", "UTF-7") 158b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xF7\x64\x4C", "UTF-1") 159b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC") 160b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\x0E\xFE\xFF", "SDSU") 161b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\xFB\xEE\x28", "BOCU-1") 162b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .StartsWith("\x84\x31\x95\x33", "GB-18030") 163b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner .Default(0); 1645807d9cce3f0ab4366bed9470355433c7b562c8dBenjamin Kramer 165156119df1d076b63609618976281961283f871dbEric Christopher if (InvalidBOM) { 166b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Diag.Report(Loc, diag::err_unsupported_bom) 167156119df1d076b63609618976281961283f871dbEric Christopher << InvalidBOM << ContentsEntry->getName(); 168b088cd3138b1fdb286c51e982ddda1e8af9d7e86Chris Lattner Buffer.setInt(Buffer.getInt() | InvalidFlag); 1695b034ad3ec0aa1ad6bcb3624390f030038670705Ted Kremenek } 170aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 171c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor if (Invalid) 172f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor *Invalid = isBufferInvalid(); 173c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor 174c815108d08b0417c6f1104e7df70dc5278839406Douglas Gregor return Buffer.getPointer(); 175c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek} 176c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek 1775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerunsigned LineTableInfo::getLineTableFilenameID(StringRef Name) { 1785b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner // Look up the filename in the string table, returning the pre-existing value 1795b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner // if it exists. 1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::StringMapEntry<unsigned> &Entry = 18165aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad FilenameIDs.GetOrCreateValue(Name, ~0U); 1825b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner if (Entry.getValue() != ~0U) 1835b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner return Entry.getValue(); 1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1855b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner // Otherwise, assign this the next available ID. 1865b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner Entry.setValue(FilenamesByID.size()); 1875b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner FilenamesByID.push_back(&Entry); 1885b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner return FilenamesByID.size()-1; 1895b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner} 1905b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 191ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner/// AddLineNote - Add a line note to the line table that indicates that there 1927285a06a0655ed93e313305182f67edb73890247James Dennett/// is a \#line at the specified FID/Offset location which changes the presumed 193ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner/// location to LineNo/FilenameID. 19447d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregorvoid LineTableInfo::AddLineNote(FileID FID, unsigned Offset, 195ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner unsigned LineNo, int FilenameID) { 19623b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner std::vector<LineEntry> &Entries = LineEntries[FID]; 1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19823b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner assert((Entries.empty() || Entries.back().FileOffset < Offset) && 19923b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner "Adding line entries out of order!"); 2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2019d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner SrcMgr::CharacteristicKind Kind = SrcMgr::C_User; 202137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner unsigned IncludeOffset = 0; 2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2049d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (!Entries.empty()) { 2059d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember 2069d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // that we are still in "foo.h". 2079d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (FilenameID == -1) 2089d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner FilenameID = Entries.back().FilenameID; 2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 210137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner // If we are after a line marker that switched us to system header mode, or 211137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner // that set #include information, preserve it. 2129d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner Kind = Entries.back().FileKind; 213137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = Entries.back().IncludeOffset; 2149d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner } 2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 216137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind, 217137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset)); 2189d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner} 2199d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner 2209d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// AddLineNote This is the same as the previous version of AddLineNote, but is 2219d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// used for GNU line markers. If EntryExit is 0, then this doesn't change the 2229d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// presumed #include stack. If it is 1, this is a file entry, if it is 2 then 2239d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// this is a file exit. FileKind specifies whether this is a system header or 2249d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// extern C system header. 22547d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregorvoid LineTableInfo::AddLineNote(FileID FID, unsigned Offset, 2269d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner unsigned LineNo, int FilenameID, 2279d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner unsigned EntryExit, 2289d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner SrcMgr::CharacteristicKind FileKind) { 2299d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner assert(FilenameID != -1 && "Unspecified filename should use other accessor"); 2301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2319d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner std::vector<LineEntry> &Entries = LineEntries[FID]; 2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2339d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner assert((Entries.empty() || Entries.back().FileOffset < Offset) && 2349d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner "Adding line entries out of order!"); 2359d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner 236137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner unsigned IncludeOffset = 0; 237137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner if (EntryExit == 0) { // No #include stack change. 238137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset; 239137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner } else if (EntryExit == 1) { 240137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = Offset-1; 241137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner } else if (EntryExit == 2) { 242137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner assert(!Entries.empty() && Entries.back().IncludeOffset && 243137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner "PPDirectives should have caught case when popping empty include stack"); 2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 245137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner // Get the include loc of the last entries' include loc as our include loc. 246137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = 0; 247137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner if (const LineEntry *PrevEntry = 248137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner FindNearestLineEntry(FID, Entries.back().IncludeOffset)) 249137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset = PrevEntry->IncludeOffset; 250137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner } 2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 252137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind, 253137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeOffset)); 254ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner} 255ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 2569d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner 2573cd949c27c63f544a081b9a750740064ddef181bChris Lattner/// FindNearestLineEntry - Find the line entry nearest to FID that is before 2583cd949c27c63f544a081b9a750740064ddef181bChris Lattner/// it. If there is no line entry before Offset in FID, return null. 25947d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregorconst LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID, 2603cd949c27c63f544a081b9a750740064ddef181bChris Lattner unsigned Offset) { 2613cd949c27c63f544a081b9a750740064ddef181bChris Lattner const std::vector<LineEntry> &Entries = LineEntries[FID]; 2623cd949c27c63f544a081b9a750740064ddef181bChris Lattner assert(!Entries.empty() && "No #line entries for this FID after all!"); 2633cd949c27c63f544a081b9a750740064ddef181bChris Lattner 2646c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner // It is very common for the query to be after the last #line, check this 2656c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner // first. 2666c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner if (Entries.back().FileOffset <= Offset) 2676c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner return &Entries.back(); 2683cd949c27c63f544a081b9a750740064ddef181bChris Lattner 2696c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner // Do a binary search to find the maximal element that is still before Offset. 2706c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner std::vector<LineEntry>::const_iterator I = 2716c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner std::upper_bound(Entries.begin(), Entries.end(), Offset); 2726c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner if (I == Entries.begin()) return 0; 2736c1fbe05efa93ebabae7150c915624efd8f3f715Chris Lattner return &*--I; 2743cd949c27c63f544a081b9a750740064ddef181bChris Lattner} 275ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 276bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor/// \brief Add a new line entry that has already been encoded into 277bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor/// the internal representation of the line table. 27847d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregorvoid LineTableInfo::AddEntry(FileID FID, 279bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor const std::vector<LineEntry> &Entries) { 280bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor LineEntries[FID] = Entries; 281bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor} 282ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 2835b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner/// getLineTableFilenameID - Return the uniqued ID for the specified filename. 2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 2855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerunsigned SourceManager::getLineTableFilenameID(StringRef Name) { 2865b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner if (LineTable == 0) 2875b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LineTable = new LineTableInfo(); 28865aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad return LineTable->getLineTableFilenameID(Name); 2895b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner} 2905b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 2915b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 2924c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner/// AddLineNote - Add a line note to the line table for the FileID and offset 2934c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner/// specified by Loc. If FilenameID is -1, it is considered to be 2944c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner/// unspecified. 2954c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattnervoid SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, 2964c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner int FilenameID) { 297e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 299e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 300e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); 301e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!Entry.isFile() || Invalid) 302e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return; 303e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 304e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::FileInfo &FileInfo = Entry.getFile(); 305ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner 306ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner // Remember that this file has #line directives now if it doesn't already. 307ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives(); 3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 309ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner if (LineTable == 0) 310ac50e3427cb9eb3dc9f13f29a78f00ef3122433dChris Lattner LineTable = new LineTableInfo(); 31147d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregor LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID); 3124c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner} 3134c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner 3149d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner/// AddLineNote - Add a GNU line marker to the line table. 3159d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattnervoid SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, 3169d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner int FilenameID, bool IsFileEntry, 3179d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner bool IsFileExit, bool IsSystemHeader, 3189d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner bool IsExternCHeader) { 3199d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // If there is no filename and no flags, this is treated just like a #line, 3209d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // which does not change the flags of the previous line marker. 3219d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (FilenameID == -1) { 3229d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader && 3239d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner "Can't set flags without setting the filename!"); 3249d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner return AddLineNote(Loc, LineNo, FilenameID); 3259d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner } 3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 327e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 328e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 329e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 330e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); 331e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!Entry.isFile() || Invalid) 332e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return; 333e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 334e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::FileInfo &FileInfo = Entry.getFile(); 3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3369d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner // Remember that this file has #line directives now if it doesn't already. 3379d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives(); 3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3399d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (LineTable == 0) 3409d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner LineTable = new LineTableInfo(); 3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3429d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner SrcMgr::CharacteristicKind FileKind; 3439d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (IsExternCHeader) 3449d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner FileKind = SrcMgr::C_ExternCSystem; 3459d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner else if (IsSystemHeader) 3469d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner FileKind = SrcMgr::C_System; 3479d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner else 3489d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner FileKind = SrcMgr::C_User; 3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3509d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner unsigned EntryExit = 0; 3519d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner if (IsFileEntry) 3529d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner EntryExit = 1; 3539d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner else if (IsFileExit) 3549d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner EntryExit = 2; 3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 35647d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregor LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID, 3579d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner EntryExit, FileKind); 3589d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner} 3599d79ebac47ffde6a1cb312f4c09b66b1b9a397fbChris Lattner 360bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas GregorLineTableInfo &SourceManager::getLineTable() { 361bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor if (LineTable == 0) 362bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor LineTable = new LineTableInfo(); 363bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor return *LineTable; 364bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor} 3654c4ea17d7f991516c37a871dfa4bbe5723fa85f0Chris Lattner 36623b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 367de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// Private 'Create' methods. 36823b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 369c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek 370d6471f7c1921c7802804ce3ff6fe9768310f72b9David BlaikieSourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr) 371299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true), 37233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), 373a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis NumBinaryProbes(0), FakeBufferForRecovery(0), 374a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis FakeContentCacheForRecovery(0) { 37533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis clearIDTables(); 37633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis Diag.setSourceManager(this); 37733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis} 37833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis 3795b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris LattnerSourceManager::~SourceManager() { 3805b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner delete LineTable; 3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3820d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner // Delete FileEntry objects corresponding to content caches. Since the actual 3830d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner // content cache objects are bump pointer allocated, we just have to run the 3840d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner // dtors, but we call the deallocate method for completeness. 3850d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) { 38699ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis if (MemBufferInfos[i]) { 38799ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis MemBufferInfos[i]->~ContentCache(); 38899ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis ContentCacheAlloc.Deallocate(MemBufferInfos[i]); 38999ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis } 3900d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner } 3910d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator 3920d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) { 39399ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis if (I->second) { 39499ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis I->second->~ContentCache(); 39599ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis ContentCacheAlloc.Deallocate(I->second); 39699ee0851015f0d334fa319c4ab9e14869520ebe5Argyrios Kyrtzidis } 3970d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner } 398e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 399e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor delete FakeBufferForRecovery; 400a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis delete FakeContentCacheForRecovery; 401fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis 402fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis for (llvm::DenseMap<FileID, MacroArgsMap *>::iterator 403fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis I = MacroArgsCacheMap.begin(),E = MacroArgsCacheMap.end(); I!=E; ++I) { 404fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis delete I->second; 405fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis } 4065b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner} 4075b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 4085b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattnervoid SourceManager::clearIDTables() { 4095b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner MainFileID = FileID(); 410d73ef135ba029db59c0b5649e6117845d9e39600Jordan Rose PredefinesFileID = FileID(); 411f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocalSLocEntryTable.clear(); 412f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LoadedSLocEntryTable.clear(); 413f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocEntryLoaded.clear(); 4145b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LastLineNoFileIDQuery = FileID(); 4155b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LastLineNoContentCache = 0; 4165b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LastFileIDLookup = FileID(); 4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4185b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner if (LineTable) 4195b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner LineTable->clear(); 4201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4213201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // Use up FileID #0 as an invalid expansion. 422f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset = 0; 423ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis CurrentLoadedOffset = MaxLoadedOffset; 424bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth createExpansionLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1); 4255b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner} 4265b9a504720fb52594ca3686e10eb6c0cfa2e7d62Chris Lattner 427de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner/// getOrCreateContentCache - Create or return a cached ContentCache for the 428de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner/// specified file. 429de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattnerconst ContentCache * 430de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris LattnerSourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { 4315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(FileEnt && "Didn't specify a file entry to use?"); 4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Do we already have information about this file? 4340d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner ContentCache *&Entry = FileInfos[FileEnt]; 4350d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner if (Entry) return Entry; 4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 43700282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // Nope, create a new Cache entry. Make sure it is at least 8-byte aligned 43800282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // so that FileInfo can use the low 3 bits of the pointer for its own 43900282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // nefarious purposes. 44000282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment; 44100282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner EntryAlign = std::max(8U, EntryAlign); 44200282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign); 443b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 444d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (OverriddenFilesInfo) { 445d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis // If the file contents are overridden with contents from another file, 446d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis // pass that file to ContentCache. 447d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator 448d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt); 449d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (overI == OverriddenFilesInfo->OverriddenFiles.end()) 450d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis new (Entry) ContentCache(FileEnt); 451d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis else 452d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt 453d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis : overI->second, 454d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis overI->second); 455d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis } else { 456b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis new (Entry) ContentCache(FileEnt); 457d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis } 458b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 4590d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner return Entry; 4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 463d1c0eee9aa30926839184b657b9e21be4a2ebdb8Ted Kremenek/// createMemBufferContentCache - Create a new ContentCache for the specified 464d1c0eee9aa30926839184b657b9e21be4a2ebdb8Ted Kremenek/// memory buffer. This does no caching. 46578d85f53b093867bbb0123f016956178eea7343eTed Kremenekconst ContentCache* 46678d85f53b093867bbb0123f016956178eea7343eTed KremenekSourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { 46700282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // Add a new ContentCache to the MemBufferInfos list and return it. Make sure 46800282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of 46900282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner // the pointer for its own nefarious purposes. 47000282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment; 47100282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner EntryAlign = std::max(8U, EntryAlign); 47200282d6e1194655a2e89f940bd6fa8484b52e666Chris Lattner ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign); 4730d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner new (Entry) ContentCache(); 4740d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner MemBufferInfos.push_back(Entry); 4750d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner Entry->setBuffer(Buffer); 4760d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner return Entry; 4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 479a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidisconst SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index, 480a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis bool *Invalid) const { 481a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis assert(!SLocEntryLoaded[Index]); 482a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis if (ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2))) { 483a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis if (Invalid) 484a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis *Invalid = true; 485a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis // If the file of the SLocEntry changed we could still have loaded it. 486a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis if (!SLocEntryLoaded[Index]) { 487a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis // Try to recover; create a SLocEntry so the rest of clang can handle it. 488a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis LoadedSLocEntryTable[Index] = SLocEntry::get(0, 489a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis FileInfo::get(SourceLocation(), 490a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis getFakeContentCacheForRecovery(), 491a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis SrcMgr::C_User)); 492a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis } 493a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis } 494a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis 495a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis return LoadedSLocEntryTable[Index]; 496a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis} 497a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis 498f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregorstd::pair<int, unsigned> 499f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas GregorSourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries, 500f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned TotalSize) { 501f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(ExternalSLocEntries && "Don't have an external sloc source"); 502f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries); 503f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocEntryLoaded.resize(LoadedSLocEntryTable.size()); 504f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor CurrentLoadedOffset -= TotalSize; 505f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(CurrentLoadedOffset >= NextLocalOffset && "Out of source locations"); 506f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor int ID = LoadedSLocEntryTable.size(); 507f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return std::make_pair(-ID - 1, CurrentLoadedOffset); 5082bf1eb09f06a9792fa94dff0703f2aa2c4bace2aDouglas Gregor} 5092bf1eb09f06a9792fa94dff0703f2aa2c4bace2aDouglas Gregor 510e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor/// \brief As part of recovering from missing or changed content, produce a 511e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor/// fake, non-empty buffer. 512e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregorconst llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const { 513e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!FakeBufferForRecovery) 514e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor FakeBufferForRecovery 515e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor = llvm::MemoryBuffer::getMemBuffer("<<<INVALID BUFFER>>"); 516e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 517e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return FakeBufferForRecovery; 518e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor} 5197f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 520a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis/// \brief As part of recovering from missing or changed content, produce a 521a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis/// fake content cache. 522a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidisconst SrcMgr::ContentCache * 523a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios KyrtzidisSourceManager::getFakeContentCacheForRecovery() const { 524a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis if (!FakeContentCacheForRecovery) { 525a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis FakeContentCacheForRecovery = new ContentCache(); 526a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(), 527a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis /*DoNotFree=*/true); 528a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis } 529a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis return FakeContentCacheForRecovery; 530a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis} 531a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deedArgyrios Kyrtzidis 532de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 5333201f382956ed9beee9fb31229c2835c1208889cChandler Carruth// Methods to create new FileID's and macro expansions. 534de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 5355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5363f86b789f5b98731937f90b3941104a313766953Dan Gohman/// createFileID - Create a new FileID for the specified ContentCache and 5370d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek/// include position. This works regardless of whether the ContentCache 5380d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek/// corresponds to a file or some other input source. 5392b2453a7d8fe732561795431f39ceb2b2a832d84Chris LattnerFileID SourceManager::createFileID(const ContentCache *File, 540de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation IncludePos, 5417f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor SrcMgr::CharacteristicKind FileCharacter, 542f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor int LoadedID, unsigned LoadedOffset) { 543f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LoadedID < 0) { 544f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(LoadedID != -1 && "Loading sentinel FileID"); 545f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned Index = unsigned(-LoadedID) - 2; 546f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(Index < LoadedSLocEntryTable.size() && "FileID out of range"); 547f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(!SLocEntryLoaded[Index] && "FileID already loaded"); 548f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, 549f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileInfo::get(IncludePos, File, FileCharacter)); 550f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocEntryLoaded[Index] = true; 551f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return FileID::get(LoadedID); 5527f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor } 553f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, 554f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileInfo::get(IncludePos, File, 555f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileCharacter))); 556c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek unsigned FileSize = File->getSize(); 557f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(NextLocalOffset + FileSize + 1 > NextLocalOffset && 558f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset && 559f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor "Ran out of source locations!"); 560f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // We do a +1 here because we want a SourceLocation that means "the end of the 561f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // file", e.g. for the "no newline at the end of the file" diagnostic. 562f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset += FileSize + 1; 5631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 564de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Set LastFileIDLookup to the newly created file. The next getFileID call is 565de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // almost guaranteed to be from that file. 566f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID FID = FileID::get(LocalSLocEntryTable.size()-1); 567ea703f1218971511181765c37073c03e1437c5ccArgyrios Kyrtzidis return LastFileIDLookup = FID; 5685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 570c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler CarruthSourceLocation 571bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler CarruthSourceManager::createMacroArgExpansionLoc(SourceLocation SpellingLoc, 572bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth SourceLocation ExpansionLoc, 573bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned TokLength) { 57478df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc, 57578df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth ExpansionLoc); 57678df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth return createExpansionLocImpl(Info, TokLength); 577c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth} 578c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth 579bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler CarruthSourceLocation 580bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler CarruthSourceManager::createExpansionLoc(SourceLocation SpellingLoc, 581bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth SourceLocation ExpansionLocStart, 582bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth SourceLocation ExpansionLocEnd, 583bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned TokLength, 584bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth int LoadedID, 585bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned LoadedOffset) { 58678df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth ExpansionInfo Info = ExpansionInfo::create(SpellingLoc, ExpansionLocStart, 58778df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth ExpansionLocEnd); 58878df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset); 589c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth} 590c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth 591c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler CarruthSourceLocation 59278df836808aee22c3157e1bc23bc4ec569b80568Chandler CarruthSourceManager::createExpansionLocImpl(const ExpansionInfo &Info, 593bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned TokLength, 594bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth int LoadedID, 595bf340e452339e374ea6eef78c1f0a2abdd16c5a3Chandler Carruth unsigned LoadedOffset) { 596f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LoadedID < 0) { 597f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(LoadedID != -1 && "Loading sentinel FileID"); 598f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned Index = unsigned(-LoadedID) - 2; 599f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(Index < LoadedSLocEntryTable.size() && "FileID out of range"); 600f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(!SLocEntryLoaded[Index] && "FileID already loaded"); 60178df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info); 602f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLocEntryLoaded[Index] = true; 603f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return SourceLocation::getMacroLoc(LoadedOffset); 6047f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor } 60578df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info)); 606f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(NextLocalOffset + TokLength + 1 > NextLocalOffset && 607f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset && 608f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor "Ran out of source locations!"); 609f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // See createFileID for that +1. 610f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NextLocalOffset += TokLength + 1; 611f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1)); 6125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 61436c35ba0aca641e60e5dbee8efbc620c08b9bd61Douglas Gregorconst llvm::MemoryBuffer * 61550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas GregorSourceManager::getMemoryBufferForFile(const FileEntry *File, 61650f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) { 6172968442603b029949246467253eeac8139a5b6d8Douglas Gregor const SrcMgr::ContentCache *IR = getOrCreateContentCache(File); 618aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor assert(IR && "getOrCreateContentCache() cannot return NULL"); 619e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner return IR->getBuffer(Diag, *this, SourceLocation(), Invalid); 6202968442603b029949246467253eeac8139a5b6d8Douglas Gregor} 6212968442603b029949246467253eeac8139a5b6d8Douglas Gregor 6220d06e998910934e5ef070f53f4c272e7c6b846c6Dan Gohmanvoid SourceManager::overrideFileContents(const FileEntry *SourceFile, 623f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const llvm::MemoryBuffer *Buffer, 624f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor bool DoNotFree) { 6252968442603b029949246467253eeac8139a5b6d8Douglas Gregor const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile); 6260d06e998910934e5ef070f53f4c272e7c6b846c6Dan Gohman assert(IR && "getOrCreateContentCache() cannot return NULL"); 6272968442603b029949246467253eeac8139a5b6d8Douglas Gregor 628f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree); 629a081da5e44600d02983d6562bed1b4fd61e410fdDouglas Gregor const_cast<SrcMgr::ContentCache *>(IR)->BufferOverridden = true; 630d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 631d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile); 6322968442603b029949246467253eeac8139a5b6d8Douglas Gregor} 6332968442603b029949246467253eeac8139a5b6d8Douglas Gregor 634b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidisvoid SourceManager::overrideFileContents(const FileEntry *SourceFile, 635b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *NewFile) { 636b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis assert(SourceFile->getSize() == NewFile->getSize() && 637b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis "Different sizes, use the FileManager to create a virtual file with " 638b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis "the correct size"); 639b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis assert(FileInfos.count(SourceFile) == 0 && 640b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis "This function should be called at the initialization stage, before " 641b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis "any parsing occurs."); 642d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile; 643d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis} 644d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 645d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidisvoid SourceManager::disableFileContentsOverride(const FileEntry *File) { 646d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (!isFileOverridden(File)) 647d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis return; 648d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 649d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis const SrcMgr::ContentCache *IR = getOrCreateContentCache(File); 650d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(0); 651d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis const_cast<SrcMgr::ContentCache *>(IR)->ContentsEntry = IR->OrigEntry; 652d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 653d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis assert(OverriddenFilesInfo); 654d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis OverriddenFilesInfo->OverriddenFiles.erase(File); 655d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File); 656b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis} 657b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis 6585f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { 659aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor bool MyInvalid = false; 660f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SLocEntry &SLoc = getSLocEntry(FID, &MyInvalid); 661e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!SLoc.isFile() || MyInvalid) { 6623de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor if (Invalid) 6633de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor *Invalid = true; 6643de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor return "<<<<<INVALID SOURCE LOCATION>>>>>"; 6653de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor } 6663de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor 6673de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor const llvm::MemoryBuffer *Buf 6683de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor = SLoc.getFile().getContentCache()->getBuffer(Diag, *this, SourceLocation(), 6693de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor &MyInvalid); 670f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor if (Invalid) 671aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor *Invalid = MyInvalid; 672aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor 673aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor if (MyInvalid) 6743de84241d90f3dd280126fdf2c4651667151c967Douglas Gregor return "<<<<<INVALID SOURCE LOCATION>>>>>"; 675aae58b0c3efb5fa9f97a3e4b1c1a2d31077efe5bDouglas Gregor 676f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer return Buf->getBuffer(); 677aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor} 6782b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner 67923b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 680de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// SourceLocation manipulation methods. 68123b5dc65451b1f91c0ecf337216c8ff473308cc2Chris Lattner//===----------------------------------------------------------------------===// 682de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 683f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// \brief Return the FileID for a SourceLocation. 684de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner/// 685f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// This is the cache-miss path of getFileID. Not as hot as that function, but 686f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// still very important. It is responsible for finding the entry in the 687f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// SLocEntry tables that contains the specified location. 688de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris LattnerFileID SourceManager::getFileIDSlow(unsigned SLocOffset) const { 689e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!SLocOffset) 690e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return FileID::get(0); 6911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 692f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Now it is time to search for the correct file. See where the SLocOffset 693f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // sits in the global view and consult local or loaded buffers for it. 694f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (SLocOffset < NextLocalOffset) 695f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return getFileIDLocal(SLocOffset); 696f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return getFileIDLoaded(SLocOffset); 697f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 698f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 699f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// \brief Return the FileID for a SourceLocation with a low offset. 700f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// 701f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// This function knows that the SourceLocation is in a local buffer, not a 702f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// loaded one. 703f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas GregorFileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { 704f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(SLocOffset < NextLocalOffset && "Bad function choice"); 705f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 706de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // After the first and second level caches, I see two common sorts of 7073201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // behavior: 1) a lot of searched FileID's are "near" the cached file 7083201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // location or are "near" the cached expansion location. 2) others are just 709de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // completely random and may be a very long way away. 710de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // 711de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // To handle this, we do a linear search for up to 8 steps to catch #1 quickly 712de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // then we fall back to a less cache efficient, but more scalable, binary 713de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // search to find the location. 7141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 715de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // See if this is near the file point - worst case we start scanning from the 716de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // most newly created FileID. 717de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::vector<SrcMgr::SLocEntry>::const_iterator I; 7181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 719f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LastFileIDLookup.ID < 0 || 720f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) { 721de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Neither loc prunes our search. 722f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I = LocalSLocEntryTable.end(); 723de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } else { 724de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Perhaps it is near the file point. 725f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID; 726de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 727de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 728de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Find the FileID that contains this. "I" is an iterator that points to a 729de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // FileID whose offset is known to be larger than SLocOffset. 730de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned NumProbes = 0; 731de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner while (1) { 732de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner --I; 733de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (I->getOffset() <= SLocOffset) { 734f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin())); 7357f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 7363201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // If this isn't an expansion, remember it. We have good locality across 7373201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // FileID lookups. 7381728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (!I->isExpansion()) 739de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner LastFileIDLookup = Res; 740de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner NumLinearScans += NumProbes+1; 741de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return Res; 742de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 743de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (++NumProbes == 8) 744de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner break; 745de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 7461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 747de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Convert "I" back into an index. We know that it is an entry whose index is 748de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // larger than the offset we are looking for. 749f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned GreaterIndex = I - LocalSLocEntryTable.begin(); 750de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // LessIndex - This is the lower bound of the range that we're searching. 751de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // We know that the offset corresponding to the FileID is is less than 752de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // SLocOffset. 753de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned LessIndex = 0; 754de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner NumProbes = 0; 755de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner while (1) { 756e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 757de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; 758f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset(); 759e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 760e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return FileID::get(0); 761e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 762de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner ++NumProbes; 7631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 764de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // If the offset of the midpoint is too large, chop the high side of the 765de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // range to the midpoint. 766de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (MidOffset > SLocOffset) { 767de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner GreaterIndex = MiddleIndex; 768de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner continue; 769de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 7701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 771de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // If the middle index contains the value, succeed and return. 772f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // FIXME: This could be made faster by using a function that's aware of 773f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // being in the local area. 774de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) { 775de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID Res = FileID::get(MiddleIndex); 776de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 7771728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth // If this isn't a macro expansion, remember it. We have good locality 778de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // across FileID lookups. 7791728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (!LocalSLocEntryTable[MiddleIndex].isExpansion()) 780de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner LastFileIDLookup = Res; 781de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner NumBinaryProbes += NumProbes; 782de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return Res; 783de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 7841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 785de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner // Otherwise, move the low-side up to the middle index. 786de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner LessIndex = MiddleIndex; 787de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner } 788de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner} 789de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 790f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// \brief Return the FileID for a SourceLocation with a high offset. 791f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// 792f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// This function knows that the SourceLocation is in a loaded buffer, not a 793f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// local one. 794f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas GregorFileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { 795c3b4575b77164fdf008cd4acc330884d56ca500fArgyrios Kyrtzidis // Sanity checking, otherwise a bug may lead to hanging in release build. 79682ccbe759b716f1747e03f54a4cd6eb164bb3427Argyrios Kyrtzidis if (SLocOffset < CurrentLoadedOffset) { 79782ccbe759b716f1747e03f54a4cd6eb164bb3427Argyrios Kyrtzidis assert(0 && "Invalid SLocOffset or bad function choice"); 798c3b4575b77164fdf008cd4acc330884d56ca500fArgyrios Kyrtzidis return FileID(); 79982ccbe759b716f1747e03f54a4cd6eb164bb3427Argyrios Kyrtzidis } 800c3b4575b77164fdf008cd4acc330884d56ca500fArgyrios Kyrtzidis 801f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Essentially the same as the local case, but the loaded array is sorted 802f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // in the other direction. 803f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 804f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // First do a linear scan from the last lookup position, if possible. 805f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned I; 806f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor int LastID = LastFileIDLookup.ID; 807f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset) 808f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I = 0; 809f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor else 810f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor I = (-LastID - 2) + 1; 811f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 812f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned NumProbes; 813f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) { 814f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Make sure the entry is loaded! 815f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I); 816f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (E.getOffset() <= SLocOffset) { 817f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID Res = FileID::get(-int(I) - 2); 818f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 8191728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (!E.isExpansion()) 820f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LastFileIDLookup = Res; 821f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NumLinearScans += NumProbes + 1; 822f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return Res; 823f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 824f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 825f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 826f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Linear scan failed. Do the binary search. Note the reverse sorting of the 827f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // table: GreaterIndex is the one where the offset is greater, which is 828f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // actually a lower index! 829f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned GreaterIndex = I; 830f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned LessIndex = LoadedSLocEntryTable.size(); 831f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NumProbes = 0; 832f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor while (1) { 833f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ++NumProbes; 834f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex; 835f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex); 836f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 837f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor ++NumProbes; 838f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 839f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (E.getOffset() > SLocOffset) { 840f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor GreaterIndex = MiddleIndex; 841f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor continue; 842f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 843f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 844f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) { 845f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID Res = FileID::get(-int(MiddleIndex) - 2); 8461728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (!E.isExpansion()) 847f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LastFileIDLookup = Res; 848f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor NumBinaryProbes += NumProbes; 849f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return Res; 850f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 851f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 852f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LessIndex = MiddleIndex; 853f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 854f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor} 855f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 856addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris LattnerSourceLocation SourceManager:: 857f84ef95ecec34f27fd05eb4e0392ca6bd3bd0be0Chandler CarruthgetExpansionLocSlowCase(SourceLocation Loc) const { 858addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner do { 859a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // Note: If Loc indicates an offset into a token that came from a macro 860a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // expansion (e.g. the 5th character of the token) we do not want to add 8611728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth // this offset when going to the expansion location. The expansion 862a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // location is the macro invocation, which the offset has nothing to do 863a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // with. This is unlike when we get the spelling loc, because the offset 864a5c6c5814b4c9f562247d2182eb59ccad128dbdeChris Lattner // directly correspond to the token whose spelling we're inspecting. 8651728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = getSLocEntry(getFileID(Loc)).getExpansion().getExpansionLocStart(); 866addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner } while (!Loc.isFileID()); 867addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 868addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner return Loc; 869addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner} 870addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 871addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris LattnerSourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const { 872addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner do { 873addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc); 8741728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc(); 875a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis Loc = Loc.getLocWithOffset(LocInfo.second); 876addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner } while (!Loc.isFileID()); 877addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner return Loc; 878addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner} 879addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 880796dbfb6c43336f58c026137c438e53eadc381f7Argyrios KyrtzidisSourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const { 881796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis do { 882796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis if (isMacroArgExpansion(Loc)) 883796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis Loc = getImmediateSpellingLoc(Loc); 884796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis else 885796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis Loc = getImmediateExpansionRange(Loc).first; 886796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis } while (!Loc.isFileID()); 887796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis return Loc; 888796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis} 889796dbfb6c43336f58c026137c438e53eadc381f7Argyrios Kyrtzidis 890addb797ca2b5afc1a1e82fd8d5d6eb2a592e75a9Chris Lattner 891de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattnerstd::pair<FileID, unsigned> 892e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler CarruthSourceManager::getDecomposedExpansionLocSlowCase( 8938b86ef0b71900c64c0c2cfca54cac08a203a16a4Argyrios Kyrtzidis const SrcMgr::SLocEntry *E) const { 8943201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // If this is an expansion record, walk through all the expansion points. 895de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FileID FID; 896de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner SourceLocation Loc; 8978b86ef0b71900c64c0c2cfca54cac08a203a16a4Argyrios Kyrtzidis unsigned Offset; 898de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner do { 8991728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = E->getExpansion().getExpansionLocStart(); 9001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 901de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner FID = getFileID(Loc); 902de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner E = &getSLocEntry(FID); 9038b86ef0b71900c64c0c2cfca54cac08a203a16a4Argyrios Kyrtzidis Offset = Loc.getOffset()-E->getOffset(); 904bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner } while (!Loc.isFileID()); 9051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 906de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return std::make_pair(FID, Offset); 907de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner} 908de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 909de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattnerstd::pair<FileID, unsigned> 910de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris LattnerSourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, 911de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner unsigned Offset) const { 9123201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // If this is an expansion record, walk through all the expansion points. 913bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner FileID FID; 914bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner SourceLocation Loc; 915bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner do { 9161728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = E->getExpansion().getSpellingLoc(); 917a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis Loc = Loc.getLocWithOffset(Offset); 9181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 919bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner FID = getFileID(Loc); 920bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner E = &getSLocEntry(FID); 921b6c465e17ec37390667223a18a340e8652c212ffArgyrios Kyrtzidis Offset = Loc.getOffset()-E->getOffset(); 922bcd1a1b5af0b2d57b20fc393a8c3b0badc58c450Chris Lattner } while (!Loc.isFileID()); 9231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 924de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner return std::make_pair(FID, Offset); 925de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner} 926de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 927387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner/// getImmediateSpellingLoc - Given a SourceLocation object, return the 928387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner/// spelling location referenced by the ID. This is the first level down 929387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner/// towards the place where the characters that make up the lexed token can be 930387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner/// found. This should not generally be used by clients. 931387616edf98739f4a0dd234c907e2b913e6a535dChris LattnerSourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{ 932387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner if (Loc.isFileID()) return Loc; 933387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc); 9341728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc(); 935a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return Loc.getLocWithOffset(LocInfo.second); 936387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner} 937387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner 938387616edf98739f4a0dd234c907e2b913e6a535dChris Lattner 9393201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// getImmediateExpansionRange - Loc is required to be an expansion location. 9403201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// Return the start/end of the expansion information. 941e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattnerstd::pair<SourceLocation,SourceLocation> 942999f739404edf2078cf9f9c28b4dc45c19765842Chandler CarruthSourceManager::getImmediateExpansionRange(SourceLocation Loc) const { 9433201f382956ed9beee9fb31229c2835c1208889cChandler Carruth assert(Loc.isMacroID() && "Not a macro expansion loc!"); 9441728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth const ExpansionInfo &Expansion = getSLocEntry(getFileID(Loc)).getExpansion(); 94578df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth return Expansion.getExpansionLocRange(); 946e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner} 947e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner 948edc3dccece244a584f8ebdb81da6c962c08e79beChandler Carruth/// getExpansionRange - Given a SourceLocation object, return the range of 949edc3dccece244a584f8ebdb81da6c962c08e79beChandler Carruth/// tokens covered by the expansion in the ultimate file. 9506678133b8ce642f93e5141f056fa643112041ad0Chris Lattnerstd::pair<SourceLocation,SourceLocation> 951edc3dccece244a584f8ebdb81da6c962c08e79beChandler CarruthSourceManager::getExpansionRange(SourceLocation Loc) const { 9526678133b8ce642f93e5141f056fa643112041ad0Chris Lattner if (Loc.isFileID()) return std::make_pair(Loc, Loc); 9531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9546678133b8ce642f93e5141f056fa643112041ad0Chris Lattner std::pair<SourceLocation,SourceLocation> Res = 955999f739404edf2078cf9f9c28b4dc45c19765842Chandler Carruth getImmediateExpansionRange(Loc); 9561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9573201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // Fully resolve the start and end locations to their ultimate expansion 9586678133b8ce642f93e5141f056fa643112041ad0Chris Lattner // points. 9596678133b8ce642f93e5141f056fa643112041ad0Chris Lattner while (!Res.first.isFileID()) 960999f739404edf2078cf9f9c28b4dc45c19765842Chandler Carruth Res.first = getImmediateExpansionRange(Res.first).first; 9616678133b8ce642f93e5141f056fa643112041ad0Chris Lattner while (!Res.second.isFileID()) 962999f739404edf2078cf9f9c28b4dc45c19765842Chandler Carruth Res.second = getImmediateExpansionRange(Res.second).second; 9636678133b8ce642f93e5141f056fa643112041ad0Chris Lattner return Res; 9646678133b8ce642f93e5141f056fa643112041ad0Chris Lattner} 9656678133b8ce642f93e5141f056fa643112041ad0Chris Lattner 96696d3589e523a04f4ff2058a7919226ce60696ae8Chandler Carruthbool SourceManager::isMacroArgExpansion(SourceLocation Loc) const { 967c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth if (!Loc.isMacroID()) return false; 968c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth 969c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth FileID FID = getFileID(Loc); 970c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth const SrcMgr::SLocEntry *E = &getSLocEntry(FID); 9711728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth const SrcMgr::ExpansionInfo &Expansion = E->getExpansion(); 97278df836808aee22c3157e1bc23bc4ec569b80568Chandler Carruth return Expansion.isMacroArgExpansion(); 973c8d1ecca1cd3fadbd331d15c420755aa6184554bChandler Carruth} 974e7fb48466afcbf2c4ccdfa658824282fdc3c512cChris Lattner 975de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 976de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 977de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// Queries about the code at a SourceLocation. 978de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 9795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 9805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getCharacterData - Return a pointer to the start of the specified location 9815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// in the appropriate MemoryBuffer. 98250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorconst char *SourceManager::getCharacterData(SourceLocation SL, 98350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 9845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Note that this is a hot function in the getSpelling() path, which is 9855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // heavily used by -E mode. 986de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL); 9871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 988c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek // Note that calling 'getBuffer()' may lazily page in a source file. 98950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool CharDataInvalid = false; 990e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(LocInfo.first, &CharDataInvalid); 991e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (CharDataInvalid || !Entry.isFile()) { 992e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 993e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor *Invalid = true; 994e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 995e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return "<<<<INVALID BUFFER>>>>"; 996e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor } 99750f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor const llvm::MemoryBuffer *Buffer 998e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor = Entry.getFile().getContentCache() 999e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor ->getBuffer(Diag, *this, SourceLocation(), &CharDataInvalid); 100050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Invalid) 100150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor *Invalid = CharDataInvalid; 100250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second); 10035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 10045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10069dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner/// getColumnNumber - Return the column # for the specified file position. 10077da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner/// this is significantly cheaper to compute than the line number. 100850f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorunsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, 100950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 101050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool MyInvalid = false; 1011d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis const llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid); 101250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Invalid) 101350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor *Invalid = MyInvalid; 101450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor 101550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (MyInvalid) 101650f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return 1; 10171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1018098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith if (FilePos >= MemBuf->getBufferSize()) { 1019d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis if (Invalid) 1020d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis *Invalid = MyInvalid; 1021d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis return 1; 1022d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis } 1023d575254dcd061ad9e6661598f4443d85a7bd1d8bArgyrios Kyrtzidis 1024098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith const char *Buf = MemBuf->getBufferStart(); 10255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned LineStart = FilePos; 10265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r') 10275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer --LineStart; 10285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FilePos-LineStart+1; 10295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 10305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10311f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan// isInvalid - Return the result of calling loc.isInvalid(), and 10321f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan// if Invalid is not null, set its value to same. 10331f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wanstatic bool isInvalid(SourceLocation Loc, bool *Invalid) { 10341f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan bool MyInvalid = Loc.isInvalid(); 10351f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (Invalid) 10361f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan *Invalid = MyInvalid; 10371f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan return MyInvalid; 10381f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan} 10391f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan 104050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorunsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc, 104150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 10421f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return 0; 10437da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc); 104450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return getColumnNumber(LocInfo.first, LocInfo.second, Invalid); 10457da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner} 10467da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner 1047a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruthunsigned SourceManager::getExpansionColumnNumber(SourceLocation Loc, 1048a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth bool *Invalid) const { 10491f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return 0; 1050e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 105150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return getColumnNumber(LocInfo.first, LocInfo.second, Invalid); 10527da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner} 10537da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner 10545ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruthunsigned SourceManager::getPresumedColumnNumber(SourceLocation Loc, 10555ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth bool *Invalid) const { 10565ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth if (isInvalid(Loc, Invalid)) return 0; 10575ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth return getPresumedLoc(Loc).getColumn(); 10585ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth} 10595ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth 1060d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#ifdef __SSE2__ 1061d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#include <emmintrin.h> 1062d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#endif 1063d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 106414bd96571ef6f0e97dc79ec4d01b547d60e8fa68Chandler Carruthstatic LLVM_ATTRIBUTE_NOINLINE void 1065d6471f7c1921c7802804ce3ff6fe9768310f72b9David BlaikieComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, 1066e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner llvm::BumpPtrAllocator &Alloc, 1067e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner const SourceManager &SM, bool &Invalid); 1068d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikiestatic void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, 1069e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner llvm::BumpPtrAllocator &Alloc, 1070e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner const SourceManager &SM, bool &Invalid) { 1071c16c208e8519476d838ad11fffc8e0ecea50550dTed Kremenek // Note that calling 'getBuffer()' may lazily page in the file. 1072e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner const MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(), 1073e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner &Invalid); 107450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Invalid) 107550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return; 10761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10775e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Find the file offsets of all of the *physical* source lines. This does 10785e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // not look at trigraphs, escaped newlines, or anything else tricky. 10795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 256> LineOffsets; 10801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10815e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Line #1 starts at char 0. 10825e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner LineOffsets.push_back(0); 10831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10845e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart(); 10855e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd(); 10865e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner unsigned Offs = 0; 10875e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner while (1) { 10885e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Skip over the contents of the line. 10895e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner const unsigned char *NextBuf = (const unsigned char *)Buf; 1090d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1091d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#ifdef __SSE2__ 1092d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // Try to skip to the next newline using SSE instructions. This is very 1093d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // performance sensitive for programs with lots of diagnostics and in -E 1094d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // mode. 1095d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer __m128i CRs = _mm_set1_epi8('\r'); 1096d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer __m128i LFs = _mm_set1_epi8('\n'); 1097d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1098d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // First fix up the alignment to 16 bytes. 1099d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer while (((uintptr_t)NextBuf & 0xF) != 0) { 1100d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer if (*NextBuf == '\n' || *NextBuf == '\r' || *NextBuf == '\0') 1101d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer goto FoundSpecialChar; 1102d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer ++NextBuf; 1103d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer } 1104d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1105d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // Scan 16 byte chunks for '\r' and '\n'. Ignore '\0'. 1106d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer while (NextBuf+16 <= End) { 1107d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer __m128i Chunk = *(__m128i*)NextBuf; 1108d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer __m128i Cmp = _mm_or_si128(_mm_cmpeq_epi8(Chunk, CRs), 1109d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer _mm_cmpeq_epi8(Chunk, LFs)); 1110d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer unsigned Mask = _mm_movemask_epi8(Cmp); 1111d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1112d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer // If we found a newline, adjust the pointer and jump to the handling code. 1113d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer if (Mask != 0) { 1114d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer NextBuf += llvm::CountTrailingZeros_32(Mask); 1115d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer goto FoundSpecialChar; 1116d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer } 1117d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer NextBuf += 16; 1118d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer } 1119d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#endif 1120d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 11215e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0') 11225e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner ++NextBuf; 1123d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer 1124d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#ifdef __SSE2__ 1125d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin KramerFoundSpecialChar: 1126d2953ce57a4f1b0a6884b3d6b35266ab4f79fa7fBenjamin Kramer#endif 11275e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner Offs += NextBuf-Buf; 11285e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner Buf = NextBuf; 11291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11305e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (Buf[0] == '\n' || Buf[0] == '\r') { 11315e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // If this is \n\r or \r\n, skip both characters. 11325e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1]) 11335e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner ++Offs, ++Buf; 11345e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner ++Offs, ++Buf; 11355e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner LineOffsets.push_back(Offs); 11365e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } else { 11375e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Otherwise, this is a null. If end of file, exit. 11385e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (Buf == End) break; 11395e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Otherwise, skip the null. 11405e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner ++Offs, ++Buf; 11415e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 11425e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 11431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11445e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // Copy the offsets into the FileInfo structure. 11455e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner FI->NumLines = LineOffsets.size(); 11460d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner FI->SourceLineCache = Alloc.Allocate<unsigned>(LineOffsets.size()); 11475e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache); 11485e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner} 11495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1150df7c17a8d02fe09a3466786bae3e40fc3252687aChris Lattner/// getLineNumber - Given a SourceLocation, return the spelling line number 11515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for the position indicated. This requires building and caching a table of 11525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// line offsets for the MemoryBuffer, so this is not cheap: use only when 11535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// about to emit a diagnostic. 115450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorunsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, 115550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 11565adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis if (FID.isInvalid()) { 11575adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis if (Invalid) 11585adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis *Invalid = true; 11595adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis return 1; 11605adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis } 11615adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis 1162de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner ContentCache *Content; 116330fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner if (LastLineNoFileIDQuery == FID) 116478d85f53b093867bbb0123f016956178eea7343eTed Kremenek Content = LastLineNoContentCache; 1165e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor else { 1166e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool MyInvalid = false; 1167e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); 1168e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (MyInvalid || !Entry.isFile()) { 1169e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1170e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor *Invalid = true; 1171e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return 1; 1172e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor } 1173e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1174e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor Content = const_cast<ContentCache*>(Entry.getFile().getContentCache()); 1175e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor } 1176e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 11775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is the first use of line information for this buffer, compute the 11785e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner /// SourceLineCache for it on demand. 117950f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Content->SourceLineCache == 0) { 118050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool MyInvalid = false; 1181e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid); 118250f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (Invalid) 118350f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor *Invalid = MyInvalid; 118450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor if (MyInvalid) 118550f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return 1; 118650f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor } else if (Invalid) 118750f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor *Invalid = false; 11885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 11895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Okay, we know we have a line number table. Do a binary search to find the 11905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // line number that this character position lands on. 119178d85f53b093867bbb0123f016956178eea7343eTed Kremenek unsigned *SourceLineCache = Content->SourceLineCache; 11925e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner unsigned *SourceLineCacheStart = SourceLineCache; 119378d85f53b093867bbb0123f016956178eea7343eTed Kremenek unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines; 11941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 119530fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner unsigned QueriedFilePos = FilePos+1; 11965e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner 11974106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // FIXME: I would like to be convinced that this code is worth being as 11981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // complicated as it is, binary search isn't that slow. 11994106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // 12004106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // If it is worth being optimized, then in my opinion it could be more 12014106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // performant, simpler, and more obviously correct by just "galloping" outward 12024106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // from the queried file position. In fact, this could be incorporated into a 12034106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // generic algorithm such as lower_bound_with_hint. 12044106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // 12054106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // If someone gives me a test case where this matters, and I will do it! - DWD 12064106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar 12075e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // If the previous query was to the same file, we know both the file pos from 12085e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // that query and the line number returned. This allows us to narrow the 12095e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // search space from the entire file to something near the match. 121030fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner if (LastLineNoFileIDQuery == FID) { 12115e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (QueriedFilePos >= LastLineNoFilePos) { 12124106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar // FIXME: Potential overflow? 12135e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner SourceLineCache = SourceLineCache+LastLineNoResult-1; 12141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12155e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // The query is likely to be nearby the previous one. Here we check to 12165e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // see if it is within 5, 10 or 20 lines. It can be far away in cases 12175e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // where big comment blocks and vertical whitespace eat up lines but 12185e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner // contribute no tokens. 12195e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (SourceLineCache+5 < SourceLineCacheEnd) { 12205e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (SourceLineCache[5] > QueriedFilePos) 12215e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner SourceLineCacheEnd = SourceLineCache+5; 12225e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner else if (SourceLineCache+10 < SourceLineCacheEnd) { 12235e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (SourceLineCache[10] > QueriedFilePos) 12245e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner SourceLineCacheEnd = SourceLineCache+10; 12255e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner else if (SourceLineCache+20 < SourceLineCacheEnd) { 12265e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner if (SourceLineCache[20] > QueriedFilePos) 12275e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner SourceLineCacheEnd = SourceLineCache+20; 12285e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12295e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12305e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12315e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } else { 12324106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar if (LastLineNoResult < Content->NumLines) 12334106d696d7d0725fcd442fdda28a07049d47c573Daniel Dunbar SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1; 12345e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12355e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner } 12361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12371cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // If the spread is large, do a "radix" test as our initial guess, based on 12381cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // the assumption that lines average to approximately the same length. 12391cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // NOTE: This is currently disabled, as it does not appear to be profitable in 12401cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // initial measurements. 12411cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner if (0 && SourceLineCacheEnd-SourceLineCache > 20) { 124278d85f53b093867bbb0123f016956178eea7343eTed Kremenek unsigned FileLen = Content->SourceLineCache[Content->NumLines-1]; 12431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12441cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // Take a stab at guessing where it is. 124578d85f53b093867bbb0123f016956178eea7343eTed Kremenek unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen; 12461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12471cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // Check for -10 and +10 lines. 12481cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner unsigned LowerBound = std::max(int(ApproxPos-10), 0); 12491cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner unsigned UpperBound = std::min(ApproxPos+10, FileLen); 12501cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner 12511cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // If the computed lower bound is less than the query location, move it in. 12521cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner if (SourceLineCache < SourceLineCacheStart+LowerBound && 12531cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner SourceLineCacheStart[LowerBound] < QueriedFilePos) 12541cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner SourceLineCache = SourceLineCacheStart+LowerBound; 12551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12561cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner // If the computed upper bound is greater than the query location, move it. 12571cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound && 12581cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner SourceLineCacheStart[UpperBound] >= QueriedFilePos) 12591cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner SourceLineCacheEnd = SourceLineCacheStart+UpperBound; 12601cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner } 12611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12621cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner unsigned *Pos 12631cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos); 12645e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner unsigned LineNo = Pos-SourceLineCacheStart; 12651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 126630fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner LastLineNoFileIDQuery = FID; 126778d85f53b093867bbb0123f016956178eea7343eTed Kremenek LastLineNoContentCache = Content; 12685e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner LastLineNoFilePos = QueriedFilePos; 12695e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner LastLineNoResult = LineNo; 12705e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner return LineNo; 12715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 12725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 12735ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruthunsigned SourceManager::getSpellingLineNumber(SourceLocation Loc, 12745ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth bool *Invalid) const { 12755ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth if (isInvalid(Loc, Invalid)) return 0; 12765ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc); 12775ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth return getLineNumber(LocInfo.first, LocInfo.second); 12785ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth} 1279642116259e8df6286063a17361c20e95b5017a0aChandler Carruthunsigned SourceManager::getExpansionLineNumber(SourceLocation Loc, 1280642116259e8df6286063a17361c20e95b5017a0aChandler Carruth bool *Invalid) const { 12811f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return 0; 1282e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 128330fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner return getLineNumber(LocInfo.first, LocInfo.second); 128430fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner} 12855ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruthunsigned SourceManager::getPresumedLineNumber(SourceLocation Loc, 128650f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 12871f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return 0; 12885ef04ee40c3332d31b6d1439f50d0ddb45812929Chandler Carruth return getPresumedLoc(Loc).getLine(); 128930fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner} 129030fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner 12916b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// getFileCharacteristic - return the file characteristic of the specified 12921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// source location, indicating whether this is a normal file, a system 12936b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// header, or an "implicit extern C" system header. 12946b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// 12956b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// This state can be modified with flags on GNU linemarker directives like: 12966b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// # 4 "foo.h" 3 12976b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// which changes all source locations in the current file after that to be 12986b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner/// considered to be from a system header. 12991eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpSrcMgr::CharacteristicKind 13006b3066780bda02e3117d71a18ca2f430ed1454afChris LattnerSourceManager::getFileCharacteristic(SourceLocation Loc) const { 13016b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!"); 1302e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 1303e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1304e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &SEntry = getSLocEntry(LocInfo.first, &Invalid); 1305e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid || !SEntry.isFile()) 1306e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return C_User; 1307e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1308e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::FileInfo &FI = SEntry.getFile(); 13096b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner 13106b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner // If there are no #line directives in this file, just return the whole-file 13116b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner // state. 13126b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner if (!FI.hasLineDirectives()) 13136b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner return FI.getFileCharacteristic(); 13141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13156b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner assert(LineTable && "Can't have linetable entries without a LineTable!"); 13166b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner // See if there is a #line directive before the location. 13176b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner const LineEntry *Entry = 131847d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregor LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second); 13191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13206b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner // If this is before the first line marker, use the file characteristic. 13216b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner if (!Entry) 13226b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner return FI.getFileCharacteristic(); 13236b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner 13246b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner return Entry->FileKind; 13256b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner} 13266b3066780bda02e3117d71a18ca2f430ed1454afChris Lattner 1327bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner/// Return the filename or buffer identifier of the buffer the location is in. 1328bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner/// Note that this name does not respect #line directives. Use getPresumedLoc 1329bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner/// for normal clients. 133050f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregorconst char *SourceManager::getBufferName(SourceLocation Loc, 133150f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor bool *Invalid) const { 13321f24e11769016e84ebf86ac5d97d43a7ce5dd5c1Zhanyong Wan if (isInvalid(Loc, Invalid)) return "<invalid loc>"; 13331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 133450f6af7a6d6951a63f3da7d4c5a7d3965bf73b63Douglas Gregor return getBuffer(getFileID(Loc), Invalid)->getBufferIdentifier(); 1335bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner} 1336bff5c512af8ca7ac92e974e04c06ff4f820e4ee1Chris Lattner 133730fc933e5fbbb5f0ea60c47976d435254e378536Chris Lattner 1338b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// getPresumedLoc - This method returns the "presumed" location of a 1339b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// SourceLocation specifies. A "presumed location" can be modified by #line 1340b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// or GNU line marker directives. This provides a view on the data that a 1341b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// user should see in diagnostics, for example. 1342b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner/// 13433201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// Note that a presumed location is always given as the expansion point of an 13443201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// expansion location, not at the spelling location. 1345b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris LattnerPresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { 1346b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner if (Loc.isInvalid()) return PresumedLoc(); 13471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13483201f382956ed9beee9fb31229c2835c1208889cChandler Carruth // Presumed locations are always for expansion points. 1349e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); 13501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1351e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1352e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); 1353e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid || !Entry.isFile()) 1354e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor return PresumedLoc(); 1355e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1356e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::FileInfo &FI = Entry.getFile(); 1357b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner const SrcMgr::ContentCache *C = FI.getContentCache(); 13581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13593cd949c27c63f544a081b9a750740064ddef181bChris Lattner // To get the source name, first consult the FileEntry (if one exists) 13603cd949c27c63f544a081b9a750740064ddef181bChris Lattner // before the MemBuffer as this will avoid unnecessarily paging in the 13613cd949c27c63f544a081b9a750740064ddef181bChris Lattner // MemBuffer. 1362e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner const char *Filename; 1363b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (C->OrigEntry) 1364b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis Filename = C->OrigEntry->getName(); 1365e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner else 1366e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner Filename = C->getBuffer(Diag, *this)->getBufferIdentifier(); 1367e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 1368c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second, &Invalid); 1369c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor if (Invalid) 1370c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor return PresumedLoc(); 1371c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor unsigned ColNo = getColumnNumber(LocInfo.first, LocInfo.second, &Invalid); 1372c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor if (Invalid) 1373c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor return PresumedLoc(); 1374c417fa024495c10a5e678ea36a5f8c715528bdd1Douglas Gregor 13753cd949c27c63f544a081b9a750740064ddef181bChris Lattner SourceLocation IncludeLoc = FI.getIncludeLoc(); 13761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13773cd949c27c63f544a081b9a750740064ddef181bChris Lattner // If we have #line directives in this file, update and overwrite the physical 13783cd949c27c63f544a081b9a750740064ddef181bChris Lattner // location info if appropriate. 13793cd949c27c63f544a081b9a750740064ddef181bChris Lattner if (FI.hasLineDirectives()) { 13803cd949c27c63f544a081b9a750740064ddef181bChris Lattner assert(LineTable && "Can't have linetable entries without a LineTable!"); 13813cd949c27c63f544a081b9a750740064ddef181bChris Lattner // See if there is a #line directive before this. If so, get it. 13823cd949c27c63f544a081b9a750740064ddef181bChris Lattner if (const LineEntry *Entry = 138347d9de678162202786aa5f8aa153a7c58a4cebd4Douglas Gregor LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) { 1384fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // If the LineEntry indicates a filename, use it. 13853cd949c27c63f544a081b9a750740064ddef181bChris Lattner if (Entry->FilenameID != -1) 13863cd949c27c63f544a081b9a750740064ddef181bChris Lattner Filename = LineTable->getFilename(Entry->FilenameID); 1387fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner 1388fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // Use the line number specified by the LineEntry. This line number may 1389fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // be multiple lines down from the line entry. Add the difference in 1390fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // physical line numbers from the query point and the line marker to the 1391fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner // total. 1392fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset); 1393fc391330724ad2d3f0f486dc7a0ce96e9e73c33bChris Lattner LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1); 13941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13950e0e5da00e92a9ee97b2469009355926ee8d94bfChris Lattner // Note that column numbers are not molested by line markers. 13961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1397137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner // Handle virtual #include manipulation. 1398137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner if (Entry->IncludeOffset) { 1399137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner IncludeLoc = getLocForStartOfFile(LocInfo.first); 1400a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis IncludeLoc = IncludeLoc.getLocWithOffset(Entry->IncludeOffset); 1401137b6a6149c53dbbcb8fba98e524d9ad0f3c8736Chris Lattner } 14023cd949c27c63f544a081b9a750740064ddef181bChris Lattner } 14033cd949c27c63f544a081b9a750740064ddef181bChris Lattner } 14043cd949c27c63f544a081b9a750740064ddef181bChris Lattner 14053cd949c27c63f544a081b9a750740064ddef181bChris Lattner return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc); 1406de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner} 1407de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 1408984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis/// \brief The size of the SLocEnty that \arg FID represents. 1409984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidisunsigned SourceManager::getFileIDSize(FileID FID) const { 1410984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis bool Invalid = false; 1411984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); 1412984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis if (Invalid) 1413984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis return 0; 1414984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis 1415984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis int ID = FID.ID; 1416984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis unsigned NextOffset; 1417984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis if ((ID > 0 && unsigned(ID+1) == local_sloc_entry_size())) 1418984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis NextOffset = getNextLocalOffset(); 1419984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis else if (ID+1 == -1) 1420984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis NextOffset = MaxLoadedOffset; 1421984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis else 1422984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis NextOffset = getSLocEntry(FileID::get(ID+1)).getOffset(); 1423984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis 1424984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis return NextOffset - Entry.getOffset() - 1; 1425984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis} 1426984e42ca1ff7775ce39372c314f1cb7d6862c4c7Argyrios Kyrtzidis 1427de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 1428de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner// Other miscellaneous methods. 1429de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner//===----------------------------------------------------------------------===// 1430de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 143186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor/// \brief Retrieve the inode for the given file entry, if possible. 143286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor/// 143386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor/// This routine involves a system call, and therefore should only be used 143486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor/// in non-performance-critical code. 143586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregorstatic llvm::Optional<ino_t> getActualFileInode(const FileEntry *File) { 143686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (!File) 143786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return llvm::Optional<ino_t>(); 143886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 143986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor struct stat StatBuf; 144086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (::stat(File->getName(), &StatBuf)) 144186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return llvm::Optional<ino_t>(); 144286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 144386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return StatBuf.st_ino; 144486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor} 144586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 144610b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis/// \brief Get the source location for the given file:line:col triplet. 144710b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis/// 144810b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis/// If the source file is included multiple times, the source location will 1449f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor/// be based upon an arbitrary inclusion. 1450ac836e442cbd17f33533bd0b4879258945bc1723Argyrios KyrtzidisSourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile, 1451507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Line, 1452507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Col) const { 145310b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis assert(SourceFile && "Null source file!"); 145410b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis assert(Line && Col && "Line and column should start from 1!"); 145510b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis 1456b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis FileID FirstFID = translateFile(SourceFile); 1457b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return translateLineCol(FirstFID, Line, Col); 1458b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis} 1459b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis 1460b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis/// \brief Get the FileID for the given file. 1461b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis/// 1462b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis/// If the source file is included multiple times, the FileID will be the 1463b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis/// first inclusion. 1464b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios KyrtzidisFileID SourceManager::translateFile(const FileEntry *SourceFile) const { 1465b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis assert(SourceFile && "Null source file!"); 1466b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis 14674a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor // Find the first file ID that corresponds to the given file. 14684a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor FileID FirstFID; 14694a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor 14704a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor // First, check the main file ID, since it is common to look for a 14714a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor // location in the main file. 147286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor llvm::Optional<ino_t> SourceFileInode; 14735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner llvm::Optional<StringRef> SourceFileName; 14744a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor if (!MainFileID.isInvalid()) { 1475e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1476e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid); 1477e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1478b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return FileID(); 1479e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 148086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (MainSLoc.isFile()) { 148186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor const ContentCache *MainContentCache 148286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor = MainSLoc.getFile().getContentCache(); 1483b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor if (!MainContentCache) { 1484b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor // Can't do anything 1485b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis } else if (MainContentCache->OrigEntry == SourceFile) { 148686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor FirstFID = MainFileID; 1487b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor } else { 148886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // Fall back: check whether we have the same base name and inode 148986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // as the main file. 1490b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *MainFile = MainContentCache->OrigEntry; 149186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor SourceFileName = llvm::sys::path::filename(SourceFile->getName()); 149286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) { 149386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor SourceFileInode = getActualFileInode(SourceFile); 149437c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor if (SourceFileInode) { 149537c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor if (llvm::Optional<ino_t> MainFileInode 149637c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor = getActualFileInode(MainFile)) { 149737c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor if (*SourceFileInode == *MainFileInode) { 149837c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor FirstFID = MainFileID; 149937c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor SourceFile = MainFile; 150037c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor } 150137c02bf479c86c31ad2af75adbe1ead2b928ca93Douglas Gregor } 150286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 150386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 150486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 150586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 15064a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor } 15074a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor 15084a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor if (FirstFID.isInvalid()) { 15094a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor // The location we're looking for isn't in the main file; look 1510f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // through all of the local source locations. 1511f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { 1512e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1513f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid); 1514e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1515b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return FileID(); 1516e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 151786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (SLoc.isFile() && 151886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor SLoc.getFile().getContentCache() && 1519b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis SLoc.getFile().getContentCache()->OrigEntry == SourceFile) { 15204a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor FirstFID = FileID::get(I); 15214a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor break; 15224a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor } 15234a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor } 1524f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // If that still didn't help, try the modules. 1525f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (FirstFID.isInvalid()) { 1526f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) { 1527f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SLocEntry &SLoc = getLoadedSLocEntry(I); 1528f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (SLoc.isFile() && 1529f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLoc.getFile().getContentCache() && 1530f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor SLoc.getFile().getContentCache()->OrigEntry == SourceFile) { 1531f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FirstFID = FileID::get(-int(I) - 2); 1532f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor break; 1533f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1534f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1535f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 15364a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor } 153786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 153886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // If we haven't found what we want yet, try again, but this time stat() 153986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // each of the files in case the files have changed since we originally 154086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // parsed the file. 154186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (FirstFID.isInvalid() && 154286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor (SourceFileName || 154386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor (SourceFileName = llvm::sys::path::filename(SourceFile->getName()))) && 154486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor (SourceFileInode || 154586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor (SourceFileInode = getActualFileInode(SourceFile)))) { 1546e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 1547f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { 1548f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor FileID IFileID; 1549f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor IFileID.ID = I; 1550f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SLocEntry &SLoc = getSLocEntry(IFileID, &Invalid); 1551e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (Invalid) 1552b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return FileID(); 1553e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor 155486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (SLoc.isFile()) { 155586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor const ContentCache *FileContentCache 155686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor = SLoc.getFile().getContentCache(); 1557b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis const FileEntry *Entry =FileContentCache? FileContentCache->OrigEntry : 0; 155886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (Entry && 1559b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor *SourceFileName == llvm::sys::path::filename(Entry->getName())) { 1560b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor if (llvm::Optional<ino_t> EntryInode = getActualFileInode(Entry)) { 1561b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor if (*SourceFileInode == *EntryInode) { 1562b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor FirstFID = FileID::get(I); 1563b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor SourceFile = Entry; 1564b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor break; 1565b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor } 1566b7a1841244418b658bcf64573ff0c00867fb9c5dDouglas Gregor } 156786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 156886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 156986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 157086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 1571b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis 1572b201e16e0c331b0bdeae7b30f9f79aae32beb1b2Argyrios Kyrtzidis return FirstFID; 1573efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis} 1574efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis 1575efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis/// \brief Get the source location in \arg FID for the given line:col. 1576efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis/// Returns null location if \arg FID is not a file SLocEntry. 1577efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios KyrtzidisSourceLocation SourceManager::translateLineCol(FileID FID, 1578507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Line, 1579507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis unsigned Col) const { 1580efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis if (FID.isInvalid()) 1581efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis return SourceLocation(); 1582efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis 1583efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis bool Invalid = false; 1584efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis const SLocEntry &Entry = getSLocEntry(FID, &Invalid); 1585efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis if (Invalid) 1586efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis return SourceLocation(); 1587efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis 1588efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis if (!Entry.isFile()) 15894a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor return SourceLocation(); 15904a160e16eb97bee03e36962d11aedc6452710bc5Douglas Gregor 15915e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis SourceLocation FileLoc = SourceLocation::getFileLoc(Entry.getOffset()); 15925e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis 159386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (Line == 1 && Col == 1) 15945e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc; 159586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 159686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor ContentCache *Content 1597efa2ff8603dae51f5f5ed7509a503f477498ad22Argyrios Kyrtzidis = const_cast<ContentCache *>(Entry.getFile().getContentCache()); 159886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (!Content) 159986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return SourceLocation(); 160086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 160186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor // If this is the first use of line information for this buffer, compute the 1602f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // SourceLineCache for it on demand. 160386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (Content->SourceLineCache == 0) { 160486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor bool MyInvalid = false; 160586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid); 160686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (MyInvalid) 160786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return SourceLocation(); 160886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 160986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 1610d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor if (Line > Content->NumLines) { 1611e127a0d80155b45dafe77f2b4380e5fa111a3345Chris Lattner unsigned Size = Content->getBuffer(Diag, *this)->getBufferSize(); 1612d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor if (Size > 0) 1613d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor --Size; 16145e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc.getLocWithOffset(Size); 1615d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor } 1616d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor 1617098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this); 1618d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor unsigned FilePos = Content->SourceLineCache[Line - 1]; 1619098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith const char *Buf = Buffer->getBufferStart() + FilePos; 1620098eaffc0c1784567ddccfe6f976ced6e904552eDylan Noblesmith unsigned BufLength = Buffer->getBufferSize() - FilePos; 16215e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis if (BufLength == 0) 16225e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc.getLocWithOffset(FilePos); 16235e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis 1624d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor unsigned i = 0; 1625d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor 1626d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor // Check that the given column is valid. 1627d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r') 1628d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor ++i; 1629d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor if (i < Col-1) 16305e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc.getLocWithOffset(FilePos + i); 1631d1eabfb15c87837c57d1eb658d75a1f48d6fd5edDouglas Gregor 16325e5e95dec56d8f2392068c43c84eaaad674c2702Argyrios Kyrtzidis return FileLoc.getLocWithOffset(FilePos + Col - 1); 163310b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis} 163410b46d2f0b976676d10681d73fe061b5ae409b36Argyrios Kyrtzidis 1635d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// \brief Compute a map of macro argument chunks to their expanded source 1636d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// location. Chunks that are not part of a macro argument will map to an 1637d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// invalid source location. e.g. if a file contains one macro argument at 1638d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// offset 100 with length 10, this is how the map will be formed: 1639d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// 0 -> SourceLocation() 1640d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// 100 -> Expanded macro arg location 1641d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// 110 -> SourceLocation() 1642fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidisvoid SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr, 1643507097ec40105ed927cb5a744fad98f5875aacacArgyrios Kyrtzidis FileID FID) const { 1644d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis assert(!FID.isInvalid()); 1645fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis assert(!CachePtr); 1646d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1647fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis CachePtr = new MacroArgsMap(); 1648fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis MacroArgsMap &MacroArgsCache = *CachePtr; 1649d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // Initially no macro argument chunk is present. 1650d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis MacroArgsCache.insert(std::make_pair(0, SourceLocation())); 1651ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis 1652ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis int ID = FID.ID; 1653ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis while (1) { 1654ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis ++ID; 1655ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis // Stop if there are no more FileIDs to check. 1656ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis if (ID > 0) { 1657ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis if (unsigned(ID) >= local_sloc_entry_size()) 1658d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return; 1659ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis } else if (ID == -1) { 1660d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return; 1661ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis } 1662ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis 1663ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID); 1664ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis if (Entry.isFile()) { 1665d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc(); 1666d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (IncludeLoc.isInvalid()) 1667d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis continue; 1668d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (!isInFileID(IncludeLoc, FID)) 1669d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return; // No more files/macros that may be "contained" in this file. 1670d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1671d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // Skip the files/macros of the #include'd file, we only care about macros 1672d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // that lexed macro arguments from our file. 1673d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (Entry.getFile().NumCreatedFIDs) 1674d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis ID += Entry.getFile().NumCreatedFIDs - 1/*because of next ++ID*/; 1675ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis continue; 1676ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis } 1677d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1678cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const ExpansionInfo &ExpInfo = Entry.getExpansion(); 1679cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 1680cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (ExpInfo.getExpansionLocStart().isFileID()) { 1681cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (!isInFileID(ExpInfo.getExpansionLocStart(), FID)) 1682cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis return; // No more files/macros that may be "contained" in this file. 1683cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis } 1684cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 1685cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (!ExpInfo.isMacroArgExpansion()) 1686ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis continue; 1687cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 1688cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation SpellLoc = ExpInfo.getSpellingLoc(); 1689cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis while (!SpellLoc.isFileID()) { 1690cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(SpellLoc); 1691cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const ExpansionInfo &Info = getSLocEntry(LocInfo.first).getExpansion(); 1692cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (!Info.isMacroArgExpansion()) 1693cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis break; 1694cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SpellLoc = Info.getSpellingLoc().getLocWithOffset(LocInfo.second); 1695cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis } 1696cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (!SpellLoc.isFileID()) 1697cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis continue; 1698cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 1699d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis unsigned BeginOffs; 1700d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (!isInFileID(SpellLoc, FID, &BeginOffs)) 1701cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis continue; 1702cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 170354232ade44d31e98ea83f43ca066128e315dcbdaArgyrios Kyrtzidis unsigned EndOffs = BeginOffs + getFileIDSize(FileID::get(ID)); 1704d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1705d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // Add a new chunk for this macro argument. A previous macro argument chunk 1706d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // may have been lexed again, so e.g. if the map is 1707d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 0 -> SourceLocation() 1708d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 100 -> Expanded loc #1 1709d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 110 -> SourceLocation() 1710d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // and we found a new macro FileID that lexed from offet 105 with length 3, 1711d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // the new map will be: 1712d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 0 -> SourceLocation() 1713d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 100 -> Expanded loc #1 1714d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 105 -> Expanded loc #2 1715d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 108 -> Expanded loc #1 1716d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 110 -> SourceLocation() 1717d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // 1718d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // Since re-lexed macro chunks will always be the same size or less of 1719d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // previous chunks, we only need to find where the ending of the new macro 1720d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis // chunk is mapped to and update the map with new begin/end mappings. 1721d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1722fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs); 1723d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis --I; 1724d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis SourceLocation EndOffsMappedLoc = I->second; 1725d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis MacroArgsCache[BeginOffs] = SourceLocation::getMacroLoc(Entry.getOffset()); 1726d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis MacroArgsCache[EndOffs] = EndOffsMappedLoc; 1727ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis } 1728ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis} 1729ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis 1730d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// \brief If \arg Loc points inside a function macro argument, the returned 1731d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// location will be the macro location in which the argument was expanded. 1732d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// If a macro argument is used multiple times, the expanded location will 1733d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// be at the first expansion of the argument. 1734d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// e.g. 1735d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// MY_MACRO(foo); 1736d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// ^ 1737d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// Passing a file location pointing at 'foo', will yield a macro location 1738d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis/// where 'foo' was expanded into. 1739507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceLocation 1740507097ec40105ed927cb5a744fad98f5875aacacArgyrios KyrtzidisSourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { 1741d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (Loc.isInvalid() || !Loc.isFileID()) 1742d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return Loc; 1743d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1744d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis FileID FID; 1745d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis unsigned Offset; 1746d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis llvm::tie(FID, Offset) = getDecomposedLoc(Loc); 1747d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (FID.isInvalid()) 1748d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return Loc; 1749d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1750fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis MacroArgsMap *&MacroArgsCache = MacroArgsCacheMap[FID]; 1751fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis if (!MacroArgsCache) 1752fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis computeMacroArgsCache(MacroArgsCache, FID); 1753fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis 1754fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis assert(!MacroArgsCache->empty()); 1755fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset); 1756d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis --I; 1757d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1758d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis unsigned MacroArgBeginOffs = I->first; 1759d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis SourceLocation MacroArgExpandedLoc = I->second; 1760d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis if (MacroArgExpandedLoc.isValid()) 1761a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis return MacroArgExpandedLoc.getLocWithOffset(Offset - MacroArgBeginOffs); 1762d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 1763d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis return Loc; 1764d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis} 1765d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis 17663201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// Given a decomposed source location, move it up the include/expansion stack 17673201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// to the parent source location. If this is possible, return the decomposed 17683201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// version of the parent in Loc and return false. If Loc is the top-level 17693201f382956ed9beee9fb31229c2835c1208889cChandler Carruth/// entry, return true and don't modify it. 1770d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattnerstatic bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc, 1771d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner const SourceManager &SM) { 1772d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner SourceLocation UpperLoc; 1773d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(Loc.first); 17741728762d5a8cfaf8d64385f47b311e84de1ae7a2Chandler Carruth if (Entry.isExpansion()) 1775d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis UpperLoc = Entry.getExpansion().getExpansionLocStart(); 1776d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner else 1777d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner UpperLoc = Entry.getFile().getIncludeLoc(); 1778d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner 1779d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner if (UpperLoc.isInvalid()) 1780d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner return true; // We reached the top. 1781d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner 1782d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner Loc = SM.getDecomposedLoc(UpperLoc); 1783d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner return false; 1784d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner} 1785d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner 1786d3b8cc27920a0f4eb6e832e24a602475aa9f0ff0Chris Lattner 17872aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis/// \brief Determines the order of 2 source locations in the translation unit. 17882aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis/// 17892aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis/// \returns true if LHS source location comes before RHS, false otherwise. 17902aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidisbool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, 17912aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis SourceLocation RHS) const { 17922aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis assert(LHS.isValid() && RHS.isValid() && "Passed invalid source location!"); 17932aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis if (LHS == RHS) 17942aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis return false; 17951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17962aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS); 17972aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS); 17981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17992aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis // If the source locations are in the same file, just compare offsets. 18002aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis if (LOffs.first == ROffs.first) 18012aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis return LOffs.second < ROffs.second; 18022aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis 18032aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis // If we are comparing a source location with multiple locations in the same 18042aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis // file, we get a big win by caching the result. 180566a915fbd73a0e404ed28f58e4a3f1b8d0f8fb94Chris Lattner if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first)) 180666a915fbd73a0e404ed28f58e4a3f1b8d0f8fb94Chris Lattner return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); 18071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1808dcb1d68f6ffa183f3919aee6b554aec3793bf13eChris Lattner // Okay, we missed in the cache, start updating the cache for this query. 180937e59a10a7a537428e5997fd5896f5b89fd34e6bArgyrios Kyrtzidis IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first, 181037e59a10a7a537428e5997fd5896f5b89fd34e6bArgyrios Kyrtzidis /*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID); 18111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1812f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // We need to find the common ancestor. The only way of doing this is to 1813f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // build the complete include chain for one and then walking up the chain 1814f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // of the other looking for a match. 1815f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // We use a map from FileID to Offset to store the chain. Easier than writing 1816f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // a custom set hash info that only depends on the first part of a pair. 1817f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor typedef llvm::DenseMap<FileID, unsigned> LocSet; 1818f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocSet LChain; 181948296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner do { 1820f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LChain.insert(LOffs); 1821f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // We catch the case where LOffs is in a file included by ROffs and 1822f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // quit early. The other way round unfortunately remains suboptimal. 1823f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this)); 1824f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LocSet::iterator I; 1825f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor while((I = LChain.find(ROffs.first)) == LChain.end()) { 1826f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (MoveUpIncludeHierarchy(ROffs, *this)) 1827f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor break; // Met at topmost file. 1828f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } 1829f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (I != LChain.end()) 1830f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor LOffs = *I; 18311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 183248296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner // If we exited because we found a nearest common ancestor, compare the 183348296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner // locations within the common file and cache them. 183448296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner if (LOffs.first == ROffs.first) { 183548296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second); 183648296ba924cb95e0d898fa7a1da33f23be8c731cChris Lattner return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); 18372aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis } 18381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1839f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // This can happen if a location is in a built-ins buffer. 1840f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // But see PR5662. 1841f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Clear the lookup cache, it depends on a common location. 184237e59a10a7a537428e5997fd5896f5b89fd34e6bArgyrios Kyrtzidis IsBeforeInTUCache.clear(); 1843f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor bool LIsBuiltins = strcmp("<built-in>", 1844f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getBuffer(LOffs.first)->getBufferIdentifier()) == 0; 1845f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor bool RIsBuiltins = strcmp("<built-in>", 1846f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor getBuffer(ROffs.first)->getBufferIdentifier()) == 0; 1847f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // built-in is before non-built-in 1848f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (LIsBuiltins != RIsBuiltins) 1849f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor return LIsBuiltins; 1850f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor assert(LIsBuiltins && RIsBuiltins && 1851f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor "Non-built-in locations must be rooted in the main file"); 1852f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // Both are in built-in buffers, but from different files. We just claim that 1853f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor // lower IDs come first. 1854dcb1d68f6ffa183f3919aee6b554aec3793bf13eChris Lattner return LOffs.first < ROffs.first; 18552aa03d588bd2d3c73deb662880c2244bf2e384b9Argyrios Kyrtzidis} 1856de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner 18575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// PrintStats - Print statistics to stderr. 18585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 18595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid SourceManager::PrintStats() const { 18606cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "\n*** Source Manager Stats:\n"; 18616cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size() 18626cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer << " mem buffers mapped.\n"; 1863f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntry's allocated (" 18646e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek << llvm::capacity_in_bytes(LocalSLocEntryTable) 1865d410e741e8085e109c1dc5886c0acea88a4ca0f4Argyrios Kyrtzidis << " bytes of capacity), " 1866f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor << NextLocalOffset << "B of Sloc address space used.\n"; 1867f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor llvm::errs() << LoadedSLocEntryTable.size() 1868f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor << " loaded SLocEntries allocated, " 1869ac836e442cbd17f33533bd0b4879258945bc1723Argyrios Kyrtzidis << MaxLoadedOffset - CurrentLoadedOffset 1870f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor << "B of Sloc address space used.\n"; 1871f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 18725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumLineNumsComputed = 0; 18735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumFileBytesMapped = 0; 18740d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){ 18750d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner NumLineNumsComputed += I->second->SourceLineCache != 0; 18760d0bf8cf58b35302312cc155287fde3e81eb25a7Chris Lattner NumFileBytesMapped += I->second->getSizeBytesMapped(); 18775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1878fb3612ef197cb8532c05f33889ec1aed7c26e5cbArgyrios Kyrtzidis unsigned NumMacroArgsComputed = MacroArgsCacheMap.size(); 18791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18806cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << NumFileBytesMapped << " bytes of files mapped, " 1881d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis << NumLineNumsComputed << " files with line #'s computed, " 1882d9d2b679d0728ea7f539f38aaea38e26b8b08043Argyrios Kyrtzidis << NumMacroArgsComputed << " files with macro args computed.\n"; 18836cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "FileID scans: " << NumLinearScans << " linear, " 18846cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer << NumBinaryProbes << " binary.\n"; 18855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 18867f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas Gregor 18877f94b0b0c6791013d2f72ced9b4bedd3b23673a6Douglas GregorExternalSLocEntrySource::~ExternalSLocEntrySource() { } 1888f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 1889f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek/// Return the amount of memory used by memory buffers, breaking down 1890f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek/// by heap-backed versus mmap'ed memory. 1891f61b831d7f6a15676b07647f507de80324cb7056Ted KremenekSourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const { 1892f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek size_t malloc_bytes = 0; 1893f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek size_t mmap_bytes = 0; 1894f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 1895f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) 1896f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek if (size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped()) 1897f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek switch (MemBufferInfos[i]->getMemoryBufferKind()) { 1898f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek case llvm::MemoryBuffer::MemoryBuffer_MMap: 1899f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek mmap_bytes += sized_mapped; 1900f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek break; 1901f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek case llvm::MemoryBuffer::MemoryBuffer_Malloc: 1902f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek malloc_bytes += sized_mapped; 1903f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek break; 1904f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek } 1905f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 1906f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek return MemoryBufferSizes(malloc_bytes, mmap_bytes); 1907f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek} 1908f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 1909ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremeneksize_t SourceManager::getDataStructureSizes() const { 1910d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis size_t size = llvm::capacity_in_bytes(MemBufferInfos) 19116e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek + llvm::capacity_in_bytes(LocalSLocEntryTable) 19126e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek + llvm::capacity_in_bytes(LoadedSLocEntryTable) 19136e36c12404269eb4909e85d3be69f78d36d1d297Ted Kremenek + llvm::capacity_in_bytes(SLocEntryLoaded) 1914d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis + llvm::capacity_in_bytes(FileInfos); 1915d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 1916d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis if (OverriddenFilesInfo) 1917d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles); 1918d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis 1919d54dff026b02303a35147224de72bb44cbb53c79Argyrios Kyrtzidis return size; 1920ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek} 1921