LCOV - code coverage report
Current view: top level - clang/Basic - SourceLocation.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 6 6 100.0 %
Date: 2016-01-31 12:01:00 Functions: 6 6 100.0 %

          Line data    Source code
       1             : //===--- SourceLocation.h - Compact identifier for Source Files -*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : ///
      10             : /// \file
      11             : /// \brief Defines the clang::SourceLocation class and associated facilities.
      12             : ///
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H
      16             : #define LLVM_CLANG_BASIC_SOURCELOCATION_H
      17             : 
      18             : #include "clang/Basic/LLVM.h"
      19             : #include "llvm/Support/Compiler.h"
      20             : #include "llvm/Support/PointerLikeTypeTraits.h"
      21             : #include <cassert>
      22             : #include <functional>
      23             : #include <string>
      24             : #include <utility>
      25             : 
      26             : namespace llvm {
      27             :   class MemoryBuffer;
      28             :   template <typename T> struct DenseMapInfo;
      29             :   template <typename T> struct isPodLike;
      30             : }
      31             : 
      32             : namespace clang {
      33             : 
      34             : class SourceManager;
      35             : 
      36             : /// \brief An opaque identifier used by SourceManager which refers to a
      37             : /// source file (MemoryBuffer) along with its \#include path and \#line data.
      38             : ///
      39             : class FileID {
      40             :   /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is 
      41             :   /// this module, and <-1 is something loaded from another module.
      42             :   int ID;
      43             : public:
      44             :   FileID() : ID(0) {}
      45             : 
      46             :   bool isInvalid() const { return ID == 0; }
      47             : 
      48             :   bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
      49             :   bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
      50             :   bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
      51             :   bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
      52             :   bool operator>(const FileID &RHS) const { return RHS < *this; }
      53             :   bool operator>=(const FileID &RHS) const { return RHS <= *this; }
      54             : 
      55             :   static FileID getSentinel() { return get(-1); }
      56             :   unsigned getHashValue() const { return static_cast<unsigned>(ID); }
      57             : 
      58             : private:
      59             :   friend class SourceManager;
      60             :   friend class ASTWriter;
      61             :   friend class ASTReader;
      62             :   
      63             :   static FileID get(int V) {
      64             :     FileID F;
      65             :     F.ID = V;
      66             :     return F;
      67             :   }
      68             :   int getOpaqueValue() const { return ID; }
      69             : };
      70             : 
      71             : 
      72             : /// \brief Encodes a location in the source. The SourceManager can decode this
      73             : /// to get at the full include stack, line and column information.
      74             : ///
      75             : /// Technically, a source location is simply an offset into the manager's view
      76             : /// of the input source, which is all input buffers (including macro
      77             : /// expansions) concatenated in an effectively arbitrary order. The manager
      78             : /// actually maintains two blocks of input buffers. One, starting at offset
      79             : /// 0 and growing upwards, contains all buffers from this module. The other,
      80             : /// starting at the highest possible offset and growing downwards, contains
      81             : /// buffers of loaded modules.
      82             : ///
      83             : /// In addition, one bit of SourceLocation is used for quick access to the
      84             : /// information whether the location is in a file or a macro expansion.
      85             : ///
      86             : /// It is important that this type remains small. It is currently 32 bits wide.
      87             : class SourceLocation {
      88             :   unsigned ID;
      89             :   friend class SourceManager;
      90             :   friend class ASTReader;
      91             :   friend class ASTWriter;
      92             :   enum : unsigned {
      93             :     MacroIDBit = 1U << 31
      94             :   };
      95             : public:
      96             : 
      97          30 :   SourceLocation() : ID(0) {}
      98             : 
      99           2 :   bool isFileID() const  { return (ID & MacroIDBit) == 0; }
     100           6 :   bool isMacroID() const { return (ID & MacroIDBit) != 0; }
     101             : 
     102             :   /// \brief Return true if this is a valid SourceLocation object.
     103             :   ///
     104             :   /// Invalid SourceLocations are often used when events have no corresponding
     105             :   /// location in the source (e.g. a diagnostic is required for a command line
     106             :   /// option).
     107          30 :   bool isValid() const { return ID != 0; }
     108             :   bool isInvalid() const { return ID == 0; }
     109             : 
     110             : private:
     111             :   /// \brief Return the offset into the manager's global input view.
     112             :   unsigned getOffset() const {
     113             :     return ID & ~MacroIDBit;
     114             :   }
     115             : 
     116             :   static SourceLocation getFileLoc(unsigned ID) {
     117             :     assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
     118             :     SourceLocation L;
     119             :     L.ID = ID;
     120             :     return L;
     121             :   }
     122             : 
     123             :   static SourceLocation getMacroLoc(unsigned ID) {
     124             :     assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
     125             :     SourceLocation L;
     126             :     L.ID = MacroIDBit | ID;
     127             :     return L;
     128             :   }
     129             : public:
     130             : 
     131             :   /// \brief Return a source location with the specified offset from this
     132             :   /// SourceLocation.
     133             :   SourceLocation getLocWithOffset(int Offset) const {
     134             :     assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
     135             :     SourceLocation L;
     136             :     L.ID = ID+Offset;
     137             :     return L;
     138             :   }
     139             : 
     140             :   /// \brief When a SourceLocation itself cannot be used, this returns
     141             :   /// an (opaque) 32-bit integer encoding for it.
     142             :   ///
     143             :   /// This should only be passed to SourceLocation::getFromRawEncoding, it
     144             :   /// should not be inspected directly.
     145         146 :   unsigned getRawEncoding() const { return ID; }
     146             : 
     147             :   /// \brief Turn a raw encoding of a SourceLocation object into
     148             :   /// a real SourceLocation.
     149             :   ///
     150             :   /// \see getRawEncoding.
     151             :   static SourceLocation getFromRawEncoding(unsigned Encoding) {
     152             :     SourceLocation X;
     153             :     X.ID = Encoding;
     154             :     return X;
     155             :   }
     156             : 
     157             :   /// \brief When a SourceLocation itself cannot be used, this returns
     158             :   /// an (opaque) pointer encoding for it.
     159             :   ///
     160             :   /// This should only be passed to SourceLocation::getFromPtrEncoding, it
     161             :   /// should not be inspected directly.
     162             :   void* getPtrEncoding() const {
     163             :     // Double cast to avoid a warning "cast to pointer from integer of different
     164             :     // size".
     165             :     return (void*)(uintptr_t)getRawEncoding();
     166             :   }
     167             : 
     168             :   /// \brief Turn a pointer encoding of a SourceLocation object back
     169             :   /// into a real SourceLocation.
     170             :   static SourceLocation getFromPtrEncoding(const void *Encoding) {
     171             :     return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
     172             :   }
     173             : 
     174             :   void print(raw_ostream &OS, const SourceManager &SM) const;
     175             :   std::string printToString(const SourceManager &SM) const;
     176             :   void dump(const SourceManager &SM) const;
     177             : };
     178             : 
     179             : inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
     180             :   return LHS.getRawEncoding() == RHS.getRawEncoding();
     181             : }
     182             : 
     183             : inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
     184             :   return !(LHS == RHS);
     185             : }
     186             : 
     187             : inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
     188          73 :   return LHS.getRawEncoding() < RHS.getRawEncoding();
     189             : }
     190             : 
     191             : /// \brief A trivial tuple used to represent a source range.
     192             : class SourceRange {
     193             :   SourceLocation B;
     194             :   SourceLocation E;
     195             : public:
     196             :   SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
     197             :   SourceRange(SourceLocation loc) : B(loc), E(loc) {}
     198             :   SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
     199             : 
     200             :   SourceLocation getBegin() const { return B; }
     201             :   SourceLocation getEnd() const { return E; }
     202             : 
     203             :   void setBegin(SourceLocation b) { B = b; }
     204             :   void setEnd(SourceLocation e) { E = e; }
     205             : 
     206             :   bool isValid() const { return B.isValid() && E.isValid(); }
     207             :   bool isInvalid() const { return !isValid(); }
     208             : 
     209             :   bool operator==(const SourceRange &X) const {
     210             :     return B == X.B && E == X.E;
     211             :   }
     212             : 
     213             :   bool operator!=(const SourceRange &X) const {
     214             :     return B != X.B || E != X.E;
     215             :   }
     216             : };
     217             :   
     218             : /// \brief Represents a character-granular source range.
     219             : ///
     220             : /// The underlying SourceRange can either specify the starting/ending character
     221             : /// of the range, or it can specify the start of the range and the start of the
     222             : /// last token of the range (a "token range").  In the token range case, the
     223             : /// size of the last token must be measured to determine the actual end of the
     224             : /// range.
     225             : class CharSourceRange { 
     226             :   SourceRange Range;
     227             :   bool IsTokenRange;
     228             : public:
     229             :   CharSourceRange() : IsTokenRange(false) {}
     230             :   CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
     231             : 
     232             :   static CharSourceRange getTokenRange(SourceRange R) {
     233             :     return CharSourceRange(R, true);
     234             :   }
     235             : 
     236             :   static CharSourceRange getCharRange(SourceRange R) {
     237             :     return CharSourceRange(R, false);
     238             :   }
     239             :     
     240             :   static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
     241             :     return getTokenRange(SourceRange(B, E));
     242             :   }
     243             :   static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) {
     244             :     return getCharRange(SourceRange(B, E));
     245             :   }
     246             :   
     247             :   /// \brief Return true if the end of this range specifies the start of
     248             :   /// the last token.  Return false if the end of this range specifies the last
     249             :   /// character in the range.
     250             :   bool isTokenRange() const { return IsTokenRange; }
     251             :   bool isCharRange() const { return !IsTokenRange; }
     252             :   
     253             :   SourceLocation getBegin() const { return Range.getBegin(); }
     254             :   SourceLocation getEnd() const { return Range.getEnd(); }
     255             :   const SourceRange &getAsRange() const { return Range; }
     256             :  
     257             :   void setBegin(SourceLocation b) { Range.setBegin(b); }
     258             :   void setEnd(SourceLocation e) { Range.setEnd(e); }
     259             :   
     260             :   bool isValid() const { return Range.isValid(); }
     261             :   bool isInvalid() const { return !isValid(); }
     262             : };
     263             : 
     264             : /// \brief A SourceLocation and its associated SourceManager.
     265             : ///
     266             : /// This is useful for argument passing to functions that expect both objects.
     267             : class FullSourceLoc : public SourceLocation {
     268             :   const SourceManager *SrcMgr;
     269             : public:
     270             :   /// \brief Creates a FullSourceLoc where isValid() returns \c false.
     271             :   explicit FullSourceLoc() : SrcMgr(nullptr) {}
     272             : 
     273             :   explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
     274             :     : SourceLocation(Loc), SrcMgr(&SM) {}
     275             : 
     276             :   /// \pre This FullSourceLoc has an associated SourceManager.
     277             :   const SourceManager &getManager() const {
     278             :     assert(SrcMgr && "SourceManager is NULL.");
     279             :     return *SrcMgr;
     280             :   }
     281             : 
     282             :   FileID getFileID() const;
     283             : 
     284             :   FullSourceLoc getExpansionLoc() const;
     285             :   FullSourceLoc getSpellingLoc() const;
     286             : 
     287             :   unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
     288             :   unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
     289             : 
     290             :   unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
     291             :   unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
     292             : 
     293             :   const char *getCharacterData(bool *Invalid = nullptr) const;
     294             : 
     295             : 
     296             :   /// \brief Return a StringRef to the source buffer data for the
     297             :   /// specified FileID.
     298             :   StringRef getBufferData(bool *Invalid = nullptr) const;
     299             : 
     300             :   /// \brief Decompose the specified location into a raw FileID + Offset pair.
     301             :   ///
     302             :   /// The first element is the FileID, the second is the offset from the
     303             :   /// start of the buffer of the location.
     304             :   std::pair<FileID, unsigned> getDecomposedLoc() const;
     305             : 
     306             :   bool isInSystemHeader() const;
     307             : 
     308             :   /// \brief Determines the order of 2 source locations in the translation unit.
     309             :   ///
     310             :   /// \returns true if this source location comes before 'Loc', false otherwise.
     311             :   bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
     312             : 
     313             :   /// \brief Determines the order of 2 source locations in the translation unit.
     314             :   ///
     315             :   /// \returns true if this source location comes before 'Loc', false otherwise.
     316             :   bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const {
     317             :     assert(Loc.isValid());
     318             :     assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
     319             :     return isBeforeInTranslationUnitThan((SourceLocation)Loc);
     320             :   }
     321             : 
     322             :   /// \brief Comparison function class, useful for sorting FullSourceLocs.
     323             :   struct BeforeThanCompare : public std::binary_function<FullSourceLoc,
     324             :                                                          FullSourceLoc, bool> {
     325             :     bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
     326             :       return lhs.isBeforeInTranslationUnitThan(rhs);
     327             :     }
     328             :   };
     329             : 
     330             :   /// \brief Prints information about this FullSourceLoc to stderr.
     331             :   ///
     332             :   /// This is useful for debugging.
     333             :   void dump() const;
     334             : 
     335             :   friend inline bool
     336             :   operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
     337             :     return LHS.getRawEncoding() == RHS.getRawEncoding() &&
     338             :           LHS.SrcMgr == RHS.SrcMgr;
     339             :   }
     340             : 
     341             :   friend inline bool
     342             :   operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
     343             :     return !(LHS == RHS);
     344             :   }
     345             : 
     346             : };
     347             : 
     348             : /// \brief Represents an unpacked "presumed" location which can be presented
     349             : /// to the user.
     350             : ///
     351             : /// A 'presumed' location can be modified by \#line and GNU line marker
     352             : /// directives and is always the expansion point of a normal location.
     353             : ///
     354             : /// You can get a PresumedLoc from a SourceLocation with SourceManager.
     355             : class PresumedLoc {
     356             :   const char *Filename;
     357             :   unsigned Line, Col;
     358             :   SourceLocation IncludeLoc;
     359             : public:
     360             :   PresumedLoc() : Filename(nullptr) {}
     361             :   PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
     362             :     : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
     363             :   }
     364             : 
     365             :   /// \brief Return true if this object is invalid or uninitialized.
     366             :   ///
     367             :   /// This occurs when created with invalid source locations or when walking
     368             :   /// off the top of a \#include stack.
     369             :   bool isInvalid() const { return Filename == nullptr; }
     370             :   bool isValid() const { return Filename != nullptr; }
     371             : 
     372             :   /// \brief Return the presumed filename of this location.
     373             :   ///
     374             :   /// This can be affected by \#line etc.
     375             :   const char *getFilename() const { return Filename; }
     376             : 
     377             :   /// \brief Return the presumed line number of this location.
     378             :   ///
     379             :   /// This can be affected by \#line etc.
     380             :   unsigned getLine() const { return Line; }
     381             : 
     382             :   /// \brief Return the presumed column number of this location.
     383             :   ///
     384             :   /// This cannot be affected by \#line, but is packaged here for convenience.
     385             :   unsigned getColumn() const { return Col; }
     386             : 
     387             :   /// \brief Return the presumed include location of this location.
     388             :   ///
     389             :   /// This can be affected by GNU linemarker directives.
     390             :   SourceLocation getIncludeLoc() const { return IncludeLoc; }
     391             : };
     392             : 
     393             : 
     394             : }  // end namespace clang
     395             : 
     396             : namespace llvm {
     397             :   /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
     398             :   /// DenseSets.
     399             :   template <>
     400             :   struct DenseMapInfo<clang::FileID> {
     401             :     static inline clang::FileID getEmptyKey() {
     402             :       return clang::FileID();
     403             :     }
     404             :     static inline clang::FileID getTombstoneKey() {
     405             :       return clang::FileID::getSentinel();
     406             :     }
     407             : 
     408             :     static unsigned getHashValue(clang::FileID S) {
     409             :       return S.getHashValue();
     410             :     }
     411             : 
     412             :     static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
     413             :       return LHS == RHS;
     414             :     }
     415             :   };
     416             :   
     417             :   template <>
     418             :   struct isPodLike<clang::SourceLocation> { static const bool value = true; };
     419             :   template <>
     420             :   struct isPodLike<clang::FileID> { static const bool value = true; };
     421             : 
     422             :   // Teach SmallPtrSet how to handle SourceLocation.
     423             :   template<>
     424             :   class PointerLikeTypeTraits<clang::SourceLocation> {
     425             :   public:
     426             :     static inline void *getAsVoidPointer(clang::SourceLocation L) {
     427             :       return L.getPtrEncoding();
     428             :     }
     429             :     static inline clang::SourceLocation getFromVoidPointer(void *P) {
     430             :       return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P);
     431             :     }
     432             :     enum { NumLowBitsAvailable = 0 };
     433             :   };
     434             : 
     435             : }  // end namespace llvm
     436             : 
     437             : #endif

Generated by: LCOV version 1.11