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