/src/llvm-project/clang/lib/Basic/SourceLocation.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- SourceLocation.cpp - Compact identifier for Source Files -----------===// |
2 | | // |
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 |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file defines accessor methods for the FullSourceLoc class. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
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" |
23 | | #include <cassert> |
24 | | #include <string> |
25 | | #include <utility> |
26 | | |
27 | | using namespace clang; |
28 | | |
29 | | //===----------------------------------------------------------------------===// |
30 | | // PrettyStackTraceLoc |
31 | | //===----------------------------------------------------------------------===// |
32 | | |
33 | 0 | void PrettyStackTraceLoc::print(raw_ostream &OS) const { |
34 | 0 | if (Loc.isValid()) { |
35 | 0 | Loc.print(OS, SM); |
36 | 0 | OS << ": "; |
37 | 0 | } |
38 | 0 | OS << Message << '\n'; |
39 | 0 | } |
40 | | |
41 | | //===----------------------------------------------------------------------===// |
42 | | // SourceLocation |
43 | | //===----------------------------------------------------------------------===// |
44 | | |
45 | | static_assert(std::is_trivially_destructible_v<SourceLocation>, |
46 | | "SourceLocation must be trivially destructible because it is " |
47 | | "used in unions"); |
48 | | |
49 | | static_assert(std::is_trivially_destructible_v<SourceRange>, |
50 | | "SourceRange must be trivially destructible because it is " |
51 | | "used in unions"); |
52 | | |
53 | 0 | unsigned SourceLocation::getHashValue() const { |
54 | 0 | return llvm::DenseMapInfo<UIntTy>::getHashValue(ID); |
55 | 0 | } |
56 | | |
57 | | void llvm::FoldingSetTrait<SourceLocation>::Profile( |
58 | 0 | const SourceLocation &X, llvm::FoldingSetNodeID &ID) { |
59 | 0 | ID.AddInteger(X.ID); |
60 | 0 | } |
61 | | |
62 | 0 | void SourceLocation::print(raw_ostream &OS, const SourceManager &SM)const{ |
63 | 0 | if (!isValid()) { |
64 | 0 | OS << "<invalid loc>"; |
65 | 0 | return; |
66 | 0 | } |
67 | | |
68 | 0 | if (isFileID()) { |
69 | 0 | PresumedLoc PLoc = SM.getPresumedLoc(*this); |
70 | |
|
71 | 0 | if (PLoc.isInvalid()) { |
72 | 0 | OS << "<invalid>"; |
73 | 0 | return; |
74 | 0 | } |
75 | | // The macro expansion and spelling pos is identical for file locs. |
76 | 0 | OS << PLoc.getFilename() << ':' << PLoc.getLine() |
77 | 0 | << ':' << PLoc.getColumn(); |
78 | 0 | return; |
79 | 0 | } |
80 | | |
81 | 0 | SM.getExpansionLoc(*this).print(OS, SM); |
82 | |
|
83 | 0 | OS << " <Spelling="; |
84 | 0 | SM.getSpellingLoc(*this).print(OS, SM); |
85 | 0 | OS << '>'; |
86 | 0 | } |
87 | | |
88 | | LLVM_DUMP_METHOD std::string |
89 | 0 | SourceLocation::printToString(const SourceManager &SM) const { |
90 | 0 | std::string S; |
91 | 0 | llvm::raw_string_ostream OS(S); |
92 | 0 | print(OS, SM); |
93 | 0 | return S; |
94 | 0 | } |
95 | | |
96 | 0 | LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const { |
97 | 0 | print(llvm::errs(), SM); |
98 | 0 | llvm::errs() << '\n'; |
99 | 0 | } |
100 | | |
101 | 0 | LLVM_DUMP_METHOD void SourceRange::dump(const SourceManager &SM) const { |
102 | 0 | print(llvm::errs(), SM); |
103 | 0 | llvm::errs() << '\n'; |
104 | 0 | } |
105 | | |
106 | | static PresumedLoc PrintDifference(raw_ostream &OS, const SourceManager &SM, |
107 | 0 | SourceLocation Loc, PresumedLoc Previous) { |
108 | 0 | if (Loc.isFileID()) { |
109 | |
|
110 | 0 | PresumedLoc PLoc = SM.getPresumedLoc(Loc); |
111 | |
|
112 | 0 | if (PLoc.isInvalid()) { |
113 | 0 | OS << "<invalid sloc>"; |
114 | 0 | return Previous; |
115 | 0 | } |
116 | | |
117 | 0 | if (Previous.isInvalid() || |
118 | 0 | strcmp(PLoc.getFilename(), Previous.getFilename()) != 0) { |
119 | 0 | OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':' |
120 | 0 | << PLoc.getColumn(); |
121 | 0 | } else if (Previous.isInvalid() || PLoc.getLine() != Previous.getLine()) { |
122 | 0 | OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn(); |
123 | 0 | } else { |
124 | 0 | OS << "col" << ':' << PLoc.getColumn(); |
125 | 0 | } |
126 | 0 | return PLoc; |
127 | 0 | } |
128 | 0 | auto PrintedLoc = PrintDifference(OS, SM, SM.getExpansionLoc(Loc), Previous); |
129 | |
|
130 | 0 | OS << " <Spelling="; |
131 | 0 | PrintedLoc = PrintDifference(OS, SM, SM.getSpellingLoc(Loc), PrintedLoc); |
132 | 0 | OS << '>'; |
133 | 0 | return PrintedLoc; |
134 | 0 | } |
135 | | |
136 | 0 | void SourceRange::print(raw_ostream &OS, const SourceManager &SM) const { |
137 | |
|
138 | 0 | OS << '<'; |
139 | 0 | auto PrintedLoc = PrintDifference(OS, SM, B, {}); |
140 | 0 | if (B != E) { |
141 | 0 | OS << ", "; |
142 | 0 | PrintDifference(OS, SM, E, PrintedLoc); |
143 | 0 | } |
144 | 0 | OS << '>'; |
145 | 0 | } |
146 | | |
147 | | LLVM_DUMP_METHOD std::string |
148 | 0 | SourceRange::printToString(const SourceManager &SM) const { |
149 | 0 | std::string S; |
150 | 0 | llvm::raw_string_ostream OS(S); |
151 | 0 | print(OS, SM); |
152 | 0 | return S; |
153 | 0 | } |
154 | | |
155 | | //===----------------------------------------------------------------------===// |
156 | | // FullSourceLoc |
157 | | //===----------------------------------------------------------------------===// |
158 | | |
159 | 0 | FileID FullSourceLoc::getFileID() const { |
160 | 0 | assert(isValid()); |
161 | 0 | return SrcMgr->getFileID(*this); |
162 | 0 | } |
163 | | |
164 | 0 | FullSourceLoc FullSourceLoc::getExpansionLoc() const { |
165 | 0 | assert(isValid()); |
166 | 0 | return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr); |
167 | 0 | } |
168 | | |
169 | 0 | std::pair<FileID, unsigned> FullSourceLoc::getDecomposedExpansionLoc() const { |
170 | 0 | return SrcMgr->getDecomposedExpansionLoc(*this); |
171 | 0 | } |
172 | | |
173 | 0 | FullSourceLoc FullSourceLoc::getSpellingLoc() const { |
174 | 0 | assert(isValid()); |
175 | 0 | return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr); |
176 | 0 | } |
177 | | |
178 | 0 | FullSourceLoc FullSourceLoc::getFileLoc() const { |
179 | 0 | assert(isValid()); |
180 | 0 | return FullSourceLoc(SrcMgr->getFileLoc(*this), *SrcMgr); |
181 | 0 | } |
182 | | |
183 | 0 | PresumedLoc FullSourceLoc::getPresumedLoc(bool UseLineDirectives) const { |
184 | 0 | if (!isValid()) |
185 | 0 | return PresumedLoc(); |
186 | | |
187 | 0 | return SrcMgr->getPresumedLoc(*this, UseLineDirectives); |
188 | 0 | } |
189 | | |
190 | 0 | bool FullSourceLoc::isMacroArgExpansion(FullSourceLoc *StartLoc) const { |
191 | 0 | assert(isValid()); |
192 | 0 | return SrcMgr->isMacroArgExpansion(*this, StartLoc); |
193 | 0 | } |
194 | | |
195 | 0 | FullSourceLoc FullSourceLoc::getImmediateMacroCallerLoc() const { |
196 | 0 | assert(isValid()); |
197 | 0 | return FullSourceLoc(SrcMgr->getImmediateMacroCallerLoc(*this), *SrcMgr); |
198 | 0 | } |
199 | | |
200 | 0 | std::pair<FullSourceLoc, StringRef> FullSourceLoc::getModuleImportLoc() const { |
201 | 0 | if (!isValid()) |
202 | 0 | return std::make_pair(FullSourceLoc(), StringRef()); |
203 | | |
204 | 0 | std::pair<SourceLocation, StringRef> ImportLoc = |
205 | 0 | SrcMgr->getModuleImportLoc(*this); |
206 | 0 | return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr), |
207 | 0 | ImportLoc.second); |
208 | 0 | } |
209 | | |
210 | 0 | unsigned FullSourceLoc::getFileOffset() const { |
211 | 0 | assert(isValid()); |
212 | 0 | return SrcMgr->getFileOffset(*this); |
213 | 0 | } |
214 | | |
215 | 0 | unsigned FullSourceLoc::getLineNumber(bool *Invalid) const { |
216 | 0 | assert(isValid()); |
217 | 0 | return SrcMgr->getLineNumber(getFileID(), getFileOffset(), Invalid); |
218 | 0 | } |
219 | | |
220 | 0 | unsigned FullSourceLoc::getColumnNumber(bool *Invalid) const { |
221 | 0 | assert(isValid()); |
222 | 0 | return SrcMgr->getColumnNumber(getFileID(), getFileOffset(), Invalid); |
223 | 0 | } |
224 | | |
225 | 0 | const FileEntry *FullSourceLoc::getFileEntry() const { |
226 | 0 | assert(isValid()); |
227 | 0 | return SrcMgr->getFileEntryForID(getFileID()); |
228 | 0 | } |
229 | | |
230 | 0 | OptionalFileEntryRef FullSourceLoc::getFileEntryRef() const { |
231 | 0 | assert(isValid()); |
232 | 0 | return SrcMgr->getFileEntryRefForID(getFileID()); |
233 | 0 | } |
234 | | |
235 | 0 | unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const { |
236 | 0 | assert(isValid()); |
237 | 0 | return SrcMgr->getExpansionLineNumber(*this, Invalid); |
238 | 0 | } |
239 | | |
240 | 0 | unsigned FullSourceLoc::getExpansionColumnNumber(bool *Invalid) const { |
241 | 0 | assert(isValid()); |
242 | 0 | return SrcMgr->getExpansionColumnNumber(*this, Invalid); |
243 | 0 | } |
244 | | |
245 | 0 | unsigned FullSourceLoc::getSpellingLineNumber(bool *Invalid) const { |
246 | 0 | assert(isValid()); |
247 | 0 | return SrcMgr->getSpellingLineNumber(*this, Invalid); |
248 | 0 | } |
249 | | |
250 | 0 | unsigned FullSourceLoc::getSpellingColumnNumber(bool *Invalid) const { |
251 | 0 | assert(isValid()); |
252 | 0 | return SrcMgr->getSpellingColumnNumber(*this, Invalid); |
253 | 0 | } |
254 | | |
255 | 0 | bool FullSourceLoc::isInSystemHeader() const { |
256 | 0 | assert(isValid()); |
257 | 0 | return SrcMgr->isInSystemHeader(*this); |
258 | 0 | } |
259 | | |
260 | 0 | bool FullSourceLoc::isBeforeInTranslationUnitThan(SourceLocation Loc) const { |
261 | 0 | assert(isValid()); |
262 | 0 | return SrcMgr->isBeforeInTranslationUnit(*this, Loc); |
263 | 0 | } |
264 | | |
265 | 0 | LLVM_DUMP_METHOD void FullSourceLoc::dump() const { |
266 | 0 | SourceLocation::dump(*SrcMgr); |
267 | 0 | } |
268 | | |
269 | 0 | const char *FullSourceLoc::getCharacterData(bool *Invalid) const { |
270 | 0 | assert(isValid()); |
271 | 0 | return SrcMgr->getCharacterData(*this, Invalid); |
272 | 0 | } |
273 | | |
274 | 0 | StringRef FullSourceLoc::getBufferData(bool *Invalid) const { |
275 | 0 | assert(isValid()); |
276 | 0 | return SrcMgr->getBufferData(SrcMgr->getFileID(*this), Invalid); |
277 | 0 | } |
278 | | |
279 | 0 | std::pair<FileID, unsigned> FullSourceLoc::getDecomposedLoc() const { |
280 | 0 | return SrcMgr->getDecomposedLoc(*this); |
281 | 0 | } |