clang  14.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 CLANG_AST_ABSTRACTBASICREADER_H
10 #define CLANG_AST_ABSTRACTBASICREADER_H
11 
12 #include "clang/AST/DeclTemplate.h"
13 
14 namespace clang {
15 namespace serialization {
16 
17 template <class T>
18 inline T makeNullableFromOptional(const Optional<T> &value) {
19  return (value ? *value : T());
20 }
21 
22 template <class T>
24  return (value ? *value : 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 // 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
122 template <class Impl>
124 protected:
127 
128 public:
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>
138  T readEnum() {
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  llvm::Optional<T> readOptional(Args &&...args) {
161  return UnpackOptionalValue<T>::unpack(
162  ReadDispatcher<T>::read(asImpl(), std::forward<Args>(args)...));
163  }
164 
166  bool isUnsigned = asImpl().readBool();
167  llvm::APInt value = asImpl().readAPInt();
168  return llvm::APSInt(std::move(value), isUnsigned);
169  }
170 
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 elemTy = asImpl().readQualType();
194  unsigned pathLength = asImpl().readUInt32();
195  for (unsigned i = 0; i < pathLength; ++i) {
196  if (elemTy->template getAs<RecordType>()) {
197  unsigned int_ = asImpl().readUInt32();
198  Decl *decl = asImpl().template readDeclAs<Decl>();
199  if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
200  elemTy = getASTContext().getRecordType(recordDecl);
201  else
202  elemTy = cast<ValueDecl>(decl)->getType();
203  path.push_back(
205  } else {
206  elemTy = getASTContext().getAsArrayType(elemTy)->getElementType();
207  path.push_back(
208  APValue::LValuePathEntry::ArrayIndex(asImpl().readUInt32()));
209  }
210  }
211  return APValue::LValuePathSerializationHelper(path, elemTy);
212  }
213 
215  static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t),
216  "update this if the value size changes");
217  uint32_t value = asImpl().readUInt32();
218  return Qualifiers::fromOpaqueValue(value);
219  }
220 
224  esi.Type = ExceptionSpecificationType(asImpl().readUInt32());
225  if (esi.Type == EST_Dynamic) {
226  esi.Exceptions = asImpl().template readArray<QualType>(buffer);
227  } else if (isComputedNoexcept(esi.Type)) {
228  esi.NoexceptExpr = asImpl().readExprRef();
229  } else if (esi.Type == EST_Uninstantiated) {
230  esi.SourceDecl = asImpl().readFunctionDeclRef();
231  esi.SourceTemplate = asImpl().readFunctionDeclRef();
232  } else if (esi.Type == EST_Unevaluated) {
233  esi.SourceDecl = asImpl().readFunctionDeclRef();
234  }
235  return esi;
236  }
237 
239  static_assert(sizeof(FunctionProtoType::ExtParameterInfo().getOpaqueValue())
240  <= sizeof(uint32_t),
241  "opaque value doesn't fit into uint32_t");
242  uint32_t value = asImpl().readUInt32();
244  }
245 
247  auto &ctx = getASTContext();
248 
249  // We build this up iteratively.
250  NestedNameSpecifier *cur = nullptr;
251 
252  uint32_t depth = asImpl().readUInt32();
253  for (uint32_t i = 0; i != depth; ++i) {
254  auto kind = asImpl().readNestedNameSpecifierKind();
255  switch (kind) {
257  cur = NestedNameSpecifier::Create(ctx, cur,
258  asImpl().readIdentifier());
259  continue;
260 
262  cur = NestedNameSpecifier::Create(ctx, cur,
263  asImpl().readNamespaceDeclRef());
264  continue;
265 
267  cur = NestedNameSpecifier::Create(ctx, cur,
268  asImpl().readNamespaceAliasDeclRef());
269  continue;
270 
273  cur = NestedNameSpecifier::Create(ctx, cur,
275  asImpl().readQualType().getTypePtr());
276  continue;
277 
280  continue;
281 
284  asImpl().readCXXRecordDeclRef());
285  continue;
286  }
287  llvm_unreachable("bad nested name specifier kind");
288  }
289 
290  return cur;
291  }
292 };
293 
294 } // end namespace serialization
295 } // end namespace clang
296 
297 #endif
clang::NestedNameSpecifier::Create
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
Definition: NestedNameSpecifier.cpp:59
clang::NestedNameSpecifier::Identifier
@ Identifier
An identifier, stored as an IdentifierInfo*.
Definition: NestedNameSpecifier.h:81
clang::NestedNameSpecifier::Super
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
Definition: NestedNameSpecifier.h:101
clang::interp::APInt
llvm::APInt APInt
Definition: Integral.h:27
clang::FunctionProtoType::ExceptionSpecInfo::NoexceptExpr
Expr * NoexceptExpr
Noexcept expression, if this is a computed noexcept specification.
Definition: Type.h:3950
clang::serialization::DataStreamBasicReader::readFixedPointSemantics
llvm::FixedPointSemantics readFixedPointSemantics()
Definition: AbstractBasicReader.h:180
llvm::SmallVector< uint64_t, 4 >
clang::NestedNameSpecifier::NamespaceAlias
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
Definition: NestedNameSpecifier.h:87
clang::serialization::DataStreamBasicReader::readQualifiers
Qualifiers readQualifiers()
Definition: AbstractBasicReader.h:214
clang::APValue::LValuePathSerializationHelper
Definition: APValue.h:240
clang::serialization::DataStreamBasicReader::readArray
llvm::ArrayRef< T > readArray(llvm::SmallVectorImpl< T > &buffer)
Definition: AbstractBasicReader.h:147
clang::NestedNameSpecifier
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Definition: NestedNameSpecifier.h:50
clang::serialization::DataStreamBasicReader::DataStreamBasicReader
DataStreamBasicReader(ASTContext &ctx)
Definition: AbstractBasicReader.h:126
clang::FunctionProtoType::ExceptionSpecInfo::SourceTemplate
FunctionDecl * SourceTemplate
The function template whose exception specification this is instantiated from, for EST_Uninstantiated...
Definition: Type.h:3958
clang::EST_Dynamic
@ EST_Dynamic
throw(T1, T2)
Definition: ExceptionSpecificationType.h:23
clang::Qualifiers
The collection of all-type qualifiers we support.
Definition: Type.h:145
llvm::Optional
Definition: LLVM.h:40
clang::isComputedNoexcept
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
Definition: ExceptionSpecificationType.h:39
clang::serialization::DataStreamBasicReader::find
Impl & find(const char *propertyName)
Implement property-find by ignoring it.
Definition: AbstractBasicReader.h:133
clang::serialization::DataStreamBasicReader::readLValuePathSerializationHelper
APValue::LValuePathSerializationHelper readLValuePathSerializationHelper(SmallVectorImpl< APValue::LValuePathEntry > &path)
Definition: AbstractBasicReader.h:191
clang::FunctionProtoType::ExceptionSpecInfo::SourceDecl
FunctionDecl * SourceDecl
The function whose exception specification this is, for EST_Unevaluated and EST_Uninstantiated.
Definition: Type.h:3954
clang::EST_Unevaluated
@ EST_Unevaluated
not evaluated yet, for special member function
Definition: ExceptionSpecificationType.h:30
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
clang::NestedNameSpecifier::Namespace
@ Namespace
A namespace, stored as a NamespaceDecl*.
Definition: NestedNameSpecifier.h:84
DeclTemplate.h
clang::serialization::DataStreamBasicReader::readObject
Impl & readObject()
Definition: AbstractBasicReader.h:144
clang::ExceptionSpecificationType
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
Definition: ExceptionSpecificationType.h:20
clang::FunctionProtoType::ExceptionSpecInfo
Holds information about the various types of exception specification.
Definition: Type.h:3942
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
clang::FunctionProtoType::ExceptionSpecInfo::Exceptions
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Definition: Type.h:3947
clang::serialization::makeNullableFromOptional
T makeNullableFromOptional(const Optional< T > &value)
Definition: AbstractBasicReader.h:18
clang::NestedNameSpecifier::Global
@ Global
The global specifier '::'. There is no stored value.
Definition: NestedNameSpecifier.h:97
clang::NestedNameSpecifier::TypeSpecWithTemplate
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
Definition: NestedNameSpecifier.h:94
clang::serialization::makePointerFromOptional
T * makePointerFromOptional(Optional< T * > value)
Definition: AbstractBasicReader.h:23
clang::serialization::BasicReaderBase
Definition: APValue.h:27
clang::FunctionType::ExtParameterInfo::getFromOpaqueValue
static ExtParameterInfo getFromOpaqueValue(unsigned char data)
Definition: Type.h:3622
clang::ast_matchers::decl
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Definition: ASTMatchersInternal.cpp:734
clang::EST_Uninstantiated
@ EST_Uninstantiated
not instantiated yet
Definition: ExceptionSpecificationType.h:31
clang::serialization::DataStreamBasicReader::readNestedNameSpecifier
NestedNameSpecifier * readNestedNameSpecifier()
Definition: AbstractBasicReader.h:246
llvm::ArrayRef
Definition: LLVM.h:34
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::FunctionType::ExtParameterInfo
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
Definition: Type.h:3572
clang::ast_matchers::recordDecl
const internal::VariadicDynCastAllOfMatcher< Decl, RecordDecl > recordDecl
Matches class, struct, and union declarations.
Definition: ASTMatchersInternal.cpp:744
clang::NestedNameSpecifier::SuperSpecifier
static NestedNameSpecifier * SuperSpecifier(const ASTContext &Context, CXXRecordDecl *RD)
Returns the nested name specifier representing the __super scope for the given CXXRecordDecl.
Definition: NestedNameSpecifier.cpp:134
clang::Qualifiers::fromOpaqueValue
static Qualifiers fromOpaqueValue(unsigned opaque)
Definition: Type.h:251
clang::APValue::LValuePathEntry::ArrayIndex
static LValuePathEntry ArrayIndex(uint64_t Index)
Definition: APValue.h:216
clang::serialization::DataStreamBasicReader::readExtParameterInfo
FunctionProtoType::ExtParameterInfo readExtParameterInfo()
Definition: AbstractBasicReader.h:238
clang::FunctionProtoType::ExceptionSpecInfo::Type
ExceptionSpecificationType Type
The kind of exception specification this is.
Definition: Type.h:3944
clang::serialization::DataStreamBasicReader::readEnum
T readEnum()
Definition: AbstractBasicReader.h:138
clang
Definition: CalledOnceCheck.h:17
clang::APValue::BaseOrMemberType
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
clang::serialization::DataStreamBasicReader::readAPSInt
llvm::APSInt readAPSInt()
Definition: AbstractBasicReader.h:165
clang::serialization::DataStreamBasicReader::readAPInt
llvm::APInt readAPInt()
Definition: AbstractBasicReader.h:171
clang::NestedNameSpecifier::GlobalSpecifier
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.
Definition: NestedNameSpecifier.cpp:126
clang::NestedNameSpecifier::TypeSpec
@ TypeSpec
A type, stored as a Type*.
Definition: NestedNameSpecifier.h:90
llvm::SmallVectorImpl
Definition: LLVM.h:39
clang::APValue::LValuePathEntry
A non-discriminated union of a base, field, or array index.
Definition: APValue.h:208
clang::serialization::DataStreamBasicReader::readOptional
llvm::Optional< T > readOptional(Args &&...args)
Definition: AbstractBasicReader.h:160
clang::diag::kind
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:62
clang::serialization::DataStreamBasicReader
DataStreamBasicReader provides convenience implementations for many BasicReader methods based on the ...
Definition: AbstractBasicReader.h:123
clang::serialization::DataStreamBasicReader::readExceptionSpecInfo
FunctionProtoType::ExceptionSpecInfo readExceptionSpecInfo(llvm::SmallVectorImpl< QualType > &buffer)
Definition: AbstractBasicReader.h:222