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