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