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