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