clang  19.0.0git
SourceLocation.cpp
Go to the documentation of this file.
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 
14 #include "clang/Basic/LLVM.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 void PrettyStackTraceLoc::print(raw_ostream &OS) const {
34  if (Loc.isValid()) {
35  Loc.print(OS, SM);
36  OS << ": ";
37  }
38  OS << Message << '\n';
39 }
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 unsigned SourceLocation::getHashValue() const {
54  return llvm::DenseMapInfo<UIntTy>::getHashValue(ID);
55 }
56 
58  const SourceLocation &X, llvm::FoldingSetNodeID &ID) {
59  ID.AddInteger(X.ID);
60 }
61 
62 void SourceLocation::print(raw_ostream &OS, const SourceManager &SM)const{
63  if (!isValid()) {
64  OS << "<invalid loc>";
65  return;
66  }
67 
68  if (isFileID()) {
69  PresumedLoc PLoc = SM.getPresumedLoc(*this);
70 
71  if (PLoc.isInvalid()) {
72  OS << "<invalid>";
73  return;
74  }
75  // The macro expansion and spelling pos is identical for file locs.
76  OS << PLoc.getFilename() << ':' << PLoc.getLine()
77  << ':' << PLoc.getColumn();
78  return;
79  }
80 
81  SM.getExpansionLoc(*this).print(OS, SM);
82 
83  OS << " <Spelling=";
84  SM.getSpellingLoc(*this).print(OS, SM);
85  OS << '>';
86 }
87 
88 LLVM_DUMP_METHOD std::string
89 SourceLocation::printToString(const SourceManager &SM) const {
90  std::string S;
91  llvm::raw_string_ostream OS(S);
92  print(OS, SM);
93  return S;
94 }
95 
96 LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const {
97  print(llvm::errs(), SM);
98  llvm::errs() << '\n';
99 }
100 
101 LLVM_DUMP_METHOD void SourceRange::dump(const SourceManager &SM) const {
102  print(llvm::errs(), SM);
103  llvm::errs() << '\n';
104 }
105 
106 static PresumedLoc PrintDifference(raw_ostream &OS, const SourceManager &SM,
107  SourceLocation Loc, PresumedLoc Previous) {
108  if (Loc.isFileID()) {
109 
110  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
111 
112  if (PLoc.isInvalid()) {
113  OS << "<invalid sloc>";
114  return Previous;
115  }
116 
117  if (Previous.isInvalid() ||
118  strcmp(PLoc.getFilename(), Previous.getFilename()) != 0) {
119  OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
120  << PLoc.getColumn();
121  } else if (Previous.isInvalid() || PLoc.getLine() != Previous.getLine()) {
122  OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
123  } else {
124  OS << "col" << ':' << PLoc.getColumn();
125  }
126  return PLoc;
127  }
128  auto PrintedLoc = PrintDifference(OS, SM, SM.getExpansionLoc(Loc), Previous);
129 
130  OS << " <Spelling=";
131  PrintedLoc = PrintDifference(OS, SM, SM.getSpellingLoc(Loc), PrintedLoc);
132  OS << '>';
133  return PrintedLoc;
134 }
135 
136 void SourceRange::print(raw_ostream &OS, const SourceManager &SM) const {
137 
138  OS << '<';
139  auto PrintedLoc = PrintDifference(OS, SM, B, {});
140  if (B != E) {
141  OS << ", ";
142  PrintDifference(OS, SM, E, PrintedLoc);
143  }
144  OS << '>';
145 }
146 
147 LLVM_DUMP_METHOD std::string
148 SourceRange::printToString(const SourceManager &SM) const {
149  std::string S;
150  llvm::raw_string_ostream OS(S);
151  print(OS, SM);
152  return S;
153 }
154 
155 //===----------------------------------------------------------------------===//
156 // FullSourceLoc
157 //===----------------------------------------------------------------------===//
158 
159 FileID FullSourceLoc::getFileID() const {
160  assert(isValid());
161  return SrcMgr->getFileID(*this);
162 }
163 
164 FullSourceLoc FullSourceLoc::getExpansionLoc() const {
165  assert(isValid());
166  return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr);
167 }
168 
169 std::pair<FileID, unsigned> FullSourceLoc::getDecomposedExpansionLoc() const {
170  return SrcMgr->getDecomposedExpansionLoc(*this);
171 }
172 
173 FullSourceLoc FullSourceLoc::getSpellingLoc() const {
174  assert(isValid());
175  return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
176 }
177 
178 FullSourceLoc FullSourceLoc::getFileLoc() const {
179  assert(isValid());
180  return FullSourceLoc(SrcMgr->getFileLoc(*this), *SrcMgr);
181 }
182 
183 PresumedLoc FullSourceLoc::getPresumedLoc(bool UseLineDirectives) const {
184  if (!isValid())
185  return PresumedLoc();
186 
187  return SrcMgr->getPresumedLoc(*this, UseLineDirectives);
188 }
189 
190 bool FullSourceLoc::isMacroArgExpansion(FullSourceLoc *StartLoc) const {
191  assert(isValid());
192  return SrcMgr->isMacroArgExpansion(*this, StartLoc);
193 }
194 
195 FullSourceLoc FullSourceLoc::getImmediateMacroCallerLoc() const {
196  assert(isValid());
197  return FullSourceLoc(SrcMgr->getImmediateMacroCallerLoc(*this), *SrcMgr);
198 }
199 
200 std::pair<FullSourceLoc, StringRef> FullSourceLoc::getModuleImportLoc() const {
201  if (!isValid())
202  return std::make_pair(FullSourceLoc(), StringRef());
203 
204  std::pair<SourceLocation, StringRef> ImportLoc =
205  SrcMgr->getModuleImportLoc(*this);
206  return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr),
207  ImportLoc.second);
208 }
209 
210 unsigned FullSourceLoc::getFileOffset() const {
211  assert(isValid());
212  return SrcMgr->getFileOffset(*this);
213 }
214 
215 unsigned FullSourceLoc::getLineNumber(bool *Invalid) const {
216  assert(isValid());
217  return SrcMgr->getLineNumber(getFileID(), getFileOffset(), Invalid);
218 }
219 
220 unsigned FullSourceLoc::getColumnNumber(bool *Invalid) const {
221  assert(isValid());
222  return SrcMgr->getColumnNumber(getFileID(), getFileOffset(), Invalid);
223 }
224 
225 const FileEntry *FullSourceLoc::getFileEntry() const {
226  assert(isValid());
227  return SrcMgr->getFileEntryForID(getFileID());
228 }
229 
230 OptionalFileEntryRef FullSourceLoc::getFileEntryRef() const {
231  assert(isValid());
232  return SrcMgr->getFileEntryRefForID(getFileID());
233 }
234 
235 unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const {
236  assert(isValid());
237  return SrcMgr->getExpansionLineNumber(*this, Invalid);
238 }
239 
240 unsigned FullSourceLoc::getExpansionColumnNumber(bool *Invalid) const {
241  assert(isValid());
242  return SrcMgr->getExpansionColumnNumber(*this, Invalid);
243 }
244 
245 unsigned FullSourceLoc::getSpellingLineNumber(bool *Invalid) const {
246  assert(isValid());
247  return SrcMgr->getSpellingLineNumber(*this, Invalid);
248 }
249 
250 unsigned FullSourceLoc::getSpellingColumnNumber(bool *Invalid) const {
251  assert(isValid());
252  return SrcMgr->getSpellingColumnNumber(*this, Invalid);
253 }
254 
255 bool FullSourceLoc::isInSystemHeader() const {
256  assert(isValid());
257  return SrcMgr->isInSystemHeader(*this);
258 }
259 
260 bool FullSourceLoc::isBeforeInTranslationUnitThan(SourceLocation Loc) const {
261  assert(isValid());
262  return SrcMgr->isBeforeInTranslationUnit(*this, Loc);
263 }
264 
265 LLVM_DUMP_METHOD void FullSourceLoc::dump() const {
266  SourceLocation::dump(*SrcMgr);
267 }
268 
269 const char *FullSourceLoc::getCharacterData(bool *Invalid) const {
270  assert(isValid());
271  return SrcMgr->getCharacterData(*this, Invalid);
272 }
273 
274 StringRef FullSourceLoc::getBufferData(bool *Invalid) const {
275  assert(isValid());
276  return SrcMgr->getBufferData(SrcMgr->getFileID(*this), Invalid);
277 }
278 
279 std::pair<FileID, unsigned> FullSourceLoc::getDecomposedLoc() const {
280  return SrcMgr->getDecomposedLoc(*this);
281 }
static char ID
Definition: Arena.cpp:183
#define SM(sm)
Definition: Cuda.cpp:83
#define X(type, name)
Definition: Value.h:143
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
void print(raw_ostream &OS) const override
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
void print(raw_ostream &OS, const SourceManager &SM) const
unsigned getHashValue() const
This class handles loading and caching of source files into memory.
The JSON file list parser is used to communicate input to InstallAPI.