File indexing completed on 2026-05-10 08:36:27
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_AST_ABSTRACTBASICREADER_H
0010 #define LLVM_CLANG_AST_ABSTRACTBASICREADER_H
0011
0012 #include "clang/AST/DeclTemplate.h"
0013 #include <optional>
0014
0015 namespace clang {
0016 namespace serialization {
0017
0018 template <class T>
0019 inline T makeNullableFromOptional(const std::optional<T> &value) {
0020 return (value ? *value : T());
0021 }
0022
0023 template <class T> inline T *makePointerFromOptional(std::optional<T *> value) {
0024 return value.value_or(nullptr);
0025 }
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
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
0097
0098
0099
0100
0101 #include "clang/AST/AbstractBasicReader.inc"
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 template <class Impl>
0123 class DataStreamBasicReader : public BasicReaderBase<Impl> {
0124 protected:
0125 using BasicReaderBase<Impl>::asImpl;
0126 DataStreamBasicReader(ASTContext &ctx) : BasicReaderBase<Impl>(ctx) {}
0127
0128 public:
0129 using BasicReaderBase<Impl>::getASTContext;
0130
0131
0132
0133 Impl &find(const char *propertyName) {
0134 return asImpl();
0135 }
0136
0137 template <class T>
0138 T readEnum() {
0139 return T(asImpl().readUInt32());
0140 }
0141
0142
0143
0144 Impl &readObject() { return asImpl(); }
0145
0146 template <class T>
0147 llvm::ArrayRef<T> readArray(llvm::SmallVectorImpl<T> &buffer) {
0148 assert(buffer.empty());
0149
0150 uint32_t size = asImpl().readUInt32();
0151 buffer.reserve(size);
0152
0153 for (uint32_t i = 0; i != size; ++i) {
0154 buffer.push_back(ReadDispatcher<T>::read(asImpl()));
0155 }
0156 return buffer;
0157 }
0158
0159 template <class T, class... Args>
0160 std::optional<T> readOptional(Args &&...args) {
0161 return UnpackOptionalValue<T>::unpack(
0162 ReadDispatcher<T>::read(asImpl(), std::forward<Args>(args)...));
0163 }
0164
0165 llvm::APSInt readAPSInt() {
0166 bool isUnsigned = asImpl().readBool();
0167 llvm::APInt value = asImpl().readAPInt();
0168 return llvm::APSInt(std::move(value), isUnsigned);
0169 }
0170
0171 llvm::APInt readAPInt() {
0172 unsigned bitWidth = asImpl().readUInt32();
0173 unsigned numWords = llvm::APInt::getNumWords(bitWidth);
0174 llvm::SmallVector<uint64_t, 4> data;
0175 for (uint32_t i = 0; i != numWords; ++i)
0176 data.push_back(asImpl().readUInt64());
0177 return llvm::APInt(bitWidth, numWords, &data[0]);
0178 }
0179
0180 llvm::FixedPointSemantics readFixedPointSemantics() {
0181 unsigned width = asImpl().readUInt32();
0182 unsigned scale = asImpl().readUInt32();
0183 unsigned tmp = asImpl().readUInt32();
0184 bool isSigned = tmp & 0x1;
0185 bool isSaturated = tmp & 0x2;
0186 bool hasUnsignedPadding = tmp & 0x4;
0187 return llvm::FixedPointSemantics(width, scale, isSigned, isSaturated,
0188 hasUnsignedPadding);
0189 }
0190
0191 APValue::LValuePathSerializationHelper readLValuePathSerializationHelper(
0192 SmallVectorImpl<APValue::LValuePathEntry> &path) {
0193 auto origTy = asImpl().readQualType();
0194 auto elemTy = origTy;
0195 unsigned pathLength = asImpl().readUInt32();
0196 for (unsigned i = 0; i < pathLength; ++i) {
0197 if (elemTy->template getAs<RecordType>()) {
0198 unsigned int_ = asImpl().readUInt32();
0199 Decl *decl = asImpl().template readDeclAs<Decl>();
0200 if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
0201 elemTy = getASTContext().getRecordType(recordDecl);
0202 else
0203 elemTy = cast<ValueDecl>(decl)->getType();
0204 path.push_back(
0205 APValue::LValuePathEntry(APValue::BaseOrMemberType(decl, int_)));
0206 } else {
0207 elemTy = getASTContext().getAsArrayType(elemTy)->getElementType();
0208 path.push_back(
0209 APValue::LValuePathEntry::ArrayIndex(asImpl().readUInt32()));
0210 }
0211 }
0212 return APValue::LValuePathSerializationHelper(path, origTy);
0213 }
0214
0215 Qualifiers readQualifiers() {
0216 static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint64_t),
0217 "update this if the value size changes");
0218 uint64_t value = asImpl().readUInt64();
0219 return Qualifiers::fromOpaqueValue(value);
0220 }
0221
0222 FunctionProtoType::ExceptionSpecInfo
0223 readExceptionSpecInfo(llvm::SmallVectorImpl<QualType> &buffer) {
0224 FunctionProtoType::ExceptionSpecInfo esi;
0225 esi.Type = ExceptionSpecificationType(asImpl().readUInt32());
0226 if (esi.Type == EST_Dynamic) {
0227 esi.Exceptions = asImpl().template readArray<QualType>(buffer);
0228 } else if (isComputedNoexcept(esi.Type)) {
0229 esi.NoexceptExpr = asImpl().readExprRef();
0230 } else if (esi.Type == EST_Uninstantiated) {
0231 esi.SourceDecl = asImpl().readFunctionDeclRef();
0232 esi.SourceTemplate = asImpl().readFunctionDeclRef();
0233 } else if (esi.Type == EST_Unevaluated) {
0234 esi.SourceDecl = asImpl().readFunctionDeclRef();
0235 }
0236 return esi;
0237 }
0238
0239 FunctionProtoType::ExtParameterInfo readExtParameterInfo() {
0240 static_assert(sizeof(FunctionProtoType::ExtParameterInfo().getOpaqueValue())
0241 <= sizeof(uint32_t),
0242 "opaque value doesn't fit into uint32_t");
0243 uint32_t value = asImpl().readUInt32();
0244 return FunctionProtoType::ExtParameterInfo::getFromOpaqueValue(value);
0245 }
0246
0247 FunctionEffect readFunctionEffect() {
0248 uint32_t value = asImpl().readUInt32();
0249 return FunctionEffect::fromOpaqueInt32(value);
0250 }
0251
0252 EffectConditionExpr readEffectConditionExpr() {
0253 return EffectConditionExpr{asImpl().readExprRef()};
0254 }
0255
0256 NestedNameSpecifier *readNestedNameSpecifier() {
0257 auto &ctx = getASTContext();
0258
0259
0260 NestedNameSpecifier *cur = nullptr;
0261
0262 uint32_t depth = asImpl().readUInt32();
0263 for (uint32_t i = 0; i != depth; ++i) {
0264 auto kind = asImpl().readNestedNameSpecifierKind();
0265 switch (kind) {
0266 case NestedNameSpecifier::Identifier:
0267 cur = NestedNameSpecifier::Create(ctx, cur,
0268 asImpl().readIdentifier());
0269 continue;
0270
0271 case NestedNameSpecifier::Namespace:
0272 cur = NestedNameSpecifier::Create(ctx, cur,
0273 asImpl().readNamespaceDeclRef());
0274 continue;
0275
0276 case NestedNameSpecifier::NamespaceAlias:
0277 cur = NestedNameSpecifier::Create(ctx, cur,
0278 asImpl().readNamespaceAliasDeclRef());
0279 continue;
0280
0281 case NestedNameSpecifier::TypeSpec:
0282 case NestedNameSpecifier::TypeSpecWithTemplate:
0283 cur = NestedNameSpecifier::Create(ctx, cur,
0284 kind == NestedNameSpecifier::TypeSpecWithTemplate,
0285 asImpl().readQualType().getTypePtr());
0286 continue;
0287
0288 case NestedNameSpecifier::Global:
0289 cur = NestedNameSpecifier::GlobalSpecifier(ctx);
0290 continue;
0291
0292 case NestedNameSpecifier::Super:
0293 cur = NestedNameSpecifier::SuperSpecifier(ctx,
0294 asImpl().readCXXRecordDeclRef());
0295 continue;
0296 }
0297 llvm_unreachable("bad nested name specifier kind");
0298 }
0299
0300 return cur;
0301 }
0302 };
0303
0304 }
0305 }
0306
0307 #endif