 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
72.1% |
235 / 326 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
91.4% |
298 / 326 |
| |
|
Line Coverage: |
90.4% |
442 / 489 |
| |
 |
|
 |
1 : //===--- SourceManager.cpp - Track and cache source files -----------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements the SourceManager interface.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/Basic/SourceManager.h"
15 : #include "clang/Basic/SourceManagerInternals.h"
16 : #include "clang/Basic/FileManager.h"
17 : #include "llvm/Support/Compiler.h"
18 : #include "llvm/Support/MemoryBuffer.h"
19 : #include "llvm/Support/raw_ostream.h"
20 : #include "llvm/System/Path.h"
21 : #include <algorithm>
22 : using namespace clang;
23 : using namespace SrcMgr;
24 : using llvm::MemoryBuffer;
25 :
26 : //===----------------------------------------------------------------------===//
27 : // SourceManager Helper Classes
28 : //===----------------------------------------------------------------------===//
29 :
30 5781: ContentCache::~ContentCache() {
5781: branch 0 taken
5781: branch 1 taken
5750: branch 3 taken
31: branch 4 taken
31 5781: delete Buffer;
32 5781: }
33 :
34 : /// getSizeBytesMapped - Returns the number of bytes actually mapped for
35 : /// this ContentCache. This can be 0 if the MemBuffer was not actually
36 : /// instantiated.
37 2: unsigned ContentCache::getSizeBytesMapped() const {
2: branch 0 taken
0: branch 1 not taken
38 2: return Buffer ? Buffer->getBufferSize() : 0;
39 : }
40 :
41 : /// getSize - Returns the size of the content encapsulated by this ContentCache.
42 : /// This can be the size of the source file or the size of an arbitrary
43 : /// scratch buffer. If the ContentCache encapsulates a source file, that
44 : /// file is not lazily brought in from disk to satisfy this query.
45 5761: unsigned ContentCache::getSize() const {
2837: branch 0 taken
2924: branch 1 taken
46 5761: return Buffer ? Buffer->getBufferSize() : Entry->getSize();
47 : }
48 :
49 99: void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) {
0: branch 0 not taken
99: branch 1 taken
50 99: assert(B != Buffer);
51 :
87: branch 0 taken
12: branch 1 taken
52 99: delete Buffer;
53 99: Buffer = B;
54 99: }
55 :
56 331682: const llvm::MemoryBuffer *ContentCache::getBuffer(std::string *ErrorStr) const {
57 : // Lazily create the Buffer for ContentCaches that wrap files.
2945: branch 0 taken
328737: branch 1 taken
2945: branch 2 taken
0: branch 3 not taken
58 331682: if (!Buffer && Entry) {
59 2945: Buffer = MemoryBuffer::getFile(Entry->getName(), ErrorStr,Entry->getSize());
60 :
61 : // If we were unable to open the file, then we are in an inconsistent
62 : // situation where the content cache referenced a file which no longer
63 : // exists. Most likely, we were using a stat cache with an invalid entry but
64 : // the file could also have been removed during processing. Since we can't
65 : // really deal with this situation, just create an empty buffer.
66 : //
67 : // FIXME: This is definitely not ideal, but our immediate clients can't
68 : // currently handle returning a null entry here. Ideally we should detect
69 : // that we are in an inconsistent situation and error out as quickly as
70 : // possible.
0: branch 0 not taken
2945: branch 1 taken
71 2945: if (!Buffer) {
72 0: const llvm::StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
73 0: Buffer = MemoryBuffer::getNewMemBuffer(Entry->getSize(), "<invalid>");
74 0: char *Ptr = const_cast<char*>(Buffer->getBufferStart());
0: branch 1 not taken
0: branch 2 not taken
75 0: for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
76 0: Ptr[i] = FillStr[i % FillStr.size()];
77 : }
78 : }
79 331682: return Buffer;
80 : }
81 :
82 7713: unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) {
83 : // Look up the filename in the string table, returning the pre-existing value
84 : // if it exists.
85 : llvm::StringMapEntry<unsigned> &Entry =
86 7713: FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U);
2610: branch 1 taken
5103: branch 2 taken
87 7713: if (Entry.getValue() != ~0U)
88 2610: return Entry.getValue();
89 :
90 : // Otherwise, assign this the next available ID.
91 5103: Entry.setValue(FilenamesByID.size());
92 5103: FilenamesByID.push_back(&Entry);
93 5103: return FilenamesByID.size()-1;
94 : }
95 :
96 : /// AddLineNote - Add a line note to the line table that indicates that there
97 : /// is a #line at the specified FID/Offset location which changes the presumed
98 : /// location to LineNo/FilenameID.
99 : void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
100 39: unsigned LineNo, int FilenameID) {
101 39: std::vector<LineEntry> &Entries = LineEntries[FID];
102 :
103 : assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
33: branch 1 taken
6: branch 2 taken
33: branch 4 taken
0: branch 5 not taken
104 39: "Adding line entries out of order!");
105 :
106 39: SrcMgr::CharacteristicKind Kind = SrcMgr::C_User;
107 39: unsigned IncludeOffset = 0;
108 :
33: branch 1 taken
6: branch 2 taken
109 39: if (!Entries.empty()) {
110 : // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember
111 : // that we are still in "foo.h".
15: branch 0 taken
18: branch 1 taken
112 33: if (FilenameID == -1)
113 15: FilenameID = Entries.back().FilenameID;
114 :
115 : // If we are after a line marker that switched us to system header mode, or
116 : // that set #include information, preserve it.
117 33: Kind = Entries.back().FileKind;
118 33: IncludeOffset = Entries.back().IncludeOffset;
119 : }
120 :
121 : Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind,
122 39: IncludeOffset));
123 39: }
124 :
125 : /// AddLineNote This is the same as the previous version of AddLineNote, but is
126 : /// used for GNU line markers. If EntryExit is 0, then this doesn't change the
127 : /// presumed #include stack. If it is 1, this is a file entry, if it is 2 then
128 : /// this is a file exit. FileKind specifies whether this is a system header or
129 : /// extern C system header.
130 : void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
131 : unsigned LineNo, int FilenameID,
132 : unsigned EntryExit,
133 7580: SrcMgr::CharacteristicKind FileKind) {
0: branch 0 not taken
7580: branch 1 taken
134 7580: assert(FilenameID != -1 && "Unspecified filename should use other accessor");
135 :
136 7580: std::vector<LineEntry> &Entries = LineEntries[FID];
137 :
138 : assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
5092: branch 1 taken
2488: branch 2 taken
5092: branch 4 taken
0: branch 5 not taken
139 7580: "Adding line entries out of order!");
140 :
141 7580: unsigned IncludeOffset = 0;
2559: branch 0 taken
5021: branch 1 taken
142 7580: if (EntryExit == 0) { // No #include stack change.
2484: branch 1 taken
75: branch 2 taken
143 2559: IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
2514: branch 0 taken
2507: branch 1 taken
144 5021: } else if (EntryExit == 1) {
145 2514: IncludeOffset = Offset-1;
2507: branch 0 taken
0: branch 1 not taken
146 2507: } else if (EntryExit == 2) {
147 : assert(!Entries.empty() && Entries.back().IncludeOffset &&
2507: branch 1 taken
0: branch 2 not taken
2507: branch 4 taken
0: branch 5 not taken
148 2507: "PPDirectives should have caught case when popping empty include stack");
149 :
150 : // Get the include loc of the last entries' include loc as our include loc.
151 2507: IncludeOffset = 0;
2507: branch 0 taken
0: branch 1 not taken
152 2507: if (const LineEntry *PrevEntry =
153 2507: FindNearestLineEntry(FID, Entries.back().IncludeOffset))
154 2507: IncludeOffset = PrevEntry->IncludeOffset;
155 : }
156 :
157 : Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind,
158 7580: IncludeOffset));
159 7580: }
160 :
161 :
162 : /// FindNearestLineEntry - Find the line entry nearest to FID that is before
163 : /// it. If there is no line entry before Offset in FID, return null.
164 : const LineEntry *LineTableInfo::FindNearestLineEntry(unsigned FID,
165 7146: unsigned Offset) {
166 7146: const std::vector<LineEntry> &Entries = LineEntries[FID];
7146: branch 1 taken
0: branch 2 not taken
167 7146: assert(!Entries.empty() && "No #line entries for this FID after all!");
168 :
169 : // It is very common for the query to be after the last #line, check this
170 : // first.
4613: branch 1 taken
2533: branch 2 taken
171 7146: if (Entries.back().FileOffset <= Offset)
172 4613: return &Entries.back();
173 :
174 : // Do a binary search to find the maximal element that is still before Offset.
175 : std::vector<LineEntry>::const_iterator I =
176 2533: std::upper_bound(Entries.begin(), Entries.end(), Offset);
2: branch 2 taken
2531: branch 3 taken
177 2533: if (I == Entries.begin()) return 0;
178 2531: return &*--I;
179 : }
180 :
181 : /// \brief Add a new line entry that has already been encoded into
182 : /// the internal representation of the line table.
183 : void LineTableInfo::AddEntry(unsigned FID,
184 49: const std::vector<LineEntry> &Entries) {
185 49: LineEntries[FID] = Entries;
186 49: }
187 :
188 : /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
189 : ///
190 7616: unsigned SourceManager::getLineTableFilenameID(const char *Ptr, unsigned Len) {
2480: branch 0 taken
5136: branch 1 taken
191 7616: if (LineTable == 0)
192 2480: LineTable = new LineTableInfo();
193 7616: return LineTable->getLineTableFilenameID(Ptr, Len);
194 : }
195 :
196 :
197 : /// AddLineNote - Add a line note to the line table for the FileID and offset
198 : /// specified by Loc. If FilenameID is -1, it is considered to be
199 : /// unspecified.
200 : void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
201 39: int FilenameID) {
202 39: std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
203 :
204 39: const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile();
205 :
206 : // Remember that this file has #line directives now if it doesn't already.
207 39: const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
208 :
0: branch 0 not taken
39: branch 1 taken
209 39: if (LineTable == 0)
210 0: LineTable = new LineTableInfo();
211 39: LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID);
212 39: }
213 :
214 : /// AddLineNote - Add a GNU line marker to the line table.
215 : void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
216 : int FilenameID, bool IsFileEntry,
217 : bool IsFileExit, bool IsSystemHeader,
218 7586: bool IsExternCHeader) {
219 : // If there is no filename and no flags, this is treated just like a #line,
220 : // which does not change the flags of the previous line marker.
6: branch 0 taken
7580: branch 1 taken
221 7586: if (FilenameID == -1) {
222 : assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader &&
6: branch 0 taken
0: branch 1 not taken
6: branch 2 taken
0: branch 3 not taken
6: branch 4 taken
0: branch 5 not taken
0: branch 6 not taken
6: branch 7 taken
223 6: "Can't set flags without setting the filename!");
224 6: return AddLineNote(Loc, LineNo, FilenameID);
225 : }
226 :
227 7580: std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
228 7580: const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile();
229 :
230 : // Remember that this file has #line directives now if it doesn't already.
231 7580: const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
232 :
0: branch 0 not taken
7580: branch 1 taken
233 7580: if (LineTable == 0)
234 0: LineTable = new LineTableInfo();
235 :
236 : SrcMgr::CharacteristicKind FileKind;
95: branch 0 taken
7485: branch 1 taken
237 7580: if (IsExternCHeader)
238 95: FileKind = SrcMgr::C_ExternCSystem;
2493: branch 0 taken
4992: branch 1 taken
239 7485: else if (IsSystemHeader)
240 2493: FileKind = SrcMgr::C_System;
241 : else
242 4992: FileKind = SrcMgr::C_User;
243 :
244 7580: unsigned EntryExit = 0;
2514: branch 0 taken
5066: branch 1 taken
245 7580: if (IsFileEntry)
246 2514: EntryExit = 1;
2507: branch 0 taken
2559: branch 1 taken
247 5066: else if (IsFileExit)
248 2507: EntryExit = 2;
249 :
250 : LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID,
251 7580: EntryExit, FileKind);
252 : }
253 :
254 92: LineTableInfo &SourceManager::getLineTable() {
48: branch 0 taken
44: branch 1 taken
255 92: if (LineTable == 0)
256 48: LineTable = new LineTableInfo();
257 92: return *LineTable;
258 : }
259 :
260 : //===----------------------------------------------------------------------===//
261 : // Private 'Create' methods.
262 : //===----------------------------------------------------------------------===//
263 :
264 2582: SourceManager::~SourceManager() {
2525: branch 0 taken
57: branch 1 taken
2525: branch 4 taken
2525: branch 5 taken
265 2582: delete LineTable;
266 :
267 : // Delete FileEntry objects corresponding to content caches. Since the actual
268 : // content cache objects are bump pointer allocated, we just have to run the
269 : // dtors, but we call the deallocate method for completeness.
2796: branch 1 taken
2582: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
270 5378: for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
271 2796: MemBufferInfos[i]->~ContentCache();
272 2796: ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
273 : }
2985: branch 3 taken
2582: branch 4 taken
0: branch 8 not taken
0: branch 9 not taken
274 5567: for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
275 2582: I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
276 2985: I->second->~ContentCache();
277 2985: ContentCacheAlloc.Deallocate(I->second);
278 : }
279 2582: }
280 :
281 2585: void SourceManager::clearIDTables() {
282 2585: MainFileID = FileID();
283 2585: SLocEntryTable.clear();
284 2585: LastLineNoFileIDQuery = FileID();
285 2585: LastLineNoContentCache = 0;
286 2585: LastFileIDLookup = FileID();
287 :
0: branch 0 not taken
2585: branch 1 taken
288 2585: if (LineTable)
289 0: LineTable->clear();
290 :
291 : // Use up FileID #0 as an invalid instantiation.
292 2585: NextOffset = 0;
293 2585: createInstantiationLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1);
294 2585: }
295 :
296 : /// getOrCreateContentCache - Create or return a cached ContentCache for the
297 : /// specified file.
298 : const ContentCache *
299 3252: SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) {
0: branch 0 not taken
3252: branch 1 taken
300 3252: assert(FileEnt && "Didn't specify a file entry to use?");
301 :
302 : // Do we already have information about this file?
303 3252: ContentCache *&Entry = FileInfos[FileEnt];
264: branch 0 taken
2988: branch 1 taken
304 3252: if (Entry) return Entry;
305 :
306 : // Nope, create a new Cache entry. Make sure it is at least 8-byte aligned
307 : // so that FileInfo can use the low 3 bits of the pointer for its own
308 : // nefarious purposes.
309 2988: unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
310 2988: EntryAlign = std::max(8U, EntryAlign);
311 2988: Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
2988: branch 1 taken
0: branch 2 not taken
312 2988: new (Entry) ContentCache(FileEnt);
313 2988: return Entry;
314 : }
315 :
316 :
317 : /// createMemBufferContentCache - Create a new ContentCache for the specified
318 : /// memory buffer. This does no caching.
319 : const ContentCache*
320 2799: SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
321 : // Add a new ContentCache to the MemBufferInfos list and return it. Make sure
322 : // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of
323 : // the pointer for its own nefarious purposes.
324 2799: unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
325 2799: EntryAlign = std::max(8U, EntryAlign);
326 2799: ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
2799: branch 1 taken
0: branch 2 not taken
327 2799: new (Entry) ContentCache();
328 2799: MemBufferInfos.push_back(Entry);
329 2799: Entry->setBuffer(Buffer);
330 2799: return Entry;
331 : }
332 :
333 : void SourceManager::PreallocateSLocEntries(ExternalSLocEntrySource *Source,
334 : unsigned NumSLocEntries,
335 48: unsigned NextOffset) {
336 48: ExternalSLocEntries = Source;
337 48: this->NextOffset = NextOffset;
338 48: SLocEntryLoaded.resize(NumSLocEntries + 1);
339 48: SLocEntryLoaded[0] = true;
340 48: SLocEntryTable.resize(SLocEntryTable.size() + NumSLocEntries);
341 48: }
342 :
343 0: void SourceManager::ClearPreallocatedSLocEntries() {
344 0: unsigned I = 0;
0: branch 1 not taken
0: branch 2 not taken
345 0: for (unsigned N = SLocEntryLoaded.size(); I != N; ++I)
0: branch 2 not taken
0: branch 3 not taken
346 0: if (!SLocEntryLoaded[I])
347 0: break;
348 :
349 : // We've already loaded all preallocated source location entries.
0: branch 1 not taken
0: branch 2 not taken
350 0: if (I == SLocEntryLoaded.size())
351 0: return;
352 :
353 : // Remove everything from location I onward.
354 0: SLocEntryTable.resize(I);
355 0: SLocEntryLoaded.clear();
356 0: ExternalSLocEntries = 0;
357 : }
358 :
359 :
360 : //===----------------------------------------------------------------------===//
361 : // Methods to create new FileID's and instantiations.
362 : //===----------------------------------------------------------------------===//
363 :
364 : /// createFileID - Create a new fileID for the specified ContentCache and
365 : /// include position. This works regardless of whether the ContentCache
366 : /// corresponds to a file or some other input source.
367 : FileID SourceManager::createFileID(const ContentCache *File,
368 : SourceLocation IncludePos,
369 : SrcMgr::CharacteristicKind FileCharacter,
370 : unsigned PreallocatedID,
371 5865: unsigned Offset) {
104: branch 0 taken
5761: branch 1 taken
372 5865: if (PreallocatedID) {
373 : // If we're filling in a preallocated ID, just load in the file
374 : // entry and return.
375 : assert(PreallocatedID < SLocEntryLoaded.size() &&
104: branch 1 taken
0: branch 2 not taken
376 104: "Preallocate ID out-of-range");
377 : assert(!SLocEntryLoaded[PreallocatedID] &&
104: branch 2 taken
0: branch 3 not taken
378 104: "Source location entry already loaded");
0: branch 0 not taken
104: branch 1 taken
379 104: assert(Offset && "Preallocate source location cannot have zero offset");
380 : SLocEntryTable[PreallocatedID]
381 104: = SLocEntry::get(Offset, FileInfo::get(IncludePos, File, FileCharacter));
382 104: SLocEntryLoaded[PreallocatedID] = true;
383 104: FileID FID = FileID::get(PreallocatedID);
384 104: return LastFileIDLookup = FID;
385 : }
386 :
387 : SLocEntryTable.push_back(SLocEntry::get(NextOffset,
388 : FileInfo::get(IncludePos, File,
389 5761: FileCharacter)));
390 5761: unsigned FileSize = File->getSize();
0: branch 0 not taken
5761: branch 1 taken
391 5761: assert(NextOffset+FileSize+1 > NextOffset && "Ran out of source locations!");
392 5761: NextOffset += FileSize+1;
393 :
394 : // Set LastFileIDLookup to the newly created file. The next getFileID call is
395 : // almost guaranteed to be from that file.
396 5761: FileID FID = FileID::get(SLocEntryTable.size()-1);
397 5761: return LastFileIDLookup = FID;
398 : }
399 :
400 : /// createInstantiationLoc - Return a new SourceLocation that encodes the fact
401 : /// that a token from SpellingLoc should actually be referenced from
402 : /// InstantiationLoc.
403 : SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc,
404 : SourceLocation ILocStart,
405 : SourceLocation ILocEnd,
406 : unsigned TokLength,
407 : unsigned PreallocatedID,
408 57689: unsigned Offset) {
409 57689: InstantiationInfo II = InstantiationInfo::get(ILocStart,ILocEnd, SpellingLoc);
36: branch 0 taken
57653: branch 1 taken
410 57689: if (PreallocatedID) {
411 : // If we're filling in a preallocated ID, just load in the
412 : // instantiation entry and return.
413 : assert(PreallocatedID < SLocEntryLoaded.size() &&
36: branch 1 taken
0: branch 2 not taken
414 36: "Preallocate ID out-of-range");
415 : assert(!SLocEntryLoaded[PreallocatedID] &&
36: branch 2 taken
0: branch 3 not taken
416 36: "Source location entry already loaded");
0: branch 0 not taken
36: branch 1 taken
417 36: assert(Offset && "Preallocate source location cannot have zero offset");
418 36: SLocEntryTable[PreallocatedID] = SLocEntry::get(Offset, II);
419 36: SLocEntryLoaded[PreallocatedID] = true;
420 36: return SourceLocation::getMacroLoc(Offset);
421 : }
422 57653: SLocEntryTable.push_back(SLocEntry::get(NextOffset, II));
0: branch 0 not taken
57653: branch 1 taken
423 57653: assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!");
424 57653: NextOffset += TokLength+1;
425 57653: return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
426 : }
427 :
428 : const llvm::MemoryBuffer *
429 87: SourceManager::getMemoryBufferForFile(const FileEntry *File) {
430 87: const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
0: branch 0 not taken
87: branch 1 taken
431 87: if (IR == 0)
432 0: return 0;
433 :
434 87: return IR->getBuffer();
435 : }
436 :
437 : bool SourceManager::overrideFileContents(const FileEntry *SourceFile,
438 99: const llvm::MemoryBuffer *Buffer) {
439 99: const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
0: branch 0 not taken
99: branch 1 taken
440 99: if (IR == 0)
441 0: return true;
442 :
443 99: const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer);
444 99: return false;
445 : }
446 :
447 : /// getBufferData - Return a pointer to the start and end of the source buffer
448 : /// data for the specified FileID.
449 : std::pair<const char*, const char*>
450 139738: SourceManager::getBufferData(FileID FID) const {
451 139738: const llvm::MemoryBuffer *Buf = getBuffer(FID);
452 139738: return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
453 : }
454 :
455 :
456 : //===----------------------------------------------------------------------===//
457 : // SourceLocation manipulation methods.
458 : //===----------------------------------------------------------------------===//
459 :
460 : /// getFileIDSlow - Return the FileID for a SourceLocation. This is a very hot
461 : /// method that is used for all SourceManager queries that start with a
462 : /// SourceLocation object. It is responsible for finding the entry in
463 : /// SLocEntryTable which contains the specified location.
464 : ///
465 98712: FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
0: branch 0 not taken
98712: branch 1 taken
466 98712: assert(SLocOffset && "Invalid FileID");
467 :
468 : // After the first and second level caches, I see two common sorts of
469 : // behavior: 1) a lot of searched FileID's are "near" the cached file location
470 : // or are "near" the cached instantiation location. 2) others are just
471 : // completely random and may be a very long way away.
472 : //
473 : // To handle this, we do a linear search for up to 8 steps to catch #1 quickly
474 : // then we fall back to a less cache efficient, but more scalable, binary
475 : // search to find the location.
476 :
477 : // See if this is near the file point - worst case we start scanning from the
478 : // most newly created FileID.
479 98712: std::vector<SrcMgr::SLocEntry>::const_iterator I;
480 :
47590: branch 2 taken
51122: branch 3 taken
481 98712: if (SLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
482 : // Neither loc prunes our search.
483 47590: I = SLocEntryTable.end();
484 : } else {
485 : // Perhaps it is near the file point.
486 51122: I = SLocEntryTable.begin()+LastFileIDLookup.ID;
487 : }
488 :
489 : // Find the FileID that contains this. "I" is an iterator that points to a
490 : // FileID whose offset is known to be larger than SLocOffset.
491 98712: unsigned NumProbes = 0;
492 113034: while (1) {
493 211746: --I;
77125: branch 0 taken
134621: branch 1 taken
494 211746: if (ExternalSLocEntries)
495 77125: getSLocEntry(FileID::get(I - SLocEntryTable.begin()));
82894: branch 2 taken
128852: branch 3 taken
496 211746: if (I->getOffset() <= SLocOffset) {
497 : #if 0
498 : printf("lin %d -> %d [%s] %d %d\n", SLocOffset,
499 : I-SLocEntryTable.begin(),
500 : I->isInstantiation() ? "inst" : "file",
501 : LastFileIDLookup.ID, int(SLocEntryTable.end()-I));
502 : #endif
503 82894: FileID Res = FileID::get(I-SLocEntryTable.begin());
504 :
505 : // If this isn't an instantiation, remember it. We have good locality
506 : // across FileID lookups.
79596: branch 2 taken
3298: branch 3 taken
507 82894: if (!I->isInstantiation())
508 79596: LastFileIDLookup = Res;
509 82894: NumLinearScans += NumProbes+1;
510 82894: return Res;
511 : }
113034: branch 0 taken
15818: branch 1 taken
512 128852: if (++NumProbes == 8)
513 15818: break;
514 : }
515 :
516 : // Convert "I" back into an index. We know that it is an entry whose index is
517 : // larger than the offset we are looking for.
518 15818: unsigned GreaterIndex = I-SLocEntryTable.begin();
519 : // LessIndex - This is the lower bound of the range that we're searching.
520 : // We know that the offset corresponding to the FileID is is less than
521 : // SLocOffset.
522 15818: unsigned LessIndex = 0;
523 15818: NumProbes = 0;
524 96598: while (1) {
525 112416: unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
526 112416: unsigned MidOffset = getSLocEntry(FileID::get(MiddleIndex)).getOffset();
527 :
528 112416: ++NumProbes;
529 :
530 : // If the offset of the midpoint is too large, chop the high side of the
531 : // range to the midpoint.
79579: branch 0 taken
32837: branch 1 taken
532 112416: if (MidOffset > SLocOffset) {
533 79579: GreaterIndex = MiddleIndex;
534 79579: continue;
535 : }
536 :
537 : // If the middle index contains the value, succeed and return.
15818: branch 2 taken
17019: branch 3 taken
538 32837: if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
539 : #if 0
540 : printf("bin %d -> %d [%s] %d %d\n", SLocOffset,
541 : I-SLocEntryTable.begin(),
542 : I->isInstantiation() ? "inst" : "file",
543 : LastFileIDLookup.ID, int(SLocEntryTable.end()-I));
544 : #endif
545 15818: FileID Res = FileID::get(MiddleIndex);
546 :
547 : // If this isn't an instantiation, remember it. We have good locality
548 : // across FileID lookups.
6: branch 2 taken
15812: branch 3 taken
549 15818: if (!I->isInstantiation())
550 6: LastFileIDLookup = Res;
551 15818: NumBinaryProbes += NumProbes;
552 15818: return Res;
553 : }
554 :
555 : // Otherwise, move the low-side up to the middle index.
556 17019: LessIndex = MiddleIndex;
557 : }
558 : }
559 :
560 : SourceLocation SourceManager::
561 72: getInstantiationLocSlowCase(SourceLocation Loc) const {
4: branch 1 taken
68: branch 2 taken
562 72: do {
563 72: std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
564 : Loc = getSLocEntry(LocInfo.first).getInstantiation()
565 72: .getInstantiationLocStart();
566 72: Loc = Loc.getFileLocWithOffset(LocInfo.second);
567 : } while (!Loc.isFileID());
568 :
569 68: return Loc;
570 : }
571 :
572 592: SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const {
8: branch 1 taken
584: branch 2 taken
573 592: do {
574 592: std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
575 592: Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
576 592: Loc = Loc.getFileLocWithOffset(LocInfo.second);
577 : } while (!Loc.isFileID());
578 584: return Loc;
579 : }
580 :
581 :
582 : std::pair<FileID, unsigned>
583 : SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
584 525: unsigned Offset) const {
585 : // If this is an instantiation record, walk through all the instantiation
586 : // points.
587 525: FileID FID;
588 525: SourceLocation Loc;
35: branch 1 taken
525: branch 2 taken
589 560: do {
590 560: Loc = E->getInstantiation().getInstantiationLocStart();
591 :
592 560: FID = getFileID(Loc);
593 560: E = &getSLocEntry(FID);
594 560: Offset += Loc.getOffset()-E->getOffset();
595 : } while (!Loc.isFileID());
596 :
597 525: return std::make_pair(FID, Offset);
598 : }
599 :
600 : std::pair<FileID, unsigned>
601 : SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
602 2171: unsigned Offset) const {
603 : // If this is an instantiation record, walk through all the instantiation
604 : // points.
605 2171: FileID FID;
606 2171: SourceLocation Loc;
996: branch 1 taken
2171: branch 2 taken
607 3167: do {
608 3167: Loc = E->getInstantiation().getSpellingLoc();
609 :
610 3167: FID = getFileID(Loc);
611 3167: E = &getSLocEntry(FID);
612 3167: Offset += Loc.getOffset()-E->getOffset();
613 : } while (!Loc.isFileID());
614 :
615 2171: return std::make_pair(FID, Offset);
616 : }
617 :
618 : /// getImmediateSpellingLoc - Given a SourceLocation object, return the
619 : /// spelling location referenced by the ID. This is the first level down
620 : /// towards the place where the characters that make up the lexed token can be
621 : /// found. This should not generally be used by clients.
622 31: SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{
0: branch 1 not taken
31: branch 2 taken
623 31: if (Loc.isFileID()) return Loc;
624 31: std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
625 31: Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
626 31: return Loc.getFileLocWithOffset(LocInfo.second);
627 : }
628 :
629 :
630 : /// getImmediateInstantiationRange - Loc is required to be an instantiation
631 : /// location. Return the start/end of the instantiation information.
632 : std::pair<SourceLocation,SourceLocation>
633 228: SourceManager::getImmediateInstantiationRange(SourceLocation Loc) const {
228: branch 1 taken
0: branch 2 not taken
634 228: assert(Loc.isMacroID() && "Not an instantiation loc!");
635 228: const InstantiationInfo &II = getSLocEntry(getFileID(Loc)).getInstantiation();
636 228: return II.getInstantiationLocRange();
637 : }
638 :
639 : /// getInstantiationRange - Given a SourceLocation object, return the
640 : /// range of tokens covered by the instantiation in the ultimate file.
641 : std::pair<SourceLocation,SourceLocation>
642 99: SourceManager::getInstantiationRange(SourceLocation Loc) const {
11: branch 1 taken
88: branch 2 taken
643 99: if (Loc.isFileID()) return std::make_pair(Loc, Loc);
644 :
645 : std::pair<SourceLocation,SourceLocation> Res =
646 88: getImmediateInstantiationRange(Loc);
647 :
648 : // Fully resolve the start and end locations to their ultimate instantiation
649 : // points.
30: branch 1 taken
88: branch 2 taken
650 206: while (!Res.first.isFileID())
651 30: Res.first = getImmediateInstantiationRange(Res.first).first;
30: branch 1 taken
88: branch 2 taken
652 206: while (!Res.second.isFileID())
653 30: Res.second = getImmediateInstantiationRange(Res.second).second;
654 88: return Res;
655 : }
656 :
657 :
658 :
659 : //===----------------------------------------------------------------------===//
660 : // Queries about the code at a SourceLocation.
661 : //===----------------------------------------------------------------------===//
662 :
663 : /// getCharacterData - Return a pointer to the start of the specified location
664 : /// in the appropriate MemoryBuffer.
665 136419: const char *SourceManager::getCharacterData(SourceLocation SL) const {
666 : // Note that this is a hot function in the getSpelling() path, which is
667 : // heavily used by -E mode.
668 136419: std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL);
669 :
670 : // Note that calling 'getBuffer()' may lazily page in a source file.
671 : return getSLocEntry(LocInfo.first).getFile().getContentCache()
672 136419: ->getBuffer()->getBufferStart() + LocInfo.second;
673 : }
674 :
675 :
676 : /// getColumnNumber - Return the column # for the specified file position.
677 : /// this is significantly cheaper to compute than the line number.
678 13770: unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos) const {
679 13770: const char *Buf = getBuffer(FID)->getBufferStart();
680 :
681 13770: unsigned LineStart = FilePos;
159178: branch 0 taken
1419: branch 1 taken
146827: branch 2 taken
12351: branch 3 taken
146827: branch 4 taken
0: branch 5 not taken
682 174367: while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
683 146827: --LineStart;
684 13770: return FilePos-LineStart+1;
685 : }
686 :
687 0: unsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc) const {
0: branch 1 not taken
0: branch 2 not taken
688 0: if (Loc.isInvalid()) return 0;
689 0: std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
690 0: return getColumnNumber(LocInfo.first, LocInfo.second);
691 : }
692 :
693 3637: unsigned SourceManager::getInstantiationColumnNumber(SourceLocation Loc) const {
0: branch 1 not taken
3637: branch 2 taken
694 3637: if (Loc.isInvalid()) return 0;
695 3637: std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
696 3637: return getColumnNumber(LocInfo.first, LocInfo.second);
697 : }
698 :
699 :
700 :
701 : static DISABLE_INLINE void ComputeLineNumbers(ContentCache* FI,
702 : llvm::BumpPtrAllocator &Alloc);
703 3989: static void ComputeLineNumbers(ContentCache* FI, llvm::BumpPtrAllocator &Alloc){
704 : // Note that calling 'getBuffer()' may lazily page in the file.
705 3989: const MemoryBuffer *Buffer = FI->getBuffer();
706 :
707 : // Find the file offsets of all of the *physical* source lines. This does
708 : // not look at trigraphs, escaped newlines, or anything else tricky.
709 3989: std::vector<unsigned> LineOffsets;
710 :
711 : // Line #1 starts at char 0.
712 3989: LineOffsets.push_back(0);
713 :
714 3989: const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
715 3989: const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
716 3989: unsigned Offs = 0;
717 395031: while (1) {
718 : // Skip over the contents of the line.
719 : // TODO: Vectorize this? This is very performance sensitive for programs
720 : // with lots of diagnostics and in -E mode.
721 399020: const unsigned char *NextBuf = (const unsigned char *)Buf;
11148829: branch 0 taken
381577: branch 1 taken
11148829: branch 2 taken
0: branch 3 not taken
11131386: branch 4 taken
17443: branch 5 taken
722 11929426: while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
723 11131386: ++NextBuf;
724 399020: Offs += NextBuf-Buf;
725 399020: Buf = NextBuf;
726 :
17443: branch 0 taken
381577: branch 1 taken
0: branch 2 not taken
17443: branch 3 taken
727 780597: if (Buf[0] == '\n' || Buf[0] == '\r') {
728 : // If this is \n\r or \r\n, skip both characters.
365105: branch 0 taken
16472: branch 1 taken
0: branch 2 not taken
365105: branch 3 taken
0: branch 4 not taken
16472: branch 5 taken
729 381577: if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
730 0: ++Offs, ++Buf;
731 381577: ++Offs, ++Buf;
732 381577: LineOffsets.push_back(Offs);
733 : } else {
734 : // Otherwise, this is a null. If end of file, exit.
13454: branch 0 taken
3989: branch 1 taken
735 17443: if (Buf == End) break;
736 : // Otherwise, skip the null.
737 13454: ++Offs, ++Buf;
738 : }
739 : }
740 :
741 : // Copy the offsets into the FileInfo structure.
742 3989: FI->NumLines = LineOffsets.size();
743 3989: FI->SourceLineCache = Alloc.Allocate<unsigned>(LineOffsets.size());
744 3989: std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
745 3989: }
746 :
747 : /// getLineNumber - Given a SourceLocation, return the spelling line number
748 : /// for the position indicated. This requires building and caching a table of
749 : /// line offsets for the MemoryBuffer, so this is not cheap: use only when
750 : /// about to emit a diagnostic.
751 37024: unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos) const {
752 : ContentCache *Content;
32559: branch 1 taken
4465: branch 2 taken
753 37024: if (LastLineNoFileIDQuery == FID)
754 32559: Content = LastLineNoContentCache;
755 : else
756 : Content = const_cast<ContentCache*>(getSLocEntry(FID)
757 4465: .getFile().getContentCache());
758 :
759 : // If this is the first use of line information for this buffer, compute the
760 : /// SourceLineCache for it on demand.
3964: branch 0 taken
33060: branch 1 taken
761 37024: if (Content->SourceLineCache == 0)
762 3964: ComputeLineNumbers(Content, ContentCacheAlloc);
763 :
764 : // Okay, we know we have a line number table. Do a binary search to find the
765 : // line number that this character position lands on.
766 37024: unsigned *SourceLineCache = Content->SourceLineCache;
767 37024: unsigned *SourceLineCacheStart = SourceLineCache;
768 37024: unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
769 :
770 37024: unsigned QueriedFilePos = FilePos+1;
771 :
772 : // FIXME: I would like to be convinced that this code is worth being as
773 : // complicated as it is, binary search isn't that slow.
774 : //
775 : // If it is worth being optimized, then in my opinion it could be more
776 : // performant, simpler, and more obviously correct by just "galloping" outward
777 : // from the queried file position. In fact, this could be incorporated into a
778 : // generic algorithm such as lower_bound_with_hint.
779 : //
780 : // If someone gives me a test case where this matters, and I will do it! - DWD
781 :
782 : // If the previous query was to the same file, we know both the file pos from
783 : // that query and the line number returned. This allows us to narrow the
784 : // search space from the entire file to something near the match.
32559: branch 1 taken
4465: branch 2 taken
785 37024: if (LastLineNoFileIDQuery == FID) {
19553: branch 0 taken
13006: branch 1 taken
786 32559: if (QueriedFilePos >= LastLineNoFilePos) {
787 : // FIXME: Potential overflow?
788 19553: SourceLineCache = SourceLineCache+LastLineNoResult-1;
789 :
790 : // The query is likely to be nearby the previous one. Here we check to
791 : // see if it is within 5, 10 or 20 lines. It can be far away in cases
792 : // where big comment blocks and vertical whitespace eat up lines but
793 : // contribute no tokens.
16933: branch 0 taken
2620: branch 1 taken
794 19553: if (SourceLineCache+5 < SourceLineCacheEnd) {
11824: branch 0 taken
5109: branch 1 taken
795 16933: if (SourceLineCache[5] > QueriedFilePos)
796 11824: SourceLineCacheEnd = SourceLineCache+5;
4973: branch 0 taken
136: branch 1 taken
797 5109: else if (SourceLineCache+10 < SourceLineCacheEnd) {
1693: branch 0 taken
3280: branch 1 taken
798 4973: if (SourceLineCache[10] > QueriedFilePos)
799 1693: SourceLineCacheEnd = SourceLineCache+10;
3111: branch 0 taken
169: branch 1 taken
800 3280: else if (SourceLineCache+20 < SourceLineCacheEnd) {
984: branch 0 taken
2127: branch 1 taken
801 3111: if (SourceLineCache[20] > QueriedFilePos)
802 984: SourceLineCacheEnd = SourceLineCache+20;
803 : }
804 : }
805 : }
806 : } else {
13005: branch 0 taken
1: branch 1 taken
807 13006: if (LastLineNoResult < Content->NumLines)
808 13005: SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
809 : }
810 : }
811 :
812 : // If the spread is large, do a "radix" test as our initial guess, based on
813 : // the assumption that lines average to approximately the same length.
814 : // NOTE: This is currently disabled, as it does not appear to be profitable in
815 : // initial measurements.
816 : if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
817 : unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
818 :
819 : // Take a stab at guessing where it is.
820 : unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
821 :
822 : // Check for -10 and +10 lines.
823 : unsigned LowerBound = std::max(int(ApproxPos-10), 0);
824 : unsigned UpperBound = std::min(ApproxPos+10, FileLen);
825 :
826 : // If the computed lower bound is less than the query location, move it in.
827 : if (SourceLineCache < SourceLineCacheStart+LowerBound &&
828 : SourceLineCacheStart[LowerBound] < QueriedFilePos)
829 : SourceLineCache = SourceLineCacheStart+LowerBound;
830 :
831 : // If the computed upper bound is greater than the query location, move it.
832 : if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
833 : SourceLineCacheStart[UpperBound] >= QueriedFilePos)
834 : SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
835 : }
836 :
837 : unsigned *Pos
838 37024: = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
839 37024: unsigned LineNo = Pos-SourceLineCacheStart;
840 :
841 37024: LastLineNoFileIDQuery = FID;
842 37024: LastLineNoContentCache = Content;
843 37024: LastLineNoFilePos = QueriedFilePos;
844 37024: LastLineNoResult = LineNo;
845 37024: return LineNo;
846 : }
847 :
848 22822: unsigned SourceManager::getInstantiationLineNumber(SourceLocation Loc) const {
18: branch 1 taken
22804: branch 2 taken
849 22822: if (Loc.isInvalid()) return 0;
850 22804: std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
851 22804: return getLineNumber(LocInfo.first, LocInfo.second);
852 : }
853 0: unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc) const {
0: branch 1 not taken
0: branch 2 not taken
854 0: if (Loc.isInvalid()) return 0;
855 0: std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
856 0: return getLineNumber(LocInfo.first, LocInfo.second);
857 : }
858 :
859 : /// getFileCharacteristic - return the file characteristic of the specified
860 : /// source location, indicating whether this is a normal file, a system
861 : /// header, or an "implicit extern C" system header.
862 : ///
863 : /// This state can be modified with flags on GNU linemarker directives like:
864 : /// # 4 "foo.h" 3
865 : /// which changes all source locations in the current file after that to be
866 : /// considered to be from a system header.
867 : SrcMgr::CharacteristicKind
868 8443: SourceManager::getFileCharacteristic(SourceLocation Loc) const {
8443: branch 1 taken
0: branch 2 not taken
869 8443: assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!");
870 8443: std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
871 8443: const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
872 :
873 : // If there are no #line directives in this file, just return the whole-file
874 : // state.
8243: branch 1 taken
200: branch 2 taken
875 8443: if (!FI.hasLineDirectives())
876 8243: return FI.getFileCharacteristic();
877 :
0: branch 0 not taken
200: branch 1 taken
878 200: assert(LineTable && "Can't have linetable entries without a LineTable!");
879 : // See if there is a #line directive before the location.
880 : const LineEntry *Entry =
881 200: LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second);
882 :
883 : // If this is before the first line marker, use the file characteristic.
0: branch 0 not taken
200: branch 1 taken
884 200: if (!Entry)
885 0: return FI.getFileCharacteristic();
886 :
887 200: return Entry->FileKind;
888 : }
889 :
890 : /// Return the filename or buffer identifier of the buffer the location is in.
891 : /// Note that this name does not respect #line directives. Use getPresumedLoc
892 : /// for normal clients.
893 1: const char *SourceManager::getBufferName(SourceLocation Loc) const {
0: branch 1 not taken
1: branch 2 taken
894 1: if (Loc.isInvalid()) return "<invalid loc>";
895 :
896 1: return getBuffer(getFileID(Loc))->getBufferIdentifier();
897 : }
898 :
899 :
900 : /// getPresumedLoc - This method returns the "presumed" location of a
901 : /// SourceLocation specifies. A "presumed location" can be modified by #line
902 : /// or GNU line marker directives. This provides a view on the data that a
903 : /// user should see in diagnostics, for example.
904 : ///
905 : /// Note that a presumed location is always given as the instantiation point
906 : /// of an instantiation location, not at the spelling location.
907 9388: PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
85: branch 1 taken
9303: branch 2 taken
908 9388: if (Loc.isInvalid()) return PresumedLoc();
909 :
910 : // Presumed locations are always for instantiation points.
911 9303: std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
912 :
913 9303: const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
914 9303: const SrcMgr::ContentCache *C = FI.getContentCache();
915 :
916 : // To get the source name, first consult the FileEntry (if one exists)
917 : // before the MemBuffer as this will avoid unnecessarily paging in the
918 : // MemBuffer.
919 : const char *Filename =
4500: branch 0 taken
4803: branch 1 taken
920 9303: C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
921 9303: unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second);
922 9303: unsigned ColNo = getColumnNumber(LocInfo.first, LocInfo.second);
923 9303: SourceLocation IncludeLoc = FI.getIncludeLoc();
924 :
925 : // If we have #line directives in this file, update and overwrite the physical
926 : // location info if appropriate.
4439: branch 1 taken
4864: branch 2 taken
927 9303: if (FI.hasLineDirectives()) {
0: branch 0 not taken
4439: branch 1 taken
928 4439: assert(LineTable && "Can't have linetable entries without a LineTable!");
929 : // See if there is a #line directive before this. If so, get it.
4437: branch 0 taken
2: branch 1 taken
930 4439: if (const LineEntry *Entry =
931 4439: LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second)) {
932 : // If the LineEntry indicates a filename, use it.
4431: branch 0 taken
6: branch 1 taken
933 4437: if (Entry->FilenameID != -1)
934 4431: Filename = LineTable->getFilename(Entry->FilenameID);
935 :
936 : // Use the line number specified by the LineEntry. This line number may
937 : // be multiple lines down from the line entry. Add the difference in
938 : // physical line numbers from the query point and the line marker to the
939 : // total.
940 4437: unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset);
941 4437: LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
942 :
943 : // Note that column numbers are not molested by line markers.
944 :
945 : // Handle virtual #include manipulation.
2935: branch 0 taken
1502: branch 1 taken
946 4437: if (Entry->IncludeOffset) {
947 2935: IncludeLoc = getLocForStartOfFile(LocInfo.first);
948 2935: IncludeLoc = IncludeLoc.getFileLocWithOffset(Entry->IncludeOffset);
949 : }
950 : }
951 : }
952 :
953 9303: return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc);
954 : }
955 :
956 : //===----------------------------------------------------------------------===//
957 : // Other miscellaneous methods.
958 : //===----------------------------------------------------------------------===//
959 :
960 : /// \brief Get the source location for the given file:line:col triplet.
961 : ///
962 : /// If the source file is included multiple times, the source location will
963 : /// be based upon the first inclusion.
964 : SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
965 12909: unsigned Line, unsigned Col) const {
0: branch 0 not taken
12909: branch 1 taken
966 12909: assert(SourceFile && "Null source file!");
12909: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
12909: branch 3 taken
967 12909: assert(Line && Col && "Line and column should start from 1!");
968 :
969 12909: fileinfo_iterator FI = FileInfos.find(SourceFile);
0: branch 2 not taken
12909: branch 3 taken
970 12909: if (FI == FileInfos.end())
971 0: return SourceLocation();
972 12909: ContentCache *Content = FI->second;
973 :
974 : // If this is the first use of line information for this buffer, compute the
975 : /// SourceLineCache for it on demand.
25: branch 0 taken
12884: branch 1 taken
976 12909: if (Content->SourceLineCache == 0)
977 25: ComputeLineNumbers(Content, ContentCacheAlloc);
978 :
0: branch 0 not taken
12909: branch 1 taken
979 12909: if (Line > Content->NumLines)
980 0: return SourceLocation();
981 :
982 12909: unsigned FilePos = Content->SourceLineCache[Line - 1];
983 12909: const char *Buf = Content->getBuffer()->getBufferStart() + FilePos;
984 12909: unsigned BufLength = Content->getBuffer()->getBufferEnd() - Buf;
985 12909: unsigned i = 0;
986 :
987 : // Check that the given column is valid.
559657: branch 0 taken
3: branch 1 taken
546751: branch 2 taken
12906: branch 3 taken
546751: branch 4 taken
0: branch 5 not taken
546751: branch 6 taken
0: branch 7 not taken
988 572569: while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
989 546751: ++i;
0: branch 0 not taken
12909: branch 1 taken
990 12909: if (i < Col-1)
991 0: return SourceLocation();
992 :
993 : // Find the first file ID that corresponds to the given file.
994 12909: FileID FirstFID;
995 :
996 : // First, check the main file ID, since it is common to look for a
997 : // location in the main file.
6: branch 1 taken
12903: branch 2 taken
998 12909: if (!MainFileID.isInvalid()) {
999 6: const SLocEntry &MainSLoc = getSLocEntry(MainFileID);
6: branch 1 taken
0: branch 2 not taken
6: branch 5 taken
0: branch 6 not taken
6: branch 7 taken
0: branch 8 not taken
1000 6: if (MainSLoc.isFile() && MainSLoc.getFile().getContentCache() == Content)
1001 6: FirstFID = MainFileID;
1002 : }
1003 :
12903: branch 1 taken
6: branch 2 taken
1004 12909: if (FirstFID.isInvalid()) {
1005 : // The location we're looking for isn't in the main file; look
1006 : // through all of the source locations.
25806: branch 1 taken
0: branch 2 not taken
1007 25806: for (unsigned I = 0, N = sloc_entry_size(); I != N; ++I) {
1008 25806: const SLocEntry &SLoc = getSLocEntry(I);
12903: branch 1 taken
12903: branch 2 taken
12903: branch 5 taken
0: branch 6 not taken
12903: branch 7 taken
12903: branch 8 taken
1009 25806: if (SLoc.isFile() && SLoc.getFile().getContentCache() == Content) {
1010 12903: FirstFID = FileID::get(I);
1011 12903: break;
1012 : }
1013 : }
1014 : }
1015 :
0: branch 1 not taken
12909: branch 2 taken
1016 12909: if (FirstFID.isInvalid())
1017 0: return SourceLocation();
1018 :
1019 12909: return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + Col - 1);
1020 : }
1021 :
1022 : /// \brief Determines the order of 2 source locations in the translation unit.
1023 : ///
1024 : /// \returns true if LHS source location comes before RHS, false otherwise.
1025 : bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
1026 127005: SourceLocation RHS) const {
127005: branch 1 taken
0: branch 2 not taken
127005: branch 4 taken
0: branch 5 not taken
1027 127005: assert(LHS.isValid() && RHS.isValid() && "Passed invalid source location!");
107: branch 1 taken
126898: branch 2 taken
1028 127005: if (LHS == RHS)
1029 107: return false;
1030 :
1031 126898: std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
1032 126898: std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS);
1033 :
1034 : // If the source locations are in the same file, just compare offsets.
88430: branch 1 taken
38468: branch 2 taken
1035 126898: if (LOffs.first == ROffs.first)
1036 88430: return LOffs.second < ROffs.second;
1037 :
1038 : // If we are comparing a source location with multiple locations in the same
1039 : // file, we get a big win by caching the result.
1040 :
38462: branch 1 taken
6: branch 2 taken
38462: branch 4 taken
0: branch 5 not taken
38462: branch 6 taken
6: branch 7 taken
1041 38468: if (LastLFIDForBeforeTUCheck == LOffs.first &&
1042 : LastRFIDForBeforeTUCheck == ROffs.first)
1043 38462: return LastResForBeforeTUCheck;
1044 :
1045 6: LastLFIDForBeforeTUCheck = LOffs.first;
1046 6: LastRFIDForBeforeTUCheck = ROffs.first;
1047 :
1048 : // "Traverse" the include/instantiation stacks of both locations and try to
1049 : // find a common "ancestor".
1050 : //
1051 : // First we traverse the stack of the right location and check each level
1052 : // against the level of the left location, while collecting all levels in a
1053 : // "stack map".
1054 :
1055 6: std::map<FileID, unsigned> ROffsMap;
1056 6: ROffsMap[ROffs.first] = ROffs.second;
1057 :
1058 0: while (1) {
1059 6: SourceLocation UpperLoc;
1060 6: const SrcMgr::SLocEntry &Entry = getSLocEntry(ROffs.first);
0: branch 1 not taken
6: branch 2 taken
1061 6: if (Entry.isInstantiation())
1062 0: UpperLoc = Entry.getInstantiation().getInstantiationLocStart();
1063 : else
1064 6: UpperLoc = Entry.getFile().getIncludeLoc();
1065 :
0: branch 1 not taken
6: branch 2 taken
1066 6: if (UpperLoc.isInvalid())
1067 6: break; // We reached the top.
1068 :
1069 0: ROffs = getDecomposedLoc(UpperLoc);
1070 :
0: branch 1 not taken
0: branch 2 not taken
1071 0: if (LOffs.first == ROffs.first)
1072 0: return LastResForBeforeTUCheck = LOffs.second < ROffs.second;
1073 :
1074 0: ROffsMap[ROffs.first] = ROffs.second;
1075 : }
1076 :
1077 : // We didn't find a common ancestor. Now traverse the stack of the left
1078 : // location, checking against the stack map of the right location.
1079 :
1080 0: while (1) {
1081 6: SourceLocation UpperLoc;
1082 6: const SrcMgr::SLocEntry &Entry = getSLocEntry(LOffs.first);
0: branch 1 not taken
6: branch 2 taken
1083 6: if (Entry.isInstantiation())
1084 0: UpperLoc = Entry.getInstantiation().getInstantiationLocStart();
1085 : else
1086 6: UpperLoc = Entry.getFile().getIncludeLoc();
1087 :
0: branch 1 not taken
6: branch 2 taken
1088 6: if (UpperLoc.isInvalid())
1089 6: break; // We reached the top.
1090 :
1091 0: LOffs = getDecomposedLoc(UpperLoc);
1092 :
1093 0: std::map<FileID, unsigned>::iterator I = ROffsMap.find(LOffs.first);
0: branch 2 not taken
0: branch 3 not taken
1094 0: if (I != ROffsMap.end())
1095 0: return LastResForBeforeTUCheck = LOffs.second < I->second;
1096 : }
1097 :
1098 : // There is no common ancestor, most probably because one location is in the
1099 : // predefines buffer.
1100 : //
1101 : // FIXME: We should rearrange the external interface so this simply never
1102 : // happens; it can't conceptually happen. Also see PR5662.
1103 :
1104 : // If exactly one location is a memory buffer, assume it preceeds the other.
1105 6: bool LIsMB = !getSLocEntry(LOffs.first).getFile().getContentCache()->Entry;
1106 6: bool RIsMB = !getSLocEntry(ROffs.first).getFile().getContentCache()->Entry;
6: branch 0 taken
0: branch 1 not taken
1107 6: if (LIsMB != RIsMB)
1108 6: return LastResForBeforeTUCheck = LIsMB;
1109 :
1110 : // Otherwise, just assume FileIDs were created in order.
1111 0: return LastResForBeforeTUCheck = (LOffs.first < ROffs.first);
1112 : }
1113 :
1114 : /// PrintStats - Print statistics to stderr.
1115 : ///
1116 2: void SourceManager::PrintStats() const {
1117 2: llvm::errs() << "\n*** Source Manager Stats:\n";
1118 : llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
1119 2: << " mem buffers mapped.\n";
1120 : llvm::errs() << SLocEntryTable.size() << " SLocEntry's allocated, "
1121 2: << NextOffset << "B of Sloc address space used.\n";
1122 :
1123 2: unsigned NumLineNumsComputed = 0;
1124 2: unsigned NumFileBytesMapped = 0;
2: branch 4 taken
2: branch 5 taken
1125 4: for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){
1126 2: NumLineNumsComputed += I->second->SourceLineCache != 0;
1127 2: NumFileBytesMapped += I->second->getSizeBytesMapped();
1128 : }
1129 :
1130 : llvm::errs() << NumFileBytesMapped << " bytes of files mapped, "
1131 2: << NumLineNumsComputed << " files with line #'s computed.\n";
1132 : llvm::errs() << "FileID scans: " << NumLinearScans << " linear, "
1133 2: << NumBinaryProbes << " binary.\n";
1134 2: }
1135 :
44: branch 0 taken
44: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
44: branch 7 taken
1136 44: ExternalSLocEntrySource::~ExternalSLocEntrySource() { }
Generated: 2010-02-10 01:31 by zcov