SourceLocation.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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. #include "clang/Basic/SourceLocation.h"
  13. #include "clang/Basic/LLVM.h"
  14. #include "clang/Basic/PrettyStackTrace.h"
  15. #include "clang/Basic/SourceManager.h"
  16. #include "llvm/ADT/DenseMapInfo.h"
  17. #include "llvm/ADT/FoldingSet.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. using namespace clang;
  26. //===----------------------------------------------------------------------===//
  27. // PrettyStackTraceLoc
  28. //===----------------------------------------------------------------------===//
  29. void PrettyStackTraceLoc::print(raw_ostream &OS) const {
  30. if (Loc.isValid()) {
  31. Loc.print(OS, SM);
  32. OS << ": ";
  33. }
  34. OS << Message << '\n';
  35. }
  36. //===----------------------------------------------------------------------===//
  37. // SourceLocation
  38. //===----------------------------------------------------------------------===//
  39. static_assert(std::is_trivially_destructible_v<SourceLocation>,
  40. "SourceLocation must be trivially destructible because it is "
  41. "used in unions");
  42. static_assert(std::is_trivially_destructible_v<SourceRange>,
  43. "SourceRange must be trivially destructible because it is "
  44. "used in unions");
  45. unsigned SourceLocation::getHashValue() const {
  46. return llvm::DenseMapInfo<UIntTy>::getHashValue(ID);
  47. }
  48. void llvm::FoldingSetTrait<SourceLocation>::Profile(
  49. const SourceLocation &X, llvm::FoldingSetNodeID &ID) {
  50. ID.AddInteger(X.ID);
  51. }
  52. void SourceLocation::print(raw_ostream &OS, const SourceManager &SM)const{
  53. if (!isValid()) {
  54. OS << "<invalid loc>";
  55. return;
  56. }
  57. if (isFileID()) {
  58. PresumedLoc PLoc = SM.getPresumedLoc(*this);
  59. if (PLoc.isInvalid()) {
  60. OS << "<invalid>";
  61. return;
  62. }
  63. // The macro expansion and spelling pos is identical for file locs.
  64. OS << PLoc.getFilename() << ':' << PLoc.getLine()
  65. << ':' << PLoc.getColumn();
  66. return;
  67. }
  68. SM.getExpansionLoc(*this).print(OS, SM);
  69. OS << " <Spelling=";
  70. SM.getSpellingLoc(*this).print(OS, SM);
  71. OS << '>';
  72. }
  73. LLVM_DUMP_METHOD std::string
  74. SourceLocation::printToString(const SourceManager &SM) const {
  75. std::string S;
  76. llvm::raw_string_ostream OS(S);
  77. print(OS, SM);
  78. return S;
  79. }
  80. LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const {
  81. print(llvm::errs(), SM);
  82. llvm::errs() << '\n';
  83. }
  84. LLVM_DUMP_METHOD void SourceRange::dump(const SourceManager &SM) const {
  85. print(llvm::errs(), SM);
  86. llvm::errs() << '\n';
  87. }
  88. static PresumedLoc PrintDifference(raw_ostream &OS, const SourceManager &SM,
  89. SourceLocation Loc, PresumedLoc Previous) {
  90. if (Loc.isFileID()) {
  91. PresumedLoc PLoc = SM.getPresumedLoc(Loc);
  92. if (PLoc.isInvalid()) {
  93. OS << "<invalid sloc>";
  94. return Previous;
  95. }
  96. if (Previous.isInvalid() ||
  97. strcmp(PLoc.getFilename(), Previous.getFilename()) != 0) {
  98. OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
  99. << PLoc.getColumn();
  100. } else if (Previous.isInvalid() || PLoc.getLine() != Previous.getLine()) {
  101. OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
  102. } else {
  103. OS << "col" << ':' << PLoc.getColumn();
  104. }
  105. return PLoc;
  106. }
  107. auto PrintedLoc = PrintDifference(OS, SM, SM.getExpansionLoc(Loc), Previous);
  108. OS << " <Spelling=";
  109. PrintedLoc = PrintDifference(OS, SM, SM.getSpellingLoc(Loc), PrintedLoc);
  110. OS << '>';
  111. return PrintedLoc;
  112. }
  113. void SourceRange::print(raw_ostream &OS, const SourceManager &SM) const {
  114. OS << '<';
  115. auto PrintedLoc = PrintDifference(OS, SM, B, {});
  116. if (B != E) {
  117. OS << ", ";
  118. PrintDifference(OS, SM, E, PrintedLoc);
  119. }
  120. OS << '>';
  121. }
  122. LLVM_DUMP_METHOD std::string
  123. SourceRange::printToString(const SourceManager &SM) const {
  124. std::string S;
  125. llvm::raw_string_ostream OS(S);
  126. print(OS, SM);
  127. return S;
  128. }
  129. //===----------------------------------------------------------------------===//
  130. // FullSourceLoc
  131. //===----------------------------------------------------------------------===//
  132. FileID FullSourceLoc::getFileID() const {
  133. assert(isValid());
  134. return SrcMgr->getFileID(*this);
  135. }
  136. FullSourceLoc FullSourceLoc::getExpansionLoc() const {
  137. assert(isValid());
  138. return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr);
  139. }
  140. std::pair<FileID, unsigned> FullSourceLoc::getDecomposedExpansionLoc() const {
  141. return SrcMgr->getDecomposedExpansionLoc(*this);
  142. }
  143. FullSourceLoc FullSourceLoc::getSpellingLoc() const {
  144. assert(isValid());
  145. return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
  146. }
  147. FullSourceLoc FullSourceLoc::getFileLoc() const {
  148. assert(isValid());
  149. return FullSourceLoc(SrcMgr->getFileLoc(*this), *SrcMgr);
  150. }
  151. PresumedLoc FullSourceLoc::getPresumedLoc(bool UseLineDirectives) const {
  152. if (!isValid())
  153. return PresumedLoc();
  154. return SrcMgr->getPresumedLoc(*this, UseLineDirectives);
  155. }
  156. bool FullSourceLoc::isMacroArgExpansion(FullSourceLoc *StartLoc) const {
  157. assert(isValid());
  158. return SrcMgr->isMacroArgExpansion(*this, StartLoc);
  159. }
  160. FullSourceLoc FullSourceLoc::getImmediateMacroCallerLoc() const {
  161. assert(isValid());
  162. return FullSourceLoc(SrcMgr->getImmediateMacroCallerLoc(*this), *SrcMgr);
  163. }
  164. std::pair<FullSourceLoc, StringRef> FullSourceLoc::getModuleImportLoc() const {
  165. if (!isValid())
  166. return std::make_pair(FullSourceLoc(), StringRef());
  167. std::pair<SourceLocation, StringRef> ImportLoc =
  168. SrcMgr->getModuleImportLoc(*this);
  169. return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr),
  170. ImportLoc.second);
  171. }
  172. unsigned FullSourceLoc::getFileOffset() const {
  173. assert(isValid());
  174. return SrcMgr->getFileOffset(*this);
  175. }
  176. unsigned FullSourceLoc::getLineNumber(bool *Invalid) const {
  177. assert(isValid());
  178. return SrcMgr->getLineNumber(getFileID(), getFileOffset(), Invalid);
  179. }
  180. unsigned FullSourceLoc::getColumnNumber(bool *Invalid) const {
  181. assert(isValid());
  182. return SrcMgr->getColumnNumber(getFileID(), getFileOffset(), Invalid);
  183. }
  184. const FileEntry *FullSourceLoc::getFileEntry() const {
  185. assert(isValid());
  186. return SrcMgr->getFileEntryForID(getFileID());
  187. }
  188. unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const {
  189. assert(isValid());
  190. return SrcMgr->getExpansionLineNumber(*this, Invalid);
  191. }
  192. unsigned FullSourceLoc::getExpansionColumnNumber(bool *Invalid) const {
  193. assert(isValid());
  194. return SrcMgr->getExpansionColumnNumber(*this, Invalid);
  195. }
  196. unsigned FullSourceLoc::getSpellingLineNumber(bool *Invalid) const {
  197. assert(isValid());
  198. return SrcMgr->getSpellingLineNumber(*this, Invalid);
  199. }
  200. unsigned FullSourceLoc::getSpellingColumnNumber(bool *Invalid) const {
  201. assert(isValid());
  202. return SrcMgr->getSpellingColumnNumber(*this, Invalid);
  203. }
  204. bool FullSourceLoc::isInSystemHeader() const {
  205. assert(isValid());
  206. return SrcMgr->isInSystemHeader(*this);
  207. }
  208. bool FullSourceLoc::isBeforeInTranslationUnitThan(SourceLocation Loc) const {
  209. assert(isValid());
  210. return SrcMgr->isBeforeInTranslationUnit(*this, Loc);
  211. }
  212. LLVM_DUMP_METHOD void FullSourceLoc::dump() const {
  213. SourceLocation::dump(*SrcMgr);
  214. }
  215. const char *FullSourceLoc::getCharacterData(bool *Invalid) const {
  216. assert(isValid());
  217. return SrcMgr->getCharacterData(*this, Invalid);
  218. }
  219. StringRef FullSourceLoc::getBufferData(bool *Invalid) const {
  220. assert(isValid());
  221. return SrcMgr->getBufferData(SrcMgr->getFileID(*this), Invalid);
  222. }
  223. std::pair<FileID, unsigned> FullSourceLoc::getDecomposedLoc() const {
  224. return SrcMgr->getDecomposedLoc(*this);
  225. }