1 //===- SourceManager.cpp - Track and cache source files -------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the SourceManager interface.
11 //===----------------------------------------------------------------------===//
13 #include "clang/Basic/SourceManager.h"
14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Basic/LLVM.h"
17 #include "clang/Basic/SourceLocation.h"
18 #include "clang/Basic/SourceManagerInternals.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/MapVector.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/Support/Allocator.h"
26 #include "llvm/Support/Capacity.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/Endian.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/FileSystem.h"
31 #include "llvm/Support/MathExtras.h"
32 #include "llvm/Support/MemoryBuffer.h"
33 #include "llvm/Support/Path.h"
34 #include "llvm/Support/raw_ostream.h"
45 using namespace clang
;
46 using namespace SrcMgr
;
47 using llvm::MemoryBuffer
;
49 //===----------------------------------------------------------------------===//
50 // SourceManager Helper Classes
51 //===----------------------------------------------------------------------===//
53 /// getSizeBytesMapped - Returns the number of bytes actually mapped for this
54 /// ContentCache. This can be 0 if the MemBuffer was not actually expanded.
55 unsigned ContentCache::getSizeBytesMapped() const {
56 return Buffer
? Buffer
->getBufferSize() : 0;
59 /// Returns the kind of memory used to back the memory buffer for
60 /// this content cache. This is used for performance analysis.
61 llvm::MemoryBuffer::BufferKind
ContentCache::getMemoryBufferKind() const {
62 if (Buffer
== nullptr) {
63 assert(0 && "Buffer should never be null");
64 return llvm::MemoryBuffer::MemoryBuffer_Malloc
;
66 return Buffer
->getBufferKind();
69 /// getSize - Returns the size of the content encapsulated by this ContentCache.
70 /// This can be the size of the source file or the size of an arbitrary
71 /// scratch buffer. If the ContentCache encapsulates a source file, that
72 /// file is not lazily brought in from disk to satisfy this query.
73 unsigned ContentCache::getSize() const {
74 return Buffer
? (unsigned)Buffer
->getBufferSize()
75 : (unsigned)ContentsEntry
->getSize();
78 const char *ContentCache::getInvalidBOM(StringRef BufStr
) {
79 // If the buffer is valid, check to see if it has a UTF Byte Order Mark
80 // (BOM). We only support UTF-8 with and without a BOM right now. See
81 // http://en.wikipedia.org/wiki/Byte_order_mark for more information.
82 const char *InvalidBOM
=
83 llvm::StringSwitch
<const char *>(BufStr
)
84 .StartsWith(llvm::StringLiteral::withInnerNUL("\x00\x00\xFE\xFF"),
86 .StartsWith(llvm::StringLiteral::withInnerNUL("\xFF\xFE\x00\x00"),
88 .StartsWith("\xFE\xFF", "UTF-16 (BE)")
89 .StartsWith("\xFF\xFE", "UTF-16 (LE)")
90 .StartsWith("\x2B\x2F\x76", "UTF-7")
91 .StartsWith("\xF7\x64\x4C", "UTF-1")
92 .StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC")
93 .StartsWith("\x0E\xFE\xFF", "SCSU")
94 .StartsWith("\xFB\xEE\x28", "BOCU-1")
95 .StartsWith("\x84\x31\x95\x33", "GB-18030")
101 std::optional
<llvm::MemoryBufferRef
>
102 ContentCache::getBufferOrNone(DiagnosticsEngine
&Diag
, FileManager
&FM
,
103 SourceLocation Loc
) const {
104 // Lazily create the Buffer for ContentCaches that wrap files. If we already
105 // computed it, just return what we have.
109 return Buffer
->getMemBufferRef();
113 // Start with the assumption that the buffer is invalid to simplify early
115 IsBufferInvalid
= true;
117 auto BufferOrError
= FM
.getBufferForFile(ContentsEntry
, IsFileVolatile
);
119 // If we were unable to open the file, then we are in an inconsistent
120 // situation where the content cache referenced a file which no longer
121 // exists. Most likely, we were using a stat cache with an invalid entry but
122 // the file could also have been removed during processing. Since we can't
123 // really deal with this situation, just create an empty buffer.
124 if (!BufferOrError
) {
125 if (Diag
.isDiagnosticInFlight())
126 Diag
.SetDelayedDiagnostic(diag::err_cannot_open_file
,
127 ContentsEntry
->getName(),
128 BufferOrError
.getError().message());
130 Diag
.Report(Loc
, diag::err_cannot_open_file
)
131 << ContentsEntry
->getName() << BufferOrError
.getError().message();
136 Buffer
= std::move(*BufferOrError
);
138 // Check that the file's size fits in an 'unsigned' (with room for a
139 // past-the-end value). This is deeply regrettable, but various parts of
140 // Clang (including elsewhere in this file!) use 'unsigned' to represent file
141 // offsets, line numbers, string literal lengths, and so on, and fail
142 // miserably on large source files.
144 // Note: ContentsEntry could be a named pipe, in which case
145 // ContentsEntry::getSize() could have the wrong size. Use
146 // MemoryBuffer::getBufferSize() instead.
147 if (Buffer
->getBufferSize() >= std::numeric_limits
<unsigned>::max()) {
148 if (Diag
.isDiagnosticInFlight())
149 Diag
.SetDelayedDiagnostic(diag::err_file_too_large
,
150 ContentsEntry
->getName());
152 Diag
.Report(Loc
, diag::err_file_too_large
)
153 << ContentsEntry
->getName();
158 // Unless this is a named pipe (in which case we can handle a mismatch),
159 // check that the file's size is the same as in the file entry (which may
160 // have come from a stat cache).
161 if (!ContentsEntry
->isNamedPipe() &&
162 Buffer
->getBufferSize() != (size_t)ContentsEntry
->getSize()) {
163 if (Diag
.isDiagnosticInFlight())
164 Diag
.SetDelayedDiagnostic(diag::err_file_modified
,
165 ContentsEntry
->getName());
167 Diag
.Report(Loc
, diag::err_file_modified
)
168 << ContentsEntry
->getName();
173 // If the buffer is valid, check to see if it has a UTF Byte Order Mark
174 // (BOM). We only support UTF-8 with and without a BOM right now. See
175 // http://en.wikipedia.org/wiki/Byte_order_mark for more information.
176 StringRef BufStr
= Buffer
->getBuffer();
177 const char *InvalidBOM
= getInvalidBOM(BufStr
);
180 Diag
.Report(Loc
, diag::err_unsupported_bom
)
181 << InvalidBOM
<< ContentsEntry
->getName();
185 // Buffer has been validated.
186 IsBufferInvalid
= false;
187 return Buffer
->getMemBufferRef();
190 unsigned LineTableInfo::getLineTableFilenameID(StringRef Name
) {
191 auto IterBool
= FilenameIDs
.try_emplace(Name
, FilenamesByID
.size());
193 FilenamesByID
.push_back(&*IterBool
.first
);
194 return IterBool
.first
->second
;
197 /// Add a line note to the line table that indicates that there is a \#line or
198 /// GNU line marker at the specified FID/Offset location which changes the
199 /// presumed location to LineNo/FilenameID. If EntryExit is 0, then this doesn't
200 /// change the presumed \#include stack. If it is 1, this is a file entry, if
201 /// it is 2 then this is a file exit. FileKind specifies whether this is a
202 /// system header or extern C system header.
203 void LineTableInfo::AddLineNote(FileID FID
, unsigned Offset
, unsigned LineNo
,
204 int FilenameID
, unsigned EntryExit
,
205 SrcMgr::CharacteristicKind FileKind
) {
206 std::vector
<LineEntry
> &Entries
= LineEntries
[FID
];
208 assert((Entries
.empty() || Entries
.back().FileOffset
< Offset
) &&
209 "Adding line entries out of order!");
211 unsigned IncludeOffset
= 0;
212 if (EntryExit
== 1) {
214 IncludeOffset
= Offset
-1;
216 const auto *PrevEntry
= Entries
.empty() ? nullptr : &Entries
.back();
217 if (EntryExit
== 2) {
219 assert(PrevEntry
&& PrevEntry
->IncludeOffset
&&
220 "PPDirectives should have caught case when popping empty include "
222 PrevEntry
= FindNearestLineEntry(FID
, PrevEntry
->IncludeOffset
);
225 IncludeOffset
= PrevEntry
->IncludeOffset
;
226 if (FilenameID
== -1) {
227 // An unspecified FilenameID means use the previous (or containing)
228 // filename if available, or the main source file otherwise.
229 FilenameID
= PrevEntry
->FilenameID
;
234 Entries
.push_back(LineEntry::get(Offset
, LineNo
, FilenameID
, FileKind
,
238 /// FindNearestLineEntry - Find the line entry nearest to FID that is before
239 /// it. If there is no line entry before Offset in FID, return null.
240 const LineEntry
*LineTableInfo::FindNearestLineEntry(FileID FID
,
242 const std::vector
<LineEntry
> &Entries
= LineEntries
[FID
];
243 assert(!Entries
.empty() && "No #line entries for this FID after all!");
245 // It is very common for the query to be after the last #line, check this
247 if (Entries
.back().FileOffset
<= Offset
)
248 return &Entries
.back();
250 // Do a binary search to find the maximal element that is still before Offset.
251 std::vector
<LineEntry
>::const_iterator I
= llvm::upper_bound(Entries
, Offset
);
252 if (I
== Entries
.begin())
257 /// Add a new line entry that has already been encoded into
258 /// the internal representation of the line table.
259 void LineTableInfo::AddEntry(FileID FID
,
260 const std::vector
<LineEntry
> &Entries
) {
261 LineEntries
[FID
] = Entries
;
264 /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
265 unsigned SourceManager::getLineTableFilenameID(StringRef Name
) {
266 return getLineTable().getLineTableFilenameID(Name
);
269 /// AddLineNote - Add a line note to the line table for the FileID and offset
270 /// specified by Loc. If FilenameID is -1, it is considered to be
272 void SourceManager::AddLineNote(SourceLocation Loc
, unsigned LineNo
,
273 int FilenameID
, bool IsFileEntry
,
275 SrcMgr::CharacteristicKind FileKind
) {
276 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedExpansionLoc(Loc
);
278 bool Invalid
= false;
279 const SLocEntry
&Entry
= getSLocEntry(LocInfo
.first
, &Invalid
);
280 if (!Entry
.isFile() || Invalid
)
283 const SrcMgr::FileInfo
&FileInfo
= Entry
.getFile();
285 // Remember that this file has #line directives now if it doesn't already.
286 const_cast<SrcMgr::FileInfo
&>(FileInfo
).setHasLineDirectives();
288 (void) getLineTable();
290 unsigned EntryExit
= 0;
296 LineTable
->AddLineNote(LocInfo
.first
, LocInfo
.second
, LineNo
, FilenameID
,
297 EntryExit
, FileKind
);
300 LineTableInfo
&SourceManager::getLineTable() {
302 LineTable
.reset(new LineTableInfo());
306 //===----------------------------------------------------------------------===//
307 // Private 'Create' methods.
308 //===----------------------------------------------------------------------===//
310 SourceManager::SourceManager(DiagnosticsEngine
&Diag
, FileManager
&FileMgr
,
311 bool UserFilesAreVolatile
)
312 : Diag(Diag
), FileMgr(FileMgr
), UserFilesAreVolatile(UserFilesAreVolatile
) {
314 Diag
.setSourceManager(this);
317 SourceManager::~SourceManager() {
318 // Delete FileEntry objects corresponding to content caches. Since the actual
319 // content cache objects are bump pointer allocated, we just have to run the
320 // dtors, but we call the deallocate method for completeness.
321 for (unsigned i
= 0, e
= MemBufferInfos
.size(); i
!= e
; ++i
) {
322 if (MemBufferInfos
[i
]) {
323 MemBufferInfos
[i
]->~ContentCache();
324 ContentCacheAlloc
.Deallocate(MemBufferInfos
[i
]);
327 for (llvm::DenseMap
<const FileEntry
*, SrcMgr::ContentCache
*>::iterator
328 I
= FileInfos
.begin(), E
= FileInfos
.end(); I
!= E
; ++I
) {
330 I
->second
->~ContentCache();
331 ContentCacheAlloc
.Deallocate(I
->second
);
336 void SourceManager::clearIDTables() {
337 MainFileID
= FileID();
338 LocalSLocEntryTable
.clear();
339 LoadedSLocEntryTable
.clear();
340 SLocEntryLoaded
.clear();
341 LastLineNoFileIDQuery
= FileID();
342 LastLineNoContentCache
= nullptr;
343 LastFileIDLookup
= FileID();
348 // Use up FileID #0 as an invalid expansion.
350 CurrentLoadedOffset
= MaxLoadedOffset
;
351 createExpansionLoc(SourceLocation(), SourceLocation(), SourceLocation(), 1);
354 bool SourceManager::isMainFile(const FileEntry
&SourceFile
) {
355 assert(MainFileID
.isValid() && "expected initialized SourceManager");
356 if (auto *FE
= getFileEntryForID(MainFileID
))
357 return FE
->getUID() == SourceFile
.getUID();
361 void SourceManager::initializeForReplay(const SourceManager
&Old
) {
362 assert(MainFileID
.isInvalid() && "expected uninitialized SourceManager");
364 auto CloneContentCache
= [&](const ContentCache
*Cache
) -> ContentCache
* {
365 auto *Clone
= new (ContentCacheAlloc
.Allocate
<ContentCache
>()) ContentCache
;
366 Clone
->OrigEntry
= Cache
->OrigEntry
;
367 Clone
->ContentsEntry
= Cache
->ContentsEntry
;
368 Clone
->BufferOverridden
= Cache
->BufferOverridden
;
369 Clone
->IsFileVolatile
= Cache
->IsFileVolatile
;
370 Clone
->IsTransient
= Cache
->IsTransient
;
371 Clone
->setUnownedBuffer(Cache
->getBufferIfLoaded());
375 // Ensure all SLocEntries are loaded from the external source.
376 for (unsigned I
= 0, N
= Old
.LoadedSLocEntryTable
.size(); I
!= N
; ++I
)
377 if (!Old
.SLocEntryLoaded
[I
])
378 Old
.loadSLocEntry(I
, nullptr);
380 // Inherit any content cache data from the old source manager.
381 for (auto &FileInfo
: Old
.FileInfos
) {
382 SrcMgr::ContentCache
*&Slot
= FileInfos
[FileInfo
.first
];
385 Slot
= CloneContentCache(FileInfo
.second
);
389 ContentCache
&SourceManager::getOrCreateContentCache(FileEntryRef FileEnt
,
391 // Do we already have information about this file?
392 ContentCache
*&Entry
= FileInfos
[FileEnt
];
396 // Nope, create a new Cache entry.
397 Entry
= ContentCacheAlloc
.Allocate
<ContentCache
>();
399 if (OverriddenFilesInfo
) {
400 // If the file contents are overridden with contents from another file,
401 // pass that file to ContentCache.
402 auto overI
= OverriddenFilesInfo
->OverriddenFiles
.find(FileEnt
);
403 if (overI
== OverriddenFilesInfo
->OverriddenFiles
.end())
404 new (Entry
) ContentCache(FileEnt
);
406 new (Entry
) ContentCache(OverridenFilesKeepOriginalName
? FileEnt
410 new (Entry
) ContentCache(FileEnt
);
413 Entry
->IsFileVolatile
= UserFilesAreVolatile
&& !isSystemFile
;
414 Entry
->IsTransient
= FilesAreTransient
;
415 Entry
->BufferOverridden
|= FileEnt
.isNamedPipe();
420 /// Create a new ContentCache for the specified memory buffer.
421 /// This does no caching.
422 ContentCache
&SourceManager::createMemBufferContentCache(
423 std::unique_ptr
<llvm::MemoryBuffer
> Buffer
) {
424 // Add a new ContentCache to the MemBufferInfos list and return it.
425 ContentCache
*Entry
= ContentCacheAlloc
.Allocate
<ContentCache
>();
426 new (Entry
) ContentCache();
427 MemBufferInfos
.push_back(Entry
);
428 Entry
->setBuffer(std::move(Buffer
));
432 const SrcMgr::SLocEntry
&SourceManager::loadSLocEntry(unsigned Index
,
433 bool *Invalid
) const {
434 assert(!SLocEntryLoaded
[Index
]);
435 if (ExternalSLocEntries
->ReadSLocEntry(-(static_cast<int>(Index
) + 2))) {
438 // If the file of the SLocEntry changed we could still have loaded it.
439 if (!SLocEntryLoaded
[Index
]) {
440 // Try to recover; create a SLocEntry so the rest of clang can handle it.
441 if (!FakeSLocEntryForRecovery
)
442 FakeSLocEntryForRecovery
= std::make_unique
<SLocEntry
>(SLocEntry::get(
443 0, FileInfo::get(SourceLocation(), getFakeContentCacheForRecovery(),
444 SrcMgr::C_User
, "")));
445 return *FakeSLocEntryForRecovery
;
449 return LoadedSLocEntryTable
[Index
];
452 std::pair
<int, SourceLocation::UIntTy
>
453 SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries
,
454 SourceLocation::UIntTy TotalSize
) {
455 assert(ExternalSLocEntries
&& "Don't have an external sloc source");
456 // Make sure we're not about to run out of source locations.
457 if (CurrentLoadedOffset
< TotalSize
||
458 CurrentLoadedOffset
- TotalSize
< NextLocalOffset
) {
459 return std::make_pair(0, 0);
461 LoadedSLocEntryTable
.resize(LoadedSLocEntryTable
.size() + NumSLocEntries
);
462 SLocEntryLoaded
.resize(LoadedSLocEntryTable
.size());
463 CurrentLoadedOffset
-= TotalSize
;
464 int ID
= LoadedSLocEntryTable
.size();
465 return std::make_pair(-ID
- 1, CurrentLoadedOffset
);
468 /// As part of recovering from missing or changed content, produce a
469 /// fake, non-empty buffer.
470 llvm::MemoryBufferRef
SourceManager::getFakeBufferForRecovery() const {
471 if (!FakeBufferForRecovery
)
472 FakeBufferForRecovery
=
473 llvm::MemoryBuffer::getMemBuffer("<<<INVALID BUFFER>>");
475 return *FakeBufferForRecovery
;
478 /// As part of recovering from missing or changed content, produce a
479 /// fake content cache.
480 SrcMgr::ContentCache
&SourceManager::getFakeContentCacheForRecovery() const {
481 if (!FakeContentCacheForRecovery
) {
482 FakeContentCacheForRecovery
= std::make_unique
<SrcMgr::ContentCache
>();
483 FakeContentCacheForRecovery
->setUnownedBuffer(getFakeBufferForRecovery());
485 return *FakeContentCacheForRecovery
;
488 /// Returns the previous in-order FileID or an invalid FileID if there
489 /// is no previous one.
490 FileID
SourceManager::getPreviousFileID(FileID FID
) const {
501 } else if (unsigned(-(ID
-1) - 2) >= LoadedSLocEntryTable
.size()) {
505 return FileID::get(ID
-1);
508 /// Returns the next in-order FileID or an invalid FileID if there is
510 FileID
SourceManager::getNextFileID(FileID FID
) const {
516 if (unsigned(ID
+1) >= local_sloc_entry_size())
518 } else if (ID
+1 >= -1) {
522 return FileID::get(ID
+1);
525 //===----------------------------------------------------------------------===//
526 // Methods to create new FileID's and macro expansions.
527 //===----------------------------------------------------------------------===//
529 /// Create a new FileID that represents the specified file
530 /// being \#included from the specified IncludePosition.
532 /// This translates NULL into standard input.
533 FileID
SourceManager::createFileID(const FileEntry
*SourceFile
,
534 SourceLocation IncludePos
,
535 SrcMgr::CharacteristicKind FileCharacter
,
537 SourceLocation::UIntTy LoadedOffset
) {
538 return createFileID(SourceFile
->getLastRef(), IncludePos
, FileCharacter
,
539 LoadedID
, LoadedOffset
);
542 FileID
SourceManager::createFileID(FileEntryRef SourceFile
,
543 SourceLocation IncludePos
,
544 SrcMgr::CharacteristicKind FileCharacter
,
546 SourceLocation::UIntTy LoadedOffset
) {
547 SrcMgr::ContentCache
&IR
= getOrCreateContentCache(SourceFile
,
548 isSystem(FileCharacter
));
550 // If this is a named pipe, immediately load the buffer to ensure subsequent
551 // calls to ContentCache::getSize() are accurate.
552 if (IR
.ContentsEntry
->isNamedPipe())
553 (void)IR
.getBufferOrNone(Diag
, getFileManager(), SourceLocation());
555 return createFileIDImpl(IR
, SourceFile
.getName(), IncludePos
, FileCharacter
,
556 LoadedID
, LoadedOffset
);
559 /// Create a new FileID that represents the specified memory buffer.
561 /// This does no caching of the buffer and takes ownership of the
562 /// MemoryBuffer, so only pass a MemoryBuffer to this once.
563 FileID
SourceManager::createFileID(std::unique_ptr
<llvm::MemoryBuffer
> Buffer
,
564 SrcMgr::CharacteristicKind FileCharacter
,
566 SourceLocation::UIntTy LoadedOffset
,
567 SourceLocation IncludeLoc
) {
568 StringRef Name
= Buffer
->getBufferIdentifier();
569 return createFileIDImpl(createMemBufferContentCache(std::move(Buffer
)), Name
,
570 IncludeLoc
, FileCharacter
, LoadedID
, LoadedOffset
);
573 /// Create a new FileID that represents the specified memory buffer.
575 /// This does not take ownership of the MemoryBuffer. The memory buffer must
576 /// outlive the SourceManager.
577 FileID
SourceManager::createFileID(const llvm::MemoryBufferRef
&Buffer
,
578 SrcMgr::CharacteristicKind FileCharacter
,
580 SourceLocation::UIntTy LoadedOffset
,
581 SourceLocation IncludeLoc
) {
582 return createFileID(llvm::MemoryBuffer::getMemBuffer(Buffer
), FileCharacter
,
583 LoadedID
, LoadedOffset
, IncludeLoc
);
586 /// Get the FileID for \p SourceFile if it exists. Otherwise, create a
587 /// new FileID for the \p SourceFile.
589 SourceManager::getOrCreateFileID(const FileEntry
*SourceFile
,
590 SrcMgr::CharacteristicKind FileCharacter
) {
591 FileID ID
= translateFile(SourceFile
);
592 return ID
.isValid() ? ID
: createFileID(SourceFile
, SourceLocation(),
596 /// createFileID - Create a new FileID for the specified ContentCache and
597 /// include position. This works regardless of whether the ContentCache
598 /// corresponds to a file or some other input source.
599 FileID
SourceManager::createFileIDImpl(ContentCache
&File
, StringRef Filename
,
600 SourceLocation IncludePos
,
601 SrcMgr::CharacteristicKind FileCharacter
,
603 SourceLocation::UIntTy LoadedOffset
) {
605 assert(LoadedID
!= -1 && "Loading sentinel FileID");
606 unsigned Index
= unsigned(-LoadedID
) - 2;
607 assert(Index
< LoadedSLocEntryTable
.size() && "FileID out of range");
608 assert(!SLocEntryLoaded
[Index
] && "FileID already loaded");
609 LoadedSLocEntryTable
[Index
] = SLocEntry::get(
610 LoadedOffset
, FileInfo::get(IncludePos
, File
, FileCharacter
, Filename
));
611 SLocEntryLoaded
[Index
] = true;
612 return FileID::get(LoadedID
);
614 unsigned FileSize
= File
.getSize();
615 if (!(NextLocalOffset
+ FileSize
+ 1 > NextLocalOffset
&&
616 NextLocalOffset
+ FileSize
+ 1 <= CurrentLoadedOffset
)) {
617 Diag
.Report(IncludePos
, diag::err_include_too_large
);
618 noteSLocAddressSpaceUsage(Diag
);
621 LocalSLocEntryTable
.push_back(
622 SLocEntry::get(NextLocalOffset
,
623 FileInfo::get(IncludePos
, File
, FileCharacter
, Filename
)));
624 // We do a +1 here because we want a SourceLocation that means "the end of the
625 // file", e.g. for the "no newline at the end of the file" diagnostic.
626 NextLocalOffset
+= FileSize
+ 1;
628 // Set LastFileIDLookup to the newly created file. The next getFileID call is
629 // almost guaranteed to be from that file.
630 FileID FID
= FileID::get(LocalSLocEntryTable
.size()-1);
631 return LastFileIDLookup
= FID
;
634 SourceLocation
SourceManager::createMacroArgExpansionLoc(
635 SourceLocation SpellingLoc
, SourceLocation ExpansionLoc
, unsigned Length
) {
636 ExpansionInfo Info
= ExpansionInfo::createForMacroArg(SpellingLoc
,
638 return createExpansionLocImpl(Info
, Length
);
641 SourceLocation
SourceManager::createExpansionLoc(
642 SourceLocation SpellingLoc
, SourceLocation ExpansionLocStart
,
643 SourceLocation ExpansionLocEnd
, unsigned Length
,
644 bool ExpansionIsTokenRange
, int LoadedID
,
645 SourceLocation::UIntTy LoadedOffset
) {
646 ExpansionInfo Info
= ExpansionInfo::create(
647 SpellingLoc
, ExpansionLocStart
, ExpansionLocEnd
, ExpansionIsTokenRange
);
648 return createExpansionLocImpl(Info
, Length
, LoadedID
, LoadedOffset
);
651 SourceLocation
SourceManager::createTokenSplitLoc(SourceLocation Spelling
,
652 SourceLocation TokenStart
,
653 SourceLocation TokenEnd
) {
654 assert(getFileID(TokenStart
) == getFileID(TokenEnd
) &&
655 "token spans multiple files");
656 return createExpansionLocImpl(
657 ExpansionInfo::createForTokenSplit(Spelling
, TokenStart
, TokenEnd
),
658 TokenEnd
.getOffset() - TokenStart
.getOffset());
662 SourceManager::createExpansionLocImpl(const ExpansionInfo
&Info
,
663 unsigned Length
, int LoadedID
,
664 SourceLocation::UIntTy LoadedOffset
) {
666 assert(LoadedID
!= -1 && "Loading sentinel FileID");
667 unsigned Index
= unsigned(-LoadedID
) - 2;
668 assert(Index
< LoadedSLocEntryTable
.size() && "FileID out of range");
669 assert(!SLocEntryLoaded
[Index
] && "FileID already loaded");
670 LoadedSLocEntryTable
[Index
] = SLocEntry::get(LoadedOffset
, Info
);
671 SLocEntryLoaded
[Index
] = true;
672 return SourceLocation::getMacroLoc(LoadedOffset
);
674 LocalSLocEntryTable
.push_back(SLocEntry::get(NextLocalOffset
, Info
));
675 // FIXME: Produce a proper diagnostic for this case.
676 assert(NextLocalOffset
+ Length
+ 1 > NextLocalOffset
&&
677 NextLocalOffset
+ Length
+ 1 <= CurrentLoadedOffset
&&
678 "Ran out of source locations!");
679 // See createFileID for that +1.
680 NextLocalOffset
+= Length
+ 1;
681 return SourceLocation::getMacroLoc(NextLocalOffset
- (Length
+ 1));
684 std::optional
<llvm::MemoryBufferRef
>
685 SourceManager::getMemoryBufferForFileOrNone(const FileEntry
*File
) {
686 SrcMgr::ContentCache
&IR
= getOrCreateContentCache(File
->getLastRef());
687 return IR
.getBufferOrNone(Diag
, getFileManager(), SourceLocation());
690 void SourceManager::overrideFileContents(
691 const FileEntry
*SourceFile
, std::unique_ptr
<llvm::MemoryBuffer
> Buffer
) {
692 SrcMgr::ContentCache
&IR
= getOrCreateContentCache(SourceFile
->getLastRef());
694 IR
.setBuffer(std::move(Buffer
));
695 IR
.BufferOverridden
= true;
697 getOverriddenFilesInfo().OverriddenFilesWithBuffer
.insert(SourceFile
);
700 void SourceManager::overrideFileContents(const FileEntry
*SourceFile
,
701 FileEntryRef NewFile
) {
702 assert(SourceFile
->getSize() == NewFile
.getSize() &&
703 "Different sizes, use the FileManager to create a virtual file with "
705 assert(FileInfos
.count(SourceFile
) == 0 &&
706 "This function should be called at the initialization stage, before "
707 "any parsing occurs.");
708 // FileEntryRef is not default-constructible.
709 auto Pair
= getOverriddenFilesInfo().OverriddenFiles
.insert(
710 std::make_pair(SourceFile
, NewFile
));
712 Pair
.first
->second
= NewFile
;
716 SourceManager::bypassFileContentsOverride(FileEntryRef File
) {
717 assert(isFileOverridden(&File
.getFileEntry()));
718 OptionalFileEntryRef BypassFile
= FileMgr
.getBypassFile(File
);
720 // If the file can't be found in the FS, give up.
724 (void)getOrCreateContentCache(*BypassFile
);
728 void SourceManager::setFileIsTransient(const FileEntry
*File
) {
729 getOrCreateContentCache(File
->getLastRef()).IsTransient
= true;
732 std::optional
<StringRef
>
733 SourceManager::getNonBuiltinFilenameForID(FileID FID
) const {
734 if (const SrcMgr::SLocEntry
*Entry
= getSLocEntryForFile(FID
))
735 if (Entry
->getFile().getContentCache().OrigEntry
)
736 return Entry
->getFile().getName();
740 StringRef
SourceManager::getBufferData(FileID FID
, bool *Invalid
) const {
741 auto B
= getBufferDataOrNone(FID
);
744 return B
? *B
: "<<<<<INVALID SOURCE LOCATION>>>>>";
747 std::optional
<StringRef
>
748 SourceManager::getBufferDataIfLoaded(FileID FID
) const {
749 if (const SrcMgr::SLocEntry
*Entry
= getSLocEntryForFile(FID
))
750 return Entry
->getFile().getContentCache().getBufferDataIfLoaded();
754 std::optional
<StringRef
> SourceManager::getBufferDataOrNone(FileID FID
) const {
755 if (const SrcMgr::SLocEntry
*Entry
= getSLocEntryForFile(FID
))
756 if (auto B
= Entry
->getFile().getContentCache().getBufferOrNone(
757 Diag
, getFileManager(), SourceLocation()))
758 return B
->getBuffer();
762 //===----------------------------------------------------------------------===//
763 // SourceLocation manipulation methods.
764 //===----------------------------------------------------------------------===//
766 /// Return the FileID for a SourceLocation.
768 /// This is the cache-miss path of getFileID. Not as hot as that function, but
769 /// still very important. It is responsible for finding the entry in the
770 /// SLocEntry tables that contains the specified location.
771 FileID
SourceManager::getFileIDSlow(SourceLocation::UIntTy SLocOffset
) const {
773 return FileID::get(0);
775 // Now it is time to search for the correct file. See where the SLocOffset
776 // sits in the global view and consult local or loaded buffers for it.
777 if (SLocOffset
< NextLocalOffset
)
778 return getFileIDLocal(SLocOffset
);
779 return getFileIDLoaded(SLocOffset
);
782 /// Return the FileID for a SourceLocation with a low offset.
784 /// This function knows that the SourceLocation is in a local buffer, not a
786 FileID
SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset
) const {
787 assert(SLocOffset
< NextLocalOffset
&& "Bad function choice");
789 // After the first and second level caches, I see two common sorts of
790 // behavior: 1) a lot of searched FileID's are "near" the cached file
791 // location or are "near" the cached expansion location. 2) others are just
792 // completely random and may be a very long way away.
794 // To handle this, we do a linear search for up to 8 steps to catch #1 quickly
795 // then we fall back to a less cache efficient, but more scalable, binary
796 // search to find the location.
798 // See if this is near the file point - worst case we start scanning from the
799 // most newly created FileID.
801 // LessIndex - This is the lower bound of the range that we're searching.
802 // We know that the offset corresponding to the FileID is less than
804 unsigned LessIndex
= 0;
805 // upper bound of the search range.
806 unsigned GreaterIndex
= LocalSLocEntryTable
.size();
807 if (LastFileIDLookup
.ID
>= 0) {
808 // Use the LastFileIDLookup to prune the search space.
809 if (LocalSLocEntryTable
[LastFileIDLookup
.ID
].getOffset() < SLocOffset
)
810 LessIndex
= LastFileIDLookup
.ID
;
812 GreaterIndex
= LastFileIDLookup
.ID
;
815 // Find the FileID that contains this.
816 unsigned NumProbes
= 0;
819 assert(GreaterIndex
< LocalSLocEntryTable
.size());
820 if (LocalSLocEntryTable
[GreaterIndex
].getOffset() <= SLocOffset
) {
821 FileID Res
= FileID::get(int(GreaterIndex
));
822 // Remember it. We have good locality across FileID lookups.
823 LastFileIDLookup
= Res
;
824 NumLinearScans
+= NumProbes
+1;
827 if (++NumProbes
== 8)
833 unsigned MiddleIndex
= (GreaterIndex
-LessIndex
)/2+LessIndex
;
834 SourceLocation::UIntTy MidOffset
=
835 getLocalSLocEntry(MiddleIndex
).getOffset();
839 // If the offset of the midpoint is too large, chop the high side of the
840 // range to the midpoint.
841 if (MidOffset
> SLocOffset
) {
842 GreaterIndex
= MiddleIndex
;
846 // If the middle index contains the value, succeed and return.
847 if (MiddleIndex
+ 1 == LocalSLocEntryTable
.size() ||
848 SLocOffset
< getLocalSLocEntry(MiddleIndex
+ 1).getOffset()) {
849 FileID Res
= FileID::get(MiddleIndex
);
851 // Remember it. We have good locality across FileID lookups.
852 LastFileIDLookup
= Res
;
853 NumBinaryProbes
+= NumProbes
;
857 // Otherwise, move the low-side up to the middle index.
858 LessIndex
= MiddleIndex
;
862 /// Return the FileID for a SourceLocation with a high offset.
864 /// This function knows that the SourceLocation is in a loaded buffer, not a
866 FileID
SourceManager::getFileIDLoaded(SourceLocation::UIntTy SLocOffset
) const {
867 if (SLocOffset
< CurrentLoadedOffset
) {
868 assert(0 && "Invalid SLocOffset or bad function choice");
872 // Essentially the same as the local case, but the loaded array is sorted
873 // in the other direction (decreasing order).
874 // GreaterIndex is the one where the offset is greater, which is actually a
876 unsigned GreaterIndex
= 0;
877 unsigned LessIndex
= LoadedSLocEntryTable
.size();
878 if (LastFileIDLookup
.ID
< 0) {
879 // Prune the search space.
880 int LastID
= LastFileIDLookup
.ID
;
881 if (getLoadedSLocEntryByID(LastID
).getOffset() > SLocOffset
)
883 (-LastID
- 2) + 1; // Exclude LastID, else we would have hit the cache
885 LessIndex
= -LastID
- 2;
888 // First do a linear scan from the last lookup position, if possible.
890 bool Invalid
= false;
891 for (NumProbes
= 0; NumProbes
< 8; ++NumProbes
, ++GreaterIndex
) {
892 // Make sure the entry is loaded!
893 const SrcMgr::SLocEntry
&E
= getLoadedSLocEntry(GreaterIndex
, &Invalid
);
895 return FileID(); // invalid entry.
896 if (E
.getOffset() <= SLocOffset
) {
897 FileID Res
= FileID::get(-int(GreaterIndex
) - 2);
898 LastFileIDLookup
= Res
;
899 NumLinearScans
+= NumProbes
+ 1;
904 // Linear scan failed. Do the binary search.
908 unsigned MiddleIndex
= (LessIndex
- GreaterIndex
) / 2 + GreaterIndex
;
909 const SrcMgr::SLocEntry
&E
= getLoadedSLocEntry(MiddleIndex
, &Invalid
);
911 return FileID(); // invalid entry.
913 if (E
.getOffset() > SLocOffset
) {
914 if (GreaterIndex
== MiddleIndex
) {
915 assert(0 && "binary search missed the entry");
918 GreaterIndex
= MiddleIndex
;
922 if (isOffsetInFileID(FileID::get(-int(MiddleIndex
) - 2), SLocOffset
)) {
923 FileID Res
= FileID::get(-int(MiddleIndex
) - 2);
924 LastFileIDLookup
= Res
;
925 NumBinaryProbes
+= NumProbes
;
929 if (LessIndex
== MiddleIndex
) {
930 assert(0 && "binary search missed the entry");
933 LessIndex
= MiddleIndex
;
937 SourceLocation
SourceManager::
938 getExpansionLocSlowCase(SourceLocation Loc
) const {
940 // Note: If Loc indicates an offset into a token that came from a macro
941 // expansion (e.g. the 5th character of the token) we do not want to add
942 // this offset when going to the expansion location. The expansion
943 // location is the macro invocation, which the offset has nothing to do
944 // with. This is unlike when we get the spelling loc, because the offset
945 // directly correspond to the token whose spelling we're inspecting.
946 Loc
= getSLocEntry(getFileID(Loc
)).getExpansion().getExpansionLocStart();
947 } while (!Loc
.isFileID());
952 SourceLocation
SourceManager::getSpellingLocSlowCase(SourceLocation Loc
) const {
954 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedLoc(Loc
);
955 Loc
= getSLocEntry(LocInfo
.first
).getExpansion().getSpellingLoc();
956 Loc
= Loc
.getLocWithOffset(LocInfo
.second
);
957 } while (!Loc
.isFileID());
961 SourceLocation
SourceManager::getFileLocSlowCase(SourceLocation Loc
) const {
963 if (isMacroArgExpansion(Loc
))
964 Loc
= getImmediateSpellingLoc(Loc
);
966 Loc
= getImmediateExpansionRange(Loc
).getBegin();
967 } while (!Loc
.isFileID());
972 std::pair
<FileID
, unsigned>
973 SourceManager::getDecomposedExpansionLocSlowCase(
974 const SrcMgr::SLocEntry
*E
) const {
975 // If this is an expansion record, walk through all the expansion points.
980 Loc
= E
->getExpansion().getExpansionLocStart();
982 FID
= getFileID(Loc
);
983 E
= &getSLocEntry(FID
);
984 Offset
= Loc
.getOffset()-E
->getOffset();
985 } while (!Loc
.isFileID());
987 return std::make_pair(FID
, Offset
);
990 std::pair
<FileID
, unsigned>
991 SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry
*E
,
992 unsigned Offset
) const {
993 // If this is an expansion record, walk through all the expansion points.
997 Loc
= E
->getExpansion().getSpellingLoc();
998 Loc
= Loc
.getLocWithOffset(Offset
);
1000 FID
= getFileID(Loc
);
1001 E
= &getSLocEntry(FID
);
1002 Offset
= Loc
.getOffset()-E
->getOffset();
1003 } while (!Loc
.isFileID());
1005 return std::make_pair(FID
, Offset
);
1008 /// getImmediateSpellingLoc - Given a SourceLocation object, return the
1009 /// spelling location referenced by the ID. This is the first level down
1010 /// towards the place where the characters that make up the lexed token can be
1011 /// found. This should not generally be used by clients.
1012 SourceLocation
SourceManager::getImmediateSpellingLoc(SourceLocation Loc
) const{
1013 if (Loc
.isFileID()) return Loc
;
1014 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedLoc(Loc
);
1015 Loc
= getSLocEntry(LocInfo
.first
).getExpansion().getSpellingLoc();
1016 return Loc
.getLocWithOffset(LocInfo
.second
);
1019 /// Return the filename of the file containing a SourceLocation.
1020 StringRef
SourceManager::getFilename(SourceLocation SpellingLoc
) const {
1021 if (const FileEntry
*F
= getFileEntryForID(getFileID(SpellingLoc
)))
1022 return F
->getName();
1026 /// getImmediateExpansionRange - Loc is required to be an expansion location.
1027 /// Return the start/end of the expansion information.
1029 SourceManager::getImmediateExpansionRange(SourceLocation Loc
) const {
1030 assert(Loc
.isMacroID() && "Not a macro expansion loc!");
1031 const ExpansionInfo
&Expansion
= getSLocEntry(getFileID(Loc
)).getExpansion();
1032 return Expansion
.getExpansionLocRange();
1035 SourceLocation
SourceManager::getTopMacroCallerLoc(SourceLocation Loc
) const {
1036 while (isMacroArgExpansion(Loc
))
1037 Loc
= getImmediateSpellingLoc(Loc
);
1041 /// getExpansionRange - Given a SourceLocation object, return the range of
1042 /// tokens covered by the expansion in the ultimate file.
1043 CharSourceRange
SourceManager::getExpansionRange(SourceLocation Loc
) const {
1045 return CharSourceRange(SourceRange(Loc
, Loc
), true);
1047 CharSourceRange Res
= getImmediateExpansionRange(Loc
);
1049 // Fully resolve the start and end locations to their ultimate expansion
1051 while (!Res
.getBegin().isFileID())
1052 Res
.setBegin(getImmediateExpansionRange(Res
.getBegin()).getBegin());
1053 while (!Res
.getEnd().isFileID()) {
1054 CharSourceRange EndRange
= getImmediateExpansionRange(Res
.getEnd());
1055 Res
.setEnd(EndRange
.getEnd());
1056 Res
.setTokenRange(EndRange
.isTokenRange());
1061 bool SourceManager::isMacroArgExpansion(SourceLocation Loc
,
1062 SourceLocation
*StartLoc
) const {
1063 if (!Loc
.isMacroID()) return false;
1065 FileID FID
= getFileID(Loc
);
1066 const SrcMgr::ExpansionInfo
&Expansion
= getSLocEntry(FID
).getExpansion();
1067 if (!Expansion
.isMacroArgExpansion()) return false;
1070 *StartLoc
= Expansion
.getExpansionLocStart();
1074 bool SourceManager::isMacroBodyExpansion(SourceLocation Loc
) const {
1075 if (!Loc
.isMacroID()) return false;
1077 FileID FID
= getFileID(Loc
);
1078 const SrcMgr::ExpansionInfo
&Expansion
= getSLocEntry(FID
).getExpansion();
1079 return Expansion
.isMacroBodyExpansion();
1082 bool SourceManager::isAtStartOfImmediateMacroExpansion(SourceLocation Loc
,
1083 SourceLocation
*MacroBegin
) const {
1084 assert(Loc
.isValid() && Loc
.isMacroID() && "Expected a valid macro loc");
1086 std::pair
<FileID
, unsigned> DecompLoc
= getDecomposedLoc(Loc
);
1087 if (DecompLoc
.second
> 0)
1088 return false; // Does not point at the start of expansion range.
1090 bool Invalid
= false;
1091 const SrcMgr::ExpansionInfo
&ExpInfo
=
1092 getSLocEntry(DecompLoc
.first
, &Invalid
).getExpansion();
1095 SourceLocation ExpLoc
= ExpInfo
.getExpansionLocStart();
1097 if (ExpInfo
.isMacroArgExpansion()) {
1098 // For macro argument expansions, check if the previous FileID is part of
1099 // the same argument expansion, in which case this Loc is not at the
1100 // beginning of the expansion.
1101 FileID PrevFID
= getPreviousFileID(DecompLoc
.first
);
1102 if (!PrevFID
.isInvalid()) {
1103 const SrcMgr::SLocEntry
&PrevEntry
= getSLocEntry(PrevFID
, &Invalid
);
1106 if (PrevEntry
.isExpansion() &&
1107 PrevEntry
.getExpansion().getExpansionLocStart() == ExpLoc
)
1113 *MacroBegin
= ExpLoc
;
1117 bool SourceManager::isAtEndOfImmediateMacroExpansion(SourceLocation Loc
,
1118 SourceLocation
*MacroEnd
) const {
1119 assert(Loc
.isValid() && Loc
.isMacroID() && "Expected a valid macro loc");
1121 FileID FID
= getFileID(Loc
);
1122 SourceLocation NextLoc
= Loc
.getLocWithOffset(1);
1123 if (isInFileID(NextLoc
, FID
))
1124 return false; // Does not point at the end of expansion range.
1126 bool Invalid
= false;
1127 const SrcMgr::ExpansionInfo
&ExpInfo
=
1128 getSLocEntry(FID
, &Invalid
).getExpansion();
1132 if (ExpInfo
.isMacroArgExpansion()) {
1133 // For macro argument expansions, check if the next FileID is part of the
1134 // same argument expansion, in which case this Loc is not at the end of the
1136 FileID NextFID
= getNextFileID(FID
);
1137 if (!NextFID
.isInvalid()) {
1138 const SrcMgr::SLocEntry
&NextEntry
= getSLocEntry(NextFID
, &Invalid
);
1141 if (NextEntry
.isExpansion() &&
1142 NextEntry
.getExpansion().getExpansionLocStart() ==
1143 ExpInfo
.getExpansionLocStart())
1149 *MacroEnd
= ExpInfo
.getExpansionLocEnd();
1153 //===----------------------------------------------------------------------===//
1154 // Queries about the code at a SourceLocation.
1155 //===----------------------------------------------------------------------===//
1157 /// getCharacterData - Return a pointer to the start of the specified location
1158 /// in the appropriate MemoryBuffer.
1159 const char *SourceManager::getCharacterData(SourceLocation SL
,
1160 bool *Invalid
) const {
1161 // Note that this is a hot function in the getSpelling() path, which is
1162 // heavily used by -E mode.
1163 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedSpellingLoc(SL
);
1165 // Note that calling 'getBuffer()' may lazily page in a source file.
1166 bool CharDataInvalid
= false;
1167 const SLocEntry
&Entry
= getSLocEntry(LocInfo
.first
, &CharDataInvalid
);
1168 if (CharDataInvalid
|| !Entry
.isFile()) {
1172 return "<<<<INVALID BUFFER>>>>";
1174 std::optional
<llvm::MemoryBufferRef
> Buffer
=
1175 Entry
.getFile().getContentCache().getBufferOrNone(Diag
, getFileManager(),
1179 return Buffer
? Buffer
->getBufferStart() + LocInfo
.second
1180 : "<<<<INVALID BUFFER>>>>";
1183 /// getColumnNumber - Return the column # for the specified file position.
1184 /// this is significantly cheaper to compute than the line number.
1185 unsigned SourceManager::getColumnNumber(FileID FID
, unsigned FilePos
,
1186 bool *Invalid
) const {
1187 std::optional
<llvm::MemoryBufferRef
> MemBuf
= getBufferOrNone(FID
);
1194 // It is okay to request a position just past the end of the buffer.
1195 if (FilePos
> MemBuf
->getBufferSize()) {
1201 const char *Buf
= MemBuf
->getBufferStart();
1202 // See if we just calculated the line number for this FilePos and can use
1203 // that to lookup the start of the line instead of searching for it.
1204 if (LastLineNoFileIDQuery
== FID
&& LastLineNoContentCache
->SourceLineCache
&&
1205 LastLineNoResult
< LastLineNoContentCache
->SourceLineCache
.size()) {
1206 const unsigned *SourceLineCache
=
1207 LastLineNoContentCache
->SourceLineCache
.begin();
1208 unsigned LineStart
= SourceLineCache
[LastLineNoResult
- 1];
1209 unsigned LineEnd
= SourceLineCache
[LastLineNoResult
];
1210 if (FilePos
>= LineStart
&& FilePos
< LineEnd
) {
1211 // LineEnd is the LineStart of the next line.
1212 // A line ends with separator LF or CR+LF on Windows.
1213 // FilePos might point to the last separator,
1214 // but we need a column number at most 1 + the last column.
1215 if (FilePos
+ 1 == LineEnd
&& FilePos
> LineStart
) {
1216 if (Buf
[FilePos
- 1] == '\r' || Buf
[FilePos
- 1] == '\n')
1219 return FilePos
- LineStart
+ 1;
1223 unsigned LineStart
= FilePos
;
1224 while (LineStart
&& Buf
[LineStart
-1] != '\n' && Buf
[LineStart
-1] != '\r')
1226 return FilePos
-LineStart
+1;
1229 // isInvalid - Return the result of calling loc.isInvalid(), and
1230 // if Invalid is not null, set its value to same.
1231 template<typename LocType
>
1232 static bool isInvalid(LocType Loc
, bool *Invalid
) {
1233 bool MyInvalid
= Loc
.isInvalid();
1235 *Invalid
= MyInvalid
;
1239 unsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc
,
1240 bool *Invalid
) const {
1241 if (isInvalid(Loc
, Invalid
)) return 0;
1242 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedSpellingLoc(Loc
);
1243 return getColumnNumber(LocInfo
.first
, LocInfo
.second
, Invalid
);
1246 unsigned SourceManager::getExpansionColumnNumber(SourceLocation Loc
,
1247 bool *Invalid
) const {
1248 if (isInvalid(Loc
, Invalid
)) return 0;
1249 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedExpansionLoc(Loc
);
1250 return getColumnNumber(LocInfo
.first
, LocInfo
.second
, Invalid
);
1253 unsigned SourceManager::getPresumedColumnNumber(SourceLocation Loc
,
1254 bool *Invalid
) const {
1255 PresumedLoc PLoc
= getPresumedLoc(Loc
);
1256 if (isInvalid(PLoc
, Invalid
)) return 0;
1257 return PLoc
.getColumn();
1260 // Check if mutli-byte word x has bytes between m and n, included. This may also
1261 // catch bytes equal to n + 1.
1262 // The returned value holds a 0x80 at each byte position that holds a match.
1263 // see http://graphics.stanford.edu/~seander/bithacks.html#HasBetweenInWord
1265 static constexpr inline T
likelyhasbetween(T x
, unsigned char m
,
1267 return ((x
- ~static_cast<T
>(0) / 255 * (n
+ 1)) & ~x
&
1268 ((x
& ~static_cast<T
>(0) / 255 * 127) +
1269 (~static_cast<T
>(0) / 255 * (127 - (m
- 1))))) &
1270 ~static_cast<T
>(0) / 255 * 128;
1273 LineOffsetMapping
LineOffsetMapping::get(llvm::MemoryBufferRef Buffer
,
1274 llvm::BumpPtrAllocator
&Alloc
) {
1276 // Find the file offsets of all of the *physical* source lines. This does
1277 // not look at trigraphs, escaped newlines, or anything else tricky.
1278 SmallVector
<unsigned, 256> LineOffsets
;
1280 // Line #1 starts at char 0.
1281 LineOffsets
.push_back(0);
1283 const unsigned char *Start
= (const unsigned char *)Buffer
.getBufferStart();
1284 const unsigned char *End
= (const unsigned char *)Buffer
.getBufferEnd();
1285 const unsigned char *Buf
= Start
;
1289 // scan sizeof(Word) bytes at a time for new lines.
1290 // This is much faster than scanning each byte independently.
1291 if ((unsigned long)(End
- Start
) > sizeof(Word
)) {
1293 Word
= llvm::support::endian::read64(Buf
, llvm::support::little
);
1294 // no new line => jump over sizeof(Word) bytes.
1295 auto Mask
= likelyhasbetween(Word
, '\n', '\r');
1297 Buf
+= sizeof(Word
);
1301 // At that point, Mask contains 0x80 set at each byte that holds a value
1304 // Scan for the next newline - it's very likely there's one.
1305 unsigned N
= llvm::countr_zero(Mask
) - 7; // -7 because 0x80 is the marker
1308 unsigned char Byte
= Word
;
1311 // If this is \r\n, skip both characters.
1317 LineOffsets
.push_back(Buf
- Start
);
1319 } while (Buf
< End
- sizeof(Word
) - 1);
1322 // Handle tail using a regular check.
1325 LineOffsets
.push_back(Buf
- Start
+ 1);
1326 } else if (*Buf
== '\r') {
1327 // If this is \r\n, skip both characters.
1328 if (Buf
+ 1 < End
&& Buf
[1] == '\n') {
1331 LineOffsets
.push_back(Buf
- Start
+ 1);
1336 return LineOffsetMapping(LineOffsets
, Alloc
);
1339 LineOffsetMapping::LineOffsetMapping(ArrayRef
<unsigned> LineOffsets
,
1340 llvm::BumpPtrAllocator
&Alloc
)
1341 : Storage(Alloc
.Allocate
<unsigned>(LineOffsets
.size() + 1)) {
1342 Storage
[0] = LineOffsets
.size();
1343 std::copy(LineOffsets
.begin(), LineOffsets
.end(), Storage
+ 1);
1346 /// getLineNumber - Given a SourceLocation, return the spelling line number
1347 /// for the position indicated. This requires building and caching a table of
1348 /// line offsets for the MemoryBuffer, so this is not cheap: use only when
1349 /// about to emit a diagnostic.
1350 unsigned SourceManager::getLineNumber(FileID FID
, unsigned FilePos
,
1351 bool *Invalid
) const {
1352 if (FID
.isInvalid()) {
1358 const ContentCache
*Content
;
1359 if (LastLineNoFileIDQuery
== FID
)
1360 Content
= LastLineNoContentCache
;
1362 bool MyInvalid
= false;
1363 const SLocEntry
&Entry
= getSLocEntry(FID
, &MyInvalid
);
1364 if (MyInvalid
|| !Entry
.isFile()) {
1370 Content
= &Entry
.getFile().getContentCache();
1373 // If this is the first use of line information for this buffer, compute the
1374 /// SourceLineCache for it on demand.
1375 if (!Content
->SourceLineCache
) {
1376 std::optional
<llvm::MemoryBufferRef
> Buffer
=
1377 Content
->getBufferOrNone(Diag
, getFileManager(), SourceLocation());
1383 Content
->SourceLineCache
=
1384 LineOffsetMapping::get(*Buffer
, ContentCacheAlloc
);
1388 // Okay, we know we have a line number table. Do a binary search to find the
1389 // line number that this character position lands on.
1390 const unsigned *SourceLineCache
= Content
->SourceLineCache
.begin();
1391 const unsigned *SourceLineCacheStart
= SourceLineCache
;
1392 const unsigned *SourceLineCacheEnd
= Content
->SourceLineCache
.end();
1394 unsigned QueriedFilePos
= FilePos
+1;
1396 // FIXME: I would like to be convinced that this code is worth being as
1397 // complicated as it is, binary search isn't that slow.
1399 // If it is worth being optimized, then in my opinion it could be more
1400 // performant, simpler, and more obviously correct by just "galloping" outward
1401 // from the queried file position. In fact, this could be incorporated into a
1402 // generic algorithm such as lower_bound_with_hint.
1404 // If someone gives me a test case where this matters, and I will do it! - DWD
1406 // If the previous query was to the same file, we know both the file pos from
1407 // that query and the line number returned. This allows us to narrow the
1408 // search space from the entire file to something near the match.
1409 if (LastLineNoFileIDQuery
== FID
) {
1410 if (QueriedFilePos
>= LastLineNoFilePos
) {
1411 // FIXME: Potential overflow?
1412 SourceLineCache
= SourceLineCache
+LastLineNoResult
-1;
1414 // The query is likely to be nearby the previous one. Here we check to
1415 // see if it is within 5, 10 or 20 lines. It can be far away in cases
1416 // where big comment blocks and vertical whitespace eat up lines but
1417 // contribute no tokens.
1418 if (SourceLineCache
+5 < SourceLineCacheEnd
) {
1419 if (SourceLineCache
[5] > QueriedFilePos
)
1420 SourceLineCacheEnd
= SourceLineCache
+5;
1421 else if (SourceLineCache
+10 < SourceLineCacheEnd
) {
1422 if (SourceLineCache
[10] > QueriedFilePos
)
1423 SourceLineCacheEnd
= SourceLineCache
+10;
1424 else if (SourceLineCache
+20 < SourceLineCacheEnd
) {
1425 if (SourceLineCache
[20] > QueriedFilePos
)
1426 SourceLineCacheEnd
= SourceLineCache
+20;
1431 if (LastLineNoResult
< Content
->SourceLineCache
.size())
1432 SourceLineCacheEnd
= SourceLineCache
+LastLineNoResult
+1;
1436 const unsigned *Pos
=
1437 std::lower_bound(SourceLineCache
, SourceLineCacheEnd
, QueriedFilePos
);
1438 unsigned LineNo
= Pos
-SourceLineCacheStart
;
1440 LastLineNoFileIDQuery
= FID
;
1441 LastLineNoContentCache
= Content
;
1442 LastLineNoFilePos
= QueriedFilePos
;
1443 LastLineNoResult
= LineNo
;
1447 unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc
,
1448 bool *Invalid
) const {
1449 if (isInvalid(Loc
, Invalid
)) return 0;
1450 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedSpellingLoc(Loc
);
1451 return getLineNumber(LocInfo
.first
, LocInfo
.second
);
1453 unsigned SourceManager::getExpansionLineNumber(SourceLocation Loc
,
1454 bool *Invalid
) const {
1455 if (isInvalid(Loc
, Invalid
)) return 0;
1456 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedExpansionLoc(Loc
);
1457 return getLineNumber(LocInfo
.first
, LocInfo
.second
);
1459 unsigned SourceManager::getPresumedLineNumber(SourceLocation Loc
,
1460 bool *Invalid
) const {
1461 PresumedLoc PLoc
= getPresumedLoc(Loc
);
1462 if (isInvalid(PLoc
, Invalid
)) return 0;
1463 return PLoc
.getLine();
1466 /// getFileCharacteristic - return the file characteristic of the specified
1467 /// source location, indicating whether this is a normal file, a system
1468 /// header, or an "implicit extern C" system header.
1470 /// This state can be modified with flags on GNU linemarker directives like:
1472 /// which changes all source locations in the current file after that to be
1473 /// considered to be from a system header.
1474 SrcMgr::CharacteristicKind
1475 SourceManager::getFileCharacteristic(SourceLocation Loc
) const {
1476 assert(Loc
.isValid() && "Can't get file characteristic of invalid loc!");
1477 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedExpansionLoc(Loc
);
1478 const SLocEntry
*SEntry
= getSLocEntryForFile(LocInfo
.first
);
1482 const SrcMgr::FileInfo
&FI
= SEntry
->getFile();
1484 // If there are no #line directives in this file, just return the whole-file
1486 if (!FI
.hasLineDirectives())
1487 return FI
.getFileCharacteristic();
1489 assert(LineTable
&& "Can't have linetable entries without a LineTable!");
1490 // See if there is a #line directive before the location.
1491 const LineEntry
*Entry
=
1492 LineTable
->FindNearestLineEntry(LocInfo
.first
, LocInfo
.second
);
1494 // If this is before the first line marker, use the file characteristic.
1496 return FI
.getFileCharacteristic();
1498 return Entry
->FileKind
;
1501 /// Return the filename or buffer identifier of the buffer the location is in.
1502 /// Note that this name does not respect \#line directives. Use getPresumedLoc
1503 /// for normal clients.
1504 StringRef
SourceManager::getBufferName(SourceLocation Loc
,
1505 bool *Invalid
) const {
1506 if (isInvalid(Loc
, Invalid
)) return "<invalid loc>";
1508 auto B
= getBufferOrNone(getFileID(Loc
));
1511 return B
? B
->getBufferIdentifier() : "<invalid buffer>";
1514 /// getPresumedLoc - This method returns the "presumed" location of a
1515 /// SourceLocation specifies. A "presumed location" can be modified by \#line
1516 /// or GNU line marker directives. This provides a view on the data that a
1517 /// user should see in diagnostics, for example.
1519 /// Note that a presumed location is always given as the expansion point of an
1520 /// expansion location, not at the spelling location.
1521 PresumedLoc
SourceManager::getPresumedLoc(SourceLocation Loc
,
1522 bool UseLineDirectives
) const {
1523 if (Loc
.isInvalid()) return PresumedLoc();
1525 // Presumed locations are always for expansion points.
1526 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedExpansionLoc(Loc
);
1528 bool Invalid
= false;
1529 const SLocEntry
&Entry
= getSLocEntry(LocInfo
.first
, &Invalid
);
1530 if (Invalid
|| !Entry
.isFile())
1531 return PresumedLoc();
1533 const SrcMgr::FileInfo
&FI
= Entry
.getFile();
1534 const SrcMgr::ContentCache
*C
= &FI
.getContentCache();
1536 // To get the source name, first consult the FileEntry (if one exists)
1537 // before the MemBuffer as this will avoid unnecessarily paging in the
1539 FileID FID
= LocInfo
.first
;
1542 Filename
= C
->OrigEntry
->getName();
1543 else if (auto Buffer
= C
->getBufferOrNone(Diag
, getFileManager()))
1544 Filename
= Buffer
->getBufferIdentifier();
1546 unsigned LineNo
= getLineNumber(LocInfo
.first
, LocInfo
.second
, &Invalid
);
1548 return PresumedLoc();
1549 unsigned ColNo
= getColumnNumber(LocInfo
.first
, LocInfo
.second
, &Invalid
);
1551 return PresumedLoc();
1553 SourceLocation IncludeLoc
= FI
.getIncludeLoc();
1555 // If we have #line directives in this file, update and overwrite the physical
1556 // location info if appropriate.
1557 if (UseLineDirectives
&& FI
.hasLineDirectives()) {
1558 assert(LineTable
&& "Can't have linetable entries without a LineTable!");
1559 // See if there is a #line directive before this. If so, get it.
1560 if (const LineEntry
*Entry
=
1561 LineTable
->FindNearestLineEntry(LocInfo
.first
, LocInfo
.second
)) {
1562 // If the LineEntry indicates a filename, use it.
1563 if (Entry
->FilenameID
!= -1) {
1564 Filename
= LineTable
->getFilename(Entry
->FilenameID
);
1565 // The contents of files referenced by #line are not in the
1567 FID
= FileID::get(0);
1570 // Use the line number specified by the LineEntry. This line number may
1571 // be multiple lines down from the line entry. Add the difference in
1572 // physical line numbers from the query point and the line marker to the
1574 unsigned MarkerLineNo
= getLineNumber(LocInfo
.first
, Entry
->FileOffset
);
1575 LineNo
= Entry
->LineNo
+ (LineNo
-MarkerLineNo
-1);
1577 // Note that column numbers are not molested by line markers.
1579 // Handle virtual #include manipulation.
1580 if (Entry
->IncludeOffset
) {
1581 IncludeLoc
= getLocForStartOfFile(LocInfo
.first
);
1582 IncludeLoc
= IncludeLoc
.getLocWithOffset(Entry
->IncludeOffset
);
1587 return PresumedLoc(Filename
.data(), FID
, LineNo
, ColNo
, IncludeLoc
);
1590 /// Returns whether the PresumedLoc for a given SourceLocation is
1591 /// in the main file.
1593 /// This computes the "presumed" location for a SourceLocation, then checks
1594 /// whether it came from a file other than the main file. This is different
1595 /// from isWrittenInMainFile() because it takes line marker directives into
1597 bool SourceManager::isInMainFile(SourceLocation Loc
) const {
1598 if (Loc
.isInvalid()) return false;
1600 // Presumed locations are always for expansion points.
1601 std::pair
<FileID
, unsigned> LocInfo
= getDecomposedExpansionLoc(Loc
);
1603 const SLocEntry
*Entry
= getSLocEntryForFile(LocInfo
.first
);
1607 const SrcMgr::FileInfo
&FI
= Entry
->getFile();
1609 // Check if there is a line directive for this location.
1610 if (FI
.hasLineDirectives())
1611 if (const LineEntry
*Entry
=
1612 LineTable
->FindNearestLineEntry(LocInfo
.first
, LocInfo
.second
))
1613 if (Entry
->IncludeOffset
)
1616 return FI
.getIncludeLoc().isInvalid();
1619 /// The size of the SLocEntry that \p FID represents.
1620 unsigned SourceManager::getFileIDSize(FileID FID
) const {
1621 bool Invalid
= false;
1622 const SrcMgr::SLocEntry
&Entry
= getSLocEntry(FID
, &Invalid
);
1627 SourceLocation::UIntTy NextOffset
;
1628 if ((ID
> 0 && unsigned(ID
+1) == local_sloc_entry_size()))
1629 NextOffset
= getNextLocalOffset();
1630 else if (ID
+1 == -1)
1631 NextOffset
= MaxLoadedOffset
;
1633 NextOffset
= getSLocEntry(FileID::get(ID
+1)).getOffset();
1635 return NextOffset
- Entry
.getOffset() - 1;
1638 //===----------------------------------------------------------------------===//
1639 // Other miscellaneous methods.
1640 //===----------------------------------------------------------------------===//
1642 /// Get the source location for the given file:line:col triplet.
1644 /// If the source file is included multiple times, the source location will
1645 /// be based upon an arbitrary inclusion.
1646 SourceLocation
SourceManager::translateFileLineCol(const FileEntry
*SourceFile
,
1648 unsigned Col
) const {
1649 assert(SourceFile
&& "Null source file!");
1650 assert(Line
&& Col
&& "Line and column should start from 1!");
1652 FileID FirstFID
= translateFile(SourceFile
);
1653 return translateLineCol(FirstFID
, Line
, Col
);
1656 /// Get the FileID for the given file.
1658 /// If the source file is included multiple times, the FileID will be the
1659 /// first inclusion.
1660 FileID
SourceManager::translateFile(const FileEntry
*SourceFile
) const {
1661 assert(SourceFile
&& "Null source file!");
1663 // First, check the main file ID, since it is common to look for a
1664 // location in the main file.
1665 if (MainFileID
.isValid()) {
1666 bool Invalid
= false;
1667 const SLocEntry
&MainSLoc
= getSLocEntry(MainFileID
, &Invalid
);
1671 if (MainSLoc
.isFile()) {
1672 if (MainSLoc
.getFile().getContentCache().OrigEntry
== SourceFile
)
1677 // The location we're looking for isn't in the main file; look
1678 // through all of the local source locations.
1679 for (unsigned I
= 0, N
= local_sloc_entry_size(); I
!= N
; ++I
) {
1680 const SLocEntry
&SLoc
= getLocalSLocEntry(I
);
1681 if (SLoc
.isFile() &&
1682 SLoc
.getFile().getContentCache().OrigEntry
== SourceFile
)
1683 return FileID::get(I
);
1686 // If that still didn't help, try the modules.
1687 for (unsigned I
= 0, N
= loaded_sloc_entry_size(); I
!= N
; ++I
) {
1688 const SLocEntry
&SLoc
= getLoadedSLocEntry(I
);
1689 if (SLoc
.isFile() &&
1690 SLoc
.getFile().getContentCache().OrigEntry
== SourceFile
)
1691 return FileID::get(-int(I
) - 2);
1697 /// Get the source location in \arg FID for the given line:col.
1698 /// Returns null location if \arg FID is not a file SLocEntry.
1699 SourceLocation
SourceManager::translateLineCol(FileID FID
,
1701 unsigned Col
) const {
1702 // Lines are used as a one-based index into a zero-based array. This assert
1703 // checks for possible buffer underruns.
1704 assert(Line
&& Col
&& "Line and column should start from 1!");
1706 if (FID
.isInvalid())
1707 return SourceLocation();
1709 bool Invalid
= false;
1710 const SLocEntry
&Entry
= getSLocEntry(FID
, &Invalid
);
1712 return SourceLocation();
1714 if (!Entry
.isFile())
1715 return SourceLocation();
1717 SourceLocation FileLoc
= SourceLocation::getFileLoc(Entry
.getOffset());
1719 if (Line
== 1 && Col
== 1)
1722 const ContentCache
*Content
= &Entry
.getFile().getContentCache();
1724 // If this is the first use of line information for this buffer, compute the
1725 // SourceLineCache for it on demand.
1726 std::optional
<llvm::MemoryBufferRef
> Buffer
=
1727 Content
->getBufferOrNone(Diag
, getFileManager());
1729 return SourceLocation();
1730 if (!Content
->SourceLineCache
)
1731 Content
->SourceLineCache
=
1732 LineOffsetMapping::get(*Buffer
, ContentCacheAlloc
);
1734 if (Line
> Content
->SourceLineCache
.size()) {
1735 unsigned Size
= Buffer
->getBufferSize();
1738 return FileLoc
.getLocWithOffset(Size
);
1741 unsigned FilePos
= Content
->SourceLineCache
[Line
- 1];
1742 const char *Buf
= Buffer
->getBufferStart() + FilePos
;
1743 unsigned BufLength
= Buffer
->getBufferSize() - FilePos
;
1745 return FileLoc
.getLocWithOffset(FilePos
);
1749 // Check that the given column is valid.
1750 while (i
< BufLength
-1 && i
< Col
-1 && Buf
[i
] != '\n' && Buf
[i
] != '\r')
1752 return FileLoc
.getLocWithOffset(FilePos
+ i
);
1755 /// Compute a map of macro argument chunks to their expanded source
1756 /// location. Chunks that are not part of a macro argument will map to an
1757 /// invalid source location. e.g. if a file contains one macro argument at
1758 /// offset 100 with length 10, this is how the map will be formed:
1759 /// 0 -> SourceLocation()
1760 /// 100 -> Expanded macro arg location
1761 /// 110 -> SourceLocation()
1762 void SourceManager::computeMacroArgsCache(MacroArgsMap
&MacroArgsCache
,
1764 assert(FID
.isValid());
1766 // Initially no macro argument chunk is present.
1767 MacroArgsCache
.insert(std::make_pair(0, SourceLocation()));
1772 // Stop if there are no more FileIDs to check.
1774 if (unsigned(ID
) >= local_sloc_entry_size())
1776 } else if (ID
== -1) {
1780 bool Invalid
= false;
1781 const SrcMgr::SLocEntry
&Entry
= getSLocEntryByID(ID
, &Invalid
);
1784 if (Entry
.isFile()) {
1785 auto& File
= Entry
.getFile();
1786 if (File
.getFileCharacteristic() == C_User_ModuleMap
||
1787 File
.getFileCharacteristic() == C_System_ModuleMap
)
1790 SourceLocation IncludeLoc
= File
.getIncludeLoc();
1791 bool IncludedInFID
=
1792 (IncludeLoc
.isValid() && isInFileID(IncludeLoc
, FID
)) ||
1793 // Predefined header doesn't have a valid include location in main
1794 // file, but any files created by it should still be skipped when
1795 // computing macro args expanded in the main file.
1796 (FID
== MainFileID
&& Entry
.getFile().getName() == "<built-in>");
1797 if (IncludedInFID
) {
1798 // Skip the files/macros of the #include'd file, we only care about
1799 // macros that lexed macro arguments from our file.
1800 if (Entry
.getFile().NumCreatedFIDs
)
1801 ID
+= Entry
.getFile().NumCreatedFIDs
- 1 /*because of next ++ID*/;
1804 // If file was included but not from FID, there is no more files/macros
1805 // that may be "contained" in this file.
1806 if (IncludeLoc
.isValid())
1811 const ExpansionInfo
&ExpInfo
= Entry
.getExpansion();
1813 if (ExpInfo
.getExpansionLocStart().isFileID()) {
1814 if (!isInFileID(ExpInfo
.getExpansionLocStart(), FID
))
1815 return; // No more files/macros that may be "contained" in this file.
1818 if (!ExpInfo
.isMacroArgExpansion())
1821 associateFileChunkWithMacroArgExp(MacroArgsCache
, FID
,
1822 ExpInfo
.getSpellingLoc(),
1823 SourceLocation::getMacroLoc(Entry
.getOffset()),
1824 getFileIDSize(FileID::get(ID
)));
1828 void SourceManager::associateFileChunkWithMacroArgExp(
1829 MacroArgsMap
&MacroArgsCache
,
1831 SourceLocation SpellLoc
,
1832 SourceLocation ExpansionLoc
,
1833 unsigned ExpansionLength
) const {
1834 if (!SpellLoc
.isFileID()) {
1835 SourceLocation::UIntTy SpellBeginOffs
= SpellLoc
.getOffset();
1836 SourceLocation::UIntTy SpellEndOffs
= SpellBeginOffs
+ ExpansionLength
;
1838 // The spelling range for this macro argument expansion can span multiple
1839 // consecutive FileID entries. Go through each entry contained in the
1840 // spelling range and if one is itself a macro argument expansion, recurse
1841 // and associate the file chunk that it represents.
1843 FileID SpellFID
; // Current FileID in the spelling range.
1844 unsigned SpellRelativeOffs
;
1845 std::tie(SpellFID
, SpellRelativeOffs
) = getDecomposedLoc(SpellLoc
);
1847 const SLocEntry
&Entry
= getSLocEntry(SpellFID
);
1848 SourceLocation::UIntTy SpellFIDBeginOffs
= Entry
.getOffset();
1849 unsigned SpellFIDSize
= getFileIDSize(SpellFID
);
1850 SourceLocation::UIntTy SpellFIDEndOffs
= SpellFIDBeginOffs
+ SpellFIDSize
;
1851 const ExpansionInfo
&Info
= Entry
.getExpansion();
1852 if (Info
.isMacroArgExpansion()) {
1853 unsigned CurrSpellLength
;
1854 if (SpellFIDEndOffs
< SpellEndOffs
)
1855 CurrSpellLength
= SpellFIDSize
- SpellRelativeOffs
;
1857 CurrSpellLength
= ExpansionLength
;
1858 associateFileChunkWithMacroArgExp(MacroArgsCache
, FID
,
1859 Info
.getSpellingLoc().getLocWithOffset(SpellRelativeOffs
),
1860 ExpansionLoc
, CurrSpellLength
);
1863 if (SpellFIDEndOffs
>= SpellEndOffs
)
1864 return; // we covered all FileID entries in the spelling range.
1866 // Move to the next FileID entry in the spelling range.
1867 unsigned advance
= SpellFIDSize
- SpellRelativeOffs
+ 1;
1868 ExpansionLoc
= ExpansionLoc
.getLocWithOffset(advance
);
1869 ExpansionLength
-= advance
;
1871 SpellRelativeOffs
= 0;
1875 assert(SpellLoc
.isFileID());
1878 if (!isInFileID(SpellLoc
, FID
, &BeginOffs
))
1881 unsigned EndOffs
= BeginOffs
+ ExpansionLength
;
1883 // Add a new chunk for this macro argument. A previous macro argument chunk
1884 // may have been lexed again, so e.g. if the map is
1885 // 0 -> SourceLocation()
1886 // 100 -> Expanded loc #1
1887 // 110 -> SourceLocation()
1888 // and we found a new macro FileID that lexed from offset 105 with length 3,
1889 // the new map will be:
1890 // 0 -> SourceLocation()
1891 // 100 -> Expanded loc #1
1892 // 105 -> Expanded loc #2
1893 // 108 -> Expanded loc #1
1894 // 110 -> SourceLocation()
1896 // Since re-lexed macro chunks will always be the same size or less of
1897 // previous chunks, we only need to find where the ending of the new macro
1898 // chunk is mapped to and update the map with new begin/end mappings.
1900 MacroArgsMap::iterator I
= MacroArgsCache
.upper_bound(EndOffs
);
1902 SourceLocation EndOffsMappedLoc
= I
->second
;
1903 MacroArgsCache
[BeginOffs
] = ExpansionLoc
;
1904 MacroArgsCache
[EndOffs
] = EndOffsMappedLoc
;
1907 /// If \arg Loc points inside a function macro argument, the returned
1908 /// location will be the macro location in which the argument was expanded.
1909 /// If a macro argument is used multiple times, the expanded location will
1910 /// be at the first expansion of the argument.
1914 /// Passing a file location pointing at 'foo', will yield a macro location
1915 /// where 'foo' was expanded into.
1917 SourceManager::getMacroArgExpandedLocation(SourceLocation Loc
) const {
1918 if (Loc
.isInvalid() || !Loc
.isFileID())
1923 std::tie(FID
, Offset
) = getDecomposedLoc(Loc
);
1924 if (FID
.isInvalid())
1927 std::unique_ptr
<MacroArgsMap
> &MacroArgsCache
= MacroArgsCacheMap
[FID
];
1928 if (!MacroArgsCache
) {
1929 MacroArgsCache
= std::make_unique
<MacroArgsMap
>();
1930 computeMacroArgsCache(*MacroArgsCache
, FID
);
1933 assert(!MacroArgsCache
->empty());
1934 MacroArgsMap::iterator I
= MacroArgsCache
->upper_bound(Offset
);
1935 // In case every element in MacroArgsCache is greater than Offset we can't
1936 // decrement the iterator.
1937 if (I
== MacroArgsCache
->begin())
1942 SourceLocation::UIntTy MacroArgBeginOffs
= I
->first
;
1943 SourceLocation MacroArgExpandedLoc
= I
->second
;
1944 if (MacroArgExpandedLoc
.isValid())
1945 return MacroArgExpandedLoc
.getLocWithOffset(Offset
- MacroArgBeginOffs
);
1950 std::pair
<FileID
, unsigned>
1951 SourceManager::getDecomposedIncludedLoc(FileID FID
) const {
1952 if (FID
.isInvalid())
1953 return std::make_pair(FileID(), 0);
1955 // Uses IncludedLocMap to retrieve/cache the decomposed loc.
1957 using DecompTy
= std::pair
<FileID
, unsigned>;
1958 auto InsertOp
= IncludedLocMap
.try_emplace(FID
);
1959 DecompTy
&DecompLoc
= InsertOp
.first
->second
;
1960 if (!InsertOp
.second
)
1961 return DecompLoc
; // already in map.
1963 SourceLocation UpperLoc
;
1964 bool Invalid
= false;
1965 const SrcMgr::SLocEntry
&Entry
= getSLocEntry(FID
, &Invalid
);
1967 if (Entry
.isExpansion())
1968 UpperLoc
= Entry
.getExpansion().getExpansionLocStart();
1970 UpperLoc
= Entry
.getFile().getIncludeLoc();
1973 if (UpperLoc
.isValid())
1974 DecompLoc
= getDecomposedLoc(UpperLoc
);
1979 /// Given a decomposed source location, move it up the include/expansion stack
1980 /// to the parent source location. If this is possible, return the decomposed
1981 /// version of the parent in Loc and return false. If Loc is the top-level
1982 /// entry, return true and don't modify it.
1983 static bool MoveUpIncludeHierarchy(std::pair
<FileID
, unsigned> &Loc
,
1984 const SourceManager
&SM
) {
1985 std::pair
<FileID
, unsigned> UpperLoc
= SM
.getDecomposedIncludedLoc(Loc
.first
);
1986 if (UpperLoc
.first
.isInvalid())
1987 return true; // We reached the top.
1993 /// Return the cache entry for comparing the given file IDs
1994 /// for isBeforeInTranslationUnit.
1995 InBeforeInTUCacheEntry
&SourceManager::getInBeforeInTUCache(FileID LFID
,
1996 FileID RFID
) const {
1997 // This is a magic number for limiting the cache size. It was experimentally
1998 // derived from a small Objective-C project (where the cache filled
1999 // out to ~250 items). We can make it larger if necessary.
2000 // FIXME: this is almost certainly full these days. Use an LRU cache?
2001 enum { MagicCacheSize
= 300 };
2002 IsBeforeInTUCacheKey
Key(LFID
, RFID
);
2004 // If the cache size isn't too large, do a lookup and if necessary default
2005 // construct an entry. We can then return it to the caller for direct
2006 // use. When they update the value, the cache will get automatically
2008 if (IBTUCache
.size() < MagicCacheSize
)
2009 return IBTUCache
.try_emplace(Key
, LFID
, RFID
).first
->second
;
2011 // Otherwise, do a lookup that will not construct a new value.
2012 InBeforeInTUCache::iterator I
= IBTUCache
.find(Key
);
2013 if (I
!= IBTUCache
.end())
2016 // Fall back to the overflow value.
2017 IBTUCacheOverflow
.setQueryFIDs(LFID
, RFID
);
2018 return IBTUCacheOverflow
;
2021 /// Determines the order of 2 source locations in the translation unit.
2023 /// \returns true if LHS source location comes before RHS, false otherwise.
2024 bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS
,
2025 SourceLocation RHS
) const {
2026 assert(LHS
.isValid() && RHS
.isValid() && "Passed invalid source location!");
2030 std::pair
<FileID
, unsigned> LOffs
= getDecomposedLoc(LHS
);
2031 std::pair
<FileID
, unsigned> ROffs
= getDecomposedLoc(RHS
);
2033 // getDecomposedLoc may have failed to return a valid FileID because, e.g. it
2034 // is a serialized one referring to a file that was removed after we loaded
2036 if (LOffs
.first
.isInvalid() || ROffs
.first
.isInvalid())
2037 return LOffs
.first
.isInvalid() && !ROffs
.first
.isInvalid();
2039 std::pair
<bool, bool> InSameTU
= isInTheSameTranslationUnit(LOffs
, ROffs
);
2041 return InSameTU
.second
;
2043 // If we arrived here, the location is either in a built-ins buffer or
2044 // associated with global inline asm. PR5662 and PR22576 are examples.
2046 StringRef LB
= getBufferOrFake(LOffs
.first
).getBufferIdentifier();
2047 StringRef RB
= getBufferOrFake(ROffs
.first
).getBufferIdentifier();
2048 bool LIsBuiltins
= LB
== "<built-in>";
2049 bool RIsBuiltins
= RB
== "<built-in>";
2050 // Sort built-in before non-built-in.
2051 if (LIsBuiltins
|| RIsBuiltins
) {
2052 if (LIsBuiltins
!= RIsBuiltins
)
2054 // Both are in built-in buffers, but from different files. We just claim that
2055 // lower IDs come first.
2056 return LOffs
.first
< ROffs
.first
;
2058 bool LIsAsm
= LB
== "<inline asm>";
2059 bool RIsAsm
= RB
== "<inline asm>";
2060 // Sort assembler after built-ins, but before the rest.
2061 if (LIsAsm
|| RIsAsm
) {
2062 if (LIsAsm
!= RIsAsm
)
2064 assert(LOffs
.first
== ROffs
.first
);
2067 bool LIsScratch
= LB
== "<scratch space>";
2068 bool RIsScratch
= RB
== "<scratch space>";
2069 // Sort scratch after inline asm, but before the rest.
2070 if (LIsScratch
|| RIsScratch
) {
2071 if (LIsScratch
!= RIsScratch
)
2073 return LOffs
.second
< ROffs
.second
;
2075 llvm_unreachable("Unsortable locations found");
2078 std::pair
<bool, bool> SourceManager::isInTheSameTranslationUnit(
2079 std::pair
<FileID
, unsigned> &LOffs
,
2080 std::pair
<FileID
, unsigned> &ROffs
) const {
2081 // If the source locations are in the same file, just compare offsets.
2082 if (LOffs
.first
== ROffs
.first
)
2083 return std::make_pair(true, LOffs
.second
< ROffs
.second
);
2085 // If we are comparing a source location with multiple locations in the same
2086 // file, we get a big win by caching the result.
2087 InBeforeInTUCacheEntry
&IsBeforeInTUCache
=
2088 getInBeforeInTUCache(LOffs
.first
, ROffs
.first
);
2090 // If we are comparing a source location with multiple locations in the same
2091 // file, we get a big win by caching the result.
2092 if (IsBeforeInTUCache
.isCacheValid())
2093 return std::make_pair(
2094 true, IsBeforeInTUCache
.getCachedResult(LOffs
.second
, ROffs
.second
));
2096 // Okay, we missed in the cache, we'll compute the answer and populate it.
2097 // We need to find the common ancestor. The only way of doing this is to
2098 // build the complete include chain for one and then walking up the chain
2099 // of the other looking for a match.
2101 // A location within a FileID on the path up from LOffs to the main file.
2104 FileID ParentFID
; // Used for breaking ties.
2106 llvm::SmallDenseMap
<FileID
, Entry
, 16> LChain
;
2110 LChain
.try_emplace(LOffs
.first
, Entry
{LOffs
.second
, Parent
});
2111 // We catch the case where LOffs is in a file included by ROffs and
2112 // quit early. The other way round unfortunately remains suboptimal.
2113 if (LOffs
.first
== ROffs
.first
)
2115 Parent
= LOffs
.first
;
2116 } while (!MoveUpIncludeHierarchy(LOffs
, *this));
2120 auto I
= LChain
.find(ROffs
.first
);
2121 if (I
!= LChain
.end()) {
2122 // Compare the locations within the common file and cache them.
2123 LOffs
.first
= I
->first
;
2124 LOffs
.second
= I
->second
.Offset
;
2125 // The relative order of LParent and RParent is a tiebreaker when
2126 // - locs expand to the same location (occurs in macro arg expansion)
2127 // - one loc is a parent of the other (we consider the parent as "first")
2128 // For the parent to be first, the invalid file ID must compare smaller.
2129 // However loaded FileIDs are <0, so we perform *unsigned* comparison!
2130 // This changes the relative order of local vs loaded FileIDs, but it
2131 // doesn't matter as these are never mixed in macro expansion.
2132 unsigned LParent
= I
->second
.ParentFID
.ID
;
2133 unsigned RParent
= Parent
.ID
;
2134 assert(((LOffs
.second
!= ROffs
.second
) ||
2135 (LParent
== 0 || RParent
== 0) ||
2136 isInSameSLocAddrSpace(getComposedLoc(I
->second
.ParentFID
, 0),
2137 getComposedLoc(Parent
, 0), nullptr)) &&
2138 "Mixed local/loaded FileIDs with same include location?");
2139 IsBeforeInTUCache
.setCommonLoc(LOffs
.first
, LOffs
.second
, ROffs
.second
,
2141 return std::make_pair(
2142 true, IsBeforeInTUCache
.getCachedResult(LOffs
.second
, ROffs
.second
));
2144 Parent
= ROffs
.first
;
2145 } while (!MoveUpIncludeHierarchy(ROffs
, *this));
2147 // If we found no match, we're not in the same TU.
2148 // We don't cache this, but it is rare.
2149 return std::make_pair(false, false);
2152 void SourceManager::PrintStats() const {
2153 llvm::errs() << "\n*** Source Manager Stats:\n";
2154 llvm::errs() << FileInfos
.size() << " files mapped, " << MemBufferInfos
.size()
2155 << " mem buffers mapped.\n";
2156 llvm::errs() << LocalSLocEntryTable
.size() << " local SLocEntry's allocated ("
2157 << llvm::capacity_in_bytes(LocalSLocEntryTable
)
2158 << " bytes of capacity), "
2159 << NextLocalOffset
<< "B of Sloc address space used.\n";
2160 llvm::errs() << LoadedSLocEntryTable
.size()
2161 << " loaded SLocEntries allocated, "
2162 << MaxLoadedOffset
- CurrentLoadedOffset
2163 << "B of Sloc address space used.\n";
2165 unsigned NumLineNumsComputed
= 0;
2166 unsigned NumFileBytesMapped
= 0;
2167 for (fileinfo_iterator I
= fileinfo_begin(), E
= fileinfo_end(); I
!= E
; ++I
){
2168 NumLineNumsComputed
+= bool(I
->second
->SourceLineCache
);
2169 NumFileBytesMapped
+= I
->second
->getSizeBytesMapped();
2171 unsigned NumMacroArgsComputed
= MacroArgsCacheMap
.size();
2173 llvm::errs() << NumFileBytesMapped
<< " bytes of files mapped, "
2174 << NumLineNumsComputed
<< " files with line #'s computed, "
2175 << NumMacroArgsComputed
<< " files with macro args computed.\n";
2176 llvm::errs() << "FileID scans: " << NumLinearScans
<< " linear, "
2177 << NumBinaryProbes
<< " binary.\n";
2180 LLVM_DUMP_METHOD
void SourceManager::dump() const {
2181 llvm::raw_ostream
&out
= llvm::errs();
2183 auto DumpSLocEntry
= [&](int ID
, const SrcMgr::SLocEntry
&Entry
,
2184 std::optional
<SourceLocation::UIntTy
> NextStart
) {
2185 out
<< "SLocEntry <FileID " << ID
<< "> " << (Entry
.isFile() ? "file" : "expansion")
2186 << " <SourceLocation " << Entry
.getOffset() << ":";
2188 out
<< *NextStart
<< ">\n";
2191 if (Entry
.isFile()) {
2192 auto &FI
= Entry
.getFile();
2193 if (FI
.NumCreatedFIDs
)
2194 out
<< " covers <FileID " << ID
<< ":" << int(ID
+ FI
.NumCreatedFIDs
)
2196 if (FI
.getIncludeLoc().isValid())
2197 out
<< " included from " << FI
.getIncludeLoc().getOffset() << "\n";
2198 auto &CC
= FI
.getContentCache();
2199 out
<< " for " << (CC
.OrigEntry
? CC
.OrigEntry
->getName() : "<none>")
2201 if (CC
.BufferOverridden
)
2202 out
<< " contents overridden\n";
2203 if (CC
.ContentsEntry
!= CC
.OrigEntry
) {
2204 out
<< " contents from "
2205 << (CC
.ContentsEntry
? CC
.ContentsEntry
->getName() : "<none>")
2209 auto &EI
= Entry
.getExpansion();
2210 out
<< " spelling from " << EI
.getSpellingLoc().getOffset() << "\n";
2211 out
<< " macro " << (EI
.isMacroArgExpansion() ? "arg" : "body")
2212 << " range <" << EI
.getExpansionLocStart().getOffset() << ":"
2213 << EI
.getExpansionLocEnd().getOffset() << ">\n";
2217 // Dump local SLocEntries.
2218 for (unsigned ID
= 0, NumIDs
= LocalSLocEntryTable
.size(); ID
!= NumIDs
; ++ID
) {
2219 DumpSLocEntry(ID
, LocalSLocEntryTable
[ID
],
2220 ID
== NumIDs
- 1 ? NextLocalOffset
2221 : LocalSLocEntryTable
[ID
+ 1].getOffset());
2223 // Dump loaded SLocEntries.
2224 std::optional
<SourceLocation::UIntTy
> NextStart
;
2225 for (unsigned Index
= 0; Index
!= LoadedSLocEntryTable
.size(); ++Index
) {
2226 int ID
= -(int)Index
- 2;
2227 if (SLocEntryLoaded
[Index
]) {
2228 DumpSLocEntry(ID
, LoadedSLocEntryTable
[Index
], NextStart
);
2229 NextStart
= LoadedSLocEntryTable
[Index
].getOffset();
2231 NextStart
= std::nullopt
;
2236 void SourceManager::noteSLocAddressSpaceUsage(
2237 DiagnosticsEngine
&Diag
, std::optional
<unsigned> MaxNotes
) const {
2239 // A location where this file was entered.
2241 // Number of times this FileEntry was entered.
2242 unsigned Inclusions
= 0;
2243 // Size usage from the file itself.
2244 uint64_t DirectSize
= 0;
2245 // Total size usage from the file and its macro expansions.
2246 uint64_t TotalSize
= 0;
2248 using UsageMap
= llvm::MapVector
<const FileEntry
*, Info
>;
2251 uint64_t CountedSize
= 0;
2253 auto AddUsageForFileID
= [&](FileID ID
) {
2254 // The +1 here is because getFileIDSize doesn't include the extra byte for
2255 // the one-past-the-end location.
2256 unsigned Size
= getFileIDSize(ID
) + 1;
2258 // Find the file that used this address space, either directly or by
2260 SourceLocation FileStart
= getFileLoc(getComposedLoc(ID
, 0));
2261 FileID FileLocID
= getFileID(FileStart
);
2262 const FileEntry
*Entry
= getFileEntryForID(FileLocID
);
2264 Info
&EntryInfo
= Usage
[Entry
];
2265 if (EntryInfo
.Loc
.isInvalid())
2266 EntryInfo
.Loc
= FileStart
;
2267 if (ID
== FileLocID
) {
2268 ++EntryInfo
.Inclusions
;
2269 EntryInfo
.DirectSize
+= Size
;
2271 EntryInfo
.TotalSize
+= Size
;
2272 CountedSize
+= Size
;
2275 // Loaded SLocEntries have indexes counting downwards from -2.
2276 for (size_t Index
= 0; Index
!= LoadedSLocEntryTable
.size(); ++Index
) {
2277 AddUsageForFileID(FileID::get(-2 - Index
));
2279 // Local SLocEntries have indexes counting upwards from 0.
2280 for (size_t Index
= 0; Index
!= LocalSLocEntryTable
.size(); ++Index
) {
2281 AddUsageForFileID(FileID::get(Index
));
2284 // Sort the usage by size from largest to smallest. Break ties by raw source
2286 auto SortedUsage
= Usage
.takeVector();
2287 auto Cmp
= [](const UsageMap::value_type
&A
, const UsageMap::value_type
&B
) {
2288 return A
.second
.TotalSize
> B
.second
.TotalSize
||
2289 (A
.second
.TotalSize
== B
.second
.TotalSize
&&
2290 A
.second
.Loc
< B
.second
.Loc
);
2292 auto SortedEnd
= SortedUsage
.end();
2293 if (MaxNotes
&& SortedUsage
.size() > *MaxNotes
) {
2294 SortedEnd
= SortedUsage
.begin() + *MaxNotes
;
2295 std::nth_element(SortedUsage
.begin(), SortedEnd
, SortedUsage
.end(), Cmp
);
2297 std::sort(SortedUsage
.begin(), SortedEnd
, Cmp
);
2299 // Produce note on sloc address space usage total.
2300 uint64_t LocalUsage
= NextLocalOffset
;
2301 uint64_t LoadedUsage
= MaxLoadedOffset
- CurrentLoadedOffset
;
2302 int UsagePercent
= static_cast<int>(100.0 * double(LocalUsage
+ LoadedUsage
) /
2304 Diag
.Report(SourceLocation(), diag::note_total_sloc_usage
)
2305 << LocalUsage
<< LoadedUsage
<< (LocalUsage
+ LoadedUsage
) << UsagePercent
;
2307 // Produce notes on sloc address space usage for each file with a high usage.
2308 uint64_t ReportedSize
= 0;
2309 for (auto &[Entry
, FileInfo
] :
2310 llvm::make_range(SortedUsage
.begin(), SortedEnd
)) {
2311 Diag
.Report(FileInfo
.Loc
, diag::note_file_sloc_usage
)
2312 << FileInfo
.Inclusions
<< FileInfo
.DirectSize
2313 << (FileInfo
.TotalSize
- FileInfo
.DirectSize
);
2314 ReportedSize
+= FileInfo
.TotalSize
;
2317 // Describe any remaining usage not reported in the per-file usage.
2318 if (ReportedSize
!= CountedSize
) {
2319 Diag
.Report(SourceLocation(), diag::note_file_misc_sloc_usage
)
2320 << (SortedUsage
.end() - SortedEnd
) << CountedSize
- ReportedSize
;
2324 ExternalSLocEntrySource::~ExternalSLocEntrySource() = default;
2326 /// Return the amount of memory used by memory buffers, breaking down
2327 /// by heap-backed versus mmap'ed memory.
2328 SourceManager::MemoryBufferSizes
SourceManager::getMemoryBufferSizes() const {
2329 size_t malloc_bytes
= 0;
2330 size_t mmap_bytes
= 0;
2332 for (unsigned i
= 0, e
= MemBufferInfos
.size(); i
!= e
; ++i
)
2333 if (size_t sized_mapped
= MemBufferInfos
[i
]->getSizeBytesMapped())
2334 switch (MemBufferInfos
[i
]->getMemoryBufferKind()) {
2335 case llvm::MemoryBuffer::MemoryBuffer_MMap
:
2336 mmap_bytes
+= sized_mapped
;
2338 case llvm::MemoryBuffer::MemoryBuffer_Malloc
:
2339 malloc_bytes
+= sized_mapped
;
2343 return MemoryBufferSizes(malloc_bytes
, mmap_bytes
);
2346 size_t SourceManager::getDataStructureSizes() const {
2347 size_t size
= llvm::capacity_in_bytes(MemBufferInfos
)
2348 + llvm::capacity_in_bytes(LocalSLocEntryTable
)
2349 + llvm::capacity_in_bytes(LoadedSLocEntryTable
)
2350 + llvm::capacity_in_bytes(SLocEntryLoaded
)
2351 + llvm::capacity_in_bytes(FileInfos
);
2353 if (OverriddenFilesInfo
)
2354 size
+= llvm::capacity_in_bytes(OverriddenFilesInfo
->OverriddenFiles
);
2359 SourceManagerForFile::SourceManagerForFile(StringRef FileName
,
2360 StringRef Content
) {
2361 // This is referenced by `FileMgr` and will be released by `FileMgr` when it
2363 IntrusiveRefCntPtr
<llvm::vfs::InMemoryFileSystem
> InMemoryFileSystem(
2364 new llvm::vfs::InMemoryFileSystem
);
2365 InMemoryFileSystem
->addFile(
2367 llvm::MemoryBuffer::getMemBuffer(Content
, FileName
,
2368 /*RequiresNullTerminator=*/false));
2369 // This is passed to `SM` as reference, so the pointer has to be referenced
2370 // in `Environment` so that `FileMgr` can out-live this function scope.
2372 std::make_unique
<FileManager
>(FileSystemOptions(), InMemoryFileSystem
);
2373 // This is passed to `SM` as reference, so the pointer has to be referenced
2374 // by `Environment` due to the same reason above.
2375 Diagnostics
= std::make_unique
<DiagnosticsEngine
>(
2376 IntrusiveRefCntPtr
<DiagnosticIDs
>(new DiagnosticIDs
),
2377 new DiagnosticOptions
);
2378 SourceMgr
= std::make_unique
<SourceManager
>(*Diagnostics
, *FileMgr
);
2379 FileID ID
= SourceMgr
->createFileID(*FileMgr
->getFile(FileName
),
2380 SourceLocation(), clang::SrcMgr::C_User
);
2381 assert(ID
.isValid());
2382 SourceMgr
->setMainFileID(ID
);