1*13fbcb42Sjoerg //==--- AbstractBasiceReader.h - Abstract basic value deserialization -----===//
2*13fbcb42Sjoerg //
3*13fbcb42Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*13fbcb42Sjoerg // See https://llvm.org/LICENSE.txt for license information.
5*13fbcb42Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*13fbcb42Sjoerg //
7*13fbcb42Sjoerg //===----------------------------------------------------------------------===//
8*13fbcb42Sjoerg 
9*13fbcb42Sjoerg #ifndef CLANG_AST_ABSTRACTBASICREADER_H
10*13fbcb42Sjoerg #define CLANG_AST_ABSTRACTBASICREADER_H
11*13fbcb42Sjoerg 
12*13fbcb42Sjoerg #include "clang/AST/DeclTemplate.h"
13*13fbcb42Sjoerg 
14*13fbcb42Sjoerg namespace clang {
15*13fbcb42Sjoerg namespace serialization {
16*13fbcb42Sjoerg 
17*13fbcb42Sjoerg template <class T>
makeNullableFromOptional(const Optional<T> & value)18*13fbcb42Sjoerg inline T makeNullableFromOptional(const Optional<T> &value) {
19*13fbcb42Sjoerg   return (value ? *value : T());
20*13fbcb42Sjoerg }
21*13fbcb42Sjoerg 
22*13fbcb42Sjoerg template <class T>
makePointerFromOptional(Optional<T * > value)23*13fbcb42Sjoerg inline T *makePointerFromOptional(Optional<T *> value) {
24*13fbcb42Sjoerg   return (value ? *value : nullptr);
25*13fbcb42Sjoerg }
26*13fbcb42Sjoerg 
27*13fbcb42Sjoerg // PropertyReader is a class concept that requires the following method:
28*13fbcb42Sjoerg //   BasicReader find(llvm::StringRef propertyName);
29*13fbcb42Sjoerg // where BasicReader is some class conforming to the BasicReader concept.
30*13fbcb42Sjoerg // An abstract AST-node reader is created with a PropertyReader and
31*13fbcb42Sjoerg // performs a sequence of calls like so:
32*13fbcb42Sjoerg //   propertyReader.find(propertyName).read##TypeName()
33*13fbcb42Sjoerg // to read the properties of the node it is deserializing.
34*13fbcb42Sjoerg 
35*13fbcb42Sjoerg // BasicReader is a class concept that requires methods like:
36*13fbcb42Sjoerg //   ValueType read##TypeName();
37*13fbcb42Sjoerg // where TypeName is the name of a PropertyType node from PropertiesBase.td
38*13fbcb42Sjoerg // and ValueType is the corresponding C++ type name.  The read method may
39*13fbcb42Sjoerg // require one or more buffer arguments.
40*13fbcb42Sjoerg //
41*13fbcb42Sjoerg // In addition to the concrete type names, BasicReader is expected to
42*13fbcb42Sjoerg // implement these methods:
43*13fbcb42Sjoerg //
44*13fbcb42Sjoerg //   template <class EnumType>
45*13fbcb42Sjoerg //   void writeEnum(T value);
46*13fbcb42Sjoerg //
47*13fbcb42Sjoerg //     Reads an enum value from the current property.  EnumType will always
48*13fbcb42Sjoerg //     be an enum type.  Only necessary if the BasicReader doesn't provide
49*13fbcb42Sjoerg //     type-specific readers for all the enum types.
50*13fbcb42Sjoerg //
51*13fbcb42Sjoerg //   template <class ValueType>
52*13fbcb42Sjoerg //   Optional<ValueType> writeOptional();
53*13fbcb42Sjoerg //
54*13fbcb42Sjoerg //     Reads an optional value from the current property.
55*13fbcb42Sjoerg //
56*13fbcb42Sjoerg //   template <class ValueType>
57*13fbcb42Sjoerg //   ArrayRef<ValueType> readArray(llvm::SmallVectorImpl<ValueType> &buffer);
58*13fbcb42Sjoerg //
59*13fbcb42Sjoerg //     Reads an array of values from the current property.
60*13fbcb42Sjoerg //
61*13fbcb42Sjoerg //   PropertyReader readObject();
62*13fbcb42Sjoerg //
63*13fbcb42Sjoerg //     Reads an object from the current property; the returned property
64*13fbcb42Sjoerg //     reader will be subjected to a sequence of property reads and then
65*13fbcb42Sjoerg //     discarded before any other properties are reader from the "outer"
66*13fbcb42Sjoerg //     property reader (which need not be the same type).  The sub-reader
67*13fbcb42Sjoerg //     will be used as if with the following code:
68*13fbcb42Sjoerg //
69*13fbcb42Sjoerg //       {
70*13fbcb42Sjoerg //         auto &&widget = W.find("widget").readObject();
71*13fbcb42Sjoerg //         auto kind = widget.find("kind").readWidgetKind();
72*13fbcb42Sjoerg //         auto declaration = widget.find("declaration").readDeclRef();
73*13fbcb42Sjoerg //         return Widget(kind, declaration);
74*13fbcb42Sjoerg //       }
75*13fbcb42Sjoerg 
76*13fbcb42Sjoerg // ReadDispatcher does type-based forwarding to one of the read methods
77*13fbcb42Sjoerg // on the BasicReader passed in:
78*13fbcb42Sjoerg //
79*13fbcb42Sjoerg // template <class ValueType>
80*13fbcb42Sjoerg // struct ReadDispatcher {
81*13fbcb42Sjoerg //   template <class BasicReader, class... BufferTypes>
82*13fbcb42Sjoerg //   static ValueType read(BasicReader &R, BufferTypes &&...);
83*13fbcb42Sjoerg // };
84*13fbcb42Sjoerg 
85*13fbcb42Sjoerg // BasicReaderBase provides convenience implementations of the read methods
86*13fbcb42Sjoerg // for EnumPropertyType and SubclassPropertyType types that just defer to
87*13fbcb42Sjoerg // the "underlying" implementations (for UInt32 and the base class,
88*13fbcb42Sjoerg // respectively).
89*13fbcb42Sjoerg //
90*13fbcb42Sjoerg // template <class Impl>
91*13fbcb42Sjoerg // class BasicReaderBase {
92*13fbcb42Sjoerg // protected:
93*13fbcb42Sjoerg //   BasicReaderBase(ASTContext &ctx);
94*13fbcb42Sjoerg //   Impl &asImpl();
95*13fbcb42Sjoerg // public:
96*13fbcb42Sjoerg //   ASTContext &getASTContext();
97*13fbcb42Sjoerg //   ...
98*13fbcb42Sjoerg // };
99*13fbcb42Sjoerg 
100*13fbcb42Sjoerg // The actual classes are auto-generated; see ClangASTPropertiesEmitter.cpp.
101*13fbcb42Sjoerg #include "clang/AST/AbstractBasicReader.inc"
102*13fbcb42Sjoerg 
103*13fbcb42Sjoerg /// DataStreamBasicReader provides convenience implementations for many
104*13fbcb42Sjoerg /// BasicReader methods based on the assumption that the
105*13fbcb42Sjoerg /// ultimate reader implementation is based on a variable-length stream
106*13fbcb42Sjoerg /// of unstructured data (like Clang's module files).  It is designed
107*13fbcb42Sjoerg /// to pair with DataStreamBasicWriter.
108*13fbcb42Sjoerg ///
109*13fbcb42Sjoerg /// This class can also act as a PropertyReader, implementing find("...")
110*13fbcb42Sjoerg /// by simply forwarding to itself.
111*13fbcb42Sjoerg ///
112*13fbcb42Sjoerg /// Unimplemented methods:
113*13fbcb42Sjoerg ///   readBool
114*13fbcb42Sjoerg ///   readUInt32
115*13fbcb42Sjoerg ///   readUInt64
116*13fbcb42Sjoerg ///   readIdentifier
117*13fbcb42Sjoerg ///   readSelector
118*13fbcb42Sjoerg ///   readSourceLocation
119*13fbcb42Sjoerg ///   readQualType
120*13fbcb42Sjoerg ///   readStmtRef
121*13fbcb42Sjoerg ///   readDeclRef
122*13fbcb42Sjoerg template <class Impl>
123*13fbcb42Sjoerg class DataStreamBasicReader : public BasicReaderBase<Impl> {
124*13fbcb42Sjoerg protected:
125*13fbcb42Sjoerg   using BasicReaderBase<Impl>::asImpl;
DataStreamBasicReader(ASTContext & ctx)126*13fbcb42Sjoerg   DataStreamBasicReader(ASTContext &ctx) : BasicReaderBase<Impl>(ctx) {}
127*13fbcb42Sjoerg 
128*13fbcb42Sjoerg public:
129*13fbcb42Sjoerg   using BasicReaderBase<Impl>::getASTContext;
130*13fbcb42Sjoerg 
131*13fbcb42Sjoerg   /// Implement property-find by ignoring it.  We rely on properties being
132*13fbcb42Sjoerg   /// serialized and deserialized in a reliable order instead.
find(const char * propertyName)133*13fbcb42Sjoerg   Impl &find(const char *propertyName) {
134*13fbcb42Sjoerg     return asImpl();
135*13fbcb42Sjoerg   }
136*13fbcb42Sjoerg 
137*13fbcb42Sjoerg   template <class T>
readEnum()138*13fbcb42Sjoerg   T readEnum() {
139*13fbcb42Sjoerg     return T(asImpl().readUInt32());
140*13fbcb42Sjoerg   }
141*13fbcb42Sjoerg 
142*13fbcb42Sjoerg   // Implement object reading by forwarding to this, collapsing the
143*13fbcb42Sjoerg   // structure into a single data stream.
readObject()144*13fbcb42Sjoerg   Impl &readObject() { return asImpl(); }
145*13fbcb42Sjoerg 
146*13fbcb42Sjoerg   template <class T>
readArray(llvm::SmallVectorImpl<T> & buffer)147*13fbcb42Sjoerg   llvm::ArrayRef<T> readArray(llvm::SmallVectorImpl<T> &buffer) {
148*13fbcb42Sjoerg     assert(buffer.empty());
149*13fbcb42Sjoerg 
150*13fbcb42Sjoerg     uint32_t size = asImpl().readUInt32();
151*13fbcb42Sjoerg     buffer.reserve(size);
152*13fbcb42Sjoerg 
153*13fbcb42Sjoerg     for (uint32_t i = 0; i != size; ++i) {
154*13fbcb42Sjoerg       buffer.push_back(ReadDispatcher<T>::read(asImpl()));
155*13fbcb42Sjoerg     }
156*13fbcb42Sjoerg     return buffer;
157*13fbcb42Sjoerg   }
158*13fbcb42Sjoerg 
159*13fbcb42Sjoerg   template <class T, class... Args>
readOptional(Args &&...args)160*13fbcb42Sjoerg   llvm::Optional<T> readOptional(Args &&...args) {
161*13fbcb42Sjoerg     return UnpackOptionalValue<T>::unpack(
162*13fbcb42Sjoerg              ReadDispatcher<T>::read(asImpl(), std::forward<Args>(args)...));
163*13fbcb42Sjoerg   }
164*13fbcb42Sjoerg 
readAPSInt()165*13fbcb42Sjoerg   llvm::APSInt readAPSInt() {
166*13fbcb42Sjoerg     bool isUnsigned = asImpl().readBool();
167*13fbcb42Sjoerg     llvm::APInt value = asImpl().readAPInt();
168*13fbcb42Sjoerg     return llvm::APSInt(std::move(value), isUnsigned);
169*13fbcb42Sjoerg   }
170*13fbcb42Sjoerg 
readAPInt()171*13fbcb42Sjoerg   llvm::APInt readAPInt() {
172*13fbcb42Sjoerg     unsigned bitWidth = asImpl().readUInt32();
173*13fbcb42Sjoerg     unsigned numWords = llvm::APInt::getNumWords(bitWidth);
174*13fbcb42Sjoerg     llvm::SmallVector<uint64_t, 4> data;
175*13fbcb42Sjoerg     for (uint32_t i = 0; i != numWords; ++i)
176*13fbcb42Sjoerg       data.push_back(asImpl().readUInt64());
177*13fbcb42Sjoerg     return llvm::APInt(bitWidth, numWords, &data[0]);
178*13fbcb42Sjoerg   }
179*13fbcb42Sjoerg 
readFixedPointSemantics()180*13fbcb42Sjoerg   llvm::FixedPointSemantics readFixedPointSemantics() {
181*13fbcb42Sjoerg     unsigned width = asImpl().readUInt32();
182*13fbcb42Sjoerg     unsigned scale = asImpl().readUInt32();
183*13fbcb42Sjoerg     unsigned tmp = asImpl().readUInt32();
184*13fbcb42Sjoerg     bool isSigned = tmp & 0x1;
185*13fbcb42Sjoerg     bool isSaturated = tmp & 0x2;
186*13fbcb42Sjoerg     bool hasUnsignedPadding = tmp & 0x4;
187*13fbcb42Sjoerg     return llvm::FixedPointSemantics(width, scale, isSigned, isSaturated,
188*13fbcb42Sjoerg                                      hasUnsignedPadding);
189*13fbcb42Sjoerg   }
190*13fbcb42Sjoerg 
readLValuePathSerializationHelper(SmallVectorImpl<APValue::LValuePathEntry> & path)191*13fbcb42Sjoerg   APValue::LValuePathSerializationHelper readLValuePathSerializationHelper(
192*13fbcb42Sjoerg       SmallVectorImpl<APValue::LValuePathEntry> &path) {
193*13fbcb42Sjoerg     auto elemTy = asImpl().readQualType();
194*13fbcb42Sjoerg     unsigned pathLength = asImpl().readUInt32();
195*13fbcb42Sjoerg     for (unsigned i = 0; i < pathLength; ++i) {
196*13fbcb42Sjoerg       if (elemTy->template getAs<RecordType>()) {
197*13fbcb42Sjoerg         unsigned int_ = asImpl().readUInt32();
198*13fbcb42Sjoerg         Decl *decl = asImpl().template readDeclAs<Decl>();
199*13fbcb42Sjoerg         if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
200*13fbcb42Sjoerg           elemTy = getASTContext().getRecordType(recordDecl);
201*13fbcb42Sjoerg         else
202*13fbcb42Sjoerg           elemTy = cast<ValueDecl>(decl)->getType();
203*13fbcb42Sjoerg         path.push_back(
204*13fbcb42Sjoerg             APValue::LValuePathEntry(APValue::BaseOrMemberType(decl, int_)));
205*13fbcb42Sjoerg       } else {
206*13fbcb42Sjoerg         elemTy = getASTContext().getAsArrayType(elemTy)->getElementType();
207*13fbcb42Sjoerg         path.push_back(
208*13fbcb42Sjoerg             APValue::LValuePathEntry::ArrayIndex(asImpl().readUInt32()));
209*13fbcb42Sjoerg       }
210*13fbcb42Sjoerg     }
211*13fbcb42Sjoerg     return APValue::LValuePathSerializationHelper(path, elemTy);
212*13fbcb42Sjoerg   }
213*13fbcb42Sjoerg 
readQualifiers()214*13fbcb42Sjoerg   Qualifiers readQualifiers() {
215*13fbcb42Sjoerg     static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t),
216*13fbcb42Sjoerg                   "update this if the value size changes");
217*13fbcb42Sjoerg     uint32_t value = asImpl().readUInt32();
218*13fbcb42Sjoerg     return Qualifiers::fromOpaqueValue(value);
219*13fbcb42Sjoerg   }
220*13fbcb42Sjoerg 
221*13fbcb42Sjoerg   FunctionProtoType::ExceptionSpecInfo
readExceptionSpecInfo(llvm::SmallVectorImpl<QualType> & buffer)222*13fbcb42Sjoerg   readExceptionSpecInfo(llvm::SmallVectorImpl<QualType> &buffer) {
223*13fbcb42Sjoerg     FunctionProtoType::ExceptionSpecInfo esi;
224*13fbcb42Sjoerg     esi.Type = ExceptionSpecificationType(asImpl().readUInt32());
225*13fbcb42Sjoerg     if (esi.Type == EST_Dynamic) {
226*13fbcb42Sjoerg       esi.Exceptions = asImpl().template readArray<QualType>(buffer);
227*13fbcb42Sjoerg     } else if (isComputedNoexcept(esi.Type)) {
228*13fbcb42Sjoerg       esi.NoexceptExpr = asImpl().readExprRef();
229*13fbcb42Sjoerg     } else if (esi.Type == EST_Uninstantiated) {
230*13fbcb42Sjoerg       esi.SourceDecl = asImpl().readFunctionDeclRef();
231*13fbcb42Sjoerg       esi.SourceTemplate = asImpl().readFunctionDeclRef();
232*13fbcb42Sjoerg     } else if (esi.Type == EST_Unevaluated) {
233*13fbcb42Sjoerg       esi.SourceDecl = asImpl().readFunctionDeclRef();
234*13fbcb42Sjoerg     }
235*13fbcb42Sjoerg     return esi;
236*13fbcb42Sjoerg   }
237*13fbcb42Sjoerg 
readExtParameterInfo()238*13fbcb42Sjoerg   FunctionProtoType::ExtParameterInfo readExtParameterInfo() {
239*13fbcb42Sjoerg     static_assert(sizeof(FunctionProtoType::ExtParameterInfo().getOpaqueValue())
240*13fbcb42Sjoerg                     <= sizeof(uint32_t),
241*13fbcb42Sjoerg                   "opaque value doesn't fit into uint32_t");
242*13fbcb42Sjoerg     uint32_t value = asImpl().readUInt32();
243*13fbcb42Sjoerg     return FunctionProtoType::ExtParameterInfo::getFromOpaqueValue(value);
244*13fbcb42Sjoerg   }
245*13fbcb42Sjoerg 
readNestedNameSpecifier()246*13fbcb42Sjoerg   NestedNameSpecifier *readNestedNameSpecifier() {
247*13fbcb42Sjoerg     auto &ctx = getASTContext();
248*13fbcb42Sjoerg 
249*13fbcb42Sjoerg     // We build this up iteratively.
250*13fbcb42Sjoerg     NestedNameSpecifier *cur = nullptr;
251*13fbcb42Sjoerg 
252*13fbcb42Sjoerg     uint32_t depth = asImpl().readUInt32();
253*13fbcb42Sjoerg     for (uint32_t i = 0; i != depth; ++i) {
254*13fbcb42Sjoerg       auto kind = asImpl().readNestedNameSpecifierKind();
255*13fbcb42Sjoerg       switch (kind) {
256*13fbcb42Sjoerg       case NestedNameSpecifier::Identifier:
257*13fbcb42Sjoerg         cur = NestedNameSpecifier::Create(ctx, cur,
258*13fbcb42Sjoerg                                           asImpl().readIdentifier());
259*13fbcb42Sjoerg         continue;
260*13fbcb42Sjoerg 
261*13fbcb42Sjoerg       case NestedNameSpecifier::Namespace:
262*13fbcb42Sjoerg         cur = NestedNameSpecifier::Create(ctx, cur,
263*13fbcb42Sjoerg                                           asImpl().readNamespaceDeclRef());
264*13fbcb42Sjoerg         continue;
265*13fbcb42Sjoerg 
266*13fbcb42Sjoerg       case NestedNameSpecifier::NamespaceAlias:
267*13fbcb42Sjoerg         cur = NestedNameSpecifier::Create(ctx, cur,
268*13fbcb42Sjoerg                                      asImpl().readNamespaceAliasDeclRef());
269*13fbcb42Sjoerg         continue;
270*13fbcb42Sjoerg 
271*13fbcb42Sjoerg       case NestedNameSpecifier::TypeSpec:
272*13fbcb42Sjoerg       case NestedNameSpecifier::TypeSpecWithTemplate:
273*13fbcb42Sjoerg         cur = NestedNameSpecifier::Create(ctx, cur,
274*13fbcb42Sjoerg                           kind == NestedNameSpecifier::TypeSpecWithTemplate,
275*13fbcb42Sjoerg                           asImpl().readQualType().getTypePtr());
276*13fbcb42Sjoerg         continue;
277*13fbcb42Sjoerg 
278*13fbcb42Sjoerg       case NestedNameSpecifier::Global:
279*13fbcb42Sjoerg         cur = NestedNameSpecifier::GlobalSpecifier(ctx);
280*13fbcb42Sjoerg         continue;
281*13fbcb42Sjoerg 
282*13fbcb42Sjoerg       case NestedNameSpecifier::Super:
283*13fbcb42Sjoerg         cur = NestedNameSpecifier::SuperSpecifier(ctx,
284*13fbcb42Sjoerg                                             asImpl().readCXXRecordDeclRef());
285*13fbcb42Sjoerg         continue;
286*13fbcb42Sjoerg       }
287*13fbcb42Sjoerg       llvm_unreachable("bad nested name specifier kind");
288*13fbcb42Sjoerg     }
289*13fbcb42Sjoerg 
290*13fbcb42Sjoerg     return cur;
291*13fbcb42Sjoerg   }
292*13fbcb42Sjoerg };
293*13fbcb42Sjoerg 
294*13fbcb42Sjoerg } // end namespace serialization
295*13fbcb42Sjoerg } // end namespace clang
296*13fbcb42Sjoerg 
297*13fbcb42Sjoerg #endif
298