|  | //===- SourceLocation.cpp - Compact identifier for Source Files -----------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | //  This file defines accessor methods for the FullSourceLoc class. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "clang/Basic/SourceLocation.h" | 
|  | #include "clang/Basic/LLVM.h" | 
|  | #include "clang/Basic/PrettyStackTrace.h" | 
|  | #include "clang/Basic/SourceManager.h" | 
|  | #include "llvm/ADT/DenseMapInfo.h" | 
|  | #include "llvm/ADT/FoldingSet.h" | 
|  | #include "llvm/Support/Compiler.h" | 
|  | #include "llvm/Support/raw_ostream.h" | 
|  | #include <cassert> | 
|  | #include <string> | 
|  | #include <utility> | 
|  |  | 
|  | using namespace clang; | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // PrettyStackTraceLoc | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | void PrettyStackTraceLoc::print(raw_ostream &OS) const { | 
|  | if (Loc.isValid()) { | 
|  | Loc.print(OS, SM); | 
|  | OS << ": "; | 
|  | } | 
|  | OS << Message << '\n'; | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // SourceLocation | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | static_assert(std::is_trivially_destructible_v<SourceLocation>, | 
|  | "SourceLocation must be trivially destructible because it is " | 
|  | "used in unions"); | 
|  |  | 
|  | static_assert(std::is_trivially_destructible_v<SourceRange>, | 
|  | "SourceRange must be trivially destructible because it is " | 
|  | "used in unions"); | 
|  |  | 
|  | unsigned SourceLocation::getHashValue() const { | 
|  | return llvm::DenseMapInfo<UIntTy>::getHashValue(ID); | 
|  | } | 
|  |  | 
|  | void llvm::FoldingSetTrait<SourceLocation>::Profile( | 
|  | const SourceLocation &X, llvm::FoldingSetNodeID &ID) { | 
|  | ID.AddInteger(X.ID); | 
|  | } | 
|  |  | 
|  | void SourceLocation::print(raw_ostream &OS, const SourceManager &SM)const{ | 
|  | if (!isValid()) { | 
|  | OS << "<invalid loc>"; | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (isFileID()) { | 
|  | PresumedLoc PLoc = SM.getPresumedLoc(*this); | 
|  |  | 
|  | if (PLoc.isInvalid()) { | 
|  | OS << "<invalid>"; | 
|  | return; | 
|  | } | 
|  | // The macro expansion and spelling pos is identical for file locs. | 
|  | OS << PLoc.getFilename() << ':' << PLoc.getLine() | 
|  | << ':' << PLoc.getColumn(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | SM.getExpansionLoc(*this).print(OS, SM); | 
|  |  | 
|  | OS << " <Spelling="; | 
|  | SM.getSpellingLoc(*this).print(OS, SM); | 
|  | OS << '>'; | 
|  | } | 
|  |  | 
|  | LLVM_DUMP_METHOD std::string | 
|  | SourceLocation::printToString(const SourceManager &SM) const { | 
|  | std::string S; | 
|  | llvm::raw_string_ostream OS(S); | 
|  | print(OS, SM); | 
|  | return S; | 
|  | } | 
|  |  | 
|  | LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const { | 
|  | print(llvm::errs(), SM); | 
|  | llvm::errs() << '\n'; | 
|  | } | 
|  |  | 
|  | LLVM_DUMP_METHOD void SourceRange::dump(const SourceManager &SM) const { | 
|  | print(llvm::errs(), SM); | 
|  | llvm::errs() << '\n'; | 
|  | } | 
|  |  | 
|  | static PresumedLoc PrintDifference(raw_ostream &OS, const SourceManager &SM, | 
|  | SourceLocation Loc, PresumedLoc Previous) { | 
|  | if (Loc.isFileID()) { | 
|  |  | 
|  | PresumedLoc PLoc = SM.getPresumedLoc(Loc); | 
|  |  | 
|  | if (PLoc.isInvalid()) { | 
|  | OS << "<invalid sloc>"; | 
|  | return Previous; | 
|  | } | 
|  |  | 
|  | if (Previous.isInvalid() || | 
|  | strcmp(PLoc.getFilename(), Previous.getFilename()) != 0) { | 
|  | OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':' | 
|  | << PLoc.getColumn(); | 
|  | } else if (Previous.isInvalid() || PLoc.getLine() != Previous.getLine()) { | 
|  | OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn(); | 
|  | } else { | 
|  | OS << "col" << ':' << PLoc.getColumn(); | 
|  | } | 
|  | return PLoc; | 
|  | } | 
|  | auto PrintedLoc = PrintDifference(OS, SM, SM.getExpansionLoc(Loc), Previous); | 
|  |  | 
|  | OS << " <Spelling="; | 
|  | PrintedLoc = PrintDifference(OS, SM, SM.getSpellingLoc(Loc), PrintedLoc); | 
|  | OS << '>'; | 
|  | return PrintedLoc; | 
|  | } | 
|  |  | 
|  | void SourceRange::print(raw_ostream &OS, const SourceManager &SM) const { | 
|  |  | 
|  | OS << '<'; | 
|  | auto PrintedLoc = PrintDifference(OS, SM, B, {}); | 
|  | if (B != E) { | 
|  | OS << ", "; | 
|  | PrintDifference(OS, SM, E, PrintedLoc); | 
|  | } | 
|  | OS << '>'; | 
|  | } | 
|  |  | 
|  | LLVM_DUMP_METHOD std::string | 
|  | SourceRange::printToString(const SourceManager &SM) const { | 
|  | std::string S; | 
|  | llvm::raw_string_ostream OS(S); | 
|  | print(OS, SM); | 
|  | return S; | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // FullSourceLoc | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | FileID FullSourceLoc::getFileID() const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getFileID(*this); | 
|  | } | 
|  |  | 
|  | FullSourceLoc FullSourceLoc::getExpansionLoc() const { | 
|  | assert(isValid()); | 
|  | return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr); | 
|  | } | 
|  |  | 
|  | FileIDAndOffset FullSourceLoc::getDecomposedExpansionLoc() const { | 
|  | return SrcMgr->getDecomposedExpansionLoc(*this); | 
|  | } | 
|  |  | 
|  | FullSourceLoc FullSourceLoc::getSpellingLoc() const { | 
|  | assert(isValid()); | 
|  | return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr); | 
|  | } | 
|  |  | 
|  | FullSourceLoc FullSourceLoc::getFileLoc() const { | 
|  | assert(isValid()); | 
|  | return FullSourceLoc(SrcMgr->getFileLoc(*this), *SrcMgr); | 
|  | } | 
|  |  | 
|  | PresumedLoc FullSourceLoc::getPresumedLoc(bool UseLineDirectives) const { | 
|  | if (!isValid()) | 
|  | return PresumedLoc(); | 
|  |  | 
|  | return SrcMgr->getPresumedLoc(*this, UseLineDirectives); | 
|  | } | 
|  |  | 
|  | bool FullSourceLoc::isMacroArgExpansion(FullSourceLoc *StartLoc) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->isMacroArgExpansion(*this, StartLoc); | 
|  | } | 
|  |  | 
|  | FullSourceLoc FullSourceLoc::getImmediateMacroCallerLoc() const { | 
|  | assert(isValid()); | 
|  | return FullSourceLoc(SrcMgr->getImmediateMacroCallerLoc(*this), *SrcMgr); | 
|  | } | 
|  |  | 
|  | std::pair<FullSourceLoc, StringRef> FullSourceLoc::getModuleImportLoc() const { | 
|  | if (!isValid()) | 
|  | return std::make_pair(FullSourceLoc(), StringRef()); | 
|  |  | 
|  | std::pair<SourceLocation, StringRef> ImportLoc = | 
|  | SrcMgr->getModuleImportLoc(*this); | 
|  | return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr), | 
|  | ImportLoc.second); | 
|  | } | 
|  |  | 
|  | unsigned FullSourceLoc::getFileOffset() const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getFileOffset(*this); | 
|  | } | 
|  |  | 
|  | unsigned FullSourceLoc::getLineNumber(bool *Invalid) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getLineNumber(getFileID(), getFileOffset(), Invalid); | 
|  | } | 
|  |  | 
|  | unsigned FullSourceLoc::getColumnNumber(bool *Invalid) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getColumnNumber(getFileID(), getFileOffset(), Invalid); | 
|  | } | 
|  |  | 
|  | const FileEntry *FullSourceLoc::getFileEntry() const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getFileEntryForID(getFileID()); | 
|  | } | 
|  |  | 
|  | OptionalFileEntryRef FullSourceLoc::getFileEntryRef() const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getFileEntryRefForID(getFileID()); | 
|  | } | 
|  |  | 
|  | unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getExpansionLineNumber(*this, Invalid); | 
|  | } | 
|  |  | 
|  | unsigned FullSourceLoc::getExpansionColumnNumber(bool *Invalid) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getExpansionColumnNumber(*this, Invalid); | 
|  | } | 
|  |  | 
|  | unsigned FullSourceLoc::getSpellingLineNumber(bool *Invalid) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getSpellingLineNumber(*this, Invalid); | 
|  | } | 
|  |  | 
|  | unsigned FullSourceLoc::getSpellingColumnNumber(bool *Invalid) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getSpellingColumnNumber(*this, Invalid); | 
|  | } | 
|  |  | 
|  | bool FullSourceLoc::isInSystemHeader() const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->isInSystemHeader(*this); | 
|  | } | 
|  |  | 
|  | bool FullSourceLoc::isBeforeInTranslationUnitThan(SourceLocation Loc) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->isBeforeInTranslationUnit(*this, Loc); | 
|  | } | 
|  |  | 
|  | LLVM_DUMP_METHOD void FullSourceLoc::dump() const { | 
|  | SourceLocation::dump(*SrcMgr); | 
|  | } | 
|  |  | 
|  | const char *FullSourceLoc::getCharacterData(bool *Invalid) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getCharacterData(*this, Invalid); | 
|  | } | 
|  |  | 
|  | StringRef FullSourceLoc::getBufferData(bool *Invalid) const { | 
|  | assert(isValid()); | 
|  | return SrcMgr->getBufferData(SrcMgr->getFileID(*this), Invalid); | 
|  | } | 
|  |  | 
|  | FileIDAndOffset FullSourceLoc::getDecomposedLoc() const { | 
|  | return SrcMgr->getDecomposedLoc(*this); | 
|  | } |