Coverage Report

Created: 2020-09-15 12:33

/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 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
140k
inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
19
140k
  return (value.isNull()
20
82
            ? llvm::Optional<T>()
21
140k
            : llvm::Optional<T>(value));
22
140k
}
llvm::Optional<clang::QualType> clang::serialization::makeOptionalFromNullable<clang::QualType>(clang::QualType const&)
Line
Count
Source
18
140k
inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
19
140k
  return (value.isNull()
20
82
            ? llvm::Optional<T>()
21
140k
            : llvm::Optional<T>(value));
22
140k
}
llvm::Optional<clang::TemplateName> clang::serialization::makeOptionalFromNullable<clang::TemplateName>(clang::TemplateName const&)
Line
Count
Source
18
12
inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
19
12
  return (value.isNull()
20
0
            ? llvm::Optional<T>()
21
12
            : llvm::Optional<T>(value));
22
12
}
23
24
template <class T>
25
230k
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
26
177k
  return (value ? llvm::Optional<T*>(value) : 
llvm::Optional<T*>()52.6k
);
27
230k
}
llvm::Optional<clang::ConceptDecl const*> clang::serialization::makeOptionalFromPointer<clang::ConceptDecl const>(clang::ConceptDecl const*)
Line
Count
Source
25
392
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
26
392
  return (value ? 
llvm::Optional<T*>(value)0
: llvm::Optional<T*>());
27
392
}
llvm::Optional<clang::IdentifierInfo const*> clang::serialization::makeOptionalFromPointer<clang::IdentifierInfo const>(clang::IdentifierInfo const*)
Line
Count
Source
25
52
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
26
52
  return (value ? llvm::Optional<T*>(value) : 
llvm::Optional<T*>()0
);
27
52
}
llvm::Optional<clang::TagDecl const*> clang::serialization::makeOptionalFromPointer<clang::TagDecl const>(clang::TagDecl const*)
Line
Count
Source
25
82.4k
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
26
50.3k
  return (value ? 
llvm::Optional<T*>(value)32.1k
: llvm::Optional<T*>());
27
82.4k
}
llvm::Optional<clang::TemplateTypeParmDecl const*> clang::serialization::makeOptionalFromPointer<clang::TemplateTypeParmDecl const>(clang::TemplateTypeParmDecl const*)
Line
Count
Source
25
147k
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
26
145k
  return (value ? llvm::Optional<T*>(value) : 
llvm::Optional<T*>()1.94k
);
27
147k
}
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
17.8M
  Impl &find(const char *propertyName) {
129
17.8M
    return asImpl();
130
17.8M
  }
131
132
  // Implement object writing by forwarding to this, collapsing the
133
  // structure into a single data stream.
134
4.62M
  Impl &writeObject() { return asImpl(); }
135
136
  template <class T>
