File indexing completed on 2026-05-10 08:37:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include "clang/Basic/SourceLocation.h"
0034 #include "llvm/Support/MathExtras.h"
0035 #include <climits>
0036
0037 #ifndef LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H
0038 #define LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H
0039
0040 namespace clang {
0041 class SourceLocationSequence;
0042
0043
0044
0045
0046
0047 class SourceLocationEncoding {
0048 using UIntTy = SourceLocation::UIntTy;
0049 constexpr static unsigned UIntBits = CHAR_BIT * sizeof(UIntTy);
0050
0051 static UIntTy encodeRaw(UIntTy Raw) {
0052 return (Raw << 1) | (Raw >> (UIntBits - 1));
0053 }
0054 static UIntTy decodeRaw(UIntTy Raw) {
0055 return (Raw >> 1) | (Raw << (UIntBits - 1));
0056 }
0057 friend SourceLocationSequence;
0058
0059 public:
0060 using RawLocEncoding = uint64_t;
0061
0062 static RawLocEncoding encode(SourceLocation Loc, UIntTy BaseOffset,
0063 unsigned BaseModuleFileIndex,
0064 SourceLocationSequence * = nullptr);
0065 static std::pair<SourceLocation, unsigned>
0066 decode(RawLocEncoding, SourceLocationSequence * = nullptr);
0067 };
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 class SourceLocationSequence {
0097 using UIntTy = SourceLocation::UIntTy;
0098 using EncodedTy = uint64_t;
0099 constexpr static auto UIntBits = SourceLocationEncoding::UIntBits;
0100 static_assert(sizeof(EncodedTy) > sizeof(UIntTy), "Need one extra bit!");
0101
0102
0103 UIntTy &Prev;
0104
0105
0106
0107 static UIntTy zigZag(UIntTy V) {
0108 UIntTy Sign = (V & (1 << (UIntBits - 1))) ? UIntTy(-1) : UIntTy(0);
0109 return Sign ^ (V << 1);
0110 }
0111 static UIntTy zagZig(UIntTy V) { return (V >> 1) ^ -(V & 1); }
0112
0113 SourceLocationSequence(UIntTy &Prev) : Prev(Prev) {}
0114
0115 EncodedTy encodeRaw(UIntTy Raw) {
0116 if (Raw == 0)
0117 return 0;
0118 UIntTy Rotated = SourceLocationEncoding::encodeRaw(Raw);
0119 if (Prev == 0)
0120 return Prev = Rotated;
0121 UIntTy Delta = Rotated - Prev;
0122 Prev = Rotated;
0123
0124
0125 return 1 + EncodedTy{zigZag(Delta)};
0126 }
0127 UIntTy decodeRaw(EncodedTy Encoded) {
0128 if (Encoded == 0)
0129 return 0;
0130 if (Prev == 0)
0131 return SourceLocationEncoding::decodeRaw(Prev = Encoded);
0132 return SourceLocationEncoding::decodeRaw(Prev += zagZig(Encoded - 1));
0133 }
0134
0135 public:
0136 SourceLocation decode(EncodedTy Encoded) {
0137 return SourceLocation::getFromRawEncoding(decodeRaw(Encoded));
0138 }
0139 EncodedTy encode(SourceLocation Loc) {
0140 return encodeRaw(Loc.getRawEncoding());
0141 }
0142
0143 class State;
0144 };
0145
0146
0147 class SourceLocationSequence::State {
0148 UIntTy Prev = 0;
0149 SourceLocationSequence Seq;
0150
0151 public:
0152
0153
0154 State(SourceLocationSequence *Parent = nullptr)
0155 : Seq(Parent ? Parent->Prev : Prev) {}
0156
0157
0158 operator SourceLocationSequence *() { return &Seq; }
0159 };
0160
0161 inline SourceLocationEncoding::RawLocEncoding
0162 SourceLocationEncoding::encode(SourceLocation Loc, UIntTy BaseOffset,
0163 unsigned BaseModuleFileIndex,
0164 SourceLocationSequence *Seq) {
0165
0166
0167 if (!BaseOffset)
0168 return Seq ? Seq->encode(Loc) : encodeRaw(Loc.getRawEncoding());
0169
0170 if (Loc.isInvalid())
0171 return 0;
0172
0173
0174
0175
0176 assert(Loc.getOffset() >= BaseOffset);
0177 Loc = Loc.getLocWithOffset(-BaseOffset);
0178 RawLocEncoding Encoded = encodeRaw(Loc.getRawEncoding());
0179
0180
0181 assert(BaseModuleFileIndex < (1 << 16));
0182 Encoded |= (RawLocEncoding)BaseModuleFileIndex << 32;
0183 return Encoded;
0184 }
0185 inline std::pair<SourceLocation, unsigned>
0186 SourceLocationEncoding::decode(RawLocEncoding Encoded,
0187 SourceLocationSequence *Seq) {
0188 unsigned ModuleFileIndex = Encoded >> 32;
0189
0190 if (!ModuleFileIndex)
0191 return {Seq ? Seq->decode(Encoded)
0192 : SourceLocation::getFromRawEncoding(decodeRaw(Encoded)),
0193 ModuleFileIndex};
0194
0195 Encoded &= llvm::maskTrailingOnes<RawLocEncoding>(32);
0196 SourceLocation Loc = SourceLocation::getFromRawEncoding(decodeRaw(Encoded));
0197
0198 return {Loc, ModuleFileIndex};
0199 }
0200
0201 }
0202 #endif