Coverage Report

Created: 2022-05-21 09:15

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h
Line
Count
Source (jump to first uncovered line)
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 LLVM_CLANG_AST_ABSTRACTBASICWRITER_H
10
#define LLVM_CLANG_AST_ABSTRACTBASICWRITER_H
11
12
#include "clang/AST/ASTContext.h"
13
#include "clang/AST/DeclTemplate.h"
14
15
namespace clang {
16
namespace serialization {
17
18
template <class T>
19
139k
inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
20
139k
  return (value.isNull()
21
139k
            ? 
llvm::Optional<T>()93
22
139k
            : 
llvm::Optional<T>(value)139k
);
23
139k
}
llvm::Optional<clang::QualType> clang::serialization::makeOptionalFromNullable<clang::QualType>(clang::QualType const&)
Line
Count
Source
19
139k
inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
20
139k
  return (value.isNull()
21
139k
            ? 
llvm::Optional<T>()93
22
139k
            : 
llvm::Optional<T>(value)139k
);
23
139k
}
llvm::Optional<clang::TemplateName> clang::serialization::makeOptionalFromNullable<clang::TemplateName>(clang::TemplateName const&)
Line
Count
Source
19
14
inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
20
14
  return (value.isNull()
21
14
            ? 
llvm::Optional<T>()0
22
14
            : llvm::Optional<T>(value));
