clang 10.0.0git

AbstractBasicWriter.h
Go to the documentation of this file.
1 //==--- AbstractBasicWriter.h - Abstract basic value serialization --------===//
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_ABSTRACTBASICWRITER_H
10 #define CLANG_AST_ABSTRACTBASICWRITER_H
11
12 #include "clang/AST/DeclTemplate.h"
13
14 namespace clang {
15 namespace serialization {
16
17 template <class T>
18 inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
19 return (value.isNull()
20 ? llvm::Optional<T>()
21 : llvm::Optional<T>(value));
22 }
23
24 template <class T>
25 inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
26 return (value ? llvm::Optional<T*>(value) : llvm::Optional<T*>());
27 }
28
29 // PropertyWriter is a class concept that requires the following method:
30 // BasicWriter find(llvm::StringRef propertyName);
31 // where BasicWriter is some class conforming to the BasicWriter concept.
32 // An abstract AST-node writer is created with a PropertyWriter and
33 // performs a sequence of calls like so:
34 // propertyWriter.find(propertyName).write##TypeName(value)
35 // to write the properties of the node it is serializing.
36
37 // BasicWriter is a class concept that requires methods like:
38 // void write##TypeName(ValueType value);
39 // where TypeName is the name of a PropertyType node from PropertiesBase.td
40 // and ValueType is the corresponding C++ type name.
41 //
42 // In addition to the concrete property types, BasicWriter is expected
43 // to implement these methods:
44 //
45 // template <class EnumType>
46 // void writeEnum(T value);
47 //
48 // Writes an enum value as the current property. EnumType will always
49 // be an enum type. Only necessary if the BasicWriter doesn't provide
50 // type-specific writers for all the enum types.
51 //
52 // template <class ValueType>
53 // void writeOptional(Optional<ValueType> value);
54 //
55 // Writes an optional value as the current property.
56 //
57 // template <class ValueType>
58 // void writeArray(ArrayRef<ValueType> value);
59 //
60 // Writes an array of values as the current property.
61 //
62 // PropertyWriter writeObject();
63 //
64 // Writes an object as the current property; the returned property
65 // writer will be subjected to a sequence of property writes and then
66 // discarded before any other properties are written to the "outer"
67 // property writer (which need not be the same type). The sub-writer
68 // will be used as if with the following code:
69 //
70 // {
71 // auto &&widget = W.find("widget").writeObject();
72 // widget.find("kind").writeWidgetKind(...);
73 // widget.find("declaration").writeDeclRef(...);
74 // }
75
76 // WriteDispatcher is a template which does type-based forwarding to one
77 // of the write methods of the BasicWriter passed in:
78 //
79 // template <class ValueType>
80 // struct WriteDispatcher {
81 // template <class BasicWriter>
82 // static void write(BasicWriter &W, ValueType value);
83 // };
84
85 // BasicWriterBase provides convenience implementations of the write
86 // methods for EnumPropertyType and SubclassPropertyType types that just
87 // defer to the "underlying" implementations (for UInt32 and the base class,
88 // respectively).
89 //
90 // template <class Impl>
91 // class BasicWriterBase {
92 // protected:
93 // Impl &asImpl();
94 // public:
95 // ...
96 // };
97
98 // The actual classes are auto-generated; see ClangASTPropertiesEmitter.cpp.
99 #include "clang/AST/AbstractBasicWriter.inc"
100
101 /// DataStreamBasicWriter provides convenience implementations for many
102 /// BasicWriter methods based on the assumption that the
103 /// ultimate writer implementation is based on a variable-length stream
104 /// of unstructured data (like Clang's module files). It is designed
105 /// to pair with DataStreamBasicReader.
106 ///
107 /// This class can also act as a PropertyWriter, implementing find("...")
108 /// by simply forwarding to itself.
109 ///
110 /// Unimplemented methods:
111 /// writeBool
112 /// writeUInt32
113 /// writeUInt64
114 /// writeIdentifier
115 /// writeSelector
116 /// writeSourceLocation
117 /// writeQualType
118 /// writeStmtRef
119 /// writeDeclRef
120 template <class Impl>
121 class DataStreamBasicWriter : public BasicWriterBase<Impl> {
122 protected:
123 using BasicWriterBase<Impl>::asImpl;
124
125 public:
126 /// Implement property-find by ignoring it. We rely on properties being
127 /// serialized and deserialized in a reliable order instead.
128 Impl &find(const char *propertyName) {
129 return asImpl();
130 }
131
132 // Implement object writing by forwarding to this, collapsing the
133 // structure into a single data stream.
134 Impl &writeObject() { return asImpl(); }
135
136 template <class T>
137 void writeEnum(T value) {
138 asImpl().writeUInt32(uint32_t(value));
139 }
140
141 template <class T>
142 void writeArray(llvm::ArrayRef<T> array) {
143 asImpl().writeUInt32(array.size());
144 for (const T &elt : array) {
145 WriteDispatcher<T>::write(asImpl(), elt);
146 }
147 }
148
149 template <class T>
150 void writeOptional(llvm::Optional<T> value) {
151 WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152 }
153
154 void writeAPSInt(const llvm::APSInt &value) {
155 asImpl().writeBool(value.isUnsigned());
156 asImpl().writeAPInt(value);
157 }
158
159 void writeAPInt(const llvm::APInt &value) {
160 asImpl().writeUInt32(value.getBitWidth());
161 const uint64_t *words = value.getRawData();
162 for (size_t i = 0, e = value.getNumWords(); i != e; ++i)
163 asImpl().writeUInt64(words[i]);
164 }
165
166 void writeQualifiers(Qualifiers value) {
167 static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t),
168 "update this if the value size changes");
169 asImpl().writeUInt32(value.getAsOpaqueValue());
170 }
171
172 void writeExceptionSpecInfo(
173 const FunctionProtoType::ExceptionSpecInfo &esi) {
174 asImpl().writeUInt32(uint32_t(esi.Type));
175 if (esi.Type == EST_Dynamic) {
176 asImpl().writeArray(esi.Exceptions);
177 } else if (isComputedNoexcept(esi.Type)) {
178 asImpl().writeExprRef(esi.NoexceptExpr);
179 } else if (esi.Type == EST_Uninstantiated) {
180 asImpl().writeDeclRef(esi.SourceDecl);
181 asImpl().writeDeclRef(esi.SourceTemplate);
182 } else if (esi.Type == EST_Unevaluated) {
183 asImpl().writeDeclRef(esi.SourceDecl);
184 }
185 }
186
187 void writeExtParameterInfo(FunctionProtoType::ExtParameterInfo epi) {
188 static_assert(sizeof(epi.getOpaqueValue()) <= sizeof(uint32_t),
189 "opaque value doesn't fit into uint32_t");
190 asImpl().writeUInt32(epi.getOpaqueValue());
191 }
192
193 void writeNestedNameSpecifier(NestedNameSpecifier *NNS) {
194 // Nested name specifiers usually aren't too long. I think that 8 would
195 // typically accommodate the vast majority.
196 SmallVector<NestedNameSpecifier *, 8> nestedNames;
197
198 // Push each of the NNS's onto a stack for serialization in reverse order.
199 while (NNS) {
200 nestedNames.push_back(NNS);
201 NNS = NNS->getPrefix();
202 }
203
204 asImpl().writeUInt32(nestedNames.size());
205 while (!nestedNames.empty()) {
206 NNS = nestedNames.pop_back_val();
207 NestedNameSpecifier::SpecifierKind kind = NNS->getKind();
208 asImpl().writeNestedNameSpecifierKind(kind);
209 switch (kind) {
210 case NestedNameSpecifier::Identifier:
211 asImpl().writeIdentifier(NNS->getAsIdentifier());
212 continue;
213
214 case NestedNameSpecifier::Namespace:
215 asImpl().writeNamespaceDeclRef(NNS->getAsNamespace());
216 continue;
217
218 case NestedNameSpecifier::NamespaceAlias:
219 asImpl().writeNamespaceAliasDeclRef(NNS->getAsNamespaceAlias());
220 continue;
221
222 case NestedNameSpecifier::TypeSpec:
223 case NestedNameSpecifier::TypeSpecWithTemplate:
224 asImpl().writeQualType(QualType(NNS->getAsType(), 0));
225 continue;
226
227 case NestedNameSpecifier::Global:
228 // Don't need to write an associated value.
229 continue;
230
231 case NestedNameSpecifier::Super:
232 asImpl().writeDeclRef(NNS->getAsRecordDecl());
233 continue;
234 }
235 llvm_unreachable("bad nested name specifier kind");
236 }
237 }
238 };
239
240 } // end namespace serialization
241 } // end namespace clang
242
243 #endif
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:654
clang::NestedNameSpecifier::Super
Microsoft&#39;s &#39;__super&#39; specifier, stored as a CXXRecordDecl* of the class it appeared in...
Definition: NestedNameSpecifier.h:99
clang::NestedNameSpecifier::getPrefix
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
Definition: NestedNameSpecifier.h:167
DeclTemplate.h
Defines the C++ template declaration subclasses.
clang::serialization::DataStreamBasicWriter::writeOptional
void writeOptional(llvm::Optional< T > value)
Definition: AbstractBasicWriter.h:150
clang::NestedNameSpecifier::Identifier
An identifier, stored as an IdentifierInfo*.
Definition: NestedNameSpecifier.h:79
clang::serialization::makeOptionalFromNullable
llvm::Optional< T > makeOptionalFromNullable(const T &value)
Definition: AbstractBasicWriter.h:18
clang::EST_Dynamic
throw(T1, T2)
Definition: ExceptionSpecificationType.h:23
clang::NestedNameSpecifier::Namespace
A namespace, stored as a NamespaceDecl*.
Definition: NestedNameSpecifier.h:82
clang::NestedNameSpecifier::getKind
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
Definition: NestedNameSpecifier.cpp:142
clang::Qualifiers
The collection of all-type qualifiers we support.
Definition: Type.h:143
llvm::Optional
Definition: LLVM.h:37
clang::NestedNameSpecifier::getAsType
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
Definition: NestedNameSpecifier.h:194
clang::FunctionType::ExtParameterInfo::getOpaqueValue
unsigned char getOpaqueValue() const
Definition: Type.h:3497
clang::NestedNameSpecifier::getAsRecordDecl
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
Definition: NestedNameSpecifier.cpp:184
clang::NestedNameSpecifier::getAsIdentifier
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
Definition: NestedNameSpecifier.h:174
clang::NestedNameSpecifier::getAsNamespaceAlias
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
Definition: NestedNameSpecifier.cpp:176
clang::serialization::DataStreamBasicWriter::writeObject
Impl & writeObject()
Definition: AbstractBasicWriter.h:134
llvm::ArrayRef
Definition: LLVM.h:31
clang::FunctionProtoType::ExceptionSpecInfo::SourceDecl
FunctionDecl * SourceDecl
The function whose exception specification this is, for EST_Unevaluated and EST_Uninstantiated.
Definition: Type.h:3823
clang::serialization::DataStreamBasicWriter::writeQualifiers
void writeQualifiers(Qualifiers value)
Definition: AbstractBasicWriter.h:166
clang::serialization::DataStreamBasicWriter::writeEnum
void writeEnum(T value)
Definition: AbstractBasicWriter.h:137
clang::serialization::DataStreamBasicWriter::writeAPSInt
void writeAPSInt(const llvm::APSInt &value)
Definition: AbstractBasicWriter.h:154
clang::NestedNameSpecifier::getAsNamespace
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
Definition: NestedNameSpecifier.cpp:168
clang::Qualifiers::getAsOpaqueValue
unsigned getAsOpaqueValue() const
Definition: Type.h:256
clang::NestedNameSpecifier::NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
Definition: NestedNameSpecifier.h:85
clang::NestedNameSpecifier::TypeSpec
A type, stored as a Type*.
Definition: NestedNameSpecifier.h:88
clang::serialization::DataStreamBasicWriter::writeExtParameterInfo
void writeExtParameterInfo(FunctionProtoType::ExtParameterInfo epi)
Definition: AbstractBasicWriter.h:187
clang::NestedNameSpecifier::SpecifierKind
SpecifierKind
The kind of specifier that completes this nested name specifier.
Definition: NestedNameSpecifier.h:77
clang::isComputedNoexcept
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
Definition: ExceptionSpecificationType.h:39
clang::FunctionProtoType::ExceptionSpecInfo::Type
ExceptionSpecificationType Type
The kind of exception specification this is.
Definition: Type.h:3813
clang::serialization::DataStreamBasicWriter
DataStreamBasicWriter provides convenience implementations for many BasicWriter methods based on the ...
Definition: AbstractBasicWriter.h:121
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:18
clang::EST_Uninstantiated
not instantiated yet
Definition: ExceptionSpecificationType.h:31
clang::NestedNameSpecifier
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Definition: NestedNameSpecifier.h:48
llvm::SmallVector
Definition: LLVM.h:35
clang::interp::APInt
llvm::APInt APInt
Definition: Integral.h:27
clang::serialization::DataStreamBasicWriter::writeAPInt
void writeAPInt(const llvm::APInt &value)
Definition: AbstractBasicWriter.h:159
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:21
clang::EST_Unevaluated
not evaluated yet, for special member function
Definition: ExceptionSpecificationType.h:30
clang::FunctionType::ExtParameterInfo
Interesting information about a specific parameter that can&#39;t simply be reflected in parameter&#39;s type...
Definition: Type.h:3448
clang::NestedNameSpecifier::TypeSpecWithTemplate
A type that was preceded by the &#39;template&#39; keyword, stored as a Type*.
Definition: NestedNameSpecifier.h:92
clang::serialization::makeOptionalFromPointer
llvm::Optional< T * > makeOptionalFromPointer(T *value)
Definition: AbstractBasicWriter.h:25
clang::FunctionProtoType::ExceptionSpecInfo::SourceTemplate
FunctionDecl * SourceTemplate
The function template whose exception specification this is instantiated from, for EST_Uninstantiated...
Definition: Type.h:3827
clang::FunctionProtoType::ExceptionSpecInfo
Holds information about the various types of exception specification.
Definition: Type.h:3811
clang::FunctionProtoType::ExceptionSpecInfo::Exceptions
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Definition: Type.h:3816
clang::FunctionProtoType::ExceptionSpecInfo::NoexceptExpr
Expr * NoexceptExpr
Noexcept expression, if this is a computed noexcept specification.
Definition: Type.h:3819
clang::serialization::DataStreamBasicWriter::find
Impl & find(const char *propertyName)
Implement property-find by ignoring it.
Definition: AbstractBasicWriter.h:128
clang::diag::kind
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:60
clang::serialization::DataStreamBasicWriter::writeExceptionSpecInfo
void writeExceptionSpecInfo(const FunctionProtoType::ExceptionSpecInfo &esi)
Definition: AbstractBasicWriter.h:172
clang::serialization::DataStreamBasicWriter::writeNestedNameSpecifier
void writeNestedNameSpecifier(NestedNameSpecifier *NNS)
Definition: AbstractBasicWriter.h:193
clang::NestedNameSpecifier::Global
The global specifier &#39;::&#39;. There is no stored value.
Definition: NestedNameSpecifier.h:95
clang::serialization::DataStreamBasicWriter::writeArray
void writeArray(llvm::ArrayRef< T > array)
Definition: AbstractBasicWriter.h:142