137
5.61M
  void writeEnum(T value) {
138
5.61M
    asImpl().writeUInt32(uint32_t(value));
139
5.61M
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::ArrayType::ArraySizeModifier>(clang::ArrayType::ArraySizeModifier)
Line
Count
Source
137
16.8k
  void writeEnum(T value) {
138
16.8k
    asImpl().writeUInt32(uint32_t(value));
139
16.8k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::attr::Kind>(clang::attr::Kind)
Line
Count
Source
137
18.5k
  void writeEnum(T value) {
138
18.5k
    asImpl().writeUInt32(uint32_t(value));
139
18.5k
  }
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
137
392
  void writeEnum(T value) {
138
392
    asImpl().writeUInt32(uint32_t(value));
139
392
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::TemplateArgument::ArgKind>(clang::TemplateArgument::ArgKind)
Line
Count
Source
137
774k
  void writeEnum(T value) {
138
774k
    asImpl().writeUInt32(uint32_t(value));
139
774k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::TemplateName::NameKind>(clang::TemplateName::NameKind)
Line
Count
Source
137
363k
  void writeEnum(T value) {
138
363k
    asImpl().writeUInt32(uint32_t(value));
139
363k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::DeclarationName::NameKind>(clang::DeclarationName::NameKind)
Line
Count
Source
137
3.48M
  void writeEnum(T value) {
138
3.48M
    asImpl().writeUInt32(uint32_t(value));
139
3.48M
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::NestedNameSpecifier::SpecifierKind>(clang::NestedNameSpecifier::SpecifierKind)
Line
Count
Source
137
104k
  void writeEnum(T value) {
138
104k
    asImpl().writeUInt32(uint32_t(value));
139
104k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OverloadedOperatorKind>(clang::OverloadedOperatorKind)
Line
Count
Source
137
124k
  void writeEnum(T value) {
138
124k
    asImpl().writeUInt32(uint32_t(value));
139
124k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::ElaboratedTypeKeyword>(clang::ElaboratedTypeKeyword)
Line
Count
Source
137
146k
  void writeEnum(T value) {
138
146k
    asImpl().writeUInt32(uint32_t(value));
139
146k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::VectorType::VectorKind>(clang::VectorType::VectorKind)
Line
Count
Source
137
1.95k
  void writeEnum(T value) {
138
1.95k
    asImpl().writeUInt32(uint32_t(value));
139
1.95k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::CallingConv>(clang::CallingConv)
Line
Count
Source
137
288k
  void writeEnum(T value) {
138
288k
    asImpl().writeUInt32(uint32_t(value));
139
288k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::RefQualifierKind>(clang::RefQualifierKind)
Line
Count
Source
137
288k
  void writeEnum(T value) {
138
288k
    asImpl().writeUInt32(uint32_t(value));
139
288k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::UnaryTransformType::UTTKind>(clang::UnaryTransformType::UTTKind)
Line
Count
Source
137
67
  void writeEnum(T value) {
138
67
    asImpl().writeUInt32(uint32_t(value));
139
67
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPLastprivateModifier>(clang::OpenMPLastprivateModifier)
Line
Count
Source
137
442
  void writeEnum(T value) {
138
442
    asImpl().writeUInt32(uint32_t(value));
139
442
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPReductionClauseModifier>(clang::OpenMPReductionClauseModifier)
Line
Count
Source
137
895
  void writeEnum(T value) {
138
895
    asImpl().writeUInt32(uint32_t(value));
139
895
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPDependClauseKind>(clang::OpenMPDependClauseKind)
Line
Count
Source
137
8
  void writeEnum(T value) {
138
8
    asImpl().writeUInt32(uint32_t(value));
139
8
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPDeviceClauseModifier>(clang::OpenMPDeviceClauseModifier)
Line
Count
Source
137
333
  void writeEnum(T value) {
138
333
    asImpl().writeUInt32(uint32_t(value));
139
333
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<clang::OpenMPOrderClauseKind>(clang::OpenMPOrderClauseKind)
Line
Count
Source
137
43
  void writeEnum(T value) {
138
43
    asImpl().writeUInt32(uint32_t(value));
139
43
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<llvm::omp::TraitSet>(llvm::omp::TraitSet)
Line
Count
Source
137
635
  void writeEnum(T value) {
138
635
    asImpl().writeUInt32(uint32_t(value));
139
635
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<llvm::omp::TraitSelector>(llvm::omp::TraitSelector)
Line
Count
Source
137
635
  void writeEnum(T value) {
138
635
    asImpl().writeUInt32(uint32_t(value));
139
635
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<llvm::omp::TraitProperty>(llvm::omp::TraitProperty)
Line
Count
Source
137
1.03k
  void writeEnum(T value) {
138
1.03k
    asImpl().writeUInt32(uint32_t(value));
139
1.03k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeEnum<llvm::omp::Directive>(llvm::omp::Directive)
Line
Count
Source
137
232
  void writeEnum(T value) {
138
232
    asImpl().writeUInt32(uint32_t(value));
139
232
  }
140
141
  template <class T>
142
961k
  void writeArray(llvm::ArrayRef<T> array) {
143
961k
    asImpl().writeUInt32(array.size());
144
1.20M
    for (const T &elt : array) {
145
1.20M
      WriteDispatcher<T>::write(asImpl(), elt);
146
1.20M
    }
147
961k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::TemplateArgument>(llvm::ArrayRef<clang::TemplateArgument>)
Line
Count
Source
142
377k
  void writeArray(llvm::ArrayRef<T> array) {
143
377k
    asImpl().writeUInt32(array.size());
144
621k
    for (const T &elt : array) {
145
621k
      WriteDispatcher<T>::write(asImpl(), elt);
146
621k
    }
147
377k
  }
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
142
291k
  void writeArray(llvm::ArrayRef<T> array) {
143
291k
    asImpl().writeUInt32(array.size());
144
577k
    for (const T &elt : array) {
145
577k
      WriteDispatcher<T>::write(asImpl(), elt);
146
577k
    }
147
291k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::FunctionType::ExtParameterInfo>(llvm::ArrayRef<clang::FunctionType::ExtParameterInfo>)
Line
Count
Source
142
288k
  void writeArray(llvm::ArrayRef<T> array) {
143
288k
    asImpl().writeUInt32(array.size());
144
847
    for (const T &elt : array) {
145
847
      WriteDispatcher<T>::write(asImpl(), elt);
146
847
    }
147
288k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeArray<clang::ObjCProtocolDecl const*>(llvm::ArrayRef<clang::ObjCProtocolDecl const*>)
Line
Count
Source
142
4.09k
  void writeArray(llvm::ArrayRef<T> array) {
143
4.09k
    asImpl().writeUInt32(array.size());
144
1.02k
    for (const T &elt : array) {
145
1.02k
      WriteDispatcher<T>::write(asImpl(), elt);
146
1.02k
    }
147
4.09k
  }
148
149
  template <class T>
150
799k
  void writeOptional(llvm::Optional<T> value) {
151
799k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152
799k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::QualType>(llvm::Optional<clang::QualType>)
Line
Count
Source
150
561k
  void writeOptional(llvm::Optional<T> value) {
151
561k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152
561k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::ConceptDecl const*>(llvm::Optional<clang::ConceptDecl const*>)
Line
Count
Source
150
392
  void writeOptional(llvm::Optional<T> value) {
151
392
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152
392
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::IdentifierInfo const*>(llvm::Optional<clang::IdentifierInfo const*>)
Line
Count
Source
150
52
  void writeOptional(llvm::Optional<T> value) {
151
52
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152
52
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<unsigned int>(llvm::Optional<unsigned int>)
Line
Count
Source
150
8.45k
  void writeOptional(llvm::Optional<T> value) {
151
8.45k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152
8.45k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::TemplateName>(llvm::Optional<clang::TemplateName>)
Line
Count
Source
150
12
  void writeOptional(llvm::Optional<T> value) {
151
12
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152
12
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::TagDecl const*>(llvm::Optional<clang::TagDecl const*>)
Line
Count
Source
150
82.4k
  void writeOptional(llvm::Optional<T> value) {
151
82.4k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152
82.4k
  }
void clang::serialization::DataStreamBasicWriter<clang::ASTRecordWriter>::writeOptional<clang::TemplateTypeParmDecl const*>(llvm::Optional<clang::TemplateTypeParmDecl const*>)
Line
Count
Source
150
147k
  void writeOptional(llvm::Optional<T> value) {
151
147k
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
152
147k
  }
153
154
207k
  void writeAPSInt(const llvm::APSInt &value) {
155
207k
    asImpl().writeBool(value.isUnsigned());
156
207k
    asImpl().writeAPInt(value);
157
207k
  }
158
159
643k
  void writeAPInt(const llvm::APInt &value) {
160
643k
    asImpl().writeUInt32(value.getBitWidth());
161
643k
    const uint64_t *words = value.getRawData();
162
1.28M
    for (size_t i = 0, e = value.getNumWords(); i != e; 
++i643k
)
163
643k
      asImpl().writeUInt64(words[i]);
164
643k
  }
165
166
312k
  void writeQualifiers(Qualifiers value) {
167
312k
    static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t),
168
312k
                  "update this if the value size changes");
169
312k
    asImpl().writeUInt32(value.getAsOpaqueValue());
170
312k
  }
171
172
  void writeExceptionSpecInfo(
173
288k
                        const FunctionProtoType::ExceptionSpecInfo &esi) {
174
288k
    asImpl().writeUInt32(uint32_t(esi.Type));
175
288k
    if (esi.Type == EST_Dynamic) {
176
3
      asImpl().writeArray(esi.Exceptions);
177
288k
    } else if (isComputedNoexcept(esi.Type)) {
178
8.26k
      asImpl().writeExprRef(esi.NoexceptExpr);
179
280k
    } else if (esi.Type == EST_Uninstantiated) {
180
2.31k
      asImpl().writeDeclRef(esi.SourceDecl);
181
2.31k
      asImpl().writeDeclRef(esi.SourceTemplate);
182
277k
    } else if (esi.Type == EST_Unevaluated) {
183
15.1k
      asImpl().writeDeclRef(esi.SourceDecl);
184
15.1k
    }
185
288k
  }
186
187
847
  void writeExtParameterInfo(FunctionProtoType::ExtParameterInfo epi) {
188
847
    static_assert(sizeof(epi.getOpaqueValue()) <= sizeof(uint32_t),
189
847
                  "opaque value doesn't fit into uint32_t");
190
847
    asImpl().writeUInt32(epi.getOpaqueValue());
191
847
  }
192
193
146k
  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
146k
    SmallVector<NestedNameSpecifier *, 8> nestedNames;
197
146k
198
    // Push each of the NNS's onto a stack for serialization in reverse order.
199
250k
    while (NNS) {
200
104k
      nestedNames.push_back(NNS);
201
104k
      NNS = NNS->getPrefix();
202
104k
    }
203
146k
204
146k
    asImpl().writeUInt32(nestedNames.size());
205
250k
    while (!nestedNames.empty()) {
206
104k
      NNS = nestedNames.pop_back_val();
207
104k
      NestedNameSpecifier::SpecifierKind kind = NNS->getKind();
208
104k
      asImpl().writeNestedNameSpecifierKind(kind);
209
104k
      switch (kind) {
210
591
      case NestedNameSpecifier::Identifier:
211
591
        asImpl().writeIdentifier(NNS->getAsIdentifier());
212
591
        continue;
213
0
214
7.24k
      case NestedNameSpecifier::Namespace:
215
7.24k
        asImpl().writeNamespaceDeclRef(NNS->getAsNamespace());
216
7.24k
        continue;
217
0
218
4
      case NestedNameSpecifier::NamespaceAlias:
219
4
        asImpl().writeNamespaceAliasDeclRef(NNS->getAsNamespaceAlias());
220
4
        continue;
221
0
222
96.6k
      case NestedNameSpecifier::TypeSpec:
223
96.6k
      case NestedNameSpecifier::TypeSpecWithTemplate:
224
96.6k
        asImpl().writeQualType(QualType(NNS->getAsType(), 0));
225
96.6k
        continue;
226
96.6k
227
17
      case NestedNameSpecifier::Global:
228
        // Don't need to write an associated value.
229
17
        continue;
230
96.6k
231
0
      case NestedNameSpecifier::Super:
232
0
        asImpl().writeDeclRef(NNS->getAsRecordDecl());
233
0
        continue;
234
0
      }
235
0
      llvm_unreachable("bad nested name specifier kind");
236
0
    }
237
146k
  }
238
};
239
240
} // end namespace serialization
241
} // end namespace clang
242
243
#endif