1 //===- SourceLocation.cpp - Compact identifier for 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 defines accessor methods for the FullSourceLoc class.
11 //===----------------------------------------------------------------------===//
13 #include "clang/Basic/SourceLocation.h"
14 #include "clang/Basic/LLVM.h"
15 #include "clang/Basic/PrettyStackTrace.h"
16 #include "clang/Basic/SourceManager.h"
17 #include "llvm/ADT/DenseMapInfo.h"
18 #include "llvm/ADT/FoldingSet.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include "llvm/Support/raw_ostream.h"
27 using namespace clang
;
29 //===----------------------------------------------------------------------===//
30 // PrettyStackTraceLoc
31 //===----------------------------------------------------------------------===//
33 void PrettyStackTraceLoc::print(raw_ostream
&OS
) const {
38 OS
<< Message
<< '\n';
41 //===----------------------------------------------------------------------===//
43 //===----------------------------------------------------------------------===//
45 static_assert(std::is_trivially_destructible_v
<SourceLocation
>,
46 "SourceLocation must be trivially destructible because it is "
49 static_assert(std::is_trivially_destructible_v
<SourceRange
>,
50 "SourceRange must be trivially destructible because it is "
53 unsigned SourceLocation::getHashValue() const {
54 return llvm::DenseMapInfo
<UIntTy
>::getHashValue(ID
);
57 void llvm::FoldingSetTrait
<SourceLocation
>::Profile(
58 const SourceLocation
&X
, llvm::FoldingSetNodeID
&ID
) {
62 void SourceLocation::print(raw_ostream
&OS
, const SourceManager
&SM
)const{
64 OS
<< "<invalid loc>";
69 PresumedLoc PLoc
= SM
.getPresumedLoc(*this);
71 if (PLoc
.isInvalid()) {
75 // The macro expansion and spelling pos is identical for file locs.
76 OS
<< PLoc
.getFilename() << ':' << PLoc
.getLine()
77 << ':' << PLoc
.getColumn();
81 SM
.getExpansionLoc(*this).print(OS
, SM
);
84 SM
.getSpellingLoc(*this).print(OS
, SM
);
88 LLVM_DUMP_METHOD
std::string
89 SourceLocation::printToString(const SourceManager
&SM
) const {
91 llvm::raw_string_ostream
OS(S
);
96 LLVM_DUMP_METHOD
void SourceLocation::dump(const SourceManager
&SM
) const {
97 print(llvm::errs(), SM
);
101 LLVM_DUMP_METHOD
void SourceRange::dump(const SourceManager
&SM
) const {
102 print(llvm::errs(), SM
);
103 llvm::errs() << '\n';
106 static PresumedLoc
PrintDifference(raw_ostream
&OS
, const SourceManager
&SM
,
107 SourceLocation Loc
, PresumedLoc Previous
) {
108 if (Loc
.isFileID()) {
110 PresumedLoc PLoc
= SM
.getPresumedLoc(Loc
);
112 if (PLoc
.isInvalid()) {
113 OS
<< "<invalid sloc>";
117 if (Previous
.isInvalid() ||
118 strcmp(PLoc
.getFilename(), Previous
.getFilename()) != 0) {
119 OS
<< PLoc
.getFilename() << ':' << PLoc
.getLine() << ':'
121 } else if (Previous
.isInvalid() || PLoc
.getLine() != Previous
.getLine()) {
122 OS
<< "line" << ':' << PLoc
.getLine() << ':' << PLoc
.getColumn();
124 OS
<< "col" << ':' << PLoc
.getColumn();
128 auto PrintedLoc
= PrintDifference(OS
, SM
, SM
.getExpansionLoc(Loc
), Previous
);
131 PrintedLoc
= PrintDifference(OS
, SM
, SM
.getSpellingLoc(Loc
), PrintedLoc
);
136 void SourceRange::print(raw_ostream
&OS
, const SourceManager
&SM
) const {
139 auto PrintedLoc
= PrintDifference(OS
, SM
, B
, {});
142 PrintDifference(OS
, SM
, E
, PrintedLoc
);
147 LLVM_DUMP_METHOD
std::string
148 SourceRange::printToString(const SourceManager
&SM
) const {
150 llvm::raw_string_ostream
OS(S
);
155 //===----------------------------------------------------------------------===//
157 //===----------------------------------------------------------------------===//
159 FileID
FullSourceLoc::getFileID() const {
161 return SrcMgr
->getFileID(*this);
164 FullSourceLoc
FullSourceLoc::getExpansionLoc() const {
166 return FullSourceLoc(SrcMgr
->getExpansionLoc(*this), *SrcMgr
);
169 std::pair
<FileID
, unsigned> FullSourceLoc::getDecomposedExpansionLoc() const {
170 return SrcMgr
->getDecomposedExpansionLoc(*this);
173 FullSourceLoc
FullSourceLoc::getSpellingLoc() const {
175 return FullSourceLoc(SrcMgr
->getSpellingLoc(*this), *SrcMgr
);
178 FullSourceLoc
FullSourceLoc::getFileLoc() const {
180 return FullSourceLoc(SrcMgr
->getFileLoc(*this), *SrcMgr
);
183 PresumedLoc
FullSourceLoc::getPresumedLoc(bool UseLineDirectives
) const {
185 return PresumedLoc();
187 return SrcMgr
->getPresumedLoc(*this, UseLineDirectives
);
190 bool FullSourceLoc::isMacroArgExpansion(FullSourceLoc
*StartLoc
) const {
192 return SrcMgr
->isMacroArgExpansion(*this, StartLoc
);
195 FullSourceLoc
FullSourceLoc::getImmediateMacroCallerLoc() const {
197 return FullSourceLoc(SrcMgr
->getImmediateMacroCallerLoc(*this), *SrcMgr
);
200 std::pair
<FullSourceLoc
, StringRef
> FullSourceLoc::getModuleImportLoc() const {
202 return std::make_pair(FullSourceLoc(), StringRef());
204 std::pair
<SourceLocation
, StringRef
> ImportLoc
=
205 SrcMgr
->getModuleImportLoc(*this);
206 return std::make_pair(FullSourceLoc(ImportLoc
.first
, *SrcMgr
),
210 unsigned FullSourceLoc::getFileOffset() const {
212 return SrcMgr
->getFileOffset(*this);
215 unsigned FullSourceLoc::getLineNumber(bool *Invalid
) const {
217 return SrcMgr
->getLineNumber(getFileID(), getFileOffset(), Invalid
);
220 unsigned FullSourceLoc::getColumnNumber(bool *Invalid
) const {
222 return SrcMgr
->getColumnNumber(getFileID(), getFileOffset(), Invalid
);
225 const FileEntry
*FullSourceLoc::getFileEntry() const {
227 return SrcMgr
->getFileEntryForID(getFileID());
230 OptionalFileEntryRef
FullSourceLoc::getFileEntryRef() const {
232 return SrcMgr
->getFileEntryRefForID(getFileID());
235 unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid
) const {
237 return SrcMgr
->getExpansionLineNumber(*this, Invalid
);
240 unsigned FullSourceLoc::getExpansionColumnNumber(bool *Invalid
) const {
242 return SrcMgr
->getExpansionColumnNumber(*this, Invalid
);
245 unsigned FullSourceLoc::getSpellingLineNumber(bool *Invalid
) const {
247 return SrcMgr
->getSpellingLineNumber(*this, Invalid
);
250 unsigned FullSourceLoc::getSpellingColumnNumber(bool *Invalid
) const {
252 return SrcMgr
->getSpellingColumnNumber(*this, Invalid
);
255 bool FullSourceLoc::isInSystemHeader() const {
257 return SrcMgr
->isInSystemHeader(*this);
260 bool FullSourceLoc::isBeforeInTranslationUnitThan(SourceLocation Loc
) const {
262 return SrcMgr
->isBeforeInTranslationUnit(*this, Loc
);
265 LLVM_DUMP_METHOD
void FullSourceLoc::dump() const {
266 SourceLocation::dump(*SrcMgr
);
269 const char *FullSourceLoc::getCharacterData(bool *Invalid
) const {
271 return SrcMgr
->getCharacterData(*this, Invalid
);
274 StringRef
FullSourceLoc::getBufferData(bool *Invalid
) const {
276 return SrcMgr
->getBufferData(SrcMgr
->getFileID(*this), Invalid
);
279 std::pair
<FileID
, unsigned> FullSourceLoc::getDecomposedLoc() const {
280 return SrcMgr
->getDecomposedLoc(*this);