xref: /llvm-project/clang/include/clang/AST/TypeProperties.td (revision df335b09eac8a48d9afc06d71a86646ff6b08131)
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  def : Property<"isFullySubstituted", Bool> {
477    let Read = [{ node->isFullySubstituted() }];
478  }
479
480  def : Creator<[{
481    return ctx.getPackIndexingType(pattern, indexExpression, isFullySubstituted);
482  }]>;
483}
484
485
486let Class = UnaryTransformType in {
487  def : Property<"baseType", QualType> {
488    let Read = [{ node->getBaseType() }];
489  }
490  def : Property<"underlyingType", QualType> {
491    let Read = [{ node->getUnderlyingType() }];
492  }
493  def : Property<"transform", UnaryTypeTransformKind> {
494    let Read = [{ node->getUTTKind() }];
495  }
496
497  def : Creator<[{
498    return ctx.getUnaryTransformType(baseType, underlyingType, transform);
499  }]>;
500}
501
502let Class = AutoType in {
503  def : Property<"deducedType", Optional<QualType>> {
504    let Read = [{ makeOptionalFromNullable(node->getDeducedType()) }];
505  }
506  def : Property<"keyword", AutoTypeKeyword> {
507    let Read = [{ node->getKeyword() }];
508  }
509  def : Property<"typeConstraintConcept", Optional<ConceptDeclRef>> {
510    let Read = [{ makeOptionalFromPointer(
511        const_cast<const ConceptDecl*>(node->getTypeConstraintConcept())) }];
512  }
513  def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
514    let Read = [{ node->getTypeConstraintArguments() }];
515  }
516  // FIXME: better enumerated value
517  // Only really required when the deduced type is null
518  def : Property<"dependence", UInt32> {
519    let Read = [{ !node->getDeducedType().isNull() ? 0 :
520                  node->containsUnexpandedParameterPack() ? 2 :
521                  node->isDependentType() ? 1 : 0 }];
522  }
523
524  def : Creator<[{
525    return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword,
526                           /*isDependentWithoutDeducedType*/ dependence > 0,
527                           /*isPackWithoutDeducedType*/ dependence > 1,
528                           makePointerFromOptional(typeConstraintConcept),
529                           typeConstraintArguments);
530  }]>;
531}
532
533let Class = DeducedTemplateSpecializationType in {
534  def : Property<"templateName", Optional<TemplateName>> {
535    let Read = [{ makeOptionalFromNullable(node->getTemplateName()) }];
536  }
537  def : Property<"deducedType", QualType> {
538    let Read = [{ node->getDeducedType() }];
539  }
540  // Only really required when the deduced type is null
541  def : Property<"dependent", Bool> {
542    let Read = [{ !node->getDeducedType().isNull()
543                    ? false : node->isDependentType() }];
544  }
545
546  def : Creator<[{
547    return ctx.getDeducedTemplateSpecializationType(
548                                     makeNullableFromOptional(templateName),
549                                     deducedType, dependent);
550  }]>;
551}
552
553let Class = TagType in {
554  def : Property<"dependent", Bool> {
555    let Read = [{ node->isDependentType() }];
556  }
557  def : Property<"declaration", DeclRef> {
558    // We don't know which declaration was originally referenced here, and we
559    // cannot reference a declaration that follows the use (because that can
560    // introduce deserialization cycles), so conservatively generate a
561    // reference to the first declaration.
562    // FIXME: If this is a reference to a class template specialization, that
563    // can still introduce a deserialization cycle.
564    let Read = [{ node->getDecl()->getCanonicalDecl() }];
565  }
566}
567
568let Class = EnumType in {
569  def : Creator<[{
570    QualType result = ctx.getEnumType(cast<EnumDecl>(declaration));
571    if (dependent)
572      const_cast<Type *>(result.getTypePtr())
573          ->addDependence(TypeDependence::DependentInstantiation);
574    return result;
575  }]>;
576}
577
578let Class = RecordType in {
579  def : Creator<[{
580    auto record = cast<RecordDecl>(declaration);
581    QualType result = ctx.getRecordType(record);
582    if (dependent)
583      const_cast<Type *>(result.getTypePtr())
584          ->addDependence(TypeDependence::DependentInstantiation);
585    return result;
586  }]>;
587}
588
589let Class = ElaboratedType in {
590  def : Property<"keyword", ElaboratedTypeKeyword> {
591    let Read = [{ node->getKeyword() }];
592  }
593  def : Property<"qualifier", NestedNameSpecifier> {
594    let Read = [{ node->getQualifier() }];
595  }
596  def : Property<"namedType", QualType> {
597    let Read = [{ node->getNamedType() }];
598  }
599  def : Property<"ownedTag", Optional<TagDeclRef>> {
600    let Read = [{ makeOptionalFromPointer(
601                    const_cast<const TagDecl *>(node->getOwnedTagDecl())) }];
602  }
603
604  def : Creator<[{
605    return ctx.getElaboratedType(keyword, qualifier, namedType,
606                                 makePointerFromOptional(ownedTag));
607  }]>;
608}
609
610let Class = InjectedClassNameType in {
611  def : Property<"declaration", DeclRef> {
612    // FIXME: drilling down to the canonical declaration is what the
613    // existing serialization code was doing, but it's not clear why.
614    let Read = [{ node->getDecl()->getCanonicalDecl() }];
615  }
616  def : Property<"injectedSpecializationType", QualType> {
617    let Read = [{ node->getInjectedSpecializationType() }];
618  }
619
620  def : Creator<[{
621    // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
622    // for AST reading, too much interdependencies.
623    const Type *T = nullptr;
624    auto typeDecl = cast<CXXRecordDecl>(declaration);
625    for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl()) {
626      if (const Type *existing = DI->getTypeForDecl()) {
627        T = existing;
628        break;
629      }
630    }
631    if (!T) {
632      T = new (ctx, TypeAlignment)
633            InjectedClassNameType(typeDecl, injectedSpecializationType);
634      for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl())
635        DI->setTypeForDecl(T);
636    }
637    return QualType(T, 0);
638  }]>;
639}
640
641let Class = ParenType in {
642  def : Property<"innerType", QualType> {
643    let Read = [{ node->getInnerType() }];
644  }
645
646  def : Creator<[{
647    return ctx.getParenType(innerType);
648  }]>;
649}
650
651let Class = MacroQualifiedType in {
652  def : Property<"underlyingType", QualType> {
653    let Read = [{ node->getUnderlyingType() }];
654  }
655  def : Property<"macroIdentifier", Identifier> {
656    let Read = [{ node->getMacroIdentifier() }];
657  }
658
659  def : Creator<[{
660    return ctx.getMacroQualifiedType(underlyingType, macroIdentifier);
661  }]>;
662}
663
664let Class = AttributedType in {
665  def : Property<"modifiedType", QualType> {
666    let Read = [{ node->getModifiedType() }];
667  }
668  def : Property<"equivalentType", QualType> {
669    let Read = [{ node->getEquivalentType() }];
670  }
671  def : Property<"attrKind", AttrKind> {
672    let Read = [{ node->getAttrKind() }];
673  }
674  def : Property<"attribute", Attr> {
675    let Read = [{ node->getAttr() }];
676  }
677
678  def : Creator<[{
679    return ctx.getAttributedType(attrKind, modifiedType,
680                                 equivalentType, attribute);
681  }]>;
682}
683
684let Class = BTFTagAttributedType in {
685  def : Property<"attr", BTFTypeTagAttr> {
686    let Read = [{ node->getAttr() }];
687  }
688  def : Property<"wrappedType", QualType> {
689    let Read = [{ node->getWrappedType() }];
690  }
691
692  def : Creator<[{
693    return ctx.getBTFTagAttributedType(attr, wrappedType);
694  }]>;
695}
696
697let Class = HLSLAttributedResourceType in {
698  def : Property<"resClass", UInt32> {
699    let Read = [{ static_cast<uint32_t>(node->getAttrs().ResourceClass) }];
700  }
701  def : Property<"isROV", Bool> {
702    let Read = [{ node->getAttrs().IsROV }];
703  }
704  def : Property<"rawBuffer", Bool> {
705    let Read = [{ node->getAttrs().RawBuffer }];
706  }
707  def : Property<"wrappedTy", QualType> {
708    let Read = [{ node->getWrappedType() }];
709  }
710  def : Property<"containedTy", QualType> {
711    let Read = [{ node->getContainedType() }];
712  }
713  def : Creator<[{
714    HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rawBuffer);
715    return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs);
716  }]>;
717}
718
719let Class = DependentAddressSpaceType in {
720  def : Property<"pointeeType", QualType> {
721    let Read = [{ node->getPointeeType() }];
722  }
723  def : Property<"addressSpace", ExprRef> {
724    let Read = [{ node->getAddrSpaceExpr() }];
725  }
726  def : Property<"attributeLoc", SourceLocation> {
727    let Read = [{ node->getAttributeLoc() }];
728  }
729
730  def : Creator<[{
731    return ctx.getDependentAddressSpaceType(pointeeType, addressSpace,
732                                            attributeLoc);
733  }]>;
734}
735
736let Class = TemplateSpecializationType in {
737  def : Property<"dependent", Bool> {
738    let Read = [{ node->isDependentType() }];
739  }
740  def : Property<"templateName", TemplateName> {
741    let Read = [{ node->getTemplateName() }];
742  }
743  def : Property<"templateArguments", Array<TemplateArgument>> {
744    let Read = [{ node->template_arguments() }];
745  }
746  def : Property<"underlyingType", Optional<QualType>> {
747    let Read = [{
748      node->isTypeAlias()
749        ? std::optional<QualType>(node->getAliasedType())
750        : node->isCanonicalUnqualified()
751            ? std::nullopt
752            : std::optional<QualType>(node->getCanonicalTypeInternal())
753    }];
754  }
755
756  def : Creator<[{
757    QualType result;
758    if (!underlyingType) {
759      result = ctx.getCanonicalTemplateSpecializationType(templateName,
760                                                          templateArguments);
761    } else {
762      result = ctx.getTemplateSpecializationType(templateName,
763                                                 templateArguments,
764                                                 *underlyingType);
765    }
766    if (dependent)
767      const_cast<Type *>(result.getTypePtr())
768          ->addDependence(TypeDependence::DependentInstantiation);
769    return result;
770  }]>;
771}
772
773let Class = DependentTemplateSpecializationType in {
774  def : Property<"keyword", ElaboratedTypeKeyword> {
775    let Read = [{ node->getKeyword() }];
776  }
777  def : Property<"qualifier", NestedNameSpecifier> {
778    let Read = [{ node->getQualifier() }];
779  }
780  def : Property<"name", Identifier> {
781    let Read = [{ node->getIdentifier() }];
782  }
783  def : Property<"templateArguments", Array<TemplateArgument>> {
784    let Read = [{ node->template_arguments() }];
785  }
786
787  def : Creator<[{
788    return ctx.getDependentTemplateSpecializationType(keyword, qualifier,
789                                                      name, templateArguments);
790  }]>;
791}
792
793let Class = TemplateTypeParmType in {
794  def : Property<"depth", UInt32> {
795    let Read = [{ node->getDepth() }];
796  }
797  def : Property<"index", UInt32> {
798    let Read = [{ node->getIndex() }];
799  }
800  def : Property<"isParameterPack", Bool> {
801    let Read = [{ node->isParameterPack() }];
802  }
803  def : Property<"declaration", Optional<TemplateTypeParmDeclRef>> {
804    let Read = [{ makeOptionalFromPointer(
805                    const_cast<const TemplateTypeParmDecl*>(node->getDecl())) }];
806  }
807
808  def : Creator<[{
809    return ctx.getTemplateTypeParmType(depth, index, isParameterPack,
810                                       makePointerFromOptional(declaration));
811  }]>;
812}
813
814let Class = SubstTemplateTypeParmType in {
815  def : Property<"replacementType", QualType> {
816    let Read = [{ node->getReplacementType() }];
817  }
818  def : Property<"associatedDecl", DeclRef> {
819    let Read = [{ node->getAssociatedDecl() }];
820  }
821  def : Property<"Index", UInt32> {
822    let Read = [{ node->getIndex() }];
823  }
824  def : Property<"PackIndex", Optional<UInt32>> {
825    let Read = [{ node->getPackIndex() }];
826  }
827  def : Property<"SubstitutionFlag", SubstTemplateTypeParmTypeFlag> {
828    let Read = [{ node->getSubstitutionFlag() }];
829  }
830
831  // The call to getCanonicalType here existed in ASTReader.cpp, too.
832  def : Creator<[{
833    return ctx.getSubstTemplateTypeParmType(
834        replacementType, associatedDecl, Index, PackIndex, SubstitutionFlag);
835  }]>;
836}
837
838let Class = PackExpansionType in {
839  def : Property<"pattern", QualType> {
840    let Read = [{ node->getPattern() }];
841  }
842  def : Property<"numExpansions", Optional<UInt32>> {
843    let Read = [{ node->getNumExpansions() }];
844  }
845
846  def : Creator<[{
847    return ctx.getPackExpansionType(pattern, numExpansions,
848                                    /*ExpectPackInType*/false);
849  }]>;
850}
851
852let Class = SubstTemplateTypeParmPackType in {
853  def : Property<"associatedDecl", DeclRef> {
854    let Read = [{ node->getAssociatedDecl() }];
855  }
856  def : Property<"Index", UInt32> {
857    let Read = [{ node->getIndex() }];
858  }
859  def : Property<"Final", Bool> {
860    let Read = [{ node->getFinal() }];
861  }
862  def : Property<"replacementPack", TemplateArgument> {
863    let Read = [{ node->getArgumentPack() }];
864  }
865
866  def : Creator<[{
867    return ctx.getSubstTemplateTypeParmPackType(
868                        associatedDecl, Index, Final, replacementPack);
869  }]>;
870}
871
872let Class = BuiltinType in {
873  def : Property<"kind", BuiltinTypeKind> {
874    let Read = [{ node->getKind() }];
875  }
876
877  def : Creator<[{
878      switch (kind) {
879#define IMAGE_TYPE(IMGTYPE, ID, SINGLETON_ID, ACCESS, SUFFIX) \
880      case BuiltinType::ID: return ctx.SINGLETON_ID;
881#include "clang/Basic/OpenCLImageTypes.def"
882
883#define EXT_OPAQUE_TYPE(EXTTYPE, ID, EXT) \
884      case BuiltinType::ID: return ctx.ID##Ty;
885#include "clang/Basic/OpenCLExtensionTypes.def"
886
887#define SVE_TYPE(NAME, ID, SINGLETON_ID) \
888      case BuiltinType::ID: return ctx.SINGLETON_ID;
889#include "clang/Basic/AArch64SVEACLETypes.def"
890
891#define PPC_VECTOR_TYPE(NAME, ID, SIZE) \
892      case BuiltinType::ID: return ctx.ID##Ty;
893#include "clang/Basic/PPCTypes.def"
894
895#define RVV_TYPE(NAME, ID, SINGLETON_ID) \
896      case BuiltinType::ID: return ctx.SINGLETON_ID;
897#include "clang/Basic/RISCVVTypes.def"
898
899#define WASM_TYPE(NAME, ID, SINGLETON_ID) \
900      case BuiltinType::ID: return ctx.SINGLETON_ID;
901#include "clang/Basic/WebAssemblyReferenceTypes.def"
902
903#define AMDGPU_TYPE(NAME, ID, SINGLETON_ID, WIDTH, ALIGN) \
904      case BuiltinType::ID: return ctx.SINGLETON_ID;
905#include "clang/Basic/AMDGPUTypes.def"
906
907#define HLSL_INTANGIBLE_TYPE(NAME, ID, SINGLETON_ID) \
908      case BuiltinType::ID: return ctx.SINGLETON_ID;
909#include "clang/Basic/HLSLIntangibleTypes.def"
910
911#define BUILTIN_TYPE(ID, SINGLETON_ID) \
912      case BuiltinType::ID: return ctx.SINGLETON_ID;
913#include "clang/AST/BuiltinTypes.def"
914      }
915      llvm_unreachable("unreachable builtin case");
916  }]>;
917}
918
919let Class = DependentNameType in {
920  def : Property<"keyword", ElaboratedTypeKeyword> {
921    let Read = [{ node->getKeyword() }];
922  }
923  def : Property<"qualifier", NestedNameSpecifier> {
924    let Read = [{ node->getQualifier() }];
925  }
926  def : Property<"name", Identifier> {
927    let Read = [{ node->getIdentifier() }];
928  }
929  def : Property<"underlyingType", Optional<QualType>> {
930    let Read = [{
931      node->isCanonicalUnqualified()
932        ? std::nullopt
933        : std::optional<QualType>(node->getCanonicalTypeInternal())
934    }];
935  }
936
937  def : Creator<[{
938    QualType canon = (underlyingType
939                        ? ctx.getCanonicalType(*underlyingType)
940                        : QualType());
941    return ctx.getDependentNameType(keyword, qualifier, name, canon);
942  }]>;
943}
944
945let Class = ObjCObjectType in {
946  def : Property<"baseType", QualType> {
947    let Read = [{ node->getBaseType() }];
948  }
949  def : Property<"typeArgsAsWritten", Array<QualType>> {
950    let Read = [{ node->getTypeArgsAsWritten() }];
951  }
952  def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
953    let Read = [{ node->getProtocols() }];
954  }
955  def : Property<"isKindOfTypeAsWritten", Bool> {
956    let Read = [{ node->isKindOfTypeAsWritten() }];
957  }
958
959  def : Creator<[{
960    return ctx.getObjCObjectType(baseType, typeArgsAsWritten, qualifiers,
961                                 isKindOfTypeAsWritten);
962  }]>;
963}
964
965let Class = ObjCInterfaceType in {
966  // We don't actually want any of the properties of the superclass.
967  def : Override {
968    let IgnoredProperties = [ "baseType", "typeArgsAsWritten",
969                              "qualifiers", "isKindOfTypeAsWritten" ];
970  }
971
972  def : Property<"declaration", DeclRef> {
973    // FIXME: drilling down to the canonical declaration is what the
974    // existing serialization code was doing, but it's not clear why.
975    let Read = [{ node->getDecl()->getCanonicalDecl() }];
976  }
977
978  def : Creator<[{
979    return ctx.getObjCInterfaceType(
980             cast<ObjCInterfaceDecl>(declaration->getCanonicalDecl()));
981  }]>;
982}
983
984let Class = ObjCTypeParamType in {
985  def : Property<"declaration", ObjCTypeParamDeclRef> {
986    let Read = [{ node->getDecl() }];
987  }
988  def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
989    let Read = [{ node->getProtocols() }];
990  }
991
992  def : Creator<[{
993    return ctx.getObjCTypeParamType(declaration, qualifiers);
994  }]>;
995}
996
997let Class = ObjCObjectPointerType in {
998  def : Property<"pointeeType", QualType> {
999    let Read = [{ node->getPointeeType() }];
1000  }
1001
1002  def : Creator<[{
1003    return ctx.getObjCObjectPointerType(pointeeType);
1004  }]>;
1005}
1006
1007let Class = PipeType in {
1008  def : Property<"elementType", QualType> {
1009    let Read = [{ node->getElementType() }];
1010  }
1011  def : Property<"isReadOnly", Bool> {
1012    let Read = [{ node->isReadOnly() }];
1013  }
1014
1015  def : Creator<[{
1016    return ctx.getPipeType(elementType, isReadOnly);
1017  }]>;
1018}
1019
1020let Class = BitIntType in {
1021  def : Property<"isUnsigned", Bool> {
1022    let Read = [{ node->isUnsigned() }];
1023  }
1024  def : Property <"numBits", UInt32> {
1025    let Read = [{ node->getNumBits() }];
1026  }
1027
1028  def : Creator<[{
1029    return ctx.getBitIntType(isUnsigned, numBits);
1030  }]>;
1031}
1032
1033let Class = DependentBitIntType in {
1034  def : Property<"isUnsigned", Bool> {
1035    let Read = [{ node->isUnsigned() }];
1036  }
1037  def : Property <"numBitsExpr", ExprRef> {
1038    let Read = [{ node->getNumBitsExpr() }];
1039  }
1040  def : Creator<[{
1041    return ctx.getDependentBitIntType(isUnsigned, numBitsExpr);
1042  }]>;
1043}
1044