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