clang 20.0.0git
SourceLocation.h
Go to the documentation of this file.
1//===- SourceLocation.h - Compact identifier for Source Files ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines the clang::SourceLocation class and associated facilities.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H
15#define LLVM_CLANG_BASIC_SOURCELOCATION_H
16
18#include "clang/Basic/LLVM.h"
19#include "llvm/ADT/StringRef.h"
20#include <cassert>
21#include <cstdint>
22#include <string>
23#include <utility>
24
25namespace llvm {
26
27class FoldingSetNodeID;
28template <typename T, typename Enable> struct FoldingSetTrait;
29
30} // namespace llvm
31
32namespace clang {
33
34class SourceManager;
35
36/// An opaque identifier used by SourceManager which refers to a
37/// source file (MemoryBuffer) along with its \#include path and \#line data.
38///
39class FileID {
40 /// A mostly-opaque identifier, where 0 is "invalid", >0 is
41 /// this module, and <-1 is something loaded from another module.
42 int ID = 0;
43
44public:
45 bool isValid() const { return ID != 0; }
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
58private:
59 friend class ASTWriter;
60 friend class ASTReader;
61 friend class SourceManager;
63
64 static FileID get(int V) {
65 FileID F;
66 F.ID = V;
67 return F;
68 }
69
70 int getOpaqueValue() const { return ID; }
71};
72
73/// Encodes a location in the source. The SourceManager can decode this
74/// to get at the full include stack, line and column information.
75///
76/// Technically, a source location is simply an offset into the manager's view
77/// of the input source, which is all input buffers (including macro
78/// expansions) concatenated in an effectively arbitrary order. The manager
79/// actually maintains two blocks of input buffers. One, starting at offset
80/// 0 and growing upwards, contains all buffers from this module. The other,
81/// starting at the highest possible offset and growing downwards, contains
82/// buffers of loaded modules.
83///
84/// In addition, one bit of SourceLocation is used for quick access to the
85/// information whether the location is in a file or a macro expansion.
86///
87/// It is important that this type remains small. It is currently 32 bits wide.
89 friend class ASTReader;
90 friend class ASTWriter;
91 friend class SourceManager;
92 friend struct llvm::FoldingSetTrait<SourceLocation, void>;
94
95public:
96 using UIntTy = uint32_t;
97 using IntTy = int32_t;
98
99private:
100 UIntTy ID = 0;
101
102 enum : UIntTy { MacroIDBit = 1ULL << (8 * sizeof(UIntTy) - 1) };
103
104public:
105 bool isFileID() const { return (ID & MacroIDBit) == 0; }
106 bool isMacroID() const { return (ID & MacroIDBit) != 0; }
107
108 /// Return true if this is a valid SourceLocation object.
109 ///
110 /// Invalid SourceLocations are often used when events have no corresponding
111 /// location in the source (e.g. a diagnostic is required for a command line
112 /// option).
113 bool isValid() const { return ID != 0; }
114 bool isInvalid() const { return ID == 0; }
115
116private:
117 /// Return the offset into the manager's global input view.
118 UIntTy getOffset() const { return ID & ~MacroIDBit; }
119
120 static SourceLocation getFileLoc(UIntTy ID) {
121 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
122 SourceLocation L;
123 L.ID = ID;
124 return L;
125 }
126
127 static SourceLocation getMacroLoc(UIntTy ID) {
128 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
129 SourceLocation L;
130 L.ID = MacroIDBit | ID;
131 return L;
132 }
133
134public:
135 /// Return a source location with the specified offset from this
136 /// SourceLocation.
138 assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
140 L.ID = ID+Offset;
141 return L;
142 }
143
144 /// When a SourceLocation itself cannot be used, this returns
145 /// an (opaque) 32-bit integer encoding for it.
146 ///
147 /// This should only be passed to SourceLocation::getFromRawEncoding, it
148 /// should not be inspected directly.
149 UIntTy getRawEncoding() const { return ID; }
150
151 /// Turn a raw encoding of a SourceLocation object into
152 /// a real SourceLocation.
153 ///
154 /// \see getRawEncoding.
157 X.ID = Encoding;
158 return X;
159 }
160
161 /// When a SourceLocation itself cannot be used, this returns
162 /// an (opaque) pointer encoding for it.
163 ///
164 /// This should only be passed to SourceLocation::getFromPtrEncoding, it
165 /// should not be inspected directly.
166 void* getPtrEncoding() const {
167 // Double cast to avoid a warning "cast to pointer from integer of different
168 // size".
169 return (void*)(uintptr_t)getRawEncoding();
170 }
171
172 /// Turn a pointer encoding of a SourceLocation object back
173 /// into a real SourceLocation.
174 static SourceLocation getFromPtrEncoding(const void *Encoding) {
176 }
177
179 return Start.isValid() && Start.isFileID() && End.isValid() &&
180 End.isFileID();
181 }
182
183 unsigned getHashValue() const;
184 void print(raw_ostream &OS, const SourceManager &SM) const;
185 std::string printToString(const SourceManager &SM) const;
186 void dump(const SourceManager &SM) const;
187};
188
189inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
190 return LHS.getRawEncoding() == RHS.