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.getUnresolvedUsingType(cast<UnresolvedUsingTypenameDecl>(declaration));
362  }]>;
363}
364
365let Class = UsingType in {
366  def : Property<"foundDeclaration", UsingShadowDeclRef> {
367    let Read = [{ node->getFoundDecl() }];
368  }
369  def : Property<"underlyingType", QualType> {
370    let Read = [{ node->getUnderlyingType() }];
371  }
372
373  def : Creator<[{
374    return ctx.getUsingType(foundDeclaration, underlyingType);
375  }]>;
376}
377
378let Class = TypedefType in {
379  def : Property<"declaration", DeclRef> {
380    let Read = [{ node->getDecl() }];
381  }
382  def : Property<"underlyingType", QualType> {
383    let Read = [{ node->desugar() }];
384  }
385
386  def : Creator<[{
387    return ctx.getTypedefType(cast<TypedefNameDecl>(declaration), underlyingType);
388  }]>;
389}
390
391let Class = TypeOfExprType in {
392  def : Property<"expression", ExprRef> {
393    let Read = [{ node->getUnderlyingExpr() }];
394  }
395
396  def : Property<"kind", TypeOfKind> {
397    let Read = [{ node->getKind() }];
398  }
399
400  def : Creator<[{
401    return ctx.getTypeOfExprType(expression, kind);
402  }]>;
403}
404
405let Class = TypeOfType in {
406  def : Property<"unmodifiedType", QualType> {
407    let Read = [{ node->getUnmodifiedType() }];
408  }
409
410  def : Property<"kind", TypeOfKind> {
411    let Read = [{ node->getKind() }];
412  }
413
414  def : Creator<[{
415    return ctx.getTypeOfType(unmodifiedType, kind);
416  }]>;
417}
418
419let Class = DecltypeType in {
420  def : Property<"underlyingType", QualType> {
421    let Read = [{ node->getUnderlyingType() }];
422  }
423  def : Property<"expression", ExprRef> {
424    let Read = [{ node->getUnderlyingExpr() }];
425  }
426
427  def : Creator<[{
428    return ctx.getDecltypeType(expression, underlyingType);
429  }]>;
430}
431
432let Class = UnaryTransformType in {
433  def : Property<"baseType", QualType> {
434    let Read = [{ node->getBaseType() }];
435  }
436  def : Property<"underlyingType", QualType> {
437    let Read = [{ node->getUnderlyingType() }];
438  }
439  def : Property<"transform", UnaryTypeTransformKind> {
440    let Read = [{ node->getUTTKind() }];
441  }
442
443  def : Creator<[{
444    return ctx.getUnaryTransformType(baseType, underlyingType, transform);
445  }]>;
446}
447
448let Class = AutoType in {
449  def : Property<"deducedType", Optional<QualType>> {
450    let Read = [{ makeOptionalFromNullable(node->getDeducedType()) }];
451  }
452  def : Property<"keyword", AutoTypeKeyword> {
453    let Read = [{ node->getKeyword() }];
454  }
455  def : Property<"typeConstraintConcept", Optional<ConceptDeclRef>> {
456    let Read = [{ makeOptionalFromPointer(
457        const_cast<const ConceptDecl*>(node->getTypeConstraintConcept())) }];
458  }
459  def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
460    let Read = [{ node->getTypeConstraintArguments() }];
461  }
462  // FIXME: better enumerated value
463  // Only really required when the deduced type is null
464  def : Property<"dependence", UInt32> {
465    let Read = [{ !node->getDeducedType().isNull() ? 0 :
466                  node->containsUnexpandedParameterPack() ? 2 :
467                  node->isDependentType() ? 1 : 0 }];
468  }
469
470  def : Creator<[{
471    return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword,
472                           /*isDependentWithoutDeducedType*/ dependence > 0,
473                           /*isPackWithoutDeducedType*/ dependence > 1,
474                           makePointerFromOptional(typeConstraintConcept),
475                           typeConstraintArguments);
476  }]>;
477}
478
479let Class = DeducedTemplateSpecializationType in {
480  def : Property<"templateName", Optional<TemplateName>> {
481    let Read = [{ makeOptionalFromNullable(node->getTemplateName()) }];
482  }
483  def : Property<"deducedType", QualType> {
484    let Read = [{ node->getDeducedType() }];
485  }
486  // Only really required when the deduced type is null
487  def : Property<"dependent", Bool> {
488    let Read = [{ !node->getDeducedType().isNull()
489                    ? false : node->isDependentType() }];
490  }
491
492  def : Creator<[{
493    return ctx.getDeducedTemplateSpecializationType(
494                                     makeNullableFromOptional(templateName),
495                                     deducedType, dependent);
496  }]>;
497}
498
499let Class = TagType in {
500  def : Property<"dependent", Bool> {
501    let Read = [{ node->isDependentType() }];
502  }
503  def : Property<"declaration", DeclRef> {
504    // We don't know which declaration was originally referenced here, and we
505    // cannot reference a declaration that follows the use (because that can
506    // introduce deserialization cycles), so conservatively generate a
507    // reference to the first declaration.
508    // FIXME: If this is a reference to a class template specialization, that
509    // can still introduce a deserialization cycle.
510    let Read = [{ node->getDecl()->getCanonicalDecl() }];
511  }
512}
513
514let Class = EnumType in {
515  def : Creator<[{
516    QualType result = ctx.getEnumType(cast<EnumDecl>(declaration));
517    if (dependent)
518      const_cast<Type *>(result.getTypePtr())
519          ->addDependence(TypeDependence::DependentInstantiation);
520    return result;
521  }]>;
522}
523
524let Class = RecordType in {
525  def : Creator<[{
526    auto record = cast<RecordDecl>(declaration);
527    QualType result = ctx.getRecordType(record);
528    if (dependent)
529      const_cast<Type *>(result.getTypePtr())
530          ->addDependence(TypeDependence::DependentInstantiation);
531    return result;
532  }]>;
533}
534
535let Class = ElaboratedType in {
536  def : Property<"keyword", ElaboratedTypeKeyword> {
537    let Read = [{ node->getKeyword() }];
538  }
539  def : Property<"qualifier", NestedNameSpecifier> {
540    let Read = [{ node->getQualifier() }];
541  }
542  def : Property<"namedType", QualType> {
543    let Read = [{ node->getNamedType() }];
544  }
545  def : Property<"ownedTag", Optional<TagDeclRef>> {
546    let Read = [{ makeOptionalFromPointer(
547                    const_cast<const TagDecl *>(node->getOwnedTagDecl())) }];
548  }
549
550  def : Creator<[{
551    return ctx.getElaboratedType(keyword, qualifier, namedType,
552                                 makePointerFromOptional(ownedTag));
553  }]>;
554}
555
556let Class = InjectedClassNameType in {
557  def : Property<"declaration", DeclRef> {
558    // FIXME: drilling down to the canonical declaration is what the
559    // existing serialization code was doing, but it's not clear why.
560    let Read = [{ node->getDecl()->getCanonicalDecl() }];
561  }
562  def : Property<"injectedSpecializationType", QualType> {
563    let Read = [{ node->getInjectedSpecializationType() }];
564  }
565
566  def : Creator<[{
567    // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
568    // for AST reading, too much interdependencies.
569    const Type *T = nullptr;
570    auto typeDecl = cast<CXXRecordDecl>(declaration);
571    for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl()) {
572      if (const Type *existing = DI->getTypeForDecl()) {
573        T = existing;
574        break;
575      }
576    }
577    if (!T) {
578      T = new (ctx, TypeAlignment)
579            InjectedClassNameType(typeDecl, injectedSpecializationType);
580      for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl())
581        DI->setTypeForDecl(T);
582    }
583    return QualType(T, 0);
584  }]>;
585}
586
587let Class = ParenType in {
588  def : Property<"innerType", QualType> {
589    let Read = [{ node->getInnerType() }];
590  }
591
592  def : Creator<[{
593    return ctx.getParenType(innerType);
594  }]>;
595}
596
597let Class = MacroQualifiedType in {
598  def : Property<"underlyingType", QualType> {
599    let Read = [{ node->getUnderlyingType() }];
600  }
601  def : Property<"macroIdentifier", Identifier> {
602    let Read = [{ node->getMacroIdentifier() }];
603  }
604
605  def : Creator<[{
606    return ctx.getMacroQualifiedType(underlyingType, macroIdentifier);
607  }]>;
608}
609
610let Class = AttributedType in {
611  def : Property<"modifiedType", QualType> {
612    let Read = [{ node->getModifiedType() }];
613  }
614  def : Property<"equivalentType", QualType> {
615    let Read = [{ node->getEquivalentType() }];
616  }
617  def : Property<"attribute", AttrKind> {
618    let Read = [{ node->getAttrKind() }];
619  }
620
621  def : Creator<[{
622    return ctx.getAttributedType(attribute, modifiedType, equivalentType);
623  }]>;
624}
625
626let Class = BTFTagAttributedType in {
627  def : Property<"attr", BTFTypeTagAttr> {
628    let Read = [{ node->getAttr() }];
629  }
630  def : Property<"wrappedType", QualType> {
631    let Read = [{ node->getWrappedType() }];
632  }
633
634  def : Creator<[{
635    return ctx.getBTFTagAttributedType(attr, wrappedType);
636  }]>;
637}
638
639let Class = DependentAddressSpaceType in {
640  def : Property<"pointeeType", QualType> {
641    let Read = [{ node->getPointeeType() }];
642  }
643  def : Property<"addressSpace", ExprRef> {
644    let Read = [{ node->getAddrSpaceExpr() }];
645  }
646  def : Property<"attributeLoc", SourceLocation> {
647    let Read = [{ node->getAttributeLoc() }];
648  }
649
650  def : Creator<[{
651    return ctx.getDependentAddressSpaceType(pointeeType, addressSpace,
652                                            attributeLoc);
653  }]>;
654}
655
656let Class = TemplateSpecializationType in {
657  def : Property<"dependent", Bool> {
658    let Read = [{ node->isDependentType() }];
659  }
660  def : Property<"templateName", TemplateName> {
661    let Read = [{ node->getTemplateName() }];
662  }
663  def : Property<"templateArguments", Array<TemplateArgument>> {
664    let Read = [{ node->template_arguments() }];
665  }
666  def : Property<"underlyingType", Optional<QualType>> {
667    let Read = [{
668      node->isTypeAlias()
669        ? std::optional<QualType>(node->getAliasedType())
670        : node->isCanonicalUnqualified()
671            ? std::nullopt
672            : std::optional<QualType>(node->getCanonicalTypeInternal())
673    }];
674  }
675
676  def : Creator<[{
677    QualType result;
678    if (!underlyingType) {
679      result = ctx.getCanonicalTemplateSpecializationType(templateName,
680                                                          templateArguments);
681    } else {
682      result = ctx.getTemplateSpecializationType(templateName,
683                                                 templateArguments,
684                                                 *underlyingType);
685    }
686    if (dependent)
687      const_cast<Type *>(result.getTypePtr())
688          ->addDependence(TypeDependence::DependentInstantiation);
689    return result;
690  }]>;
691}
692
693let Class = DependentTemplateSpecializationType in {
694  def : Property<"keyword", ElaboratedTypeKeyword> {
695    let Read = [{ node->getKeyword() }];
696  }
697  def : Property<"qualifier", NestedNameSpecifier> {
698    let Read = [{ node->getQualifier() }];
699  }
700  def : Property<"name", Identifier> {
701    let Read = [{ node->getIdentifier() }];
702  }
703  def : Property<"templateArguments", Array<TemplateArgument>> {
704    let Read = [{ node->template_arguments() }];
705  }
706
707  def : Creator<[{
708    return ctx.getDependentTemplateSpecializationType(keyword, qualifier,
709                                                      name, templateArguments);
710  }]>;
711}
712
713let Class = TemplateTypeParmType in {
714  def : Property<"depth", UInt32> {
715    let Read = [{ node->getDepth() }];
716  }
717  def : Property<"index", UInt32> {
718    let Read = [{ node->getIndex() }];
719  }
720  def : Property<"isParameterPack", Bool> {
721    let Read = [{ node->isParameterPack() }];
722  }
723  def : Property<"declaration", Optional<TemplateTypeParmDeclRef>> {
724    let Read = [{ makeOptionalFromPointer(
725                    const_cast<const TemplateTypeParmDecl*>(node->getDecl())) }];
726  }
727
728  def : Creator<[{
729    return ctx.getTemplateTypeParmType(depth, index, isParameterPack,
730                                       makePointerFromOptional(declaration));
731  }]>;
732}
733
734let Class = SubstTemplateTypeParmType in {
735  def : Property<"replacementType", QualType> {
736    let Read = [{ node->getReplacementType() }];
737  }
738  def : Property<"associatedDecl", DeclRef> {
739    let Read = [{ node->getAssociatedDecl() }];
740  }
741  def : Property<"Index", UInt32> {
742    let Read = [{ node->getIndex() }];
743  }
744  def : Property<"PackIndex", Optional<UInt32>> {
745    let Read = [{ node->getPackIndex() }];
746  }
747
748  // The call to getCanonicalType here existed in ASTReader.cpp, too.
749  def : Creator<[{
750    return ctx.getSubstTemplateTypeParmType(
751        replacementType, associatedDecl, Index, PackIndex);
752  }]>;
753}
754
755let Class = PackExpansionType in {
756  def : Property<"pattern", QualType> {
757    let Read = [{ node->getPattern() }];
758  }
759  def : Property<"numExpansions", Optional<UInt32>> {
760    let Read = [{ node->getNumExpansions() }];
761  }
762
763  def : Creator<[{
764    return ctx.getPackExpansionType(pattern, numExpansions,
765                                    /*ExpectPackInType*/false);
766  }]>;
767}
768
769let Class = SubstTemplateTypeParmPackType in {
770  def : Property<"associatedDecl", DeclRef> {
771    let Read = [{ node->getAssociatedDecl() }];
772  }
773  def : Property<"Index", UInt32> {
774    let Read = [{ node->getIndex() }];
775  }
776  def : Property<"Final", Bool> {
777    let Read = [{ node->getFinal() }];
778  }
779  def : Property<"replacementPack", TemplateArgument> {
780    let Read = [{ node->getArgumentPack() }];
781  }
782
783  def : Creator<[{
784    return ctx.getSubstTemplateTypeParmPackType(
785                        associatedDecl, Index, Final, replacementPack);
786  }]>;
787}
788
789let Class = BuiltinType in {
790  def : Property<"kind", BuiltinTypeKind> {
791    let Read = [{ node->getKind() }];
792  }
793
794  def : Creator<[{
795      switch (kind) {
796#define IMAGE_TYPE(IMGTYPE, ID, SINGLETON_ID, ACCESS, SUFFIX) \
797      case BuiltinType::ID: return ctx.SINGLETON_ID;
798#include "clang/Basic/OpenCLImageTypes.def"
799
800#define EXT_OPAQUE_TYPE(EXTTYPE, ID, EXT) \
801      case BuiltinType::ID: return ctx.ID##Ty;
802#include "clang/Basic/OpenCLExtensionTypes.def"
803
804#define SVE_TYPE(NAME, ID, SINGLETON_ID) \
805      case BuiltinType::ID: return ctx.SINGLETON_ID;
806#include "clang/Basic/AArch64SVEACLETypes.def"
807
808#define PPC_VECTOR_TYPE(NAME, ID, SIZE) \
809      case BuiltinType::ID: return ctx.ID##Ty;
810#include "clang/Basic/PPCTypes.def"
811
812#define RVV_TYPE(NAME, ID, SINGLETON_ID) \
813      case BuiltinType::ID: return ctx.SINGLETON_ID;
814#include "clang/Basic/RISCVVTypes.def"
815
816#define BUILTIN_TYPE(ID, SINGLETON_ID) \
817      case BuiltinType::ID: return ctx.SINGLETON_ID;
818#include "clang/AST/BuiltinTypes.def"
819      }
820      llvm_unreachable("unreachable builtin case");
821  }]>;
822}
823
824let Class = DependentNameType in {
825  def : Property<"keyword", ElaboratedTypeKeyword> {
826    let Read = [{ node->getKeyword() }];
827  }
828  def : Property<"qualifier", NestedNameSpecifier> {
829    let Read = [{ node->getQualifier() }];
830  }
831  def : Property<"name", Identifier> {
832    let Read = [{ node->getIdentifier() }];
833  }
834  def : Property<"underlyingType", Optional<QualType>> {
835    let Read = [{
836      node->isCanonicalUnqualified()
837        ? std::nullopt
838        : std::optional<QualType>(node->getCanonicalTypeInternal())
839    }];
840  }
841
842  def : Creator<[{
843    QualType canon = (underlyingType
844                        ? ctx.getCanonicalType(*underlyingType)
845                        : QualType());
846    return ctx.getDependentNameType(keyword, qualifier, name, canon);
847  }]>;
848}
849
850let Class = ObjCObjectType in {
851  def : Property<"baseType", QualType> {
852    let Read = [{ node->getBaseType() }];
853  }
854  def : Property<"typeArgsAsWritten", Array<QualType>> {
855    let Read = [{ node->getTypeArgsAsWritten() }];
856  }
857  def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
858    let Read = [{ node->getProtocols() }];
859  }
860  def : Property<"isKindOfTypeAsWritten", Bool> {
861    let Read = [{ node->isKindOfTypeAsWritten() }];
862  }
863
864  def : Creator<[{
865    return ctx.getObjCObjectType(baseType, typeArgsAsWritten, qualifiers,
866                                 isKindOfTypeAsWritten);
867  }]>;
868}
869
870let Class = ObjCInterfaceType in {
871  // We don't actually want any of the properties of the superclass.
872  def : Override {
873    let IgnoredProperties = [ "baseType", "typeArgsAsWritten",
874                              "qualifiers", "isKindOfTypeAsWritten" ];
875  }
876
877  def : Property<"declaration", DeclRef> {
878    // FIXME: drilling down to the canonical declaration is what the
879    // existing serialization code was doing, but it's not clear why.
880    let Read = [{ node->getDecl()->getCanonicalDecl() }];
881  }
882
883  def : Creator<[{
884    return ctx.getObjCInterfaceType(
885             cast<ObjCInterfaceDecl>(declaration->getCanonicalDecl()));
886  }]>;
887}
888
889let Class = ObjCTypeParamType in {
890  def : Property<"declaration", ObjCTypeParamDeclRef> {
891    let Read = [{ node->getDecl() }];
892  }
893  def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
894    let Read = [{ node->getProtocols() }];
895  }
896
897  def : Creator<[{
898    return ctx.getObjCTypeParamType(declaration, qualifiers);
899  }]>;
900}
901
902let Class = ObjCObjectPointerType in {
903  def : Property<"pointeeType", QualType> {
904    let Read = [{ node->getPointeeType() }];
905  }
906
907  def : Creator<[{
908    return ctx.getObjCObjectPointerType(pointeeType);
909  }]>;
910}
911
912let Class = PipeType in {
913  def : Property<"elementType", QualType> {
914    let Read = [{ node->getElementType() }];
915  }
916  def : Property<"isReadOnly", Bool> {
917    let Read = [{ node->isReadOnly() }];
918  }
919
920  def : Creator<[{
921    return ctx.getPipeType(elementType, isReadOnly);
922  }]>;
923}
924
925let Class = BitIntType in {
926  def : Property<"isUnsigned", Bool> {
927    let Read = [{ node->isUnsigned() }];
928  }
929  def : Property <"numBits", UInt32> {
930    let Read = [{ node->getNumBits() }];
931  }
932
933  def : Creator<[{
934    return ctx.getBitIntType(isUnsigned, numBits);
935  }]>;
936}
937
938let Class = DependentBitIntType in {
939  def : Property<"isUnsigned", Bool> {
940    let Read = [{ node->isUnsigned() }];
941  }
942  def : Property <"numBitsExpr", ExprRef> {
943    let Read = [{ node->getNumBitsExpr() }];
944  }
945  def : Creator<[{
946    return ctx.getDependentBitIntType(isUnsigned, numBitsExpr);
947  }]>;
948}
949