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