clang API Documentation
00001 //===--- SourceLocation.h - Compact identifier for Source Files -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief Defines the clang::SourceLocation class and associated facilities. 00012 /// 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H 00016 #define LLVM_CLANG_BASIC_SOURCELOCATION_H 00017 00018 #include "clang/Basic/LLVM.h" 00019 #include "llvm/Support/Compiler.h" 00020 #include "llvm/Support/PointerLikeTypeTraits.h" 00021 #include <cassert> 00022 #include <functional> 00023 #include <string> 00024 #include <utility> 00025 00026 namespace llvm { 00027 class MemoryBuffer; 00028 template <typename T> struct DenseMapInfo; 00029 template <typename T> struct isPodLike; 00030 } 00031 00032 namespace clang { 00033 00034 class SourceManager; 00035 00036 /// \brief An opaque identifier used by SourceManager which refers to a 00037 /// source file (MemoryBuffer) along with its \#include path and \#line data. 00038 /// 00039 class FileID { 00040 /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is 00041 /// this module, and <-1 is something loaded from another module. 00042 int ID; 00043 public: 00044 FileID() : ID(0) {} 00045 00046 bool isInvalid() const { return ID == 0; } 00047 00048 bool operator==(const FileID &RHS) const { return ID == RHS.ID; } 00049 bool operator<(const FileID &RHS) const { return ID < RHS.ID; } 00050 bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; } 00051 bool operator!=(const FileID &RHS) const { return !(*this == RHS); } 00052 bool operator>(const FileID &RHS) const { return RHS < *this; } 00053 bool operator>=(const FileID &RHS) const { return RHS <= *this; } 00054 00055 static FileID getSentinel() { return get(-1); } 00056 unsigned getHashValue() const { return static_cast<unsigned>(ID); } 00057 00058 private: 00059 friend class SourceManager; 00060 friend class ASTWriter; 00061 friend class ASTReader; 00062 00063 static FileID get(int V) { 00064 FileID F; 00065 F.ID = V; 00066 return F; 00067 } 00068 int getOpaqueValue() const { return ID; } 00069 }; 00070 00071 00072 /// \brief Encodes a location in the source. The SourceManager can decode this 00073 /// to get at the full include stack, line and column information. 00074 /// 00075 /// Technically, a source location is simply an offset into the manager's view 00076 /// of the input source, which is all input buffers (including macro 00077 /// expansions) concatenated in an effectively arbitrary order. The manager 00078 /// actually maintains two blocks of input buffers. One, starting at offset 00079 /// 0 and growing upwards, contains all buffers from this module. The other, 00080 /// starting at the highest possible offset and growing downwards, contains 00081 /// buffers of loaded modules. 00082 /// 00083 /// In addition, one bit of SourceLocation is used for quick access to the 00084 /// information whether the location is in a file or a macro expansion. 00085 /// 00086 /// It is important that this type remains small. It is currently 32 bits wide. 00087 class SourceLocation { 00088 unsigned ID; 00089 friend class SourceManager; 00090 friend class ASTReader; 00091 friend class ASTWriter; 00092 enum : unsigned { 00093 MacroIDBit = 1U << 31 00094 }; 00095 public: 00096 00097 SourceLocation() : ID(0) {} 00098 00099 bool isFileID() const { return (ID & MacroIDBit) == 0; } 00100 bool isMacroID() const { return (ID & MacroIDBit) != 0; } 00101 00102 /// \brief Return true if this is a valid SourceLocation object. 00103 /// 00104 /// Invalid SourceLocations are often used when events have no corresponding 00105 /// location in the source (e.g. a diagnostic is required for a command line 00106 /// option). 00107 bool isValid() const { return ID != 0; } 00108 bool isInvalid() const { return ID == 0; } 00109 00110 private: 00111 /// \brief Return the offset into the manager's global input view. 00112 unsigned getOffset() const { 00113 return ID & ~MacroIDBit; 00114 } 00115 00116 static SourceLocation getFileLoc(unsigned ID) { 00117 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!"); 00118 SourceLocation L; 00119 L.ID = ID; 00120 return L; 00121 } 00122 00123 static SourceLocation getMacroLoc(unsigned ID) { 00124 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!"); 00125 SourceLocation L; 00126 L.ID = MacroIDBit | ID; 00127 return L; 00128 } 00129 public: 00130 00131 /// \brief Return a source location with the specified offset from this 00132 /// SourceLocation. 00133 SourceLocation getLocWithOffset(int Offset) const { 00134 assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow"); 00135 SourceLocation L; 00136 L.ID = ID+Offset; 00137 return L; 00138 } 00139 00140 /// \brief When a SourceLocation itself cannot be used, this returns 00141 /// an (opaque) 32-bit integer encoding for it. 00142 /// 00143 /// This should only be passed to SourceLocation::getFromRawEncoding, it 00144 /// should not be inspected directly. 00145 unsigned getRawEncoding() const { return ID; } 00146 00147 /// \brief Turn a raw encoding of a SourceLocation object into 00148 /// a real SourceLocation. 00149 /// 00150 /// \see getRawEncoding. 00151 static SourceLocation getFromRawEncoding(unsigned Encoding) { 00152 SourceLocation X; 00153 X.ID = Encoding; 00154 return X; 00155 } 00156 00157 /// \brief When a SourceLocation itself cannot be used, this returns 00158 /// an (opaque) pointer encoding for it. 00159 /// 00160 /// This should only be passed to SourceLocation::getFromPtrEncoding, it 00161 /// should not be inspected directly. 00162 void* getPtrEncoding() const { 00163 // Double cast to avoid a warning "cast to pointer from integer of different 00164 // size". 00165 return (void*)(uintptr_t)getRawEncoding(); 00166 } 00167 00168 /// \brief Turn a pointer encoding of a SourceLocation object back 00169 /// into a real SourceLocation. 00170 static SourceLocation getFromPtrEncoding(const void *Encoding) { 00171 return getFromRawEncoding((unsigned)(uintptr_t)Encoding); 00172 } 00173 00174 void print(raw_ostream &OS, const SourceManager &SM) const; 00175 std::string printToString(const SourceManager &SM) const; 00176 void dump(const SourceManager &SM) const; 00177 }; 00178 00179 inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) { 00180 return LHS.getRawEncoding() == RHS.getRawEncoding(); 00181 } 00182 00183 inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) { 00184 return !(LHS == RHS); 00185 } 00186 00187 inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) { 00188 return LHS.getRawEncoding() < RHS.getRawEncoding(); 00189 } 00190 00191 /// \brief A trivial tuple used to represent a source range. 00192 class SourceRange { 00193 SourceLocation B; 00194 SourceLocation E; 00195 public: 00196 SourceRange(): B(SourceLocation()), E(SourceLocation()) {} 00197 SourceRange(SourceLocation loc) : B(loc), E(loc) {} 00198 SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {} 00199 00200 SourceLocation getBegin() const { return B; } 00201 SourceLocation getEnd() const { return E; } 00202 00203 void setBegin(SourceLocation b) { B = b; } 00204 void setEnd(SourceLocation e) { E = e; } 00205 00206 bool isValid() const { return B.isValid() && E.isValid(); } 00207 bool isInvalid() const { return !isValid(); } 00208 00209 bool operator==(const SourceRange &X) const { 00210 return B == X.B && E == X.E; 00211 } 00212 00213 bool operator!=(const SourceRange &X) const { 00214 return B != X.B || E != X.E; 00215 } 00216 }; 00217 00218 /// \brief Represents a character-granular source range. 00219 /// 00220 /// The underlying SourceRange can either specify the starting/ending character 00221 /// of the range, or it can specify the start of the range and the start of the 00222 /// last token of the range (a "token range"). In the token range case, the 00223 /// size of the last token must be measured to determine the actual end of the 00224 /// range. 00225 class CharSourceRange { 00226 SourceRange Range; 00227 bool IsTokenRange; 00228 public: 00229 CharSourceRange() : IsTokenRange(false) {} 00230 CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {} 00231 00232 static CharSourceRange getTokenRange(SourceRange R) { 00233 return CharSourceRange(R, true); 00234 } 00235 00236 static CharSourceRange getCharRange(SourceRange R) { 00237 return CharSourceRange(R, false); 00238 } 00239 00240 static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) { 00241 return getTokenRange(SourceRange(B, E)); 00242 } 00243 static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) { 00244 return getCharRange(SourceRange(B, E)); 00245 } 00246 00247 /// \brief Return true if the end of this range specifies the start of 00248 /// the last token. Return false if the end of this range specifies the last 00249 /// character in the range. 00250 bool isTokenRange() const { return IsTokenRange; } 00251 bool isCharRange() const { return !IsTokenRange; } 00252 00253 SourceLocation getBegin() const { return Range.getBegin(); } 00254 SourceLocation getEnd() const { return Range.getEnd(); } 00255 const SourceRange &getAsRange() const { return Range; } 00256 00257 void setBegin(SourceLocation b) { Range.setBegin(b); } 00258 void setEnd(SourceLocation e) { Range.setEnd(e); } 00259 00260 bool isValid() const { return Range.isValid(); } 00261 bool isInvalid() const { return !isValid(); } 00262 }; 00263 00264 /// \brief A SourceLocation and its associated SourceManager. 00265 /// 00266 /// This is useful for argument passing to functions that expect both objects. 00267 class FullSourceLoc : public SourceLocation { 00268 const SourceManager *SrcMgr; 00269 public: 00270 /// \brief Creates a FullSourceLoc where isValid() returns \c false. 00271 explicit FullSourceLoc() : SrcMgr(nullptr) {} 00272 00273 explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM) 00274 : SourceLocation(Loc), SrcMgr(&SM) {} 00275 00276 /// \pre This FullSourceLoc has an associated SourceManager. 00277 const SourceManager &getManager() const { 00278 assert(SrcMgr && "SourceManager is NULL."); 00279 return *SrcMgr; 00280 } 00281 00282 FileID getFileID() const; 00283 00284 FullSourceLoc getExpansionLoc() const; 00285 FullSourceLoc getSpellingLoc() const; 00286 00287 unsigned getExpansionLineNumber(bool *Invalid = nullptr) const; 00288 unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const; 00289 00290 unsigned getSpellingLineNumber(bool *Invalid = nullptr) const; 00291 unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const; 00292 00293 const char *getCharacterData(bool *Invalid = nullptr) const; 00294 00295 00296 /// \brief Return a StringRef to the source buffer data for the 00297 /// specified FileID. 00298 StringRef getBufferData(bool *Invalid = nullptr) const; 00299 00300 /// \brief Decompose the specified location into a raw FileID + Offset pair. 00301 /// 00302 /// The first element is the FileID, the second is the offset from the 00303 /// start of the buffer of the location. 00304 std::pair<FileID, unsigned> getDecomposedLoc() const; 00305 00306 bool isInSystemHeader() const; 00307 00308 /// \brief Determines the order of 2 source locations in the translation unit. 00309 /// 00310 /// \returns true if this source location comes before 'Loc', false otherwise. 00311 bool isBeforeInTranslationUnitThan(SourceLocation Loc) const; 00312 00313 /// \brief Determines the order of 2 source locations in the translation unit. 00314 /// 00315 /// \returns true if this source location comes before 'Loc', false otherwise. 00316 bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const { 00317 assert(Loc.isValid()); 00318 assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!"); 00319 return isBeforeInTranslationUnitThan((SourceLocation)Loc); 00320 } 00321 00322 /// \brief Comparison function class, useful for sorting FullSourceLocs. 00323 struct BeforeThanCompare : public std::binary_function<FullSourceLoc, 00324 FullSourceLoc, bool> { 00325 bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const { 00326 return lhs.isBeforeInTranslationUnitThan(rhs); 00327 } 00328 }; 00329 00330 /// \brief Prints information about this FullSourceLoc to stderr. 00331 /// 00332 /// This is useful for debugging. 00333 void dump() const; 00334 00335 friend inline bool 00336 operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) { 00337 return LHS.getRawEncoding() == RHS.getRawEncoding() && 00338 LHS.SrcMgr == RHS.SrcMgr; 00339 } 00340 00341 friend inline bool 00342 operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) { 00343 return !(LHS == RHS); 00344 } 00345 00346 }; 00347 00348 /// \brief Represents an unpacked "presumed" location which can be presented 00349 /// to the user. 00350 /// 00351 /// A 'presumed' location can be modified by \#line and GNU line marker 00352 /// directives and is always the expansion point of a normal location. 00353 /// 00354 /// You can get a PresumedLoc from a SourceLocation with SourceManager. 00355 class PresumedLoc { 00356 const char *Filename; 00357 unsigned Line, Col; 00358 SourceLocation IncludeLoc; 00359 public: 00360 PresumedLoc() : Filename(nullptr) {} 00361 PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL) 00362 : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) { 00363 } 00364 00365 /// \brief Return true if this object is invalid or uninitialized. 00366 /// 00367 /// This occurs when created with invalid source locations or when walking 00368 /// off the top of a \#include stack. 00369 bool isInvalid() const { return Filename == nullptr; } 00370 bool isValid() const { return Filename != nullptr; } 00371 00372 /// \brief Return the presumed filename of this location. 00373 /// 00374 /// This can be affected by \#line etc. 00375 const char *getFilename() const { return Filename; } 00376 00377 /// \brief Return the presumed line number of this location. 00378 /// 00379 /// This can be affected by \#line etc. 00380 unsigned getLine() const { return Line; } 00381 00382 /// \brief Return the presumed column number of this location. 00383 /// 00384 /// This cannot be affected by \#line, but is packaged here for convenience. 00385 unsigned getColumn() const { return Col; } 00386 00387 /// \brief Return the presumed include location of this location. 00388 /// 00389 /// This can be affected by GNU linemarker directives. 00390 SourceLocation getIncludeLoc() const { return IncludeLoc; } 00391 }; 00392 00393 00394 } // end namespace clang 00395 00396 namespace llvm { 00397 /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and 00398 /// DenseSets. 00399 template <> 00400 struct DenseMapInfo<clang::FileID> { 00401 static inline clang::FileID getEmptyKey() { 00402 return clang::FileID(); 00403 } 00404 static inline clang::FileID getTombstoneKey() { 00405 return clang::FileID::getSentinel(); 00406 } 00407 00408 static unsigned getHashValue(clang::FileID S) { 00409 return S.getHashValue(); 00410 } 00411 00412 static bool isEqual(clang::FileID LHS, clang::FileID RHS) { 00413 return LHS == RHS; 00414 } 00415 }; 00416 00417 template <> 00418 struct isPodLike<clang::SourceLocation> { static const bool value = true; }; 00419 template <> 00420 struct isPodLike<clang::FileID> { static const bool value = true; }; 00421 00422 // Teach SmallPtrSet how to handle SourceLocation. 00423 template<> 00424 class PointerLikeTypeTraits<clang::SourceLocation> { 00425 public: 00426 static inline void *getAsVoidPointer(clang::SourceLocation L) { 00427 return L.getPtrEncoding(); 00428 } 00429 static inline clang::SourceLocation getFromVoidPointer(void *P) { 00430 return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P); 00431 } 00432 enum { NumLowBitsAvailable = 0 }; 00433 }; 00434 00435 } // end namespace llvm 00436 00437 #endif