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