SourceLocation.cpp 7.1 KB

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