/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/Type.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Type.cpp - Type representation and manipulation --------------------===// |
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 | | // This file implements type-related functionality. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "clang/AST/Type.h" |
14 | | #include "Linkage.h" |
15 | | #include "clang/AST/ASTContext.h" |
16 | | #include "clang/AST/Attr.h" |
17 | | #include "clang/AST/CharUnits.h" |
18 | | #include "clang/AST/Decl.h" |
19 | | #include "clang/AST/DeclBase.h" |
20 | | #include "clang/AST/DeclCXX.h" |
21 | | #include "clang/AST/DeclObjC.h" |
22 | | #include "clang/AST/DeclTemplate.h" |
23 | | #include "clang/AST/DependenceFlags.h" |
24 | | #include "clang/AST/Expr.h" |
25 | | #include "clang/AST/NestedNameSpecifier.h" |
26 | | #include "clang/AST/NonTrivialTypeVisitor.h" |
27 | | #include "clang/AST/PrettyPrinter.h" |
28 | | #include "clang/AST/TemplateBase.h" |
29 | | #include "clang/AST/TemplateName.h" |
30 | | #include "clang/AST/TypeVisitor.h" |
31 | | #include "clang/Basic/AddressSpaces.h" |
32 | | #include "clang/Basic/ExceptionSpecificationType.h" |
33 | | #include "clang/Basic/IdentifierTable.h" |
34 | | #include "clang/Basic/LLVM.h" |
35 | | #include "clang/Basic/LangOptions.h" |
36 | | #include "clang/Basic/Linkage.h" |
37 | | #include "clang/Basic/Specifiers.h" |
38 | | #include "clang/Basic/TargetCXXABI.h" |
39 | | #include "clang/Basic/TargetInfo.h" |
40 | | #include "clang/Basic/Visibility.h" |
41 | | #include "llvm/ADT/APInt.h" |
42 | | #include "llvm/ADT/APSInt.h" |
43 | | #include "llvm/ADT/ArrayRef.h" |
44 | | #include "llvm/ADT/FoldingSet.h" |
45 | | #include "llvm/ADT/None.h" |
46 | | #include "llvm/ADT/SmallVector.h" |
47 | | #include "llvm/Support/Casting.h" |
48 | | #include "llvm/Support/ErrorHandling.h" |
49 | | #include "llvm/Support/MathExtras.h" |
50 | | #include <algorithm> |
51 | | #include <cassert> |
52 | | #include <cstdint> |
53 | | #include <cstring> |
54 | | #include <type_traits> |
55 | | |
56 | | using namespace clang; |
57 | | |
58 | 5.11k | bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const { |
59 | 5.11k | return (*this != Other) && |
60 | | // CVR qualifiers superset |
61 | 5.11k | (((Mask & CVRMask) | (Other.Mask & CVRMask)) == (Mask & CVRMask))140 && |
62 | | // ObjC GC qualifiers superset |
63 | 5.11k | (94 (getObjCGCAttr() == Other.getObjCGCAttr())94 || |
64 | 94 | (0 hasObjCGCAttr()0 && !Other.hasObjCGCAttr()0 )) && |
65 | | // Address space superset. |
66 | 5.11k | (94 (getAddressSpace() == Other.getAddressSpace())94 || |
67 | 94 | (4 hasAddressSpace()4 && !Other.hasAddressSpace()2 )) && |
68 | | // Lifetime qualifier superset. |
69 | 5.11k | (92 (getObjCLifetime() == Other.getObjCLifetime())92 || |
70 | 92 | (36 hasObjCLifetime()36 && !Other.hasObjCLifetime()22 )); |
71 | 5.11k | } |
72 | | |
73 | 11.7k | const IdentifierInfo* QualType::getBaseTypeIdentifier() const { |
74 | 11.7k | const Type* ty = getTypePtr(); |
75 | 11.7k | NamedDecl *ND = nullptr; |
76 | 11.7k | if (ty->isPointerType() || ty->isReferenceType()) |
77 | 0 | return ty->getPointeeType().getBaseTypeIdentifier(); |
78 | 11.7k | else if (ty->isRecordType()) |
79 | 11.5k | ND = ty->castAs<RecordType>()->getDecl(); |
80 | 223 | else if (ty->isEnumeralType()) |
81 | 14 | ND = ty->castAs<EnumType>()->getDecl(); |
82 | 209 | else if (ty->getTypeClass() == Type::Typedef) |
83 | 17 | ND = ty->castAs<TypedefType>()->getDecl(); |
84 | 192 | else if (ty->isArrayType()) |
85 | 0 | return ty->castAsArrayTypeUnsafe()-> |
86 | 0 | getElementType().getBaseTypeIdentifier(); |
87 | | |
88 | 11.7k | if (ND) |
89 | 11.5k | return ND->getIdentifier(); |
90 | 192 | return nullptr; |
91 | 11.7k | } |
92 | | |
93 | 37 | bool QualType::mayBeDynamicClass() const { |
94 | 37 | const auto *ClassDecl = getTypePtr()->getPointeeCXXRecordDecl(); |
95 | 37 | return ClassDecl && ClassDecl->mayBeDynamicClass()26 ; |
96 | 37 | } |
97 | | |
98 | 18 | bool QualType::mayBeNotDynamicClass() const { |
99 | 18 | const auto *ClassDecl = getTypePtr()->getPointeeCXXRecordDecl(); |
100 | 18 | return !ClassDecl || ClassDecl->mayBeNonDynamicClass()13 ; |
101 | 18 | } |
102 | | |
103 | 26.9M | bool QualType::isConstant(QualType T, const ASTContext &Ctx) { |
104 | 26.9M | if (T.isConstQualified()) |
105 | 9.42M | return true; |
106 | | |
107 | 17.5M | if (const ArrayType *AT = Ctx.getAsArrayType(T)) |
108 | 368k | return AT->getElementType().isConstant(Ctx); |
109 | | |
110 | 17.1M | return T.getAddressSpace() == LangAS::opencl_constant; |
111 | 17.5M | } |
112 | | |
113 | | // C++ [temp.dep.type]p1: |
114 | | // A type is dependent if it is... |
115 | | // - an array type constructed from any dependent type or whose |
116 | | // size is specified by a constant expression that is |
117 | | // value-dependent, |
118 | | ArrayType::ArrayType(TypeClass tc, QualType et, QualType can, |
119 | | ArraySizeModifier sm, unsigned tq, const Expr *sz) |
120 | | // Note, we need to check for DependentSizedArrayType explicitly here |
121 | | // because we use a DependentSizedArrayType with no size expression as the |
122 | | // type of a dependent array of unknown bound with a dependent braced |
123 | | // initializer: |
124 | | // |
125 | | // template<int ...N> int arr[] = {N...}; |
126 | | : Type(tc, can, |
127 | | et->getDependence() | |
128 | | (sz ? toTypeDependence( |
129 | | turnValueToTypeDependence(sz->getDependence())) |
130 | | : TypeDependence::None) | |
131 | | (tc == VariableArray ? TypeDependence::VariablyModified |
132 | | : TypeDependence::None) | |
133 | | (tc == DependentSizedArray |
134 | | ? TypeDependence::DependentInstantiation |
135 | | : TypeDependence::None)), |
136 | 645k | ElementType(et) { |
137 | 645k | ArrayTypeBits.IndexTypeQuals = tq; |
138 | 645k | ArrayTypeBits.SizeModifier = sm; |
139 | 645k | } |
140 | | |
141 | | unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context, |
142 | | QualType ElementType, |
143 | 258k | const llvm::APInt &NumElements) { |
144 | 258k | uint64_t ElementSize = Context.getTypeSizeInChars(ElementType).getQuantity(); |
145 | | |
146 | | // Fast path the common cases so we can avoid the conservative computation |
147 | | // below, which in common cases allocates "large" APSInt values, which are |
148 | | // slow. |
149 | | |
150 | | // If the element size is a power of 2, we can directly compute the additional |
151 | | // number of addressing bits beyond those required for the element count. |
152 | 258k | if (llvm::isPowerOf2_64(ElementSize)) { |
153 | 245k | return NumElements.getActiveBits() + llvm::Log2_64(ElementSize); |
154 | 245k | } |
155 | | |
156 | | // If both the element count and element size fit in 32-bits, we can do the |
157 | | // computation directly in 64-bits. |
158 | 12.8k | if ((ElementSize >> 32) == 0 && NumElements.getBitWidth() <= 6412.8k && |
159 | 12.8k | (NumElements.getZExtValue() >> 32) == 012.8k ) { |
160 | 12.8k | uint64_t TotalSize = NumElements.getZExtValue() * ElementSize; |
161 | 12.8k | return 64 - llvm::countLeadingZeros(TotalSize); |
162 | 12.8k | } |
163 | | |
164 | | // Otherwise, use APSInt to handle arbitrary sized values. |
165 | 2 | llvm::APSInt SizeExtended(NumElements, true); |
166 | 2 | unsigned SizeTypeBits = Context.getTypeSize(Context.getSizeType()); |
167 | 2 | SizeExtended = SizeExtended.extend(std::max(SizeTypeBits, |
168 | 2 | SizeExtended.getBitWidth()) * 2); |
169 | | |
170 | 2 | llvm::APSInt TotalSize(llvm::APInt(SizeExtended.getBitWidth(), ElementSize)); |
171 | 2 | TotalSize *= SizeExtended; |
172 | | |
173 | 2 | return TotalSize.getActiveBits(); |
174 | 12.8k | } |
175 | | |
176 | 330k | unsigned ConstantArrayType::getMaxSizeBits(const ASTContext &Context) { |
177 | 330k | unsigned Bits = Context.getTypeSize(Context.getSizeType()); |
178 | | |
179 | | // Limit the number of bits in size_t so that maximal bit size fits 64 bit |
180 | | // integer (see PR8256). We can do this as currently there is no hardware |
181 | | // that supports full 64-bit virtual space. |
182 | 330k | if (Bits > 61) |
183 | 313k | Bits = 61; |
184 | | |
185 | 330k | return Bits; |
186 | 330k | } |
187 | | |
188 | | void ConstantArrayType::Profile(llvm::FoldingSetNodeID &ID, |
189 | | const ASTContext &Context, QualType ET, |
190 | | const llvm::APInt &ArraySize, |
191 | | const Expr *SizeExpr, ArraySizeModifier SizeMod, |
192 | 14.1M | unsigned TypeQuals) { |
193 | 14.1M | ID.AddPointer(ET.getAsOpaquePtr()); |
194 | 14.1M | ID.AddInteger(ArraySize.getZExtValue()); |
195 | 14.1M | ID.AddInteger(SizeMod); |
196 | 14.1M | ID.AddInteger(TypeQuals); |
197 | 14.1M | ID.AddBoolean(SizeExpr != nullptr); |
198 | 14.1M | if (SizeExpr) |
199 | 258 | SizeExpr->Profile(ID, Context, true); |
200 | 14.1M | } |
201 | | |
202 | | DependentSizedArrayType::DependentSizedArrayType(const ASTContext &Context, |
203 | | QualType et, QualType can, |
204 | | Expr *e, ArraySizeModifier sm, |
205 | | unsigned tq, |
206 | | SourceRange brackets) |
207 | | : ArrayType(DependentSizedArray, et, can, sm, tq, e), |
208 | 33.9k | Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {} |
209 | | |
210 | | void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID, |
211 | | const ASTContext &Context, |
212 | | QualType ET, |
213 | | ArraySizeModifier SizeMod, |
214 | | unsigned TypeQuals, |
215 | 41.6k | Expr *E) { |
216 | 41.6k | ID.AddPointer(ET.getAsOpaquePtr()); |
217 | 41.6k | ID.AddInteger(SizeMod); |
218 | 41.6k | ID.AddInteger(TypeQuals); |
219 | 41.6k | E->Profile(ID, Context, true); |
220 | 41.6k | } |
221 | | |
222 | | DependentVectorType::DependentVectorType(const ASTContext &Context, |
223 | | QualType ElementType, |
224 | | QualType CanonType, Expr *SizeExpr, |
225 | | SourceLocation Loc, |
226 | | VectorType::VectorKind VecKind) |
227 | | : Type(DependentVector, CanonType, |
228 | | TypeDependence::DependentInstantiation | |
229 | | ElementType->getDependence() | |
230 | | (SizeExpr ? toTypeDependence(SizeExpr->getDependence()) |
231 | | : TypeDependence::None)), |
232 | 85 | Context(Context), ElementType(ElementType), SizeExpr(SizeExpr), Loc(Loc) { |
233 | 85 | VectorTypeBits.VecKind = VecKind; |
234 | 85 | } |
235 | | |
236 | | void DependentVectorType::Profile(llvm::FoldingSetNodeID &ID, |
237 | | const ASTContext &Context, |
238 | | QualType ElementType, const Expr *SizeExpr, |
239 | 96 | VectorType::VectorKind VecKind) { |
240 | 96 | ID.AddPointer(ElementType.getAsOpaquePtr()); |
241 | 96 | ID.AddInteger(VecKind); |
242 | 96 | SizeExpr->Profile(ID, Context, true); |
243 | 96 | } |
244 | | |
245 | | DependentSizedExtVectorType::DependentSizedExtVectorType( |
246 | | const ASTContext &Context, QualType ElementType, QualType can, |
247 | | Expr *SizeExpr, SourceLocation loc) |
248 | | : Type(DependentSizedExtVector, can, |
249 | | TypeDependence::DependentInstantiation | |
250 | | ElementType->getDependence() | |
251 | | (SizeExpr ? toTypeDependence(SizeExpr->getDependence()) |
252 | | : TypeDependence::None)), |
253 | 104 | Context(Context), SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) { |
254 | 104 | } |
255 | | |
256 | | void |
257 | | DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, |
258 | | const ASTContext &Context, |
259 | 112 | QualType ElementType, Expr *SizeExpr) { |
260 | 112 | ID.AddPointer(ElementType.getAsOpaquePtr()); |
261 | 112 | SizeExpr->Profile(ID, Context, true); |
262 | 112 | } |
263 | | |
264 | | DependentAddressSpaceType::DependentAddressSpaceType(const ASTContext &Context, |
265 | | QualType PointeeType, |
266 | | QualType can, |
267 | | Expr *AddrSpaceExpr, |
268 | | SourceLocation loc) |
269 | | : Type(DependentAddressSpace, can, |
270 | | TypeDependence::DependentInstantiation | |
271 | | PointeeType->getDependence() | |
272 | | (AddrSpaceExpr ? toTypeDependence(AddrSpaceExpr->getDependence()) |
273 | | : TypeDependence::None)), |
274 | | Context(Context), AddrSpaceExpr(AddrSpaceExpr), PointeeType(PointeeType), |
275 | 88 | loc(loc) {} |
276 | | |
277 | | void DependentAddressSpaceType::Profile(llvm::FoldingSetNodeID &ID, |
278 | | const ASTContext &Context, |
279 | | QualType PointeeType, |
280 | 71 | Expr *AddrSpaceExpr) { |
281 | 71 | ID.AddPointer(PointeeType.getAsOpaquePtr()); |
282 | 71 | AddrSpaceExpr->Profile(ID, Context, true); |
283 | 71 | } |
284 | | |
285 | | MatrixType::MatrixType(TypeClass tc, QualType matrixType, QualType canonType, |
286 | | const Expr *RowExpr, const Expr *ColumnExpr) |
287 | | : Type(tc, canonType, |
288 | | (RowExpr ? (matrixType->getDependence() | TypeDependence::Dependent | |
289 | | TypeDependence::Instantiation | |
290 | | (matrixType->isVariablyModifiedType() |
291 | | ? TypeDependence::VariablyModified |
292 | | : TypeDependence::None) | |
293 | | (matrixType->containsUnexpandedParameterPack() || |
294 | | (RowExpr && |
295 | | RowExpr->containsUnexpandedParameterPack()) || |
296 | | (ColumnExpr && |
297 | | ColumnExpr->containsUnexpandedParameterPack()) |
298 | | ? TypeDependence::UnexpandedPack |
299 | | : TypeDependence::None)) |
300 | | : matrixType->getDependence())), |
301 | 492 | ElementType(matrixType) {} |
302 | | |
303 | | ConstantMatrixType::ConstantMatrixType(QualType matrixType, unsigned nRows, |
304 | | unsigned nColumns, QualType canonType) |
305 | | : ConstantMatrixType(ConstantMatrix, matrixType, nRows, nColumns, |
306 | 363 | canonType) {} Unexecuted instantiation: clang::ConstantMatrixType::ConstantMatrixType(clang::QualType, unsigned int, unsigned int, clang::QualType) clang::ConstantMatrixType::ConstantMatrixType(clang::QualType, unsigned int, unsigned int, clang::QualType) Line | Count | Source | 306 | 363 | canonType) {} |
|
307 | | |
308 | | ConstantMatrixType::ConstantMatrixType(TypeClass tc, QualType matrixType, |
309 | | unsigned nRows, unsigned nColumns, |
310 | | QualType canonType) |
311 | | : MatrixType(tc, matrixType, canonType), NumRows(nRows), |
312 | 363 | NumColumns(nColumns) {} |
313 | | |
314 | | DependentSizedMatrixType::DependentSizedMatrixType( |
315 | | const ASTContext &CTX, QualType ElementType, QualType CanonicalType, |
316 | | Expr *RowExpr, Expr *ColumnExpr, SourceLocation loc) |
317 | | : MatrixType(DependentSizedMatrix, ElementType, CanonicalType, RowExpr, |
318 | | ColumnExpr), |
319 | 129 | Context(CTX), RowExpr(RowExpr), ColumnExpr(ColumnExpr), loc(loc) {} |
320 | | |
321 | | void DependentSizedMatrixType::Profile(llvm::FoldingSetNodeID &ID, |
322 | | const ASTContext &CTX, |
323 | | QualType ElementType, Expr *RowExpr, |
324 | 109 | Expr *ColumnExpr) { |
325 | 109 | ID.AddPointer(ElementType.getAsOpaquePtr()); |
326 | 109 | RowExpr->Profile(ID, CTX, true); |
327 | 109 | ColumnExpr->Profile(ID, CTX, true); |
328 | 109 | } |
329 | | |
330 | | VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType, |
331 | | VectorKind vecKind) |
332 | 49.4k | : VectorType(Vector, vecType, nElements, canonType, vecKind) {} Unexecuted instantiation: clang::VectorType::VectorType(clang::QualType, unsigned int, clang::QualType, clang::VectorType::VectorKind) clang::VectorType::VectorType(clang::QualType, unsigned int, clang::QualType, clang::VectorType::VectorKind) Line | Count | Source | 332 | 49.4k | : VectorType(Vector, vecType, nElements, canonType, vecKind) {} |
|
333 | | |
334 | | VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements, |
335 | | QualType canonType, VectorKind vecKind) |
336 | 56.3k | : Type(tc, canonType, vecType->getDependence()), ElementType(vecType) { |
337 | 56.3k | VectorTypeBits.VecKind = vecKind; |
338 | 56.3k | VectorTypeBits.NumElements = nElements; |
339 | 56.3k | } |
340 | | |
341 | | BitIntType::BitIntType(bool IsUnsigned, unsigned NumBits) |
342 | | : Type(BitInt, QualType{}, TypeDependence::None), IsUnsigned(IsUnsigned), |
343 | 561 | NumBits(NumBits) {} |
344 | | |
345 | | DependentBitIntType::DependentBitIntType(const ASTContext &Context, |
346 | | bool IsUnsigned, Expr *NumBitsExpr) |
347 | | : Type(DependentBitInt, QualType{}, |
348 | | toTypeDependence(NumBitsExpr->getDependence())), |
349 | 14 | Context(Context), ExprAndUnsigned(NumBitsExpr, IsUnsigned) {} |
350 | | |
351 | 168 | bool DependentBitIntType::isUnsigned() const { |
352 | 168 | return ExprAndUnsigned.getInt(); |
353 | 168 | } |
354 | | |
355 | 201 | clang::Expr *DependentBitIntType::getNumBitsExpr() const { |
356 | 201 | return ExprAndUnsigned.getPointer(); |
357 | 201 | } |
358 | | |
359 | | void DependentBitIntType::Profile(llvm::FoldingSetNodeID &ID, |
360 | | const ASTContext &Context, bool IsUnsigned, |
361 | 28 | Expr *NumBitsExpr) { |
362 | 28 | ID.AddBoolean(IsUnsigned); |
363 | 28 | NumBitsExpr->Profile(ID, Context, true); |
364 | 28 | } |
365 | | |
366 | | /// getArrayElementTypeNoTypeQual - If this is an array type, return the |
367 | | /// element type of the array, potentially with type qualifiers missing. |
368 | | /// This method should never be used when type qualifiers are meaningful. |
369 | 2.82k | const Type *Type::getArrayElementTypeNoTypeQual() const { |
370 | | // If this is directly an array type, return it. |
371 | 2.82k | if (const auto *ATy = dyn_cast<ArrayType>(this)) |
372 | 1.26k | return ATy->getElementType().getTypePtr(); |
373 | | |
374 | | // If the canonical form of this type isn't the right kind, reject it. |
375 | 1.56k | if (!isa<ArrayType>(CanonicalType)) |
376 | 1.53k | return nullptr; |
377 | | |
378 | | // If this is a typedef for an array type, strip the typedef off without |
379 | | // losing all typedef information. |
380 | 33 | return cast<ArrayType>(getUnqualifiedDesugaredType()) |
381 | 33 | ->getElementType().getTypePtr(); |
382 | 1.56k | } |
383 | | |
384 | | /// getDesugaredType - Return the specified type with any "sugar" removed from |
385 | | /// the type. This takes off typedefs, typeof's etc. If the outer level of |
386 | | /// the type is already concrete, it returns it unmodified. This is similar |
387 | | /// to getting the canonical type, but it doesn't remove *all* typedefs. For |
388 | | /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is |
389 | | /// concrete. |
390 | 1.67M | QualType QualType::getDesugaredType(QualType T, const ASTContext &Context) { |
391 | 1.67M | SplitQualType split = getSplitDesugaredType(T); |
392 | 1.67M | return Context.getQualifiedType(split.Ty, split.Quals); |
393 | 1.67M | } |
394 | | |
395 | | QualType QualType::getSingleStepDesugaredTypeImpl(QualType type, |
396 | 1.48k | const ASTContext &Context) { |
397 | 1.48k | SplitQualType split = type.split(); |
398 | 1.48k | QualType desugar = split.Ty->getLocallyUnqualifiedSingleStepDesugaredType(); |
399 | 1.48k | return Context.getQualifiedType(desugar, split.Quals); |
400 | 1.48k | } |
401 | | |
402 | | // Check that no type class is polymorphic. LLVM style RTTI should be used |
403 | | // instead. If absolutely needed an exception can still be added here by |
404 | | // defining the appropriate macro (but please don't do this). |
405 | | #define TYPE(CLASS, BASE) \ |
406 | | static_assert(!std::is_polymorphic<CLASS##Type>::value, \ |
407 | | #CLASS "Type should not be polymorphic!"); |
408 | | #include "clang/AST/TypeNodes.inc" |
409 | | |
410 | | // Check that no type class has a non-trival destructor. Types are |
411 | | // allocated with the BumpPtrAllocator from ASTContext and therefore |
412 | | // their destructor is not executed. |
413 | | // |
414 | | // FIXME: ConstantArrayType is not trivially destructible because of its |
415 | | // APInt member. It should be replaced in favor of ASTContext allocation. |
416 | | #define TYPE(CLASS, BASE) \ |
417 | | static_assert(std::is_trivially_destructible<CLASS##Type>::value || \ |
418 | | std::is_same<CLASS##Type, ConstantArrayType>::value, \ |
419 | | #CLASS "Type should be trivially destructible!"); |
420 | | #include "clang/AST/TypeNodes.inc" |
421 | | |
422 | 2.78M | QualType Type::getLocallyUnqualifiedSingleStepDesugaredType() const { |
423 | 2.78M | switch (getTypeClass()) { |
424 | 0 | #define ABSTRACT_TYPE(Class, Parent) |
425 | 0 | #define TYPE(Class, Parent) \ |
426 | 743k | case Type::Class: { \ |
427 | 743k | const auto *ty = cast<Class##Type>(this); \ |
428 | 2.78M | if (!ty->isSugared()) return QualType(ty, 0)2.04M ; \ |
429 | 743k | return ty->desugar(); \ |
430 | 743k | } |
431 | 2.78M | #include "clang/AST/TypeNodes.inc"0 |
432 | 2.78M | } |
433 | 0 | llvm_unreachable("bad type kind!"); |
434 | 0 | } |
435 | | |
436 | 57.1M | SplitQualType QualType::getSplitDesugaredType(QualType T) { |
437 | 57.1M | QualifierCollector Qs; |
438 | | |
439 | 57.1M | QualType Cur = T; |
440 | 125M | while (true) { |
441 | 125M | const Type *CurTy = Qs.strip(Cur); |
442 | 125M | switch (CurTy->getTypeClass()) { |
443 | 0 | #define ABSTRACT_TYPE(Class, Parent) |
444 | 0 | #define TYPE(Class, Parent) \ |
445 | 68.4M | case Type::Class: { \ |
446 | 68.4M | const auto *Ty = cast<Class##Type>(CurTy); \ |
447 | 125M | if (!Ty->isSugared()) \ |
448 | 68.4M | return SplitQualType(Ty, Qs)57.1M ; \ |
449 | 68.4M | Cur = Ty->desugar(); \ |
450 | 68.4M | break; \ |
451 | 68.4M | } |
452 | 125M | #include "clang/AST/TypeNodes.inc"0 |
453 | 125M | } |
454 | 125M | } |
455 | 57.1M | } |
456 | | |
457 | 32.1k | SplitQualType QualType::getSplitUnqualifiedTypeImpl(QualType type) { |
458 | 32.1k | SplitQualType split = type.split(); |
459 | | |
460 | | // All the qualifiers we've seen so far. |
461 | 32.1k | Qualifiers quals = split.Quals; |
462 | | |
463 | | // The last type node we saw with any nodes inside it. |
464 | 32.1k | const Type *lastTypeWithQuals = split.Ty; |
465 | | |
466 | 54.7k | while (true) { |
467 | 54.7k | QualType next; |
468 | | |
469 | | // Do a single-step desugar, aborting the loop if the type isn't |
470 | | // sugared. |
471 | 54.7k | switch (split.Ty->getTypeClass()) { |
472 | 0 | #define ABSTRACT_TYPE(Class, Parent) |
473 | 0 | #define TYPE(Class, Parent) \ |
474 | 22.6k | case Type::Class: { \ |
475 | 22.6k | const auto *ty = cast<Class##Type>(split.Ty); \ |
476 | 54.7k | if (!ty->isSugared()) goto done32.1k ; \ |
477 | 22.6k | next = ty->desugar(); \ |
478 | 22.6k | break; \ |
479 | 22.6k | } |
480 | 54.7k | #include "clang/AST/TypeNodes.inc"0 |
481 | 54.7k | } |
482 | | |
483 | | // Otherwise, split the underlying type. If that yields qualifiers, |
484 | | // update the information. |
485 | 22.6k | split = next.split(); |
486 | 22.6k | if (!split.Quals.empty()) { |
487 | 12.2k | lastTypeWithQuals = split.Ty; |
488 | 12.2k | quals.addConsistentQualifiers(split.Quals); |
489 | 12.2k | } |
490 | 22.6k | } |
491 | | |
492 | 32.1k | done: |
493 | 32.1k | return SplitQualType(lastTypeWithQuals, quals); |
494 | 32.1k | } |
495 | | |
496 | 34 | QualType QualType::IgnoreParens(QualType T) { |
497 | | // FIXME: this seems inherently un-qualifiers-safe. |
498 | 68 | while (const auto *PT = T->getAs<ParenType>()) |
499 | 34 | T = PT->getInnerType(); |
500 | 34 | return T; |
501 | 34 | } |
502 | | |
503 | | /// This will check for a T (which should be a Type which can act as |
504 | | /// sugar, such as a TypedefType) by removing any existing sugar until it |
505 | | /// reaches a T or a non-sugared type. |
506 | 53.2M | template<typename T> static const T *getAsSugar(const Type *Cur) { |
507 | 70.2M | while (true) { |
508 | 70.2M | if (const auto *Sugar = dyn_cast<T>(Cur)) |
509 | 5.85M | return Sugar; |
510 | 64.3M | switch (Cur->getTypeClass()) { |
511 | 0 | #define ABSTRACT_TYPE(Class, Parent) |
512 | 0 | #define TYPE(Class, Parent) \ |
513 | 16.9M | case Type::Class: { \ |
514 | 16.9M | const auto *Ty = cast<Class##Type>(Cur); \ |
515 | 64.3M | if (!Ty->isSugared()) return 047.4M ; \ |
516 | 16.9M | Cur = Ty->desugar().getTypePtr(); \ |
517 | 16.9M | break; \ |
518 | 16.9M | } |
519 | 64.3M | #include "clang/AST/TypeNodes.inc"0 |
520 | 64.3M | } |
521 | 64.3M | } |
522 | 53.2M | } Type.cpp:clang::TypedefType const* getAsSugar<clang::TypedefType>(clang::Type const*) Line | Count | Source | 506 | 9.60M | template<typename T> static const T *getAsSugar(const Type *Cur) { | 507 | 9.86M | while (true) { | 508 | 9.86M | if (const auto *Sugar = dyn_cast<T>(Cur)) | 509 | 3.89M | return Sugar; | 510 | 5.97M | switch (Cur->getTypeClass()) { | 511 | 0 | #define ABSTRACT_TYPE(Class, Parent) | 512 | 0 | #define TYPE(Class, Parent) \ | 513 | 0 | case Type::Class: { \ | 514 | 0 | const auto *Ty = cast<Class##Type>(Cur); \ | 515 | 0 | if (!Ty->isSugared()) return 0; \ | 516 | 0 | Cur = Ty->desugar().getTypePtr(); \ | 517 | 0 | break; \ | 518 | 0 | } | 519 | 0 | #include "clang/AST/TypeNodes.inc" | 520 | 5.97M | } | 521 | 5.97M | } | 522 | 9.60M | } |
Type.cpp:clang::TemplateSpecializationType const* getAsSugar<clang::TemplateSpecializationType>(clang::Type const*) Line | Count | Source | 506 | 1.84M | template<typename T> static const T *getAsSugar(const Type *Cur) { | 507 | 1.89M | while (true) { | 508 | 1.89M | if (const auto *Sugar = dyn_cast<T>(Cur)) | 509 | 1.26M | return Sugar; | 510 | 629k | switch (Cur->getTypeClass()) { | 511 | 0 | #define ABSTRACT_TYPE(Class, Parent) | 512 | 0 | #define TYPE(Class, Parent) \ | 513 | 0 | case Type::Class: { \ | 514 | 0 | const auto *Ty = cast<Class##Type>(Cur); \ | 515 | 0 | if (!Ty->isSugared()) return 0; \ | 516 | 0 | Cur = Ty->desugar().getTypePtr(); \ | 517 | 0 | break; \ | 518 | 0 | } | 519 | 0 | #include "clang/AST/TypeNodes.inc" | 520 | 629k | } | 521 | 629k | } | 522 | 1.84M | } |
Type.cpp:clang::AttributedType const* getAsSugar<clang::AttributedType>(clang::Type const*) Line | Count | Source | 506 | 41.8M | template<typename T> static const T *getAsSugar(const Type *Cur) { | 507 | 58.4M | while (true) { | 508 | 58.4M | if (const auto *Sugar = dyn_cast<T>(Cur)) | 509 | 696k | return Sugar; | 510 | 57.7M | switch (Cur->getTypeClass()) { | 511 | 0 | #define ABSTRACT_TYPE(Class, Parent) | 512 | 0 | #define TYPE(Class, Parent) \ | 513 | 0 | case Type::Class: { \ | 514 | 0 | const auto *Ty = cast<Class##Type>(Cur); \ | 515 | 0 | if (!Ty->isSugared()) return 0; \ | 516 | 0 | Cur = Ty->desugar().getTypePtr(); \ | 517 | 0 | break; \ | 518 | 0 | } | 519 | 0 | #include "clang/AST/TypeNodes.inc" | 520 | 57.7M | } | 521 | 57.7M | } | 522 | 41.8M | } |
|
523 | | |
524 | 9.60M | template <> const TypedefType *Type::getAs() const { |
525 | 9.60M | return getAsSugar<TypedefType>(this); |
526 | 9.60M | } |
527 | | |
528 | 1.84M | template <> const TemplateSpecializationType *Type::getAs() const { |
529 | 1.84M | return getAsSugar<TemplateSpecializationType>(this); |
530 | 1.84M | } |
531 | | |
532 | 41.8M | template <> const AttributedType *Type::getAs() const { |
533 | 41.8M | return getAsSugar<AttributedType>(this); |
534 | 41.8M | } |
535 | | |
536 | | /// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic |
537 | | /// sugar off the given type. This should produce an object of the |
538 | | /// same dynamic type as the canonical type. |
539 | 66.6M | const Type *Type::getUnqualifiedDesugaredType() const { |
540 | 66.6M | const Type *Cur = this; |
541 | | |
542 | 121M | while (true) { |
543 | 121M | switch (Cur->getTypeClass()) { |
544 | 0 | #define ABSTRACT_TYPE(Class, Parent) |
545 | 0 | #define TYPE(Class, Parent) \ |
546 | 54.4M | case Class: { \ |
547 | 54.4M | const auto *Ty = cast<Class##Type>(Cur); \ |
548 | 121M | if (!Ty->isSugared()) return Cur66.6M ; \ |
549 | 54.4M | Cur = Ty->desugar().getTypePtr(); \ |
550 | 54.4M | break; \ |
551 | 54.4M | } |
552 | 121M | #include "clang/AST/TypeNodes.inc"0 |
553 | 121M | } |
554 | 121M | } |
555 | 66.6M | } |
556 | | |
557 | 2.43k | bool Type::isClassType() const { |
558 | 2.43k | if (const auto *RT = getAs<RecordType>()) |
559 | 81 | return RT->getDecl()->isClass(); |
560 | 2.35k | return false; |
561 | 2.43k | } |
562 | | |
563 | 2.66M | bool Type::isStructureType() const { |
564 | 2.66M | if (const auto *RT = getAs<RecordType>()) |
565 | 159k | return RT->getDecl()->isStruct(); |
566 | 2.50M | return false; |
567 | 2.66M | } |
568 | | |
569 | 1.00k | bool Type::isObjCBoxableRecordType() const { |
570 | 1.00k | if (const auto *RT = getAs<RecordType>()) |
571 | 141 | return RT->getDecl()->hasAttr<ObjCBoxableAttr>(); |
572 | 863 | return false; |
573 | 1.00k | } |
574 | | |
575 | 121 | bool Type::isInterfaceType() const { |
576 | 121 | if (const auto *RT = getAs<RecordType>()) |
577 | 3 | return RT->getDecl()->isInterface(); |
578 | 118 | return false; |
579 | 121 | } |
580 | | |
581 | 996k | bool Type::isStructureOrClassType() const { |
582 | 996k | if (const auto *RT = getAs<RecordType>()) { |
583 | 130k | RecordDecl *RD = RT->getDecl(); |
584 | 130k | return RD->isStruct() || RD->isClass()28.2k || RD->isInterface()388 ; |
585 | 130k | } |
586 | 866k | return false; |
587 | 996k | } |
588 | | |
589 | 446k | bool Type::isVoidPointerType() const { |
590 | 446k | if (const auto *PT = getAs<PointerType>()) |
591 | 440k | return PT->getPointeeType()->isVoidType(); |
592 | 6.29k | return false; |
593 | 446k | } |
594 | | |
595 | 1.46M | bool Type::isUnionType() const { |
596 | 1.46M | if (const auto *RT = getAs<RecordType>()) |
597 | 598k | return RT->getDecl()->isUnion(); |
598 | 871k | return false; |
599 | 1.46M | } |
600 | | |
601 | 1.07M | bool Type::isComplexType() const { |
602 | 1.07M | if (const auto *CT = dyn_cast<ComplexType>(CanonicalType)) |
603 | 1.88k | return CT->getElementType()->isFloatingType(); |
604 | 1.07M | return false; |
605 | 1.07M | } |
606 | | |
607 | 1.04M | bool Type::isComplexIntegerType() const { |
608 | | // Check for GCC complex integer extension. |
609 | 1.04M | return getAsComplexIntegerType(); |
610 | 1.04M | } |
611 | | |
612 | 42 | bool Type::isScopedEnumeralType() const { |
613 | 42 | if (const auto *ET = getAs<EnumType>()) |
614 | 31 | return ET->getDecl()->isScoped(); |
615 | 11 | return false; |
616 | 42 | } |
617 | | |
618 | 1.04M | const ComplexType *Type::getAsComplexIntegerType() const { |
619 | 1.04M | if (const auto *Complex = getAs<ComplexType>()) |
620 | 516 | if (Complex->getElementType()->isIntegerType()) |
621 | 434 | return Complex; |
622 | 1.04M | return nullptr; |
623 | 1.04M | } |
624 | | |
625 | 12.9M | QualType Type::getPointeeType() const { |
626 | 12.9M | if (const auto *PT = getAs<PointerType>()) |
627 | 10.7M | return PT->getPointeeType(); |
628 | 2.21M | if (const auto *OPT = getAs<ObjCObjectPointerType>()) |
629 | 890k | return OPT->getPointeeType(); |
630 | 1.32M | if (const auto *BPT = getAs<BlockPointerType>()) |
631 | 3.53k | return BPT->getPointeeType(); |
632 | 1.32M | if (const auto *RT = getAs<ReferenceType>()) |
633 | 996k | return RT->getPointeeType(); |
634 | 325k | if (const auto *MPT = getAs<MemberPointerType>()) |
635 | 302 | return MPT->getPointeeType(); |
636 | 325k | if (const auto *DT = getAs<DecayedType>()) |
637 | 0 | return DT->getPointeeType(); |
638 | 325k | return {}; |
639 | 325k | } |
640 | | |
641 | 51.2k | const RecordType *Type::getAsStructureType() const { |
642 | | // If this is directly a structure type, return it. |
643 | 51.2k | if (const auto *RT = dyn_cast<RecordType>(this)) { |
644 | 20.2k | if (RT->getDecl()->isStruct()) |
645 | 19.7k | return RT; |
646 | 20.2k | } |
647 | | |
648 | | // If the canonical form of this type isn't the right kind, reject it. |
649 | 31.5k | if (const auto *RT = dyn_cast<RecordType>(CanonicalType)) { |
650 | 6.07k | if (!RT->getDecl()->isStruct()) |
651 | 802 | return nullptr; |
652 | | |
653 | | // If this is a typedef for a structure type, strip the typedef off without |
654 | | // losing all typedef information. |
655 | 5.26k | return cast<RecordType>(getUnqualifiedDesugaredType()); |
656 | 6.07k | } |
657 | 25.4k | return nullptr; |
658 | 31.5k | } |
659 | | |
660 | 4.45M | const RecordType *Type::getAsUnionType() const { |
661 | | // If this is directly a union type, return it. |
662 | 4.45M | if (const auto *RT = dyn_cast<RecordType>(this)) { |
663 | 18.8k | if (RT->getDecl()->isUnion()) |
664 | 1.12k | return RT; |
665 | 18.8k | } |
666 | | |
667 | | // If the canonical form of this type isn't the right kind, reject it. |
668 | 4.45M | if (const auto *RT = dyn_cast<RecordType>(CanonicalType)) { |
669 | 20.1k | if (!RT->getDecl()->isUnion()) |
670 | 20.0k | return nullptr; |
671 | | |
672 | | // If this is a typedef for a union type, strip the typedef off without |
673 | | // losing all typedef information. |
674 | 146 | return cast<RecordType>(getUnqualifiedDesugaredType()); |
675 | 20.1k | } |
676 | | |
677 | 4.43M | return nullptr; |
678 | 4.45M | } |
679 | | |
680 | | bool Type::isObjCIdOrObjectKindOfType(const ASTContext &ctx, |
681 | 15.0k | const ObjCObjectType *&bound) const { |
682 | 15.0k | bound = nullptr; |
683 | | |
684 | 15.0k | const auto *OPT = getAs<ObjCObjectPointerType>(); |
685 | 15.0k | if (!OPT) |
686 | 27 | return false; |
687 | | |
688 | | // Easy case: id. |
689 | 14.9k | if (OPT->isObjCIdType()) |
690 | 1.91k | return true; |
691 | | |
692 | | // If it's not a __kindof type, reject it now. |
693 | 13.0k | if (!OPT->isKindOfType()) |
694 | 13.0k | return false; |
695 | | |
696 | | // If it's Class or qualified Class, it's not an object type. |
697 | 19 | if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) |
698 | 3 | return false; |
699 | | |
700 | | // Figure out the type bound for the __kindof type. |
701 | 16 | bound = OPT->getObjectType()->stripObjCKindOfTypeAndQuals(ctx) |
702 | 16 | ->getAs<ObjCObjectType>(); |
703 | 16 | return true; |
704 | 19 | } |
705 | | |
706 | 13.3k | bool Type::isObjCClassOrClassKindOfType() const { |
707 | 13.3k | const auto *OPT = getAs<ObjCObjectPointerType>(); |
708 | 13.3k | if (!OPT) |
709 | 2 | return false; |
710 | | |
711 | | // Easy case: Class. |
712 | 13.3k | if (OPT->isObjCClassType()) |
713 | 490 | return true; |
714 | | |
715 | | // If it's not a __kindof type, reject it now. |
716 | 12.8k | if (!OPT->isKindOfType()) |
717 | 12.8k | return false; |
718 | | |
719 | | // If it's Class or qualified Class, it's a class __kindof type. |
720 | 6 | return OPT->isObjCClassType() || OPT->isObjCQualifiedClassType(); |
721 | 12.8k | } |
722 | | |
723 | | ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D, QualType can, |
724 | | ArrayRef<ObjCProtocolDecl *> protocols) |
725 | | : Type(ObjCTypeParam, can, toSemanticDependence(can->getDependence())), |
726 | 70.7k | OTPDecl(const_cast<ObjCTypeParamDecl *>(D)) { |
727 | 70.7k | initialize(protocols); |
728 | 70.7k | } |
729 | | |
730 | | ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, |
731 | | ArrayRef<QualType> typeArgs, |
732 | | ArrayRef<ObjCProtocolDecl *> protocols, |
733 | | bool isKindOf) |
734 | 112k | : Type(ObjCObject, Canonical, Base->getDependence()), BaseType(Base) { |
735 | 112k | ObjCObjectTypeBits.IsKindOf = isKindOf; |
736 | | |
737 | 112k | ObjCObjectTypeBits.NumTypeArgs = typeArgs.size(); |
738 | 112k | assert(getTypeArgsAsWritten().size() == typeArgs.size() && |
739 | 112k | "bitfield overflow in type argument count"); |
740 | 112k | if (!typeArgs.empty()) |
741 | 40.0k | memcpy(getTypeArgStorage(), typeArgs.data(), |
742 | 40.0k | typeArgs.size() * sizeof(QualType)); |
743 | | |
744 | 112k | for (auto typeArg : typeArgs) { |
745 | 48.8k | addDependence(typeArg->getDependence() & ~TypeDependence::VariablyModified); |
746 | 48.8k | } |
747 | | // Initialize the protocol qualifiers. The protocol storage is known |
748 | | // after we set number of type arguments. |
749 | 112k | initialize(protocols); |
750 | 112k | } |
751 | | |
752 | 143k | bool ObjCObjectType::isSpecialized() const { |
753 | | // If we have type arguments written here, the type is specialized. |
754 | 143k | if (ObjCObjectTypeBits.NumTypeArgs > 0) |
755 | 1.95k | return true; |
756 | | |
757 | | // Otherwise, check whether the base type is specialized. |
758 | 141k | if (const auto objcObject = getBaseType()->getAs<ObjCObjectType>()) { |
759 | | // Terminate when we reach an interface type. |
760 | 140k | if (isa<ObjCInterfaceType>(objcObject)) |
761 | 140k | return false; |
762 | | |
763 | 1 | return objcObject->isSpecialized(); |
764 | 140k | } |
765 | | |
766 | | // Not specialized. |
767 | 1.96k | return false; |
768 | 141k | } |
769 | | |
770 | 6.91k | ArrayRef<QualType> ObjCObjectType::getTypeArgs() const { |
771 | | // We have type arguments written on this type. |
772 | 6.91k | if (isSpecializedAsWritten()) |
773 | 948 | return getTypeArgsAsWritten(); |
774 | | |
775 | | // Look at the base type, which might have type arguments. |
776 | 5.96k | if (const auto objcObject = getBaseType()->getAs<ObjCObjectType>()) { |
777 | | // Terminate when we reach an interface type. |
778 | 5.96k | if (isa<ObjCInterfaceType>(objcObject)) |
779 | 5.96k | return {}; |
780 | | |
781 | 0 | return objcObject->getTypeArgs(); |
782 | 5.96k | } |
783 | | |
784 | | // No type arguments. |
785 | 1 | return {}; |
786 | 5.96k | } |
787 | | |
788 | 55.9k | bool ObjCObjectType::isKindOfType() const { |
789 | 55.9k | if (isKindOfTypeAsWritten()) |
790 | 222 | return true; |
791 | | |
792 | | // Look at the base type, which might have type arguments. |
793 | 55.7k | if (const auto objcObject = getBaseType()->getAs<ObjCObjectType>()) { |
794 | | // Terminate when we reach an interface type. |
795 | 33.7k | if (isa<ObjCInterfaceType>(objcObject)) |
796 | 33.7k | return false; |
797 | | |
798 | 0 | return objcObject->isKindOfType(); |
799 | 33.7k | } |
800 | | |
801 | | // Not a "__kindof" type. |
802 | 21.9k | return false; |
803 | 55.7k | } |
804 | | |
805 | | QualType ObjCObjectType::stripObjCKindOfTypeAndQuals( |
806 | 175 | const ASTContext &ctx) const { |
807 | 175 | if (!isKindOfType() && qual_empty()105 ) |
808 | 66 | return QualType(this, 0); |
809 | | |
810 | | // Recursively strip __kindof. |
811 | 109 | SplitQualType splitBaseType = getBaseType().split(); |
812 | 109 | QualType baseType(splitBaseType.Ty, 0); |
813 | 109 | if (const auto *baseObj = splitBaseType.Ty->getAs<ObjCObjectType>()) |
814 | 66 | baseType = baseObj->stripObjCKindOfTypeAndQuals(ctx); |
815 | | |
816 | 109 | return ctx.getObjCObjectType(ctx.getQualifiedType(baseType, |
817 | 109 | splitBaseType.Quals), |
818 | 109 | getTypeArgsAsWritten(), |
819 | 109 | /*protocols=*/{}, |
820 | 109 | /*isKindOf=*/false); |
821 | 175 | } |
822 | | |
823 | 3.80M | ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const { |
824 | 3.80M | ObjCInterfaceDecl *Canon = Decl->getCanonicalDecl(); |
825 | 3.80M | if (ObjCInterfaceDecl *Def = Canon->getDefinition()) |
826 | 3.65M | return Def; |
827 | 150k | return Canon; |
828 | 3.80M | } |
829 | | |
830 | | const ObjCObjectPointerType *ObjCObjectPointerType::stripObjCKindOfTypeAndQuals( |
831 | 2.70k | const ASTContext &ctx) const { |
832 | 2.70k | if (!isKindOfType() && qual_empty()2.65k ) |
833 | 2.61k | return this; |
834 | | |
835 | 93 | QualType obj = getObjectType()->stripObjCKindOfTypeAndQuals(ctx); |
836 | 93 | return ctx.getObjCObjectPointerType(obj)->castAs<ObjCObjectPointerType>(); |
837 | 2.70k | } |
838 | | |
839 | | namespace { |
840 | | |
841 | | /// Visitor used to perform a simple type transformation that does not change |
842 | | /// the semantics of the type. |
843 | | template <typename Derived> |
844 | | struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> { |
845 | | ASTContext &Ctx; |
846 | | |
847 | 20.0k | QualType recurse(QualType type) { |
848 | | // Split out the qualifiers from the type. |
849 | 20.0k | SplitQualType splitType = type.split(); |
850 | | |
851 | | // Visit the type itself. |
852 | 20.0k | QualType result = static_cast<Derived *>(this)->Visit(splitType.Ty); |
853 | 20.0k | if (result.isNull()) |
854 | 0 | return result; |
855 | | |
856 | | // Reconstruct the transformed type by applying the local qualifiers |
857 | | // from the split type. |
858 | 20.0k | return Ctx.getQualifiedType(result, splitType.Quals); |
859 | 20.0k | } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::recurse(clang::QualType) Line | Count | Source | 847 | 19.5k | QualType recurse(QualType type) { | 848 | | // Split out the qualifiers from the type. | 849 | 19.5k | SplitQualType splitType = type.split(); | 850 | | | 851 | | // Visit the type itself. | 852 | 19.5k | QualType result = static_cast<Derived *>(this)->Visit(splitType.Ty); | 853 | 19.5k | if (result.isNull()) | 854 | 0 | return result; | 855 | | | 856 | | // Reconstruct the transformed type by applying the local qualifiers | 857 | | // from the split type. | 858 | 19.5k | return Ctx.getQualifiedType(result, splitType.Quals); | 859 | 19.5k | } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::recurse(clang::QualType) Line | Count | Source | 847 | 484 | QualType recurse(QualType type) { | 848 | | // Split out the qualifiers from the type. | 849 | 484 | SplitQualType splitType = type.split(); | 850 | | | 851 | | // Visit the type itself. | 852 | 484 | QualType result = static_cast<Derived *>(this)->Visit(splitType.Ty); | 853 | 484 | if (result.isNull()) | 854 | 0 | return result; | 855 | | | 856 | | // Reconstruct the transformed type by applying the local qualifiers | 857 | | // from the split type. | 858 | 484 | return Ctx.getQualifiedType(result, splitType.Quals); | 859 | 484 | } |
|
860 | | |
861 | | public: |
862 | 7.96k | explicit SimpleTransformVisitor(ASTContext &ctx) : Ctx(ctx) {} Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::SimpleTransformVisitor(clang::ASTContext&) Line | Count | Source | 862 | 7.74k | explicit SimpleTransformVisitor(ASTContext &ctx) : Ctx(ctx) {} |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::SimpleTransformVisitor(clang::ASTContext&) Line | Count | Source | 862 | 219 | explicit SimpleTransformVisitor(ASTContext &ctx) : Ctx(ctx) {} |
|
863 | | |
864 | | // None of the clients of this transformation can occur where |
865 | | // there are dependent types, so skip dependent types. |
866 | | #define TYPE(Class, Base) |
867 | | #define DEPENDENT_TYPE(Class, Base) \ |
868 | 0 | QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDependentSizedArrayType(clang::DependentSizedArrayType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDependentAddressSpaceType(clang::DependentAddressSpaceType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDependentBitIntType(clang::DependentBitIntType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDependentNameType(clang::DependentNameType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDependentSizedExtVectorType(clang::DependentSizedExtVectorType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDependentTemplateSpecializationType(clang::DependentTemplateSpecializationType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDependentVectorType(clang::DependentVectorType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitInjectedClassNameType(clang::InjectedClassNameType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDependentSizedMatrixType(clang::DependentSizedMatrixType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitPackExpansionType(clang::PackExpansionType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitSubstTemplateTypeParmPackType(clang::SubstTemplateTypeParmPackType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitTemplateTypeParmType(clang::TemplateTypeParmType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitUnresolvedUsingType(clang::UnresolvedUsingType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDependentSizedArrayType(clang::DependentSizedArrayType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDependentAddressSpaceType(clang::DependentAddressSpaceType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDependentBitIntType(clang::DependentBitIntType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDependentNameType(clang::DependentNameType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDependentSizedExtVectorType(clang::DependentSizedExtVectorType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDependentTemplateSpecializationType(clang::DependentTemplateSpecializationType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDependentVectorType(clang::DependentVectorType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitInjectedClassNameType(clang::InjectedClassNameType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDependentSizedMatrixType(clang::DependentSizedMatrixType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitPackExpansionType(clang::PackExpansionType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitSubstTemplateTypeParmPackType(clang::SubstTemplateTypeParmPackType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitTemplateTypeParmType(clang::TemplateTypeParmType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitUnresolvedUsingType(clang::UnresolvedUsingType const*) |
869 | | #include "clang/AST/TypeNodes.inc" |
870 | | |
871 | | #define TRIVIAL_TYPE_CLASS(Class) \ |
872 | 4.00k | QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitBuiltinType(clang::BuiltinType const*) Line | Count | Source | 872 | 3.75k | QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitObjCInterfaceType(clang::ObjCInterfaceType const*) Line | Count | Source | 872 | 28 | QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); } |
Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitEnumType(clang::EnumType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitRecordType(clang::RecordType const*) Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitBuiltinType(clang::BuiltinType const*) Line | Count | Source | 872 | 66 | QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitObjCInterfaceType(clang::ObjCInterfaceType const*) Line | Count | Source | 872 | 154 | QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); } |
Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitEnumType(clang::EnumType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitRecordType(clang::RecordType const*) |
873 | | #define SUGARED_TYPE_CLASS(Class) \ |
874 | 1.99k | QualType Visit##Class##Type(const Class##Type *T) { \ |
875 | 1.99k | if (!T->isSugared()) \ |
876 | 1.99k | return QualType(T, 0)0 ; \ |
877 | 1.99k | QualType desugaredType = recurse(T->desugar()); \ |
878 | 1.99k | if (desugaredType.isNull()) \ |
879 | 1.99k | return {}0 ; \ |
880 | 1.99k | if (desugaredType.getAsOpaquePtr() == T->desugar().getAsOpaquePtr()) \ |
881 | 1.99k | return QualType(T, 0)1.99k ; \ |
882 | 1.99k | return desugaredType1 ; \ |
883 | 1.99k | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDecltypeType(clang::DecltypeType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitElaboratedType(clang::ElaboratedType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitMacroQualifiedType(clang::MacroQualifiedType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitTemplateSpecializationType(clang::TemplateSpecializationType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitTypeOfExprType(clang::TypeOfExprType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitTypeOfType(clang::TypeOfType const*) Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitTypedefType(clang::TypedefType const*) Line | Count | Source | 874 | 1.97k | QualType Visit##Class##Type(const Class##Type *T) { \ | 875 | 1.97k | if (!T->isSugared()) \ | 876 | 1.97k | return QualType(T, 0)0 ; \ | 877 | 1.97k | QualType desugaredType = recurse(T->desugar()); \ | 878 | 1.97k | if (desugaredType.isNull()) \ | 879 | 1.97k | return {}0 ; \ | 880 | 1.97k | if (desugaredType.getAsOpaquePtr() == T->desugar().getAsOpaquePtr()) \ | 881 | 1.97k | return QualType(T, 0)1.97k ; \ | 882 | 1.97k | return desugaredType1 ; \ | 883 | 1.97k | } |
Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitUnaryTransformType(clang::UnaryTransformType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDecltypeType(clang::DecltypeType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitElaboratedType(clang::ElaboratedType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitMacroQualifiedType(clang::MacroQualifiedType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitObjCTypeParamType(clang::ObjCTypeParamType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitTemplateSpecializationType(clang::TemplateSpecializationType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitTypeOfExprType(clang::TypeOfExprType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitTypeOfType(clang::TypeOfType const*) Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitTypedefType(clang::TypedefType const*) Line | Count | Source | 874 | 26 | QualType Visit##Class##Type(const Class##Type *T) { \ | 875 | 26 | if (!T->isSugared()) \ | 876 | 26 | return QualType(T, 0)0 ; \ | 877 | 26 | QualType desugaredType = recurse(T->desugar()); \ | 878 | 26 | if (desugaredType.isNull()) \ | 879 | 26 | return {}0 ; \ | 880 | 26 | if (desugaredType.getAsOpaquePtr() == T->desugar().getAsOpaquePtr()) \ | 881 | 26 | return QualType(T, 0); \ | 882 | 26 | return desugaredType0 ; \ | 883 | 26 | } |
Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitUnaryTransformType(clang::UnaryTransformType const*) |
884 | | |
885 | | TRIVIAL_TYPE_CLASS(Builtin) |
886 | | |
887 | 0 | QualType VisitComplexType(const ComplexType *T) { |
888 | 0 | QualType elementType = recurse(T->getElementType()); |
889 | 0 | if (elementType.isNull()) |
890 | 0 | return {}; |
891 | | |
892 | 0 | if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) |
893 | 0 | return QualType(T, 0); |
894 | | |
895 | 0 | return Ctx.getComplexType(elementType); |
896 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitComplexType(clang::ComplexType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitComplexType(clang::ComplexType const*) |
897 | | |
898 | 44 | QualType VisitPointerType(const PointerType *T) { |
899 | 44 | QualType pointeeType = recurse(T->getPointeeType()); |
900 | 44 | if (pointeeType.isNull()) |
901 | 0 | return {}; |
902 | | |
903 | 44 | if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) |
904 | 34 | return QualType(T, 0); |
905 | | |
906 | 10 | return Ctx.getPointerType(pointeeType); |
907 | 44 | } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitPointerType(clang::PointerType const*) Line | Count | Source | 898 | 33 | QualType VisitPointerType(const PointerType *T) { | 899 | 33 | QualType pointeeType = recurse(T->getPointeeType()); | 900 | 33 | if (pointeeType.isNull()) | 901 | 0 | return {}; | 902 | | | 903 | 33 | if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) | 904 | 23 | return QualType(T, 0); | 905 | | | 906 | 10 | return Ctx.getPointerType(pointeeType); | 907 | 33 | } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitPointerType(clang::PointerType const*) Line | Count | Source | 898 | 11 | QualType VisitPointerType(const PointerType *T) { | 899 | 11 | QualType pointeeType = recurse(T->getPointeeType()); | 900 | 11 | if (pointeeType.isNull()) | 901 | 0 | return {}; | 902 | | | 903 | 11 | if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) | 904 | 11 | return QualType(T, 0); | 905 | | | 906 | 0 | return Ctx.getPointerType(pointeeType); | 907 | 11 | } |
|
908 | | |
909 | 11 | QualType VisitBlockPointerType(const BlockPointerType *T) { |
910 | 11 | QualType pointeeType = recurse(T->getPointeeType()); |
911 | 11 | if (pointeeType.isNull()) |
912 | 0 | return {}; |
913 | | |
914 | 11 | if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) |
915 | 8 | return QualType(T, 0); |
916 | | |
917 | 3 | return Ctx.getBlockPointerType(pointeeType); |
918 | 11 | } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitBlockPointerType(clang::BlockPointerType const*) Line | Count | Source | 909 | 9 | QualType VisitBlockPointerType(const BlockPointerType *T) { | 910 | 9 | QualType pointeeType = recurse(T->getPointeeType()); | 911 | 9 | if (pointeeType.isNull()) | 912 | 0 | return {}; | 913 | | | 914 | 9 | if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) | 915 | 6 | return QualType(T, 0); | 916 | | | 917 | 3 | return Ctx.getBlockPointerType(pointeeType); | 918 | 9 | } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitBlockPointerType(clang::BlockPointerType const*) Line | Count | Source | 909 | 2 | QualType VisitBlockPointerType(const BlockPointerType *T) { | 910 | 2 | QualType pointeeType = recurse(T->getPointeeType()); | 911 | 2 | if (pointeeType.isNull()) | 912 | 0 | return {}; | 913 | | | 914 | 2 | if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) | 915 | 2 | return QualType(T, 0); | 916 | | | 917 | 0 | return Ctx.getBlockPointerType(pointeeType); | 918 | 2 | } |
|
919 | | |
920 | 0 | QualType VisitLValueReferenceType(const LValueReferenceType *T) { |
921 | 0 | QualType pointeeType = recurse(T->getPointeeTypeAsWritten()); |
922 | 0 | if (pointeeType.isNull()) |
923 | 0 | return {}; |
924 | | |
925 | 0 | if (pointeeType.getAsOpaquePtr() |
926 | 0 | == T->getPointeeTypeAsWritten().getAsOpaquePtr()) |
927 | 0 | return QualType(T, 0); |
928 | | |
929 | 0 | return Ctx.getLValueReferenceType(pointeeType, T->isSpelledAsLValue()); |
930 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitLValueReferenceType(clang::LValueReferenceType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitLValueReferenceType(clang::LValueReferenceType const*) |
931 | | |
932 | 0 | QualType VisitRValueReferenceType(const RValueReferenceType *T) { |
933 | 0 | QualType pointeeType = recurse(T->getPointeeTypeAsWritten()); |
934 | 0 | if (pointeeType.isNull()) |
935 | 0 | return {}; |
936 | | |
937 | 0 | if (pointeeType.getAsOpaquePtr() |
938 | 0 | == T->getPointeeTypeAsWritten().getAsOpaquePtr()) |
939 | 0 | return QualType(T, 0); |
940 | | |
941 | 0 | return Ctx.getRValueReferenceType(pointeeType); |
942 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitRValueReferenceType(clang::RValueReferenceType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitRValueReferenceType(clang::RValueReferenceType const*) |
943 | | |
944 | 0 | QualType VisitMemberPointerType(const MemberPointerType *T) { |
945 | 0 | QualType pointeeType = recurse(T->getPointeeType()); |
946 | 0 | if (pointeeType.isNull()) |
947 | 0 | return {}; |
948 | | |
949 | 0 | if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) |
950 | 0 | return QualType(T, 0); |
951 | | |
952 | 0 | return Ctx.getMemberPointerType(pointeeType, T->getClass()); |
953 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitMemberPointerType(clang::MemberPointerType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitMemberPointerType(clang::MemberPointerType const*) |
954 | | |
955 | 0 | QualType VisitConstantArrayType(const ConstantArrayType *T) { |
956 | 0 | QualType elementType = recurse(T->getElementType()); |
957 | 0 | if (elementType.isNull()) |
958 | 0 | return {}; |
959 | | |
960 | 0 | if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) |
961 | 0 | return QualType(T, 0); |
962 | | |
963 | 0 | return Ctx.getConstantArrayType(elementType, T->getSize(), T->getSizeExpr(), |
964 | 0 | T->getSizeModifier(), |
965 | 0 | T->getIndexTypeCVRQualifiers()); |
966 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitConstantArrayType(clang::ConstantArrayType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitConstantArrayType(clang::ConstantArrayType const*) |
967 | | |
968 | 0 | QualType VisitVariableArrayType(const VariableArrayType *T) { |
969 | 0 | QualType elementType = recurse(T->getElementType()); |
970 | 0 | if (elementType.isNull()) |
971 | 0 | return {}; |
972 | | |
973 | 0 | if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) |
974 | 0 | return QualType(T, 0); |
975 | | |
976 | 0 | return Ctx.getVariableArrayType(elementType, T->getSizeExpr(), |
977 | 0 | T->getSizeModifier(), |
978 | 0 | T->getIndexTypeCVRQualifiers(), |
979 | 0 | T->getBracketsRange()); |
980 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitVariableArrayType(clang::VariableArrayType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitVariableArrayType(clang::VariableArrayType const*) |
981 | | |
982 | 0 | QualType VisitIncompleteArrayType(const IncompleteArrayType *T) { |
983 | 0 | QualType elementType = recurse(T->getElementType()); |
984 | 0 | if (elementType.isNull()) |
985 | 0 | return {}; |
986 | | |
987 | 0 | if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) |
988 | 0 | return QualType(T, 0); |
989 | | |
990 | 0 | return Ctx.getIncompleteArrayType(elementType, T->getSizeModifier(), |
991 | 0 | T->getIndexTypeCVRQualifiers()); |
992 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitIncompleteArrayType(clang::IncompleteArrayType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitIncompleteArrayType(clang::IncompleteArrayType const*) |
993 | | |
994 | 0 | QualType VisitVectorType(const VectorType *T) { |
995 | 0 | QualType elementType = recurse(T->getElementType()); |
996 | 0 | if (elementType.isNull()) |
997 | 0 | return {}; |
998 | | |
999 | 0 | if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) |
1000 | 0 | return QualType(T, 0); |
1001 | | |
1002 | 0 | return Ctx.getVectorType(elementType, T->getNumElements(), |
1003 | 0 | T->getVectorKind()); |
1004 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitVectorType(clang::VectorType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitVectorType(clang::VectorType const*) |
1005 | | |
1006 | 0 | QualType VisitExtVectorType(const ExtVectorType *T) { |
1007 | 0 | QualType elementType = recurse(T->getElementType()); |
1008 | 0 | if (elementType.isNull()) |
1009 | 0 | return {}; |
1010 | | |
1011 | 0 | if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) |
1012 | 0 | return QualType(T, 0); |
1013 | | |
1014 | 0 | return Ctx.getExtVectorType(elementType, T->getNumElements()); |
1015 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitExtVectorType(clang::ExtVectorType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitExtVectorType(clang::ExtVectorType const*) |
1016 | | |
1017 | 0 | QualType VisitConstantMatrixType(const ConstantMatrixType *T) { |
1018 | 0 | QualType elementType = recurse(T->getElementType()); |
1019 | 0 | if (elementType.isNull()) |
1020 | 0 | return {}; |
1021 | 0 | if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) |
1022 | 0 | return QualType(T, 0); |
1023 | | |
1024 | 0 | return Ctx.getConstantMatrixType(elementType, T->getNumRows(), |
1025 | 0 | T->getNumColumns()); |
1026 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitConstantMatrixType(clang::ConstantMatrixType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitConstantMatrixType(clang::ConstantMatrixType const*) |
1027 | | |
1028 | 0 | QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T) { |
1029 | 0 | QualType returnType = recurse(T->getReturnType()); |
1030 | 0 | if (returnType.isNull()) |
1031 | 0 | return {}; |
1032 | | |
1033 | 0 | if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr()) |
1034 | 0 | return QualType(T, 0); |
1035 | | |
1036 | 0 | return Ctx.getFunctionNoProtoType(returnType, T->getExtInfo()); |
1037 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitFunctionNoProtoType(clang::FunctionNoProtoType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitFunctionNoProtoType(clang::FunctionNoProtoType const*) |
1038 | | |
1039 | 13 | QualType VisitFunctionProtoType(const FunctionProtoType *T) { |
1040 | 13 | QualType returnType = recurse(T->getReturnType()); |
1041 | 13 | if (returnType.isNull()) |
1042 | 0 | return {}; |
1043 | | |
1044 | | // Transform parameter types. |
1045 | 13 | SmallVector<QualType, 4> paramTypes; |
1046 | 13 | bool paramChanged = false; |
1047 | 18 | for (auto paramType : T->getParamTypes()) { |
1048 | 18 | QualType newParamType = recurse(paramType); |
1049 | 18 | if (newParamType.isNull()) |
1050 | 0 | return {}; |
1051 | | |
1052 | 18 | if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr()) |
1053 | 10 | paramChanged = true; |
1054 | | |
1055 | 18 | paramTypes.push_back(newParamType); |
1056 | 18 | } |
1057 | | |
1058 | | // Transform extended info. |
1059 | 13 | FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo(); |
1060 | 13 | bool exceptionChanged = false; |
1061 | 13 | if (info.ExceptionSpec.Type == EST_Dynamic) { |
1062 | 0 | SmallVector<QualType, 4> exceptionTypes; |
1063 | 0 | for (auto exceptionType : info.ExceptionSpec.Exceptions) { |
1064 | 0 | QualType newExceptionType = recurse(exceptionType); |
1065 | 0 | if (newExceptionType.isNull()) |
1066 | 0 | return {}; |
1067 | | |
1068 | 0 | if (newExceptionType.getAsOpaquePtr() != exceptionType.getAsOpaquePtr()) |
1069 | 0 | exceptionChanged = true; |
1070 | |
|
1071 | 0 | exceptionTypes.push_back(newExceptionType); |
1072 | 0 | } |
1073 | | |
1074 | 0 | if (exceptionChanged) { |
1075 | 0 | info.ExceptionSpec.Exceptions = |
1076 | 0 | llvm::makeArrayRef(exceptionTypes).copy(Ctx); |
1077 | 0 | } |
1078 | 0 | } |
1079 | | |
1080 | 13 | if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() && |
1081 | 13 | !paramChanged && !exceptionChanged8 ) |
1082 | 8 | return QualType(T, 0); |
1083 | | |
1084 | 5 | return Ctx.getFunctionType(returnType, paramTypes, info); |
1085 | 13 | } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitFunctionProtoType(clang::FunctionProtoType const*) Line | Count | Source | 1039 | 11 | QualType VisitFunctionProtoType(const FunctionProtoType *T) { | 1040 | 11 | QualType returnType = recurse(T->getReturnType()); | 1041 | 11 | if (returnType.isNull()) | 1042 | 0 | return {}; | 1043 | | | 1044 | | // Transform parameter types. | 1045 | 11 | SmallVector<QualType, 4> paramTypes; | 1046 | 11 | bool paramChanged = false; | 1047 | 16 | for (auto paramType : T->getParamTypes()) { | 1048 | 16 | QualType newParamType = recurse(paramType); | 1049 | 16 | if (newParamType.isNull()) | 1050 | 0 | return {}; | 1051 | | | 1052 | 16 | if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr()) | 1053 | 10 | paramChanged = true; | 1054 | | | 1055 | 16 | paramTypes.push_back(newParamType); | 1056 | 16 | } | 1057 | | | 1058 | | // Transform extended info. | 1059 | 11 | FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo(); | 1060 | 11 | bool exceptionChanged = false; | 1061 | 11 | if (info.ExceptionSpec.Type == EST_Dynamic) { | 1062 | 0 | SmallVector<QualType, 4> exceptionTypes; | 1063 | 0 | for (auto exceptionType : info.ExceptionSpec.Exceptions) { | 1064 | 0 | QualType newExceptionType = recurse(exceptionType); | 1065 | 0 | if (newExceptionType.isNull()) | 1066 | 0 | return {}; | 1067 | | | 1068 | 0 | if (newExceptionType.getAsOpaquePtr() != exceptionType.getAsOpaquePtr()) | 1069 | 0 | exceptionChanged = true; | 1070 | |
| 1071 | 0 | exceptionTypes.push_back(newExceptionType); | 1072 | 0 | } | 1073 | | | 1074 | 0 | if (exceptionChanged) { | 1075 | 0 | info.ExceptionSpec.Exceptions = | 1076 | 0 | llvm::makeArrayRef(exceptionTypes).copy(Ctx); | 1077 | 0 | } | 1078 | 0 | } | 1079 | | | 1080 | 11 | if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() && | 1081 | 11 | !paramChanged && !exceptionChanged6 ) | 1082 | 6 | return QualType(T, 0); | 1083 | | | 1084 | 5 | return Ctx.getFunctionType(returnType, paramTypes, info); | 1085 | 11 | } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitFunctionProtoType(clang::FunctionProtoType const*) Line | Count | Source | 1039 | 2 | QualType VisitFunctionProtoType(const FunctionProtoType *T) { | 1040 | 2 | QualType returnType = recurse(T->getReturnType()); | 1041 | 2 | if (returnType.isNull()) | 1042 | 0 | return {}; | 1043 | | | 1044 | | // Transform parameter types. | 1045 | 2 | SmallVector<QualType, 4> paramTypes; | 1046 | 2 | bool paramChanged = false; | 1047 | 2 | for (auto paramType : T->getParamTypes()) { | 1048 | 2 | QualType newParamType = recurse(paramType); | 1049 | 2 | if (newParamType.isNull()) | 1050 | 0 | return {}; | 1051 | | | 1052 | 2 | if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr()) | 1053 | 0 | paramChanged = true; | 1054 | | | 1055 | 2 | paramTypes.push_back(newParamType); | 1056 | 2 | } | 1057 | | | 1058 | | // Transform extended info. | 1059 | 2 | FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo(); | 1060 | 2 | bool exceptionChanged = false; | 1061 | 2 | if (info.ExceptionSpec.Type == EST_Dynamic) { | 1062 | 0 | SmallVector<QualType, 4> exceptionTypes; | 1063 | 0 | for (auto exceptionType : info.ExceptionSpec.Exceptions) { | 1064 | 0 | QualType newExceptionType = recurse(exceptionType); | 1065 | 0 | if (newExceptionType.isNull()) | 1066 | 0 | return {}; | 1067 | | | 1068 | 0 | if (newExceptionType.getAsOpaquePtr() != exceptionType.getAsOpaquePtr()) | 1069 | 0 | exceptionChanged = true; | 1070 | |
| 1071 | 0 | exceptionTypes.push_back(newExceptionType); | 1072 | 0 | } | 1073 | | | 1074 | 0 | if (exceptionChanged) { | 1075 | 0 | info.ExceptionSpec.Exceptions = | 1076 | 0 | llvm::makeArrayRef(exceptionTypes).copy(Ctx); | 1077 | 0 | } | 1078 | 0 | } | 1079 | | | 1080 | 2 | if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() && | 1081 | 2 | !paramChanged && !exceptionChanged) | 1082 | 2 | return QualType(T, 0); | 1083 | | | 1084 | 0 | return Ctx.getFunctionType(returnType, paramTypes, info); | 1085 | 2 | } |
|
1086 | | |
1087 | 13 | QualType VisitParenType(const ParenType *T) { |
1088 | 13 | QualType innerType = recurse(T->getInnerType()); |
1089 | 13 | if (innerType.isNull()) |
1090 | 0 | return {}; |
1091 | | |
1092 | 13 | if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr()) |
1093 | 8 | return QualType(T, 0); |
1094 | | |
1095 | 5 | return Ctx.getParenType(innerType); |
1096 | 13 | } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitParenType(clang::ParenType const*) Line | Count | Source | 1087 | 11 | QualType VisitParenType(const ParenType *T) { | 1088 | 11 | QualType innerType = recurse(T->getInnerType()); | 1089 | 11 | if (innerType.isNull()) | 1090 | 0 | return {}; | 1091 | | | 1092 | 11 | if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr()) | 1093 | 6 | return QualType(T, 0); | 1094 | | | 1095 | 5 | return Ctx.getParenType(innerType); | 1096 | 11 | } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitParenType(clang::ParenType const*) Line | Count | Source | 1087 | 2 | QualType VisitParenType(const ParenType *T) { | 1088 | 2 | QualType innerType = recurse(T->getInnerType()); | 1089 | 2 | if (innerType.isNull()) | 1090 | 0 | return {}; | 1091 | | | 1092 | 2 | if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr()) | 1093 | 2 | return QualType(T, 0); | 1094 | | | 1095 | 0 | return Ctx.getParenType(innerType); | 1096 | 2 | } |
|
1097 | | |
1098 | | SUGARED_TYPE_CLASS(Typedef) |
1099 | | SUGARED_TYPE_CLASS(ObjCTypeParam) |
1100 | | SUGARED_TYPE_CLASS(MacroQualified) |
1101 | | |
1102 | 0 | QualType VisitAdjustedType(const AdjustedType *T) { |
1103 | 0 | QualType originalType = recurse(T->getOriginalType()); |
1104 | 0 | if (originalType.isNull()) |
1105 | 0 | return {}; |
1106 | | |
1107 | 0 | QualType adjustedType = recurse(T->getAdjustedType()); |
1108 | 0 | if (adjustedType.isNull()) |
1109 | 0 | return {}; |
1110 | | |
1111 | 0 | if (originalType.getAsOpaquePtr() |
1112 | 0 | == T->getOriginalType().getAsOpaquePtr() && |
1113 | 0 | adjustedType.getAsOpaquePtr() == T->getAdjustedType().getAsOpaquePtr()) |
1114 | 0 | return QualType(T, 0); |
1115 | | |
1116 | 0 | return Ctx.getAdjustedType(originalType, adjustedType); |
1117 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitAdjustedType(clang::AdjustedType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitAdjustedType(clang::AdjustedType const*) |
1118 | | |
1119 | 0 | QualType VisitDecayedType(const DecayedType *T) { |
1120 | 0 | QualType originalType = recurse(T->getOriginalType()); |
1121 | 0 | if (originalType.isNull()) |
1122 | 0 | return {}; |
1123 | | |
1124 | 0 | if (originalType.getAsOpaquePtr() |
1125 | 0 | == T->getOriginalType().getAsOpaquePtr()) |
1126 | 0 | return QualType(T, 0); |
1127 | | |
1128 | 0 | return Ctx.getDecayedType(originalType); |
1129 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitDecayedType(clang::DecayedType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitDecayedType(clang::DecayedType const*) |
1130 | | |
1131 | | SUGARED_TYPE_CLASS(TypeOfExpr) |
1132 | | SUGARED_TYPE_CLASS(TypeOf) |
1133 | | SUGARED_TYPE_CLASS(Decltype) |
1134 | | SUGARED_TYPE_CLASS(UnaryTransform) |
1135 | | TRIVIAL_TYPE_CLASS(Record) |
1136 | | TRIVIAL_TYPE_CLASS(Enum) |
1137 | | |
1138 | | // FIXME: Non-trivial to implement, but important for C++ |
1139 | | SUGARED_TYPE_CLASS(Elaborated) |
1140 | | |
1141 | 3.86k | QualType VisitAttributedType(const AttributedType *T) { |
1142 | 3.86k | QualType modifiedType = recurse(T->getModifiedType()); |
1143 | 3.86k | if (modifiedType.isNull()) |
1144 | 0 | return {}; |
1145 | | |
1146 | 3.86k | QualType equivalentType = recurse(T->getEquivalentType()); |
1147 | 3.86k | if (equivalentType.isNull()) |
1148 | 0 | return {}; |
1149 | | |
1150 | 3.86k | if (modifiedType.getAsOpaquePtr() |
1151 | 3.86k | == T->getModifiedType().getAsOpaquePtr() && |
1152 | 3.86k | equivalentType.getAsOpaquePtr() |
1153 | 409 | == T->getEquivalentType().getAsOpaquePtr()) |
1154 | 409 | return QualType(T, 0); |
1155 | | |
1156 | 3.45k | return Ctx.getAttributedType(T->getAttrKind(), modifiedType, |
1157 | 3.45k | equivalentType); |
1158 | 3.86k | } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitAttributedType(clang::AttributedType const*) Line | Count | Source | 1141 | 3.85k | QualType VisitAttributedType(const AttributedType *T) { | 1142 | 3.85k | QualType modifiedType = recurse(T->getModifiedType()); | 1143 | 3.85k | if (modifiedType.isNull()) | 1144 | 0 | return {}; | 1145 | | | 1146 | 3.85k | QualType equivalentType = recurse(T->getEquivalentType()); | 1147 | 3.85k | if (equivalentType.isNull()) | 1148 | 0 | return {}; | 1149 | | | 1150 | 3.85k | if (modifiedType.getAsOpaquePtr() | 1151 | 3.85k | == T->getModifiedType().getAsOpaquePtr() && | 1152 | 3.85k | equivalentType.getAsOpaquePtr() | 1153 | 399 | == T->getEquivalentType().getAsOpaquePtr()) | 1154 | 399 | return QualType(T, 0); | 1155 | | | 1156 | 3.45k | return Ctx.getAttributedType(T->getAttrKind(), modifiedType, | 1157 | 3.45k | equivalentType); | 1158 | 3.85k | } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitAttributedType(clang::AttributedType const*) Line | Count | Source | 1141 | 10 | QualType VisitAttributedType(const AttributedType *T) { | 1142 | 10 | QualType modifiedType = recurse(T->getModifiedType()); | 1143 | 10 | if (modifiedType.isNull()) | 1144 | 0 | return {}; | 1145 | | | 1146 | 10 | QualType equivalentType = recurse(T->getEquivalentType()); | 1147 | 10 | if (equivalentType.isNull()) | 1148 | 0 | return {}; | 1149 | | | 1150 | 10 | if (modifiedType.getAsOpaquePtr() | 1151 | 10 | == T->getModifiedType().getAsOpaquePtr() && | 1152 | 10 | equivalentType.getAsOpaquePtr() | 1153 | 10 | == T->getEquivalentType().getAsOpaquePtr()) | 1154 | 10 | return QualType(T, 0); | 1155 | | | 1156 | 0 | return Ctx.getAttributedType(T->getAttrKind(), modifiedType, | 1157 | 0 | equivalentType); | 1158 | 10 | } |
|
1159 | | |
1160 | 0 | QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { |
1161 | 0 | QualType replacementType = recurse(T->getReplacementType()); |
1162 | 0 | if (replacementType.isNull()) |
1163 | 0 | return {}; |
1164 | | |
1165 | 0 | if (replacementType.getAsOpaquePtr() |
1166 | 0 | == T->getReplacementType().getAsOpaquePtr()) |
1167 | 0 | return QualType(T, 0); |
1168 | | |
1169 | 0 | return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(), |
1170 | 0 | replacementType); |
1171 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitSubstTemplateTypeParmType(clang::SubstTemplateTypeParmType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitSubstTemplateTypeParmType(clang::SubstTemplateTypeParmType const*) |
1172 | | |
1173 | | // FIXME: Non-trivial to implement, but important for C++ |
1174 | | SUGARED_TYPE_CLASS(TemplateSpecialization) |
1175 | | |
1176 | 0 | QualType VisitAutoType(const AutoType *T) { |
1177 | 0 | if (!T->isDeduced()) |
1178 | 0 | return QualType(T, 0); |
1179 | | |
1180 | 0 | QualType deducedType = recurse(T->getDeducedType()); |
1181 | 0 | if (deducedType.isNull()) |
1182 | 0 | return {}; |
1183 | | |
1184 | 0 | if (deducedType.getAsOpaquePtr() |
1185 | 0 | == T->getDeducedType().getAsOpaquePtr()) |
1186 | 0 | return QualType(T, 0); |
1187 | | |
1188 | 0 | return Ctx.getAutoType(deducedType, T->getKeyword(), |
1189 | 0 | T->isDependentType(), /*IsPack=*/false, |
1190 | 0 | T->getTypeConstraintConcept(), |
1191 | 0 | T->getTypeConstraintArguments()); |
1192 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitAutoType(clang::AutoType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitAutoType(clang::AutoType const*) |
1193 | | |
1194 | 840 | QualType VisitObjCObjectType(const ObjCObjectType *T) { |
1195 | 840 | QualType baseType = recurse(T->getBaseType()); |
1196 | 840 | if (baseType.isNull()) |
1197 | 0 | return {}; |
1198 | | |
1199 | | // Transform type arguments. |
1200 | 840 | bool typeArgChanged = false; |
1201 | 840 | SmallVector<QualType, 4> typeArgs; |
1202 | 840 | for (auto typeArg : T->getTypeArgsAsWritten()) { |
1203 | 6 | QualType newTypeArg = recurse(typeArg); |
1204 | 6 | if (newTypeArg.isNull()) |
1205 | 0 | return {}; |
1206 | | |
1207 | 6 | if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr()) |
1208 | 2 | typeArgChanged = true; |
1209 | | |
1210 | 6 | typeArgs.push_back(newTypeArg); |
1211 | 6 | } |
1212 | | |
1213 | 840 | if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() && |
1214 | 840 | !typeArgChanged) |
1215 | 838 | return QualType(T, 0); |
1216 | | |
1217 | 2 | return Ctx.getObjCObjectType(baseType, typeArgs, |
1218 | 2 | llvm::makeArrayRef(T->qual_begin(), |
1219 | 2 | T->getNumProtocols()), |
1220 | 2 | T->isKindOfTypeAsWritten()); |
1221 | 840 | } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitObjCObjectType(clang::ObjCObjectType const*) Line | Count | Source | 1194 | 813 | QualType VisitObjCObjectType(const ObjCObjectType *T) { | 1195 | 813 | QualType baseType = recurse(T->getBaseType()); | 1196 | 813 | if (baseType.isNull()) | 1197 | 0 | return {}; | 1198 | | | 1199 | | // Transform type arguments. | 1200 | 813 | bool typeArgChanged = false; | 1201 | 813 | SmallVector<QualType, 4> typeArgs; | 1202 | 813 | for (auto typeArg : T->getTypeArgsAsWritten()) { | 1203 | 2 | QualType newTypeArg = recurse(typeArg); | 1204 | 2 | if (newTypeArg.isNull()) | 1205 | 0 | return {}; | 1206 | | | 1207 | 2 | if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr()) | 1208 | 0 | typeArgChanged = true; | 1209 | | | 1210 | 2 | typeArgs.push_back(newTypeArg); | 1211 | 2 | } | 1212 | | | 1213 | 813 | if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() && | 1214 | 813 | !typeArgChanged) | 1215 | 813 | return QualType(T, 0); | 1216 | | | 1217 | 0 | return Ctx.getObjCObjectType(baseType, typeArgs, | 1218 | 0 | llvm::makeArrayRef(T->qual_begin(), | 1219 | 0 | T->getNumProtocols()), | 1220 | 0 | T->isKindOfTypeAsWritten()); | 1221 | 813 | } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitObjCObjectType(clang::ObjCObjectType const*) Line | Count | Source | 1194 | 27 | QualType VisitObjCObjectType(const ObjCObjectType *T) { | 1195 | 27 | QualType baseType = recurse(T->getBaseType()); | 1196 | 27 | if (baseType.isNull()) | 1197 | 0 | return {}; | 1198 | | | 1199 | | // Transform type arguments. | 1200 | 27 | bool typeArgChanged = false; | 1201 | 27 | SmallVector<QualType, 4> typeArgs; | 1202 | 27 | for (auto typeArg : T->getTypeArgsAsWritten()) { | 1203 | 4 | QualType newTypeArg = recurse(typeArg); | 1204 | 4 | if (newTypeArg.isNull()) | 1205 | 0 | return {}; | 1206 | | | 1207 | 4 | if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr()) | 1208 | 2 | typeArgChanged = true; | 1209 | | | 1210 | 4 | typeArgs.push_back(newTypeArg); | 1211 | 4 | } | 1212 | | | 1213 | 27 | if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() && | 1214 | 27 | !typeArgChanged) | 1215 | 25 | return QualType(T, 0); | 1216 | | | 1217 | 2 | return Ctx.getObjCObjectType(baseType, typeArgs, | 1218 | 2 | llvm::makeArrayRef(T->qual_begin(), | 1219 | 2 | T->getNumProtocols()), | 1220 | 2 | T->isKindOfTypeAsWritten()); | 1221 | 27 | } |
|
1222 | | |
1223 | | TRIVIAL_TYPE_CLASS(ObjCInterface) |
1224 | | |
1225 | 1.38k | QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { |
1226 | 1.38k | QualType pointeeType = recurse(T->getPointeeType()); |
1227 | 1.38k | if (pointeeType.isNull()) |
1228 | 0 | return {}; |
1229 | | |
1230 | 1.38k | if (pointeeType.getAsOpaquePtr() |
1231 | 1.38k | == T->getPointeeType().getAsOpaquePtr()) |
1232 | 995 | return QualType(T, 0); |
1233 | | |
1234 | 386 | return Ctx.getObjCObjectPointerType(pointeeType); |
1235 | 1.38k | } Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitObjCObjectPointerType(clang::ObjCObjectPointerType const*) Line | Count | Source | 1225 | 1.21k | QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { | 1226 | 1.21k | QualType pointeeType = recurse(T->getPointeeType()); | 1227 | 1.21k | if (pointeeType.isNull()) | 1228 | 0 | return {}; | 1229 | | | 1230 | 1.21k | if (pointeeType.getAsOpaquePtr() | 1231 | 1.21k | == T->getPointeeType().getAsOpaquePtr()) | 1232 | 836 | return QualType(T, 0); | 1233 | | | 1234 | 376 | return Ctx.getObjCObjectPointerType(pointeeType); | 1235 | 1.21k | } |
Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitObjCObjectPointerType(clang::ObjCObjectPointerType const*) Line | Count | Source | 1225 | 169 | QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { | 1226 | 169 | QualType pointeeType = recurse(T->getPointeeType()); | 1227 | 169 | if (pointeeType.isNull()) | 1228 | 0 | return {}; | 1229 | | | 1230 | 169 | if (pointeeType.getAsOpaquePtr() | 1231 | 169 | == T->getPointeeType().getAsOpaquePtr()) | 1232 | 159 | return QualType(T, 0); | 1233 | | | 1234 | 10 | return Ctx.getObjCObjectPointerType(pointeeType); | 1235 | 169 | } |
|
1236 | | |
1237 | 0 | QualType VisitAtomicType(const AtomicType *T) { |
1238 | 0 | QualType valueType = recurse(T->getValueType()); |
1239 | 0 | if (valueType.isNull()) |
1240 | 0 | return {}; |
1241 | | |
1242 | 0 | if (valueType.getAsOpaquePtr() |
1243 | 0 | == T->getValueType().getAsOpaquePtr()) |
1244 | 0 | return QualType(T, 0); |
1245 | | |
1246 | 0 | return Ctx.getAtomicType(valueType); |
1247 | 0 | } Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::SubstObjCTypeArgsVisitor>::VisitAtomicType(clang::AtomicType const*) Unexecuted instantiation: Type.cpp:(anonymous namespace)::SimpleTransformVisitor<(anonymous namespace)::StripObjCKindOfTypeVisitor>::VisitAtomicType(clang::AtomicType const*) |
1248 | | |
1249 | | #undef TRIVIAL_TYPE_CLASS |
1250 | | #undef SUGARED_TYPE_CLASS |
1251 | | }; |
1252 | | |
1253 | | struct SubstObjCTypeArgsVisitor |
1254 | | : public SimpleTransformVisitor<SubstObjCTypeArgsVisitor> { |
1255 | | using BaseType = SimpleTransformVisitor<SubstObjCTypeArgsVisitor>; |
1256 | | |
1257 | | ArrayRef<QualType> TypeArgs; |
1258 | | ObjCSubstitutionContext SubstContext; |
1259 | | |
1260 | | SubstObjCTypeArgsVisitor(ASTContext &ctx, ArrayRef<QualType> typeArgs, |
1261 | | ObjCSubstitutionContext context) |
1262 | 7.74k | : BaseType(ctx), TypeArgs(typeArgs), SubstContext(context) {} |
1263 | | |
1264 | 7.42k | QualType VisitObjCTypeParamType(const ObjCTypeParamType *OTPTy) { |
1265 | | // Replace an Objective-C type parameter reference with the corresponding |
1266 | | // type argument. |
1267 | 7.42k | ObjCTypeParamDecl *typeParam = OTPTy->getDecl(); |
1268 | | // If we have type arguments, use them. |
1269 | 7.42k | if (!TypeArgs.empty()) { |
1270 | 341 | QualType argType = TypeArgs[typeParam->getIndex()]; |
1271 | 341 | if (OTPTy->qual_empty()) |
1272 | 340 | return argType; |
1273 | | |
1274 | | // Apply protocol lists if exists. |
1275 | 1 | bool hasError; |
1276 | 1 | SmallVector<ObjCProtocolDecl *, 8> protocolsVec; |
1277 | 1 | protocolsVec.append(OTPTy->qual_begin(), OTPTy->qual_end()); |
1278 | 1 | ArrayRef<ObjCProtocolDecl *> protocolsToApply = protocolsVec; |
1279 | 1 | return Ctx.applyObjCProtocolQualifiers( |
1280 | 1 | argType, protocolsToApply, hasError, true/*allowOnPointerType*/); |
1281 | 341 | } |
1282 | | |
1283 | 7.08k | switch (SubstContext) { |
1284 | 321 | case ObjCSubstitutionContext::Ordinary: |
1285 | 6.48k | case ObjCSubstitutionContext::Parameter: |
1286 | 6.48k | case ObjCSubstitutionContext::Superclass: |
1287 | | // Substitute the bound. |
1288 | 6.48k | return typeParam->getUnderlyingType(); |
1289 | | |
1290 | 570 | case ObjCSubstitutionContext::Result: |
1291 | 603 | case ObjCSubstitutionContext::Property: { |
1292 | | // Substitute the __kindof form of the underlying type. |
1293 | 603 | const auto *objPtr = |
1294 | 603 | typeParam->getUnderlyingType()->castAs<ObjCObjectPointerType>(); |
1295 | | |
1296 | | // __kindof types, id, and Class don't need an additional |
1297 | | // __kindof. |
1298 | 603 | if (objPtr->isKindOfType() || objPtr->isObjCIdOrClassType()) |
1299 | 564 | return typeParam->getUnderlyingType(); |
1300 | | |
1301 | | // Add __kindof. |
1302 | 39 | const auto *obj = objPtr->getObjectType(); |
1303 | 39 | QualType resultTy = Ctx.getObjCObjectType( |
1304 | 39 | obj->getBaseType(), obj->getTypeArgsAsWritten(), obj->getProtocols(), |
1305 | 39 | /*isKindOf=*/true); |
1306 | | |
1307 | | // Rebuild object pointer type. |
1308 | 39 | return Ctx.getObjCObjectPointerType(resultTy); |
1309 | 603 | } |
1310 | 7.08k | } |
1311 | 0 | llvm_unreachable("Unexpected ObjCSubstitutionContext!"); |
1312 | 0 | } |
1313 | | |
1314 | 0 | QualType VisitFunctionType(const FunctionType *funcType) { |
1315 | 0 | // If we have a function type, update the substitution context |
1316 | 0 | // appropriately. |
1317 | 0 |
|
1318 | 0 | //Substitute result type. |
1319 | 0 | QualType returnType = funcType->getReturnType().substObjCTypeArgs( |
1320 | 0 | Ctx, TypeArgs, ObjCSubstitutionContext::Result); |
1321 | 0 | if (returnType.isNull()) |
1322 | 0 | return {}; |
1323 | 0 |
|
1324 | 0 | // Handle non-prototyped functions, which only substitute into the result |
1325 | 0 | // type. |
1326 | 0 | if (isa<FunctionNoProtoType>(funcType)) { |
1327 | 0 | // If the return type was unchanged, do nothing. |
1328 | 0 | if (returnType.getAsOpaquePtr() == |
1329 | 0 | funcType->getReturnType().getAsOpaquePtr()) |
1330 | 0 | return BaseType::VisitFunctionType(funcType); |
1331 | 0 |
|
1332 | 0 | // Otherwise, build a new type. |
1333 | 0 | return Ctx.getFunctionNoProtoType(returnType, funcType->getExtInfo()); |
1334 | 0 | } |
1335 | 0 |
|
1336 | 0 | const auto *funcProtoType = cast<FunctionProtoType>(funcType); |
1337 | 0 |
|
1338 | 0 | // Transform parameter types. |
1339 | 0 | SmallVector<QualType, 4> paramTypes; |
1340 | 0 | bool paramChanged = false; |
1341 | 0 | for (auto paramType : funcProtoType->getParamTypes()) { |
1342 | 0 | QualType newParamType = paramType.substObjCTypeArgs( |
1343 | 0 | Ctx, TypeArgs, ObjCSubstitutionContext::Parameter); |
1344 | 0 | if (newParamType.isNull()) |
1345 | 0 | return {}; |
1346 | 0 |
|
1347 | 0 | if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr()) |
1348 | 0 | paramChanged = true; |
1349 | 0 |
|
1350 | 0 | paramTypes.push_back(newParamType); |
1351 | 0 | } |
1352 | 0 |
|
1353 | 0 | // Transform extended info. |
1354 | 0 | FunctionProtoType::ExtProtoInfo info = funcProtoType->getExtProtoInfo(); |
1355 | 0 | bool exceptionChanged = false; |
1356 | 0 | if (info.ExceptionSpec.Type == EST_Dynamic) { |
1357 | 0 | SmallVector<QualType, 4> exceptionTypes; |
1358 | 0 | for (auto exceptionType : info.ExceptionSpec.Exceptions) { |
1359 | 0 | QualType newExceptionType = exceptionType.substObjCTypeArgs( |
1360 | 0 | Ctx, TypeArgs, ObjCSubstitutionContext::Ordinary); |
1361 | 0 | if (newExceptionType.isNull()) |
1362 | 0 | return {}; |
1363 | 0 |
|
1364 | 0 | if (newExceptionType.getAsOpaquePtr() != exceptionType.getAsOpaquePtr()) |
1365 | 0 | exceptionChanged = true; |
1366 | 0 |
|
1367 | 0 | exceptionTypes.push_back(newExceptionType); |
1368 | 0 | } |
1369 | 0 |
|
1370 | 0 | if (exceptionChanged) { |
1371 | 0 | info.ExceptionSpec.Exceptions = |
1372 | 0 | llvm::makeArrayRef(exceptionTypes).copy(Ctx); |
1373 | 0 | } |
1374 | 0 | } |
1375 | 0 |
|
1376 | 0 | if (returnType.getAsOpaquePtr() == |
1377 | 0 | funcProtoType->getReturnType().getAsOpaquePtr() && |
1378 | 0 | !paramChanged && !exceptionChanged) |
1379 | 0 | return BaseType::VisitFunctionType(funcType); |
1380 | 0 |
|
1381 | 0 | return Ctx.getFunctionType(returnType, paramTypes, info); |
1382 | 0 | } |
1383 | | |
1384 | 1.21k | QualType VisitObjCObjectType(const ObjCObjectType *objcObjectType) { |
1385 | | // Substitute into the type arguments of a specialized Objective-C object |
1386 | | // type. |
1387 | 1.21k | if (objcObjectType->isSpecializedAsWritten()) { |
1388 | 401 | SmallVector<QualType, 4> newTypeArgs; |
1389 | 401 | bool anyChanged = false; |
1390 | 404 | for (auto typeArg : objcObjectType->getTypeArgsAsWritten()) { |
1391 | 404 | QualType newTypeArg = typeArg.substObjCTypeArgs( |
1392 | 404 | Ctx, TypeArgs, ObjCSubstitutionContext::Ordinary); |
1393 | 404 | if (newTypeArg.isNull()) |
1394 | 0 | return {}; |
1395 | | |
1396 | 404 | if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr()) { |
1397 | | // If we're substituting based on an unspecialized context type, |
1398 | | // produce an unspecialized type. |
1399 | 402 | ArrayRef<ObjCProtocolDecl *> protocols( |
1400 | 402 | objcObjectType->qual_begin(), objcObjectType->getNumProtocols()); |
1401 | 402 | if (TypeArgs.empty() && |
1402 | 402 | SubstContext != ObjCSubstitutionContext::Superclass321 ) { |
1403 | 321 | return Ctx.getObjCObjectType( |
1404 | 321 | objcObjectType->getBaseType(), {}, protocols, |
1405 | 321 | objcObjectType->isKindOfTypeAsWritten()); |
1406 | 321 | } |
1407 | | |
1408 | 81 | anyChanged = true; |
1409 | 81 | } |
1410 | | |
1411 | 83 | newTypeArgs.push_back(newTypeArg); |
1412 | 83 | } |
1413 | | |
1414 | 80 | if (anyChanged) { |
1415 | 78 | ArrayRef<ObjCProtocolDecl *> protocols( |
1416 | 78 | objcObjectType->qual_begin(), objcObjectType->getNumProtocols()); |
1417 | 78 | return Ctx.getObjCObjectType(objcObjectType->getBaseType(), newTypeArgs, |
1418 | 78 | protocols, |
1419 | 78 | objcObjectType->isKindOfTypeAsWritten()); |
1420 | 78 | } |
1421 | 80 | } |
1422 | | |
1423 | 813 | return BaseType::VisitObjCObjectType(objcObjectType); |
1424 | 1.21k | } |
1425 | | |
1426 | 3.85k | QualType VisitAttributedType(const AttributedType *attrType) { |
1427 | 3.85k | QualType newType = BaseType::VisitAttributedType(attrType); |
1428 | 3.85k | if (newType.isNull()) |
1429 | 0 | return {}; |
1430 | | |
1431 | 3.85k | const auto *newAttrType = dyn_cast<AttributedType>(newType.getTypePtr()); |
1432 | 3.85k | if (!newAttrType || newAttrType->getAttrKind() != attr::ObjCKindOf) |
1433 | 3.83k | return newType; |
1434 | | |
1435 | | // Find out if it's an Objective-C object or object pointer type; |
1436 | 22 | QualType newEquivType = newAttrType->getEquivalentType(); |
1437 | 22 | const ObjCObjectPointerType *ptrType = |
1438 | 22 | newEquivType->getAs<ObjCObjectPointerType>(); |
1439 | 22 | const ObjCObjectType *objType = ptrType |
1440 | 22 | ? ptrType->getObjectType() |
1441 | 22 | : newEquivType->getAs<ObjCObjectType>()0 ; |
1442 | 22 | if (!objType) |
1443 | 0 | return newType; |
1444 | | |
1445 | | // Rebuild the "equivalent" type, which pushes __kindof down into |
1446 | | // the object type. |
1447 | 22 | newEquivType = Ctx.getObjCObjectType( |
1448 | 22 | objType->getBaseType(), objType->getTypeArgsAsWritten(), |
1449 | 22 | objType->getProtocols(), |
1450 | | // There is no need to apply kindof on an unqualified id type. |
1451 | 22 | /*isKindOf=*/objType->isObjCUnqualifiedId() ? false0 : true); |
1452 | | |
1453 | | // If we started with an object pointer type, rebuild it. |
1454 | 22 | if (ptrType) |
1455 | 22 | newEquivType = Ctx.getObjCObjectPointerType(newEquivType); |
1456 | | |
1457 | | // Rebuild the attributed type. |
1458 | 22 | return Ctx.getAttributedType(newAttrType->getAttrKind(), |
1459 | 22 | newAttrType->getModifiedType(), newEquivType); |
1460 | 22 | } |
1461 | | }; |
1462 | | |
1463 | | struct StripObjCKindOfTypeVisitor |
1464 | | : public SimpleTransformVisitor<StripObjCKindOfTypeVisitor> { |
1465 | | using BaseType = SimpleTransformVisitor<StripObjCKindOfTypeVisitor>; |
1466 | | |
1467 | 219 | explicit StripObjCKindOfTypeVisitor(ASTContext &ctx) : BaseType(ctx) {} |
1468 | | |
1469 | 42 | QualType VisitObjCObjectType(const ObjCObjectType *objType) { |
1470 | 42 | if (!objType->isKindOfType()) |
1471 | 27 | return BaseType::VisitObjCObjectType(objType); |
1472 | | |
1473 | 15 | QualType baseType = objType->getBaseType().stripObjCKindOfType(Ctx); |
1474 | 15 | return Ctx.getObjCObjectType(baseType, objType->getTypeArgsAsWritten(), |
1475 | 15 | objType->getProtocols(), |
1476 | 15 | /*isKindOf=*/false); |
1477 | 42 | } |
1478 | | }; |
1479 | | |
1480 | | } // namespace |
1481 | | |
1482 | | /// Substitute the given type arguments for Objective-C type |
1483 | | /// parameters within the given type, recursively. |
1484 | | QualType QualType::substObjCTypeArgs(ASTContext &ctx, |
1485 | | ArrayRef<QualType> typeArgs, |
1486 | 7.74k | ObjCSubstitutionContext context) const { |
1487 | 7.74k | SubstObjCTypeArgsVisitor visitor(ctx, typeArgs, context); |
1488 | 7.74k | return visitor.recurse(*this); |
1489 | 7.74k | } |
1490 | | |
1491 | | QualType QualType::substObjCMemberType(QualType objectType, |
1492 | | const DeclContext *dc, |
1493 | 32.2k | ObjCSubstitutionContext context) const { |
1494 | 32.2k | if (auto subs = objectType->getObjCSubstitutions(dc)) |
1495 | 3.36k | return substObjCTypeArgs(dc->getParentASTContext(), *subs, context); |
1496 | | |
1497 | 28.8k | return *this; |
1498 | 32.2k | } |
1499 | | |
1500 | 219 | QualType QualType::stripObjCKindOfType(const ASTContext &constCtx) const { |
1501 | | // FIXME: Because ASTContext::getAttributedType() is non-const. |
1502 | 219 | auto &ctx = const_cast<ASTContext &>(constCtx); |
1503 | 219 | StripObjCKindOfTypeVisitor visitor(ctx); |
1504 | 219 | return visitor.recurse(*this); |
1505 | 219 | } |
1506 | | |
1507 | 1.02M | QualType QualType::getAtomicUnqualifiedType() const { |
1508 | 1.02M | if (const auto AT = getTypePtr()->getAs<AtomicType>()) |
1509 | 654 | return AT->getValueType().getUnqualifiedType(); |
1510 | 1.02M | return getUnqualifiedType(); |
1511 | 1.02M | } |
1512 | | |
1513 | | Optional<ArrayRef<QualType>> Type::getObjCSubstitutions( |
1514 | 56.7k | const DeclContext *dc) const { |
1515 | | // Look through method scopes. |
1516 | 56.7k | if (const auto method = dyn_cast<ObjCMethodDecl>(dc)) |
1517 | 221 | dc = method->getDeclContext(); |
1518 | | |
1519 | | // Find the class or category in which the type we're substituting |
1520 | | // was declared. |
1521 | 56.7k | const auto *dcClassDecl = dyn_cast<ObjCInterfaceDecl>(dc); |
1522 | 56.7k | const ObjCCategoryDecl *dcCategoryDecl = nullptr; |
1523 | 56.7k | ObjCTypeParamList *dcTypeParams = nullptr; |
1524 | 56.7k | if (dcClassDecl) { |
1525 | | // If the class does not have any type parameters, there's no |
1526 | | // substitution to do. |
1527 | 39.7k | dcTypeParams = dcClassDecl->getTypeParamList(); |
1528 | 39.7k | if (!dcTypeParams) |
1529 | 33.7k | return None; |
1530 | 39.7k | } else { |
1531 | | // If we are in neither a class nor a category, there's no |
1532 | | // substitution to perform. |
1533 | 16.9k | dcCategoryDecl = dyn_cast<ObjCCategoryDecl>(dc); |
1534 | 16.9k | if (!dcCategoryDecl) |
1535 | 7.32k | return None; |
1536 | | |
1537 | | // If the category does not have any type parameters, there's no |
1538 | | // substitution to do. |
1539 | 9.62k | dcTypeParams = dcCategoryDecl->getTypeParamList(); |
1540 | 9.62k | if (!dcTypeParams) |
1541 | 8.89k | return None; |
1542 | | |
1543 | 728 | dcClassDecl = dcCategoryDecl->getClassInterface(); |
1544 | 728 | if (!dcClassDecl) |
1545 | 0 | return None; |
1546 | 728 | } |
1547 | 6.74k | assert(dcTypeParams && "No substitutions to perform"); |
1548 | 0 | assert(dcClassDecl && "No class context"); |
1549 | | |
1550 | | // Find the underlying object type. |
1551 | 0 | const ObjCObjectType *objectType; |
1552 | 6.74k | if (const auto *objectPointerType = getAs<ObjCObjectPointerType>()) { |
1553 | 6.29k | objectType = objectPointerType->getObjectType(); |
1554 | 6.29k | } else if (453 getAs<BlockPointerType>()453 ) { |
1555 | 8 | ASTContext &ctx = dc->getParentASTContext(); |
1556 | 8 | objectType = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, {}, {}) |
1557 | 8 | ->castAs<ObjCObjectType>(); |
1558 | 445 | } else { |
1559 | 445 | objectType = getAs<ObjCObjectType>(); |
1560 | 445 | } |
1561 | | |
1562 | | /// Extract the class from the receiver object type. |
1563 | 6.74k | ObjCInterfaceDecl *curClassDecl = objectType ? objectType->getInterface() |
1564 | 6.74k | : nullptr0 ; |
1565 | 6.74k | if (!curClassDecl) { |
1566 | | // If we don't have a context type (e.g., this is "id" or some |
1567 | | // variant thereof), substitute the bounds. |
1568 | 84 | return llvm::ArrayRef<QualType>(); |
1569 | 84 | } |
1570 | | |
1571 | | // Follow the superclass chain until we've mapped the receiver type |
1572 | | // to the same class as the context. |
1573 | 11.4k | while (6.66k curClassDecl != dcClassDecl) { |
1574 | | // Map to the superclass type. |
1575 | 9.08k | QualType superType = objectType->getSuperClassType(); |
1576 | 9.08k | if (superType.isNull()) { |
1577 | 4.32k | objectType = nullptr; |
1578 | 4.32k | break; |
1579 | 4.32k | } |
1580 | | |
1581 | 4.75k | objectType = superType->castAs<ObjCObjectType>(); |
1582 | 4.75k | curClassDecl = objectType->getInterface(); |
1583 | 4.75k | } |
1584 | | |
1585 | | // If we don't have a receiver type, or the receiver type does not |
1586 | | // have type arguments, substitute in the defaults. |
1587 | 6.66k | if (!objectType || objectType->isUnspecialized()2.33k ) { |
1588 | 6.20k | return llvm::ArrayRef<QualType>(); |
1589 | 6.20k | } |
1590 | | |
1591 | | // The receiver type has the type arguments we want. |
1592 | 459 | return objectType->getTypeArgs(); |
1593 | 6.66k | } |
1594 | | |
1595 | 9 | bool Type::acceptsObjCTypeParams() const { |
1596 | 9 | if (auto *IfaceT = getAsObjCInterfaceType()) { |
1597 | 2 | if (auto *ID = IfaceT->getInterface()) { |
1598 | 2 | if (ID->getTypeParamList()) |
1599 | 1 | return true; |
1600 | 2 | } |
1601 | 2 | } |
1602 | | |
1603 | 8 | return false; |
1604 | 9 | } |
1605 | | |
1606 | 326 | void ObjCObjectType::computeSuperClassTypeSlow() const { |
1607 | | // Retrieve the class declaration for this type. If there isn't one |
1608 | | // (e.g., this is some variant of "id" or "Class"), then there is no |
1609 | | // superclass type. |
1610 | 326 | ObjCInterfaceDecl *classDecl = getInterface(); |
1611 | 326 | if (!classDecl) { |
1612 | 0 | CachedSuperClassType.setInt(true); |
1613 | 0 | return; |
1614 | 0 | } |
1615 | | |
1616 | | // Extract the superclass type. |
1617 | 326 | const ObjCObjectType *superClassObjTy = classDecl->getSuperClassType(); |
1618 | 326 | if (!superClassObjTy) { |
1619 | 50 | CachedSuperClassType.setInt(true); |
1620 | 50 | return; |
1621 | 50 | } |
1622 | | |
1623 | 276 | ObjCInterfaceDecl *superClassDecl = superClassObjTy->getInterface(); |
1624 | 276 | if (!superClassDecl) { |
1625 | 0 | CachedSuperClassType.setInt(true); |
1626 | 0 | return; |
1627 | 0 | } |
1628 | | |
1629 | | // If the superclass doesn't have type parameters, then there is no |
1630 | | // substitution to perform. |
1631 | 276 | QualType superClassType(superClassObjTy, 0); |
1632 | 276 | ObjCTypeParamList *superClassTypeParams = superClassDecl->getTypeParamList(); |
1633 | 276 | if (!superClassTypeParams) { |
1634 | 139 | CachedSuperClassType.setPointerAndInt( |
1635 | 139 | superClassType->castAs<ObjCObjectType>(), true); |
1636 | 139 | return; |
1637 | 139 | } |
1638 | | |
1639 | | // If the superclass reference is unspecialized, return it. |
1640 | 137 | if (superClassObjTy->isUnspecialized()) { |
1641 | 6 | CachedSuperClassType.setPointerAndInt(superClassObjTy, true); |
1642 | 6 | return; |
1643 | 6 | } |
1644 | | |
1645 | | // If the subclass is not parameterized, there aren't any type |
1646 | | // parameters in the superclass reference to substitute. |
1647 | 131 | ObjCTypeParamList *typeParams = classDecl->getTypeParamList(); |
1648 | 131 | if (!typeParams) { |
1649 | 7 | CachedSuperClassType.setPointerAndInt( |
1650 | 7 | superClassType->castAs<ObjCObjectType>(), true); |
1651 | 7 | return; |
1652 | 7 | } |
1653 | | |
1654 | | // If the subclass type isn't specialized, return the unspecialized |
1655 | | // superclass. |
1656 | 124 | if (isUnspecialized()) { |
1657 | 99 | QualType unspecializedSuper |
1658 | 99 | = classDecl->getASTContext().getObjCInterfaceType( |
1659 | 99 | superClassObjTy->getInterface()); |
1660 | 99 | CachedSuperClassType.setPointerAndInt( |
1661 | 99 | unspecializedSuper->castAs<ObjCObjectType>(), |
1662 | 99 | true); |
1663 | 99 | return; |
1664 | 99 | } |
1665 | | |
1666 | | // Substitute the provided type arguments into the superclass type. |
1667 | 25 | ArrayRef<QualType> typeArgs = getTypeArgs(); |
1668 | 25 | assert(typeArgs.size() == typeParams->size()); |
1669 | 0 | CachedSuperClassType.setPointerAndInt( |
1670 | 25 | superClassType.substObjCTypeArgs(classDecl->getASTContext(), typeArgs, |
1671 | 25 | ObjCSubstitutionContext::Superclass) |
1672 | 25 | ->castAs<ObjCObjectType>(), |
1673 | 25 | true); |
1674 | 25 | } |
1675 | | |
1676 | 29.4k | const ObjCInterfaceType *ObjCObjectPointerType::getInterfaceType() const { |
1677 | 29.4k | if (auto interfaceDecl = getObjectType()->getInterface()) { |
1678 | 24.9k | return interfaceDecl->getASTContext().getObjCInterfaceType(interfaceDecl) |
1679 | 24.9k | ->castAs<ObjCInterfaceType>(); |
1680 | 24.9k | } |
1681 | | |
1682 | 4.49k | return nullptr; |
1683 | 29.4k | } |
1684 | | |
1685 | 0 | QualType ObjCObjectPointerType::getSuperClassType() const { |
1686 | 0 | QualType superObjectType = getObjectType()->getSuperClassType(); |
1687 | 0 | if (superObjectType.isNull()) |
1688 | 0 | return superObjectType; |
1689 | | |
1690 | 0 | ASTContext &ctx = getInterfaceDecl()->getASTContext(); |
1691 | 0 | return ctx.getObjCObjectPointerType(superObjectType); |
1692 | 0 | } |
1693 | | |
1694 | 525 | const ObjCObjectType *Type::getAsObjCQualifiedInterfaceType() const { |
1695 | | // There is no sugar for ObjCObjectType's, just return the canonical |
1696 | | // type pointer if it is the right class. There is no typedef information to |
1697 | | // return and these cannot be Address-space qualified. |
1698 | 525 | if (const auto *T = getAs<ObjCObjectType>()) |
1699 | 451 | if (T->getNumProtocols() && T->getInterface()53 ) |
1700 | 53 | return T; |
1701 | 472 | return nullptr; |
1702 | 525 | } |
1703 | | |
1704 | 522 | bool Type::isObjCQualifiedInterfaceType() const { |
1705 | 522 | return getAsObjCQualifiedInterfaceType() != nullptr; |
1706 | 522 | } |
1707 | | |
1708 | 12.8k | const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const { |
1709 | | // There is no sugar for ObjCQualifiedIdType's, just return the canonical |
1710 | | // type pointer if it is the right class. |
1711 | 12.8k | if (const auto *OPT = getAs<ObjCObjectPointerType>()) { |
1712 | 12.8k | if (OPT->isObjCQualifiedIdType()) |
1713 | 231 | return OPT; |
1714 | 12.8k | } |
1715 | 12.6k | return nullptr; |
1716 | 12.8k | } |
1717 | | |
1718 | 10 | const ObjCObjectPointerType *Type::getAsObjCQualifiedClassType() const { |
1719 | | // There is no sugar for ObjCQualifiedClassType's, just return the canonical |
1720 | | // type pointer if it is the right class. |
1721 | 10 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) { |
1722 | 10 | if (OPT->isObjCQualifiedClassType()) |
1723 | 10 | return OPT; |
1724 | 10 | } |
1725 | 0 | return nullptr; |
1726 | 10 | } |
1727 | | |
1728 | 7.82k | const ObjCObjectType *Type::getAsObjCInterfaceType() const { |
1729 | 7.82k | if (const auto *OT = getAs<ObjCObjectType>()) { |
1730 | 4.71k | if (OT->getInterface()) |
1731 | 4.71k | return OT; |
1732 | 4.71k | } |
1733 | 3.10k | return nullptr; |
1734 | 7.82k | } |
1735 | | |
1736 | 13.9k | const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const { |
1737 | 13.9k | if (const auto *OPT = getAs<ObjCObjectPointerType>()) { |
1738 | 13.8k | if (OPT->getInterfaceType()) |
1739 | 13.5k | return OPT; |
1740 | 13.8k | } |
1741 | 370 | return nullptr; |
1742 | 13.9k | } |
1743 | | |
1744 | 1.09M | const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const { |
1745 | 1.09M | QualType PointeeType; |
1746 | 1.09M | if (const auto *PT = getAs<PointerType>()) |
1747 | 650k | PointeeType = PT->getPointeeType(); |
1748 | 441k | else if (const auto *RT = getAs<ReferenceType>()) |
1749 | 12.1k | PointeeType = RT->getPointeeType(); |
1750 | 429k | else |
1751 | 429k | return nullptr; |
1752 | | |
1753 | 662k | if (const auto *RT = PointeeType->getAs<RecordType>()) |
1754 | 572k | return dyn_cast<CXXRecordDecl>(RT->getDecl()); |
1755 | | |
1756 | 89.8k | return nullptr; |
1757 | 662k | } |
1758 | | |
1759 | 113M | CXXRecordDecl *Type::getAsCXXRecordDecl() const { |
1760 | 113M | return dyn_cast_or_null<CXXRecordDecl>(getAsTagDecl()); |
1761 | 113M | } |
1762 | | |
1763 | 175M | RecordDecl *Type::getAsRecordDecl() const { |
1764 | 175M | return dyn_cast_or_null<RecordDecl>(getAsTagDecl()); |
1765 | 175M | } |
1766 | | |
1767 | 294M | TagDecl *Type::getAsTagDecl() const { |
1768 | 294M | if (const auto *TT = getAs<TagType>()) |
1769 | 31.1M | return TT->getDecl(); |
1770 | 263M | if (const auto *Injected = getAs<InjectedClassNameType>()) |
1771 | 955k | return Injected->getDecl(); |
1772 | | |
1773 | 262M | return nullptr; |
1774 | 263M | } |
1775 | | |
1776 | 3.08M | bool Type::hasAttr(attr::Kind AK) const { |
1777 | 3.08M | const Type *Cur = this; |
1778 | 3.08M | while (const auto *AT = Cur->getAs<AttributedType>()) { |
1779 | 13.1k | if (AT->getAttrKind() == AK) |
1780 | 12.3k | return true; |
1781 | 795 | Cur = AT->getEquivalentType().getTypePtr(); |
1782 | 795 | } |
1783 | 3.07M | return false; |
1784 | 3.08M | } |
1785 | | |
1786 | | namespace { |
1787 | | |
1788 | | class GetContainedDeducedTypeVisitor : |
1789 | | public TypeVisitor<GetContainedDeducedTypeVisitor, Type*> { |
1790 | | bool Syntactic; |
1791 | | |
1792 | | public: |
1793 | | GetContainedDeducedTypeVisitor(bool Syntactic = false) |
1794 | 139M | : Syntactic(Syntactic) {} |
1795 | | |
1796 | | using TypeVisitor<GetContainedDeducedTypeVisitor, Type*>::Visit; |
1797 | | |
1798 | 9.63M | Type *Visit(QualType T) { |
1799 | 9.63M | if (T.isNull()) |
1800 | 0 | return nullptr; |
1801 | 9.63M | return Visit(T.getTypePtr()); |
1802 | 9.63M | } |
1803 | | |
1804 | | // The deduced type itself. |
1805 | 415k | Type *VisitDeducedType(const DeducedType *AT) { |
1806 | 415k | return const_cast<DeducedType*>(AT); |
1807 | 415k | } |
1808 | | |
1809 | | // Only these types can contain the desired 'auto' type. |
1810 | 1.93M | Type *VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { |
1811 | 1.93M | return Visit(T->getReplacementType()); |
1812 | 1.93M | } |
1813 | | |
1814 | 2.05M | Type *VisitElaboratedType(const ElaboratedType *T) { |
1815 | 2.05M | return Visit(T->getNamedType()); |
1816 | 2.05M | } |
1817 | | |
1818 | 866k | Type *VisitPointerType(const PointerType *T) { |
1819 | 866k | return Visit(T->getPointeeType()); |
1820 | 866k | } |
1821 | | |
1822 | 3.00k | Type *VisitBlockPointerType(const BlockPointerType *T) { |
1823 | 3.00k | return Visit(T->getPointeeType()); |
1824 | 3.00k | } |
1825 | | |
1826 | 643k | Type *VisitReferenceType(const ReferenceType *T) { |
1827 | 643k | return Visit(T->getPointeeTypeAsWritten()); |
1828 | 643k | } |
1829 | | |
1830 | 6.39k | Type *VisitMemberPointerType(const MemberPointerType *T) { |
1831 | 6.39k | return Visit(T->getPointeeType()); |
1832 | 6.39k | } |
1833 | | |
1834 | 184k | Type *VisitArrayType(const ArrayType *T) { |
1835 | 184k | return Visit(T->getElementType()); |
1836 | 184k | } |
1837 | | |
1838 | | Type *VisitDependentSizedExtVectorType( |
1839 | 24 | const DependentSizedExtVectorType *T) { |
1840 | 24 | return Visit(T->getElementType()); |
1841 | 24 | } |
1842 | | |
1843 | 272k | Type *VisitVectorType(const VectorType *T) { |
1844 | 272k | return Visit(T->getElementType()); |
1845 | 272k | } |
1846 | | |
1847 | 31 | Type *VisitDependentSizedMatrixType(const DependentSizedMatrixType *T) { |
1848 | 31 | return Visit(T->getElementType()); |
1849 | 31 | } |
1850 | | |
1851 | 29 | Type *VisitConstantMatrixType(const ConstantMatrixType *T) { |
1852 | 29 | return Visit(T->getElementType()); |
1853 | 29 | } |
1854 | | |
1855 | 684k | Type *VisitFunctionProtoType(const FunctionProtoType *T) { |
1856 | 684k | if (Syntactic && T->hasTrailingReturn()98 ) |
1857 | 37 | return const_cast<FunctionProtoType*>(T); |
1858 | 684k | return VisitFunctionType(T); |
1859 | 684k | } |
1860 | | |
1861 | 684k | Type *VisitFunctionType(const FunctionType *T) { |
1862 | 684k | return Visit(T->getReturnType()); |
1863 | 684k | } |
1864 | | |
1865 | 31.3k | Type *VisitParenType(const ParenType *T) { |
1866 | 31.3k | return Visit(T->getInnerType()); |
1867 | 31.3k | } |
1868 | | |
1869 | 2.40M | Type *VisitAttributedType(const AttributedType *T) { |
1870 | 2.40M | return Visit(T->getModifiedType()); |
1871 | 2.40M | } |
1872 | | |
1873 | 560k | Type *VisitMacroQualifiedType(const MacroQualifiedType *T) { |
1874 | 560k | return Visit(T->getUnderlyingType()); |
1875 | 560k | } |
1876 | | |
1877 | 1.63k | Type *VisitAdjustedType(const AdjustedType *T) { |
1878 | 1.63k | return Visit(T->getOriginalType()); |
1879 | 1.63k | } |
1880 | | |
1881 | 447 | Type *VisitPackExpansionType(const PackExpansionType *T) { |
1882 | 447 | return Visit(T->getPattern()); |
1883 | 447 | } |
1884 | | }; |
1885 | | |
1886 | | } // namespace |
1887 | | |
1888 | 139M | DeducedType *Type::getContainedDeducedType() const { |
1889 | 139M | return cast_or_null<DeducedType>( |
1890 | 139M | GetContainedDeducedTypeVisitor().Visit(this)); |
1891 | 139M | } |
1892 | | |
1893 | 40.7k | bool Type::hasAutoForTrailingReturnType() const { |
1894 | 40.7k | return isa_and_nonnull<FunctionType>( |
1895 | 40.7k | GetContainedDeducedTypeVisitor(true).Visit(this)); |
1896 | 40.7k | } |
1897 | | |
1898 | 7.33M | bool Type::hasIntegerRepresentation() const { |
1899 | 7.33M | if (const auto *VT = dyn_cast<VectorType>(CanonicalType)) |
1900 | 102k | return VT->getElementType()->isIntegerType(); |
1901 | 7.23M | if (CanonicalType->isVLSTBuiltinType()) { |
1902 | 896 | const auto *VT = cast<BuiltinType>(CanonicalType); |
1903 | 896 | return VT->getKind() == BuiltinType::SveBool || |
1904 | 896 | (855 VT->getKind() >= BuiltinType::SveInt8855 && |
1905 | 855 | VT->getKind() <= BuiltinType::SveUint64); |
1906 | 896 | } |
1907 | | |
1908 | 7.23M | return isIntegerType(); |
1909 | 7.23M | } |
1910 | | |
1911 | | /// Determine whether this type is an integral type. |
1912 | | /// |
1913 | | /// This routine determines whether the given type is an integral type per |
1914 | | /// C++ [basic.fundamental]p7. Although the C standard does not define the |
1915 | | /// term "integral type", it has a similar term "integer type", and in C++ |
1916 | | /// the two terms are equivalent. However, C's "integer type" includes |
1917 | | /// enumeration types, while C++'s "integer type" does not. The \c ASTContext |
1918 | | /// parameter is used to determine whether we should be following the C or |
1919 | | /// C++ rules when determining whether this type is an integral/integer type. |
1920 | | /// |
1921 | | /// For cases where C permits "an integer type" and C++ permits "an integral |
1922 | | /// type", use this routine. |
1923 | | /// |
1924 | | /// For cases where C permits "an integer type" and C++ permits "an integral |
1925 | | /// or enumeration type", use \c isIntegralOrEnumerationType() instead. |
1926 | | /// |
1927 | | /// \param Ctx The context in which this type occurs. |
1928 | | /// |
1929 | | /// \returns true if the type is considered an integral type, false otherwise. |
1930 | 17.2M | bool Type::isIntegralType(const ASTContext &Ctx) const { |
1931 | 17.2M | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
1932 | 16.8M | return BT->getKind() >= BuiltinType::Bool && |
1933 | 16.8M | BT->getKind() <= BuiltinType::Int12816.8M ; |
1934 | | |
1935 | | // Complete enum types are integral in C. |
1936 | 448k | if (!Ctx.getLangOpts().CPlusPlus) |
1937 | 325k | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) |
1938 | 452 | return ET->getDecl()->isComplete(); |
1939 | | |
1940 | 448k | return isBitIntType(); |
1941 | 448k | } |
1942 | | |
1943 | 35.5M | bool Type::isIntegralOrUnscopedEnumerationType() const { |
1944 | 35.5M | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
1945 | 22.1M | return BT->getKind() >= BuiltinType::Bool && |
1946 | 22.1M | BT->getKind() <= BuiltinType::Int12821.8M ; |
1947 | | |
1948 | 13.3M | if (isBitIntType()) |
1949 | 494 | return true; |
1950 | | |
1951 | 13.3M | return isUnscopedEnumerationType(); |
1952 | 13.3M | } |
1953 | | |
1954 | 21.7M | bool Type::isUnscopedEnumerationType() const { |
1955 | 21.7M | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) |
1956 | 10.2M | return !ET->getDecl()->isScoped(); |
1957 | | |
1958 | 11.5M | return false; |
1959 | 21.7M | } |
1960 | | |
1961 | 389k | bool Type::isCharType() const { |
1962 | 389k | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
1963 | 236k | return BT->getKind() == BuiltinType::Char_U || |
1964 | 236k | BT->getKind() == BuiltinType::UChar236k || |
1965 | 236k | BT->getKind() == BuiltinType::Char_S228k || |
1966 | 236k | BT->getKind() == BuiltinType::SChar178k ; |
1967 | 152k | return false; |
1968 | 389k | } |
1969 | | |
1970 | 2.04k | bool Type::isWideCharType() const { |
1971 | 2.04k | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
1972 | 2.02k | return BT->getKind() == BuiltinType::WChar_S || |
1973 | 2.02k | BT->getKind() == BuiltinType::WChar_U1.97k ; |
1974 | 14 | return false; |
1975 | 2.04k | } |
1976 | | |
1977 | 2.15k | bool Type::isChar8Type() const { |
1978 | 2.15k | if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) |
1979 | 1.80k | return BT->getKind() == BuiltinType::Char8; |
1980 | 354 | return false; |
1981 | 2.15k | } |
1982 | | |
1983 | 1.67k | bool Type::isChar16Type() const { |
1984 | 1.67k | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
1985 | 1.65k | return BT->getKind() == BuiltinType::Char16; |
1986 | 14 | return false; |
1987 | 1.67k | } |
1988 | | |
1989 | 1.64k | bool Type::isChar32Type() const { |
1990 | 1.64k | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
1991 | 1.63k | return BT->getKind() == BuiltinType::Char32; |
1992 | 14 | return false; |
1993 | 1.64k | } |
1994 | | |
1995 | | /// Determine whether this type is any of the built-in character |
1996 | | /// types. |
1997 | 4.09M | bool Type::isAnyCharacterType() const { |
1998 | 4.09M | const auto *BT = dyn_cast<BuiltinType>(CanonicalType); |
1999 | 4.09M | if (!BT) return false117k ; |
2000 | 3.97M | switch (BT->getKind()) { |
2001 | 3.97M | default: return false; |
2002 | 3 | case BuiltinType::Char_U: |
2003 | 115 | case BuiltinType::UChar: |
2004 | 115 | case BuiltinType::WChar_U: |
2005 | 269 | case BuiltinType::Char8: |
2006 | 683 | case BuiltinType::Char16: |
2007 | 1.12k | case BuiltinType::Char32: |
2008 | 2.24k | case BuiltinType::Char_S: |
2009 | 2.25k | case BuiltinType::SChar: |
2010 | 2.71k | case BuiltinType::WChar_S: |
2011 | 2.71k | return true; |
2012 | 3.97M | } |
2013 | 3.97M | } |
2014 | | |
2015 | | /// isSignedIntegerType - Return true if this is an integer type that is |
2016 | | /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], |
2017 | | /// an enum decl which has a signed representation |
2018 | 648k | bool Type::isSignedIntegerType() const { |
2019 | 648k | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
2020 | 647k | return BT->getKind() >= BuiltinType::Char_S && |
2021 | 647k | BT->getKind() <= BuiltinType::Int128249k ; |
2022 | 647k | } |
2023 | | |
2024 | 702 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { |
2025 | | // Incomplete enum types are not treated as integer types. |
2026 | | // FIXME: In C++, enum types are never integer types. |
2027 | 383 | if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()376 ) |
2028 | 322 | return ET->getDecl()->getIntegerType()->isSignedIntegerType(); |
2029 | 383 | } |
2030 | | |
2031 | 380 | if (const auto *IT = dyn_cast<BitIntType>(CanonicalType)) |
2032 | 165 | return IT->isSigned(); |
2033 | 215 | if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType)) |
2034 | 0 | return IT->isSigned(); |
2035 | | |
2036 | 215 | return false; |
2037 | 215 | } |
2038 | | |
2039 | 31.7M | bool Type::isSignedIntegerOrEnumerationType() const { |
2040 | 31.7M | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
2041 | 30.9M | return BT->getKind() >= BuiltinType::Char_S && |
2042 | 30.9M | BT->getKind() <= BuiltinType::Int12820.8M ; |
2043 | 30.9M | } |
2044 | | |
2045 | 826k | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) { |
2046 | 279k | if (ET->getDecl()->isComplete()) |
2047 | 279k | return ET->getDecl()->getIntegerType()->isSignedIntegerType(); |
2048 | 279k | } |
2049 | | |
2050 | 546k | if (const auto *IT = dyn_cast<BitIntType>(CanonicalType)) |
2051 | 653 | return IT->isSigned(); |
2052 | 546k | if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType)) |
2053 | 0 | return IT->isSigned(); |
2054 | | |
2055 | 546k | return false; |
2056 | 546k | } |
2057 | | |
2058 | 6.78M | bool Type::hasSignedIntegerRepresentation() const { |
2059 | 6.78M | if (const auto *VT = dyn_cast<VectorType>(CanonicalType)) |
2060 | 210k | return VT->getElementType()->isSignedIntegerOrEnumerationType(); |
2061 | 6.57M | else |
2062 | 6.57M | return isSignedIntegerOrEnumerationType(); |
2063 | 6.78M | } |
2064 | | |
2065 | | /// isUnsignedIntegerType - Return true if this is an integer type that is |
2066 | | /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum |
2067 | | /// decl which has an unsigned representation |
2068 | 7.17M | bool Type::isUnsignedIntegerType() const { |
2069 | 7.17M | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
2070 | 7.17M | return BT->getKind() >= BuiltinType::Bool && |
2071 | 7.17M | BT->getKind() <= BuiltinType::UInt1287.17M ; |
2072 | 7.17M | } |
2073 | | |
2074 | 6.58k | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) { |
2075 | | // Incomplete enum types are not treated as integer types. |
2076 | | // FIXME: In C++, enum types are never integer types. |
2077 | 184 | if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()) |
2078 | 167 | return ET->getDecl()->getIntegerType()->isUnsignedIntegerType(); |
2079 | 184 | } |
2080 | | |
2081 | 6.42k | if (const auto *IT = dyn_cast<BitIntType>(CanonicalType)) |
2082 | 108 | return IT->isUnsigned(); |
2083 | 6.31k | if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType)) |
2084 | 0 | return IT->isUnsigned(); |
2085 | | |
2086 | 6.31k | return false; |
2087 | 6.31k | } |
2088 | | |
2089 | 20.2M | bool Type::isUnsignedIntegerOrEnumerationType() const { |
2090 | 20.2M | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
2091 | 20.1M | return BT->getKind() >= BuiltinType::Bool && |
2092 | 20.1M | BT->getKind() <= BuiltinType::UInt12820.1M ; |
2093 | 20.1M | } |
2094 | | |
2095 | 151k | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) { |
2096 | 6.81k | if (ET->getDecl()->isComplete()) |
2097 | 6.81k | return ET->getDecl()->getIntegerType()->isUnsignedIntegerType(); |
2098 | 6.81k | } |
2099 | | |
2100 | 144k | if (const auto *IT = dyn_cast<BitIntType>(CanonicalType)) |
2101 | 235 | return IT->isUnsigned(); |
2102 | 144k | if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType)) |
2103 | 0 | return IT->isUnsigned(); |
2104 | | |
2105 | 144k | return false; |
2106 | 144k | } |
2107 | | |
2108 | 971k | bool Type::hasUnsignedIntegerRepresentation() const { |
2109 | 971k | if (const auto *VT = dyn_cast<VectorType>(CanonicalType)) |
2110 | 26.0k | return VT->getElementType()->isUnsignedIntegerOrEnumerationType(); |
2111 | 945k | if (const auto *VT = dyn_cast<MatrixType>(CanonicalType)) |
2112 | 17 | return VT->getElementType()->isUnsignedIntegerOrEnumerationType(); |
2113 | 945k | if (CanonicalType->isVLSTBuiltinType()) { |
2114 | 162 | const auto *VT = cast<BuiltinType>(CanonicalType); |
2115 | 162 | return VT->getKind() >= BuiltinType::SveUint8 && |
2116 | 162 | VT->getKind() <= BuiltinType::SveUint6496 ; |
2117 | 162 | } |
2118 | 945k | return isUnsignedIntegerOrEnumerationType(); |
2119 | 945k | } |
2120 | | |
2121 | 13.9M | bool Type::isFloatingType() const { |
2122 | 13.9M | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
2123 | 13.5M | return BT->getKind() >= BuiltinType::Half && |
2124 | 13.5M | BT->getKind() <= BuiltinType::Ibm1285.75M ; |
2125 | 387k | if (const auto *CT = dyn_cast<ComplexType>(CanonicalType)) |
2126 | 2.39k | return CT->getElementType()->isFloatingType(); |
2127 | 384k | return false; |
2128 | 387k | } |
2129 | | |
2130 | 11.3M | bool Type::hasFloatingRepresentation() const { |
2131 | 11.3M | if (const auto *VT = dyn_cast<VectorType>(CanonicalType)) |
2132 | 55.5k | return VT->getElementType()->isFloatingType(); |
2133 | 11.2M | else |
2134 | 11.2M | return isFloatingType(); |
2135 | 11.3M | } |
2136 | | |
2137 | 13.8M | bool Type::isRealFloatingType() const { |
2138 | 13.8M | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
2139 | 6.19M | return BT->isFloatingPoint(); |
2140 | 7.65M | return false; |
2141 | 13.8M | } |
2142 | | |
2143 | 283k | bool Type::isRealType() const { |
2144 | 283k | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
2145 | 254k | return BT->getKind() >= BuiltinType::Bool && |
2146 | 254k | BT->getKind() <= BuiltinType::Ibm128254k ; |
2147 | 29.5k | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) |
2148 | 74 | return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped(); |
2149 | 29.4k | return isBitIntType(); |
2150 | 29.5k | } |
2151 | | |
2152 | 10.8M | bool Type::isArithmeticType() const { |
2153 | 10.8M | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
2154 | 9.79M | return BT->getKind() >= BuiltinType::Bool && |
2155 | 9.79M | BT->getKind() <= BuiltinType::Ibm1289.71M && |
2156 | 9.79M | BT->getKind() != BuiltinType::BFloat169.71M ; |
2157 | 1.01M | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) |
2158 | | // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2). |
2159 | | // If a body isn't seen by the time we get here, return false. |
2160 | | // |
2161 | | // C++0x: Enumerations are not arithmetic types. For now, just return |
2162 | | // false for scoped enumerations since that will disable any |
2163 | | // unwanted implicit conversions. |
2164 | 147k | return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete()138k ; |
2165 | 865k | return isa<ComplexType>(CanonicalType) || isBitIntType()861k ; |
2166 | 1.01M | } |
2167 | | |
2168 | 1.11M | Type::ScalarTypeKind Type::getScalarTypeKind() const { |
2169 | 1.11M | assert(isScalarType()); |
2170 | | |
2171 | 0 | const Type *T = CanonicalType.getTypePtr(); |
2172 | 1.11M | if (const auto *BT = dyn_cast<BuiltinType>(T)) { |
2173 | 853k | if (BT->getKind() == BuiltinType::Bool) return STK_Bool257k ; |
2174 | 595k | if (BT->getKind() == BuiltinType::NullPtr) return STK_CPointer32 ; |
2175 | 595k | if (BT->isInteger()) return STK_Integral558k ; |
2176 | 37.3k | if (BT->isFloatingPoint()) return STK_Floating36.7k ; |
2177 | 589 | if (BT->isFixedPointType()) return STK_FixedPoint; |
2178 | 0 | llvm_unreachable("unknown scalar builtin type"); |
2179 | 258k | } else if (isa<PointerType>(T)) { |
2180 | 244k | return STK_CPointer; |
2181 | 244k | } else if (13.8k isa<BlockPointerType>(T)13.8k ) { |
2182 | 93 | return STK_BlockPointer; |
2183 | 13.7k | } else if (isa<ObjCObjectPointerType>(T)) { |
2184 | 7.54k | return STK_ObjCObjectPointer; |
2185 | 7.54k | } else if (6.21k isa<MemberPointerType>(T)6.21k ) { |
2186 | 111 | return STK_MemberPointer; |
2187 | 6.10k | } else if (isa<EnumType>(T)) { |
2188 | 4.78k | assert(cast<EnumType>(T)->getDecl()->isComplete()); |
2189 | 0 | return STK_Integral; |
2190 | 4.78k | } else if (const auto *1.31k CT1.31k = dyn_cast<ComplexType>(T)) { |
2191 | 1.26k | if (CT->getElementType()->isRealFloatingType()) |
2192 | 1.00k | return STK_FloatingComplex; |
2193 | 261 | return STK_IntegralComplex; |
2194 | 1.26k | } else if (51 isBitIntType()51 ) { |
2195 | 51 | return STK_Integral; |
2196 | 51 | } |
2197 | | |
2198 | 0 | llvm_unreachable("unknown scalar type"); |
2199 | 0 | } |
2200 | | |
2201 | | /// Determines whether the type is a C++ aggregate type or C |
2202 | | /// aggregate or union type. |
2203 | | /// |
2204 | | /// An aggregate type is an array or a class type (struct, union, or |
2205 | | /// class) that has no user-declared constructors, no private or |
2206 | | /// protected non-static data members, no base classes, and no virtual |
2207 | | /// functions (C++ [dcl.init.aggr]p1). The notion of an aggregate type |
2208 | | /// subsumes the notion of C aggregates (C99 6.2.5p21) because it also |
2209 | | /// includes union types. |
2210 | 141k | bool Type::isAggregateType() const { |
2211 | 141k | if (const auto *Record = dyn_cast<RecordType>(CanonicalType)) { |
2212 | 112k | if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(Record->getDecl())) |
2213 | 100k | return ClassDecl->isAggregate(); |
2214 | | |
2215 | 12.5k | return true; |
2216 | 112k | } |
2217 | | |
2218 | 28.4k | return isa<ArrayType>(CanonicalType); |
2219 | 141k | } |
2220 | | |
2221 | | /// isConstantSizeType - Return true if this is not a variable sized type, |
2222 | | /// according to the rules of C99 6.7.5p3. It is not legal to call this on |
2223 | | /// incomplete types or dependent types. |
2224 | 7.06M | bool Type::isConstantSizeType() const { |
2225 | 7.06M | assert(!isIncompleteType() && "This doesn't make sense for incomplete types"); |
2226 | 0 | assert(!isDependentType() && "This doesn't make sense for dependent types"); |
2227 | | // The VAT must have a size, as it is known to be complete. |
2228 | 0 | return !isa<VariableArrayType>(CanonicalType); |
2229 | 7.06M | } |
2230 | | |
2231 | | /// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1) |
2232 | | /// - a type that can describe objects, but which lacks information needed to |
2233 | | /// determine its size. |
2234 | 110M | bool Type::isIncompleteType(NamedDecl **Def) const { |
2235 | 110M | if (Def) |
2236 | 58.3M | *Def = nullptr; |
2237 | | |
2238 | 110M | switch (CanonicalType->getTypeClass()) { |
2239 | 25.7M | default: return false; |
2240 | 50.3M | case Builtin: |
2241 | | // Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never |
2242 | | // be completed. |
2243 | 50.3M | return isVoidType(); |
2244 | 7.75M | case Enum: { |
2245 | 7.75M | EnumDecl *EnumD = cast<EnumType>(CanonicalType)->getDecl(); |
2246 | 7.75M | if (Def) |
2247 | 7.48M | *Def = EnumD; |
2248 | 7.75M | return !EnumD->isComplete(); |
2249 | 0 | } |
2250 | 26.0M | case Record: { |
2251 | | // A tagged type (struct/union/enum/class) is incomplete if the decl is a |
2252 | | // forward declaration, but not a full definition (C99 6.2.5p22). |
2253 | 26.0M | RecordDecl *Rec = cast<RecordType>(CanonicalType)->getDecl(); |
2254 | 26.0M | if (Def) |
2255 | 18.7M | *Def = Rec; |
2256 | 26.0M | return !Rec->isCompleteDefinition(); |
2257 | 0 | } |
2258 | 460k | case ConstantArray: |
2259 | 475k | case VariableArray: |
2260 | | // An array is incomplete if its element type is incomplete |
2261 | | // (C++ [dcl.array]p1). |
2262 | | // We don't handle dependent-sized arrays (dependent types are never treated |
2263 | | // as incomplete). |
2264 | 475k | return cast<ArrayType>(CanonicalType)->getElementType() |
2265 | 475k | ->isIncompleteType(Def); |
2266 | 2.69k | case IncompleteArray: |
2267 | | // An array of unknown size is an incomplete type (C99 6.2.5p22). |
2268 | 2.69k | return true; |
2269 | 23.3k | case MemberPointer: { |
2270 | | // Member pointers in the MS ABI have special behavior in |
2271 | | // RequireCompleteType: they attach a MSInheritanceAttr to the CXXRecordDecl |
2272 | | // to indicate which inheritance model to use. |
2273 | 23.3k | auto *MPTy = cast<MemberPointerType>(CanonicalType); |
2274 | 23.3k | const Type *ClassTy = MPTy->getClass(); |
2275 | | // Member pointers with dependent class types don't get special treatment. |
2276 | 23.3k | if (ClassTy->isDependentType()) |
2277 | 9.11k | return false; |
2278 | 14.2k | const CXXRecordDecl *RD = ClassTy->getAsCXXRecordDecl(); |
2279 | 14.2k | ASTContext &Context = RD->getASTContext(); |
2280 | | // Member pointers not in the MS ABI don't get special treatment. |
2281 | 14.2k | if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) |
2282 | 10.4k | return false; |
2283 | | // The inheritance attribute might only be present on the most recent |
2284 | | // CXXRecordDecl, use that one. |
2285 | 3.78k | RD = RD->getMostRecentNonInjectedDecl(); |
2286 | | // Nothing interesting to do if the inheritance attribute is already set. |
2287 | 3.78k | if (RD->hasAttr<MSInheritanceAttr>()) |
2288 | 3.76k | return false; |
2289 | 17 | return true; |
2290 | 3.78k | } |
2291 | 273 | case ObjCObject: |
2292 | 273 | return cast<ObjCObjectType>(CanonicalType)->getBaseType() |
2293 | 273 | ->isIncompleteType(Def); |
2294 | 133k | case ObjCInterface: { |
2295 | | // ObjC interfaces are incomplete if they are @class, not @interface. |
2296 | 133k | ObjCInterfaceDecl *Interface |
2297 | 133k | = cast<ObjCInterfaceType>(CanonicalType)->getDecl(); |
2298 | 133k | if (Def) |
2299 | 133k | *Def = Interface; |
2300 | 133k | return !Interface->hasDefinition(); |
2301 | 3.78k | } |
2302 | 110M | } |
2303 | 110M | } |
2304 | | |
2305 | 22.2M | bool Type::isSizelessBuiltinType() const { |
2306 | 22.2M | if (const BuiltinType *BT = getAs<BuiltinType>()) { |
2307 | 6.66M | switch (BT->getKind()) { |
2308 | | // SVE Types |
2309 | 208k | #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id: |
2310 | 208k | #include "clang/Basic/AArch64SVEACLETypes.def"0 |
2311 | 341k | #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id: |
2312 | 208k | #include "clang/Basic/RISCVVTypes.def"5.16k |
2313 | 5.16k | return true; |
2314 | 6.65M | default: |
2315 | 6.65M | return false; |
2316 | 6.66M | } |
2317 | 6.66M | } |
2318 | 15.5M | return false; |
2319 | 22.2M | } |
2320 | | |
2321 | 1.91M | bool Type::isSizelessType() const { return isSizelessBuiltinType(); } |
2322 | | |
2323 | 22.7M | bool Type::isVLSTBuiltinType() const { |
2324 | 22.7M | if (const BuiltinType *BT = getAs<BuiltinType>()) { |
2325 | 21.6M | switch (BT->getKind()) { |
2326 | 1.91k | case BuiltinType::SveInt8: |
2327 | 3.75k | case BuiltinType::SveInt16: |
2328 | 5.91k | case BuiltinType::SveInt32: |
2329 | 7.96k | case BuiltinType::SveInt64: |
2330 | 9.68k | case BuiltinType::SveUint8: |
2331 | 11.3k | case BuiltinType::SveUint16: |
2332 | 13.0k | case BuiltinType::SveUint32: |
2333 | 14.7k | case BuiltinType::SveUint64: |
2334 | 16.2k | case BuiltinType::SveFloat16: |
2335 | 17.8k | case BuiltinType::SveFloat32: |
2336 | 19.7k | case BuiltinType::SveFloat64: |
2337 | 19.9k | case BuiltinType::SveBFloat16: |
2338 | 20.7k | case BuiltinType::SveBool: |
2339 | 20.7k | return true; |
2340 | 21.6M | default: |
2341 | 21.6M | return false; |
2342 | 21.6M | } |
2343 | 21.6M | } |
2344 | 1.09M | return false; |
2345 | 22.7M | } |
2346 | | |
2347 | 3.05k | QualType Type::getSveEltType(const ASTContext &Ctx) const { |
2348 | 3.05k | assert(isVLSTBuiltinType() && "unsupported type!"); |
2349 | | |
2350 | 0 | const BuiltinType *BTy = getAs<BuiltinType>(); |
2351 | 3.05k | if (BTy->getKind() == BuiltinType::SveBool) |
2352 | | // Represent predicates as i8 rather than i1 to avoid any layout issues. |
2353 | | // The type is bitcasted to a scalable predicate type when casting between |
2354 | | // scalable and fixed-length vectors. |
2355 | 154 | return Ctx.UnsignedCharTy; |
2356 | 2.89k | else |
2357 | 2.89k | return Ctx.getBuiltinVectorTypeInfo(BTy).ElementType; |
2358 | 3.05k | } |
2359 | | |
2360 | 1.28M | bool QualType::isPODType(const ASTContext &Context) const { |
2361 | | // C++11 has a more relaxed definition of POD. |
2362 | 1.28M | if (Context.getLangOpts().CPlusPlus11) |
2363 | 1.27M | return isCXX11PODType(Context); |
2364 | | |
2365 | 13.6k | return isCXX98PODType(Context); |
2366 | 1.28M | } |
2367 | | |
2368 | 2.42M | bool QualType::isCXX98PODType(const ASTContext &Context) const { |
2369 | | // The compiler shouldn't query this for incomplete types, but the user might. |
2370 | | // We return false for that case. Except for incomplete arrays of PODs, which |
2371 | | // are PODs according to the standard. |
2372 | 2.42M | if (isNull()) |
2373 | 0 | return false; |
2374 | | |
2375 | 2.42M | if ((*this)->isIncompleteArrayType()) |
2376 | 90 | return Context.getBaseElementType(*this).isCXX98PODType(Context); |
2377 | | |
2378 | 2.42M | if ((*this)->isIncompleteType()) |
2379 | 1.47k | return false; |
2380 | | |
2381 | 2.41M | if (hasNonTrivialObjCLifetime()) |
2382 | 28 | return false; |
2383 | | |
2384 | 2.41M | QualType CanonicalType = getTypePtr()->CanonicalType; |
2385 | 2.41M | switch (CanonicalType->getTypeClass()) { |
2386 | | // Everything not explicitly mentioned is not POD. |
2387 | 305k | default: return false; |
2388 | 0 | case Type::VariableArray: |
2389 | 512 | case Type::ConstantArray: |
2390 | | // IncompleteArray is handled above. |
2391 | 512 | return Context.getBaseElementType(*this).isCXX98PODType(Context); |
2392 | | |
2393 | 15.3k | case Type::ObjCObjectPointer: |
2394 | 15.4k | case Type::BlockPointer: |
2395 | 1.26M | case Type::Builtin: |
2396 | 1.26M | case Type::Complex: |
2397 | 1.74M | case Type::Pointer: |
2398 | 1.75M | case Type::MemberPointer: |
2399 | 1.75M | case Type::Vector: |
2400 | 1.75M | case Type::ExtVector: |
2401 | 1.75M | case Type::BitInt: |
2402 | 1.75M | return true; |
2403 | | |
2404 | 2.96k | case Type::Enum: |
2405 | 2.96k | return true; |
2406 | | |
2407 | 354k | case Type::Record: |
2408 | 354k | if (const auto *ClassDecl = |
2409 | 354k | dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl())) |
2410 | 351k | return ClassDecl->isPOD(); |
2411 | | |
2412 | | // C struct/union is POD. |
2413 | 2.80k | return true; |
2414 | 2.41M | } |
2415 | 2.41M | } |
2416 | | |
2417 | 2.13k | bool QualType::isTrivialType(const ASTContext &Context) const { |
2418 | | // The compiler shouldn't query this for incomplete types, but the user might. |
2419 | | // We return false for that case. Except for incomplete arrays of PODs, which |
2420 | | // are PODs according to the standard. |
2421 | 2.13k | if (isNull()) |
2422 | 0 | return false; |
2423 | | |
2424 | 2.13k | if ((*this)->isArrayType()) |
2425 | 21 | return Context.getBaseElementType(*this).isTrivialType(Context); |
2426 | | |
2427 | 2.11k | if ((*this)->isSizelessBuiltinType()) |
2428 | 4 | return true; |
2429 | | |
2430 | | // Return false for incomplete types after skipping any incomplete array |
2431 | | // types which are expressly allowed by the standard and thus our API. |
2432 | 2.10k | if ((*this)->isIncompleteType()) |
2433 | 15 | return false; |
2434 | | |
2435 | 2.09k | if (hasNonTrivialObjCLifetime()) |
2436 | 4 | return false; |
2437 | | |
2438 | 2.08k | QualType CanonicalType = getTypePtr()->CanonicalType; |
2439 | 2.08k | if (CanonicalType->isDependentType()) |
2440 | 0 | return false; |
2441 | | |
2442 | | // C++0x [basic.types]p9: |
2443 | | // Scalar types, trivial class types, arrays of such types, and |
2444 | | // cv-qualified versions of these types are collectively called trivial |
2445 | | // types. |
2446 | | |
2447 | | // As an extension, Clang treats vector types as Scalar types. |
2448 | 2.08k | if (CanonicalType->isScalarType() || CanonicalType->isVectorType()806 ) |
2449 | 1.29k | return true; |
2450 | 792 | if (const auto *RT = CanonicalType->getAs<RecordType>()) { |
2451 | 755 | if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) { |
2452 | | // C++11 [class]p6: |
2453 | | // A trivial class is a class that has a default constructor, |
2454 | | // has no non-trivial default constructors, and is trivially |
2455 | | // copyable. |
2456 | 755 | return ClassDecl->hasDefaultConstructor() && |
2457 | 755 | !ClassDecl->hasNonTrivialDefaultConstructor()411 && |
2458 | 755 | ClassDecl->isTriviallyCopyable()332 ; |
2459 | 755 | } |
2460 | | |
2461 | 0 | return true; |
2462 | 755 | } |
2463 | | |
2464 | | // No other types can match. |
2465 | 37 | return false; |
2466 | 792 | } |
2467 | | |
2468 | 507k | bool QualType::isTriviallyCopyableType(const ASTContext &Context) const { |
2469 | 507k | if ((*this)->isArrayType()) |
2470 | 60.3k | return Context.getBaseElementType(*this).isTriviallyCopyableType(Context); |
2471 | | |
2472 | 447k | if (hasNonTrivialObjCLifetime()) |
2473 | 39 | return false; |
2474 | | |
2475 | | // C++11 [basic.types]p9 - See Core 2094 |
2476 | | // Scalar types, trivially copyable class types, arrays of such types, and |
2477 | | // cv-qualified versions of these types are collectively |
2478 | | // called trivially copyable types. |
2479 | | |
2480 | 447k | QualType CanonicalType = getCanonicalType(); |
2481 | 447k | if (CanonicalType->isDependentType()) |
2482 | 39.7k | return false; |
2483 | | |
2484 | 407k | if (CanonicalType->isSizelessBuiltinType()) |
2485 | 7 | return true; |
2486 | | |
2487 | | // Return false for incomplete types after skipping any incomplete array types |
2488 | | // which are expressly allowed by the standard and thus our API. |
2489 | 407k | if (CanonicalType->isIncompleteType()) |
2490 | 30 | return false; |
2491 | | |
2492 | | // As an extension, Clang treats vector types as Scalar types. |
2493 | 407k | if (CanonicalType->isScalarType() || CanonicalType->isVectorType()51.5k ) |
2494 | 365k | return true; |
2495 | | |
2496 | 42.3k | if (const auto *RT = CanonicalType->getAs<RecordType>()) { |
2497 | 42.2k | if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) { |
2498 | 41.9k | if (!ClassDecl->isTriviallyCopyable()) return false37.6k ; |
2499 | 41.9k | } |
2500 | | |
2501 | 4.57k | return true; |
2502 | 42.2k | } |
2503 | | |
2504 | | // No other types can match. |
2505 | 104 | return false; |
2506 | 42.3k | } |
2507 | | |
2508 | 101 | bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const { |
2509 | 101 | QualType BaseElementType = Context.getBaseElementType(*this); |
2510 | | |
2511 | 101 | if (BaseElementType->isIncompleteType()) { |
2512 | 3 | return false; |
2513 | 98 | } else if (const auto *RD = BaseElementType->getAsRecordDecl()) { |
2514 | 78 | return RD->canPassInRegisters(); |
2515 | 78 | } else { |
2516 | 20 | switch (isNonTrivialToPrimitiveDestructiveMove()) { |
2517 | 17 | case PCK_Trivial: |
2518 | 17 | return !isDestructedType(); |
2519 | 1 | case PCK_ARCStrong: |
2520 | 1 | return true; |
2521 | 2 | default: |
2522 | 2 | return false; |
2523 | 20 | } |
2524 | 20 | } |
2525 | 101 | } |
2526 | | |
2527 | 3.63M | bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const { |
2528 | 3.63M | return !Context.getLangOpts().ObjCAutoRefCount && |
2529 | 3.63M | Context.getLangOpts().ObjCWeak3.63M && |
2530 | 3.63M | getObjCLifetime() != Qualifiers::OCL_Weak125 ; |
2531 | 3.63M | } |
2532 | | |
2533 | 172k | bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD) { |
2534 | 172k | return RD->hasNonTrivialToPrimitiveDefaultInitializeCUnion(); |
2535 | 172k | } |
2536 | | |
2537 | 758k | bool QualType::hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD) { |
2538 | 758k | return RD->hasNonTrivialToPrimitiveDestructCUnion(); |
2539 | 758k | } |
2540 | | |
2541 | 697k | bool QualType::hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD) { |
2542 | 697k | return RD->hasNonTrivialToPrimitiveCopyCUnion(); |
2543 | 697k | } |
2544 | | |
2545 | | QualType::PrimitiveDefaultInitializeKind |
2546 | 1.87M | QualType::isNonTrivialToPrimitiveDefaultInitialize() const { |
2547 | 1.87M | if (const auto *RT = |
2548 | 1.87M | getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>()) |
2549 | 532k | if (RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) |
2550 | 123 | return PDIK_Struct; |
2551 | | |
2552 | 1.87M | switch (getQualifiers().getObjCLifetime()) { |
2553 | 162 | case Qualifiers::OCL_Strong: |
2554 | 162 | return PDIK_ARCStrong; |
2555 | 45 | case Qualifiers::OCL_Weak: |
2556 | 45 | return PDIK_ARCWeak; |
2557 | 1.87M | default: |
2558 | 1.87M | return PDIK_Trivial; |
2559 | 1.87M | } |
2560 | 1.87M | } |
2561 | | |
2562 | 1.84M | QualType::PrimitiveCopyKind QualType::isNonTrivialToPrimitiveCopy() const { |
2563 | 1.84M | if (const auto *RT = |
2564 | 1.84M | getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>()) |
2565 | 534k | if (RT->getDecl()->isNonTrivialToPrimitiveCopy()) |
2566 | 219 | return PCK_Struct; |
2567 | | |
2568 | 1.84M | Qualifiers Qs = getQualifiers(); |
2569 | 1.84M | switch (Qs.getObjCLifetime()) { |
2570 | 575 | case Qualifiers::OCL_Strong: |
2571 | 575 | return PCK_ARCStrong; |
2572 | 258 | case Qualifiers::OCL_Weak: |
2573 | 258 | return PCK_ARCWeak; |
2574 | 1.84M | default: |
2575 | 1.84M | return Qs.hasVolatile() ? PCK_VolatileTrivial2.53k : PCK_Trivial1.83M ; |
2576 | 1.84M | } |
2577 | 1.84M | } |
2578 | | |
2579 | | QualType::PrimitiveCopyKind |
2580 | 1.09k | QualType::isNonTrivialToPrimitiveDestructiveMove() const { |
2581 | 1.09k | return isNonTrivialToPrimitiveCopy(); |
2582 | 1.09k | } |
2583 | | |
2584 | 17.7M | bool Type::isLiteralType(const ASTContext &Ctx) const { |
2585 | 17.7M | if (isDependentType()) |
2586 | 263k | return false; |
2587 | | |
2588 | | // C++1y [basic.types]p10: |
2589 | | // A type is a literal type if it is: |
2590 | | // -- cv void; or |
2591 | 17.5M | if (Ctx.getLangOpts().CPlusPlus14 && isVoidType()3.61M ) |
2592 | 6.02k | return true; |
2593 | | |
2594 | | // C++11 [basic.types]p10: |
2595 | | // A type is a literal type if it is: |
2596 | | // [...] |
2597 | | // -- an array of literal type other than an array of runtime bound; or |
2598 | 17.4M | if (isVariableArrayType()) |
2599 | 3 | return false; |
2600 | 17.4M | const Type *BaseTy = getBaseElementTypeUnsafe(); |
2601 | 17.4M | assert(BaseTy && "NULL element type"); |
2602 | | |
2603 | | // Return false for incomplete types after skipping any incomplete array |
2604 | | // types; those are expressly allowed by the standard and thus our API. |
2605 | 17.4M | if (BaseTy->isIncompleteType()) |
2606 | 10.8k | return false; |
2607 | | |
2608 | | // C++11 [basic.types]p10: |
2609 | | // A type is a literal type if it is: |
2610 | | // -- a scalar type; or |
2611 | | // As an extension, Clang treats vector types and complex types as |
2612 | | // literal types. |
2613 | 17.4M | if (BaseTy->isScalarType() || BaseTy->isVectorType()2.08M || |
2614 | 17.4M | BaseTy->isAnyComplexType()1.42M ) |
2615 | 16.0M | return true; |
2616 | | // -- a reference type; or |
2617 | 1.42M | if (BaseTy->isReferenceType()) |
2618 | 409k | return true; |
2619 | | // -- a class type that has all of the following properties: |
2620 | 1.01M | if (const auto *RT = BaseTy->getAs<RecordType>()) { |
2621 | | // -- a trivial destructor, |
2622 | | // -- every constructor call and full-expression in the |
2623 | | // brace-or-equal-initializers for non-static data members (if any) |
2624 | | // is a constant expression, |
2625 | | // -- it is an aggregate type or has at least one constexpr |
2626 | | // constructor or constructor template that is not a copy or move |
2627 | | // constructor, and |
2628 | | // -- all non-static data members and base classes of literal types |
2629 | | // |
2630 | | // We resolve DR1361 by ignoring the second bullet. |
2631 | 959k | if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) |
2632 | 959k | return ClassDecl->isLiteral(); |
2633 | | |
2634 | 147 | return true; |
2635 | 959k | } |
2636 | | |
2637 | | // We treat _Atomic T as a literal type if T is a literal type. |
2638 | 57.2k | if (const auto *AT = BaseTy->getAs<AtomicType>()) |
2639 | 1.44k | return AT->getValueType()->isLiteralType(Ctx); |
2640 | | |
2641 | | // If this type hasn't been deduced yet, then conservatively assume that |
2642 | | // it'll work out to be a literal type. |
2643 | 55.8k | if (isa<AutoType>(BaseTy->getCanonicalTypeInternal())) |
2644 | 1 | return true; |
2645 | | |
2646 | 55.8k | return false; |
2647 | 55.8k | } |
2648 | | |
2649 | 1.84M | bool Type::isStructuralType() const { |
2650 | | // C++20 [temp.param]p6: |
2651 | | // A structural type is one of the following: |
2652 | | // -- a scalar type; or |
2653 | | // -- a vector type [Clang extension]; or |
2654 | 1.84M | if (isScalarType() || isVectorType()306k ) |
2655 | 1.53M | return true; |
2656 | | // -- an lvalue reference type; or |
2657 | 302k | if (isLValueReferenceType()) |
2658 | 210k | return true; |
2659 | | // -- a literal class type [...under some conditions] |
2660 | 92.7k | if (const CXXRecordDecl *RD = getAsCXXRecordDecl()) |
2661 | 339 | return RD->isStructural(); |
2662 | 92.4k | return false; |
2663 | 92.7k | } |
2664 | | |
2665 | 1.20k | bool Type::isStandardLayoutType() const { |
2666 | 1.20k | if (isDependentType()) |
2667 | 0 | return false; |
2668 | | |
2669 | | // C++0x [basic.types]p9: |
2670 | | // Scalar types, standard-layout class types, arrays of such types, and |
2671 | | // cv-qualified versions of these types are collectively called |
2672 | | // standard-layout types. |
2673 | 1.20k | const Type *BaseTy = getBaseElementTypeUnsafe(); |
2674 | 1.20k | assert(BaseTy && "NULL element type"); |
2675 | | |
2676 | | // Return false for incomplete types after skipping any incomplete array |
2677 | | // types which are expressly allowed by the standard and thus our API. |
2678 | 1.20k | if (BaseTy->isIncompleteType()) |
2679 | 6 | return false; |
2680 | | |
2681 | | // As an extension, Clang treats vector types as Scalar types. |
2682 | 1.19k | if (BaseTy->isScalarType() || BaseTy->isVectorType()405 ) return true816 ; |
2683 | 381 | if (const auto *RT = BaseTy->getAs<RecordType>()) { |
2684 | 377 | if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) |
2685 | 265 | if (!ClassDecl->isStandardLayout()) |
2686 | 105 | return false; |
2687 | | |
2688 | | // Default to 'true' for non-C++ class types. |
2689 | | // FIXME: This is a bit dubious, but plain C structs should trivially meet |
2690 | | // all the requirements of standard layout classes. |
2691 | 272 | return true; |
2692 | 377 | } |
2693 | | |
2694 | | // No other types can match. |
2695 | 4 | return false; |
2696 | 381 | } |
2697 | | |
2698 | | // This is effectively the intersection of isTrivialType and |
2699 | | // isStandardLayoutType. We implement it directly to avoid redundant |
2700 | | // conversions from a type to a CXXRecordDecl. |
2701 | 1.27M | bool QualType::isCXX11PODType(const ASTContext &Context) const { |
2702 | 1.27M | const Type *ty = getTypePtr(); |
2703 | 1.27M | if (ty->isDependentType()) |
2704 | 30.8k | return false; |
2705 | | |
2706 | 1.23M | if (hasNonTrivialObjCLifetime()) |
2707 | 47 | return false; |
2708 | | |
2709 | | // C++11 [basic.types]p9: |
2710 | | // Scalar types, POD classes, arrays of such types, and cv-qualified |
2711 | | // versions of these types are collectively called trivial types. |
2712 | 1.23M | const Type *BaseTy = ty->getBaseElementTypeUnsafe(); |
2713 | 1.23M | assert(BaseTy && "NULL element type"); |
2714 | | |
2715 | 1.23M | if (BaseTy->isSizelessBuiltinType()) |
2716 | 39 | return true; |
2717 | | |
2718 | | // Return false for incomplete types after skipping any incomplete array |
2719 | | // types which are expressly allowed by the standard and thus our API. |
2720 | 1.23M | if (BaseTy->isIncompleteType()) |
2721 | 75.7k | return false; |
2722 | | |
2723 | | // As an extension, Clang treats vector types as Scalar types. |
2724 | 1.16M | if (BaseTy->isScalarType() || BaseTy->isVectorType()116k ) return true1.04M ; |
2725 | 115k | if (const auto *RT = BaseTy->getAs<RecordType>()) { |
2726 | 92.6k | if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) { |
2727 | | // C++11 [class]p10: |
2728 | | // A POD struct is a non-union class that is both a trivial class [...] |
2729 | 92.6k | if (!ClassDecl->isTrivial()) return false54.6k ; |
2730 | | |
2731 | | // C++11 [class]p10: |
2732 | | // A POD struct is a non-union class that is both a trivial class and |
2733 | | // a standard-layout class [...] |
2734 | 37.9k | if (!ClassDecl->isStandardLayout()) return false333 ; |
2735 | | |
2736 | | // C++11 [class]p10: |
2737 | | // A POD struct is a non-union class that is both a trivial class and |
2738 | | // a standard-layout class, and has no non-static data members of type |
2739 | | // non-POD struct, non-POD union (or array of such types). [...] |
2740 | | // |
2741 | | // We don't directly query the recursive aspect as the requirements for |
2742 | | // both standard-layout classes and trivial classes apply recursively |
2743 | | // already. |
2744 | 37.9k | } |
2745 | | |
2746 | 37.6k | return true; |
2747 | 92.6k | } |
2748 | | |
2749 | | // No other types can match. |
2750 | 23.2k | return false; |
2751 | 115k | } |
2752 | | |
2753 | 1.64k | bool Type::isNothrowT() const { |
2754 | 1.64k | if (const auto *RD = getAsCXXRecordDecl()) { |
2755 | 1.61k | IdentifierInfo *II = RD->getIdentifier(); |
2756 | 1.61k | if (II && II->isStr("nothrow_t") && RD->isInStdNamespace()1.54k ) |
2757 | 1.54k | return true; |
2758 | 1.61k | } |
2759 | 98 | return false; |
2760 | 1.64k | } |
2761 | | |
2762 | 15.6k | bool Type::isAlignValT() const { |
2763 | 15.6k | if (const auto *ET = getAs<EnumType>()) { |
2764 | 9.10k | IdentifierInfo *II = ET->getDecl()->getIdentifier(); |
2765 | 9.10k | if (II && II->isStr("align_val_t") && ET->getDecl()->isInStdNamespace()) |
2766 | 9.10k | return true; |
2767 | 9.10k | } |
2768 | 6.55k | return false; |
2769 | 15.6k | } |
2770 | | |
2771 | 5.68k | bool Type::isStdByteType() const { |
2772 | 5.68k | if (const auto *ET = getAs<EnumType>()) { |
2773 | 37 | IdentifierInfo *II = ET->getDecl()->getIdentifier(); |
2774 | 37 | if (II && II->isStr("byte")35 && ET->getDecl()->isInStdNamespace()13 ) |
2775 | 10 | return true; |
2776 | 37 | } |
2777 | 5.67k | return false; |
2778 | 5.68k | } |
2779 | | |
2780 | 23.9M | bool Type::isPromotableIntegerType() const { |
2781 | 23.9M | if (const auto *BT = getAs<BuiltinType>()) |
2782 | 15.0M | switch (BT->getKind()) { |
2783 | 62.6k | case BuiltinType::Bool: |
2784 | 233k | case BuiltinType::Char_S: |
2785 | 234k | case BuiltinType::Char_U: |
2786 | 250k | case BuiltinType::SChar: |
2787 | 385k | case BuiltinType::UChar: |
2788 | 417k | case BuiltinType::Short: |
2789 | 471k | case BuiltinType::UShort: |
2790 | 475k | case BuiltinType::WChar_S: |
2791 | 476k | case BuiltinType::WChar_U: |
2792 | 476k | case BuiltinType::Char8: |
2793 | 479k | case BuiltinType::Char16: |
2794 | 483k | case BuiltinType::Char32: |
2795 | 483k | return true; |
2796 | 14.5M | default: |
2797 | 14.5M | return false; |
2798 | 15.0M | } |
2799 | | |
2800 | | // Enumerated types are promotable to their compatible integer types |
2801 | | // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2). |
2802 | 8.90M | if (const auto *ET = getAs<EnumType>()){ |
2803 | 8.64M | if (this->isDependentType() || ET->getDecl()->getPromotionType().isNull() |
2804 | 8.64M | || ET->getDecl()->isScoped()8.64M ) |
2805 | 192k | return false; |
2806 | | |
2807 | 8.45M | return true; |
2808 | 8.64M | } |
2809 | | |
2810 | 261k | return false; |
2811 | 8.90M | } |
2812 | | |
2813 | 6.37k | bool Type::isSpecifierType() const { |
2814 | | // Note that this intentionally does not use the canonical type. |
2815 | 6.37k | switch (getTypeClass()) { |
2816 | 2.26k | case Builtin: |
2817 | 2.27k | case Record: |
2818 | 2.27k | case Enum: |
2819 | 2.27k | case Typedef: |
2820 | 2.27k | case Complex: |
2821 | 2.27k | case TypeOfExpr: |
2822 | 2.27k | case TypeOf: |
2823 | 3.64k | case TemplateTypeParm: |
2824 | 5.74k | case SubstTemplateTypeParm: |
2825 | 5.75k | case TemplateSpecialization: |
2826 | 5.93k | case Elaborated: |
2827 | 5.93k | case DependentName: |
2828 | 5.93k | case DependentTemplateSpecialization: |
2829 | 5.93k | case ObjCInterface: |
2830 | 5.93k | case ObjCObject: |
2831 | 5.93k | return true; |
2832 | 437 | default: |
2833 | 437 | return false; |
2834 | 6.37k | } |
2835 | 6.37k | } |
2836 | | |
2837 | | ElaboratedTypeKeyword |
2838 | 2.94M | TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) { |
2839 | 2.94M | switch (TypeSpec) { |
2840 | 2 | default: return ETK_None; |
2841 | 213k | case TST_typename: return ETK_Typename; |
2842 | 15.6k | case TST_class: return ETK_Class; |
2843 | 1.82M | case TST_struct: return ETK_Struct; |
2844 | 0 | case TST_interface: return ETK_Interface; |
2845 | 61.5k | case TST_union: return ETK_Union; |
2846 | 829k | case TST_enum: return ETK_Enum; |
2847 | 2.94M | } |
2848 | 2.94M | } |
2849 | | |
2850 | | TagTypeKind |
2851 | 3.15M | TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) { |
2852 | 3.15M | switch(TypeSpec) { |
2853 | 286k | case TST_class: return TTK_Class; |
2854 | 1.94M | case TST_struct: return TTK_Struct; |
2855 | 34 | case TST_interface: return TTK_Interface; |
2856 | 47.9k | case TST_union: return TTK_Union; |
2857 | 876k | case TST_enum: return TTK_Enum; |
2858 | 3.15M | } |
2859 | | |
2860 | 0 | llvm_unreachable("Type specifier is not a tag type kind."); |
2861 | 0 | } |
2862 | | |
2863 | | ElaboratedTypeKeyword |
2864 | 183k | TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) { |
2865 | 183k | switch (Kind) { |
2866 | 40.1k | case TTK_Class: return ETK_Class; |
2867 | 136k | case TTK_Struct: return ETK_Struct; |
2868 | 1 | case TTK_Interface: return ETK_Interface; |
2869 | 5.79k | case TTK_Union: return ETK_Union; |
2870 | 1.09k | case TTK_Enum: return ETK_Enum; |
2871 | 183k | } |
2872 | 0 | llvm_unreachable("Unknown tag type kind."); |
2873 | 0 | } |
2874 | | |
2875 | | TagTypeKind |
2876 | 1.54k | TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) { |
2877 | 1.54k | switch (Keyword) { |
2878 | 1.27k | case ETK_Class: return TTK_Class; |
2879 | 246 | case ETK_Struct: return TTK_Struct; |
2880 | 0 | case ETK_Interface: return TTK_Interface; |
2881 | 6 | case ETK_Union: return TTK_Union; |
2882 | 18 | case ETK_Enum: return TTK_Enum; |
2883 | 0 | case ETK_None: // Fall through. |
2884 | 0 | case ETK_Typename: |
2885 | 0 | llvm_unreachable("Elaborated type keyword is not a tag type kind."); |
2886 | 1.54k | } |
2887 | 0 | llvm_unreachable("Unknown elaborated type keyword."); |
2888 | 0 | } |
2889 | | |
2890 | | bool |
2891 | 15.5k | TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) { |
2892 | 15.5k | switch (Keyword) { |
2893 | 0 | case ETK_None: |
2894 | 1.26k | case ETK_Typename: |
2895 | 1.26k | return false; |
2896 | 12.2k | case ETK_Class: |
2897 | 14.2k | case ETK_Struct: |
2898 | 14.2k | case ETK_Interface: |
2899 | 14.2k | case ETK_Union: |
2900 | 14.2k | case ETK_Enum: |
2901 | 14.2k | return true; |
2902 | 15.5k | } |
2903 | 0 | llvm_unreachable("Unknown elaborated type keyword."); |
2904 | 0 | } |
2905 | | |
2906 | 182k | StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) { |
2907 | 182k | switch (Keyword) { |
2908 | 1.28k | case ETK_None: return {}; |
2909 | 797 | case ETK_Typename: return "typename"; |
2910 | 34.7k | case ETK_Class: return "class"; |
2911 | 137k | case ETK_Struct: return "struct"; |
2912 | 1 | case ETK_Interface: return "__interface"; |
2913 | 5.91k | case ETK_Union: return "union"; |
2914 | 1.78k | case ETK_Enum: return "enum"; |
2915 | 182k | } |
2916 | | |
2917 | 0 | llvm_unreachable("Unknown elaborated type keyword."); |
2918 | 0 | } |
2919 | | |
2920 | | DependentTemplateSpecializationType::DependentTemplateSpecializationType( |
2921 | | ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, |
2922 | | const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args, QualType Canon) |
2923 | | : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, |
2924 | | TypeDependence::DependentInstantiation | |
2925 | | (NNS ? toTypeDependence(NNS->getDependence()) |
2926 | | : TypeDependence::None)), |
2927 | 47.7k | NNS(NNS), Name(Name) { |
2928 | 47.7k | DependentTemplateSpecializationTypeBits.NumArgs = Args.size(); |
2929 | 47.7k | assert((!NNS || NNS->isDependent()) && |
2930 | 47.7k | "DependentTemplateSpecializatonType requires dependent qualifier"); |
2931 | 0 | TemplateArgument *ArgBuffer = getArgBuffer(); |
2932 | 82.7k | for (const TemplateArgument &Arg : Args) { |
2933 | 82.7k | addDependence(toTypeDependence(Arg.getDependence() & |
2934 | 82.7k | TemplateArgumentDependence::UnexpandedPack)); |
2935 | | |
2936 | 82.7k | new (ArgBuffer++) TemplateArgument(Arg); |
2937 | 82.7k | } |
2938 | 47.7k | } |
2939 | | |
2940 | | void |
2941 | | DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, |
2942 | | const ASTContext &Context, |
2943 | | ElaboratedTypeKeyword Keyword, |
2944 | | NestedNameSpecifier *Qualifier, |
2945 | | const IdentifierInfo *Name, |
2946 | 97.4k | ArrayRef<TemplateArgument> Args) { |
2947 | 97.4k | ID.AddInteger(Keyword); |
2948 | 97.4k | ID.AddPointer(Qualifier); |
2949 | 97.4k | ID.AddPointer(Name); |
2950 | 97.4k | for (const TemplateArgument &Arg : Args) |
2951 | 168k | Arg.Profile(ID, Context); |
2952 | 97.4k | } |
2953 | | |
2954 | 15.5k | bool Type::isElaboratedTypeSpecifier() const { |
2955 | 15.5k | ElaboratedTypeKeyword Keyword; |
2956 | 15.5k | if (const auto *Elab = dyn_cast<ElaboratedType>(this)) |
2957 | 14.2k | Keyword = Elab->getKeyword(); |
2958 | 1.35k | else if (const auto *DepName = dyn_cast<DependentNameType>(this)) |
2959 | 1.27k | Keyword = DepName->getKeyword(); |
2960 | 87 | else if (const auto *DepTST = |
2961 | 87 | dyn_cast<DependentTemplateSpecializationType>(this)) |
2962 | 0 | Keyword = DepTST->getKeyword(); |
2963 | 87 | else |
2964 | 87 | return false; |
2965 | | |
2966 | 15.5k | return TypeWithKeyword::KeywordIsTagTypeKind(Keyword); |
2967 | 15.5k | } |
2968 | | |
2969 | 6.30k | const char *Type::getTypeClassName() const { |
2970 | 6.30k | switch (TypeBits.TC) { |
2971 | 0 | #define ABSTRACT_TYPE(Derived, Base) |
2972 | 6.30k | #define TYPE(Derived, Base) case Derived: return #Derived; |
2973 | 6.30k | #include "clang/AST/TypeNodes.inc"0 |
2974 | 6.30k | } |
2975 | | |
2976 | 0 | llvm_unreachable("Invalid type class."); |
2977 | 0 | } |
2978 | | |
2979 | 1.32M | StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { |
2980 | 1.32M | switch (getKind()) { |
2981 | 146k | case Void: |
2982 | 146k | return "void"; |
2983 | 67.8k | case Bool: |
2984 | 67.8k | return Policy.Bool ? "bool"66.6k : "_Bool"1.25k ; |
2985 | 377k | case Char_S: |
2986 | 377k | return "char"; |
2987 | 319 | case Char_U: |
2988 | 319 | return "char"; |
2989 | 4.17k | case SChar: |
2990 | 4.17k | return "signed char"; |
2991 | 8.86k | case Short: |
2992 | 8.86k | return "short"; |
2993 | 383k | case Int: |
2994 | 383k | return "int"; |
2995 | 20.2k | case Long: |
2996 | 20.2k | return "long"; |
2997 | 27.8k | case LongLong: |
2998 | 27.8k | return "long long"; |
2999 | 2.72k | case Int128: |
3000 | 2.72k | return "__int128"; |
3001 | 24.6k | case UChar: |
3002 | 24.6k | return "unsigned char"; |
3003 | 6.16k | case UShort: |
3004 | 6.16k | return "unsigned short"; |
3005 | 31.8k | case UInt: |
3006 | 31.8k | return "unsigned int"; |
3007 | 32.4k | case ULong: |
3008 | 32.4k | return "unsigned long"; |
3009 | 6.32k | case ULongLong: |
3010 | 6.32k | return "unsigned long long"; |
3011 | 1.48k | case UInt128: |
3012 | 1.48k | return "unsigned __int128"; |
3013 | 746 | case Half: |
3014 | 746 | return Policy.Half ? "half"235 : "__fp16"511 ; |
3015 | 306 | case BFloat16: |
3016 | 306 | return "__bf16"; |
3017 | 33.1k | case Float: |
3018 | 33.1k | return "float"; |
3019 | 38.0k | case Double: |
3020 | 38.0k | return "double"; |
3021 | 6.05k | case LongDouble: |
3022 | 6.05k | return "long double"; |
3023 | 75 | case ShortAccum: |
3024 | 75 | return "short _Accum"; |
3025 | 139 | case Accum: |
3026 | 139 | return "_Accum"; |
3027 | 45 | case LongAccum: |
3028 | 45 | return "long _Accum"; |
3029 | 28 | case UShortAccum: |
3030 | 28 | return "unsigned short _Accum"; |
3031 | 22 | case UAccum: |
3032 | 22 | return "unsigned _Accum"; |
3033 | 16 | case ULongAccum: |
3034 | 16 | return "unsigned long _Accum"; |
3035 | 35 | case BuiltinType::ShortFract: |
3036 | 35 | return "short _Fract"; |
3037 | 39 | case BuiltinType::Fract: |
3038 | 39 | return "_Fract"; |
3039 | 33 | case BuiltinType::LongFract: |
3040 | 33 | return "long _Fract"; |
3041 | 20 | case BuiltinType::UShortFract: |
3042 | 20 | return "unsigned short _Fract"; |
3043 | 22 | case BuiltinType::UFract: |
3044 | 22 | return "unsigned _Fract"; |
3045 | 20 | case BuiltinType::ULongFract: |
3046 | 20 | return "unsigned long _Fract"; |
3047 | 17 | case BuiltinType::SatShortAccum: |
3048 | 17 | return "_Sat short _Accum"; |
3049 | 17 | case BuiltinType::SatAccum: |
3050 | 17 | return "_Sat _Accum"; |
3051 | 17 | case BuiltinType::SatLongAccum: |
3052 | 17 | return "_Sat long _Accum"; |
3053 | 8 | case BuiltinType::SatUShortAccum: |
3054 | 8 | return "_Sat unsigned short _Accum"; |
3055 | 8 | case BuiltinType::SatUAccum: |
3056 | 8 | return "_Sat unsigned _Accum"; |
3057 | 8 | case BuiltinType::SatULongAccum: |
3058 | 8 | return "_Sat unsigned long _Accum"; |
3059 | 17 | case BuiltinType::SatShortFract: |
3060 | 17 | return "_Sat short _Fract"; |
3061 | 17 | case BuiltinType::SatFract: |
3062 | 17 | return "_Sat _Fract"; |
3063 | 17 | case BuiltinType::SatLongFract: |
3064 | 17 | return "_Sat long _Fract"; |
3065 | 8 | case BuiltinType::SatUShortFract: |
3066 | 8 | return "_Sat unsigned short _Fract"; |
3067 | 8 | case BuiltinType::SatUFract: |
3068 | 8 | return "_Sat unsigned _Fract"; |
3069 | 8 | case BuiltinType::SatULongFract: |
3070 | 8 | return "_Sat unsigned long _Fract"; |
3071 | 923 | case Float16: |
3072 | 923 | return "_Float16"; |
3073 | 209 | case Float128: |
3074 | 209 | return "__float128"; |
3075 | 114 | case Ibm128: |
3076 | 114 | return "__ibm128"; |
3077 | 25.3k | case WChar_S: |
3078 | 25.3k | case WChar_U: |
3079 | 25.3k | return Policy.MSWChar ? "__wchar_t"8 : "wchar_t"25.3k ; |
3080 | 1.08k | case Char8: |
3081 | 1.08k | return "char8_t"; |
3082 | 18.6k | case Char16: |
3083 | 18.6k | return "char16_t"; |
3084 | 18.6k | case Char32: |
3085 | 18.6k | return "char32_t"; |
3086 | 3.96k | case NullPtr: |
3087 | 3.96k | return "std::nullptr_t"; |
3088 | 295 | case Overload: |
3089 | 295 | return "<overloaded function type>"; |
3090 | 443 | case BoundMember: |
3091 | 443 | return "<bound member function type>"; |
3092 | 10 | case PseudoObject: |
3093 | 10 | return "<pseudo-object type>"; |
3094 | 481 | case Dependent: |
3095 | 481 | return "<dependent type>"; |
3096 | 28 | case UnknownAny: |
3097 | 28 | return "<unknown type>"; |
3098 | 0 | case ARCUnbridgedCast: |
3099 | 0 | return "<ARC unbridged cast type>"; |
3100 | 71 | case BuiltinFn: |
3101 | 71 | return "<builtin fn type>"; |
3102 | 6.18k | case ObjCId: |
3103 | 6.18k | return "id"; |
3104 | 1.17k | case ObjCClass: |
3105 | 1.17k | return "Class"; |
3106 | 643 | case ObjCSel: |
3107 | 643 | return "SEL"; |
3108 | 0 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ |
3109 | 780 | case Id: \ |
3110 | 780 | return "__" #Access " " #ImgType "_t"; |
3111 | 643 | #include "clang/Basic/OpenCLImageTypes.def" |
3112 | 221 | case OCLSampler: |
3113 | 221 | return "sampler_t"; |
3114 | 39 | case OCLEvent: |
3115 | 39 | return "event_t"; |
3116 | 76 | case OCLClkEvent: |
3117 | 76 | return "clk_event_t"; |
3118 | 67 | case OCLQueue: |
3119 | 67 | return "queue_t"; |
3120 | 93 | case OCLReserveID: |
3121 | 93 | return "reserve_id_t"; |
3122 | 0 | case IncompleteMatrixIdx: |
3123 | 0 | return "<incomplete matrix index type>"; |
3124 | 8 | case OMPArraySection: |
3125 | 8 | return "<OpenMP array section type>"; |
3126 | 0 | case OMPArrayShaping: |
3127 | 0 | return "<OpenMP array shaping type>"; |
3128 | 0 | case OMPIterator: |
3129 | 0 | return "<OpenMP iterator type>"; |
3130 | 0 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
3131 | 332 | case Id: \ |
3132 | 332 | return #ExtType; |
3133 | 0 | #include "clang/Basic/OpenCLExtensionTypes.def" |
3134 | 0 | #define SVE_TYPE(Name, Id, SingletonId) \ |
3135 | 25.0k | case Id: \ |
3136 | 25.0k | return Name; |
3137 | 26 | #include "clang/Basic/AArch64SVEACLETypes.def" |
3138 | 0 | #define PPC_VECTOR_TYPE(Name, Id, Size) \ |
3139 | 218 | case Id: \ |
3140 | 218 | return #Name; |
3141 | 1.71k | #include "clang/Basic/PPCTypes.def" |
3142 | 0 | #define RVV_TYPE(Name, Id, SingletonId) \ |
3143 | 132 | case Id: \ |
3144 | 132 | return Name; |
3145 | 1.32M | #include "clang/Basic/RISCVVTypes.def"116 |
3146 | 1.32M | } |
3147 | | |
3148 | 0 | llvm_unreachable("Invalid builtin type."); |
3149 | 0 | } |
3150 | | |
3151 | 19.1M | QualType QualType::getNonPackExpansionType() const { |
3152 | | // We never wrap type sugar around a PackExpansionType. |
3153 | 19.1M | if (auto *PET = dyn_cast<PackExpansionType>(getTypePtr())) |
3154 | 38.6k | return PET->getPattern(); |
3155 | 19.1M | return *this; |
3156 | 19.1M | } |
3157 | | |
3158 | 16.5M | QualType QualType::getNonLValueExprType(const ASTContext &Context) const { |
3159 | 16.5M | if (const auto *RefType = getTypePtr()->getAs<ReferenceType>()) |
3160 | 566k | return RefType->getPointeeType(); |
3161 | | |
3162 | | // C++0x [basic.lval]: |
3163 | | // Class prvalues can have cv-qualified types; non-class prvalues always |
3164 | | // have cv-unqualified types. |
3165 | | // |
3166 | | // See also C99 6.3.2.1p2. |
3167 | 16.0M | if (!Context.getLangOpts().CPlusPlus || |
3168 | 16.0M | (4.85M !getTypePtr()->isDependentType()4.85M && !getTypePtr()->isRecordType()4.60M )) |
3169 | 15.4M | return getUnqualifiedType(); |
3170 | | |
3171 | 575k | return *this; |
3172 | 16.0M | } |
3173 | | |
3174 | 324 | StringRef FunctionType::getNameForCallConv(CallingConv CC) { |
3175 | 324 | switch (CC) { |
3176 | 139 | case CC_C: return "cdecl"; |
3177 | 80 | case CC_X86StdCall: return "stdcall"; |
3178 | 32 | case CC_X86FastCall: return "fastcall"; |
3179 | 10 | case CC_X86ThisCall: return "thiscall"; |
3180 | 1 | case CC_X86Pascal: return "pascal"; |
3181 | 22 | case CC_X86VectorCall: return "vectorcall"; |
3182 | 3 | case CC_Win64: return "ms_abi"; |
3183 | 0 | case CC_X86_64SysV: return "sysv_abi"; |
3184 | 1 | case CC_X86RegCall : return "regcall"; |
3185 | 0 | case CC_AAPCS: return "aapcs"; |
3186 | 0 | case CC_AAPCS_VFP: return "aapcs-vfp"; |
3187 | 3 | case CC_AArch64VectorCall: return "aarch64_vector_pcs"; |
3188 | 3 | case CC_AArch64SVEPCS: return "aarch64_sve_pcs"; |
3189 | 0 | case CC_AMDGPUKernelCall: return "amdgpu_kernel"; |
3190 | 0 | case CC_IntelOclBicc: return "intel_ocl_bicc"; |
3191 | 0 | case CC_SpirFunction: return "spir_function"; |
3192 | 0 | case CC_OpenCLKernel: return "opencl_kernel"; |
3193 | 8 | case CC_Swift: return "swiftcall"; |
3194 | 8 | case CC_SwiftAsync: return "swiftasynccall"; |
3195 | 6 | case CC_PreserveMost: return "preserve_most"; |
3196 | 8 | case CC_PreserveAll: return "preserve_all"; |
3197 | 324 | } |
3198 | | |
3199 | 0 | llvm_unreachable("Invalid calling convention."); |
3200 | 0 | } |
3201 | | |
3202 | | FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params, |
3203 | | QualType canonical, |
3204 | | const ExtProtoInfo &epi) |
3205 | | : FunctionType(FunctionProto, result, canonical, result->getDependence(), |
3206 | 16.5M | epi.ExtInfo) { |
3207 | 16.5M | FunctionTypeBits.FastTypeQuals = epi.TypeQuals.getFastQualifiers(); |
3208 | 16.5M | FunctionTypeBits.RefQualifier = epi.RefQualifier; |
3209 | 16.5M | FunctionTypeBits.NumParams = params.size(); |
3210 | 16.5M | assert(getNumParams() == params.size() && "NumParams overflow!"); |
3211 | 0 | FunctionTypeBits.ExceptionSpecType = epi.ExceptionSpec.Type; |
3212 | 16.5M | FunctionTypeBits.HasExtParameterInfos = !!epi.ExtParameterInfos; |
3213 | 16.5M | FunctionTypeBits.Variadic = epi.Variadic; |
3214 | 16.5M | FunctionTypeBits.HasTrailingReturn = epi.HasTrailingReturn; |
3215 | | |
3216 | 16.5M | if (epi.requiresFunctionProtoTypeExtraBitfields()) { |
3217 | 624 | FunctionTypeBits.HasExtraBitfields = true; |
3218 | 624 | auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>(); |
3219 | 624 | ExtraBits = FunctionTypeExtraBitfields(); |
3220 | 16.5M | } else { |
3221 | 16.5M | FunctionTypeBits.HasExtraBitfields = false; |
3222 | 16.5M | } |
3223 | | |
3224 | | |
3225 | | // Fill in the trailing argument array. |
3226 | 16.5M | auto *argSlot = getTrailingObjects<QualType>(); |
3227 | 49.7M | for (unsigned i = 0; i != getNumParams(); ++i33.1M ) { |
3228 | 33.1M | addDependence(params[i]->getDependence() & |
3229 | 33.1M | ~TypeDependence::VariablyModified); |
3230 | 33.1M | argSlot[i] = params[i]; |
3231 | 33.1M | } |
3232 | | |
3233 | | // Fill in the exception type array if present. |
3234 | 16.5M | if (getExceptionSpecType() == EST_Dynamic) { |
3235 | 624 | auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>(); |
3236 | 624 | ExtraBits.NumExceptionType = epi.ExceptionSpec.Exceptions.size(); |
3237 | | |
3238 | 624 | assert(hasExtraBitfields() && "missing trailing extra bitfields!"); |
3239 | 0 | auto *exnSlot = |
3240 | 624 | reinterpret_cast<QualType *>(getTrailingObjects<ExceptionType>()); |
3241 | 624 | unsigned I = 0; |
3242 | 706 | for (QualType ExceptionType : epi.ExceptionSpec.Exceptions) { |
3243 | | // Note that, before C++17, a dependent exception specification does |
3244 | | // *not* make a type dependent; it's not even part of the C++ type |
3245 | | // system. |
3246 | 706 | addDependence( |
3247 | 706 | ExceptionType->getDependence() & |
3248 | 706 | (TypeDependence::Instantiation | TypeDependence::UnexpandedPack)); |
3249 | | |
3250 | 706 | exnSlot[I++] = ExceptionType; |
3251 | 706 | } |
3252 | 624 | } |
3253 | | // Fill in the Expr * in the exception specification if present. |
3254 | 16.5M | else if (isComputedNoexcept(getExceptionSpecType())) { |
3255 | 332k | assert(epi.ExceptionSpec.NoexceptExpr && "computed noexcept with no expr"); |
3256 | 0 | assert((getExceptionSpecType() == EST_DependentNoexcept) == |
3257 | 332k | epi.ExceptionSpec.NoexceptExpr->isValueDependent()); |
3258 | | |
3259 | | // Store the noexcept expression and context. |
3260 | 0 | *getTrailingObjects<Expr *>() = epi.ExceptionSpec.NoexceptExpr; |
3261 | | |
3262 | 332k | addDependence( |
3263 | 332k | toTypeDependence(epi.ExceptionSpec.NoexceptExpr->getDependence()) & |
3264 | 332k | (TypeDependence::Instantiation | TypeDependence::UnexpandedPack)); |
3265 | 332k | } |
3266 | | // Fill in the FunctionDecl * in the exception specification if present. |
3267 | 16.2M | else if (getExceptionSpecType() == EST_Uninstantiated) { |
3268 | | // Store the function decl from which we will resolve our |
3269 | | // exception specification. |
3270 | 103k | auto **slot = getTrailingObjects<FunctionDecl *>(); |
3271 | 103k | slot[0] = epi.ExceptionSpec.SourceDecl; |
3272 | 103k | slot[1] = epi.ExceptionSpec.SourceTemplate; |
3273 | | // This exception specification doesn't make the type dependent, because |
3274 | | // it's not instantiated as part of instantiating the type. |
3275 | 16.1M | } else if (getExceptionSpecType() == EST_Unevaluated) { |
3276 | | // Store the function decl from which we will resolve our |
3277 | | // exception specification. |
3278 | 575k | auto **slot = getTrailingObjects<FunctionDecl *>(); |
3279 | 575k | slot[0] = epi.ExceptionSpec.SourceDecl; |
3280 | 575k | } |
3281 | | |
3282 | | // If this is a canonical type, and its exception specification is dependent, |
3283 | | // then it's a dependent type. This only happens in C++17 onwards. |
3284 | 16.5M | if (isCanonicalUnqualified()) { |
3285 | 7.42M | if (getExceptionSpecType() == EST_Dynamic || |
3286 | 7.42M | getExceptionSpecType() == EST_DependentNoexcept7.42M ) { |
3287 | 5.05k | assert(hasDependentExceptionSpec() && "type should not be canonical"); |
3288 | 0 | addDependence(TypeDependence::DependentInstantiation); |
3289 | 5.05k | } |
3290 | 9.15M | } else if (getCanonicalTypeInternal()->isDependentType()) { |
3291 | | // Ask our canonical type whether our exception specification was dependent. |
3292 | 2.51M | addDependence(TypeDependence::DependentInstantiation); |
3293 | 2.51M | } |
3294 | | |
3295 | | // Fill in the extra parameter info if present. |
3296 | 16.5M | if (epi.ExtParameterInfos) { |
3297 | 13.3k | auto *extParamInfos = getTrailingObjects<ExtParameterInfo>(); |
3298 | 55.1k | for (unsigned i = 0; i != getNumParams(); ++i41.7k ) |
3299 | 41.7k | extParamInfos[i] = epi.ExtParameterInfos[i]; |
3300 | 13.3k | } |
3301 | | |
3302 | 16.5M | if (epi.TypeQuals.hasNonFastQualifiers()) { |
3303 | 623 | FunctionTypeBits.HasExtQuals = 1; |
3304 | 623 | *getTrailingObjects<Qualifiers>() = epi.TypeQuals; |
3305 | 16.5M | } else { |
3306 | 16.5M | FunctionTypeBits.HasExtQuals = 0; |
3307 | 16.5M | } |
3308 | | |
3309 | | // Fill in the Ellipsis location info if present. |
3310 | 16.5M | if (epi.Variadic) { |
3311 | 122k | auto &EllipsisLoc = *getTrailingObjects<SourceLocation>(); |
3312 | 122k | EllipsisLoc = epi.EllipsisLoc; |
3313 | 122k | } |
3314 | 16.5M | } |
3315 | | |
3316 | 35.5k | bool FunctionProtoType::hasDependentExceptionSpec() const { |
3317 | 35.5k | if (Expr *NE = getNoexceptExpr()) |
3318 | 5.10k | return NE->isValueDependent(); |
3319 | 30.4k | for (QualType ET : exceptions()) |
3320 | | // A pack expansion with a non-dependent pattern is still dependent, |
3321 | | // because we don't know whether the pattern is in the exception spec |
3322 | | // or not (that depends on whether the pack has 0 expansions). |
3323 | 224 | if (ET->isDependentType() || ET->getAs<PackExpansionType>()217 ) |
3324 | 7 | return true; |
3325 | 30.4k | return false; |
3326 | 30.4k | } |
3327 | | |
3328 | 39.8k | bool FunctionProtoType::hasInstantiationDependentExceptionSpec() const { |
3329 | 39.8k | if (Expr *NE = getNoexceptExpr()) |
3330 | 5 | return NE->isInstantiationDependent(); |
3331 | 39.8k | for (QualType ET : exceptions()) |
3332 | 25 | if (ET->isInstantiationDependentType()) |
3333 | 17 | return true; |
3334 | 39.8k | return false; |
3335 | 39.8k | } |
3336 | | |
3337 | 2.00M | CanThrowResult FunctionProtoType::canThrow() const { |
3338 | 2.00M | switch (getExceptionSpecType()) { |
3339 | 0 | case EST_Unparsed: |
3340 | 0 | case EST_Unevaluated: |
3341 | 0 | llvm_unreachable("should not call this with unresolved exception specs"); |
3342 | |
|
3343 | 1.79k | case EST_DynamicNone: |
3344 | 438k | case EST_BasicNoexcept: |
3345 | 456k | case EST_NoexceptTrue: |
3346 | 457k | case EST_NoThrow: |
3347 | 457k | return CT_Cannot; |
3348 | | |
3349 | 1.51M | case EST_None: |
3350 | 1.51M | case EST_MSAny: |
3351 | 1.52M | case EST_NoexceptFalse: |
3352 | 1.52M | return CT_Can; |
3353 | | |
3354 | 684 | case EST_Dynamic: |
3355 | | // A dynamic exception specification is throwing unless every exception |
3356 | | // type is an (unexpanded) pack expansion type. |
3357 | 688 | for (unsigned I = 0; I != getNumExceptions(); ++I4 ) |
3358 | 685 | if (!getExceptionType(I)->getAs<PackExpansionType>()) |
3359 | 681 | return CT_Can; |
3360 | 3 | return CT_Dependent; |
3361 | | |
3362 | 4 | case EST_Uninstantiated: |
3363 | 26.4k | case EST_DependentNoexcept: |
3364 | 26.4k | return CT_Dependent; |
3365 | 2.00M | } |
3366 | | |
3367 | 0 | llvm_unreachable("unexpected exception specification kind"); |
3368 | 0 | } |
3369 | | |
3370 | 113k | bool FunctionProtoType::isTemplateVariadic() const { |
3371 | 154k | for (unsigned ArgIdx = getNumParams(); ArgIdx; --ArgIdx40.6k ) |
3372 | 43.6k | if (isa<PackExpansionType>(getParamType(ArgIdx - 1))) |
3373 | 2.96k | return true; |
3374 | | |
3375 | 110k | return false; |
3376 | 113k | } |
3377 | | |
3378 | | void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, |
3379 | | const QualType *ArgTys, unsigned NumParams, |
3380 | | const ExtProtoInfo &epi, |
3381 | 100M | const ASTContext &Context, bool Canonical) { |
3382 | | // We have to be careful not to get ambiguous profile encodings. |
3383 | | // Note that valid type pointers are never ambiguous with anything else. |
3384 | | // |
3385 | | // The encoding grammar begins: |
3386 | | // type type* bool int bool |
3387 | | // If that final bool is true, then there is a section for the EH spec: |
3388 | | // bool type* |
3389 | | // This is followed by an optional "consumed argument" section of the |
3390 | | // same length as the first type sequence: |
3391 | | // bool* |
3392 | | // Finally, we have the ext info and trailing return type flag: |
3393 | | // int bool |
3394 | | // |
3395 | | // There is no ambiguity between the consumed arguments and an empty EH |
3396 | | // spec because of the leading 'bool' which unambiguously indicates |
3397 | | // whether the following bool is the EH spec or part of the arguments. |
3398 | | |
3399 | 100M | ID.AddPointer(Result.getAsOpaquePtr()); |
3400 | 320M | for (unsigned i = 0; i != NumParams; ++i219M ) |
3401 | 219M | ID.AddPointer(ArgTys[i].getAsOpaquePtr()); |
3402 | | // This method is relatively performance sensitive, so as a performance |
3403 | | // shortcut, use one AddInteger call instead of four for the next four |
3404 | | // fields. |
3405 | 100M | assert(!(unsigned(epi.Variadic) & ~1) && |
3406 | 100M | !(unsigned(epi.RefQualifier) & ~3) && |
3407 | 100M | !(unsigned(epi.ExceptionSpec.Type) & ~15) && |
3408 | 100M | "Values larger than expected."); |
3409 | 0 | ID.AddInteger(unsigned(epi.Variadic) + |
3410 | 100M | (epi.RefQualifier << 1) + |
3411 | 100M | (epi.ExceptionSpec.Type << 3)); |
3412 | 100M | ID.Add(epi.TypeQuals); |
3413 | 100M | if (epi.ExceptionSpec.Type == EST_Dynamic) { |
3414 | 1.99k | for (QualType Ex : epi.ExceptionSpec.Exceptions) |
3415 | 2.18k | ID.AddPointer(Ex.getAsOpaquePtr()); |
3416 | 100M | } else if (isComputedNoexcept(epi.ExceptionSpec.Type)) { |
3417 | 1.49M | epi.ExceptionSpec.NoexceptExpr->Profile(ID, Context, Canonical); |
3418 | 99.0M | } else if (epi.ExceptionSpec.Type == EST_Uninstantiated || |
3419 | 99.0M | epi.ExceptionSpec.Type == EST_Unevaluated98.8M ) { |
3420 | 1.61M | ID.AddPointer(epi.ExceptionSpec.SourceDecl->getCanonicalDecl()); |
3421 | 1.61M | } |
3422 | 100M | if (epi.ExtParameterInfos) { |
3423 | 253k | for (unsigned i = 0; i != NumParams; ++i193k ) |
3424 | 193k | ID.AddInteger(epi.ExtParameterInfos[i].getOpaqueValue()); |
3425 | 60.4k | } |
3426 | 100M | epi.ExtInfo.Profile(ID); |
3427 | 100M | ID.AddBoolean(epi.HasTrailingReturn); |
3428 | 100M | } |
3429 | | |
3430 | | void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, |
3431 | 56.1M | const ASTContext &Ctx) { |
3432 | 56.1M | Profile(ID, getReturnType(), param_type_begin(), getNumParams(), |
3433 | 56.1M | getExtProtoInfo(), Ctx, isCanonicalUnqualified()); |
3434 | 56.1M | } |
3435 | | |
3436 | | TypedefType::TypedefType(TypeClass tc, const TypedefNameDecl *D, |
3437 | | QualType underlying, QualType can) |
3438 | | : Type(tc, can, toSemanticDependence(underlying->getDependence())), |
3439 | 3.22M | Decl(const_cast<TypedefNameDecl *>(D)) { |
3440 | 3.22M | assert(!isa<TypedefType>(can) && "Invalid canonical type"); |
3441 | 3.22M | } |
3442 | | |
3443 | 109M | QualType TypedefType::desugar() const { |
3444 | 109M | return getDecl()->getUnderlyingType(); |
3445 | 109M | } |
3446 | | |
3447 | | UsingType::UsingType(const UsingShadowDecl *Found, QualType Underlying, |
3448 | | QualType Canon) |
3449 | | : Type(Using, Canon, toSemanticDependence(Underlying->getDependence())), |
3450 | 26.6k | Found(const_cast<UsingShadowDecl *>(Found)) { |
3451 | 26.6k | assert(Underlying == getUnderlyingType()); |
3452 | 26.6k | } |
3453 | | |
3454 | 1.43M | QualType UsingType::getUnderlyingType() const { |
3455 | 1.43M | return QualType(cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl(), 0); |
3456 | 1.43M | } |
3457 | | |
3458 | 421k | QualType MacroQualifiedType::desugar() const { return getUnderlyingType(); } |
3459 | | |
3460 | 90 | QualType MacroQualifiedType::getModifiedType() const { |
3461 | | // Step over MacroQualifiedTypes from the same macro to find the type |
3462 | | // ultimately qualified by the macro qualifier. |
3463 | 90 | QualType Inner = cast<AttributedType>(getUnderlyingType())->getModifiedType(); |
3464 | 106 | while (auto *InnerMQT = dyn_cast<MacroQualifiedType>(Inner)) { |
3465 | 16 | if (InnerMQT->getMacroIdentifier() != getMacroIdentifier()) |
3466 | 0 | break; |
3467 | 16 | Inner = InnerMQT->getModifiedType(); |
3468 | 16 | } |
3469 | 90 | return Inner; |
3470 | 90 | } |
3471 | | |
3472 | | TypeOfExprType::TypeOfExprType(Expr *E, QualType can) |
3473 | | : Type(TypeOfExpr, can, |
3474 | | toTypeDependence(E->getDependence()) | |
3475 | | (E->getType()->getDependence() & |
3476 | | TypeDependence::VariablyModified)), |
3477 | 3.23k | TOExpr(E) {} |
3478 | | |
3479 | 27.6k | bool TypeOfExprType::isSugared() const { |
3480 | 27.6k | return !TOExpr->isTypeDependent(); |
3481 | 27.6k | } |
3482 | | |
3483 | 13.9k | QualType TypeOfExprType::desugar() const { |
3484 | 13.9k | if (isSugared()) |
3485 | 13.9k | return getUnderlyingExpr()->getType(); |
3486 | | |
3487 | 0 | return QualType(this, 0); |
3488 | 13.9k | } |
3489 | | |
3490 | | void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, |
3491 | 2.10k | const ASTContext &Context, Expr *E) { |
3492 | 2.10k | E->Profile(ID, Context, true); |
3493 | 2.10k | } |
3494 | | |
3495 | | DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) |
3496 | | // C++11 [temp.type]p2: "If an expression e involves a template parameter, |
3497 | | // decltype(e) denotes a unique dependent type." Hence a decltype type is |
3498 | | // type-dependent even if its expression is only instantiation-dependent. |
3499 | | : Type(Decltype, can, |
3500 | | toTypeDependence(E->getDependence()) | |
3501 | | (E->isInstantiationDependent() ? TypeDependence::Dependent |
3502 | | : TypeDependence::None) | |
3503 | | (E->getType()->getDependence() & |
3504 | | TypeDependence::VariablyModified)), |
3505 | 350k | E(E), UnderlyingType(underlyingType) {} |
3506 | | |
3507 | 508k | bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); } |
3508 | | |
3509 | 249k | QualType DecltypeType::desugar() const { |
3510 | 249k | if (isSugared()) |
3511 | 249k | return getUnderlyingType(); |
3512 | | |
3513 | 0 | return QualType(this, 0); |
3514 | 249k | } |
3515 | | |
3516 | | DependentDecltypeType::DependentDecltypeType(const ASTContext &Context, Expr *E) |
3517 | 87.8k | : DecltypeType(E, Context.DependentTy), Context(Context) {} |
3518 | | |
3519 | | void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, |
3520 | 276k | const ASTContext &Context, Expr *E) { |
3521 | 276k | E->Profile(ID, Context, true); |
3522 | 276k | } |
3523 | | |
3524 | | UnaryTransformType::UnaryTransformType(QualType BaseType, |
3525 | | QualType UnderlyingType, UTTKind UKind, |
3526 | | QualType CanonicalType) |
3527 | | : Type(UnaryTransform, CanonicalType, BaseType->getDependence()), |
3528 | 2.53k | BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) {} |
3529 | | |
3530 | | DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C, |
3531 | | QualType BaseType, |
3532 | | UTTKind UKind) |
3533 | 515 | : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) {} |
3534 | | |
3535 | | TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) |
3536 | | : Type(TC, can, |
3537 | | D->isDependentType() ? TypeDependence::DependentInstantiation |
3538 | | : TypeDependence::None), |
3539 | 4.65M | decl(const_cast<TagDecl *>(D)) {} |
3540 | | |
3541 | 198M | static TagDecl *getInterestingTagDecl(TagDecl *decl) { |
3542 | 209M | for (auto I : decl->redecls()) { |
3543 | 209M | if (I->isCompleteDefinition() || I->isBeingDefined()35.8M ) |
3544 | 191M | return I; |
3545 | 209M | } |
3546 | | // If there's no definition (not even in progress), return what we have. |
3547 | 7.16M | return decl; |
3548 | 198M | } |
3549 | | |
3550 | 194M | TagDecl *TagType::getDecl() const { |
3551 | 194M | return getInterestingTagDecl(decl); |
3552 | 194M | } |
3553 | | |
3554 | 3.33M | bool TagType::isBeingDefined() const { |
3555 | 3.33M | return getDecl()->isBeingDefined(); |
3556 | 3.33M | } |
3557 | | |
3558 | 1.75k | bool RecordType::hasConstFields() const { |
3559 | 1.75k | std::vector<const RecordType*> RecordTypeList; |
3560 | 1.75k | RecordTypeList.push_back(this); |
3561 | 1.75k | unsigned NextToCheckIndex = 0; |
3562 | | |
3563 | 3.60k | while (RecordTypeList.size() > NextToCheckIndex) { |
3564 | 1.86k | for (FieldDecl *FD : |
3565 | 3.18k | RecordTypeList[NextToCheckIndex]->getDecl()->fields()) { |
3566 | 3.18k | QualType FieldTy = FD->getType(); |
3567 | 3.18k | if (FieldTy.isConstQualified()) |
3568 | 16 | return true; |
3569 | 3.17k | FieldTy = FieldTy.getCanonicalType(); |
3570 | 3.17k | if (const auto *FieldRecTy = FieldTy->getAs<RecordType>()) { |
3571 | 127 | if (!llvm::is_contained(RecordTypeList, FieldRecTy)) |
3572 | 115 | RecordTypeList.push_back(FieldRecTy); |
3573 | 127 | } |
3574 | 3.17k | } |
3575 | 1.85k | ++NextToCheckIndex; |
3576 | 1.85k | } |
3577 | 1.73k | return false; |
3578 | 1.75k | } |
3579 | | |
3580 | 23 | bool AttributedType::isQualifier() const { |
3581 | | // FIXME: Generate this with TableGen. |
3582 | 23 | switch (getAttrKind()) { |
3583 | | // These are type qualifiers in the traditional C sense: they annotate |
3584 | | // something about a specific value/variable of a type. (They aren't |
3585 | | // always part of the canonical type, though.) |
3586 | 0 | case attr::ObjCGC: |
3587 | 17 | case attr::ObjCOwnership: |
3588 | 17 | case attr::ObjCInertUnsafeUnretained: |
3589 | 18 | case attr::TypeNonNull: |
3590 | 19 | case attr::TypeNullable: |
3591 | 19 | case attr::TypeNullableResult: |
3592 | 19 | case attr::TypeNullUnspecified: |
3593 | 19 | case attr::LifetimeBound: |
3594 | 23 | case attr::AddressSpace: |
3595 | 23 | return true; |
3596 | | |
3597 | | // All other type attributes aren't qualifiers; they rewrite the modified |
3598 | | // type to be a semantically different type. |
3599 | 0 | default: |
3600 | 0 | return false; |
3601 | 23 | } |
3602 | 23 | } |
3603 | | |
3604 | 2.41k | bool AttributedType::isMSTypeSpec() const { |
3605 | | // FIXME: Generate this with TableGen? |
3606 | 2.41k | switch (getAttrKind()) { |
3607 | 2.39k | default: return false; |
3608 | 10 | case attr::Ptr32: |
3609 | 14 | case attr::Ptr64: |
3610 | 18 | case attr::SPtr: |
3611 | 22 | case attr::UPtr: |
3612 | 22 | return true; |
3613 | 2.41k | } |
3614 | 0 | llvm_unreachable("invalid attr kind"); |
3615 | 0 | } |
3616 | | |
3617 | 1.38k | bool AttributedType::isCallingConv() const { |
3618 | | // FIXME: Generate this with TableGen. |
3619 | 1.38k | switch (getAttrKind()) { |
3620 | 929 | default: return false; |
3621 | 0 | case attr::Pcs: |
3622 | 193 | case attr::CDecl: |
3623 | 240 | case attr::FastCall: |
3624 | 305 | case attr::StdCall: |
3625 | 340 | case attr::ThisCall: |
3626 | 342 | case attr::RegCall: |
3627 | 345 | case attr::SwiftCall: |
3628 | 348 | case attr::SwiftAsyncCall: |
3629 | 382 | case attr::VectorCall: |
3630 | 385 | case attr::AArch64VectorPcs: |
3631 | 388 | case attr::AArch64SVEPcs: |
3632 | 388 | case attr::AMDGPUKernelCall: |
3633 | 388 | case attr::Pascal: |
3634 | 397 | case attr::MSABI: |
3635 | 404 | case attr::SysVABI: |
3636 | 404 | case attr::IntelOclBicc: |
3637 | 430 | case attr::PreserveMost: |
3638 | 456 | case attr::PreserveAll: |
3639 | 456 | return true; |
3640 | 1.38k | } |
3641 | 0 | llvm_unreachable("invalid attr kind"); |
3642 | 0 | } |
3643 | | |
3644 | 4.17M | CXXRecordDecl *InjectedClassNameType::getDecl() const { |
3645 | 4.17M | return cast<CXXRecordDecl>(getInterestingTagDecl(Decl)); |
3646 | 4.17M | } |
3647 | | |
3648 | 588k | IdentifierInfo *TemplateTypeParmType::getIdentifier() const { |
3649 | 588k | return isCanonicalUnqualified() ? nullptr4.44k : getDecl()->getIdentifier()584k ; |
3650 | 588k | } |
3651 | | |
3652 | | SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType( |
3653 | | const TemplateTypeParmType *Param, QualType Canon, |
3654 | | const TemplateArgument &ArgPack) |
3655 | | : Type(SubstTemplateTypeParmPack, Canon, |
3656 | | TypeDependence::DependentInstantiation | |
3657 | | TypeDependence::UnexpandedPack), |
3658 | 10.8k | Replaced(Param), Arguments(ArgPack.pack_begin()) { |
3659 | 10.8k | SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size(); |
3660 | 10.8k | } |
3661 | | |
3662 | 42.4k | TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const { |
3663 | 42.4k | return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs())); |
3664 | 42.4k | } |
3665 | | |
3666 | 21.3k | void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) { |
3667 | 21.3k | Profile(ID, getReplacedParameter(), getArgumentPack()); |
3668 | 21.3k | } |
3669 | | |
3670 | | void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID, |
3671 | | const TemplateTypeParmType *Replaced, |
3672 | 46.7k | const TemplateArgument &ArgPack) { |
3673 | 46.7k | ID.AddPointer(Replaced); |
3674 | 46.7k | ID.AddInteger(ArgPack.pack_size()); |
3675 | 46.7k | for (const auto &P : ArgPack.pack_elements()) |
3676 | 185k | ID.AddPointer(P.getAsType().getAsOpaquePtr()); |
3677 | 46.7k | } |
3678 | | |
3679 | | bool TemplateSpecializationType::anyDependentTemplateArguments( |
3680 | 7.15M | const TemplateArgumentListInfo &Args, ArrayRef<TemplateArgument> Converted) { |
3681 | 7.15M | return anyDependentTemplateArguments(Args.arguments(), Converted); |
3682 | 7.15M | } |
3683 | | |
3684 | | bool TemplateSpecializationType::anyDependentTemplateArguments( |
3685 | 7.15M | ArrayRef<TemplateArgumentLoc> Args, ArrayRef<TemplateArgument> Converted) { |
3686 | 7.15M | for (const TemplateArgument &Arg : Converted) |
3687 | 9.21M | if (Arg.isDependent()) |
3688 | 4.38M | return true; |
3689 | 2.76M | return false; |
3690 | 7.15M | } |
3691 | | |
3692 | | bool TemplateSpecializationType::anyInstantiationDependentTemplateArguments( |
3693 | 2.38k | ArrayRef<TemplateArgumentLoc> Args) { |
3694 | 2.38k | for (const TemplateArgumentLoc &ArgLoc : Args) { |
3695 | 1.29k | if (ArgLoc.getArgument().isInstantiationDependent()) |
3696 | 276 | return true; |
3697 | 1.29k | } |
3698 | 2.10k | return false; |
3699 | 2.38k | } |
3700 | | |
3701 | | TemplateSpecializationType::TemplateSpecializationType( |
3702 | | TemplateName T, ArrayRef<TemplateArgument> Args, QualType Canon, |
3703 | | QualType AliasedType) |
3704 | | : Type(TemplateSpecialization, Canon.isNull() ? QualType(this, 0) : Canon, |
3705 | | (Canon.isNull() |
3706 | | ? TypeDependence::DependentInstantiation |
3707 | | : toSemanticDependence(Canon->getDependence())) | |
3708 | | (toTypeDependence(T.getDependence()) & |
3709 | | TypeDependence::UnexpandedPack)), |
3710 | 14.1M | Template(T) { |
3711 | 14.1M | TemplateSpecializationTypeBits.NumArgs = Args.size(); |
3712 | 14.1M | TemplateSpecializationTypeBits.TypeAlias = !AliasedType.isNull(); |
3713 | | |
3714 | 14.1M | assert(!T.getAsDependentTemplateName() && |
3715 | 14.1M | "Use DependentTemplateSpecializationType for dependent template-name"); |
3716 | 0 | assert((T.getKind() == TemplateName::Template || |
3717 | 14.1M | T.getKind() == TemplateName::SubstTemplateTemplateParm || |
3718 | 14.1M | T.getKind() == TemplateName::SubstTemplateTemplateParmPack || |
3719 | 14.1M | T.getKind() == TemplateName::UsingTemplate) && |
3720 | 14.1M | "Unexpected template name for TemplateSpecializationType"); |
3721 | | |
3722 | 0 | auto *TemplateArgs = reinterpret_cast<TemplateArgument *>(this + 1); |
3723 | 24.1M | for (const TemplateArgument &Arg : Args) { |
3724 | | // Update instantiation-dependent, variably-modified, and error bits. |
3725 | | // If the canonical type exists and is non-dependent, the template |
3726 | | // specialization type can be non-dependent even if one of the type |
3727 | | // arguments is. Given: |
3728 | | // template<typename T> using U = int; |
3729 | | // U<T> is always non-dependent, irrespective of the type T. |
3730 | | // However, U<Ts> contains an unexpanded parameter pack, even though |
3731 | | // its expansion (and thus its desugared type) doesn't. |
3732 | 24.1M | addDependence(toTypeDependence(Arg.getDependence()) & |
3733 | 24.1M | ~TypeDependence::Dependent); |
3734 | 24.1M | if (Arg.getKind() == TemplateArgument::Type) |
3735 | 18.8M | addDependence(Arg.getAsType()->getDependence() & |
3736 | 18.8M | TypeDependence::VariablyModified); |
3737 | 24.1M | new (TemplateArgs++) TemplateArgument(Arg); |
3738 | 24.1M | } |
3739 | | |
3740 | | // Store the aliased type if this is a type alias template specialization. |
3741 | 14.1M | if (isTypeAlias()) { |
3742 | 1.24M | auto *Begin = reinterpret_cast<TemplateArgument *>(this + 1); |
3743 | 1.24M | *reinterpret_cast<QualType*>(Begin + getNumArgs()) = AliasedType; |
3744 | 1.24M | } |
3745 | 14.1M | } |
3746 | | |
3747 | | void |
3748 | | TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, |
3749 | | TemplateName T, |
3750 | | ArrayRef<TemplateArgument> Args, |
3751 | 15.8M | const ASTContext &Context) { |
3752 | 15.8M | T.Profile(ID); |
3753 | 15.8M | for (const TemplateArgument &Arg : Args) |
3754 | 29.1M | Arg.Profile(ID, Context); |
3755 | 15.8M | } |
3756 | | |
3757 | | QualType |
3758 | 167k | QualifierCollector::apply(const ASTContext &Context, QualType QT) const { |
3759 | 167k | if (!hasNonFastQualifiers()) |
3760 | 161k | return QT.withFastQualifiers(getFastQualifiers()); |
3761 | | |
3762 | 6.11k | return Context.getQualifiedType(QT, *this); |
3763 | 167k | } |
3764 | | |
3765 | | QualType |
3766 | 73.9k | QualifierCollector::apply(const ASTContext &Context, const Type *T) const { |
3767 | 73.9k | if (!hasNonFastQualifiers()) |
3768 | 73.9k | return QualType(T, getFastQualifiers()); |
3769 | | |
3770 | 0 | return Context.getQualifiedType(T, *this); |
3771 | 73.9k | } |
3772 | | |
3773 | | void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID, |
3774 | | QualType BaseType, |
3775 | | ArrayRef<QualType> typeArgs, |
3776 | | ArrayRef<ObjCProtocolDecl *> protocols, |
3777 | 540k | bool isKindOf) { |
3778 | 540k | ID.AddPointer(BaseType.getAsOpaquePtr()); |
3779 | 540k | ID.AddInteger(typeArgs.size()); |
3780 | 540k | for (auto typeArg : typeArgs) |
3781 | 490k | ID.AddPointer(typeArg.getAsOpaquePtr()); |
3782 | 540k | ID.AddInteger(protocols.size()); |
3783 | 540k | for (auto proto : protocols) |
3784 | 79.4k | ID.AddPointer(proto); |
3785 | 540k | ID.AddBoolean(isKindOf); |
3786 | 540k | } |
3787 | | |
3788 | 301k | void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) { |
3789 | 301k | Profile(ID, getBaseType(), getTypeArgsAsWritten(), |
3790 | 301k | llvm::makeArrayRef(qual_begin(), getNumProtocols()), |
3791 | 301k | isKindOfTypeAsWritten()); |
3792 | 301k | } |
3793 | | |
3794 | | void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID, |
3795 | | const ObjCTypeParamDecl *OTPDecl, |
3796 | | QualType CanonicalType, |
3797 | 192k | ArrayRef<ObjCProtocolDecl *> protocols) { |
3798 | 192k | ID.AddPointer(OTPDecl); |
3799 | 192k | ID.AddPointer(CanonicalType.getAsOpaquePtr()); |
3800 | 192k | ID.AddInteger(protocols.size()); |
3801 | 192k | for (auto proto : protocols) |
3802 | 8.66k | ID.AddPointer(proto); |
3803 | 192k | } |
3804 | | |
3805 | 121k | void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID) { |
3806 | 121k | Profile(ID, getDecl(), getCanonicalTypeInternal(), |
3807 | 121k | llvm::makeArrayRef(qual_begin(), getNumProtocols())); |
3808 | 121k | } |
3809 | | |
3810 | | namespace { |
3811 | | |
3812 | | /// The cached properties of a type. |
3813 | | class CachedProperties { |
3814 | | Linkage L; |
3815 | | bool local; |
3816 | | |
3817 | | public: |
3818 | 6.22M | CachedProperties(Linkage L, bool local) : L(L), local(local) {} |
3819 | | |
3820 | 2.21M | Linkage getLinkage() const { return L; } |
3821 | 6.21M | bool hasLocalOrUnnamedType() const { return local; } |
3822 | | |
3823 | 2.00M | friend CachedProperties merge(CachedProperties L, CachedProperties R) { |
3824 | 2.00M | Linkage MergedLinkage = minLinkage(L.L, R.L); |
3825 | 2.00M | return CachedProperties(MergedLinkage, L.hasLocalOrUnnamedType() || |
3826 | 2.00M | R.hasLocalOrUnnamedType()2.00M ); |
3827 | 2.00M | } |
3828 | | }; |
3829 | | |
3830 | | } // namespace |
3831 | | |
3832 | | static CachedProperties computeCachedProperties(const Type *T); |
3833 | | |
3834 | | namespace clang { |
3835 | | |
3836 | | /// The type-property cache. This is templated so as to be |
3837 | | /// instantiated at an internal type to prevent unnecessary symbol |
3838 | | /// leakage. |
3839 | | template <class Private> class TypePropertyCache { |
3840 | | public: |
3841 | 3.69M | static CachedProperties get(QualType T) { |
3842 | 3.69M | return get(T.getTypePtr()); |
3843 | 3.69M | } |
3844 | | |
3845 | 3.69M | static CachedProperties get(const Type *T) { |
3846 | 3.69M | ensure(T); |
3847 | 3.69M | return CachedProperties(T->TypeBits.getLinkage(), |
3848 | 3.69M | T->TypeBits.hasLocalOrUnnamedType()); |
3849 | 3.69M | } |
3850 | | |
3851 | 11.2M | static void ensure(const Type *T) { |
3852 | | // If the cache is valid, we're okay. |
3853 | 11.2M | if (T->TypeBits.isCacheValid()) return7.44M ; |
3854 | | |
3855 | | // If this type is non-canonical, ask its canonical type for the |
3856 | | // relevant information. |
3857 | 3.76M | if (!T->isCanonicalUnqualified()) { |
3858 | 1.55M | const Type *CT = T->getCanonicalTypeInternal().getTypePtr(); |
3859 | 1.55M | ensure(CT); |
3860 | 1.55M | T->TypeBits.CacheValid = true; |
3861 | 1.55M | T->TypeBits.CachedLinkage = CT->TypeBits.CachedLinkage; |
3862 | 1.55M | T->TypeBits.CachedLocalOrUnnamed = CT->TypeBits.CachedLocalOrUnnamed; |
3863 | 1.55M | return; |
3864 | 1.55M | } |
3865 | | |
3866 | | // Compute the cached properties and then set the cache. |
3867 | 2.21M | CachedProperties Result = computeCachedProperties(T); |
3868 | 2.21M | T->TypeBits.CacheValid = true; |
3869 | 2.21M | T->TypeBits.CachedLinkage = Result.getLinkage(); |
3870 | 2.21M | T->TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType(); |
3871 | 2.21M | } |
3872 | | }; |
3873 | | |
3874 | | } // namespace clang |
3875 | | |
3876 | | // Instantiate the friend template at a private class. In a |
3877 | | // reasonable implementation, these symbols will be internal. |
3878 | | // It is terrible that this is the best way to accomplish this. |
3879 | | namespace { |
3880 | | |
3881 | | class Private {}; |
3882 | | |
3883 | | } // namespace |
3884 | | |
3885 | | using Cache = TypePropertyCache<Private>; |
3886 | | |
3887 | 2.21M | static CachedProperties computeCachedProperties(const Type *T) { |
3888 | 2.21M | switch (T->getTypeClass()) { |
3889 | 0 | #define TYPE(Class,Base) |
3890 | 0 | #define NON_CANONICAL_TYPE(Class,Base) case Type::Class: |
3891 | 0 | #include "clang/AST/TypeNodes.inc" |
3892 | 0 | llvm_unreachable("didn't expect a non-canonical type here"); |
3893 | |
|
3894 | 0 | #define TYPE(Class,Base) |
3895 | 899k | #define DEPENDENT_TYPE(Class,Base) case Type::Class: |
3896 | 649k | #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class: |
3897 | 163k | #include "clang/AST/TypeNodes.inc"0 |
3898 | | // Treat instantiation-dependent types as external. |
3899 | 163k | if (!T->isInstantiationDependentType()) T->dump()0 ; |
3900 | 163k | assert(T->isInstantiationDependentType()); |
3901 | 0 | return CachedProperties(ExternalLinkage, false); |
3902 | | |
3903 | 537 | case Type::Auto: |
3904 | 564 | case Type::DeducedTemplateSpecialization: |
3905 | | // Give non-deduced 'auto' types external linkage. We should only see them |
3906 | | // here in error recovery. |
3907 | 564 | return CachedProperties(ExternalLinkage, false); |
3908 | | |
3909 | 137 | case Type::BitInt: |
3910 | 146k | case Type::Builtin: |
3911 | | // C++ [basic.link]p8: |
3912 | | // A type is said to have linkage if and only if: |
3913 | | // - it is a fundamental type (3.9.1); or |
3914 | 146k | return CachedProperties(ExternalLinkage, false); |
3915 | | |
3916 | 201k | case Type::Record: |
3917 | 207k | case Type::Enum: { |
3918 | 207k | const TagDecl *Tag = cast<TagType>(T)->getDecl(); |
3919 | | |
3920 | | // C++ [basic.link]p8: |
3921 | | // - it is a class or enumeration type that is named (or has a name |
3922 | | // for linkage purposes (7.1.3)) and the name has linkage; or |
3923 | | // - it is a specialization of a class template (14); or |
3924 | 207k | Linkage L = Tag->getLinkageInternal(); |
3925 | 207k | bool IsLocalOrUnnamed = |
3926 | 207k | Tag->getDeclContext()->isFunctionOrMethod() || |
3927 | 207k | !Tag->hasNameForLinkage()206k ; |
3928 | 207k | return CachedProperties(L, IsLocalOrUnnamed); |
3929 | 201k | } |
3930 | | |
3931 | | // C++ [basic.link]p8: |
3932 | | // - it is a compound type (3.9.2) other than a class or enumeration, |
3933 | | // compounded exclusively from types that have linkage; or |
3934 | 167 | case Type::Complex: |
3935 | 167 | return Cache::get(cast<ComplexType>(T)->getElementType()); |
3936 | 123k | case Type::Pointer: |
3937 | 123k | return Cache::get(cast<PointerType>(T)->getPointeeType()); |
3938 | 655 | case Type::BlockPointer: |
3939 | 655 | return Cache::get(cast<BlockPointerType>(T)->getPointeeType()); |
3940 | 224k | case Type::LValueReference: |
3941 | 281k | case Type::RValueReference: |
3942 | 281k | return Cache::get(cast<ReferenceType>(T)->getPointeeType()); |
3943 | 3.79k | case Type::MemberPointer: { |
3944 | 3.79k | const auto *MPT = cast<MemberPointerType>(T); |
3945 | 3.79k | return merge(Cache::get(MPT->getClass()), |
3946 | 3.79k | Cache::get(MPT->getPointeeType())); |
3947 | 224k | } |
3948 | 3.92k | case Type::ConstantArray: |
3949 | 4.72k | case Type::IncompleteArray: |
3950 | 4.77k | case Type::VariableArray: |
3951 | 4.77k | return Cache::get(cast<ArrayType>(T)->getElementType()); |
3952 | 2.06k | case Type::Vector: |
3953 | 2.35k | case Type::ExtVector: |
3954 | 2.35k | return Cache::get(cast<VectorType>(T)->getElementType()); |
3955 | 71 | case Type::ConstantMatrix: |
3956 | 71 | return Cache::get(cast<ConstantMatrixType>(T)->getElementType()); |
3957 | 14 | case Type::FunctionNoProto: |
3958 | 14 | return Cache::get(cast<FunctionType>(T)->getReturnType()); |
3959 | 1.27M | case Type::FunctionProto: { |
3960 | 1.27M | const auto *FPT = cast<FunctionProtoType>(T); |
3961 | 1.27M | CachedProperties result = Cache::get(FPT->getReturnType()); |
3962 | 1.27M | for (const auto &ai : FPT->param_types()) |
3963 | 2.00M | result = merge(result, Cache::get(ai)); |
3964 | 1.27M | return result; |
3965 | 2.06k | } |
3966 | 417 | case Type::ObjCInterface: { |
3967 | 417 | Linkage L = cast<ObjCInterfaceType>(T)->getDecl()->getLinkageInternal(); |
3968 | 417 | return CachedProperties(L, false); |
3969 | 2.06k | } |
3970 | 1.53k | case Type::ObjCObject: |
3971 | 1.53k | return Cache::get(cast<ObjCObjectType>(T)->getBaseType()); |
3972 | 1.92k | case Type::ObjCObjectPointer: |
3973 | 1.92k | return Cache::get(cast<ObjCObjectPointerType>(T)->getPointeeType()); |
3974 | 216 | case Type::Atomic: |
3975 | 216 | return Cache::get(cast<AtomicType>(T)->getValueType()); |
3976 | 49 | case Type::Pipe: |
3977 | 49 | return Cache::get(cast<PipeType>(T)->getElementType()); |
3978 | 2.21M | } |
3979 | | |
3980 | 0 | llvm_unreachable("unhandled type class"); |
3981 | 0 | } |
3982 | | |
3983 | | /// Determine the linkage of this type. |
3984 | 5.95M | Linkage Type::getLinkage() const { |
3985 | 5.95M | Cache::ensure(this); |
3986 | 5.95M | return TypeBits.getLinkage(); |
3987 | 5.95M | } |
3988 | | |
3989 | 8.08k | bool Type::hasUnnamedOrLocalType() const { |
3990 | 8.08k | Cache::ensure(this); |
3991 | 8.08k | return TypeBits.hasLocalOrUnnamedType(); |
3992 | 8.08k | } |
3993 | | |
3994 | 1.96M | LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) { |
3995 | 1.96M | switch (T->getTypeClass()) { |
3996 | 0 | #define TYPE(Class,Base) |
3997 | 0 | #define NON_CANONICAL_TYPE(Class,Base) case Type::Class: |
3998 | 0 | #include "clang/AST/TypeNodes.inc" |
3999 | 0 | llvm_unreachable("didn't expect a non-canonical type here"); |
4000 | |
|
4001 | 0 | #define TYPE(Class,Base) |
4002 | 0 | #define DEPENDENT_TYPE(Class,Base) case Type::Class: |
4003 | 0 | #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class: |
4004 | 0 | #include "clang/AST/TypeNodes.inc" |
4005 | | // Treat instantiation-dependent types as external. |
4006 | 0 | assert(T->isInstantiationDependentType()); |
4007 | 0 | return LinkageInfo::external(); |
4008 | | |
4009 | 124 | case Type::BitInt: |
4010 | 782k | case Type::Builtin: |
4011 | 782k | return LinkageInfo::external(); |
4012 | | |
4013 | 0 | case Type::Auto: |
4014 | 0 | case Type::DeducedTemplateSpecialization: |
4015 | 0 | return LinkageInfo::external(); |
4016 | | |
4017 | 829k | case Type::Record: |
4018 | 832k | case Type::Enum: |
4019 | 832k | return getDeclLinkageAndVisibility(cast<TagType>(T)->getDecl()); |
4020 | | |
4021 | 43 | case Type::Complex: |
4022 | 43 | return computeTypeLinkageInfo(cast<ComplexType>(T)->getElementType()); |
4023 | 242k | case Type::Pointer: |
4024 | 242k | return computeTypeLinkageInfo(cast<PointerType>(T)->getPointeeType()); |
4025 | 88 | case Type::BlockPointer: |
4026 | 88 | return computeTypeLinkageInfo(cast<BlockPointerType>(T)->getPointeeType()); |
4027 | 41.9k | case Type::LValueReference: |
4028 | 45.1k | case Type::RValueReference: |
4029 | 45.1k | return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType()); |
4030 | 4.77k | case Type::MemberPointer: { |
4031 | 4.77k | const auto *MPT = cast<MemberPointerType>(T); |
4032 | 4.77k | LinkageInfo LV = computeTypeLinkageInfo(MPT->getClass()); |
4033 | 4.77k | LV.merge(computeTypeLinkageInfo(MPT->getPointeeType())); |
4034 | 4.77k | return LV; |
4035 | 41.9k | } |
4036 | 6.31k | case Type::ConstantArray: |
4037 | 12.3k | case Type::IncompleteArray: |
4038 | 12.3k | case Type::VariableArray: |
4039 | 12.3k | return computeTypeLinkageInfo(cast<ArrayType>(T)->getElementType()); |
4040 | 215 | case Type::Vector: |
4041 | 310 | case Type::ExtVector: |
4042 | 310 | return computeTypeLinkageInfo(cast<VectorType>(T)->getElementType()); |
4043 | 0 | case Type::ConstantMatrix: |
4044 | 0 | return computeTypeLinkageInfo( |
4045 | 0 | cast<ConstantMatrixType>(T)->getElementType()); |
4046 | 0 | case Type::FunctionNoProto: |
4047 | 0 | return computeTypeLinkageInfo(cast<FunctionType>(T)->getReturnType()); |
4048 | 48.4k | case Type::FunctionProto: { |
4049 | 48.4k | const auto *FPT = cast<FunctionProtoType>(T); |
4050 | 48.4k | LinkageInfo LV = computeTypeLinkageInfo(FPT->getReturnType()); |
4051 | 48.4k | for (const auto &ai : FPT->param_types()) |
4052 | 41.8k | LV.merge(computeTypeLinkageInfo(ai)); |
4053 | 48.4k | return LV; |
4054 | 215 | } |
4055 | 623 | case Type::ObjCInterface: |
4056 | 623 | return getDeclLinkageAndVisibility(cast<ObjCInterfaceType>(T)->getDecl()); |
4057 | 136 | case Type::ObjCObject: |
4058 | 136 | return computeTypeLinkageInfo(cast<ObjCObjectType>(T)->getBaseType()); |
4059 | 737 | case Type::ObjCObjectPointer: |
4060 | 737 | return computeTypeLinkageInfo( |
4061 | 737 | cast<ObjCObjectPointerType>(T)->getPointeeType()); |
4062 | 111 | case Type::Atomic: |
4063 | 111 | return computeTypeLinkageInfo(cast<AtomicType>(T)->getValueType()); |
4064 | 0 | case Type::Pipe: |
4065 | 0 | return computeTypeLinkageInfo(cast<PipeType>(T)->getElementType()); |
4066 | 1.96M | } |
4067 | | |
4068 | 0 | llvm_unreachable("unhandled type class"); |
4069 | 0 | } |
4070 | | |
4071 | 162k | bool Type::isLinkageValid() const { |
4072 | 162k | if (!TypeBits.isCacheValid()) |
4073 | 162k | return true; |
4074 | | |
4075 | 0 | Linkage L = LinkageComputer{} |
4076 | 0 | .computeTypeLinkageInfo(getCanonicalTypeInternal()) |
4077 | 0 | .getLinkage(); |
4078 | 0 | return L == TypeBits.getLinkage(); |
4079 | 162k | } |
4080 | | |
4081 | 1.56M | LinkageInfo LinkageComputer::getTypeLinkageAndVisibility(const Type *T) { |
4082 | 1.56M | if (!T->isCanonicalUnqualified()) |
4083 | 81.8k | return computeTypeLinkageInfo(T->getCanonicalTypeInternal()); |
4084 | | |
4085 | 1.48M | LinkageInfo LV = computeTypeLinkageInfo(T); |
4086 | 1.48M | assert(LV.getLinkage() == T->getLinkage()); |
4087 | 0 | return LV; |
4088 | 1.56M | } |
4089 | | |
4090 | 2.14k | LinkageInfo Type::getLinkageAndVisibility() const { |
4091 | 2.14k | return LinkageComputer{}.getTypeLinkageAndVisibility(this); |
4092 | 2.14k | } |
4093 | | |
4094 | | Optional<NullabilityKind> |
4095 | 38.6M | Type::getNullability(const ASTContext &Context) const { |
4096 | 38.6M | QualType Type(this, 0); |
4097 | 38.6M | while (const auto *AT = Type->getAs<AttributedType>()) { |
4098 | | // Check whether this is an attributed type with nullability |
4099 | | // information. |
4100 | 680k | if (auto Nullability = AT->getImmediateNullability()) |
4101 | 664k | return Nullability; |
4102 | | |
4103 | 16.3k | Type = AT->getEquivalentType(); |
4104 | 16.3k | } |
4105 | 38.0M | return None; |
4106 | 38.6M | } |
4107 | | |
4108 | 118M | bool Type::canHaveNullability(bool ResultIfUnknown) const { |
4109 | 118M | QualType type = getCanonicalTypeInternal(); |
4110 | | |
4111 | 118M | switch (type->getTypeClass()) { |
4112 | | // We'll only see canonical types here. |
4113 | 0 | #define NON_CANONICAL_TYPE(Class, Parent) \ |
4114 | 0 | case Type::Class: \ |
4115 | 0 | llvm_unreachable("non-canonical type"); |
4116 | 0 | #define TYPE(Class, Parent) |
4117 | 0 | #include "clang/AST/TypeNodes.inc" |
4118 | | |
4119 | | // Pointer types. |
4120 | 4.12M | case Type::Pointer: |
4121 | 4.25M | case Type::BlockPointer: |
4122 | 4.25M | case Type::MemberPointer: |
4123 | 7.16M | case Type::ObjCObjectPointer: |
4124 | 7.16M | return true; |
4125 | | |
4126 | | // Dependent types that could instantiate to pointer types. |
4127 | 403 | case Type::UnresolvedUsing: |
4128 | 1.57k | case Type::TypeOfExpr: |
4129 | 1.57k | case Type::TypeOf: |
4130 | 65.9k | case Type::Decltype: |
4131 | 67.0k | case Type::UnaryTransform: |
4132 | 5.75M | case Type::TemplateTypeParm: |
4133 | 5.75M | case Type::SubstTemplateTypeParmPack: |
4134 | 7.68M | case Type::DependentName: |
4135 | 7.71M | case Type::DependentTemplateSpecialization: |
4136 | 7.76M | case Type::Auto: |
4137 | 7.76M | return ResultIfUnknown; |
4138 | | |
4139 | | // Dependent template specializations can instantiate to pointer |
4140 | | // types unless they're known to be specializations of a class |
4141 | | // template. |
4142 | 1.49M | case Type::TemplateSpecialization: |
4143 | 1.49M | if (TemplateDecl *templateDecl |
4144 | 1.49M | = cast<TemplateSpecializationType>(type.getTypePtr()) |
4145 | 1.49M | ->getTemplateName().getAsTemplateDecl()) { |
4146 | 1.49M | if (isa<ClassTemplateDecl>(templateDecl)) |
4147 | 1.47M | return false; |
4148 | 1.49M | } |
4149 | 14.1k | return ResultIfUnknown; |
4150 | | |
4151 | 82.9M | case Type::Builtin: |
4152 | 82.9M | switch (cast<BuiltinType>(type.getTypePtr())->getKind()) { |
4153 | | // Signed, unsigned, and floating-point types cannot have nullability. |
4154 | 402M | #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id: |
4155 | 345M | #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id: |
4156 | 205M | #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id: |
4157 | 0 | #define BUILTIN_TYPE(Id, SingletonId) |
4158 | 26.1M | #include "clang/AST/BuiltinTypes.def"0 |
4159 | 26.1M | return false; |
4160 | | |
4161 | | // Dependent types that could instantiate to a pointer type. |
4162 | 6.02k | case BuiltinType::Dependent: |
4163 | 6.02k | case BuiltinType::Overload: |
4164 | 6.02k | case BuiltinType::BoundMember: |
4165 | 6.02k | case BuiltinType::PseudoObject: |
4166 | 6.08k | case BuiltinType::UnknownAny: |
4167 | 6.08k | case BuiltinType::ARCUnbridgedCast: |
4168 | 6.08k | return ResultIfUnknown; |
4169 | | |
4170 | 4.10M | case BuiltinType::Void: |
4171 | 4.10M | case BuiltinType::ObjCId: |
4172 | 4.10M | case BuiltinType::ObjCClass: |
4173 | 4.10M | case BuiltinType::ObjCSel: |
4174 | 4.10M | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ |
4175 | 148M | case BuiltinType::Id: |
4176 | 148M | #include "clang/Basic/OpenCLImageTypes.def"4.10M |
4177 | 148M | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
4178 | 148M | case BuiltinType::Id:49.4M |
4179 | 148M | #include "clang/Basic/OpenCLExtensionTypes.def"4.11M |
4180 | 49.4M | case BuiltinType::OCLSampler: |
4181 | 4.13M | case BuiltinType::OCLEvent: |
4182 | 4.13M | case BuiltinType::OCLClkEvent: |
4183 | 4.13M | case BuiltinType::OCLQueue: |
4184 | 4.13M | case BuiltinType::OCLReserveID: |
4185 | 4.13M | #define SVE_TYPE(Name, Id, SingletonId) \ |
4186 | 1.84G | case BuiltinType::Id: |
4187 | 1.84G | #include "clang/Basic/AArch64SVEACLETypes.def"4.13M |
4188 | 1.84G | #define PPC_VECTOR_TYPE(Name, Id, Size) \ |
4189 | 1.84G | case BuiltinType::Id:113M |
4190 | 1.84G | #include "clang/Basic/PPCTypes.def"56.7M |
4191 | 3.74G | #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id: |
4192 | 3.74G | #include "clang/Basic/RISCVVTypes.def"56.7M |
4193 | 3.74G | case BuiltinType::BuiltinFn: |
4194 | 56.8M | case BuiltinType::NullPtr: |
4195 | 56.8M | case BuiltinType::IncompleteMatrixIdx: |
4196 | 56.8M | case BuiltinType::OMPArraySection: |
4197 | 56.8M | case BuiltinType::OMPArrayShaping: |
4198 | 56.8M | case BuiltinType::OMPIterator: |
4199 | 56.8M | return false; |
4200 | 82.9M | } |
4201 | 0 | llvm_unreachable("unknown builtin type"); |
4202 | | |
4203 | | // Non-pointer types. |
4204 | 8.67k | case Type::Complex: |
4205 | 43.8k | case Type::LValueReference: |
4206 | 44.1k | case Type::RValueReference: |
4207 | 125k | case Type::ConstantArray: |
4208 | 145k | case Type::IncompleteArray: |
4209 | 145k | case Type::VariableArray: |
4210 | 145k | case Type::DependentSizedArray: |
4211 | 145k | case Type::DependentVector: |
4212 | 145k | case Type::DependentSizedExtVector: |
4213 | 12.0M | case Type::Vector: |
4214 | 12.4M | case Type::ExtVector: |
4215 | 12.4M | case Type::ConstantMatrix: |
4216 | 12.4M | case Type::DependentSizedMatrix: |
4217 | 12.4M | case Type::DependentAddressSpace: |
4218 | 12.4M | case Type::FunctionProto: |
4219 | 12.4M | case Type::FunctionNoProto: |
4220 | 16.5M | case Type::Record: |
4221 | 16.5M | case Type::DeducedTemplateSpecialization: |
4222 | 17.3M | case Type::Enum: |
4223 | 17.8M | case Type::InjectedClassName: |
4224 | 17.8M | case Type::PackExpansion: |
4225 | 17.9M | case Type::ObjCObject: |
4226 | 18.9M | case Type::ObjCInterface: |
4227 | 19.0M | case Type::Atomic: |
4228 | 19.0M | case Type::Pipe: |
4229 | 19.0M | case Type::BitInt: |
4230 | 19.0M | case Type::DependentBitInt: |
4231 | 19.0M | return false; |
4232 | 118M | } |
4233 | 0 | llvm_unreachable("bad type kind!"); |
4234 | 0 | } |
4235 | | |
4236 | | llvm::Optional<NullabilityKind> |
4237 | 1.03M | AttributedType::getImmediateNullability() const { |
4238 | 1.03M | if (getAttrKind() == attr::TypeNonNull) |
4239 | 353k | return NullabilityKind::NonNull; |
4240 | 678k | if (getAttrKind() == attr::TypeNullable) |
4241 | 611k | return NullabilityKind::Nullable; |
4242 | 66.8k | if (getAttrKind() == attr::TypeNullUnspecified) |
4243 | 48.5k | return NullabilityKind::Unspecified; |
4244 | 18.2k | if (getAttrKind() == attr::TypeNullableResult) |
4245 | 47 | return NullabilityKind::NullableResult; |
4246 | 18.1k | return None; |
4247 | 18.2k | } |
4248 | | |
4249 | 723k | Optional<NullabilityKind> AttributedType::stripOuterNullability(QualType &T) { |
4250 | 723k | QualType AttrTy = T; |
4251 | 723k | if (auto MacroTy = dyn_cast<MacroQualifiedType>(T)) |
4252 | 58 | AttrTy = MacroTy->getUnderlyingType(); |
4253 | | |
4254 | 723k | if (auto attributed = dyn_cast<AttributedType>(AttrTy)) { |
4255 | 347k | if (auto nullability = attributed->getImmediateNullability()) { |
4256 | 347k | T = attributed->getModifiedType(); |
4257 | 347k | return nullability; |
4258 | 347k | } |
4259 | 347k | } |
4260 | | |
4261 | 375k | return None; |
4262 | 723k | } |
4263 | | |
4264 | 467 | bool Type::isBlockCompatibleObjCPointerType(ASTContext &ctx) const { |
4265 | 467 | const auto *objcPtr = getAs<ObjCObjectPointerType>(); |
4266 | 467 | if (!objcPtr) |
4267 | 32 | return false; |
4268 | | |
4269 | 435 | if (objcPtr->isObjCIdType()) { |
4270 | | // id is always okay. |
4271 | 280 | return true; |
4272 | 280 | } |
4273 | | |
4274 | | // Blocks are NSObjects. |
4275 | 155 | if (ObjCInterfaceDecl *iface = objcPtr->getInterfaceDecl()) { |
4276 | 131 | if (iface->getIdentifier() != ctx.getNSObjectName()) |
4277 | 114 | return false; |
4278 | | |
4279 | | // Continue to check qualifiers, below. |
4280 | 131 | } else if (24 objcPtr->isObjCQualifiedIdType()24 ) { |
4281 | | // Continue to check qualifiers, below. |
4282 | 21 | } else { |
4283 | 3 | return false; |
4284 | 3 | } |
4285 | | |
4286 | | // Check protocol qualifiers. |
4287 | 51 | for (ObjCProtocolDecl *proto : objcPtr->quals())38 { |
4288 | | // Blocks conform to NSObject and NSCopying. |
4289 | 51 | if (proto->getIdentifier() != ctx.getNSObjectName() && |
4290 | 51 | proto->getIdentifier() != ctx.getNSCopyingName()33 ) |
4291 | 14 | return false; |
4292 | 51 | } |
4293 | | |
4294 | 24 | return true; |
4295 | 38 | } |
4296 | | |
4297 | 24.4k | Qualifiers::ObjCLifetime Type::getObjCARCImplicitLifetime() const { |
4298 | 24.4k | if (isObjCARCImplicitlyUnretainedType()) |
4299 | 218 | return Qualifiers::OCL_ExplicitNone; |
4300 | 24.2k | return Qualifiers::OCL_Strong; |
4301 | 24.4k | } |
4302 | | |
4303 | 30.0k | bool Type::isObjCARCImplicitlyUnretainedType() const { |
4304 | 30.0k | assert(isObjCLifetimeType() && |
4305 | 30.0k | "cannot query implicit lifetime for non-inferrable type"); |
4306 | | |
4307 | 0 | const Type *canon = getCanonicalTypeInternal().getTypePtr(); |
4308 | | |
4309 | | // Walk down to the base type. We don't care about qualifiers for this. |
4310 | 30.1k | while (const auto *array = dyn_cast<ArrayType>(canon)) |
4311 | 89 | canon = array->getElementType().getTypePtr(); |
4312 | | |
4313 | 30.0k | if (const auto *opt = dyn_cast<ObjCObjectPointerType>(canon)) { |
4314 | | // Class and Class<Protocol> don't require retention. |
4315 | 28.6k | if (opt->getObjectType()->isObjCClass()) |
4316 | 256 | return true; |
4317 | 28.6k | } |
4318 | | |
4319 | 29.8k | return false; |
4320 | 30.0k | } |
4321 | | |
4322 | 2.90M | bool Type::isObjCNSObjectType() const { |
4323 | 2.90M | const Type *cur = this; |
4324 | 3.29M | while (true3.29M ) { |
4325 | 3.29M | if (const auto *typedefType = dyn_cast<TypedefType>(cur)) |
4326 | 872k | return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>(); |
4327 | | |
4328 | | // Single-step desugar until we run out of sugar. |
4329 | 2.41M | QualType next = cur->getLocallyUnqualifiedSingleStepDesugaredType(); |
4330 | 2.41M | if (next.getTypePtr() == cur) return false2.03M ; |
4331 | 386k | cur = next.getTypePtr(); |
4332 | 386k | } |
4333 | 2.90M | } |
4334 | | |
4335 | 12.1k | bool Type::isObjCIndependentClassType() const { |
4336 | 12.1k | if (const auto *typedefType = dyn_cast<TypedefType>(this)) |
4337 | 2.76k | return typedefType->getDecl()->hasAttr<ObjCIndependentClassAttr>(); |
4338 | 9.34k | return false; |
4339 | 12.1k | } |
4340 | | |
4341 | 3.26M | bool Type::isObjCRetainableType() const { |
4342 | 3.26M | return isObjCObjectPointerType() || |
4343 | 3.26M | isBlockPointerType()2.90M || |
4344 | 3.26M | isObjCNSObjectType()2.89M ; |
4345 | 3.26M | } |
4346 | | |
4347 | 541 | bool Type::isObjCIndirectLifetimeType() const { |
4348 | 541 | if (isObjCLifetimeType()) |
4349 | 182 | return true; |
4350 | 359 | if (const auto *OPT = getAs<PointerType>()) |
4351 | 181 | return OPT->getPointeeType()->isObjCIndirectLifetimeType(); |
4352 | 178 | if (const auto *Ref = getAs<ReferenceType>()) |
4353 | 0 | return Ref->getPointeeType()->isObjCIndirectLifetimeType(); |
4354 | 178 | if (const auto *MemPtr = getAs<MemberPointerType>()) |
4355 | 0 | return MemPtr->getPointeeType()->isObjCIndirectLifetimeType(); |
4356 | 178 | return false; |
4357 | 178 | } |
4358 | | |
4359 | | /// Returns true if objects of this type have lifetime semantics under |
4360 | | /// ARC. |
4361 | 270k | bool Type::isObjCLifetimeType() const { |
4362 | 270k | const Type *type = this; |
4363 | 275k | while (const ArrayType *array = type->getAsArrayTypeUnsafe()) |
4364 | 4.09k | type = array->getElementType().getTypePtr(); |
4365 | 270k | return type->isObjCRetainableType(); |
4366 | 270k | } |
4367 | | |
4368 | | /// Determine whether the given type T is a "bridgable" Objective-C type, |
4369 | | /// which is either an Objective-C object pointer type or an |
4370 | 12.1M | bool Type::isObjCARCBridgableType() const { |
4371 | 12.1M | return isObjCObjectPointerType() || isBlockPointerType()12.0M ; |
4372 | 12.1M | } |
4373 | | |
4374 | | /// Determine whether the given type T is a "bridgeable" C type. |
4375 | 504 | bool Type::isCARCBridgableType() const { |
4376 | 504 | const auto *Pointer = getAs<PointerType>(); |
4377 | 504 | if (!Pointer) |
4378 | 2 | return false; |
4379 | | |
4380 | 502 | QualType Pointee = Pointer->getPointeeType(); |
4381 | 502 | return Pointee->isVoidType() || Pointee->isRecordType()251 ; |
4382 | 504 | } |
4383 | | |
4384 | | /// Check if the specified type is the CUDA device builtin surface type. |
4385 | 16.4k | bool Type::isCUDADeviceBuiltinSurfaceType() const { |
4386 | 16.4k | if (const auto *RT = getAs<RecordType>()) |
4387 | 587 | return RT->getDecl()->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>(); |
4388 | 15.8k | return false; |
4389 | 16.4k | } |
4390 | | |
4391 | | /// Check if the specified type is the CUDA device builtin texture type. |
4392 | 16.4k | bool Type::isCUDADeviceBuiltinTextureType() const { |
4393 | 16.4k | if (const auto *RT = getAs<RecordType>()) |
4394 | 579 | return RT->getDecl()->hasAttr<CUDADeviceBuiltinTextureTypeAttr>(); |
4395 | 15.8k | return false; |
4396 | 16.4k | } |
4397 | | |
4398 | 251 | bool Type::hasSizedVLAType() const { |
4399 | 251 | if (!isVariablyModifiedType()) return false73 ; |
4400 | | |
4401 | 178 | if (const auto *ptr = getAs<PointerType>()) |
4402 | 82 | return ptr->getPointeeType()->hasSizedVLAType(); |
4403 | 96 | if (const auto *ref = getAs<ReferenceType>()) |
4404 | 1 | return ref->getPointeeType()->hasSizedVLAType(); |
4405 | 95 | if (const ArrayType *arr = getAsArrayTypeUnsafe()) { |
4406 | 90 | if (isa<VariableArrayType>(arr) && |
4407 | 90 | cast<VariableArrayType>(arr)->getSizeExpr()) |
4408 | 0 | return true; |
4409 | | |
4410 | 90 | return arr->getElementType()->hasSizedVLAType(); |
4411 | 90 | } |
4412 | | |
4413 | 5 | return false; |
4414 | 95 | } |
4415 | | |
4416 | 20.5M | QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) { |
4417 | 20.5M | switch (type.getObjCLifetime()) { |
4418 | 20.5M | case Qualifiers::OCL_None: |
4419 | 20.5M | case Qualifiers::OCL_ExplicitNone: |
4420 | 20.5M | case Qualifiers::OCL_Autoreleasing: |
4421 | 20.5M | break; |
4422 | | |
4423 | 6.57k | case Qualifiers::OCL_Strong: |
4424 | 6.57k | return DK_objc_strong_lifetime; |
4425 | 1.96k | case Qualifiers::OCL_Weak: |
4426 | 1.96k | return DK_objc_weak_lifetime; |
4427 | 20.5M | } |
4428 | | |
4429 | 20.5M | if (const auto *RT = |
4430 | 20.5M | type->getBaseElementTypeUnsafe()->getAs<RecordType>()) { |
4431 | 1.08M | const RecordDecl *RD = RT->getDecl(); |
4432 | 1.08M | if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { |
4433 | | /// Check if this is a C++ object with a non-trivial destructor. |
4434 | 497k | if (CXXRD->hasDefinition() && !CXXRD->hasTrivialDestructor()496k ) |
4435 | 84.0k | return DK_cxx_destructor; |
4436 | 585k | } else { |
4437 | | /// Check if this is a C struct that is non-trivial to destroy or an array |
4438 | | /// that contains such a struct. |
4439 | 585k | if (RD->isNonTrivialToPrimitiveDestroy()) |
4440 | 618 | return DK_nontrivial_c_struct; |
4441 | 585k | } |
4442 | 1.08M | } |
4443 | | |
4444 | 20.4M | return DK_none; |
4445 | 20.5M | } |
4446 | | |
4447 | 5.06k | CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const { |
4448 | 5.06k | return getClass()->getAsCXXRecordDecl()->getMostRecentNonInjectedDecl(); |
4449 | 5.06k | } |
4450 | | |
4451 | | void clang::FixedPointValueToString(SmallVectorImpl<char> &Str, |
4452 | 147 | llvm::APSInt Val, unsigned Scale) { |
4453 | 147 | llvm::FixedPointSemantics FXSema(Val.getBitWidth(), Scale, Val.isSigned(), |
4454 | 147 | /*IsSaturated=*/false, |
4455 | 147 | /*HasUnsignedPadding=*/false); |
4456 | 147 | llvm::APFixedPoint(Val, FXSema).toString(Str); |
4457 | 147 | } |
4458 | | |
4459 | | AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, |
4460 | | TypeDependence ExtraDependence, QualType Canon, |
4461 | | ConceptDecl *TypeConstraintConcept, |
4462 | | ArrayRef<TemplateArgument> TypeConstraintArgs) |
4463 | 57.5k | : DeducedType(Auto, DeducedAsType, ExtraDependence, Canon) { |
4464 | 57.5k | AutoTypeBits.Keyword = (unsigned)Keyword; |
4465 | 57.5k | AutoTypeBits.NumArgs = TypeConstraintArgs.size(); |
4466 | 57.5k | this->TypeConstraintConcept = TypeConstraintConcept; |
4467 | 57.5k | if (TypeConstraintConcept) { |
4468 | 265 | TemplateArgument *ArgBuffer = getArgBuffer(); |
4469 | 265 | for (const TemplateArgument &Arg : TypeConstraintArgs) { |
4470 | 140 | addDependence( |
4471 | 140 | toSyntacticDependence(toTypeDependence(Arg.getDependence()))); |
4472 | | |
4473 | 140 | new (ArgBuffer++) TemplateArgument(Arg); |
4474 | 140 | } |
4475 | 265 | } |
4476 | 57.5k | } |
4477 | | |
4478 | | void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
4479 | | QualType Deduced, AutoTypeKeyword Keyword, |
4480 | | bool IsDependent, ConceptDecl *CD, |
4481 | 206k | ArrayRef<TemplateArgument> Arguments) { |
4482 | 206k | ID.AddPointer(Deduced.getAsOpaquePtr()); |
4483 | 206k | ID.AddInteger((unsigned)Keyword); |
4484 | 206k | ID.AddBoolean(IsDependent); |
4485 | 206k | ID.AddPointer(CD); |
4486 | 206k | for (const TemplateArgument &Arg : Arguments) |
4487 | 433 | Arg.Profile(ID, Context); |
4488 | 206k | } |