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