SourceLocation.h revision 877e6a6fb05660a3cc3fc24bcbef4df5e4702423
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===--- SourceLocation.h - Compact identifier for Source Files -*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// \file
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// \brief Defines the clang::SourceLocation class and associated facilities.
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)///
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===//
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_CLANG_SOURCELOCATION_H
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_CLANG_SOURCELOCATION_H
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/Basic/LLVM.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/Compiler.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "llvm/Support/PointerLikeTypeTraits.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cassert>
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <functional>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <utility>
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace llvm {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MemoryBuffer;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename T> struct DenseMapInfo;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename T> struct isPodLike;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace clang {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class SourceManager;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/// \brief An opaque identifier used by SourceManager which refers to a
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// source file (MemoryBuffer) along with its \#include path and \#line data.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileID {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// this module, and <-1 is something loaded from another module.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int ID;
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)public:
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FileID() : ID(0) {}
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool isInvalid() const { return ID == 0; }
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator>(const FileID &RHS) const { return RHS < *this; }
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool operator>=(const FileID &RHS) const { return RHS <= *this; }
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  static FileID getSentinel() { return get(-1); }
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  unsigned getHashValue() const { return static_cast<unsigned>(ID); }
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)private:
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  friend class SourceManager;
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  friend class ASTWriter;
610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  friend class ASTReader;
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static FileID get(int V) {
640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    FileID F;
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    F.ID = V;
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return F;
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int getOpaqueValue() const { return ID; }
690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// \brief Encodes a location in the source. The SourceManager can decode this
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// to get at the full include stack, line and column information.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// Technically, a source location is simply an offset into the manager's view
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// of the input source, which is all input buffers (including macro
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// expansions) concatenated in an effectively arbitrary order. The manager
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// actually maintains two blocks of input buffers. One, starting at offset
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// 0 and growing upwards, contains all buffers from this module. The other,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// starting at the highest possible offset and growing downwards, contains
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// buffers of loaded modules.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)///
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/// In addition, one bit of SourceLocation is used for quick access to the
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// information whether the location is in a file or a macro expansion.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)///
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// It is important that this type remains small. It is currently 32 bits wide.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SourceLocation {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned ID;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class SourceManager;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class ASTReader;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class ASTWriter;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum LLVM_ENUM_INT_TYPE(unsigned) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MacroIDBit = 1U << 31
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)public:
96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SourceLocation() : ID(0) {}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool isFileID() const  { return (ID & MacroIDBit) == 0; }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool isMacroID() const { return (ID & MacroIDBit) != 0; }
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// \brief Return true if this is a valid SourceLocation object.
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /// Invalid SourceLocations are often used when events have no corresponding
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /// location in the source (e.g. a diagnostic is required for a command line
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /// option).
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool isValid() const { return ID != 0; }
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool isInvalid() const { return ID == 0; }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)private:
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  /// \brief Return the offset into the manager's global input view.
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  unsigned getOffset() const {
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return ID & ~MacroIDBit;
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static SourceLocation getFileLoc(unsigned ID) {
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SourceLocation L;
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    L.ID = ID;
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return L;
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static SourceLocation getMacroLoc(unsigned ID) {
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SourceLocation L;
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    L.ID = MacroIDBit | ID;
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return L;
128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)public:
13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  /// \brief Return a source location with the specified offset from this
13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  /// SourceLocation.
13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  SourceLocation getLocWithOffset(int Offset) const {
13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    SourceLocation L;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    L.ID = ID+Offset;
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return L;
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  /// \brief When a SourceLocation itself cannot be used, this returns
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  /// an (opaque) 32-bit integer encoding for it.
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ///
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// This should only be passed to SourceLocation::getFromRawEncoding, it
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  /// should not be inspected directly.
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  unsigned getRawEncoding() const { return ID; }
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// \brief Turn a raw encoding of a SourceLocation object into
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// a real SourceLocation.
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ///
150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// \see getRawEncoding.
151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  static SourceLocation getFromRawEncoding(unsigned Encoding) {
152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SourceLocation X;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    X.ID = Encoding;
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return X;
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// \brief When a SourceLocation itself cannot be used, this returns
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// an (opaque) pointer encoding for it.
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// This should only be passed to SourceLocation::getFromPtrEncoding, it
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// should not be inspected directly.
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void* getPtrEncoding() const {
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Double cast to avoid a warning "cast to pointer from integer of different
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // size".
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return (void*)(uintptr_t)getRawEncoding();
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// \brief Turn a pointer encoding of a SourceLocation object back
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// into a real SourceLocation.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static SourceLocation getFromPtrEncoding(const void *Encoding) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void print(raw_ostream &OS, const SourceManager &SM) const;
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LLVM_ATTRIBUTE_USED std::string printToString(const SourceManager &SM) const;
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void dump(const SourceManager &SM) const;
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return LHS.getRawEncoding() == RHS.getRawEncoding();
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return !(LHS == RHS);
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return LHS.getRawEncoding() < RHS.getRawEncoding();
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)/// \brief A trival tuple used to represent a source range.
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class SourceRange {
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SourceLocation B;
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SourceLocation E;
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)public:
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SourceRange(SourceLocation loc) : B(loc), E(loc) {}
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SourceLocation getBegin() const { return B; }
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SourceLocation getEnd() const { return E; }
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void setBegin(SourceLocation b) { B = b; }
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void setEnd(SourceLocation e) { E = e; }
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool isValid() const { return B.isValid() && E.isValid(); }
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool isInvalid() const { return !isValid(); }
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool operator==(const SourceRange &X) const {
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return B == X.B && E == X.E;
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool operator!=(const SourceRange &X) const {
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return B != X.B || E != X.E;
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/// \brief Represents a character-granular source range.
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch///
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/// The underlying SourceRange can either specify the starting/ending character
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/// of the range, or it can specify the start of the range and the start of the
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/// last token of the range (a "token range").  In the token range case, the
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/// size of the last token must be measured to determine the actual end of the
2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)/// range.
2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class CharSourceRange {
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SourceRange Range;
2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool IsTokenRange;
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochpublic:
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CharSourceRange() : IsTokenRange(false) {}
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static CharSourceRange getTokenRange(SourceRange R) {
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return CharSourceRange(R, true);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static CharSourceRange getCharRange(SourceRange R) {
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return CharSourceRange(R, false);
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return getTokenRange(SourceRange(B, E));
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) {
2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return getCharRange(SourceRange(B, E));
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  /// \brief Return true if the end of this range specifies the start of
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// the last token.  Return false if the end of this range specifies the last
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// character in the range.
250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool isTokenRange() const { return IsTokenRange; }
251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool isCharRange() const { return !IsTokenRange; }
252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
253ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SourceLocation getBegin() const { return Range.getBegin(); }
254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SourceLocation getEnd() const { return Range.getEnd(); }
255ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const SourceRange &getAsRange() const { return Range; }
256558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
257558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void setBegin(SourceLocation b) { Range.setBegin(b); }
258558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void setEnd(SourceLocation e) { Range.setEnd(e); }
259558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool isValid() const { return Range.isValid(); }
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool isInvalid() const { return !isValid(); }
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
263558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
264558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/// \brief A SourceLocation and its associated SourceManager.
265558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch///
266558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/// This is useful for argument passing to functions that expect both objects.
267558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass FullSourceLoc : public SourceLocation {
268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  const SourceManager *SrcMgr;
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)public:
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// \brief Creates a FullSourceLoc where isValid() returns \c false.
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit FullSourceLoc() : SrcMgr(0) {}
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : SourceLocation(Loc), SrcMgr(&SM) {}
275558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
276558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /// \pre This FullSourceLoc has an associated SourceManager.
277558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  const SourceManager &getManager() const {
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    assert(SrcMgr && "SourceManager is NULL.");
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return *SrcMgr;
280c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  }
281558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  FileID getFileID() const;
283558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  FullSourceLoc getExpansionLoc() const;
285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  FullSourceLoc getSpellingLoc() const;
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
287558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  unsigned getExpansionLineNumber(bool *Invalid = 0) const;
288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  unsigned getExpansionColumnNumber(bool *Invalid = 0) const;
289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
290558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  unsigned getSpellingLineNumber(bool *Invalid = 0) const;
291558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  unsigned getSpellingColumnNumber(bool *Invalid = 0) const;
292558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
293558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  const char *getCharacterData(bool *Invalid = 0) const;
294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
295558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  const llvm::MemoryBuffer* getBuffer(bool *Invalid = 0) const;
2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  /// \brief Return a StringRef to the source buffer data for the
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  /// specified FileID.
299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  StringRef getBufferData(bool *Invalid = 0) const;
300558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /// \brief Decompose the specified location into a raw FileID + Offset pair.
302558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ///
303558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /// The first element is the FileID, the second is the offset from the
304558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /// start of the buffer of the location.
305558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  std::pair<FileID, unsigned> getDecomposedLoc() const;
306558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
307558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool isInSystemHeader() const;
308558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
309558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /// \brief Determines the order of 2 source locations in the translation unit.
310558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ///
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /// \returns true if this source location comes before 'Loc', false otherwise.
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /// \brief Determines the order of 2 source locations in the translation unit.
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ///
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /// \returns true if this source location comes before 'Loc', false otherwise.
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const {
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    assert(Loc.isValid());
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return isBeforeInTranslationUnitThan((SourceLocation)Loc);
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /// \brief Comparison function class, useful for sorting FullSourceLocs.
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  struct BeforeThanCompare : public std::binary_function<FullSourceLoc,
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                         FullSourceLoc, bool> {
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return lhs.isBeforeInTranslationUnitThan(rhs);
328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// \brief Prints information about this FullSourceLoc to stderr.
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ///
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// This is useful for debugging.
334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  LLVM_ATTRIBUTE_USED void dump() const;
335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend inline bool
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LHS.getRawEncoding() == RHS.getRawEncoding() &&
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          LHS.SrcMgr == RHS.SrcMgr;
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend inline bool
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return !(LHS == RHS);
345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/// \brief Represents an unpacked "presumed" location which can be presented
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/// to the user.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)/// A 'presumed' location can be modified by \#line and GNU line marker
3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)/// directives and is always the expansion point of a normal location.
3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)///
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/// You can get a PresumedLoc from a SourceLocation with SourceManager.
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class PresumedLoc {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *Filename;
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned Line, Col;
3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SourceLocation IncludeLoc;
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public:
3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PresumedLoc() : Filename(0) {}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /// \brief Return true if this object is invalid or uninitialized.
3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ///
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// This occurs when created with invalid source locations or when walking
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /// off the top of a \#include stack.
3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool isInvalid() const { return Filename == 0; }
3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool isValid() const { return Filename != 0; }
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /// \brief Return the presumed filename of this location.
3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ///
3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /// This can be affected by \#line etc.
3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char *getFilename() const { return Filename; }
3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// \brief Return the presumed line number of this location.
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// This can be affected by \#line etc.
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned getLine() const { return Line; }
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \brief Return the presumed column number of this location.
3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ///
3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /// This cannot be affected by \#line, but is packaged here for convenience.
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  unsigned getColumn() const { return Col; }
3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// \brief Return the presumed include location of this location.
3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ///
39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /// This can be affected by GNU linemarker directives.
3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SourceLocation getIncludeLoc() const { return IncludeLoc; }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // end namespace clang
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace llvm {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /// DenseSets.
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <>
4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  struct DenseMapInfo<clang::FileID> {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static inline clang::FileID getEmptyKey() {
4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return clang::FileID();
404d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
405d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    static inline clang::FileID getTombstoneKey() {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return clang::FileID::getSentinel();
4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    static unsigned getHashValue(clang::FileID S) {
410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      return S.getHashValue();
4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return LHS == RHS;
415b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  template <>
41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  template <>
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct isPodLike<clang::FileID> { static const bool value = true; };
4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Teach SmallPtrSet how to handle SourceLocation.
4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  template<>
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  class PointerLikeTypeTraits<clang::SourceLocation> {
4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  public:
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    static inline void *getAsVoidPointer(clang::SourceLocation L) {
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return L.getPtrEncoding();
429d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
430d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    static inline clang::SourceLocation getFromVoidPointer(void *P) {
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P);
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    enum { NumLowBitsAvailable = 0 };
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // end namespace llvm
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)