clang  9.0.0svn
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/StringRef.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include <cassert>
22 #include <string>
23 #include <utility>
24 
25 using namespace clang;
26 
27 //===----------------------------------------------------------------------===//
28 // PrettyStackTraceLoc
29 //===----------------------------------------------------------------------===//
30 
31 void PrettyStackTraceLoc::print(raw_ostream &OS) const {
32  if (Loc.isValid()) {
33  Loc.print(OS, SM);
34  OS << ": ";
35  }
36  OS << Message << '\n';
37 }
38 
39 //===----------------------------------------------------------------------===//
40 // SourceLocation
41 //===----------------------------------------------------------------------===//
42 
43 void SourceLocation::print(raw_ostream &OS, const SourceManager &SM)const{
44  if (!isValid()) {
45  OS << "<invalid loc>";
46  return;
47  }
48 
49  if (isFileID()) {
50  PresumedLoc PLoc = SM.getPresumedLoc(*this);
51 
52  if (PLoc.isInvalid()) {
53  OS << "<invalid>";
54  return;
55  }
56  // The macro expansion and spelling pos is identical for file locs.
57  OS << PLoc.getFilename() << ':' << PLoc.getLine()
58  << ':' << PLoc.getColumn();
59  return;
60  }
61 
62  SM.getExpansionLoc(*this).print(OS, SM);
63 
64  OS << " <Spelling=";
65  SM.getSpellingLoc(*this).print(OS, SM);
66  OS << '>';
67 }
68 
69 LLVM_DUMP_METHOD std::string
70 SourceLocation::printToString(const SourceManager &SM) const {
71  std::string S;
72  llvm::raw_string_ostream OS(S);
73  print(OS, SM);
74  return OS.str();
75 }
76 
77 LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const {
78  print(llvm::errs(), SM);
79  llvm::errs() << '\n';
80 }
81 
82 LLVM_DUMP_METHOD void SourceRange::dump(const SourceManager &SM) const {
83  print(llvm::errs(), SM);
84  llvm::errs() << '\n';
85 }
86 
87 static PresumedLoc PrintDifference(raw_ostream &OS, const SourceManager &SM,
88  SourceLocation Loc, PresumedLoc Previous) {
89  if (Loc.isFileID()) {
90 
91  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
92 
93  if (PLoc.isInvalid()) {
94  OS << "<invalid sloc>";
95  return Previous;
96  }
97 
98  if (Previous.isInvalid() ||
99  strcmp(PLoc.getFilename(), Previous.getFilename()) != 0) {
100  OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
101  << PLoc.getColumn();
102  } else if (Previous.isInvalid() || PLoc.getLine() != Previous.getLine()) {
103  OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
104  } else {
105  OS << "col" << ':' << PLoc.getColumn();
106  }
107  return PLoc;
108  }
109  auto PrintedLoc = PrintDifference(OS, SM, SM.getExpansionLoc(Loc), Previous);
110 
111  OS << " <Spelling=";
112  PrintedLoc = PrintDifference(OS, SM, SM.getSpellingLoc(Loc), PrintedLoc);
113  OS << '>';
114  return PrintedLoc;
115 }
116 
117 void SourceRange::print(raw_ostream &OS, const SourceManager &SM) const {
118 
119  OS << '<';
120  auto PrintedLoc = PrintDifference(OS, SM, B, {});
121  if (B != E) {
122  OS << ", ";
123  PrintDifference(OS, SM, E, PrintedLoc);
124  }
125  OS << '>';
126 }
127 
128 LLVM_DUMP_METHOD std::string
129 SourceRange::printToString(const SourceManager &SM) const {
130  std::string S;
131  llvm::raw_string_ostream OS(S);
132  print(OS, SM);
133  return OS.str();
134 }
135 
136 //===----------------------------------------------------------------------===//
137 // FullSourceLoc
138 //===----------------------------------------------------------------------===//
139 
140 FileID FullSourceLoc::getFileID() const {
141  assert(isValid());
142  return SrcMgr->getFileID(*this);
143 }
144 
145 FullSourceLoc FullSourceLoc::getExpansionLoc() const {
146  assert(isValid());
147  return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr);
148 }
149 
150 FullSourceLoc FullSourceLoc::getSpellingLoc() const {
151  assert(isValid());
152  return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
153 }
154 
155 FullSourceLoc FullSourceLoc::getFileLoc() const {
156  assert(isValid());
157  return FullSourceLoc(SrcMgr->getFileLoc(*this), *SrcMgr);
158 }
159 
160 PresumedLoc FullSourceLoc::getPresumedLoc(bool UseLineDirectives) const {
161  if (!isValid())
162  return PresumedLoc();
163 
164  return SrcMgr->getPresumedLoc(*this, UseLineDirectives);
165 }
166 
167 bool FullSourceLoc::isMacroArgExpansion(FullSourceLoc *StartLoc) const {
168  assert(isValid());
169  return SrcMgr->isMacroArgExpansion(*this, StartLoc);
170 }
171 
172 FullSourceLoc FullSourceLoc::getImmediateMacroCallerLoc() const {
173  assert(isValid());
174  return FullSourceLoc(SrcMgr->getImmediateMacroCallerLoc(*this), *SrcMgr);
175 }
176 
177 std::pair<FullSourceLoc, StringRef> FullSourceLoc::getModuleImportLoc() const {
178  if (!isValid())
179  return std::make_pair(FullSourceLoc(), StringRef());
180 
181  std::pair<SourceLocation, StringRef> ImportLoc =
182  SrcMgr->getModuleImportLoc(*this);
183  return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr),
184  ImportLoc.second);
185 }
186 
187 unsigned FullSourceLoc::getFileOffset() const {
188  assert(isValid());
189  return SrcMgr->getFileOffset(*this);
190 }
191 
192 unsigned FullSourceLoc::getLineNumber(bool *Invalid) const {
193  assert(isValid());
194  return SrcMgr->getLineNumber(getFileID(), getFileOffset(), Invalid);
195 }
196 
197 unsigned FullSourceLoc::getColumnNumber(bool *Invalid) const {
198  assert(isValid());
199  return SrcMgr->getColumnNumber(getFileID(), getFileOffset(), Invalid);
200 }
201 
202 const FileEntry *FullSourceLoc::getFileEntry() const {
203  assert(isValid());
204  return SrcMgr->getFileEntryForID(getFileID());
205 }
206 
207 unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const {
208  assert(isValid());
209  return SrcMgr->getExpansionLineNumber(*this, Invalid);
210 }
211 
212 unsigned FullSourceLoc::getExpansionColumnNumber(bool *Invalid) const {
213  assert(isValid());
214  return SrcMgr->getExpansionColumnNumber(*this, Invalid);
215 }
216 
217 unsigned FullSourceLoc::getSpellingLineNumber(bool *Invalid) const {
218  assert(isValid());
219  return SrcMgr->getSpellingLineNumber(*this, Invalid);
220 }
221 
222 unsigned FullSourceLoc::getSpellingColumnNumber(bool *Invalid) const {
223  assert(isValid());
224  return SrcMgr->getSpellingColumnNumber(*this, Invalid);
225 }
226 
227 bool FullSourceLoc::isInSystemHeader() const {
228  assert(isValid());
229  return SrcMgr->isInSystemHeader(*this);
230 }
231 
232 bool FullSourceLoc::isBeforeInTranslationUnitThan(SourceLocation Loc) const {
233  assert(isValid());
234  return SrcMgr->isBeforeInTranslationUnit(*this, Loc);
235 }
236 
237 LLVM_DUMP_METHOD void FullSourceLoc::dump() const {
238  SourceLocation::dump(*SrcMgr);
239 }
240 
241 const char *FullSourceLoc::getCharacterData(bool *Invalid) const {
242  assert(isValid());
243  return SrcMgr->getCharacterData(*this, Invalid);
244 }
245 
246 StringRef FullSourceLoc::getBufferData(bool *Invalid) const {
247  assert(isValid());
248  return SrcMgr->getBuffer(SrcMgr->getFileID(*this), Invalid)->getBuffer();
249 }
250 
251 std::pair<FileID, unsigned> FullSourceLoc::getDecomposedLoc() const {
252  return SrcMgr->getDecomposedLoc(*this);
253 }
Defines the SourceManager interface.
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
void print(raw_ostream &OS) const override
void print(raw_ostream &OS, const SourceManager &SM) const
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
bool isInvalid() const
Return true if this object is invalid or uninitialized.
unsigned getLine() const
Return the presumed line number of this location.
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getColumn() const
Return the presumed column number of this location.
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
Defines the clang::SourceLocation class and associated facilities.
This class handles loading and caching of source files into memory.