1 //==--- TypeProperties.td - Type property definitions ---------------------===//
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
7 //===----------------------------------------------------------------------===//
9 include "clang/AST/PropertiesBase.td"
10 include "clang/Basic/TypeNodes.td"
12 let Class = ComplexType in {
13 def : Property<"elementType", QualType> {
14 let Read = [{ node->getElementType() }];
17 def : Creator<[{ return ctx.getComplexType(elementType); }]>;
20 let Class = PointerType in {
21 def : Property<"pointeeType", QualType> {
22 let Read = [{ node->getPointeeType() }];
25 def : Creator<[{ return ctx.getPointerType(pointeeType); }]>;
28 let Class = AdjustedType in {
29 def : Property<"originalType", QualType> {
30 let Read = [{ node->getOriginalType() }];
32 def : Property<"adjustedType", QualType> {
33 let Read = [{ node->getAdjustedType() }];
36 def : Creator<[{ return ctx.getAdjustedType(originalType, adjustedType); }]>;
39 let Class = DecayedType in {
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" ];
46 def : Creator<[{ return ctx.getAdjustedParameterType(originalType); }]>;
49 let Class = BlockPointerType in {
50 def : Property<"pointeeType", QualType> {
51 let Read = [{ node->getPointeeType() }];
54 def : Creator<[{ return ctx.getBlockPointerType(pointeeType); }]>;
57 let Class = ReferenceType in {
58 def : Property<"pointeeTypeAsWritten", QualType> {
59 let Read = [{ node->getPointeeTypeAsWritten() }];
63 let Class = LValueReferenceType in {
64 def : Property<"isSpelledAsLValue", Bool> {
65 let Read = [{ node->isSpelledAsLValue() }];
69 return ctx.getLValueReferenceType(pointeeTypeAsWritten,
74 let Class = RValueReferenceType in {
76 return ctx.getRValueReferenceType(pointeeTypeAsWritten);
80 let Class = MemberPointerType in {
81 def : Property<"pointeeType", QualType> {
82 let Read = [{ node->getPointeeType() }];
84 def : Property<"baseType", QualType> {
85 let Read = [{ QualType(node->getClass(), 0) }];
89 return ctx.getMemberPointerType(pointeeType, baseType.getTypePtr());
93 let Class = ArrayType in {
94 def : Property<"elementType", QualType> {
95 let Read = [{ node->getElementType() }];
97 def : Property<"sizeModifier", ArraySizeModifier> {
98 let Read = [{ node->getSizeModifier() }];
100 def : Property<"indexQualifiers", Qualifiers> {
101 let Read = [{ Qualifiers::fromCVRMask(node->getIndexTypeCVRQualifiers()) }];
105 let Class = ConstantArrayType in {
106 def : Property<"sizeValue", APInt> {
107 let Read = [{ node->getSize() }];
109 def : Property<"size", ExprRef> {
110 let Read = [{ node->getSizeExpr() }];
114 return ctx.getConstantArrayType(elementType, sizeValue, size,
116 indexQualifiers.getCVRQualifiers());
120 let Class = IncompleteArrayType in {
122 return ctx.getIncompleteArrayType(elementType, sizeModifier,
123 indexQualifiers.getCVRQualifiers());
127 let Class = VariableArrayType in {
128 def : Property<"leftBracketLoc", SourceLocation> {
129 let Read = [{ node->getLBracketLoc() }];
131 def : Property<"rightBracketLoc", SourceLocation> {
132 let Read = [{ node->getRBracketLoc() }];
134 def : Property<"size", ExprRef> {
135 let Read = [{ node->getSizeExpr() }];
139 return ctx.getVariableArrayType(elementType, size, sizeModifier,
140 indexQualifiers.getCVRQualifiers(),
141 SourceRange(leftBracketLoc,
146 let Class = DependentSizedArrayType in {
147 def : Property<"size", ExprRef> {
148 let Read = [{ node->getSizeExpr() }];
150 def : Property<"leftBracketLoc", SourceLocation> {
151 let Read = [{ node->getLBracketLoc() }];
153 def : Property<"rightBracketLoc", SourceLocation> {
154 let Read = [{ node->getRBracketLoc() }];
158 return ctx.getDependentSizedArrayType(elementType, size, sizeModifier,
159 indexQualifiers.getCVRQualifiers(),
160 SourceRange(leftBracketLoc,
165 let Class = VectorType in {
166 def : Property<"elementType", QualType> {
167 let Read = [{ node->getElementType() }];
169 def : Property<"numElements", UInt32> {
170 let Read = [{ node->getNumElements() }];
172 def : Property<"vectorKind", VectorKind> {
173 let Read = [{ node->getVectorKind() }];
177 return ctx.getVectorType(elementType, numElements, vectorKind);
181 let Class = DependentVectorType in {
182 def : Property<"elementType", QualType> {
183 let Read = [{ node->getElementType() }];
185 def : Property<"size", ExprRef> {
186 let Read = [{ node->getSizeExpr() }];
188 def : Property<"attributeLoc", SourceLocation> {
189 let Read = [{ node->getAttributeLoc() }];
191 def : Property<"vectorKind", VectorKind> {
192 let Read = [{ node->getVectorKind() }];
196 return ctx.getDependentVectorType(elementType, size, attributeLoc,
201 let Class = ExtVectorType in {
203 let IgnoredProperties = [ "vectorKind" ];
207 return ctx.getExtVectorType(elementType, numElements);
211 let Class = DependentSizedExtVectorType in {
212 def : Property<"elementType", QualType> {
213 let Read = [{ node->getElementType() }];
215 def : Property<"size", ExprRef> {
216 let Read = [{ node->getSizeExpr() }];
218 def : Property<"attributeLoc", SourceLocation> {
219 let Read = [{ node->getAttributeLoc() }];
223 return ctx.getDependentSizedExtVectorType(elementType, size, attributeLoc);
227 let Class = MatrixType in {
228 def : Property<"elementType", QualType> {
229 let Read = [{ node->getElementType() }];
233 let Class = ConstantMatrixType in {
234 def : Property<"numRows", UInt32> {
235 let Read = [{ node->getNumRows() }];
237 def : Property<"numColumns", UInt32> {
238 let Read = [{ node->getNumColumns() }];
242 return ctx.getConstantMatrixType(elementType, numRows, numColumns);
246 let Class = DependentSizedMatrixType in {
247 def : Property<"rows", ExprRef> {
248 let Read = [{ node->getRowExpr() }];
250 def : Property<"columns", ExprRef> {
251 let Read = [{ node->getColumnExpr() }];
253 def : Property<"attributeLoc", SourceLocation> {
254 let Read = [{ node->getAttributeLoc() }];
258 return ctx.getDependentSizedMatrixType(elementType, rows, columns, attributeLoc);
262 let Class = FunctionType in {
263 def : Property<"returnType", QualType> {
264 let Read = [{ node->getReturnType() }];
266 def : Property<"noReturn", Bool> {
267 let Read = [{ node->getExtInfo().getNoReturn() }];
269 def : Property<"hasRegParm", Bool> {
270 let Read = [{ node->getExtInfo().getHasRegParm() }];
272 def : Property<"regParm", UInt32> {
273 let Read = [{ node->getExtInfo().getRegParm() }];
275 def : Property<"callingConvention", CallingConv> {
276 let Read = [{ node->getExtInfo().getCC() }];
278 def : Property<"producesResult", Bool> {
279 let Read = [{ node->getExtInfo().getProducesResult() }];
281 def : Property<"noCallerSavedRegs", Bool> {
282 let Read = [{ node->getExtInfo().getNoCallerSavedRegs() }];
284 def : Property<"noCfCheck", Bool> {
285 let Read = [{ node->getExtInfo().getNoCfCheck() }];
287 def : Property<"cmseNSCall", Bool> {
288 let Read = [{ node->getExtInfo().getCmseNSCall() }];
292 let Class = FunctionNoProtoType in {
294 auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
295 callingConvention, producesResult,
296 noCallerSavedRegs, noCfCheck,
298 return ctx.getFunctionNoProtoType(returnType, extInfo);
302 let Class = FunctionProtoType in {
303 def : Property<"variadic", Bool> {
304 let Read = [{ node->isVariadic() }];
306 def : Property<"trailingReturn", Bool> {
307 let Read = [{ node->hasTrailingReturn() }];
309 def : Property<"methodQualifiers", Qualifiers> {
310 let Read = [{ node->getMethodQuals() }];
312 def : Property<"refQualifier", RefQualifierKind> {
313 let Read = [{ node->getRefQualifier() }];
315 def : Property<"exceptionSpecifier", ExceptionSpecInfo> {
316 let Read = [{ node->getExceptionSpecInfo() }];
318 def : Property<"parameters", Array<QualType>> {
319 let Read = [{ node->getParamTypes() }];
321 def : Property<"extParameterInfo", Array<ExtParameterInfo>> {
322 let Read = [{ node->hasExtParameterInfos()
323 ? node->getExtParameterInfos()
324 : llvm::ArrayRef<FunctionProtoType::ExtParameterInfo>() }];
328 auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
329 callingConvention, producesResult,
330 noCallerSavedRegs, noCfCheck,
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);
345 let Class = AtomicType in {
346 def : Property<"valueType", QualType> {
347 let Read = [{ node->getValueType() }];
351 return ctx.getAtomicType(valueType);
355 let Class = UnresolvedUsingType in {
356 def : Property<"declaration", DeclRef> {
357 let Read = [{ node->getDecl() }];
361 return ctx.getTypeDeclType(cast<UnresolvedUsingTypenameDecl>(declaration));
365 let Class = TypedefType in {
366 def : Property<"declaration", DeclRef> {
367 let Read = [{ node->getDecl() }];
369 def : Property<"canonicalType", Optional<QualType>> {
370 let Read = [{ makeOptionalFromNullable(node->getCanonicalTypeInternal()) }];
374 QualType finalCanonicalType =
375 canonicalType ? ctx.getCanonicalType(*canonicalType)
377 return ctx.getTypedefType(cast<TypedefNameDecl>(declaration),
382 let Class = TypeOfExprType in {
383 def : Property<"expression", ExprRef> {
384 let Read = [{ node->getUnderlyingExpr() }];
388 return ctx.getTypeOfExprType(expression);
392 let Class = TypeOfType in {
393 def : Property<"underlyingType", QualType> {
394 let Read = [{ node->getUnderlyingType() }];
398 return ctx.getTypeOfType(underlyingType);
402 let Class = DecltypeType in {
403 def : Property<"underlyingType", QualType> {
404 let Read = [{ node->getUnderlyingType() }];
406 def : Property<"expression", ExprRef> {
407 let Read = [{ node->getUnderlyingExpr() }];
411 return ctx.getDecltypeType(expression, underlyingType);
415 let Class = UnaryTransformType in {
416 def : Property<"baseType", QualType> {
417 let Read = [{ node->getBaseType() }];
419 def : Property<"underlyingType", QualType> {
420 let Read = [{ node->getUnderlyingType() }];
422 def : Property<"transform", UnaryTypeTransformKind> {
423 let Read = [{ node->getUTTKind() }];
427 return ctx.getUnaryTransformType(baseType, underlyingType, transform);
431 let Class = AutoType in {
432 def : Property<"deducedType", Optional<QualType>> {
433 let Read = [{ makeOptionalFromNullable(node->getDeducedType()) }];
435 def : Property<"keyword", AutoTypeKeyword> {
436 let Read = [{ node->getKeyword() }];
438 def : Property<"typeConstraintConcept", Optional<ConceptDeclRef>> {
439 let Read = [{ makeOptionalFromPointer(
440 const_cast<const ConceptDecl*>(node->getTypeConstraintConcept())) }];
442 def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
443 let Read = [{ node->getTypeConstraintArguments() }];
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 }];
454 return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword,
455 /*isDependentWithoutDeducedType*/ dependence > 0,
456 /*isPackWithoutDeducedType*/ dependence > 1,
457 makePointerFromOptional(typeConstraintConcept),
458 typeConstraintArguments);
462 let Class = DeducedTemplateSpecializationType in {
463 def : Property<"templateName", Optional<TemplateName>> {
464 let Read = [{ makeOptionalFromNullable(node->getTemplateName()) }];
466 def : Property<"deducedType", QualType> {
467 let Read = [{ node->getDeducedType() }];
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() }];
476 return ctx.getDeducedTemplateSpecializationType(
477 makeNullableFromOptional(templateName),
478 deducedType, dependent);
482 let Class = TagType in {
483 def : Property<"dependent", Bool> {
484 let Read = [{ node->isDependentType() }];
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() }];
493 let Class = EnumType in {
495 QualType result = ctx.getEnumType(cast<EnumDecl>(declaration));
497 const_cast<Type *>(result.getTypePtr())
498 ->addDependence(TypeDependence::DependentInstantiation);
503 let Class = RecordType in {
505 auto record = cast<RecordDecl>(declaration);
506 QualType result = ctx.getRecordType(record);
508 const_cast<Type *>(result.getTypePtr())
509 ->addDependence(TypeDependence::DependentInstantiation);
514 let Class = ElaboratedType in {
515 def : Property<"keyword", ElaboratedTypeKeyword> {
516 let Read = [{ node->getKeyword() }];
518 def : Property<"qualifier", NestedNameSpecifier> {
519 let Read = [{ node->getQualifier() }];
521 def : Property<"namedType", QualType> {
522 let Read = [{ node->getNamedType() }];
524 def : Property<"ownedTag", Optional<TagDeclRef>> {
525 let Read = [{ makeOptionalFromPointer(
526 const_cast<const TagDecl *>(node->getOwnedTagDecl())) }];
530 return ctx.getElaboratedType(keyword, qualifier, namedType,
531 makePointerFromOptional(ownedTag));
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() }];
541 def : Property<"injectedSpecializationType", QualType> {
542 let Read = [{ node->getInjectedSpecializationType() }];
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()) {
557 T = new (ctx, TypeAlignment)
558 InjectedClassNameType(typeDecl, injectedSpecializationType);
559 for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl())
560 DI->setTypeForDecl(T);
562 return QualType(T, 0);
566 let Class = ParenType in {
567 def : Property<"innerType", QualType> {
568 let Read = [{ node->getInnerType() }];
572 return ctx.getParenType(innerType);
576 let Class = MacroQualifiedType in {
577 def : Property<"underlyingType", QualType> {
578 let Read = [{ node->getUnderlyingType() }];
580 def : Property<"macroIdentifier", Identifier> {
581 let Read = [{ node->getMacroIdentifier() }];
585 return ctx.getMacroQualifiedType(underlyingType, macroIdentifier);
589 let Class = AttributedType in {
590 def : Property<"modifiedType", QualType> {
591 let Read = [{ node->getModifiedType() }];
593 def : Property<"equivalentType", QualType> {
594 let Read = [{ node->getEquivalentType() }];
596 def : Property<"attribute", AttrKind> {
597 let Read = [{ node->getAttrKind() }];
601 return ctx.getAttributedType(attribute, modifiedType, equivalentType);
605 let Class = DependentAddressSpaceType in {
606 def : Property<"pointeeType", QualType> {
607 let Read = [{ node->getPointeeType() }];
609 def : Property<"addressSpace", ExprRef> {
610 let Read = [{ node->getAddrSpaceExpr() }];
612 def : Property<"attributeLoc", SourceLocation> {
613 let Read = [{ node->getAttributeLoc() }];
617 return ctx.getDependentAddressSpaceType(pointeeType, addressSpace,
622 let Class = TemplateSpecializationType in {
623 def : Property<"dependent", Bool> {
624 let Read = [{ node->isDependentType() }];
626 def : Property<"templateName", TemplateName> {
627 let Read = [{ node->getTemplateName() }];
629 def : Property<"templateArguments", Array<TemplateArgument>> {
630 let Read = [{ node->template_arguments() }];
632 def : Property<"underlyingType", Optional<QualType>> {
635 ? llvm::Optional<QualType>(node->getAliasedType())
636 : node->isCanonicalUnqualified()
638 : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
644 if (!underlyingType.hasValue()) {
645 result = ctx.getCanonicalTemplateSpecializationType(templateName,
648 result = ctx.getTemplateSpecializationType(templateName,
653 const_cast<Type *>(result.getTypePtr())
654 ->addDependence(TypeDependence::DependentInstantiation);
659 let Class = DependentTemplateSpecializationType in {
660 def : Property<"keyword", ElaboratedTypeKeyword> {
661 let Read = [{ node->getKeyword() }];
663 def : Property<"qualifier", NestedNameSpecifier> {
664 let Read = [{ node->getQualifier() }];
666 def : Property<"name", Identifier> {
667 let Read = [{ node->getIdentifier() }];
669 def : Property<"templateArguments", Array<TemplateArgument>> {
670 let Read = [{ node->template_arguments() }];
674 return ctx.getDependentTemplateSpecializationType(keyword, qualifier,
675 name, templateArguments);
679 let Class = TemplateTypeParmType in {
680 def : Property<"depth", UInt32> {
681 let Read = [{ node->getDepth() }];
683 def : Property<"index", UInt32> {
684 let Read = [{ node->getIndex() }];
686 def : Property<"isParameterPack", Bool> {
687 let Read = [{ node->isParameterPack() }];
689 def : Property<"declaration", Optional<TemplateTypeParmDeclRef>> {
690 let Read = [{ makeOptionalFromPointer(
691 const_cast<const TemplateTypeParmDecl*>(node->getDecl())) }];
695 return ctx.getTemplateTypeParmType(depth, index, isParameterPack,
696 makePointerFromOptional(declaration));
700 let Class = SubstTemplateTypeParmType in {
701 def : Property<"replacedParameter", QualType> {
702 let Read = [{ QualType(node->getReplacedParameter(), 0) }];
704 def : Property<"replacementType", QualType> {
705 let Read = [{ node->getReplacementType() }];
709 // The call to getCanonicalType here existed in ASTReader.cpp, too.
710 return ctx.getSubstTemplateTypeParmType(
711 cast<TemplateTypeParmType>(replacedParameter),
712 ctx.getCanonicalType(replacementType));
716 let Class = PackExpansionType in {
717 def : Property<"pattern", QualType> {
718 let Read = [{ node->getPattern() }];
720 def : Property<"numExpansions", Optional<UInt32>> {
721 let Read = [{ node->getNumExpansions() }];
725 return ctx.getPackExpansionType(pattern, numExpansions);
729 let Class = SubstTemplateTypeParmPackType in {
730 def : Property<"replacedParameter", QualType> {
731 let Read = [{ QualType(node->getReplacedParameter(), 0) }];
733 def : Property<"replacementPack", TemplateArgument> {
734 let Read = [{ node->getArgumentPack() }];
738 return ctx.getSubstTemplateTypeParmPackType(
739 cast<TemplateTypeParmType>(replacedParameter),
744 let Class = BuiltinType in {
745 def : Property<"kind", BuiltinTypeKind> {
746 let Read = [{ node->getKind() }];
751 #define IMAGE_TYPE(IMGTYPE, ID, SINGLETON_ID, ACCESS, SUFFIX) \
752 case BuiltinType::ID: return ctx.SINGLETON_ID;
753 #include "clang/Basic/OpenCLImageTypes.def"
755 #define EXT_OPAQUE_TYPE(EXTTYPE, ID, EXT) \
756 case BuiltinType::ID: return ctx.ID##Ty;
757 #include "clang/Basic/OpenCLExtensionTypes.def"
759 #define SVE_TYPE(NAME, ID, SINGLETON_ID) \
760 case BuiltinType::ID: return ctx.SINGLETON_ID;
761 #include "clang/Basic/AArch64SVEACLETypes.def"
763 #define BUILTIN_TYPE(ID, SINGLETON_ID) \
764 case BuiltinType::ID: return ctx.SINGLETON_ID;
765 #include "clang/AST/BuiltinTypes.def"
767 llvm_unreachable("unreachable builtin case");
771 let Class = DependentNameType in {
772 def : Property<"keyword", ElaboratedTypeKeyword> {
773 let Read = [{ node->getKeyword() }];
775 def : Property<"qualifier", NestedNameSpecifier> {
776 let Read = [{ node->getQualifier() }];
778 def : Property<"name", Identifier> {
779 let Read = [{ node->getIdentifier() }];
781 def : Property<"underlyingType", Optional<QualType>> {
783 node->isCanonicalUnqualified()
785 : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
790 QualType canon = (underlyingType
791 ? ctx.getCanonicalType(*underlyingType)
793 return ctx.getDependentNameType(keyword, qualifier, name, canon);
797 let Class = ObjCObjectType in {
798 def : Property<"baseType", QualType> {
799 let Read = [{ node->getBaseType() }];
801 def : Property<"typeArgsAsWritten", Array<QualType>> {
802 let Read = [{ node->getTypeArgsAsWritten() }];
804 def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
805 let Read = [{ node->getProtocols() }];
807 def : Property<"isKindOfTypeAsWritten", Bool> {
808 let Read = [{ node->isKindOfTypeAsWritten() }];
812 return ctx.getObjCObjectType(baseType, typeArgsAsWritten, qualifiers,
813 isKindOfTypeAsWritten);
817 let Class = ObjCInterfaceType in {
818 // We don't actually want any of the properties of the superclass.
820 let IgnoredProperties = [ "baseType", "typeArgsAsWritten",
821 "qualifiers", "isKindOfTypeAsWritten" ];
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() }];
831 return ctx.getObjCInterfaceType(
832 cast<ObjCInterfaceDecl>(declaration->getCanonicalDecl()));
836 let Class = ObjCTypeParamType in {
837 def : Property<"declaration", ObjCTypeParamDeclRef> {
838 let Read = [{ node->getDecl() }];
840 def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
841 let Read = [{ node->getProtocols() }];
845 return ctx.getObjCTypeParamType(declaration, qualifiers);
849 let Class = ObjCObjectPointerType in {
850 def : Property<"pointeeType", QualType> {
851 let Read = [{ node->getPointeeType() }];
855 return ctx.getObjCObjectPointerType(pointeeType);
859 let Class = PipeType in {
860 def : Property<"elementType", QualType> {
861 let Read = [{ node->getElementType() }];
863 def : Property<"isReadOnly", Bool> {
864 let Read = [{ node->isReadOnly() }];
868 return ctx.getPipeType(elementType, isReadOnly);
872 let Class = ExtIntType in {
873 def : Property<"isUnsigned", Bool> {
874 let Read = [{ node->isUnsigned() }];
876 def : Property <"numBits", UInt32> {
877 let Read = [{ node->getNumBits() }];
881 return ctx.getExtIntType(isUnsigned, numBits);
885 let Class = DependentExtIntType in {
886 def : Property<"isUnsigned", Bool> {
887 let Read = [{ node->isUnsigned() }];
889 def : Property <"numBitsExpr", ExprRef> {
890 let Read = [{ node->getNumBitsExpr() }];
893 return ctx.getDependentExtIntType(isUnsigned, numBitsExpr);