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