 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
68.3% |
28 / 41 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
95.1% |
39 / 41 |
| |
|
Line Coverage: |
100.0% |
136 / 136 |
| |
 |
|
 |
1 : //===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===//
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 defines the SourceManager interface.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_CLANG_SOURCEMANAGER_H
15 : #define LLVM_CLANG_SOURCEMANAGER_H
16 :
17 : #include "clang/Basic/SourceLocation.h"
18 : #include "llvm/Support/Allocator.h"
19 : #include "llvm/System/DataTypes.h"
20 : #include "llvm/ADT/DenseMap.h"
21 : #include <vector>
22 : #include <cassert>
23 :
24 : namespace llvm {
25 : class MemoryBuffer;
26 : }
27 :
28 : namespace clang {
29 :
30 : class SourceManager;
31 : class FileManager;
32 : class FileEntry;
33 : class IdentifierTokenInfo;
34 : class LineTableInfo;
35 :
36 : /// SrcMgr - Public enums and private classes that are part of the
37 : /// SourceManager implementation.
38 : ///
39 : namespace SrcMgr {
40 : /// CharacteristicKind - This is used to represent whether a file or directory
41 : /// holds normal user code, system code, or system code which is implicitly
42 : /// 'extern "C"' in C++ mode. Entire directories can be tagged with this
43 : /// (this is maintained by DirectoryLookup and friends) as can specific
44 : /// FileIDInfos when a #pragma system_header is seen or various other cases.
45 : ///
46 : enum CharacteristicKind {
47 : C_User, C_System, C_ExternCSystem
48 : };
49 :
50 : /// ContentCache - Once instance of this struct is kept for every file
51 : /// loaded or used. This object owns the MemoryBuffer object.
52 : class ContentCache {
53 : /// Buffer - The actual buffer containing the characters from the input
54 : /// file. This is owned by the ContentCache object.
55 : mutable const llvm::MemoryBuffer *Buffer;
56 :
57 : public:
58 : /// Reference to the file entry. This reference does not own
59 : /// the FileEntry object. It is possible for this to be NULL if
60 : /// the ContentCache encapsulates an imaginary text buffer.
61 : const FileEntry *Entry;
62 :
63 : /// SourceLineCache - A bump pointer allocated array of offsets for each
64 : /// source line. This is lazily computed. This is owned by the
65 : /// SourceManager BumpPointerAllocator object.
66 : unsigned *SourceLineCache;
67 :
68 : /// NumLines - The number of lines in this ContentCache. This is only valid
69 : /// if SourceLineCache is non-null.
70 : unsigned NumLines;
71 :
72 : /// getBuffer - Returns the memory buffer for the associated content. If
73 : /// there is an error opening this buffer the first time, this manufactures
74 : /// a temporary buffer and returns a non-empty error string.
75 : const llvm::MemoryBuffer *getBuffer(std::string *ErrorStr = 0) const;
76 :
77 : /// getSize - Returns the size of the content encapsulated by this
78 : /// ContentCache. This can be the size of the source file or the size of an
79 : /// arbitrary scratch buffer. If the ContentCache encapsulates a source
80 : /// file this size is retrieved from the file's FileEntry.
81 : unsigned getSize() const;
82 :
83 : /// getSizeBytesMapped - Returns the number of bytes actually mapped for
84 : /// this ContentCache. This can be 0 if the MemBuffer was not actually
85 : /// instantiated.
86 : unsigned getSizeBytesMapped() const;
87 :
88 2799: void setBuffer(const llvm::MemoryBuffer *B) {
0: branch 0 not taken
2799: branch 1 taken
89 2799: assert(!Buffer && "MemoryBuffer already set.");
90 2799: Buffer = B;
91 2799: }
92 :
93 : /// \brief Replace the existing buffer (which will be deleted)
94 : /// with the given buffer.
95 : void replaceBuffer(const llvm::MemoryBuffer *B);
96 :
97 5787: ContentCache(const FileEntry *Ent = 0)
98 5787: : Buffer(0), Entry(Ent), SourceLineCache(0), NumLines(0) {}
99 :
100 : ~ContentCache();
101 :
102 : /// The copy ctor does not allow copies where source object has either
103 : /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
104 : /// is not transfered, so this is a logical error.
105 : ContentCache(const ContentCache &RHS) : Buffer(0), SourceLineCache(0) {
106 : Entry = RHS.Entry;
107 :
108 : assert (RHS.Buffer == 0 && RHS.SourceLineCache == 0
109 : && "Passed ContentCache object cannot own a buffer.");
110 :
111 : NumLines = RHS.NumLines;
112 : }
113 :
114 : private:
115 : // Disable assignments.
116 : ContentCache &operator=(const ContentCache& RHS);
117 : };
118 :
119 : /// FileInfo - Information about a FileID, basically just the logical file
120 : /// that it represents and include stack information.
121 : ///
122 : /// Each FileInfo has include stack information, indicating where it came
123 : /// from. This information encodes the #include chain that a token was
124 : /// instantiated from. The main include file has an invalid IncludeLoc.
125 : ///
126 : /// FileInfos contain a "ContentCache *", with the contents of the file.
127 : ///
128 : class FileInfo {
129 : /// IncludeLoc - The location of the #include that brought in this file.
130 : /// This is an invalid SLOC for the main file (top of the #include chain).
131 : unsigned IncludeLoc; // Really a SourceLocation
132 :
133 : /// Data - This contains the ContentCache* and the bits indicating the
134 : /// characteristic of the file and whether it has #line info, all bitmangled
135 : /// together.
136 : uintptr_t Data;
137 : public:
138 : /// get - Return a FileInfo object.
139 : static FileInfo get(SourceLocation IL, const ContentCache *Con,
140 5865: CharacteristicKind FileCharacter) {
141 : FileInfo X;
142 5865: X.IncludeLoc = IL.getRawEncoding();
143 5865: X.Data = (uintptr_t)Con;
0: branch 0 not taken
5865: branch 1 taken
144 5865: assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
0: branch 0 not taken
5865: branch 1 taken
145 5865: assert((unsigned)FileCharacter < 4 && "invalid file character");
146 5865: X.Data |= (unsigned)FileCharacter;
147 : return X;
148 : }
149 :
150 9416: SourceLocation getIncludeLoc() const {
151 9416: return SourceLocation::getFromRawEncoding(IncludeLoc);
152 : }
153 328416: const ContentCache* getContentCache() const {
154 328416: return reinterpret_cast<const ContentCache*>(Data & ~7UL);
155 : }
156 :
157 : /// getCharacteristic - Return whether this is a system header or not.
158 8341: CharacteristicKind getFileCharacteristic() const {
159 8341: return (CharacteristicKind)(Data & 3);
160 : }
161 :
162 : /// hasLineDirectives - Return true if this FileID has #line directives in
163 : /// it.
164 17841: bool hasLineDirectives() const { return (Data & 4) != 0; }
165 :
166 : /// setHasLineDirectives - Set the flag that indicates that this FileID has
167 : /// line table entries associated with it.
168 7620: void setHasLineDirectives() {
169 7620: Data |= 4;
170 7620: }
171 : };
172 :
173 : /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation
174 : /// location - where the token was ultimately instantiated, and the
175 : /// SpellingLoc - where the actual character data for the token came from.
176 : class InstantiationInfo {
177 : // Really these are all SourceLocations.
178 :
179 : /// SpellingLoc - Where the spelling for the token can be found.
180 : unsigned SpellingLoc;
181 :
182 : /// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these
183 : /// indicate the start and end of the instantiation. In object-like macros,
184 : /// these will be the same. In a function-like macro instantiation, the
185 : /// start will be the identifier and the end will be the ')'.
186 : unsigned InstantiationLocStart, InstantiationLocEnd;
187 : public:
188 3884: SourceLocation getSpellingLoc() const {
189 3884: return SourceLocation::getFromRawEncoding(SpellingLoc);
190 : }
191 954: SourceLocation getInstantiationLocStart() const {
192 954: return SourceLocation::getFromRawEncoding(InstantiationLocStart);
193 : }
194 322: SourceLocation getInstantiationLocEnd() const {
195 322: return SourceLocation::getFromRawEncoding(InstantiationLocEnd);
196 : }
197 :
198 228: std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const {
199 : return std::make_pair(getInstantiationLocStart(),
200 228: getInstantiationLocEnd());
201 : }
202 :
203 : /// get - Return a InstantiationInfo for an expansion. IL specifies
204 : /// the instantiation location (where the macro is expanded), and SL
205 : /// specifies the spelling location (where the characters from the token
206 : /// come from). IL and PL can both refer to normal File SLocs or
207 : /// instantiation locations.
208 : static InstantiationInfo get(SourceLocation ILStart, SourceLocation ILEnd,
209 57689: SourceLocation SL) {
210 : InstantiationInfo X;
211 57689: X.SpellingLoc = SL.getRawEncoding();
212 57689: X.InstantiationLocStart = ILStart.getRawEncoding();
213 57689: X.InstantiationLocEnd = ILEnd.getRawEncoding();
214 : return X;
215 : }
216 : };
217 :
218 : /// SLocEntry - This is a discriminated union of FileInfo and
219 : /// InstantiationInfo. SourceManager keeps an array of these objects, and
220 : /// they are uniquely identified by the FileID datatype.
221 : class SLocEntry {
222 : unsigned Offset; // low bit is set for instantiation info.
223 : union {
224 : FileInfo File;
225 : InstantiationInfo Instantiation;
226 : };
227 : public:
228 2160322: unsigned getOffset() const { return Offset >> 1; }
229 :
230 498354: bool isInstantiation() const { return Offset & 1; }
231 394886: bool isFile() const { return !isInstantiation(); }
232 :
233 344494: const FileInfo &getFile() const {
344494: branch 1 taken
0: branch 2 not taken
234 344494: assert(isFile() && "Not a file SLocEntry!");
235 344494: return File;
236 : }
237 :
238 4744: const InstantiationInfo &getInstantiation() const {
4744: branch 1 taken
0: branch 2 not taken
239 4744: assert(isInstantiation() && "Not an instantiation SLocEntry!");
240 4744: return Instantiation;
241 : }
242 :
243 5865: static SLocEntry get(unsigned Offset, const FileInfo &FI) {
244 : SLocEntry E;
245 5865: E.Offset = Offset << 1;
246 5865: E.File = FI;
247 : return E;
248 : }
249 :
250 57689: static SLocEntry get(unsigned Offset, const InstantiationInfo &II) {
251 : SLocEntry E;
252 57689: E.Offset = (Offset << 1) | 1;
253 57689: E.Instantiation = II;
254 : return E;
255 : }
256 : };
257 : } // end SrcMgr namespace.
258 :
259 : /// \brief External source of source location entries.
260 48: class ExternalSLocEntrySource {
261 : public:
262 : virtual ~ExternalSLocEntrySource();
263 :
264 : /// \brief Read the source location entry with index ID.
265 : virtual void ReadSLocEntry(unsigned ID) = 0;
266 : };
267 :
268 : /// SourceManager - This file handles loading and caching of source files into
269 : /// memory. This object owns the MemoryBuffer objects for all of the loaded
270 : /// files and assigns unique FileID's for each unique #include chain.
271 : ///
272 : /// The SourceManager can be queried for information about SourceLocation
273 : /// objects, turning them into either spelling or instantiation locations.
274 : /// Spelling locations represent where the bytes corresponding to a token came
275 : /// from and instantiation locations represent where the location is in the
276 : /// user's view. In the case of a macro expansion, for example, the spelling
277 : /// location indicates where the expanded token came from and the instantiation
278 : /// location specifies where it was expanded.
279 : class SourceManager {
280 : mutable llvm::BumpPtrAllocator ContentCacheAlloc;
281 :
282 : /// FileInfos - Memoized information about all of the files tracked by this
283 : /// SourceManager. This set allows us to merge ContentCache entries based
284 : /// on their FileEntry*. All ContentCache objects will thus have unique,
285 : /// non-null, FileEntry pointers.
286 : llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
287 :
288 : /// MemBufferInfos - Information about various memory buffers that we have
289 : /// read in. All FileEntry* within the stored ContentCache objects are NULL,
290 : /// as they do not refer to a file.
291 : std::vector<SrcMgr::ContentCache*> MemBufferInfos;
292 :
293 : /// SLocEntryTable - This is an array of SLocEntry's that we have created.
294 : /// FileID is an index into this vector. This array is sorted by the offset.
295 : std::vector<SrcMgr::SLocEntry> SLocEntryTable;
296 : /// NextOffset - This is the next available offset that a new SLocEntry can
297 : /// start at. It is SLocEntryTable.back().getOffset()+size of back() entry.
298 : unsigned NextOffset;
299 :
300 : /// \brief If source location entries are being lazily loaded from
301 : /// an external source, this vector indicates whether the Ith source
302 : /// location entry has already been loaded from the external storage.
303 : std::vector<bool> SLocEntryLoaded;
304 :
305 : /// \brief An external source for source location entries.
306 : ExternalSLocEntrySource *ExternalSLocEntries;
307 :
308 : /// LastFileIDLookup - This is a one-entry cache to speed up getFileID.
309 : /// LastFileIDLookup records the last FileID looked up or created, because it
310 : /// is very common to look up many tokens from the same file.
311 : mutable FileID LastFileIDLookup;
312 :
313 : /// LineTable - This holds information for #line directives. It is referenced
314 : /// by indices from SLocEntryTable.
315 : LineTableInfo *LineTable;
316 :
317 : /// LastLineNo - These ivars serve as a cache used in the getLineNumber
318 : /// method which is used to speedup getLineNumber calls to nearby locations.
319 : mutable FileID LastLineNoFileIDQuery;
320 : mutable SrcMgr::ContentCache *LastLineNoContentCache;
321 : mutable unsigned LastLineNoFilePos;
322 : mutable unsigned LastLineNoResult;
323 :
324 : /// MainFileID - The file ID for the main source file of the translation unit.
325 : FileID MainFileID;
326 :
327 : // Statistics for -print-stats.
328 : mutable unsigned NumLinearScans, NumBinaryProbes;
329 :
330 : // Cache results for the isBeforeInTranslationUnit method.
331 : mutable FileID LastLFIDForBeforeTUCheck;
332 : mutable FileID LastRFIDForBeforeTUCheck;
333 : mutable bool LastResForBeforeTUCheck;
334 :
335 : // SourceManager doesn't support copy construction.
336 : explicit SourceManager(const SourceManager&);
337 : void operator=(const SourceManager&);
338 : public:
339 2585: SourceManager()
340 : : ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
341 2585: NumBinaryProbes(0) {
342 2585: clearIDTables();
343 2585: }
344 : ~SourceManager();
345 :
346 : void clearIDTables();
347 :
348 : //===--------------------------------------------------------------------===//
349 : // MainFileID creation and querying methods.
350 : //===--------------------------------------------------------------------===//
351 :
352 : /// getMainFileID - Returns the FileID of the main source file.
353 10762: FileID getMainFileID() const { return MainFileID; }
354 :
355 : /// createMainFileID - Create the FileID for the main source file.
356 : FileID createMainFileID(const FileEntry *SourceFile,
357 2422: SourceLocation IncludePos) {
2422: branch 1 taken
0: branch 2 not taken
358 2422: assert(MainFileID.isInvalid() && "MainFileID already set!");
359 2422: MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
360 2422: return MainFileID;
361 : }
362 :
363 : //===--------------------------------------------------------------------===//
364 : // Methods to create new FileID's and instantiations.
365 : //===--------------------------------------------------------------------===//
366 :
367 : /// createFileID - Create a new FileID that represents the specified file
368 : /// being #included from the specified IncludePosition. This returns 0 on
369 : /// error and translates NULL into standard input.
370 : /// PreallocateID should be non-zero to specify which a pre-allocated,
371 : /// lazily computed source location is being filled in by this operation.
372 : FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
373 : SrcMgr::CharacteristicKind FileCharacter,
374 : unsigned PreallocatedID = 0,
375 3066: unsigned Offset = 0) {
376 3066: const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
0: branch 0 not taken
3066: branch 1 taken
377 3066: if (IR == 0) return FileID(); // Error opening file?
378 3066: return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset);
379 : }
380 :
381 : /// createFileIDForMemBuffer - Create a new FileID that represents the
382 : /// specified memory buffer. This does no caching of the buffer and takes
383 : /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
384 : FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
385 : unsigned PreallocatedID = 0,
386 2799: unsigned Offset = 0) {
387 : return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
388 2799: SrcMgr::C_User, PreallocatedID, Offset);
389 : }
390 :
391 : /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
392 : /// that will represent the FileID for the main source. One example
393 : /// of when this would be used is when the main source is read from STDIN.
394 97: FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
97: branch 1 taken
0: branch 2 not taken
395 97: assert(MainFileID.isInvalid() && "MainFileID already set!");
396 97: MainFileID = createFileIDForMemBuffer(Buffer);
397 97: return MainFileID;
398 : }
399 :
400 : /// createInstantiationLoc - Return a new SourceLocation that encodes the fact
401 : /// that a token at Loc should actually be referenced from InstantiationLoc.
402 : /// TokLength is the length of the token being instantiated.
403 : SourceLocation createInstantiationLoc(SourceLocation Loc,
404 : SourceLocation InstantiationLocStart,
405 : SourceLocation InstantiationLocEnd,
406 : unsigned TokLength,
407 : unsigned PreallocatedID = 0,
408 : unsigned Offset = 0);
409 :
410 : /// \brief Retrieve the memory buffer associated with the given file.
411 : const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File);
412 :
413 : /// \brief Override the contents of the given source file by providing an
414 : /// already-allocated buffer.
415 : ///
416 : /// \param SourceFile the source file whose contents will be override.
417 : ///
418 : /// \param Buffer the memory buffer whose contents will be used as the
419 : /// data in the given source file.
420 : ///
421 : /// \returns true if an error occurred, false otherwise.
422 : bool overrideFileContents(const FileEntry *SourceFile,
423 : const llvm::MemoryBuffer *Buffer);
424 :
425 : //===--------------------------------------------------------------------===//
426 : // FileID manipulation methods.
427 : //===--------------------------------------------------------------------===//
428 :
429 : /// getBuffer - Return the buffer for the specified FileID. If there is an
430 : /// error opening this buffer the first time, this manufactures a temporary
431 : /// buffer and returns a non-empty error string.
432 160517: const llvm::MemoryBuffer *getBuffer(FileID FID, std::string *Error = 0) const{
433 160517: return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Error);
434 : }
435 :
436 : /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
437 4591: const FileEntry *getFileEntryForID(FileID FID) const {
438 4591: return getSLocEntry(FID).getFile().getContentCache()->Entry;
439 : }
440 :
441 : /// getBufferData - Return a pointer to the start and end of the source buffer
442 : /// data for the specified FileID.
443 : std::pair<const char*, const char*> getBufferData(FileID FID) const;
444 :
445 :
446 : //===--------------------------------------------------------------------===//
447 : // SourceLocation manipulation methods.
448 : //===--------------------------------------------------------------------===//
449 :
450 : /// getFileID - Return the FileID for a SourceLocation. This is a very
451 : /// hot method that is used for all SourceManager queries that start with a
452 : /// SourceLocation object. It is responsible for finding the entry in
453 : /// SLocEntryTable which contains the specified location.
454 : ///
455 597779: FileID getFileID(SourceLocation SpellingLoc) const {
456 597779: unsigned SLocOffset = SpellingLoc.getOffset();
457 :
458 : // If our one-entry cache covers this offset, just return it.
499067: branch 2 taken
98712: branch 2 taken
459 597779: if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
460 499067: return LastFileIDLookup;
461 :
462 98712: return getFileIDSlow(SLocOffset);
463 : }
464 :
465 : /// getLocForStartOfFile - Return the source location corresponding to the
466 : /// first byte of the specified file.
467 24194: SourceLocation getLocForStartOfFile(FileID FID) const {
24194: branch 1 taken
0: branch 2 not taken
468 24194: assert(FID.ID < SLocEntryTable.size() && "FileID out of range");
24194: branch 2 taken
0: branch 3 not taken
469 24194: assert(getSLocEntry(FID).isFile() && "FileID is not a file");
470 24194: unsigned FileOffset = getSLocEntry(FID).getOffset();
471 24194: return SourceLocation::getFileLoc(FileOffset);
472 : }
473 :
474 : /// getInstantiationLoc - Given a SourceLocation object, return the
475 : /// instantiation location referenced by the ID.
476 145240: SourceLocation getInstantiationLoc(SourceLocation Loc) const {
477 : // Handle the non-mapped case inline, defer to out of line code to handle
478 : // instantiations.
145172: branch 1 taken
68: branch 2 taken
479 145240: if (Loc.isFileID()) return Loc;
480 68: return getInstantiationLocSlowCase(Loc);
481 : }
482 :
483 : /// getImmediateInstantiationRange - Loc is required to be an instantiation
484 : /// location. Return the start/end of the instantiation information.
485 : std::pair<SourceLocation,SourceLocation>
486 : getImmediateInstantiationRange(SourceLocation Loc) const;
487 :
488 : /// getInstantiationRange - Given a SourceLocation object, return the
489 : /// range of tokens covered by the instantiation in the ultimate file.
490 : std::pair<SourceLocation,SourceLocation>
491 : getInstantiationRange(SourceLocation Loc) const;
492 :
493 :
494 : /// getSpellingLoc - Given a SourceLocation object, return the spelling
495 : /// location referenced by the ID. This is the place where the characters
496 : /// that make up the lexed token can be found.
497 5834: SourceLocation getSpellingLoc(SourceLocation Loc) const {
498 : // Handle the non-mapped case inline, defer to out of line code to handle
499 : // instantiations.
584: branch 2 taken
0: branch 2 not taken
500 5834: if (Loc.isFileID()) return Loc;
501 584: return getSpellingLocSlowCase(Loc);
502 : }
503 :
504 : /// getImmediateSpellingLoc - Given a SourceLocation object, return the
505 : /// spelling location referenced by the ID. This is the first level down
506 : /// towards the place where the characters that make up the lexed token can be
507 : /// found. This should not generally be used by clients.
508 : SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
509 :
510 : /// getDecomposedLoc - Decompose the specified location into a raw FileID +
511 : /// Offset pair. The first element is the FileID, the second is the
512 : /// offset from the start of the buffer of the location.
513 394719: std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const {
514 394719: FileID FID = getFileID(Loc);
515 394719: return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset());
516 : }
517 :
518 : /// getDecomposedInstantiationLoc - Decompose the specified location into a
519 : /// raw FileID + Offset pair. If the location is an instantiation record,
520 : /// walk through it until we find the final location instantiated.
521 : std::pair<FileID, unsigned>
522 56923: getDecomposedInstantiationLoc(SourceLocation Loc) const {
523 56923: FileID FID = getFileID(Loc);
524 56923: const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
525 :
526 56923: unsigned Offset = Loc.getOffset()-E->getOffset();
56398: branch 1 taken
525: branch 2 taken
527 56923: if (Loc.isFileID())
528 56398: return std::make_pair(FID, Offset);
529 :
530 525: return getDecomposedInstantiationLocSlowCase(E, Offset);
531 : }
532 :
533 : /// getDecomposedSpellingLoc - Decompose the specified location into a raw
534 : /// FileID + Offset pair. If the location is an instantiation record, walk
535 : /// through it until we find its spelling record.
536 : std::pair<FileID, unsigned>
537 136419: getDecomposedSpellingLoc(SourceLocation Loc) const {
538 136419: FileID FID = getFileID(Loc);
539 136419: const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
540 :
541 136419: unsigned Offset = Loc.getOffset()-E->getOffset();
542 136419: if (Loc.isFileID())
543 134248: return std::make_pair(FID, Offset);
544 2171: return getDecomposedSpellingLocSlowCase(E, Offset);
545 : }
546 :
547 : /// getFileOffset - This method returns the offset from the start
548 : /// of the file that the specified SourceLocation represents. This is not very
549 : /// meaningful for a macro ID.
550 169: unsigned getFileOffset(SourceLocation SpellingLoc) const {
551 169: return getDecomposedLoc(SpellingLoc).second;
552 : }
553 :
554 :
555 : //===--------------------------------------------------------------------===//
556 : // Queries about the code at a SourceLocation.
557 : //===--------------------------------------------------------------------===//
558 :
559 : /// getCharacterData - Return a pointer to the start of the specified location
560 : /// in the appropriate spelling MemoryBuffer.
561 : const char *getCharacterData(SourceLocation SL) const;
562 :
563 : /// getColumnNumber - Return the column # for the specified file position.
564 : /// This is significantly cheaper to compute than the line number. This
565 : /// returns zero if the column number isn't known. This may only be called on
566 : /// a file sloc, so you must choose a spelling or instantiation location
567 : /// before calling this method.
568 : unsigned getColumnNumber(FileID FID, unsigned FilePos) const;
569 : unsigned getSpellingColumnNumber(SourceLocation Loc) const;
570 : unsigned getInstantiationColumnNumber(SourceLocation Loc) const;
571 :
572 :
573 : /// getLineNumber - Given a SourceLocation, return the spelling line number
574 : /// for the position indicated. This requires building and caching a table of
575 : /// line offsets for the MemoryBuffer, so this is not cheap: use only when
576 : /// about to emit a diagnostic.
577 : unsigned getLineNumber(FileID FID, unsigned FilePos) const;
578 :
579 : unsigned getInstantiationLineNumber(SourceLocation Loc) const;
580 : unsigned getSpellingLineNumber(SourceLocation Loc) const;
581 :
582 : /// Return the filename or buffer identifier of the buffer the location is in.
583 : /// Note that this name does not respect #line directives. Use getPresumedLoc
584 : /// for normal clients.
585 : const char *getBufferName(SourceLocation Loc) const;
586 :
587 : /// getFileCharacteristic - return the file characteristic of the specified
588 : /// source location, indicating whether this is a normal file, a system
589 : /// header, or an "implicit extern C" system header.
590 : ///
591 : /// This state can be modified with flags on GNU linemarker directives like:
592 : /// # 4 "foo.h" 3
593 : /// which changes all source locations in the current file after that to be
594 : /// considered to be from a system header.
595 : SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
596 :
597 : /// getPresumedLoc - This method returns the "presumed" location of a
598 : /// SourceLocation specifies. A "presumed location" can be modified by #line
599 : /// or GNU line marker directives. This provides a view on the data that a
600 : /// user should see in diagnostics, for example.
601 : ///
602 : /// Note that a presumed location is always given as the instantiation point
603 : /// of an instantiation location, not at the spelling location.
604 : PresumedLoc getPresumedLoc(SourceLocation Loc) const;
605 :
606 : /// isFromSameFile - Returns true if both SourceLocations correspond to
607 : /// the same file.
608 51: bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
609 51: return getFileID(Loc1) == getFileID(Loc2);
610 : }
611 :
612 : /// isFromMainFile - Returns true if the file of provided SourceLocation is
613 : /// the main file.
614 2958: bool isFromMainFile(SourceLocation Loc) const {
615 2958: return getFileID(Loc) == getMainFileID();
616 : }
617 :
618 : /// isInSystemHeader - Returns if a SourceLocation is in a system header.
619 4617: bool isInSystemHeader(SourceLocation Loc) const {
620 4617: return getFileCharacteristic(Loc) != SrcMgr::C_User;
621 : }
622 :
623 : /// isInExternCSystemHeader - Returns if a SourceLocation is in an "extern C"
624 : /// system header.
625 2503: bool isInExternCSystemHeader(SourceLocation Loc) const {
626 2503: return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
627 : }
628 :
629 : //===--------------------------------------------------------------------===//
630 : // Line Table Manipulation Routines
631 : //===--------------------------------------------------------------------===//
632 :
633 : /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
634 : ///
635 : unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
636 :
637 : /// AddLineNote - Add a line note to the line table for the FileID and offset
638 : /// specified by Loc. If FilenameID is -1, it is considered to be
639 : /// unspecified.
640 : void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
641 : void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
642 : bool IsFileEntry, bool IsFileExit,
643 : bool IsSystemHeader, bool IsExternCHeader);
644 :
645 : /// \brief Determine if the source manager has a line table.
646 44: bool hasLineTable() const { return LineTable != 0; }
647 :
648 : /// \brief Retrieve the stored line table.
649 : LineTableInfo &getLineTable();
650 :
651 : //===--------------------------------------------------------------------===//
652 : // Other miscellaneous methods.
653 : //===--------------------------------------------------------------------===//
654 :
655 : /// \brief Get the source location for the given file:line:col triplet.
656 : ///
657 : /// If the source file is included multiple times, the source location will
658 : /// be based upon the first inclusion.
659 : SourceLocation getLocation(const FileEntry *SourceFile,
660 : unsigned Line, unsigned Col) const;
661 :
662 : /// \brief Determines the order of 2 source locations in the translation unit.
663 : ///
664 : /// \returns true if LHS source location comes before RHS, false otherwise.
665 : bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
666 :
667 : // Iterators over FileInfos.
668 : typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
669 : ::const_iterator fileinfo_iterator;
670 3: fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
671 3: fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
672 82: bool hasFileInfo(const FileEntry *File) const {
673 82: return FileInfos.find(File) != FileInfos.end();
674 : }
675 :
676 : /// PrintStats - Print statistics to stderr.
677 : ///
678 : void PrintStats() const;
679 :
680 12992: unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
681 :
682 : // FIXME: Exposing this is a little gross; what we want is a good way
683 : // to iterate the entries that were not defined in a PCH file (or
684 : // any other external source).
685 1: unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
686 :
687 2309214: const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
2309214: branch 1 taken
0: branch 2 not taken
688 2309214: assert(ID < SLocEntryTable.size() && "Invalid id");
1716527: branch 0 taken
592687: branch 1 taken
1714986: branch 3 taken
1541: branch 4 taken
39: branch 6 taken
1714947: branch 7 taken
39: branch 8 taken
2309175: branch 9 taken
689 4025741: if (ExternalSLocEntries &&
690 : ID < SLocEntryLoaded.size() &&
691 : !SLocEntryLoaded[ID])
692 39: ExternalSLocEntries->ReadSLocEntry(ID);
693 2309214: return SLocEntryTable[ID];
694 : }
695 :
696 2283124: const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
697 2283124: return getSLocEntry(FID.ID);
698 : }
699 :
700 138: unsigned getNextOffset() const { return NextOffset; }
701 :
702 : /// \brief Preallocate some number of source location entries, which
703 : /// will be loaded as needed from the given external source.
704 : void PreallocateSLocEntries(ExternalSLocEntrySource *Source,
705 : unsigned NumSLocEntries,
706 : unsigned NextOffset);
707 :
708 : /// \brief Clear out any preallocated source location entries that
709 : /// haven't already been loaded.
710 : void ClearPreallocatedSLocEntries();
711 :
712 : private:
713 : /// isOffsetInFileID - Return true if the specified FileID contains the
714 : /// specified SourceLocation offset. This is a very hot method.
715 630616: inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
716 630616: const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
717 : // If the entry is after the offset, it can't contain it.
0: branch 2 not taken
718 630616: if (SLocOffset < Entry.getOffset()) return false;
719 :
720 : // If this is the last entry than it does. Otherwise, the entry after it
721 : // has to not include it.
89017: branch 1 taken
490477: branch 2 taken
722 579494: if (FID.ID+1 == SLocEntryTable.size()) return true;
723 :
724 490477: return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
725 : }
726 :
727 : /// createFileID - Create a new fileID for the specified ContentCache and
728 : /// include position. This works regardless of whether the ContentCache
729 : /// corresponds to a file or some other input source.
730 : FileID createFileID(const SrcMgr::ContentCache* File,
731 : SourceLocation IncludePos,
732 : SrcMgr::CharacteristicKind DirCharacter,
733 : unsigned PreallocatedID = 0,
734 : unsigned Offset = 0);
735 :
736 : const SrcMgr::ContentCache *
737 : getOrCreateContentCache(const FileEntry *SourceFile);
738 :
739 : /// createMemBufferContentCache - Create a new ContentCache for the specified
740 : /// memory buffer.
741 : const SrcMgr::ContentCache*
742 : createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
743 :
744 : FileID getFileIDSlow(unsigned SLocOffset) const;
745 :
746 : SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const;
747 : SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
748 :
749 : std::pair<FileID, unsigned>
750 : getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
751 : unsigned Offset) const;
752 : std::pair<FileID, unsigned>
753 : getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
754 : unsigned Offset) const;
755 : };
756 :
757 :
758 : } // end namespace clang
759 :
760 : #endif
Generated: 2010-02-10 01:31 by zcov