23
14
}
24
25
template <class T>
26
225k
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
27
225k
  return (value ? 
llvm::Optional<T*>(value)179k
:
llvm::Optional<T*>()46.1k
);
28
225k
}
llvm::Optional<clang::ConceptDecl const*> clang::serialization::makeOptionalFromPointer<clang::ConceptDecl const>(clang::ConceptDecl const*)
Line
Count
Source
26
575
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
27
575
  return (value ? 
llvm::Optional<T*>(value)0
: llvm::Optional<T*>());
28
575
}
llvm::Optional<clang::IdentifierInfo const*> clang::serialization::makeOptionalFromPointer<clang::IdentifierInfo const>(clang::IdentifierInfo const*)
Line
Count
Source
26
30
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
27
30
  return (value ? llvm::Optional<T*>(value) : 
llvm::Optional<T*>()0
);
28
30
}
llvm::Optional<clang::TagDecl const*> clang::serialization::makeOptionalFromPointer<clang::TagDecl const>(clang::TagDecl const*)
Line
Count
Source
26
76.0k
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
27
76.0k
  return (value ? 
llvm::Optional<T*>(value)32.3k
:
llvm::Optional<T*>()43.6k
);
28
76.0k
}
llvm::Optional<clang::TemplateTypeParmDecl const*> clang::serialization::makeOptionalFromPointer<clang::TemplateTypeParmDecl const>(clang::TemplateTypeParmDecl const*)
Line
Count
Source
26
149k
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
27
149k
  return (value ? 
llvm::Optional<T*>(value)147k
:
llvm::Optional<T*>()1.98k
);
28
149k
}
29
30
// PropertyWriter is a class concept that requires the following method:
31
//   BasicWriter find(llvm::StringRef propertyName);
32
// where BasicWriter is some class conforming to the BasicWriter concept.
33
// An abstract AST-node writer is created with a PropertyWriter and
34
// performs a sequence of calls like so:
35
//   propertyWriter.find(propertyName).write##TypeName(value)
36
// to write the properties of the node it is serializing.
37
38
// BasicWriter is a class concept that requires methods like:
39
//   void write##TypeName(ValueType value);
40
// where TypeName is the name of a PropertyType node from PropertiesBase.td
41
// and ValueType is the corresponding C++ type name.
42
//
43
// In addition to the concrete property types, BasicWriter is expected
44
// to implement these methods:
45
//
46
//   template <class EnumType>
47
//   void writeEnum(T value);
48
//
49
//     Writes an enum value as the current property.  EnumType will always
50
//     be an enum type.  Only necessary if the BasicWriter doesn't provide
51
//     type-specific writers for all the enum types.
52
//
53
//   template <class ValueType>
54
//   void writeOptional(Optional<ValueType> value);
55
//
56
//     Writes an optional value as the current property.
57
//
58
//   template <class ValueType>
59
//   void writeArray(ArrayRef<ValueType> value);
60
//
61
//     Writes an array of values as the current property.
62
//
63
//   PropertyWriter writeObject();
64
//
65
//     Writes an object as the current property; the returned property
66
//     writer will be subjected to a sequence of property writes and then
67
//     discarded before any other properties are written to the "outer"
68
//     property writer (which need not be the same type).  The sub-writer
69
//     will be used as if with the following code:
70
//
71
//       {
72
//         auto &&widget = W.find("widget").writeObject();
73
//         widget.find("kind").writeWidgetKind(...);
74
//         widget.find("declaration").writeDeclRef(...);
75
//       }
76
77
// WriteDispatcher is a template which does type-based forwarding to one
78
// of the write methods of the BasicWriter passed in:
79
//
80
// template <class ValueType>
81
// struct WriteDispatcher {
82
//   template <class BasicWriter>
83
//   static void write(BasicWriter &W, ValueType value);
84
// };
85
86
// BasicWriterBase provides convenience implementations of the write
87
// methods for EnumPropertyType and SubclassPropertyType types that just
88
// defer to the "underlying" implementations (for UInt32 and the base class,
89
// respectively).
90
//
91
// template <class Impl>
92
// class BasicWriterBase {
93
// protected:
94
//   Impl &asImpl();
95
// public:
96
//   ...
97
// };
98
99
// The actual classes are auto-generated; see ClangASTPropertiesEmitter.cpp.
100
#include "clang/AST/AbstractBasicWriter.inc"
101
102
/// DataStreamBasicWriter provides convenience implementations for many
103
/// BasicWriter methods based on the assumption that the
104
/// ultimate writer implementation is based on a variable-length stream
105
/// of unstructured data (like Clang's module files).  It is designed
106
/// to pair with DataStreamBasicReader.
107
///
108
/// This class can also act as a PropertyWriter, implementing find("...")
109
/// by simply forwarding to itself.
110
///
111
/// Unimplemented methods:
112
///   writeBool
113
///   writeUInt32
114
///   writeUInt64
115
///   writeIdentifier
116
///   writeSelector
117
///   writeSourceLocation
118
///   writeQualType
119
///   writeStmtRef
120
///   writeDeclRef
121
template <class Impl>
122
class DataStreamBasicWriter : public BasicWriterBase<Impl> {
123
protected:
124
  using BasicWriterBase<Impl>::asImpl;
125
10.5M
  DataStreamBasicWriter(ASTContext &ctx) : BasicWriterBase<Impl>(ctx) {}
126
127
public:
128
  /// Implement property-find by ignoring it.  We rely on properties being
129
  /// serialized and deserialized in a reliable order instead.
130
17.3M
  Impl &find(const char *propertyName) {
131
17.3M
    return asImpl();
132
17.3M
  }
133
134
  // Implement object writing by forwarding to this, collapsing the
135
  // structure into a single data stream.
136
4.49M
  Impl &writeObject() { return asImpl(); }
137
138
  template <class T>
139
5.46M
  void writeEnum(T value) {
140
5.46M
    asImpl().writeUInt32(uint32_t(value));
141
5.46M
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::ArrayType::ArraySizeModifier>(clang::ArrayType::ArraySizeModifier)
Line
Count
Source
139
16.9k
  void writeEnum(T value) {
140
16.9k
    asImpl().writeUInt32(uint32_t(value));
141
16.9k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::attr::Kind>(clang::attr::Kind)
Line
Count
Source
139
16.7k
  void writeEnum(T value) {
140
16.7k
    asImpl().writeUInt32(uint32_t(value));
141
16.7k
  }
Unexecuted instantiation: void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::BuiltinType::Kind>(clang::BuiltinType::Kind)
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::AutoTypeKeyword>(clang::AutoTypeKeyword)
Line
Count
Source
139
575
  void writeEnum(T value) {
140
575
    asImpl().writeUInt32(uint32_t(value));
141
575
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::TemplateArgument::ArgKind>(clang::TemplateArgument::ArgKind)
Line
Count
Source
139
748k
  void writeEnum(T value) {
140
748k
    asImpl().writeUInt32(uint32_t(value));
141
748k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::TemplateName::NameKind>(clang::TemplateName::NameKind)
Line
Count
Source
139
353k
  void writeEnum(T value) {
140
353k
    asImpl().writeUInt32(uint32_t(value));
141
353k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::DeclarationName::NameKind>(clang::DeclarationName::NameKind)
Line
Count
Source
139
3.39M
  void writeEnum(T value) {
140
3.39M
    asImpl().writeUInt32(uint32_t(value));
141
3.39M
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::NestedNameSpecifier::SpecifierKind>(clang::NestedNameSpecifier::SpecifierKind)
Line
Count
Source
139
98.2k
  void writeEnum(T value) {
140
98.2k
    asImpl().writeUInt32(uint32_t(value));
141
98.2k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OverloadedOperatorKind>(clang::OverloadedOperatorKind)
Line
Count
Source
139
130k
  void writeEnum(T value) {
140
130k
    asImpl().writeUInt32(uint32_t(value));
141
130k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::ElaboratedTypeKeyword>(clang::ElaboratedTypeKeyword)
Line
Count
Source
139
142k
  void writeEnum(T value) {
140
142k
    asImpl().writeUInt32(uint32_t(value));
141
142k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::VectorType::VectorKind>(clang::VectorType::VectorKind)
Line
Count
Source
139
2.47k
  void writeEnum(T value) {
140
2.47k
    asImpl().writeUInt32(uint32_t(value));
141
2.47k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::CallingConv>(clang::CallingConv)
Line
Count
Source
139
279k
  void writeEnum(T value) {
140
279k
    asImpl().writeUInt32(uint32_t(value));
141
279k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::RefQualifierKind>(clang::RefQualifierKind)
Line
Count
Source
139
279k
  void writeEnum(T value) {
140
279k
    asImpl().writeUInt32(uint32_t(value));
141
279k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::UnaryTransformType::UTTKind>(clang::UnaryTransformType::UTTKind)
Line
Count
Source
139
78
  void writeEnum(T value) {
140
78
    asImpl().writeUInt32(uint32_t(value));
141
78
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPBindClauseKind>(clang::OpenMPBindClauseKind)
Line
Count
Source
139
20
  void writeEnum(T value) {
140
20
    asImpl().writeUInt32(uint32_t(value));
141
20
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPDeviceClauseModifier>(clang::OpenMPDeviceClauseModifier)
Line
Count
Source
139
353
  void writeEnum(T value) {
140
353
    asImpl().writeUInt32(uint32_t(value));
141
353
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPLastprivateModifier>(clang::OpenMPLastprivateModifier)
Line
Count
Source
139
452
  void writeEnum(T value) {
140
452
    asImpl().writeUInt32(uint32_t(value));
141
452
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPOrderClauseKind>(clang::OpenMPOrderClauseKind)
Line
Count
Source
139
52
  void writeEnum(T value) {
140
52
    asImpl().writeUInt32(uint32_t(value));
141
52
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPReductionClauseModifier>(clang::OpenMPReductionClauseModifier)
Line
Count
Source
139
949
  void writeEnum(T value) {
140
949
    asImpl().writeUInt32(uint32_t(value));
141
949
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPDependClauseKind>(clang::OpenMPDependClauseKind)
Line
Count
Source
139
8
  void writeEnum(T value) {
140
8
    asImpl().writeUInt32(uint32_t(value));
141
8
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<llvm::omp::TraitSet>(llvm::omp::TraitSet)
Line
Count
Source
139
705
  void writeEnum(T value) {
140
705
    asImpl().writeUInt32(uint32_t(value));
141
705
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<llvm::omp::TraitSelector>(llvm::omp::TraitSelector)
Line
Count
Source
139
737
  void writeEnum(T value) {
140
737
    asImpl().writeUInt32(uint32_t(value));
141
737
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<llvm::omp::TraitProperty>(llvm::omp::TraitProperty)
Line
Count
Source
139
1.13k
  void writeEnum(T value) {
140
1.13k
    asImpl().writeUInt32(uint32_t(value));
141
1.13k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::APValue::ValueKind>(clang::APValue::ValueKind)
Line
Count
Source
139
192
  void writeEnum(T value) {
140
192
    asImpl().writeUInt32(uint32_t(value));
141
192
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<llvm::omp::Directive>(llvm::omp::Directive)
Line
Count
Source
139
232
  void writeEnum(T value) {
140
232
    asImpl().writeUInt32(uint32_t(value));
141
232
  }
142
143
  template <class T>
144
925k
  void writeArray(llvm::ArrayRef<T> array) {
145
925k
    asImpl().writeUInt32(array.size());
146
1.15M
    for (const T &elt : array) {
147
1.15M
      WriteDispatcher<T>::write(asImpl(), elt);
148
1.15M
    }
149
925k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::TemplateArgument>(llvm::ArrayRef<clang::TemplateArgument>)
Line
Count
Source
144
361k
  void writeArray(llvm::ArrayRef<T> array) {
145
361k
    asImpl().writeUInt32(array.size());
146
603k
    for (const T &elt : array) {
147
603k
      WriteDispatcher<T>::write(asImpl(), elt);
148
603k
    }
149
361k
  }
Unexecuted instantiation: void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::NamedDecl const*>(llvm::ArrayRef<clang::NamedDecl const*>)
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::QualType>(llvm::ArrayRef<clang::QualType>)
Line
Count
Source
144
281k
  void writeArray(llvm::ArrayRef<T> array) {
145
281k
    asImpl().writeUInt32(array.size());
146
553k
    for (const T &elt : array) {
147
553k
      WriteDispatcher<T>::write(asImpl(), elt);
148
553k
    }
149
281k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::FunctionType::ExtParameterInfo>(llvm::ArrayRef<clang::FunctionType::ExtParameterInfo>)
Line
Count
Source
144
279k
  void writeArray(llvm::ArrayRef<T> array) {
145
279k
    asImpl().writeUInt32(array.size());
146
279k
    for (const T &elt : array) {
147
835
      WriteDispatcher<T>::write(asImpl(), elt);
148
835
    }
149
279k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::ObjCProtocolDecl const*>(llvm::ArrayRef<clang::ObjCProtocolDecl const*>)
Line
Count
Source
144
3.69k
  void writeArray(llvm::ArrayRef<T> array) {
145
3.69k
    asImpl().writeUInt32(array.size());
146
3.69k
    for (const T &elt : array) {
147
966
      WriteDispatcher<T>::write(asImpl(), elt);
148
966
    }
149
3.69k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::APValue>(llvm::ArrayRef<clang::APValue>)
Line
Count
Source
144
69
  void writeArray(llvm::ArrayRef<T> array) {
145
69
    asImpl().writeUInt32(array.size());
146
142
    for (const T &elt : array) {
147
142
      WriteDispatcher<T>::write(asImpl(), elt);
148
142
    }
149
69
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::CXXRecordDecl const*>(llvm::ArrayRef<clang::CXXRecordDecl const*>)
Line
Count
Source
144
6
  void writeArray(llvm::ArrayRef<T> array) {
145
6
    asImpl().writeUInt32(array.size());
146
6
    for (const T &elt : array) {
147
0
      WriteDispatcher<T>::write(asImpl(), elt);
148
0
    }
149
6
  }
150
151
  template <class T>
152
791k
  void writeOptional(llvm::Optional<T> value) {
153
791k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
154
791k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::QualType>(llvm::Optional<clang::QualType>)
Line
Count
Source
152
556k
  void writeOptional(llvm::Optional<T> value) {
153
556k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
154
556k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::ConceptDecl const*>(llvm::Optional<clang::ConceptDecl const*>)
Line
Count
Source
152
575
  void writeOptional(llvm::Optional<T> value) {
153
575
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
154
575
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::IdentifierInfo const*>(llvm::Optional<clang::IdentifierInfo const*>)
Line
Count
Source
152
30
  void writeOptional(llvm::Optional<T> value) {
153
30
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
154
30
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<unsigned int>(llvm::Optional<unsigned int>)
Line
Count
Source
152
9.88k
  void writeOptional(llvm::Optional<T> value) {
153
9.88k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
154
9.88k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::TemplateName>(llvm::Optional<clang::TemplateName>)
Line
Count
Source
152
14
  void writeOptional(llvm::Optional<T> value) {
153
14
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
154
14
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::TagDecl const*>(llvm::Optional<clang::TagDecl const*>)
Line
Count
Source
152
76.0k
  void writeOptional(llvm::Optional<T> value) {
153
76.0k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
154
76.0k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::TemplateTypeParmDecl const*>(llvm::Optional<clang::TemplateTypeParmDecl const*>)
Line
Count
Source
152
149k
  void writeOptional(llvm::Optional<T> value) {
153
149k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
154
149k
  }
155
156
182k
  void writeAPSInt(const llvm::APSInt &value) {
157
182k
    asImpl().writeBool(value.isUnsigned());
158
182k
    asImpl().writeAPInt(value);
159
182k
  }
160
161
596k
  void writeAPInt(const llvm::APInt &value) {
162
596k
    asImpl().writeUInt32(value.getBitWidth());
163
596k
    const uint64_t *words = value.getRawData();
164
1.19M
    for (size_t i = 0, e = value.getNumWords(); i != e; 
++i596k
)
165
596k
      asImpl().writeUInt64(words[i]);
166
596k
  }
167
168
0
  void writeFixedPointSemantics(const llvm::FixedPointSemantics &sema) {
169
0
    asImpl().writeUInt32(sema.getWidth());
170
0
    asImpl().writeUInt32(sema.getScale());
171
0
    asImpl().writeUInt32(sema.isSigned() | sema.isSaturated() << 1 |
172
0
                         sema.hasUnsignedPadding() << 2);
173
0
  }
174
175
  void writeLValuePathSerializationHelper(
176
21
      APValue::LValuePathSerializationHelper lvaluePath) {
177
21
    ArrayRef<APValue::LValuePathEntry> path = lvaluePath.Path;
178
21
    QualType elemTy = lvaluePath.getType();
179
21
    asImpl().writeQualType(elemTy);
180
21
    asImpl().writeUInt32(path.size());
181
21
    auto &ctx = ((BasicWriterBase<Impl> *)this)->getASTContext();
182
21
    for (auto elem : path) {
183
15
      if (elemTy->getAs<RecordType>()) {
184
9
        asImpl().writeUInt32(elem.getAsBaseOrMember().getInt());
185
9
        const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
186
9
        if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
187
1
          asImpl().writeDeclRef(recordDecl);
188
1
          elemTy = ctx.getRecordType(recordDecl);
189
8
        } else {
190
8
          const auto *valueDecl = cast<ValueDecl>(baseOrMember);
191
8
          asImpl().writeDeclRef(valueDecl);
192
8
          elemTy = valueDecl->getType();
193
8
        }
194
9
      } else {
195
6
        asImpl().writeUInt32(elem.getAsArrayIndex());
196
6
        elemTy = ctx.getAsArrayType(elemTy)->getElementType();
197
6
      }
198
15
    }
199
21
  }
200
201
302k
  void writeQualifiers(Qualifiers value) {
202
302k
    static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t),
203
302k
                  "update this if the value size changes");
204
302k
    asImpl().writeUInt32(value.getAsOpaqueValue());
205
302k
  }
206
207
  void writeExceptionSpecInfo(
208
279k
                        const FunctionProtoType::ExceptionSpecInfo &esi) {
209
279k
    asImpl().writeUInt32(uint32_t(esi.Type));
210
279k
    if (esi.Type == EST_Dynamic) {
211
3
      asImpl().writeArray(esi.Exceptions);
212
279k
    } else if (isComputedNoexcept(esi.Type)) {
213
7.23k
      asImpl().writeExprRef(esi.NoexceptExpr);
214
271k
    } else if (esi.Type == EST_Uninstantiated) {
215
1.44k
      asImpl().writeDeclRef(esi.SourceDecl);
216
1.44k
      asImpl().writeDeclRef(esi.SourceTemplate);
217
270k
    } else if (esi.Type == EST_Unevaluated) {
218
15.1k
      asImpl().writeDeclRef(esi.SourceDecl);
219
15.1k
    }
220
279k
  }
221
222
835
  void writeExtParameterInfo(FunctionProtoType::ExtParameterInfo epi) {
223
835
    static_assert(sizeof(epi.getOpaqueValue()) <= sizeof(uint32_t),
224
835
                  "opaque value doesn't fit into uint32_t");
225
835
    asImpl().writeUInt32(epi.getOpaqueValue());
226
835
  }
227
228
142k
  void writeNestedNameSpecifier(NestedNameSpecifier *NNS) {
229
    // Nested name specifiers usually aren't too long. I think that 8 would
230
    // typically accommodate the vast majority.
231
142k
    SmallVector<NestedNameSpecifier *, 8> nestedNames;
232
233
    // Push each of the NNS's onto a stack for serialization in reverse order.
234
240k
    while (NNS) {
235
98.2k
      nestedNames.push_back(NNS);
236
98.2k
      NNS = NNS->getPrefix();
237
98.2k
    }
238
239
142k
    asImpl().writeUInt32(nestedNames.size());
240
240k
    while (!nestedNames.empty()) {
241
98.2k
      NNS = nestedNames.pop_back_val();
242
98.2k
      NestedNameSpecifier::SpecifierKind kind = NNS->getKind();
243
98.2k
      asImpl().writeNestedNameSpecifierKind(kind);
244
98.2k
      switch (kind) {
245
687
      case NestedNameSpecifier::Identifier:
246
687
        asImpl().writeIdentifier(NNS->getAsIdentifier());
247
687
        continue;
248
249
4.65k
      case NestedNameSpecifier::Namespace:
250
4.65k
        asImpl().writeNamespaceDeclRef(NNS->getAsNamespace());
251
4.65k
        continue;
252
253
4
      case NestedNameSpecifier::NamespaceAlias:
254
4
        asImpl().writeNamespaceAliasDeclRef(NNS->getAsNamespaceAlias());
255
4
        continue;
256
257
92.7k
      case NestedNameSpecifier::TypeSpec:
258
92.8k
      case NestedNameSpecifier::TypeSpecWithTemplate:
259
92.8k
        asImpl().writeQualType(QualType(NNS->getAsType(), 0));
260
92.8k
        continue;
261
262
17
      case NestedNameSpecifier::Global:
263
        // Don't need to write an associated value.
264
17
        continue;
265
266
0
      case NestedNameSpecifier::Super:
267
0
        asImpl().writeDeclRef(NNS->getAsRecordDecl());
268
0
        continue;
269
98.2k
      }
270
0
      llvm_unreachable("bad nested name specifier kind");
271
0
    }
272
142k
  }
273
};
274
275
} // end namespace serialization
276
} // end namespace clang
277
278
#endif