1//==--- TypeProperties.td - Type property definitions ---------------------===//
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
9include "clang/AST/PropertiesBase.td"
10include "clang/Basic/TypeNodes.td"
11
12let Class = ComplexType in {
13  def : Property<"elementType", QualType> {
14    let Read = [{ node->getElementType() }];
15  }
16
17  def : Creator<[{ return ctx.getComplexType(elementType); }]>;
18}
19
20let Class = PointerType in {
21  def : Property<"pointeeType", QualType> {
22    let Read = [{ node->getPointeeType() }];
23  }
24
25  def : Creator<[{ return ctx.getPointerType(pointeeType); }]>;
26}
27
28let Class = AdjustedType in {
29  def : Property<"originalType", QualType> {
30    let Read = [{ node->getOriginalType() }];
31  }
32  def : Property<"adjustedType", QualType> {
33    let Read = [{ node->getAdjustedType() }];
34  }
35
36  def : Creator<[{ return ctx.getAdjustedType(originalType, adjustedType); }]>;
37}
38
39let Class = DecayedType in {
40  def : Override {
41    // We don't need to serialize the adjusted type because we can always
42    // derive it by decaying the original type.
43    let IgnoredProperties = [ "adjustedType" ];
44  }
45
46  def : Creator<[{ return ctx.getAdjustedParameterType(originalType); }]>;
47}
48
49let Class = BlockPointerType in {
50  def : Property<"pointeeType", QualType> {
51    let Read = [{ node->getPointeeType() }];
52  }
53
54  def : Creator<[{ return ctx.getBlockPointerType(pointeeType); }]>;
55}
56
57let Class = ReferenceType in {
58  def : Property<"pointeeTypeAsWritten", QualType> {
59    let Read = [{ node->getPointeeTypeAsWritten() }];
60  }
61}
62
63let Class = LValueReferenceType in {
64  def : Property<"isSpelledAsLValue", Bool> {
65    let Read = [{ node->isSpelledAsLValue() }];
66  }
67
68  def : Creator<[{
69    return ctx.getLValueReferenceType(pointeeTypeAsWritten,
70                                      isSpelledAsLValue);
71  }]>;
72}
73
74let Class = RValueReferenceType in {
75  def : Creator<[{
76    return ctx.getRValueReferenceType(pointeeTypeAsWritten);
77  }]>;
78}
79
80let Class = MemberPointerType in {
81  def : Property<"pointeeType", QualType> {
82    let Read = [{ node->getPointeeType() }];
83  }
84  def : Property<"baseType", QualType> {
85    let Read = [{ QualType(node->getClass(), 0) }];
86  }
87
88  def : Creator<[{
89    return ctx.getMemberPointerType(pointeeType, baseType.getTypePtr());
90  }]>;
91}
92
93let Class = ArrayType in {
94  def : Property<"elementType", QualType> {
95    let Read = [{ node->getElementType() }];
96  }
97  def : Property<"sizeModifier", ArraySizeModifier> {
98    let Read = [{ node->getSizeModifier() }];
99  }
100  def : Property<"indexQualifiers", Qualifiers> {
101    let Read = [{ Qualifiers::fromCVRMask(node->getIndexTypeCVRQualifiers()) }];
102  }
103}
104
105let Class = ConstantArrayType in {
106  def : Property<"sizeValue", APInt> {
107    let Read = [{ node->getSize() }];
108  }
109  def : Property<"size", ExprRef> {
110    let Read = [{ node->getSizeExpr() }];
111  }
112
113  def : Creator<[{
114    return ctx.getConstantArrayType(elementType, sizeValue, size,
115                                    sizeModifier,
116                                    indexQualifiers.getCVRQualifiers());
117  }]>;
118}
119
120let Class = IncompleteArrayType in {
121  def : Creator<[{
122    return ctx.getIncompleteArrayType(elementType, sizeModifier,
123                                      indexQualifiers.getCVRQualifiers());
124  }]>;
125}
126
127let Class = VariableArrayType in {
128  def : Property<"leftBracketLoc", SourceLocation> {
129    let Read = [{ node->getLBracketLoc() }];
130  }
131  def : Property<"rightBracketLoc", SourceLocation> {
132    let Read = [{ node->getRBracketLoc() }];
133  }
134  def : Property<"size", ExprRef> {
135    let Read = [{ node->getSizeExpr() }];
136  }
137
138  def : Creator<[{
139    return ctx.getVariableArrayType(elementType, size, sizeModifier,
140                                    indexQualifiers.getCVRQualifiers(),
141                                    SourceRange(leftBracketLoc,
142                                                rightBracketLoc));
143  }]>;
144}
145
146let Class = DependentSizedArrayType in {
147  def : Property<"size", ExprRef> {
148    let Read = [{ node->getSizeExpr() }];
149  }
150  def : Property<"leftBracketLoc", SourceLocation> {
151    let Read = [{ node->getLBracketLoc() }];
152  }
153  def : Property<"rightBracketLoc", SourceLocation> {
154    let Read = [{ node->getRBracketLoc() }];
155  }
156
157  def : Creator<[{
158    return ctx.getDependentSizedArrayType(elementType, size, sizeModifier,
159                                          indexQualifiers.getCVRQualifiers(),
160                                          SourceRange(leftBracketLoc,
161                                                      rightBracketLoc));
162  }]>;
163}
164
165let Class = VectorType in {
166  def : Property<"elementType", QualType> {
167    let Read = [{ node->getElementType() }];
168  }
169  def : Property<"numElements", UInt32> {
170    let Read = [{ node->getNumElements() }];
171  }
172  def : Property<"vectorKind", VectorKind> {
173    let Read = [{ node->getVectorKind() }];
174  }
175
176  def : Creator<[{
177    return ctx.getVectorType(elementType, numElements, vectorKind);
178  }]>;
179}
180
181let Class = DependentVectorType in {
182  def : Property<"elementType", QualType> {
183    let Read = [{ node->getElementType() }];
184  }
185  def : Property<"size", ExprRef> {
186    let Read = [{ node->getSizeExpr() }];
187  }
188  def : Property<"attributeLoc", SourceLocation> {
189    let Read = [{ node->getAttributeLoc() }];
190  }
191  def : Property<"vectorKind", VectorKind> {
192    let Read = [{ node->getVectorKind() }];
193  }
194
195  def : Creator<[{
196    return ctx.getDependentVectorType(elementType, size, attributeLoc,
197                                      vectorKind);
198  }]>;
199}
200
201let Class = ExtVectorType in {
202  def : Override {
203    let IgnoredProperties = [ "vectorKind" ];
204  }
205
206  def : Creator<[{
207    return ctx.getExtVectorType(elementType, numElements);
208  }]>;
209}
210
211let Class = DependentSizedExtVectorType in {
212  def : Property<"elementType", QualType> {
213    let Read = [{ node->getElementType() }];
214  }
215  def : Property<"size", ExprRef> {
216    let Read = [{ node->getSizeExpr() }];
217  }
218  def : Property<"attributeLoc", SourceLocation> {
219    let Read = [{ node->getAttributeLoc() }];
220  }
221
222  def : Creator<[{
223    return ctx.getDependentSizedExtVectorType(elementType, size, attributeLoc);
224  }]>;
225}
226
227let Class = MatrixType in {
228  def : Property<"elementType", QualType> {
229    let Read = [{ node->getElementType() }];
230  }
231}
232
233let Class = ConstantMatrixType in {
234  def : Property<"numRows", UInt32> {
235    let Read = [{ node->getNumRows() }];
236  }
237  def : Property<"numColumns", UInt32> {
238    let Read = [{ node->getNumColumns() }];
239  }
240
241  def : Creator<[{
242    return ctx.getConstantMatrixType(elementType, numRows, numColumns);
243  }]>;
244}
245
246let Class = DependentSizedMatrixType in {
247  def : Property<"rows", ExprRef> {
248    let Read = [{ node->getRowExpr() }];
249  }
250  def : Property<"columns", ExprRef> {
251    let Read = [{ node->getColumnExpr() }];
252  }
253  def : Property<"attributeLoc", SourceLocation> {
254    let Read = [{ node->getAttributeLoc() }];
255  }
256
257  def : Creator<[{
258    return ctx.getDependentSizedMatrixType(elementType, rows, columns, attributeLoc);
259  }]>;
260}
261
262let Class = FunctionType in {
263  def : Property<"returnType", QualType> {
264    let Read = [{ node->getReturnType() }];
265  }
266  def : Property<"noReturn", Bool> {
267    let Read = [{ node->getExtInfo().getNoReturn() }];
268  }
269  def : Property<"hasRegParm", Bool> {
270    let Read = [{ node->getExtInfo().getHasRegParm() }];
271  }
272  def : Property<"regParm", UInt32> {
273    let Read = [{ node->getExtInfo().getRegParm() }];
274  }
275  def : Property<"callingConvention", CallingConv> {
276    let Read = [{ node->getExtInfo().getCC() }];
277  }
278  def : Property<"producesResult", Bool> {
279    let Read = [{ node->getExtInfo().getProducesResult() }];
280  }
281  def : Property<"noCallerSavedRegs", Bool> {
282    let Read = [{ node->getExtInfo().getNoCallerSavedRegs() }];
283  }
284  def : Property<"noCfCheck", Bool> {
285    let Read = [{ node->getExtInfo().getNoCfCheck() }];
286  }
287  def : Property<"cmseNSCall", Bool> {
288    let Read = [{ node->getExtInfo().getCmseNSCall() }];
289  }
290}
291
292let Class = FunctionNoProtoType in {
293  def : Creator<[{
294    auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
295                                         callingConvention, producesResult,
296                                         noCallerSavedRegs, noCfCheck,
297                                         cmseNSCall);
298    return ctx.getFunctionNoProtoType(returnType, extInfo);
299  }]>;
300}
301
302let Class = FunctionProtoType in {
303  def : Property<"variadic", Bool> {
304    let Read = [{ node->isVariadic() }];
305  }
306  def : Property<"trailingReturn", Bool> {
307    let Read = [{ node->hasTrailingReturn() }];
308  }
309  def : Property<"methodQualifiers", Qualifiers> {
310    let Read = [{ node->getMethodQuals() }];
311  }
312  def : Property<"refQualifier", RefQualifierKind> {
313    let Read = [{ node->getRefQualifier() }];
314  }
315  def : Property<"exceptionSpecifier", ExceptionSpecInfo> {
316    let Read = [{ node->getExceptionSpecInfo() }];
317  }
318  def : Property<"parameters", Array<QualType>> {
319    let Read = [{ node->getParamTypes() }];
320  }
321  def : Property<"extParameterInfo", Array<ExtParameterInfo>> {
322    let Read = [{ node->hasExtParameterInfos()
323                    ? node->getExtParameterInfos()
324                    : llvm::ArrayRef<FunctionProtoType::ExtParameterInfo>() }];
325  }
326
327  def : Creator<[{
328    auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
329                                         callingConvention, producesResult,
330                                         noCallerSavedRegs, noCfCheck,
331                                         cmseNSCall);
332    FunctionProtoType::ExtProtoInfo epi;
333    epi.ExtInfo = extInfo;
334    epi.Variadic = variadic;
335    epi.HasTrailingReturn = trailingReturn;
336    epi.TypeQuals = methodQualifiers;
337    epi.RefQualifier = refQualifier;
338    epi.ExceptionSpec = exceptionSpecifier;
339    epi.ExtParameterInfos =
340      extParameterInfo.empty() ? nullptr : extParameterInfo.data();
341    return ctx.getFunctionType(returnType, parameters, epi);
342  }]>;
343}
344
345let Class = AtomicType in {
346  def : Property<"valueType", QualType> {
347    let Read = [{ node->getValueType() }];
348  }
349
350  def : Creator<[{
351    return ctx.getAtomicType(valueType);
352  }]>;
353}
354
355let Class = UnresolvedUsingType in {
356  def : Property<"declaration", DeclRef> {
357    let Read = [{ node->getDecl() }];
358  }
359
360  def : Creator<[{
361    return ctx.getTypeDeclType(cast<UnresolvedUsingTypenameDecl>(declaration));
362  }]>;
363}
364
365let Class = TypedefType in {
366  def : Property<"declaration", DeclRef> {
367    let Read = [{ node->getDecl() }];
368  }
369  def : Property<"canonicalType", Optional<QualType>> {
370    let Read = [{ makeOptionalFromNullable(node->getCanonicalTypeInternal()) }];
371  }
372
373  def : Creator<[{
374    QualType finalCanonicalType =
375      canonicalType ? ctx.getCanonicalType(*canonicalType)
376                    : QualType();
377    return ctx.getTypedefType(cast<TypedefNameDecl>(declaration),
378                              finalCanonicalType);
379  }]>;
380}
381
382let Class = TypeOfExprType in {
383  def : Property<"expression", ExprRef> {
384    let Read = [{ node->getUnderlyingExpr() }];
385  }
386
387  def : Creator<[{
388    return ctx.getTypeOfExprType(expression);
389  }]>;
390}
391
392let Class = TypeOfType in {
393  def : Property<"underlyingType", QualType> {
394    let Read = [{ node->getUnderlyingType() }];
395  }
396
397  def : Creator<[{
398    return ctx.getTypeOfType(underlyingType);
399  }]>;
400}
401
402let Class = DecltypeType in {
403  def : Property<"underlyingType", QualType> {
404    let Read = [{ node->getUnderlyingType() }];
405  }
406  def : Property<"expression", ExprRef> {
407    let Read = [{ node->getUnderlyingExpr() }];
408  }
409
410  def : Creator<[{
411    return ctx.getDecltypeType(expression, underlyingType);
412  }]>;
413}
414
415let Class = UnaryTransformType in {
416  def : Property<"baseType", QualType> {
417    let Read = [{ node->getBaseType() }];
418  }
419  def : Property<"underlyingType", QualType> {
420    let Read = [{ node->getUnderlyingType() }];
421  }
422  def : Property<"transform", UnaryTypeTransformKind> {
423    let Read = [{ node->getUTTKind() }];
424  }
425
426  def : Creator<[{
427    return ctx.getUnaryTransformType(baseType, underlyingType, transform);
428  }]>;
429}
430
431let Class = AutoType in {
432  def : Property<"deducedType", Optional<QualType>> {
433    let Read = [{ makeOptionalFromNullable(node->getDeducedType()) }];
434  }
435  def : Property<"keyword", AutoTypeKeyword> {
436    let Read = [{ node->getKeyword() }];
437  }
438  def : Property<"typeConstraintConcept", Optional<ConceptDeclRef>> {
439    let Read = [{ makeOptionalFromPointer(
440        const_cast<const ConceptDecl*>(node->getTypeConstraintConcept())) }];
441  }
442  def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
443    let Read = [{ node->getTypeConstraintArguments() }];
444  }
445  // FIXME: better enumerated value
446  // Only really required when the deduced type is null
447  def : Property<"dependence", UInt32> {
448    let Read = [{ !node->getDeducedType().isNull() ? 0 :
449                  node->containsUnexpandedParameterPack() ? 2 :
450                  node->isDependentType() ? 1 : 0 }];
451  }
452
453  def : Creator<[{
454    return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword,
455                           /*isDependentWithoutDeducedType*/ dependence > 0,
456                           /*isPackWithoutDeducedType*/ dependence > 1,
457                           makePointerFromOptional(typeConstraintConcept),
458                           typeConstraintArguments);
459  }]>;
460}
461
462let Class = DeducedTemplateSpecializationType in {
463  def : Property<"templateName", Optional<TemplateName>> {
464    let Read = [{ makeOptionalFromNullable(node->getTemplateName()) }];
465  }
466  def : Property<"deducedType", QualType> {
467    let Read = [{ node->getDeducedType() }];
468  }
469  // Only really required when the deduced type is null
470  def : Property<"dependent", Bool> {
471    let Read = [{ !node->getDeducedType().isNull()
472                    ? false : node->isDependentType() }];
473  }
474
475  def : Creator<[{
476    return ctx.getDeducedTemplateSpecializationType(
477                                     makeNullableFromOptional(templateName),
478                                     deducedType, dependent);
479  }]>;
480}
481
482let Class = TagType in {
483  def : Property<"dependent", Bool> {
484    let Read = [{ node->isDependentType() }];
485  }
486  def : Property<"declaration", DeclRef> {
487    // We don't know which declaration was originally referenced here, and we
488    // cannot reference a declaration that follows the use (because that can
489    // introduce deserialization cycles), so conservatively generate a
490    // reference to the first declaration.
491    // FIXME: If this is a reference to a class template specialization, that
492    // can still introduce a deserialization cycle.
493    let Read = [{ node->getDecl()->getCanonicalDecl() }];
494  }
495}
496
497let Class = EnumType in {
498  def : Creator<[{
499    QualType result = ctx.getEnumType(cast<EnumDecl>(declaration));
500    if (dependent)
501      const_cast<Type *>(result.getTypePtr())
502          ->addDependence(TypeDependence::DependentInstantiation);
503    return result;
504  }]>;
505}
506
507let Class = RecordType in {
508  def : Creator<[{
509    auto record = cast<RecordDecl>(declaration);
510    QualType result = ctx.getRecordType(record);
511    if (dependent)
512      const_cast<Type *>(result.getTypePtr())
513          ->addDependence(TypeDependence::DependentInstantiation);
514    return result;
515  }]>;
516}
517
518let Class = ElaboratedType in {
519  def : Property<"keyword", ElaboratedTypeKeyword> {
520    let Read = [{ node->getKeyword() }];
521  }
522  def : Property<"qualifier", NestedNameSpecifier> {
523    let Read = [{ node->getQualifier() }];
524  }
525  def : Property<"namedType", QualType> {
526    let Read = [{ node->getNamedType() }];
527  }
528  def : Property<"ownedTag", Optional<TagDeclRef>> {
529    let Read = [{ makeOptionalFromPointer(
530                    const_cast<const TagDecl *>(node->getOwnedTagDecl())) }];
531  }
532
533  def : Creator<[{
534    return ctx.getElaboratedType(keyword, qualifier, namedType,
535                                 makePointerFromOptional(ownedTag));
536  }]>;
537}
538
539let Class = InjectedClassNameType in {
540  def : Property<"declaration", DeclRef> {
541    // FIXME: drilling down to the canonical declaration is what the
542    // existing serialization code was doing, but it's not clear why.
543    let Read = [{ node->getDecl()->getCanonicalDecl() }];
544  }
545  def : Property<"injectedSpecializationType", QualType> {
546    let Read = [{ node->getInjectedSpecializationType() }];
547  }
548
549  def : Creator<[{
550    // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
551    // for AST reading, too much interdependencies.
552    const Type *T = nullptr;
553    auto typeDecl = cast<CXXRecordDecl>(declaration);
554    for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl()) {
555      if (const Type *existing = DI->getTypeForDecl()) {
556        T = existing;
557        break;
558      }
559    }
560    if (!T) {
561      T = new (ctx, TypeAlignment)
562            InjectedClassNameType(typeDecl, injectedSpecializationType);
563      for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl())
564        DI->setTypeForDecl(T);
565    }
566    return QualType(T, 0);
567  }]>;
568}
569
570let Class = ParenType in {
571  def : Property<"innerType", QualType> {
572    let Read = [{ node->getInnerType() }];
573  }
574
575  def : Creator<[{
576    return ctx.getParenType(innerType);
577  }]>;
578}
579
580let Class = MacroQualifiedType in {
581  def : Property<"underlyingType", QualType> {
582    let Read = [{ node->getUnderlyingType() }];
583  }
584  def : Property<"macroIdentifier", Identifier> {
585    let Read = [{ node->getMacroIdentifier() }];
586  }
587
588  def : Creator<[{
589    return ctx.getMacroQualifiedType(underlyingType, macroIdentifier);
590  }]>;
591}
592
593let Class = AttributedType in {
594  def : Property<"modifiedType", QualType> {
595    let Read = [{ node->getModifiedType() }];
596  }
597  def : Property<"equivalentType", QualType> {
598    let Read = [{ node->getEquivalentType() }];
599  }
600  def : Property<"attribute", AttrKind> {
601    let Read = [{ node->getAttrKind() }];
602  }
603
604  def : Creator<[{
605    return ctx.getAttributedType(attribute, modifiedType, equivalentType);
606  }]>;
607}
608
609let Class = DependentAddressSpaceType in {
610  def : Property<"pointeeType", QualType> {
611    let Read = [{ node->getPointeeType() }];
612  }
613  def : Property<"addressSpace", ExprRef> {
614    let Read = [{ node->getAddrSpaceExpr() }];
615  }
616  def : Property<"attributeLoc", SourceLocation> {
617    let Read = [{ node->getAttributeLoc() }];
618  }
619
620  def : Creator<[{
621    return ctx.getDependentAddressSpaceType(pointeeType, addressSpace,
622                                            attributeLoc);
623  }]>;
624}
625
626let Class = TemplateSpecializationType in {
627  def : Property<"dependent", Bool> {
628    let Read = [{ node->isDependentType() }];
629  }
630  def : Property<"templateName", TemplateName> {
631    let Read = [{ node->getTemplateName() }];
632  }
633  def : Property<"templateArguments", Array<TemplateArgument>> {
634    let Read = [{ node->template_arguments() }];
635  }
636  def : Property<"underlyingType", Optional<QualType>> {
637    let Read = [{
638      node->isTypeAlias()
639        ? llvm::Optional<QualType>(node->getAliasedType())
640        : node->isCanonicalUnqualified()
641            ? llvm::None
642            : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
643    }];
644  }
645
646  def : Creator<[{
647    QualType result;
648    if (!underlyingType.hasValue()) {
649      result = ctx.getCanonicalTemplateSpecializationType(templateName,
650                                                          templateArguments);
651    } else {
652      result = ctx.getTemplateSpecializationType(templateName,
653                                                 templateArguments,
654                                                 *underlyingType);
655    }
656    if (dependent)
657      const_cast<Type *>(result.getTypePtr())
658          ->addDependence(TypeDependence::DependentInstantiation);
659    return result;
660  }]>;
661}
662
663let Class = DependentTemplateSpecializationType in {
664  def : Property<"keyword", ElaboratedTypeKeyword> {
665    let Read = [{ node->getKeyword() }];
666  }
667  def : Property<"qualifier", NestedNameSpecifier> {
668    let Read = [{ node->getQualifier() }];
669  }
670  def : Property<"name", Identifier> {
671    let Read = [{ node->getIdentifier() }];
672  }
673  def : Property<"templateArguments", Array<TemplateArgument>> {
674    let Read = [{ node->template_arguments() }];
675  }
676
677  def : Creator<[{
678    return ctx.getDependentTemplateSpecializationType(keyword, qualifier,
679                                                      name, templateArguments);
680  }]>;
681}
682
683let Class = TemplateTypeParmType in {
684  def : Property<"depth", UInt32> {
685    let Read = [{ node->getDepth() }];
686  }
687  def : Property<"index", UInt32> {
688    let Read = [{ node->getIndex() }];
689  }
690  def : Property<"isParameterPack", Bool> {
691    let Read = [{ node->isParameterPack() }];
692  }
693  def : Property<"declaration", Optional<TemplateTypeParmDeclRef>> {
694    let Read = [{ makeOptionalFromPointer(
695                    const_cast<const TemplateTypeParmDecl*>(node->getDecl())) }];
696  }
697
698  def : Creator<[{
699    return ctx.getTemplateTypeParmType(depth, index, isParameterPack,
700                                       makePointerFromOptional(declaration));
701  }]>;
702}
703
704let Class = SubstTemplateTypeParmType in {
705  def : Property<"replacedParameter", QualType> {
706    let Read = [{ QualType(node->getReplacedParameter(), 0) }];
707  }
708  def : Property<"replacementType", QualType> {
709    let Read = [{ node->getReplacementType() }];
710  }
711
712  def : Creator<[{
713    // The call to getCanonicalType here existed in ASTReader.cpp, too.
714    return ctx.getSubstTemplateTypeParmType(
715        cast<TemplateTypeParmType>(replacedParameter),
716        ctx.getCanonicalType(replacementType));
717  }]>;
718}
719
720let Class = PackExpansionType in {
721  def : Property<"pattern", QualType> {
722    let Read = [{ node->getPattern() }];
723  }
724  def : Property<"numExpansions", Optional<UInt32>> {
725    let Read = [{ node->getNumExpansions() }];
726  }
727
728  def : Creator<[{
729    return ctx.getPackExpansionType(pattern, numExpansions,
730                                    /*ExpectPackInType*/false);
731  }]>;
732}
733
734let Class = SubstTemplateTypeParmPackType in {
735  def : Property<"replacedParameter", QualType> {
736    let Read = [{ QualType(node->getReplacedParameter(), 0) }];
737  }
738  def : Property<"replacementPack", TemplateArgument> {
739    let Read = [{ node->getArgumentPack() }];
740  }
741
742  def : Creator<[{
743    return ctx.getSubstTemplateTypeParmPackType(
744                         cast<TemplateTypeParmType>(replacedParameter),
745                        replacementPack);
746  }]>;
747}
748
749let Class = BuiltinType in {
750  def : Property<"kind", BuiltinTypeKind> {
751    let Read = [{ node->getKind() }];
752  }
753
754  def : Creator<[{
755      switch (kind) {
756#define IMAGE_TYPE(IMGTYPE, ID, SINGLETON_ID, ACCESS, SUFFIX) \
757      case BuiltinType::ID: return ctx.SINGLETON_ID;
758#include "clang/Basic/OpenCLImageTypes.def"
759
760#define EXT_OPAQUE_TYPE(EXTTYPE, ID, EXT) \
761      case BuiltinType::ID: return ctx.ID##Ty;
762#include "clang/Basic/OpenCLExtensionTypes.def"
763
764#define SVE_TYPE(NAME, ID, SINGLETON_ID) \
765      case BuiltinType::ID: return ctx.SINGLETON_ID;
766#include "clang/Basic/AArch64SVEACLETypes.def"
767
768#define PPC_VECTOR_TYPE(NAME, ID, SIZE) \
769      case BuiltinType::ID: return ctx.ID##Ty;
770#include "clang/Basic/PPCTypes.def"
771
772#define RVV_TYPE(NAME, ID, SINGLETON_ID) \
773      case BuiltinType::ID: return ctx.SINGLETON_ID;
774#include "clang/Basic/RISCVVTypes.def"
775
776#define BUILTIN_TYPE(ID, SINGLETON_ID) \
777      case BuiltinType::ID: return ctx.SINGLETON_ID;
778#include "clang/AST/BuiltinTypes.def"
779      }
780      llvm_unreachable("unreachable builtin case");
781  }]>;
782}
783
784let Class = DependentNameType in {
785  def : Property<"keyword", ElaboratedTypeKeyword> {
786    let Read = [{ node->getKeyword() }];
787  }
788  def : Property<"qualifier", NestedNameSpecifier> {
789    let Read = [{ node->getQualifier() }];
790  }
791  def : Property<"name", Identifier> {
792    let Read = [{ node->getIdentifier() }];
793  }
794  def : Property<"underlyingType", Optional<QualType>> {
795    let Read = [{
796      node->isCanonicalUnqualified()
797        ? llvm::None
798        : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
799    }];
800  }
801
802  def : Creator<[{
803    QualType canon = (underlyingType
804                        ? ctx.getCanonicalType(*underlyingType)
805                        : QualType());
806    return ctx.getDependentNameType(keyword, qualifier, name, canon);
807  }]>;
808}
809
810let Class = ObjCObjectType in {
811  def : Property<"baseType", QualType> {
812    let Read = [{ node->getBaseType() }];
813  }
814  def : Property<"typeArgsAsWritten", Array<QualType>> {
815    let Read = [{ node->getTypeArgsAsWritten() }];
816  }
817  def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
818    let Read = [{ node->getProtocols() }];
819  }
820  def : Property<"isKindOfTypeAsWritten", Bool> {
821    let Read = [{ node->isKindOfTypeAsWritten() }];
822  }
823
824  def : Creator<[{
825    return ctx.getObjCObjectType(baseType, typeArgsAsWritten, qualifiers,
826                                 isKindOfTypeAsWritten);
827  }]>;
828}
829
830let Class = ObjCInterfaceType in {
831  // We don't actually want any of the properties of the superclass.
832  def : Override {
833    let IgnoredProperties = [ "baseType", "typeArgsAsWritten",
834                              "qualifiers", "isKindOfTypeAsWritten" ];
835  }
836
837  def : Property<"declaration", DeclRef> {
838    // FIXME: drilling down to the canonical declaration is what the
839    // existing serialization code was doing, but it's not clear why.
840    let Read = [{ node->getDecl()->getCanonicalDecl() }];
841  }
842
843  def : Creator<[{
844    return ctx.getObjCInterfaceType(
845             cast<ObjCInterfaceDecl>(declaration->getCanonicalDecl()));
846  }]>;
847}
848
849let Class = ObjCTypeParamType in {
850  def : Property<"declaration", ObjCTypeParamDeclRef> {
851    let Read = [{ node->getDecl() }];
852  }
853  def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
854    let Read = [{ node->getProtocols() }];
855  }
856
857  def : Creator<[{
858    return ctx.getObjCTypeParamType(declaration, qualifiers);
859  }]>;
860}
861
862let Class = ObjCObjectPointerType in {
863  def : Property<"pointeeType", QualType> {
864    let Read = [{ node->getPointeeType() }];
865  }
866
867  def : Creator<[{
868    return ctx.getObjCObjectPointerType(pointeeType);
869  }]>;
870}
871
872let Class = PipeType in {
873  def : Property<"elementType", QualType> {
874    let Read = [{ node->getElementType() }];
875  }
876  def : Property<"isReadOnly", Bool> {
877    let Read = [{ node->isReadOnly() }];
878  }
879
880  def : Creator<[{
881    return ctx.getPipeType(elementType, isReadOnly);
882  }]>;
883}
884
885let Class = ExtIntType in {
886  def : Property<"isUnsigned", Bool> {
887    let Read = [{ node->isUnsigned() }];
888  }
889  def : Property <"numBits", UInt32> {
890    let Read = [{ node->getNumBits() }];
891  }
892
893  def : Creator<[{
894    return ctx.getExtIntType(isUnsigned, numBits);
895  }]>;
896}
897
898let Class = DependentExtIntType in {
899  def : Property<"isUnsigned", Bool> {
900    let Read = [{ node->isUnsigned() }];
901  }
902  def : Property <"numBitsExpr", ExprRef> {
903    let Read = [{ node->getNumBitsExpr() }];
904  }
905  def : Creator<[{
906    return ctx.getDependentExtIntType(isUnsigned, numBitsExpr);
907  }]>;
908}
909