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