clang 19.0.0git
AbstractBasicReader.h
Go to the documentation of this file.
1//==--- AbstractBasiceReader.h - Abstract basic value deserialization -----===//
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#ifndef LLVM_CLANG_AST_ABSTRACTBASICREADER_H
10#define LLVM_CLANG_AST_ABSTRACTBASICREADER_H
11
13#include <optional>
14
15namespace clang {
16namespace serialization {
17
18template <class T>
19inline T makeNullableFromOptional(const std::optional<T> &value) {
20 return (value ? *value : T());
21}
22
23template <class T> inline T *makePointerFromOptional(std::optional<T *> value) {
24 return value.value_or(nullptr);
25}
26
27// PropertyReader is a class concept that requires the following method:
28// BasicReader find(llvm::StringRef propertyName);
29// where BasicReader is some class conforming to the BasicReader concept.
30// An abstract AST-node reader is created with a PropertyReader and
31// performs a sequence of calls like so:
32// propertyReader.find(propertyName).read##TypeName()
33// to read the properties of the node it is deserializing.
34
35// BasicReader is a class concept that requires methods like:
36// ValueType read##TypeName();
37// where TypeName is the name of a PropertyType node from PropertiesBase.td
38// and ValueType is the corresponding C++ type name. The read method may
39// require one or more buffer arguments.
40//
41// In addition to the concrete type names, BasicReader is expected to
42// implement these methods:
43//
44// template <class EnumType>
45// void writeEnum(T value);
46//
47// Reads an enum value from the current property. EnumType will always
48// be an enum type. Only necessary if the BasicReader doesn't provide
49// type-specific readers for all the enum types.
50//
51// template <class ValueType>
52// std::optional<ValueType> writeOptional();
53//
54// Reads an optional value from the current property.
55//
56// template <class ValueType>
57// ArrayRef<ValueType> readArray(llvm::SmallVectorImpl<ValueType> &buffer);
58//
59// Reads an array of values from the current property.
60//
61// PropertyReader readObject();
62//
63// Reads an object from the current property; the returned property
64// reader will be subjected to a sequence of property reads and then
65// discarded before any other properties are reader from the "outer"
66// property reader (which need not be the same type). The sub-reader
67// will be used as if with the following code:
68//
69// {
70// auto &&widget = W.find("widget").readObject();
71// auto kind = widget.find("kind").readWidgetKind();
72// auto declaration = widget.find("declaration").readDeclRef();
73// return Widget(kind, declaration);
74// }
75
76// ReadDispatcher does type-based forwarding to one of the read methods
77// on the BasicReader passed in:
78//
79// template <class ValueType>
80// struct ReadDispatcher {
81// template <class BasicReader, class... BufferTypes>
82// static ValueType read(BasicReader &R, BufferTypes &&...);
83// };
84
85// BasicReaderBase provides convenience implementations of the read methods
86// for EnumPropertyType and SubclassPropertyType types that just defer to
87// the "underlying" implementations (for UInt32 and the base class,
88// respectively).
89//
90// template <class Impl>
91// class BasicReaderBase {
92// protected:
93// BasicReaderBase(ASTContext &ctx);
94// Impl &asImpl();
95// public:
96// ASTContext &getASTContext();
97// ...
98// };
99
100// The actual classes are auto-generated; see ClangASTPropertiesEmitter.cpp.
101#include "clang/AST/AbstractBasicReader.inc"
102
103/// DataStreamBasicReader provides convenience implementations for many
104/// BasicReader methods based on the assumption that the
105/// ultimate reader implementation is based on a variable-length stream
106/// of unstructured data (like Clang's module files). It is designed
107/// to pair with DataStreamBasicWriter.
108///
109/// This class can also act as a PropertyReader, implementing find("...")
110/// by simply forwarding to itself.
111///
112/// Unimplemented methods:
113/// readBool
114/// readUInt32
115/// readUInt64
116/// readIdentifier
117/// readSelector
118/// readSourceLocation
119/// readQualType
120/// readStmtRef
121/// readDeclRef
122template <class Impl>
124protected:
125 using BasicReaderBase<Impl>::asImpl;
127
128public:
129 using BasicReaderBase<Impl>::getASTContext;
130
131 /// Implement property-find by ignoring it. We rely on properties being
132 /// serialized and deserialized in a reliable order instead.
133 Impl &find(const char *propertyName) {
134 return asImpl();
135 }
136
137 template <class T>
139 return T(asImpl().readUInt32());
140 }
141
142 // Implement object reading by forwarding to this, collapsing the
143 // structure into a single data stream.
144 Impl &readObject() { return asImpl(); }
145
146 template <class T>
148 assert(buffer.empty());
149
150 uint32_t size = asImpl().readUInt32();
151 buffer.reserve(size);
152
153 for (uint32_t i = 0; i != size; ++i) {
154 buffer.push_back(ReadDispatcher<T>::read(asImpl()));
155 }
156 return buffer;
157 }
158
159 template <class T, class... Args>
160 std::optional<T> readOptional(Args &&...args) {
161 return UnpackOptionalValue<T>::unpack(
162 ReadDispatcher<T>::read(asImpl(), std::forward<Args>(args)...));
163 }
164
165 llvm::APSInt readAPSInt() {
166 bool isUnsigned = asImpl().readBool();
167 llvm::APInt value = asImpl().readAPInt();
168 return llvm::APSInt(std::move(value), isUnsigned);
169 }
170
171 llvm::APInt readAPInt() {
172 unsigned bitWidth = asImpl().readUInt32();
173 unsigned numWords = llvm::APInt::getNumWords(bitWidth);
175 for (uint32_t i = 0; i != numWords; ++i)
176 data.push_back(asImpl().readUInt64());
177 return llvm::APInt(bitWidth, numWords, &data[0]);
178 }
179
180 llvm::FixedPointSemantics readFixedPointSemantics() {
181 unsigned width = asImpl().readUInt32();
182 unsigned scale = asImpl().readUInt32();
183 unsigned tmp = asImpl().readUInt32();
184 bool isSigned = tmp & 0x1;
185 bool isSaturated = tmp & 0x2;
186 bool hasUnsignedPadding = tmp & 0x4;
187 return llvm::FixedPointSemantics(width, scale, isSigned, isSaturated,
188 hasUnsignedPadding);
189 }
190
193 auto origTy = asImpl().readQualType();
194 auto elemTy = origTy;
195 unsigned pathLength = asImpl().readUInt32();
196 for (unsigned i = 0; i < pathLength; ++i) {
197 if (elemTy->template getAs<RecordType>()) {
198 unsigned int_ = asImpl().readUInt32();
199 Decl *decl = asImpl().template readDeclAs<Decl>();
200 if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
201 elemTy = getASTContext().getRecordType(recordDecl);
202 else
203 elemTy = cast<ValueDecl>(decl)->getType();
204 path.push_back(
206 } else {
207 elemTy = getASTContext().getAsArrayType(elemTy)->getElementType();
208 path.push_back(
209 APValue::LValuePathEntry::ArrayIndex(asImpl().readUInt32()));
210 }
211 }
212 return APValue::LValuePathSerializationHelper(path, origTy);
213 }
214
216 static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t),
217 "update this if the value size changes");
218 uint32_t value = asImpl().readUInt32();
219 return Qualifiers::fromOpaqueValue(value);
220 }
221
225 esi.Type = ExceptionSpecificationType(asImpl().readUInt32());
226 if (esi.Type == EST_Dynamic) {
227 esi.Exceptions = asImpl().template readArray<QualType>(buffer);
228 } else if (isComputedNoexcept(esi.Type)) {
229 esi.NoexceptExpr = asImpl().readExprRef();
230 } else if (esi.Type == EST_Uninstantiated) {
231 esi.SourceDecl = asImpl().readFunctionDeclRef();
232 esi.SourceTemplate = asImpl().readFunctionDeclRef();
233 } else if (esi.Type == EST_Unevaluated) {
234 esi.SourceDecl = asImpl().readFunctionDeclRef();
235 }
236 return esi;
237 }
238
241 <= sizeof(uint32_t),
242 "opaque value doesn't fit into uint32_t");
243 uint32_t value = asImpl().readUInt32();
244 return FunctionProtoType::ExtParameterInfo::getFromOpaqueValue(value);
245 }
246
248 auto &ctx = getASTContext();
249
250 // We build this up iteratively.
251 NestedNameSpecifier *cur = nullptr;
252
253 uint32_t depth = asImpl().readUInt32();
254 for (uint32_t i = 0; i != depth; ++i) {
255 auto kind = asImpl().readNestedNameSpecifierKind();
256 switch (kind) {
258 cur = NestedNameSpecifier::Create(ctx, cur,
259 asImpl().readIdentifier());
260 continue;
261
263 cur = NestedNameSpecifier::Create(ctx, cur,
264 asImpl().readNamespaceDeclRef());
265 continue;
266
268 cur = NestedNameSpecifier::Create(ctx, cur,
269 asImpl().readNamespaceAliasDeclRef());
270 continue;
271
274 cur = NestedNameSpecifier::Create(ctx, cur,
276 asImpl().readQualType().getTypePtr());
277 continue;
278
281 continue;
282
285 asImpl().readCXXRecordDeclRef());
286 continue;
287 }
288 llvm_unreachable("bad nested name specifier kind");
289 }
290
291 return cur;
292 }
293};
294
295} // end namespace serialization
296} // end namespace clang
297
298#endif
static bool isUnsigned(SValBuilder &SVB, NonLoc Value)
Defines the C++ template declaration subclasses.
A non-discriminated union of a base, field, or array index.
Definition: APValue.h:208
static LValuePathEntry ArrayIndex(uint64_t Index)
Definition: APValue.h:216
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
Definition: APValue.h:205
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
Definition: Type.h:4072
unsigned char getOpaqueValue() const
Definition: Type.h:4121
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, const IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
@ TypeSpec
A type, stored as a Type*.
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Identifier
An identifier, stored as an IdentifierInfo*.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace, stored as a NamespaceDecl*.
static NestedNameSpecifier * SuperSpecifier(const ASTContext &Context, CXXRecordDecl *RD)
Returns the nested name specifier representing the __super scope for the given CXXRecordDecl.
The collection of all-type qualifiers we support.
Definition: Type.h:148
unsigned getAsOpaqueValue() const
Definition: Type.h:261
static Qualifiers fromOpaqueValue(unsigned opaque)
Definition: Type.h:254
DataStreamBasicReader provides convenience implementations for many BasicReader methods based on the ...
FunctionProtoType::ExceptionSpecInfo readExceptionSpecInfo(llvm::SmallVectorImpl< QualType > &buffer)
FunctionProtoType::ExtParameterInfo readExtParameterInfo()
APValue::LValuePathSerializationHelper readLValuePathSerializationHelper(SmallVectorImpl< APValue::LValuePathEntry > &path)
std::optional< T > readOptional(Args &&...args)
llvm::ArrayRef< T > readArray(llvm::SmallVectorImpl< T > &buffer)
Impl & find(const char *propertyName)
Implement property-find by ignoring it.
llvm::FixedPointSemantics readFixedPointSemantics()
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, RecordDecl > recordDecl
Matches class, struct, and union declarations.
T * makePointerFromOptional(std::optional< T * > value)
T makeNullableFromOptional(const std::optional< T > &value)
The JSON file list parser is used to communicate input to InstallAPI.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
const FunctionProtoType * T
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_Uninstantiated
not instantiated yet
@ EST_Unevaluated
not evaluated yet, for special member function
@ EST_Dynamic
throw(T1, T2)
Holds information about the various types of exception specification.
Definition: Type.h:4497
FunctionDecl * SourceDecl
The function whose exception specification this is, for EST_Unevaluated and EST_Uninstantiated.
Definition: Type.h:4509
FunctionDecl * SourceTemplate
The function template whose exception specification this is instantiated from, for EST_Uninstantiated...
Definition: Type.h:4513
ExceptionSpecificationType Type
The kind of exception specification this is.
Definition: Type.h:4499
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Definition: Type.h:4502
Expr * NoexceptExpr
Noexcept expression, if this is a computed noexcept specification.
Definition: Type.h:4505