/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/Type.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Type.h - C Language Family Type Representation -----------*- C++ -*-===// |
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 | | /// \file |
10 | | /// C Language Family Type Representation |
11 | | /// |
12 | | /// This file defines the clang::Type interface and subclasses, used to |
13 | | /// represent types for languages in the C family. |
14 | | // |
15 | | //===----------------------------------------------------------------------===// |
16 | | |
17 | | #ifndef LLVM_CLANG_AST_TYPE_H |
18 | | #define LLVM_CLANG_AST_TYPE_H |
19 | | |
20 | | #include "clang/AST/DependenceFlags.h" |
21 | | #include "clang/AST/NestedNameSpecifier.h" |
22 | | #include "clang/AST/TemplateName.h" |
23 | | #include "clang/Basic/AddressSpaces.h" |
24 | | #include "clang/Basic/AttrKinds.h" |
25 | | #include "clang/Basic/Diagnostic.h" |
26 | | #include "clang/Basic/ExceptionSpecificationType.h" |
27 | | #include "clang/Basic/LLVM.h" |
28 | | #include "clang/Basic/Linkage.h" |
29 | | #include "clang/Basic/PartialDiagnostic.h" |
30 | | #include "clang/Basic/SourceLocation.h" |
31 | | #include "clang/Basic/Specifiers.h" |
32 | | #include "clang/Basic/Visibility.h" |
33 | | #include "llvm/ADT/APInt.h" |
34 | | #include "llvm/ADT/APSInt.h" |
35 | | #include "llvm/ADT/ArrayRef.h" |
36 | | #include "llvm/ADT/FoldingSet.h" |
37 | | #include "llvm/ADT/PointerIntPair.h" |
38 | | #include "llvm/ADT/PointerUnion.h" |
39 | | #include "llvm/ADT/StringRef.h" |
40 | | #include "llvm/ADT/Twine.h" |
41 | | #include "llvm/ADT/iterator_range.h" |
42 | | #include "llvm/Support/Casting.h" |
43 | | #include "llvm/Support/Compiler.h" |
44 | | #include "llvm/Support/ErrorHandling.h" |
45 | | #include "llvm/Support/PointerLikeTypeTraits.h" |
46 | | #include "llvm/Support/TrailingObjects.h" |
47 | | #include "llvm/Support/type_traits.h" |
48 | | #include <cassert> |
49 | | #include <cstddef> |
50 | | #include <cstdint> |
51 | | #include <cstring> |
52 | | #include <optional> |
53 | | #include <string> |
54 | | #include <type_traits> |
55 | | #include <utility> |
56 | | |
57 | | namespace clang { |
58 | | |
59 | | class BTFTypeTagAttr; |
60 | | class ExtQuals; |
61 | | class QualType; |
62 | | class ConceptDecl; |
63 | | class TagDecl; |
64 | | class TemplateParameterList; |
65 | | class Type; |
66 | | |
67 | | enum { |
68 | | TypeAlignmentInBits = 4, |
69 | | TypeAlignment = 1 << TypeAlignmentInBits |
70 | | }; |
71 | | |
72 | | namespace serialization { |
73 | | template <class T> class AbstractTypeReader; |
74 | | template <class T> class AbstractTypeWriter; |
75 | | } |
76 | | |
77 | | } // namespace clang |
78 | | |
79 | | namespace llvm { |
80 | | |
81 | | template <typename T> |
82 | | struct PointerLikeTypeTraits; |
83 | | template<> |
84 | | struct PointerLikeTypeTraits< ::clang::Type*> { |
85 | 2.96G | static inline void *getAsVoidPointer(::clang::Type *P) { return P; } |
86 | | |
87 | 292M | static inline ::clang::Type *getFromVoidPointer(void *P) { |
88 | 292M | return static_cast< ::clang::Type*>(P); |
89 | 292M | } |
90 | | |
91 | | static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; |
92 | | }; |
93 | | |
94 | | template<> |
95 | | struct PointerLikeTypeTraits< ::clang::ExtQuals*> { |
96 | 664k | static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; } |
97 | | |
98 | 4.93M | static inline ::clang::ExtQuals *getFromVoidPointer(void *P) { |
99 | 4.93M | return static_cast< ::clang::ExtQuals*>(P); |
100 | 4.93M | } |
101 | | |
102 | | static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; |
103 | | }; |
104 | | |
105 | | } // namespace llvm |
106 | | |
107 | | namespace clang { |
108 | | |
109 | | class ASTContext; |
110 | | template <typename> class CanQual; |
111 | | class CXXRecordDecl; |
112 | | class DeclContext; |
113 | | class EnumDecl; |
114 | | class Expr; |
115 | | class ExtQualsTypeCommonBase; |
116 | | class FunctionDecl; |
117 | | class IdentifierInfo; |
118 | | class NamedDecl; |
119 | | class ObjCInterfaceDecl; |
120 | | class ObjCProtocolDecl; |
121 | | class ObjCTypeParamDecl; |
122 | | struct PrintingPolicy; |
123 | | class RecordDecl; |
124 | | class Stmt; |
125 | | class TagDecl; |
126 | | class TemplateArgument; |
127 | | class TemplateArgumentListInfo; |
128 | | class TemplateArgumentLoc; |
129 | | class TemplateTypeParmDecl; |
130 | | class TypedefNameDecl; |
131 | | class UnresolvedUsingTypenameDecl; |
132 | | class UsingShadowDecl; |
133 | | |
134 | | using CanQualType = CanQual<Type>; |
135 | | |
136 | | // Provide forward declarations for all of the *Type classes. |
137 | | #define TYPE(Class, Base) class Class##Type; |
138 | | #include "clang/AST/TypeNodes.inc" |
139 | | |
140 | | /// The collection of all-type qualifiers we support. |
141 | | /// Clang supports five independent qualifiers: |
142 | | /// * C99: const, volatile, and restrict |
143 | | /// * MS: __unaligned |
144 | | /// * Embedded C (TR18037): address spaces |
145 | | /// * Objective C: the GC attributes (none, weak, or strong) |
146 | | class Qualifiers { |
147 | | public: |
148 | | enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. |
149 | | Const = 0x1, |
150 | | Restrict = 0x2, |
151 | | Volatile = 0x4, |
152 | | CVRMask = Const | Volatile | Restrict |
153 | | }; |
154 | | |
155 | | enum GC { |
156 | | GCNone = 0, |
157 | | Weak, |
158 | | Strong |
159 | | }; |
160 | | |
161 | | enum ObjCLifetime { |
162 | | /// There is no lifetime qualification on this type. |
163 | | OCL_None, |
164 | | |
165 | | /// This object can be modified without requiring retains or |
166 | | /// releases. |
167 | | OCL_ExplicitNone, |
168 | | |
169 | | /// Assigning into this object requires the old value to be |
170 | | /// released and the new value to be retained. The timing of the |
171 | | /// release of the old value is inexact: it may be moved to |
172 | | /// immediately after the last known point where the value is |
173 | | /// live. |
174 | | OCL_Strong, |
175 | | |
176 | | /// Reading or writing from this object requires a barrier call. |
177 | | OCL_Weak, |
178 | | |
179 | | /// Assigning into this object requires a lifetime extension. |
180 | | OCL_Autoreleasing |
181 | | }; |
182 | | |
183 | | enum { |
184 | | /// The maximum supported address space number. |
185 | | /// 23 bits should be enough for anyone. |
186 | | MaxAddressSpace = 0x7fffffu, |
187 | | |
188 | | /// The width of the "fast" qualifier mask. |
189 | | FastWidth = 3, |
190 | | |
191 | | /// The fast qualifier mask. |
192 | | FastMask = (1 << FastWidth) - 1 |
193 | | }; |
194 | | |
195 | | /// Returns the common set of qualifiers while removing them from |
196 | | /// the given sets. |
197 | 9.67M | static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { |
198 | | // If both are only CVR-qualified, bit operations are sufficient. |
199 | 9.67M | if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)9.67M ) { |
200 | 9.67M | Qualifiers Q; |
201 | 9.67M | Q.Mask = L.Mask & R.Mask; |
202 | 9.67M | L.Mask &= ~Q.Mask; |
203 | 9.67M | R.Mask &= ~Q.Mask; |
204 | 9.67M | return Q; |
205 | 9.67M | } |
206 | | |
207 | 1.22k | Qualifiers Q; |
208 | 1.22k | unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); |
209 | 1.22k | Q.addCVRQualifiers(CommonCRV); |
210 | 1.22k | L.removeCVRQualifiers(CommonCRV); |
211 | 1.22k | R.removeCVRQualifiers(CommonCRV); |
212 | | |
213 | 1.22k | if (L.getObjCGCAttr() == R.getObjCGCAttr()) { |
214 | 1.21k | Q.setObjCGCAttr(L.getObjCGCAttr()); |
215 | 1.21k | L.removeObjCGCAttr(); |
216 | 1.21k | R.removeObjCGCAttr(); |
217 | 1.21k | } |
218 | | |
219 | 1.22k | if (L.getObjCLifetime() == R.getObjCLifetime()) { |
220 | 826 | Q.setObjCLifetime(L.getObjCLifetime()); |
221 | 826 | L.removeObjCLifetime(); |
222 | 826 | R.removeObjCLifetime(); |
223 | 826 | } |
224 | | |
225 | 1.22k | if (L.getAddressSpace() == R.getAddressSpace()) { |
226 | 413 | Q.setAddressSpace(L.getAddressSpace()); |
227 | 413 | L.removeAddressSpace(); |
228 | 413 | R.removeAddressSpace(); |
229 | 413 | } |
230 | 1.22k | return Q; |
231 | 9.67M | } |
232 | | |
233 | 144M | static Qualifiers fromFastMask(unsigned Mask) { |
234 | 144M | Qualifiers Qs; |
235 | 144M | Qs.addFastQualifiers(Mask); |
236 | 144M | return Qs; |
237 | 144M | } |
238 | | |
239 | 7.05M | static Qualifiers fromCVRMask(unsigned CVR) { |
240 | 7.05M | Qualifiers Qs; |
241 | 7.05M | Qs.addCVRQualifiers(CVR); |
242 | 7.05M | return Qs; |
243 | 7.05M | } |
244 | | |
245 | 1.89M | static Qualifiers fromCVRUMask(unsigned CVRU) { |
246 | 1.89M | Qualifiers Qs; |
247 | 1.89M | Qs.addCVRUQualifiers(CVRU); |
248 | 1.89M | return Qs; |
249 | 1.89M | } |
250 | | |
251 | | // Deserialize qualifiers from an opaque representation. |
252 | 521k | static Qualifiers fromOpaqueValue(unsigned opaque) { |
253 | 521k | Qualifiers Qs; |
254 | 521k | Qs.Mask = opaque; |
255 | 521k | return Qs; |
256 | 521k | } |
257 | | |
258 | | // Serialize these qualifiers into an opaque representation. |
259 | 4.27M | unsigned getAsOpaqueValue() const { |
260 | 4.27M | return Mask; |
261 | 4.27M | } |
262 | | |
263 | 11.5M | bool hasConst() const { return Mask & Const; } |
264 | 506 | bool hasOnlyConst() const { return Mask == Const; } |
265 | 489k | void removeConst() { Mask &= ~Const; } |
266 | 388k | void addConst() { Mask |= Const; } |
267 | 0 | Qualifiers withConst() const { |
268 | 0 | Qualifiers Qs = *this; |
269 | 0 | Qs.addConst(); |
270 | 0 | return Qs; |
271 | 0 | } |
272 | | |
273 | 25.2M | bool hasVolatile() const { return Mask & Volatile; } |
274 | 26 | bool hasOnlyVolatile() const { return Mask == Volatile; } |
275 | 3.14M | void removeVolatile() { Mask &= ~Volatile; } |
276 | 2.90M | void addVolatile() { Mask |= Volatile; } |
277 | 2.75M | Qualifiers withVolatile() const { |
278 | 2.75M | Qualifiers Qs = *this; |
279 | 2.75M | Qs.addVolatile(); |
280 | 2.75M | return Qs; |
281 | 2.75M | } |
282 | | |
283 | 8.47M | bool hasRestrict() const { return Mask & Restrict; } |
284 | 20 | bool hasOnlyRestrict() const { return Mask == Restrict; } |
285 | 1.90M | void removeRestrict() { Mask &= ~Restrict; } |
286 | 152k | void addRestrict() { Mask |= Restrict; } |
287 | 0 | Qualifiers withRestrict() const { |
288 | 0 | Qualifiers Qs = *this; |
289 | 0 | Qs.addRestrict(); |
290 | 0 | return Qs; |
291 | 0 | } |
292 | | |
293 | 29 | bool hasCVRQualifiers() const { return getCVRQualifiers(); } |
294 | 29.5M | unsigned getCVRQualifiers() const { return Mask & CVRMask; } |
295 | 83.7k | unsigned getCVRUQualifiers() const { return Mask & (CVRMask | UMask); } |
296 | | |
297 | 1.48M | void setCVRQualifiers(unsigned mask) { |
298 | 1.48M | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); |
299 | 1.48M | Mask = (Mask & ~CVRMask) | mask; |
300 | 1.48M | } |
301 | 5.06M | void removeCVRQualifiers(unsigned mask) { |
302 | 5.06M | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); |
303 | 5.06M | Mask &= ~mask; |
304 | 5.06M | } |
305 | 3.13M | void removeCVRQualifiers() { |
306 | 3.13M | removeCVRQualifiers(CVRMask); |
307 | 3.13M | } |
308 | 7.25M | void addCVRQualifiers(unsigned mask) { |
309 | 7.25M | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); |
310 | 7.25M | Mask |= mask; |
311 | 7.25M | } |
312 | 34.1M | void addCVRUQualifiers(unsigned mask) { |
313 | 34.1M | assert(!(mask & ~CVRMask & ~UMask) && "bitmask contains non-CVRU bits"); |
314 | 34.1M | Mask |= mask; |
315 | 34.1M | } |
316 | | |
317 | 35.7M | bool hasUnaligned() const { return Mask & UMask; } |
318 | 5.97M | void setUnaligned(bool flag) { |
319 | 5.97M | Mask = (Mask & ~UMask) | (flag ? UMask152 : 05.97M ); |
320 | 5.97M | } |
321 | 9.22M | void removeUnaligned() { Mask &= ~UMask; } |
322 | 0 | void addUnaligned() { Mask |= UMask; } |
323 | | |
324 | 2.17M | bool hasObjCGCAttr() const { return Mask & GCAttrMask; } |
325 | 48.7M | GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } |
326 | 7.83M | void setObjCGCAttr(GC type) { |
327 | 7.83M | Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift); |
328 | 7.83M | } |
329 | 2.85M | void removeObjCGCAttr() { setObjCGCAttr(GCNone); } |
330 | 258 | void addObjCGCAttr(GC type) { |
331 | 258 | assert(type); |
332 | 258 | setObjCGCAttr(type); |
333 | 258 | } |
334 | 382 | Qualifiers withoutObjCGCAttr() const { |
335 | 382 | Qualifiers qs = *this; |
336 | 382 | qs.removeObjCGCAttr(); |
337 | 382 | return qs; |
338 | 382 | } |
339 | 522 | Qualifiers withoutObjCLifetime() const { |
340 | 522 | Qualifiers qs = *this; |
341 | 522 | qs.removeObjCLifetime(); |
342 | 522 | return qs; |
343 | 522 | } |
344 | 6 | Qualifiers withoutAddressSpace() const { |
345 | 6 | Qualifiers qs = *this; |
346 | 6 | qs.removeAddressSpace(); |
347 | 6 | return qs; |
348 | 6 | } |
349 | | |
350 | 48.5M | bool hasObjCLifetime() const { return Mask & LifetimeMask; } |
351 | 110M | ObjCLifetime getObjCLifetime() const { |
352 | 110M | return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift); |
353 | 110M | } |
354 | 730k | void setObjCLifetime(ObjCLifetime type) { |
355 | 730k | Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift); |
356 | 730k | } |
357 | 657k | void removeObjCLifetime() { setObjCLifetime(OCL_None); } |
358 | 31.2k | void addObjCLifetime(ObjCLifetime type) { |
359 | 31.2k | assert(type); |
360 | 31.2k | assert(!hasObjCLifetime()); |
361 | 31.2k | Mask |= (type << LifetimeShift); |
362 | 31.2k | } |
363 | | |
364 | | /// True if the lifetime is neither None or ExplicitNone. |
365 | 4.56M | bool hasNonTrivialObjCLifetime() const { |
366 | 4.56M | ObjCLifetime lifetime = getObjCLifetime(); |
367 | 4.56M | return (lifetime > OCL_ExplicitNone); |
368 | 4.56M | } |
369 | | |
370 | | /// True if the lifetime is either strong or weak. |
371 | 150 | bool hasStrongOrWeakObjCLifetime() const { |
372 | 150 | ObjCLifetime lifetime = getObjCLifetime(); |
373 | 150 | return (lifetime == OCL_Strong || lifetime == OCL_Weak148 ); |
374 | 150 | } |
375 | | |
376 | 32.2M | bool hasAddressSpace() const { return Mask & AddressSpaceMask; } |
377 | 248M | LangAS getAddressSpace() const { |
378 | 248M | return static_cast<LangAS>(Mask >> AddressSpaceShift); |
379 | 248M | } |
380 | 10 | bool hasTargetSpecificAddressSpace() const { |
381 | 10 | return isTargetAddressSpace(getAddressSpace()); |
382 | 10 | } |
383 | | /// Get the address space attribute value to be printed by diagnostics. |
384 | 10 | unsigned getAddressSpaceAttributePrintValue() const { |
385 | 10 | auto Addr = getAddressSpace(); |
386 | | // This function is not supposed to be used with language specific |
387 | | // address spaces. If that happens, the diagnostic message should consider |
388 | | // printing the QualType instead of the address space value. |
389 | 10 | assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace()); |
390 | 10 | if (Addr != LangAS::Default) |
391 | 10 | return toTargetAddressSpace(Addr); |
392 | | // TODO: The diagnostic messages where Addr may be 0 should be fixed |
393 | | // since it cannot differentiate the situation where 0 denotes the default |
394 | | // address space or user specified __attribute__((address_space(0))). |
395 | 0 | return 0; |
396 | 10 | } |
397 | 1.02M | void setAddressSpace(LangAS space) { |
398 | 1.02M | assert((unsigned)space <= MaxAddressSpace); |
399 | 1.02M | Mask = (Mask & ~AddressSpaceMask) |
400 | 1.02M | | (((uint32_t) space) << AddressSpaceShift); |
401 | 1.02M | } |
402 | 400k | void removeAddressSpace() { setAddressSpace(LangAS::Default); } |
403 | 537k | void addAddressSpace(LangAS space) { |
404 | 537k | assert(space != LangAS::Default); |
405 | 537k | setAddressSpace(space); |
406 | 537k | } |
407 | | |
408 | | // Fast qualifiers are those that can be allocated directly |
409 | | // on a QualType object. |
410 | 1.68M | bool hasFastQualifiers() const { return getFastQualifiers(); } |
411 | 133M | unsigned getFastQualifiers() const { return Mask & FastMask; } |
412 | 0 | void setFastQualifiers(unsigned mask) { |
413 | 0 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); |
414 | 0 | Mask = (Mask & ~FastMask) | mask; |
415 | 0 | } |
416 | 635k | void removeFastQualifiers(unsigned mask) { |
417 | 635k | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); |
418 | 635k | Mask &= ~mask; |
419 | 635k | } |
420 | 635k | void removeFastQualifiers() { |
421 | 635k | removeFastQualifiers(FastMask); |
422 | 635k | } |
423 | 1.29G | void addFastQualifiers(unsigned mask) { |
424 | 1.29G | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); |
425 | 1.29G | Mask |= mask; |
426 | 1.29G | } |
427 | | |
428 | | /// Return true if the set contains any qualifiers which require an ExtQuals |
429 | | /// node to be allocated. |
430 | 149M | bool hasNonFastQualifiers() const { return Mask & ~FastMask; } |
431 | 0 | Qualifiers getNonFastQualifiers() const { |
432 | 0 | Qualifiers Quals = *this; |
433 | 0 | Quals.setFastQualifiers(0); |
434 | 0 | return Quals; |
435 | 0 | } |
436 | | |
437 | | /// Return true if the set contains any qualifiers. |
438 | 26.4M | bool hasQualifiers() const { return Mask; } |
439 | 4.57M | bool empty() const { return !Mask; } |
440 | | |
441 | | /// Add the qualifiers from the given set to this set. |
442 | 20.4M | void addQualifiers(Qualifiers Q) { |
443 | | // If the other set doesn't have any non-boolean qualifiers, just |
444 | | // bit-or it in. |
445 | 20.4M | if (!(Q.Mask & ~CVRMask)) |
446 | 20.4M | Mask |= Q.Mask; |
447 | 1.34k | else { |
448 | 1.34k | Mask |= (Q.Mask & CVRMask); |
449 | 1.34k | if (Q.hasAddressSpace()) |
450 | 806 | addAddressSpace(Q.getAddressSpace()); |
451 | 1.34k | if (Q.hasObjCGCAttr()) |
452 | 38 | addObjCGCAttr(Q.getObjCGCAttr()); |
453 | 1.34k | if (Q.hasObjCLifetime()) |
454 | 494 | addObjCLifetime(Q.getObjCLifetime()); |
455 | 1.34k | } |
456 | 20.4M | } |
457 | | |
458 | | /// Remove the qualifiers from the given set from this set. |
459 | 578k | void removeQualifiers(Qualifiers Q) { |
460 | | // If the other set doesn't have any non-boolean qualifiers, just |
461 | | // bit-and the inverse in. |
462 | 578k | if (!(Q.Mask & ~CVRMask)) |
463 | 578k | Mask &= ~Q.Mask; |
464 | 69 | else { |
465 | 69 | Mask &= ~(Q.Mask & CVRMask); |
466 | 69 | if (getObjCGCAttr() == Q.getObjCGCAttr()) |
467 | 69 | removeObjCGCAttr(); |
468 | 69 | if (getObjCLifetime() == Q.getObjCLifetime()) |
469 | 69 | removeObjCLifetime(); |
470 | 69 | if (getAddressSpace() == Q.getAddressSpace()) |
471 | 10 | removeAddressSpace(); |
472 | 69 | } |
473 | 578k | } |
474 | | |
475 | | /// Add the qualifiers from the given set to this set, given that |
476 | | /// they don't conflict. |
477 | 2.33M | void addConsistentQualifiers(Qualifiers qs) { |
478 | 2.33M | assert(getAddressSpace() == qs.getAddressSpace() || |
479 | 2.33M | !hasAddressSpace() || !qs.hasAddressSpace()); |
480 | 2.33M | assert(getObjCGCAttr() == qs.getObjCGCAttr() || |
481 | 2.33M | !hasObjCGCAttr() || !qs.hasObjCGCAttr()); |
482 | 2.33M | assert(getObjCLifetime() == qs.getObjCLifetime() || |
483 | 2.33M | !hasObjCLifetime() || !qs.hasObjCLifetime()); |
484 | 2.33M | Mask |= qs.Mask; |
485 | 2.33M | } |
486 | | |
487 | | /// Returns true if address space A is equal to or a superset of B. |
488 | | /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of |
489 | | /// overlapping address spaces. |
490 | | /// CL1.1 or CL1.2: |
491 | | /// every address space is a superset of itself. |
492 | | /// CL2.0 adds: |
493 | | /// __generic is a superset of any address space except for __constant. |
494 | 11.7M | static bool isAddressSpaceSupersetOf(LangAS A, LangAS B) { |
495 | | // Address spaces must match exactly. |
496 | 11.7M | return A == B || |
497 | | // Otherwise in OpenCLC v2.0 s6.5.5: every address space except |
498 | | // for __constant can be used as __generic. |
499 | 11.7M | (133k A == LangAS::opencl_generic133k && B != LangAS::opencl_constant11.0k ) || |
500 | | // We also define global_device and global_host address spaces, |
501 | | // to distinguish global pointers allocated on host from pointers |
502 | | // allocated on device, which are a subset of __global. |
503 | 11.7M | (127k A == LangAS::opencl_global127k && (57.7k B == LangAS::opencl_global_device57.7k || |
504 | 57.7k | B == LangAS::opencl_global_host57.7k )) || |
505 | 11.7M | (127k A == LangAS::sycl_global127k && (20 B == LangAS::sycl_global_device20 || |
506 | 20 | B == LangAS::sycl_global_host17 )) || |
507 | | // Consider pointer size address spaces to be equivalent to default. |
508 | 11.7M | (127k (127k isPtrSizeAddressSpace(A)127k || A == LangAS::Default127k ) && |
509 | 127k | (464 isPtrSizeAddressSpace(B)464 || B == LangAS::Default443 )) || |
510 | | // Default is a superset of SYCL address spaces. |
511 | 11.7M | (127k A == LangAS::Default127k && |
512 | 127k | (431 B == LangAS::sycl_private431 || B == LangAS::sycl_local411 || |
513 | 431 | B == LangAS::sycl_global375 || B == LangAS::sycl_global_device329 || |
514 | 431 | B == LangAS::sycl_global_host321 )) || |
515 | | // In HIP device compilation, any cuda address space is allowed |
516 | | // to implicitly cast into the default address space. |
517 | 11.7M | (127k A == LangAS::Default127k && |
518 | 127k | (313 B == LangAS::cuda_constant313 || B == LangAS::cuda_device303 || |
519 | 313 | B == LangAS::cuda_shared303 )); |
520 | 11.7M | } |
521 | | |
522 | | /// Returns true if the address space in these qualifiers is equal to or |
523 | | /// a superset of the address space in the argument qualifiers. |
524 | 9.25M | bool isAddressSpaceSupersetOf(Qualifiers other) const { |
525 | 9.25M | return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace()); |
526 | 9.25M | } |
527 | | |
528 | | /// Determines if these qualifiers compatibly include another set. |
529 | | /// Generally this answers the question of whether an object with the other |
530 | | /// qualifiers can be safely used as an object with these qualifiers. |
531 | 9.12M | bool compatiblyIncludes(Qualifiers other) const { |
532 | 9.12M | return isAddressSpaceSupersetOf(other) && |
533 | | // ObjC GC qualifiers can match, be added, or be removed, but can't |
534 | | // be changed. |
535 | 9.12M | (9.04M getObjCGCAttr() == other.getObjCGCAttr()9.04M || !hasObjCGCAttr()18 || |
536 | 9.04M | !other.hasObjCGCAttr()15 ) && |
537 | | // ObjC lifetime qualifiers must match exactly. |
538 | 9.12M | getObjCLifetime() == other.getObjCLifetime()9.04M && |
539 | | // CVR qualifiers may subset. |
540 | 9.12M | (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask))9.04M && |
541 | | // U qualifier may superset. |
542 | 9.12M | (8.74M !other.hasUnaligned()8.74M || hasUnaligned()2 ); |
543 | 9.12M | } |
544 | | |
545 | | /// Determines if these qualifiers compatibly include another set of |
546 | | /// qualifiers from the narrow perspective of Objective-C ARC lifetime. |
547 | | /// |
548 | | /// One set of Objective-C lifetime qualifiers compatibly includes the other |
549 | | /// if the lifetime qualifiers match, or if both are non-__weak and the |
550 | | /// including set also contains the 'const' qualifier, or both are non-__weak |
551 | | /// and one is None (which can only happen in non-ARC modes). |
552 | 21.1k | bool compatiblyIncludesObjCLifetime(Qualifiers other) const { |
553 | 21.1k | if (getObjCLifetime() == other.getObjCLifetime()) |
554 | 20.8k | return true; |
555 | | |
556 | 303 | if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak252 ) |
557 | 128 | return false; |
558 | | |
559 | 175 | if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None142 ) |
560 | 76 | return true; |
561 | | |
562 | 99 | return hasConst(); |
563 | 175 | } |
564 | | |
565 | | /// Determine whether this set of qualifiers is a strict superset of |
566 | | /// another set of qualifiers, not considering qualifier compatibility. |
567 | | bool isStrictSupersetOf(Qualifiers Other) const; |
568 | | |
569 | 4.01M | bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } |
570 | 43.1M | bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } |
571 | | |
572 | 26.3M | explicit operator bool() const { return hasQualifiers(); } |
573 | | |
574 | 20.4M | Qualifiers &operator+=(Qualifiers R) { |
575 | 20.4M | addQualifiers(R); |
576 | 20.4M | return *this; |
577 | 20.4M | } |
578 | | |
579 | | // Union two qualifier sets. If an enumerated qualifier appears |
580 | | // in both sets, use the one from the right. |
581 | 1.21M | friend Qualifiers operator+(Qualifiers L, Qualifiers R) { |
582 | 1.21M | L += R; |
583 | 1.21M | return L; |
584 | 1.21M | } |
585 | | |
586 | 578k | Qualifiers &operator-=(Qualifiers R) { |
587 | 578k | removeQualifiers(R); |
588 | 578k | return *this; |
589 | 578k | } |
590 | | |
591 | | /// Compute the difference between two qualifier sets. |
592 | 13.7k | friend Qualifiers operator-(Qualifiers L, Qualifiers R) { |
593 | 13.7k | L -= R; |
594 | 13.7k | return L; |
595 | 13.7k | } |
596 | | |
597 | | std::string getAsString() const; |
598 | | std::string getAsString(const PrintingPolicy &Policy) const; |
599 | | |
600 | | static std::string getAddrSpaceAsString(LangAS AS); |
601 | | |
602 | | bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; |
603 | | void print(raw_ostream &OS, const PrintingPolicy &Policy, |
604 | | bool appendSpaceIfNonEmpty = false) const; |
605 | | |
606 | 120M | void Profile(llvm::FoldingSetNodeID &ID) const { |
607 | 120M | ID.AddInteger(Mask); |
608 | 120M | } |
609 | | |
610 | | private: |
611 | | // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| |
612 | | // |C R V|U|GCAttr|Lifetime|AddressSpace| |
613 | | uint32_t Mask = 0; |
614 | | |
615 | | static const uint32_t UMask = 0x8; |
616 | | static const uint32_t UShift = 3; |
617 | | static const uint32_t GCAttrMask = 0x30; |
618 | | static const uint32_t GCAttrShift = 4; |
619 | | static const uint32_t LifetimeMask = 0x1C0; |
620 | | static const uint32_t LifetimeShift = 6; |
621 | | static const uint32_t AddressSpaceMask = |
622 | | ~(CVRMask | UMask | GCAttrMask | LifetimeMask); |
623 | | static const uint32_t AddressSpaceShift = 9; |
624 | | }; |
625 | | |
626 | | class QualifiersAndAtomic { |
627 | | Qualifiers Quals; |
628 | | bool HasAtomic; |
629 | | |
630 | | public: |
631 | 4.06M | QualifiersAndAtomic() : HasAtomic(false) {} |
632 | | QualifiersAndAtomic(Qualifiers Quals, bool HasAtomic) |
633 | 2.75M | : Quals(Quals), HasAtomic(HasAtomic) {} |
634 | | |
635 | 416k | operator Qualifiers() const { return Quals; } |
636 | | |
637 | 18.7M | bool hasVolatile() const { return Quals.hasVolatile(); } |
638 | 0 | bool hasConst() const { return Quals.hasConst(); } |
639 | 14.0k | bool hasRestrict() const { return Quals.hasRestrict(); } |
640 | 15.9M | bool hasAtomic() const { return HasAtomic; } |
641 | | |
642 | 0 | void addVolatile() { Quals.addVolatile(); } |
643 | 234k | void addConst() { Quals.addConst(); } |
644 | 0 | void addRestrict() { Quals.addRestrict(); } |
645 | 12 | void addAtomic() { HasAtomic = true; } |
646 | | |
647 | 2.75M | void removeVolatile() { Quals.removeVolatile(); } |
648 | 0 | void removeConst() { Quals.removeConst(); } |
649 | 0 | void removeRestrict() { Quals.removeRestrict(); } |
650 | 2.26k | void removeAtomic() { HasAtomic = false; } |
651 | | |
652 | 2.75M | QualifiersAndAtomic withVolatile() { |
653 | 2.75M | return {Quals.withVolatile(), HasAtomic}; |
654 | 2.75M | } |
655 | 0 | QualifiersAndAtomic withConst() { return {Quals.withConst(), HasAtomic}; } |
656 | 0 | QualifiersAndAtomic withRestrict() { |
657 | 0 | return {Quals.withRestrict(), HasAtomic}; |
658 | 0 | } |
659 | 2.26k | QualifiersAndAtomic withAtomic() { return {Quals, true}; } |
660 | | |
661 | 416k | QualifiersAndAtomic &operator+=(Qualifiers RHS) { |
662 | 416k | Quals += RHS; |
663 | 416k | return *this; |
664 | 416k | } |
665 | | }; |
666 | | |
667 | | /// A std::pair-like structure for storing a qualified type split |
668 | | /// into its local qualifiers and its locally-unqualified type. |
669 | | struct SplitQualType { |
670 | | /// The locally-unqualified type. |
671 | | const Type *Ty = nullptr; |
672 | | |
673 | | /// The local qualifiers. |
674 | | Qualifiers Quals; |
675 | | |
676 | | SplitQualType() = default; |
677 | 122M | SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {} |
678 | | |
679 | | SplitQualType getSingleStepDesugaredType() const; // end of this file |
680 | | |
681 | | // Make std::tie work. |
682 | 361k | std::pair<const Type *,Qualifiers> asPair() const { |
683 | 361k | return std::pair<const Type *, Qualifiers>(Ty, Quals); |
684 | 361k | } |
685 | | |
686 | 0 | friend bool operator==(SplitQualType a, SplitQualType b) { |
687 | 0 | return a.Ty == b.Ty && a.Quals == b.Quals; |
688 | 0 | } |
689 | 69.4k | friend bool operator!=(SplitQualType a, SplitQualType b) { |
690 | 69.4k | return a.Ty != b.Ty || a.Quals != b.Quals60.8k ; |
691 | 69.4k | } |
692 | | }; |
693 | | |
694 | | /// The kind of type we are substituting Objective-C type arguments into. |
695 | | /// |
696 | | /// The kind of substitution affects the replacement of type parameters when |
697 | | /// no concrete type information is provided, e.g., when dealing with an |
698 | | /// unspecialized type. |
699 | | enum class ObjCSubstitutionContext { |
700 | | /// An ordinary type. |
701 | | Ordinary, |
702 | | |
703 | | /// The result type of a method or function. |
704 | | Result, |
705 | | |
706 | | /// The parameter type of a method or function. |
707 | | Parameter, |
708 | | |
709 | | /// The type of a property. |
710 | | Property, |
711 | | |
712 | | /// The superclass of a type. |
713 | | Superclass, |
714 | | }; |
715 | | |
716 | | /// The kind of 'typeof' expression we're after. |
717 | | enum class TypeOfKind : uint8_t { |
718 | | Qualified, |
719 | | Unqualified, |
720 | | }; |
721 | | |
722 | | /// A (possibly-)qualified type. |
723 | | /// |
724 | | /// For efficiency, we don't store CV-qualified types as nodes on their |
725 | | /// own: instead each reference to a type stores the qualifiers. This |
726 | | /// greatly reduces the number of nodes we need to allocate for types (for |
727 | | /// example we only need one for 'int', 'const int', 'volatile int', |
728 | | /// 'const volatile int', etc). |
729 | | /// |
730 | | /// As an added efficiency bonus, instead of making this a pair, we |
731 | | /// just store the two bits we care about in the low bits of the |
732 | | /// pointer. To handle the packing/unpacking, we make QualType be a |
733 | | /// simple wrapper class that acts like a smart pointer. A third bit |
734 | | /// indicates whether there are extended qualifiers present, in which |
735 | | /// case the pointer points to a special structure. |
736 | | class QualType { |
737 | | friend class QualifierCollector; |
738 | | |
739 | | // Thankfully, these are efficiently composable. |
740 | | llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>, |
741 | | Qualifiers::FastWidth> Value; |
742 | | |
743 | 4.93M | const ExtQuals *getExtQualsUnsafe() const { |
744 | 4.93M | return Value.getPointer().get<const ExtQuals*>(); |
745 | 4.93M | } |
746 | | |
747 | 291M | const Type *getTypePtrUnsafe() const { |
748 | 291M | return Value.getPointer().get<const Type*>(); |
749 | 291M | } |
750 | | |
751 | 38.9G | const ExtQualsTypeCommonBase *getCommonPtr() const { |
752 | 38.9G | assert(!isNull() && "Cannot retrieve a NULL type pointer"); |
753 | 38.9G | auto CommonPtrVal = reinterpret_cast<uintptr_t>(Value.getOpaqueValue()); |
754 | 38.9G | CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1); |
755 | 38.9G | return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal); |
756 | 38.9G | } |
757 | | |
758 | | public: |
759 | 17.6G | QualType() = default; |
760 | 2.96G | QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {} |
761 | 664k | QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {} |
762 | | |
763 | 10.7G | unsigned getLocalFastQualifiers() const { return Value.getInt(); } |
764 | 0 | void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } |
765 | | |
766 | | bool UseExcessPrecision(const ASTContext &Ctx); |
767 | | |
768 | | /// Retrieves a pointer to the underlying (unqualified) type. |
769 | | /// |
770 | | /// This function requires that the type not be NULL. If the type might be |
771 | | /// NULL, use the (slightly less efficient) \c getTypePtrOrNull(). |
772 | | const Type *getTypePtr() const; |
773 | | |
774 | | const Type *getTypePtrOrNull() const; |
775 | | |
776 | | /// Retrieves a pointer to the name of the base type. |
777 | | const IdentifierInfo *getBaseTypeIdentifier() const; |
778 | | |
779 | | /// Divides a QualType into its unqualified type and a set of local |
780 | | /// qualifiers. |
781 | | SplitQualType split() const; |
782 | | |
783 | 4.09G | void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } |
784 | | |
785 | 14.1G | static QualType getFromOpaquePtr(const void *Ptr) { |
786 | 14.1G | QualType T; |
787 | 14.1G | T.Value.setFromOpaqueValue(const_cast<void*>(Ptr)); |
788 | 14.1G | return T; |
789 | 14.1G | } |
790 | | |
791 | 3.31M | const Type &operator*() const { |
792 | 3.31M | return *getTypePtr(); |
793 | 3.31M | } |
794 | | |
795 | 11.7G | const Type *operator->() const { |
796 | 11.7G | return getTypePtr(); |
797 | 11.7G | } |
798 | | |
799 | | bool isCanonical() const; |
800 | | bool isCanonicalAsParam() const; |
801 | | |
802 | | /// Return true if this QualType doesn't point to a type yet. |
803 | 45.0G | bool isNull() const { |
804 | 45.0G | return Value.getPointer().isNull(); |
805 | 45.0G | } |
806 | | |
807 | | // Determines if a type can form `T&`. |
808 | | bool isReferenceable() const; |
809 | | |
810 | | /// Determine whether this particular QualType instance has the |
811 | | /// "const" qualifier set, without looking through typedefs that may have |
812 | | /// added "const" at a different level. |
813 | 84.8M | bool isLocalConstQualified() const { |
814 | 84.8M | return (getLocalFastQualifiers() & Qualifiers::Const); |
815 | 84.8M | } |
816 | | |
817 | | /// Determine whether this type is const-qualified. |
818 | | bool isConstQualified() const; |
819 | | |
820 | | /// Determine whether this particular QualType instance has the |
821 | | /// "restrict" qualifier set, without looking through typedefs that may have |
822 | | /// added "restrict" at a different level. |
823 | 596k | bool isLocalRestrictQualified() const { |
824 | 596k | return (getLocalFastQualifiers() & Qualifiers::Restrict); |
825 | 596k | } |
826 | | |
827 | | /// Determine whether this type is restrict-qualified. |
828 | | bool isRestrictQualified() const; |
829 | | |
830 | | /// Determine whether this particular QualType instance has the |
831 | | /// "volatile" qualifier set, without looking through typedefs that may have |
832 | | /// added "volatile" at a different level. |
833 | 426M | bool isLocalVolatileQualified() const { |
834 | 426M | return (getLocalFastQualifiers() & Qualifiers::Volatile); |
835 | 426M | } |
836 | | |
837 | | /// Determine whether this type is volatile-qualified. |
838 | | bool isVolatileQualified() const; |
839 | | |
840 | | /// Determine whether this particular QualType instance has any |
841 | | /// qualifiers, without looking through any typedefs that might add |
842 | | /// qualifiers at a different level. |
843 | 7.41G | bool hasLocalQualifiers() const { |
844 | 7.41G | return getLocalFastQualifiers() || hasLocalNonFastQualifiers()7.27G ; |
845 | 7.41G | } |
846 | | |
847 | | /// Determine whether this type has any qualifiers. |
848 | | bool hasQualifiers() const; |
849 | | |
850 | | /// Determine whether this particular QualType instance has any |
851 | | /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType |
852 | | /// instance. |
853 | 8.08G | bool hasLocalNonFastQualifiers() const { |
854 | 8.08G | return Value.getPointer().is<const ExtQuals*>(); |
855 | 8.08G | } |
856 | | |
857 | | /// Retrieve the set of qualifiers local to this particular QualType |
858 | | /// instance, not including any qualifiers acquired through typedefs or |
859 | | /// other sugar. |
860 | | Qualifiers getLocalQualifiers() const; |
861 | | |
862 | | /// Retrieve the set of qualifiers applied to this type. |
863 | | Qualifiers getQualifiers() const; |
864 | | |
865 | | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers |
866 | | /// local to this particular QualType instance, not including any qualifiers |
867 | | /// acquired through typedefs or other sugar. |
868 | 82.1M | unsigned getLocalCVRQualifiers() const { |
869 | 82.1M | return getLocalFastQualifiers(); |
870 | 82.1M | } |
871 | | |
872 | | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers |
873 | | /// applied to this type. |
874 | | unsigned getCVRQualifiers() const; |
875 | | |
876 | 29.6M | bool isConstant(const ASTContext& Ctx) const { |
877 | 29.6M | return QualType::isConstant(*this, Ctx); |
878 | 29.6M | } |
879 | | |
880 | | /// Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). |
881 | | bool isPODType(const ASTContext &Context) const; |
882 | | |
883 | | /// Return true if this is a POD type according to the rules of the C++98 |
884 | | /// standard, regardless of the current compilation's language. |
885 | | bool isCXX98PODType(const ASTContext &Context) const; |
886 | | |
887 | | /// Return true if this is a POD type according to the more relaxed rules |
888 | | /// of the C++11 standard, regardless of the current compilation's language. |
889 | | /// (C++0x [basic.types]p9). Note that, unlike |
890 | | /// CXXRecordDecl::isCXX11StandardLayout, this takes DRs into account. |
891 | | bool isCXX11PODType(const ASTContext &Context) const; |
892 | | |
893 | | /// Return true if this is a trivial type per (C++0x [basic.types]p9) |
894 | | bool isTrivialType(const ASTContext &Context) const; |
895 | | |
896 | | /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) |
897 | | bool isTriviallyCopyableType(const ASTContext &Context) const; |
898 | | |
899 | | /// Return true if this is a trivially relocatable type. |
900 | | bool isTriviallyRelocatableType(const ASTContext &Context) const; |
901 | | |
902 | | /// Return true if this is a trivially equality comparable type. |
903 | | bool isTriviallyEqualityComparableType(const ASTContext &Context) const; |
904 | | |
905 | | /// Returns true if it is a class and it might be dynamic. |
906 | | bool mayBeDynamicClass() const; |
907 | | |
908 | | /// Returns true if it is not a class or if the class might not be dynamic. |
909 | | bool mayBeNotDynamicClass() const; |
910 | | |
911 | | // Don't promise in the API that anything besides 'const' can be |
912 | | // easily added. |
913 | | |
914 | | /// Add the `const` type qualifier to this QualType. |
915 | 376k | void addConst() { |
916 | 376k | addFastQualifiers(Qualifiers::Const); |
917 | 376k | } |
918 | 7.64M | QualType withConst() const { |
919 | 7.64M | return withFastQualifiers(Qualifiers::Const); |
920 | 7.64M | } |
921 | | |
922 | | /// Add the `volatile` type qualifier to this QualType. |
923 | 116 | void addVolatile() { |
924 | 116 | addFastQualifiers(Qualifiers::Volatile); |
925 | 116 | } |
926 | 418 | QualType withVolatile() const { |
927 | 418 | return withFastQualifiers(Qualifiers::Volatile); |
928 | 418 | } |
929 | | |
930 | | /// Add the `restrict` qualifier to this QualType. |
931 | 153 | void addRestrict() { |
932 | 153 | addFastQualifiers(Qualifiers::Restrict); |
933 | 153 | } |
934 | 1.56M | QualType withRestrict() const { |
935 | 1.56M | return withFastQualifiers(Qualifiers::Restrict); |
936 | 1.56M | } |
937 | | |
938 | 8.60k | QualType withCVRQualifiers(unsigned CVR) const { |
939 | 8.60k | return withFastQualifiers(CVR); |
940 | 8.60k | } |
941 | | |
942 | 1.60G | void addFastQualifiers(unsigned TQs) { |
943 | 1.60G | assert(!(TQs & ~Qualifiers::FastMask) |
944 | 1.60G | && "non-fast qualifier bits set in mask!"); |
945 | 1.60G | Value.setInt(Value.getInt() | TQs); |
946 | 1.60G | } |
947 | | |
948 | | void removeLocalConst(); |
949 | | void removeLocalVolatile(); |
950 | | void removeLocalRestrict(); |
951 | | |
952 | 8.09M | void removeLocalFastQualifiers() { Value.setInt(0); } |
953 | 87.8k | void removeLocalFastQualifiers(unsigned Mask) { |
954 | 87.8k | assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers"); |
955 | 87.8k | Value.setInt(Value.getInt() & ~Mask); |
956 | 87.8k | } |
957 | | |
958 | | // Creates a type with the given qualifiers in addition to any |
959 | | // qualifiers already on this type. |
960 | 1.60G | QualType withFastQualifiers(unsigned TQs) const { |
961 | 1.60G | QualType T = *this; |
962 | 1.60G | T.addFastQualifiers(TQs); |
963 | 1.60G | return T; |
964 | 1.60G | } |
965 | | |
966 | | // Creates a type with exactly the given fast qualifiers, removing |
967 | | // any existing fast qualifiers. |
968 | 0 | QualType withExactLocalFastQualifiers(unsigned TQs) const { |
969 | 0 | return withoutLocalFastQualifiers().withFastQualifiers(TQs); |
970 | 0 | } |
971 | | |
972 | | // Removes fast qualifiers, but leaves any extended qualifiers in place. |
973 | 627 | QualType withoutLocalFastQualifiers() const { |
974 | 627 | QualType T = *this; |
975 | 627 | T.removeLocalFastQualifiers(); |
976 | 627 | return T; |
977 | 627 | } |
978 | | |
979 | | QualType getCanonicalType() const; |
980 | | |
981 | | /// Return this type with all of the instance-specific qualifiers |
982 | | /// removed, but without removing any qualifiers that may have been applied |
983 | | /// through typedefs. |
984 | 111M | QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); } |
985 | | |
986 | | /// Retrieve the unqualified variant of the given type, |
987 | | /// removing as little sugar as possible. |
988 | | /// |
989 | | /// This routine looks through various kinds of sugar to find the |
990 | | /// least-desugared type that is unqualified. For example, given: |
991 | | /// |
992 | | /// \code |
993 | | /// typedef int Integer; |
994 | | /// typedef const Integer CInteger; |
995 | | /// typedef CInteger DifferenceType; |
996 | | /// \endcode |
997 | | /// |
998 | | /// Executing \c getUnqualifiedType() on the type \c DifferenceType will |
999 | | /// desugar until we hit the type \c Integer, which has no qualifiers on it. |
1000 | | /// |
1001 | | /// The resulting type might still be qualified if it's sugar for an array |
1002 | | /// type. To strip qualifiers even from within a sugared array type, use |
1003 | | /// ASTContext::getUnqualifiedArrayType. |
1004 | | /// |
1005 | | /// Note: In C, the _Atomic qualifier is special (see C2x 6.2.5p29 for |
1006 | | /// details), and it is not stripped by this function. Use |
1007 | | /// getAtomicUnqualifiedType() to strip qualifiers including _Atomic. |
1008 | | inline QualType getUnqualifiedType() const; |
1009 | | |
1010 | | /// Retrieve the unqualified variant of the given type, removing as little |
1011 | | /// sugar as possible. |
1012 | | /// |
1013 | | /// Like getUnqualifiedType(), but also returns the set of |
1014 | | /// qualifiers that were built up. |
1015 | | /// |
1016 | | /// The resulting type might still be qualified if it's sugar for an array |
1017 | | /// type. To strip qualifiers even from within a sugared array type, use |
1018 | | /// ASTContext::getUnqualifiedArrayType. |
1019 | | inline SplitQualType getSplitUnqualifiedType() const; |
1020 | | |
1021 | | /// Determine whether this type is more qualified than the other |
1022 | | /// given type, requiring exact equality for non-CVR qualifiers. |
1023 | | bool isMoreQualifiedThan(QualType Other) const; |
1024 | | |
1025 | | /// Determine whether this type is at least as qualified as the other |
1026 | | /// given type, requiring exact equality for non-CVR qualifiers. |
1027 | | bool isAtLeastAsQualifiedAs(QualType Other) const; |
1028 | | |
1029 | | QualType getNonReferenceType() const; |
1030 | | |
1031 | | /// Determine the type of a (typically non-lvalue) expression with the |
1032 | | /// specified result type. |
1033 | | /// |
1034 | | /// This routine should be used for expressions for which the return type is |
1035 | | /// explicitly specified (e.g., in a cast or call) and isn't necessarily |
1036 | | /// an lvalue. It removes a top-level reference (since there are no |
1037 | | /// expressions of reference type) and deletes top-level cvr-qualifiers |
1038 | | /// from non-class types (in C++) or all types (in C). |
1039 | | QualType getNonLValueExprType(const ASTContext &Context) const; |
1040 | | |
1041 | | /// Remove an outer pack expansion type (if any) from this type. Used as part |
1042 | | /// of converting the type of a declaration to the type of an expression that |
1043 | | /// references that expression. It's meaningless for an expression to have a |
1044 | | /// pack expansion type. |
1045 | | QualType getNonPackExpansionType() const; |
1046 | | |
1047 | | /// Return the specified type with any "sugar" removed from |
1048 | | /// the type. This takes off typedefs, typeof's etc. If the outer level of |
1049 | | /// the type is already concrete, it returns it unmodified. This is similar |
1050 | | /// to getting the canonical type, but it doesn't remove *all* typedefs. For |
1051 | | /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is |
1052 | | /// concrete. |
1053 | | /// |
1054 | | /// Qualifiers are left in place. |
1055 | 1.36M | QualType getDesugaredType(const ASTContext &Context) const { |
1056 | 1.36M | return getDesugaredType(*this, Context); |
1057 | 1.36M | } |
1058 | | |
1059 | 67.1M | SplitQualType getSplitDesugaredType() const { |
1060 | 67.1M | return getSplitDesugaredType(*this); |
1061 | 67.1M | } |
1062 | | |
1063 | | /// Return the specified type with one level of "sugar" removed from |
1064 | | /// the type. |
1065 | | /// |
1066 | | /// This routine takes off the first typedef, typeof, etc. If the outer level |
1067 | | /// of the type is already concrete, it returns it unmodified. |
1068 | 2.31k | QualType getSingleStepDesugaredType(const ASTContext &Context) const { |
1069 | 2.31k | return getSingleStepDesugaredTypeImpl(*this, Context); |
1070 | 2.31k | } |
1071 | | |
1072 | | /// Returns the specified type after dropping any |
1073 | | /// outer-level parentheses. |
1074 | 427 | QualType IgnoreParens() const { |
1075 | 427 | if (isa<ParenType>(*this)) |
1076 | 34 | return QualType::IgnoreParens(*this); |
1077 | 393 | return *this; |
1078 | 427 | } |
1079 | | |
1080 | | /// Indicate whether the specified types and qualifiers are identical. |
1081 | 3.97G | friend bool operator==(const QualType &LHS, const QualType &RHS) { |
1082 | 3.97G | return LHS.Value == RHS.Value; |
1083 | 3.97G | } |
1084 | 151M | friend bool operator!=(const QualType &LHS, const QualType &RHS) { |
1085 | 151M | return LHS.Value != RHS.Value; |
1086 | 151M | } |
1087 | 292 | friend bool operator<(const QualType &LHS, const QualType &RHS) { |
1088 | 292 | return LHS.Value < RHS.Value; |
1089 | 292 | } |
1090 | | |
1091 | | static std::string getAsString(SplitQualType split, |
1092 | 111k | const PrintingPolicy &Policy) { |
1093 | 111k | return getAsString(split.Ty, split.Quals, Policy); |
1094 | 111k | } |
1095 | | static std::string getAsString(const Type *ty, Qualifiers qs, |
1096 | | const PrintingPolicy &Policy); |
1097 | | |
1098 | | std::string getAsString() const; |
1099 | | std::string getAsString(const PrintingPolicy &Policy) const; |
1100 | | |
1101 | | void print(raw_ostream &OS, const PrintingPolicy &Policy, |
1102 | | const Twine &PlaceHolder = Twine(), |
1103 | | unsigned Indentation = 0) const; |
1104 | | |
1105 | | static void print(SplitQualType split, raw_ostream &OS, |
1106 | | const PrintingPolicy &policy, const Twine &PlaceHolder, |
1107 | 2.17M | unsigned Indentation = 0) { |
1108 | 2.17M | return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation); |
1109 | 2.17M | } |
1110 | | |
1111 | | static void print(const Type *ty, Qualifiers qs, |
1112 | | raw_ostream &OS, const PrintingPolicy &policy, |
1113 | | const Twine &PlaceHolder, |
1114 | | unsigned Indentation = 0); |
1115 | | |
1116 | | void getAsStringInternal(std::string &Str, |
1117 | | const PrintingPolicy &Policy) const; |
1118 | | |
1119 | | static void getAsStringInternal(SplitQualType split, std::string &out, |
1120 | 569k | const PrintingPolicy &policy) { |
1121 | 569k | return getAsStringInternal(split.Ty, split.Quals, out, policy); |
1122 | 569k | } |
1123 | | |
1124 | | static void getAsStringInternal(const Type *ty, Qualifiers qs, |
1125 | | std::string &out, |
1126 | | const PrintingPolicy &policy); |
1127 | | |
1128 | | class StreamedQualTypeHelper { |
1129 | | const QualType &T; |
1130 | | const PrintingPolicy &Policy; |
1131 | | const Twine &PlaceHolder; |
1132 | | unsigned Indentation; |
1133 | | |
1134 | | public: |
1135 | | StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, |
1136 | | const Twine &PlaceHolder, unsigned Indentation) |
1137 | | : T(T), Policy(Policy), PlaceHolder(PlaceHolder), |
1138 | 3.89k | Indentation(Indentation) {} |
1139 | | |
1140 | | friend raw_ostream &operator<<(raw_ostream &OS, |
1141 | 3.89k | const StreamedQualTypeHelper &SQT) { |
1142 | 3.89k | SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation); |
1143 | 3.89k | return OS; |
1144 | 3.89k | } |
1145 | | }; |
1146 | | |
1147 | | StreamedQualTypeHelper stream(const PrintingPolicy &Policy, |
1148 | | const Twine &PlaceHolder = Twine(), |
1149 | 3.89k | unsigned Indentation = 0) const { |
1150 | 3.89k | return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation); |
1151 | 3.89k | } |
1152 | | |
1153 | | void dump(const char *s) const; |
1154 | | void dump() const; |
1155 | | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; |
1156 | | |
1157 | 352M | void Profile(llvm::FoldingSetNodeID &ID) const { |
1158 | 352M | ID.AddPointer(getAsOpaquePtr()); |
1159 | 352M | } |
1160 | | |
1161 | | /// Check if this type has any address space qualifier. |
1162 | | inline bool hasAddressSpace() const; |
1163 | | |
1164 | | /// Return the address space of this type. |
1165 | | inline LangAS getAddressSpace() const; |
1166 | | |
1167 | | /// Returns true if address space qualifiers overlap with T address space |
1168 | | /// qualifiers. |
1169 | | /// OpenCL C defines conversion rules for pointers to different address spaces |
1170 | | /// and notion of overlapping address spaces. |
1171 | | /// CL1.1 or CL1.2: |
1172 | | /// address spaces overlap iff they are they same. |
1173 | | /// OpenCL C v2.0 s6.5.5 adds: |
1174 | | /// __generic overlaps with any address space except for __constant. |
1175 | 22.9k | bool isAddressSpaceOverlapping(QualType T) const { |
1176 | 22.9k | Qualifiers Q = getQualifiers(); |
1177 | 22.9k | Qualifiers TQ = T.getQualifiers(); |
1178 | | // Address spaces overlap if at least one of them is a superset of another |
1179 | 22.9k | return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q)376 ; |
1180 | 22.9k | } |
1181 | | |
1182 | | /// Returns gc attribute of this type. |
1183 | | inline Qualifiers::GC getObjCGCAttr() const; |
1184 | | |
1185 | | /// true when Type is objc's weak. |
1186 | 4.80M | bool isObjCGCWeak() const { |
1187 | 4.80M | return getObjCGCAttr() == Qualifiers::Weak; |
1188 | 4.80M | } |
1189 | | |
1190 | | /// true when Type is objc's strong. |
1191 | 2.21M | bool isObjCGCStrong() const { |
1192 | 2.21M | return getObjCGCAttr() == Qualifiers::Strong; |
1193 | 2.21M | } |
1194 | | |
1195 | | /// Returns lifetime attribute of this type. |
1196 | 56.8M | Qualifiers::ObjCLifetime getObjCLifetime() const { |
1197 | 56.8M | return getQualifiers().getObjCLifetime(); |
1198 | 56.8M | } |
1199 | | |
1200 | 4.55M | bool hasNonTrivialObjCLifetime() const { |
1201 | 4.55M | return getQualifiers().hasNonTrivialObjCLifetime(); |
1202 | 4.55M | } |
1203 | | |
1204 | 150 | bool hasStrongOrWeakObjCLifetime() const { |
1205 | 150 | return getQualifiers().hasStrongOrWeakObjCLifetime(); |
1206 | 150 | } |
1207 | | |
1208 | | // true when Type is objc's weak and weak is enabled but ARC isn't. |
1209 | | bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const; |
1210 | | |
1211 | | enum PrimitiveDefaultInitializeKind { |
1212 | | /// The type does not fall into any of the following categories. Note that |
1213 | | /// this case is zero-valued so that values of this enum can be used as a |
1214 | | /// boolean condition for non-triviality. |
1215 | | PDIK_Trivial, |
1216 | | |
1217 | | /// The type is an Objective-C retainable pointer type that is qualified |
1218 | | /// with the ARC __strong qualifier. |
1219 | | PDIK_ARCStrong, |
1220 | | |
1221 | | /// The type is an Objective-C retainable pointer type that is qualified |
1222 | | /// with the ARC __weak qualifier. |
1223 | | PDIK_ARCWeak, |
1224 | | |
1225 | | /// The type is a struct containing a field whose type is not PCK_Trivial. |
1226 | | PDIK_Struct |
1227 | | }; |
1228 | | |
1229 | | /// Functions to query basic properties of non-trivial C struct types. |
1230 | | |
1231 | | /// Check if this is a non-trivial type that would cause a C struct |
1232 | | /// transitively containing this type to be non-trivial to default initialize |
1233 | | /// and return the kind. |
1234 | | PrimitiveDefaultInitializeKind |
1235 | | isNonTrivialToPrimitiveDefaultInitialize() const; |
1236 | | |
1237 | | enum PrimitiveCopyKind { |
1238 | | /// The type does not fall into any of the following categories. Note that |
1239 | | /// this case is zero-valued so that values of this enum can be used as a |
1240 | | /// boolean condition for non-triviality. |
1241 | | PCK_Trivial, |
1242 | | |
1243 | | /// The type would be trivial except that it is volatile-qualified. Types |
1244 | | /// that fall into one of the other non-trivial cases may additionally be |
1245 | | /// volatile-qualified. |
1246 | | PCK_VolatileTrivial, |
1247 | | |
1248 | | /// The type is an Objective-C retainable pointer type that is qualified |
1249 | | /// with the ARC __strong qualifier. |
1250 | | PCK_ARCStrong, |
1251 | | |
1252 | | /// The type is an Objective-C retainable pointer type that is qualified |
1253 | | /// with the ARC __weak qualifier. |
1254 | | PCK_ARCWeak, |
1255 | | |
1256 | | /// The type is a struct containing a field whose type is neither |
1257 | | /// PCK_Trivial nor PCK_VolatileTrivial. |
1258 | | /// Note that a C++ struct type does not necessarily match this; C++ copying |
1259 | | /// semantics are too complex to express here, in part because they depend |
1260 | | /// on the exact constructor or assignment operator that is chosen by |
1261 | | /// overload resolution to do the copy. |
1262 | | PCK_Struct |
1263 | | }; |
1264 | | |
1265 | | /// Check if this is a non-trivial type that would cause a C struct |
1266 | | /// transitively containing this type to be non-trivial to copy and return the |
1267 | | /// kind. |
1268 | | PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const; |
1269 | | |
1270 | | /// Check if this is a non-trivial type that would cause a C struct |
1271 | | /// transitively containing this type to be non-trivial to destructively |
1272 | | /// move and return the kind. Destructive move in this context is a C++-style |
1273 | | /// move in which the source object is placed in a valid but unspecified state |
1274 | | /// after it is moved, as opposed to a truly destructive move in which the |
1275 | | /// source object is placed in an uninitialized state. |
1276 | | PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const; |
1277 | | |
1278 | | enum DestructionKind { |
1279 | | DK_none, |
1280 | | DK_cxx_destructor, |
1281 | | DK_objc_strong_lifetime, |
1282 | | DK_objc_weak_lifetime, |
1283 | | DK_nontrivial_c_struct |
1284 | | }; |
1285 | | |
1286 | | /// Returns a nonzero value if objects of this type require |
1287 | | /// non-trivial work to clean up after. Non-zero because it's |
1288 | | /// conceivable that qualifiers (objc_gc(weak)?) could make |
1289 | | /// something require destruction. |
1290 | 22.8M | DestructionKind isDestructedType() const { |
1291 | 22.8M | return isDestructedTypeImpl(*this); |
1292 | 22.8M | } |
1293 | | |
1294 | | /// Check if this is or contains a C union that is non-trivial to |
1295 | | /// default-initialize, which is a union that has a member that is non-trivial |
1296 | | /// to default-initialize. If this returns true, |
1297 | | /// isNonTrivialToPrimitiveDefaultInitialize returns PDIK_Struct. |
1298 | | bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const; |
1299 | | |
1300 | | /// Check if this is or contains a C union that is non-trivial to destruct, |
1301 | | /// which is a union that has a member that is non-trivial to destruct. If |
1302 | | /// this returns true, isDestructedType returns DK_nontrivial_c_struct. |
1303 | | bool hasNonTrivialToPrimitiveDestructCUnion() const; |
1304 | | |
1305 | | /// Check if this is or contains a C union that is non-trivial to copy, which |
1306 | | /// is a union that has a member that is non-trivial to copy. If this returns |
1307 | | /// true, isNonTrivialToPrimitiveCopy returns PCK_Struct. |
1308 | | bool hasNonTrivialToPrimitiveCopyCUnion() const; |
1309 | | |
1310 | | /// Determine whether expressions of the given type are forbidden |
1311 | | /// from being lvalues in C. |
1312 | | /// |
1313 | | /// The expression types that are forbidden to be lvalues are: |
1314 | | /// - 'void', but not qualified void |
1315 | | /// - function types |
1316 | | /// |
1317 | | /// The exact rule here is C99 6.3.2.1: |
1318 | | /// An lvalue is an expression with an object type or an incomplete |
1319 | | /// type other than void. |
1320 | | bool isCForbiddenLValueType() const; |
1321 | | |
1322 | | /// Substitute type arguments for the Objective-C type parameters used in the |
1323 | | /// subject type. |
1324 | | /// |
1325 | | /// \param ctx ASTContext in which the type exists. |
1326 | | /// |
1327 | | /// \param typeArgs The type arguments that will be substituted for the |
1328 | | /// Objective-C type parameters in the subject type, which are generally |
1329 | | /// computed via \c Type::getObjCSubstitutions. If empty, the type |
1330 | | /// parameters will be replaced with their bounds or id/Class, as appropriate |
1331 | | /// for the context. |
1332 | | /// |
1333 | | /// \param context The context in which the subject type was written. |
1334 | | /// |
1335 | | /// \returns the resulting type. |
1336 | | QualType substObjCTypeArgs(ASTContext &ctx, |
1337 | | ArrayRef<QualType> typeArgs, |
1338 | | ObjCSubstitutionContext context) const; |
1339 | | |
1340 | | /// Substitute type arguments from an object type for the Objective-C type |
1341 | | /// parameters used in the subject type. |
1342 | | /// |
1343 | | /// This operation combines the computation of type arguments for |
1344 | | /// substitution (\c Type::getObjCSubstitutions) with the actual process of |
1345 | | /// substitution (\c QualType::substObjCTypeArgs) for the convenience of |
1346 | | /// callers that need to perform a single substitution in isolation. |
1347 | | /// |
1348 | | /// \param objectType The type of the object whose member type we're |
1349 | | /// substituting into. For example, this might be the receiver of a message |
1350 | | /// or the base of a property access. |
1351 | | /// |
1352 | | /// \param dc The declaration context from which the subject type was |
1353 | | /// retrieved, which indicates (for example) which type parameters should |
1354 | | /// be substituted. |
1355 | | /// |
1356 | | /// \param context The context in which the subject type was written. |
1357 | | /// |
1358 | | /// \returns the subject type after replacing all of the Objective-C type |
1359 | | /// parameters with their corresponding arguments. |
1360 | | QualType substObjCMemberType(QualType objectType, |
1361 | | const DeclContext *dc, |
1362 | | ObjCSubstitutionContext context) const; |
1363 | | |
1364 | | /// Strip Objective-C "__kindof" types from the given type. |
1365 | | QualType stripObjCKindOfType(const ASTContext &ctx) const; |
1366 | | |
1367 | | /// Remove all qualifiers including _Atomic. |
1368 | | QualType getAtomicUnqualifiedType() const; |
1369 | | |
1370 | | private: |
1371 | | // These methods are implemented in a separate translation unit; |
1372 | | // "static"-ize them to avoid creating temporary QualTypes in the |
1373 | | // caller. |
1374 | | static bool isConstant(QualType T, const ASTContext& Ctx); |
1375 | | static QualType getDesugaredType(QualType T, const ASTContext &Context); |
1376 | | static SplitQualType getSplitDesugaredType(QualType T); |
1377 | | static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); |
1378 | | static QualType getSingleStepDesugaredTypeImpl(QualType type, |
1379 | | const ASTContext &C); |
1380 | | static QualType IgnoreParens(QualType T); |
1381 | | static DestructionKind isDestructedTypeImpl(QualType type); |
1382 | | |
1383 | | /// Check if \param RD is or contains a non-trivial C union. |
1384 | | static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD); |
1385 | | static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD); |
1386 | | static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD); |
1387 | | }; |
1388 | | |
1389 | | raw_ostream &operator<<(raw_ostream &OS, QualType QT); |
1390 | | |
1391 | | } // namespace clang |
1392 | | |
1393 | | namespace llvm { |
1394 | | |
1395 | | /// Implement simplify_type for QualType, so that we can dyn_cast from QualType |
1396 | | /// to a specific Type class. |
1397 | | template<> struct simplify_type< ::clang::QualType> { |
1398 | | using SimpleType = const ::clang::Type *; |
1399 | | |
1400 | 16.3G | static SimpleType getSimplifiedValue(::clang::QualType Val) { |
1401 | 16.3G | return Val.getTypePtr(); |
1402 | 16.3G | } |
1403 | | }; |
1404 | | |
1405 | | // Teach SmallPtrSet that QualType is "basically a pointer". |
1406 | | template<> |
1407 | | struct PointerLikeTypeTraits<clang::QualType> { |
1408 | 144M | static inline void *getAsVoidPointer(clang::QualType P) { |
1409 | 144M | return P.getAsOpaquePtr(); |
1410 | 144M | } |
1411 | | |
1412 | 311M | static inline clang::QualType getFromVoidPointer(void *P) { |
1413 | 311M | return clang::QualType::getFromOpaquePtr(P); |
1414 | 311M | } |
1415 | | |
1416 | | // Various qualifiers go in low bits. |
1417 | | static constexpr int NumLowBitsAvailable = 0; |
1418 | | }; |
1419 | | |
1420 | | } // namespace llvm |
1421 | | |
1422 | | namespace clang { |
1423 | | |
1424 | | /// Base class that is common to both the \c ExtQuals and \c Type |
1425 | | /// classes, which allows \c QualType to access the common fields between the |
1426 | | /// two. |
1427 | | class ExtQualsTypeCommonBase { |
1428 | | friend class ExtQuals; |
1429 | | friend class QualType; |
1430 | | friend class Type; |
1431 | | |
1432 | | /// The "base" type of an extended qualifiers type (\c ExtQuals) or |
1433 | | /// a self-referential pointer (for \c Type). |
1434 | | /// |
1435 | | /// This pointer allows an efficient mapping from a QualType to its |
1436 | | /// underlying type pointer. |
1437 | | const Type *const BaseType; |
1438 | | |
1439 | | /// The canonical type of this type. A QualType. |
1440 | | QualType CanonicalType; |
1441 | | |
1442 | | ExtQualsTypeCommonBase(const Type *baseType, QualType canon) |
1443 | 94.0M | : BaseType(baseType), CanonicalType(canon) {} |
1444 | | }; |
1445 | | |
1446 | | /// We can encode up to four bits in the low bits of a |
1447 | | /// type pointer, but there are many more type qualifiers that we want |
1448 | | /// to be able to apply to an arbitrary type. Therefore we have this |
1449 | | /// struct, intended to be heap-allocated and used by QualType to |
1450 | | /// store qualifiers. |
1451 | | /// |
1452 | | /// The current design tags the 'const', 'restrict', and 'volatile' qualifiers |
1453 | | /// in three low bits on the QualType pointer; a fourth bit records whether |
1454 | | /// the pointer is an ExtQuals node. The extended qualifiers (address spaces, |
1455 | | /// Objective-C GC attributes) are much more rare. |
1456 | | class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode { |
1457 | | // NOTE: changing the fast qualifiers should be straightforward as |
1458 | | // long as you don't make 'const' non-fast. |
1459 | | // 1. Qualifiers: |
1460 | | // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ). |
1461 | | // Fast qualifiers must occupy the low-order bits. |
1462 | | // b) Update Qualifiers::FastWidth and FastMask. |
1463 | | // 2. QualType: |
1464 | | // a) Update is{Volatile,Restrict}Qualified(), defined inline. |
1465 | | // b) Update remove{Volatile,Restrict}, defined near the end of |
1466 | | // this header. |
1467 | | // 3. ASTContext: |
1468 | | // a) Update get{Volatile,Restrict}Type. |
1469 | | |
1470 | | /// The immutable set of qualifiers applied by this node. Always contains |
1471 | | /// extended qualifiers. |
1472 | | Qualifiers Quals; |
1473 | | |
1474 | 29.1k | ExtQuals *this_() { return this; } |
1475 | | |
1476 | | public: |
1477 | | ExtQuals(const Type *baseType, QualType canon, Qualifiers quals) |
1478 | | : ExtQualsTypeCommonBase(baseType, |
1479 | | canon.isNull() ? QualType(this_(), 0) : canon), |
1480 | 49.2k | Quals(quals) { |
1481 | 49.2k | assert(Quals.hasNonFastQualifiers() |
1482 | 49.2k | && "ExtQuals created with no fast qualifiers"); |
1483 | 49.2k | assert(!Quals.hasFastQualifiers() |
1484 | 49.2k | && "ExtQuals created with fast qualifiers"); |
1485 | 49.2k | } |
1486 | | |
1487 | 5.52M | Qualifiers getQualifiers() const { return Quals; } |
1488 | | |
1489 | 0 | bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); } |
1490 | 0 | Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); } |
1491 | | |
1492 | 0 | bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); } |
1493 | 0 | Qualifiers::ObjCLifetime getObjCLifetime() const { |
1494 | 0 | return Quals.getObjCLifetime(); |
1495 | 0 | } |
1496 | | |
1497 | 0 | bool hasAddressSpace() const { return Quals.hasAddressSpace(); } |
1498 | 0 | LangAS getAddressSpace() const { return Quals.getAddressSpace(); } |
1499 | | |
1500 | 1.74M | const Type *getBaseType() const { return BaseType; } |
1501 | | |
1502 | | public: |
1503 | 998k | void Profile(llvm::FoldingSetNodeID &ID) const { |
1504 | 998k | Profile(ID, getBaseType(), Quals); |
1505 | 998k | } |
1506 | | |
1507 | | static void Profile(llvm::FoldingSetNodeID &ID, |
1508 | | const Type *BaseType, |
1509 | 1.63M | Qualifiers Quals) { |
1510 | 1.63M | assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!"); |
1511 | 1.63M | ID.AddPointer(BaseType); |
1512 | 1.63M | Quals.Profile(ID); |
1513 | 1.63M | } |
1514 | | }; |
1515 | | |
1516 | | /// The kind of C++11 ref-qualifier associated with a function type. |
1517 | | /// This determines whether a member function's "this" object can be an |
1518 | | /// lvalue, rvalue, or neither. |
1519 | | enum RefQualifierKind { |
1520 | | /// No ref-qualifier was provided. |
1521 | | RQ_None = 0, |
1522 | | |
1523 | | /// An lvalue ref-qualifier was provided (\c &). |
1524 | | RQ_LValue, |
1525 | | |
1526 | | /// An rvalue ref-qualifier was provided (\c &&). |
1527 | | RQ_RValue |
1528 | | }; |
1529 | | |
1530 | | /// Which keyword(s) were used to create an AutoType. |
1531 | | enum class AutoTypeKeyword { |
1532 | | /// auto |
1533 | | Auto, |
1534 | | |
1535 | | /// decltype(auto) |
1536 | | DecltypeAuto, |
1537 | | |
1538 | | /// __auto_type (GNU extension) |
1539 | | GNUAutoType |
1540 | | }; |
1541 | | |
1542 | | /// The base class of the type hierarchy. |
1543 | | /// |
1544 | | /// A central concept with types is that each type always has a canonical |
1545 | | /// type. A canonical type is the type with any typedef names stripped out |
1546 | | /// of it or the types it references. For example, consider: |
1547 | | /// |
1548 | | /// typedef int foo; |
1549 | | /// typedef foo* bar; |
1550 | | /// 'int *' 'foo *' 'bar' |
1551 | | /// |
1552 | | /// There will be a Type object created for 'int'. Since int is canonical, its |
1553 | | /// CanonicalType pointer points to itself. There is also a Type for 'foo' (a |
1554 | | /// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next |
1555 | | /// there is a PointerType that represents 'int*', which, like 'int', is |
1556 | | /// canonical. Finally, there is a PointerType type for 'foo*' whose canonical |
1557 | | /// type is 'int*', and there is a TypedefType for 'bar', whose canonical type |
1558 | | /// is also 'int*'. |
1559 | | /// |
1560 | | /// Non-canonical types are useful for emitting diagnostics, without losing |
1561 | | /// information about typedefs being used. Canonical types are useful for type |
1562 | | /// comparisons (they allow by-pointer equality tests) and useful for reasoning |
1563 | | /// about whether something has a particular form (e.g. is a function type), |
1564 | | /// because they implicitly, recursively, strip all typedefs out of a type. |
1565 | | /// |
1566 | | /// Types, once created, are immutable. |
1567 | | /// |
1568 | | class alignas(8) Type : public ExtQualsTypeCommonBase { |
1569 | | public: |
1570 | | enum TypeClass { |
1571 | | #define TYPE(Class, Base) Class, |
1572 | | #define LAST_TYPE(Class) TypeLast = Class |
1573 | | #define ABSTRACT_TYPE(Class, Base) |
1574 | | #include "clang/AST/TypeNodes.inc" |
1575 | | }; |
1576 | | |
1577 | | private: |
1578 | | /// Bitfields required by the Type class. |
1579 | | class TypeBitfields { |
1580 | | friend class Type; |
1581 | | template <class T> friend class TypePropertyCache; |
1582 | | |
1583 | | /// TypeClass bitfield - Enum that specifies what subclass this belongs to. |
1584 | | unsigned TC : 8; |
1585 | | |
1586 | | /// Store information on the type dependency. |
1587 | | unsigned Dependence : llvm::BitWidth<TypeDependence>; |
1588 | | |
1589 | | /// True if the cache (i.e. the bitfields here starting with |
1590 | | /// 'Cache') is valid. |
1591 | | mutable unsigned CacheValid : 1; |
1592 | | |
1593 | | /// Linkage of this type. |
1594 | | mutable unsigned CachedLinkage : 3; |
1595 | | |
1596 | | /// Whether this type involves and local or unnamed types. |
1597 | | mutable unsigned CachedLocalOrUnnamed : 1; |
1598 | | |
1599 | | /// Whether this type comes from an AST file. |
1600 | | mutable unsigned FromAST : 1; |
1601 | | |
1602 | 25.6M | bool isCacheValid() const { |
1603 | 25.6M | return CacheValid; |
1604 | 25.6M | } |
1605 | | |
1606 | 10.0M | Linkage getLinkage() const { |
1607 | 10.0M | assert(isCacheValid() && "getting linkage from invalid cache"); |
1608 | 10.0M | return static_cast<Linkage>(CachedLinkage); |
1609 | 10.0M | } |
1610 | | |
1611 | 3.82M | bool hasLocalOrUnnamedType() const { |
1612 | 3.82M | assert(isCacheValid() && "getting linkage from invalid cache"); |
1613 | 3.82M | return CachedLocalOrUnnamed; |
1614 | 3.82M | } |
1615 | | }; |
1616 | | enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 }; |
1617 | | |
1618 | | protected: |
1619 | | // These classes allow subclasses to somewhat cleanly pack bitfields |
1620 | | // into Type. |
1621 | | |
1622 | | class ArrayTypeBitfields { |
1623 | | friend class ArrayType; |
1624 | | |
1625 | | unsigned : NumTypeBits; |
1626 | | |
1627 | | /// CVR qualifiers from declarations like |
1628 | | /// 'int X[static restrict 4]'. For function parameters only. |
1629 | | unsigned IndexTypeQuals : 3; |
1630 | | |
1631 | | /// Storage class qualifiers from declarations like |
1632 | | /// 'int X[static restrict 4]'. For function parameters only. |
1633 | | /// Actually an ArrayType::ArraySizeModifier. |
1634 | | unsigned SizeModifier : 3; |
1635 | | }; |
1636 | | |
1637 | | class ConstantArrayTypeBitfields { |
1638 | | friend class ConstantArrayType; |
1639 | | |
1640 | | unsigned : NumTypeBits + 3 + 3; |
1641 | | |
1642 | | /// Whether we have a stored size expression. |
1643 | | unsigned HasStoredSizeExpr : 1; |
1644 | | }; |
1645 | | |
1646 | | class BuiltinTypeBitfields { |
1647 | | friend class BuiltinType; |
1648 | | |
1649 | | unsigned : NumTypeBits; |
1650 | | |
1651 | | /// The kind (BuiltinType::Kind) of builtin type this is. |
1652 | | unsigned Kind : 8; |
1653 | | }; |
1654 | | |
1655 | | /// FunctionTypeBitfields store various bits belonging to FunctionProtoType. |
1656 | | /// Only common bits are stored here. Additional uncommon bits are stored |
1657 | | /// in a trailing object after FunctionProtoType. |
1658 | | class FunctionTypeBitfields { |
1659 | | friend class FunctionProtoType; |
1660 | | friend class FunctionType; |
1661 | | |
1662 | | unsigned : NumTypeBits; |
1663 | | |
1664 | | /// Extra information which affects how the function is called, like |
1665 | | /// regparm and the calling convention. |
1666 | | unsigned ExtInfo : 13; |
1667 | | |
1668 | | /// The ref-qualifier associated with a \c FunctionProtoType. |
1669 | | /// |
1670 | | /// This is a value of type \c RefQualifierKind. |
1671 | | unsigned RefQualifier : 2; |
1672 | | |
1673 | | /// Used only by FunctionProtoType, put here to pack with the |
1674 | | /// other bitfields. |
1675 | | /// The qualifiers are part of FunctionProtoType because... |
1676 | | /// |
1677 | | /// C++ 8.3.5p4: The return type, the parameter type list and the |
1678 | | /// cv-qualifier-seq, [...], are part of the function type. |
1679 | | unsigned FastTypeQuals : Qualifiers::FastWidth; |
1680 | | /// Whether this function has extended Qualifiers. |
1681 | | unsigned HasExtQuals : 1; |
1682 | | |
1683 | | /// The number of parameters this function has, not counting '...'. |
1684 | | /// According to [implimits] 8 bits should be enough here but this is |
1685 | | /// somewhat easy to exceed with metaprogramming and so we would like to |
1686 | | /// keep NumParams as wide as reasonably possible. |
1687 | | unsigned NumParams : 16; |
1688 | | |
1689 | | /// The type of exception specification this function has. |
1690 | | unsigned ExceptionSpecType : 4; |
1691 | | |
1692 | | /// Whether this function has extended parameter information. |
1693 | | unsigned HasExtParameterInfos : 1; |
1694 | | |
1695 | | /// Whether this function has extra bitfields for the prototype. |
1696 | | unsigned HasExtraBitfields : 1; |
1697 | | |
1698 | | /// Whether the function is variadic. |
1699 | | unsigned Variadic : 1; |
1700 | | |
1701 | | /// Whether this function has a trailing return type. |
1702 | | unsigned HasTrailingReturn : 1; |
1703 | | }; |
1704 | | |
1705 | | class ObjCObjectTypeBitfields { |
1706 | | friend class ObjCObjectType; |
1707 | | |
1708 | | unsigned : NumTypeBits; |
1709 | | |
1710 | | /// The number of type arguments stored directly on this object type. |
1711 | | unsigned NumTypeArgs : 7; |
1712 | | |
1713 | | /// The number of protocols stored directly on this object type. |
1714 | | unsigned NumProtocols : 6; |
1715 | | |
1716 | | /// Whether this is a "kindof" type. |
1717 | | unsigned IsKindOf : 1; |
1718 | | }; |
1719 | | |
1720 | | class ReferenceTypeBitfields { |
1721 | | friend class ReferenceType; |
1722 | | |
1723 | | unsigned : NumTypeBits; |
1724 | | |
1725 | | /// True if the type was originally spelled with an lvalue sigil. |
1726 | | /// This is never true of rvalue references but can also be false |
1727 | | /// on lvalue references because of C++0x [dcl.typedef]p9, |
1728 | | /// as follows: |
1729 | | /// |
1730 | | /// typedef int &ref; // lvalue, spelled lvalue |
1731 | | /// typedef int &&rvref; // rvalue |
1732 | | /// ref &a; // lvalue, inner ref, spelled lvalue |
1733 | | /// ref &&a; // lvalue, inner ref |
1734 | | /// rvref &a; // lvalue, inner ref, spelled lvalue |
1735 | | /// rvref &&a; // rvalue, inner ref |
1736 | | unsigned SpelledAsLValue : 1; |
1737 | | |
1738 | | /// True if the inner type is a reference type. This only happens |
1739 | | /// in non-canonical forms. |
1740 | | unsigned InnerRef : 1; |
1741 | | }; |
1742 | | |
1743 | | class TypeWithKeywordBitfields { |
1744 | | friend class TypeWithKeyword; |
1745 | | |
1746 | | unsigned : NumTypeBits; |
1747 | | |
1748 | | /// An ElaboratedTypeKeyword. 8 bits for efficient access. |
1749 | | unsigned Keyword : 8; |
1750 | | }; |
1751 | | |
1752 | | enum { NumTypeWithKeywordBits = 8 }; |
1753 | | |
1754 | | class ElaboratedTypeBitfields { |
1755 | | friend class ElaboratedType; |
1756 | | |
1757 | | unsigned : NumTypeBits; |
1758 | | unsigned : NumTypeWithKeywordBits; |
1759 | | |
1760 | | /// Whether the ElaboratedType has a trailing OwnedTagDecl. |
1761 | | unsigned HasOwnedTagDecl : 1; |
1762 | | }; |
1763 | | |
1764 | | class VectorTypeBitfields { |
1765 | | friend class VectorType; |
1766 | | friend class DependentVectorType; |
1767 | | |
1768 | | unsigned : NumTypeBits; |
1769 | | |
1770 | | /// The kind of vector, either a generic vector type or some |
1771 | | /// target-specific vector type such as for AltiVec or Neon. |
1772 | | unsigned VecKind : 4; |
1773 | | /// The number of elements in the vector. |
1774 | | uint32_t NumElements; |
1775 | | }; |
1776 | | |
1777 | | class AttributedTypeBitfields { |
1778 | | friend class AttributedType; |
1779 | | |
1780 | | unsigned : NumTypeBits; |
1781 | | |
1782 | | /// An AttributedType::Kind |
1783 | | unsigned AttrKind : 32 - NumTypeBits; |
1784 | | }; |
1785 | | |
1786 | | class AutoTypeBitfields { |
1787 | | friend class AutoType; |
1788 | | |
1789 | | unsigned : NumTypeBits; |
1790 | | |
1791 | | /// Was this placeholder type spelled as 'auto', 'decltype(auto)', |
1792 | | /// or '__auto_type'? AutoTypeKeyword value. |
1793 | | unsigned Keyword : 2; |
1794 | | |
1795 | | /// The number of template arguments in the type-constraints, which is |
1796 | | /// expected to be able to hold at least 1024 according to [implimits]. |
1797 | | /// However as this limit is somewhat easy to hit with template |
1798 | | /// metaprogramming we'd prefer to keep it as large as possible. |
1799 | | /// At the moment it has been left as a non-bitfield since this type |
1800 | | /// safely fits in 64 bits as an unsigned, so there is no reason to |
1801 | | /// introduce the performance impact of a bitfield. |
1802 | | unsigned NumArgs; |
1803 | | }; |
1804 | | |
1805 | | class TypeOfBitfields { |
1806 | | friend class TypeOfType; |
1807 | | friend class TypeOfExprType; |
1808 | | |
1809 | | unsigned : NumTypeBits; |
1810 | | unsigned IsUnqual : 1; // If true: typeof_unqual, else: typeof |
1811 | | }; |
1812 | | |
1813 | | class UsingBitfields { |
1814 | | friend class UsingType; |
1815 | | |
1816 | | unsigned : NumTypeBits; |
1817 | | |
1818 | | /// True if the underlying type is different from the declared one. |
1819 | | unsigned hasTypeDifferentFromDecl : 1; |
1820 | | }; |
1821 | | |
1822 | | class TypedefBitfields { |
1823 | | friend class TypedefType; |
1824 | | |
1825 | | unsigned : NumTypeBits; |
1826 | | |
1827 | | /// True if the underlying type is different from the declared one. |
1828 | | unsigned hasTypeDifferentFromDecl : 1; |
1829 | | }; |
1830 | | |
1831 | | class SubstTemplateTypeParmTypeBitfields { |
1832 | | friend class SubstTemplateTypeParmType; |
1833 | | |
1834 | | unsigned : NumTypeBits; |
1835 | | |
1836 | | unsigned HasNonCanonicalUnderlyingType : 1; |
1837 | | |
1838 | | // The index of the template parameter this substitution represents. |
1839 | | unsigned Index : 15; |
1840 | | |
1841 | | /// Represents the index within a pack if this represents a substitution |
1842 | | /// from a pack expansion. This index starts at the end of the pack and |
1843 | | /// increments towards the beginning. |
1844 | | /// Positive non-zero number represents the index + 1. |
1845 | | /// Zero means this is not substituted from an expansion. |
1846 | | unsigned PackIndex : 16; |
1847 | | }; |
1848 | | |
1849 | | class SubstTemplateTypeParmPackTypeBitfields { |
1850 | | friend class SubstTemplateTypeParmPackType; |
1851 | | |
1852 | | unsigned : NumTypeBits; |
1853 | | |
1854 | | // The index of the template parameter this substitution represents. |
1855 | | unsigned Index : 16; |
1856 | | |
1857 | | /// The number of template arguments in \c Arguments, which is |
1858 | | /// expected to be able to hold at least 1024 according to [implimits]. |
1859 | | /// However as this limit is somewhat easy to hit with template |
1860 | | /// metaprogramming we'd prefer to keep it as large as possible. |
1861 | | unsigned NumArgs : 16; |
1862 | | }; |
1863 | | |
1864 | | class TemplateSpecializationTypeBitfields { |
1865 | | friend class TemplateSpecializationType; |
1866 | | |
1867 | | unsigned : NumTypeBits; |
1868 | | |
1869 | | /// Whether this template specialization type is a substituted type alias. |
1870 | | unsigned TypeAlias : 1; |
1871 | | |
1872 | | /// The number of template arguments named in this class template |
1873 | | /// specialization, which is expected to be able to hold at least 1024 |
1874 | | /// according to [implimits]. However, as this limit is somewhat easy to |
1875 | | /// hit with template metaprogramming we'd prefer to keep it as large |
1876 | | /// as possible. At the moment it has been left as a non-bitfield since |
1877 | | /// this type safely fits in 64 bits as an unsigned, so there is no reason |
1878 | | /// to introduce the performance impact of a bitfield. |
1879 | | unsigned NumArgs; |
1880 | | }; |
1881 | | |
1882 | | class DependentTemplateSpecializationTypeBitfields { |
1883 | | friend class DependentTemplateSpecializationType; |
1884 | | |
1885 | | unsigned : NumTypeBits; |
1886 | | unsigned : NumTypeWithKeywordBits; |
1887 | | |
1888 | | /// The number of template arguments named in this class template |
1889 | | /// specialization, which is expected to be able to hold at least 1024 |
1890 | | /// according to [implimits]. However, as this limit is somewhat easy to |
1891 | | /// hit with template metaprogramming we'd prefer to keep it as large |
1892 | | /// as possible. At the moment it has been left as a non-bitfield since |
1893 | | /// this type safely fits in 64 bits as an unsigned, so there is no reason |
1894 | | /// to introduce the performance impact of a bitfield. |
1895 | | unsigned NumArgs; |
1896 | | }; |
1897 | | |
1898 | | class PackExpansionTypeBitfields { |
1899 | | friend class PackExpansionType; |
1900 | | |
1901 | | unsigned : NumTypeBits; |
1902 | | |
1903 | | /// The number of expansions that this pack expansion will |
1904 | | /// generate when substituted (+1), which is expected to be able to |
1905 | | /// hold at least 1024 according to [implimits]. However, as this limit |
1906 | | /// is somewhat easy to hit with template metaprogramming we'd prefer to |
1907 | | /// keep it as large as possible. At the moment it has been left as a |
1908 | | /// non-bitfield since this type safely fits in 64 bits as an unsigned, so |
1909 | | /// there is no reason to introduce the performance impact of a bitfield. |
1910 | | /// |
1911 | | /// This field will only have a non-zero value when some of the parameter |
1912 | | /// packs that occur within the pattern have been substituted but others |
1913 | | /// have not. |
1914 | | unsigned NumExpansions; |
1915 | | }; |
1916 | | |
1917 | | union { |
1918 | | TypeBitfields TypeBits; |
1919 | | ArrayTypeBitfields ArrayTypeBits; |
1920 | | ConstantArrayTypeBitfields ConstantArrayTypeBits; |
1921 | | AttributedTypeBitfields AttributedTypeBits; |
1922 | | AutoTypeBitfields AutoTypeBits; |
1923 | | TypeOfBitfields TypeOfBits; |
1924 | | TypedefBitfields TypedefBits; |
1925 | | UsingBitfields UsingBits; |
1926 | | BuiltinTypeBitfields BuiltinTypeBits; |
1927 | | FunctionTypeBitfields FunctionTypeBits; |
1928 | | ObjCObjectTypeBitfields ObjCObjectTypeBits; |
1929 | | ReferenceTypeBitfields ReferenceTypeBits; |
1930 | | TypeWithKeywordBitfields TypeWithKeywordBits; |
1931 | | ElaboratedTypeBitfields ElaboratedTypeBits; |
1932 | | VectorTypeBitfields VectorTypeBits; |
1933 | | SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits; |
1934 | | SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; |
1935 | | TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; |
1936 | | DependentTemplateSpecializationTypeBitfields |
1937 | | DependentTemplateSpecializationTypeBits; |
1938 | | PackExpansionTypeBitfields PackExpansionTypeBits; |
1939 | | }; |
1940 | | |
1941 | | private: |
1942 | | template <class T> friend class TypePropertyCache; |
1943 | | |
1944 | | /// Set whether this type comes from an AST file. |
1945 | 4.86M | void setFromAST(bool V = true) const { |
1946 | 4.86M | TypeBits.FromAST = V; |
1947 | 4.86M | } |
1948 | | |
1949 | | protected: |
1950 | | friend class ASTContext; |
1951 | | |
1952 | | Type(TypeClass tc, QualType canon, TypeDependence Dependence) |
1953 | | : ExtQualsTypeCommonBase(this, |
1954 | 94.0M | canon.isNull() ? QualType(this_(), 0) : canon) { |
1955 | 94.0M | static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase), |
1956 | 94.0M | "changing bitfields changed sizeof(Type)!"); |
1957 | 94.0M | static_assert(alignof(decltype(*this)) % sizeof(void *) == 0, |
1958 | 94.0M | "Insufficient alignment!"); |
1959 | 94.0M | TypeBits.TC = tc; |
1960 | 94.0M | TypeBits.Dependence = static_cast<unsigned>(Dependence); |
1961 | 94.0M | TypeBits.CacheValid = false; |
1962 | 94.0M | TypeBits.CachedLocalOrUnnamed = false; |
1963 | 94.0M | TypeBits.CachedLinkage = NoLinkage; |
1964 | 94.0M | TypeBits.FromAST = false; |
1965 | 94.0M | } |
1966 | | |
1967 | | // silence VC++ warning C4355: 'this' : used in base member initializer list |
1968 | 24.4M | Type *this_() { return this; } |
1969 | | |
1970 | 80.7M | void setDependence(TypeDependence D) { |
1971 | 80.7M | TypeBits.Dependence = static_cast<unsigned>(D); |
1972 | 80.7M | } |
1973 | | |
1974 | 80.7M | void addDependence(TypeDependence D) { setDependence(getDependence() | D); } |
1975 | | |
1976 | | public: |
1977 | | friend class ASTReader; |
1978 | | friend class ASTWriter; |
1979 | | template <class T> friend class serialization::AbstractTypeReader; |
1980 | | template <class T> friend class serialization::AbstractTypeWriter; |
1981 | | |
1982 | | Type(const Type &) = delete; |
1983 | | Type(Type &&) = delete; |
1984 | | Type &operator=(const Type &) = delete; |
1985 | | Type &operator=(Type &&) = delete; |
1986 | | |
1987 | 35.6G | TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } |
1988 | | |
1989 | | /// Whether this type comes from an AST file. |
1990 | 7.87k | bool isFromAST() const { return TypeBits.FromAST; } |
1991 | | |
1992 | | /// Whether this type is or contains an unexpanded parameter |
1993 | | /// pack, used to support C++0x variadic templates. |
1994 | | /// |
1995 | | /// A type that contains a parameter pack shall be expanded by the |
1996 | | /// ellipsis operator at some point. For example, the typedef in the |
1997 | | /// following example contains an unexpanded parameter pack 'T': |
1998 | | /// |
1999 | | /// \code |
2000 | | /// template<typename ...T> |
2001 | | /// struct X { |
2002 | | /// typedef T* pointer_types; // ill-formed; T is a parameter pack. |
2003 | | /// }; |
2004 | | /// \endcode |
2005 | | /// |
2006 | | /// Note that this routine does not specify which |
2007 | 42.2M | bool containsUnexpandedParameterPack() const { |
2008 | 42.2M | return getDependence() & TypeDependence::UnexpandedPack; |
2009 | 42.2M | } |
2010 | | |
2011 | | /// Determines if this type would be canonical if it had no further |
2012 | | /// qualification. |
2013 | 1.54G | bool isCanonicalUnqualified() const { |
2014 | 1.54G | return CanonicalType == QualType(this, 0); |
2015 | 1.54G | } |
2016 | | |
2017 | | /// Pull a single level of sugar off of this locally-unqualified type. |
2018 | | /// Users should generally prefer SplitQualType::getSingleStepDesugaredType() |
2019 | | /// or QualType::getSingleStepDesugaredType(const ASTContext&). |
2020 | | QualType getLocallyUnqualifiedSingleStepDesugaredType() const; |
2021 | | |
2022 | | /// As an extension, we classify types as one of "sized" or "sizeless"; |
2023 | | /// every type is one or the other. Standard types are all sized; |
2024 | | /// sizeless types are purely an extension. |
2025 | | /// |
2026 | | /// Sizeless types contain data with no specified size, alignment, |
2027 | | /// or layout. |
2028 | | bool isSizelessType() const; |
2029 | | bool isSizelessBuiltinType() const; |
2030 | | |
2031 | | /// Returns true for SVE scalable vector types. |
2032 | | bool isSVESizelessBuiltinType() const; |
2033 | | |
2034 | | /// Returns true for RVV scalable vector types. |
2035 | | bool isRVVSizelessBuiltinType() const; |
2036 | | |
2037 | | /// Check if this is a WebAssembly Reference Type. |
2038 | | bool isWebAssemblyReferenceType() const; |
2039 | | bool isWebAssemblyExternrefType() const; |
2040 | | |
2041 | | /// Determines if this is a sizeless type supported by the |
2042 | | /// 'arm_sve_vector_bits' type attribute, which can be applied to a single |
2043 | | /// SVE vector or predicate, excluding tuple types such as svint32x4_t. |
2044 | | bool isVLSTBuiltinType() const; |
2045 | | |
2046 | | /// Returns the representative type for the element of an SVE builtin type. |
2047 | | /// This is used to represent fixed-length SVE vectors created with the |
2048 | | /// 'arm_sve_vector_bits' type attribute as VectorType. |
2049 | | QualType getSveEltType(const ASTContext &Ctx) const; |
2050 | | |
2051 | | /// Determines if this is a sizeless type supported by the |
2052 | | /// 'riscv_rvv_vector_bits' type attribute, which can be applied to a single |
2053 | | /// RVV vector or mask. |
2054 | | bool isRVVVLSBuiltinType() const; |
2055 | | |
2056 | | /// Returns the representative type for the element of an RVV builtin type. |
2057 | | /// This is used to represent fixed-length RVV vectors created with the |
2058 | | /// 'riscv_rvv_vector_bits' type attribute as VectorType. |
2059 | | QualType getRVVEltType(const ASTContext &Ctx) const; |
2060 | | |
2061 | | /// Types are partitioned into 3 broad categories (C99 6.2.5p1): |
2062 | | /// object types, function types, and incomplete types. |
2063 | | |
2064 | | /// Return true if this is an incomplete type. |
2065 | | /// A type that can describe objects, but which lacks information needed to |
2066 | | /// determine its size (e.g. void, or a fwd declared struct). Clients of this |
2067 | | /// routine will need to determine if the size is actually required. |
2068 | | /// |
2069 | | /// Def If non-null, and the type refers to some kind of declaration |
2070 | | /// that can be completed (such as a C struct, C++ class, or Objective-C |
2071 | | /// class), will be set to the declaration. |
2072 | | bool isIncompleteType(NamedDecl **Def = nullptr) const; |
2073 | | |
2074 | | /// Return true if this is an incomplete or object |
2075 | | /// type, in other words, not a function type. |
2076 | 546k | bool isIncompleteOrObjectType() const { |
2077 | 546k | return !isFunctionType(); |
2078 | 546k | } |
2079 | | |
2080 | | /// Determine whether this type is an object type. |
2081 | 1.52M | bool isObjectType() const { |
2082 | | // C++ [basic.types]p8: |
2083 | | // An object type is a (possibly cv-qualified) type that is not a |
2084 | | // function type, not a reference type, and not a void type. |
2085 | 1.52M | return !isReferenceType() && !isFunctionType()1.44M && !isVoidType()1.18M ; |
2086 | 1.52M | } |
2087 | | |
2088 | | /// Return true if this is a literal type |
2089 | | /// (C++11 [basic.types]p10) |
2090 | | bool isLiteralType(const ASTContext &Ctx) const; |
2091 | | |
2092 | | /// Determine if this type is a structural type, per C++20 [temp.param]p7. |
2093 | | bool isStructuralType() const; |
2094 | | |
2095 | | /// Test if this type is a standard-layout type. |
2096 | | /// (C++0x [basic.type]p9) |
2097 | | bool isStandardLayoutType() const; |
2098 | | |
2099 | | /// Helper methods to distinguish type categories. All type predicates |
2100 | | /// operate on the canonical type, ignoring typedefs and qualifiers. |
2101 | | |
2102 | | /// Returns true if the type is a builtin type. |
2103 | | bool isBuiltinType() const; |
2104 | | |
2105 | | /// Test for a particular builtin type. |
2106 | | bool isSpecificBuiltinType(unsigned K) const; |
2107 | | |
2108 | | /// Test for a type which does not represent an actual type-system type but |
2109 | | /// is instead used as a placeholder for various convenient purposes within |
2110 | | /// Clang. All such types are BuiltinTypes. |
2111 | | bool isPlaceholderType() const; |
2112 | | const BuiltinType *getAsPlaceholderType() const; |
2113 | | |
2114 | | /// Test for a specific placeholder type. |
2115 | | bool isSpecificPlaceholderType(unsigned K) const; |
2116 | | |
2117 | | /// Test for a placeholder type other than Overload; see |
2118 | | /// BuiltinType::isNonOverloadPlaceholderType. |
2119 | | bool isNonOverloadPlaceholderType() const; |
2120 | | |
2121 | | /// isIntegerType() does *not* include complex integers (a GCC extension). |
2122 | | /// isComplexIntegerType() can be used to test for complex integers. |
2123 | | bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) |
2124 | | bool isEnumeralType() const; |
2125 | | |
2126 | | /// Determine whether this type is a scoped enumeration type. |
2127 | | bool isScopedEnumeralType() const; |
2128 | | bool isBooleanType() const; |
2129 | | bool isCharType() const; |
2130 | | bool isWideCharType() const; |
2131 | | bool isChar8Type() const; |
2132 | | bool isChar16Type() const; |
2133 | | bool isChar32Type() const; |
2134 | | bool isAnyCharacterType() const; |
2135 | | bool isIntegralType(const ASTContext &Ctx) const; |
2136 | | |
2137 | | /// Determine whether this type is an integral or enumeration type. |
2138 | | bool isIntegralOrEnumerationType() const; |
2139 | | |
2140 | | /// Determine whether this type is an integral or unscoped enumeration type. |
2141 | | bool isIntegralOrUnscopedEnumerationType() const; |
2142 | | bool isUnscopedEnumerationType() const; |
2143 | | |
2144 | | /// Floating point categories. |
2145 | | bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) |
2146 | | /// isComplexType() does *not* include complex integers (a GCC extension). |
2147 | | /// isComplexIntegerType() can be used to test for complex integers. |
2148 | | bool isComplexType() const; // C99 6.2.5p11 (complex) |
2149 | | bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. |
2150 | | bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) |
2151 | | bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) |
2152 | | bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 |
2153 | | bool isBFloat16Type() const; |
2154 | | bool isFloat128Type() const; |
2155 | | bool isIbm128Type() const; |
2156 | | bool isRealType() const; // C99 6.2.5p17 (real floating + integer) |
2157 | | bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) |
2158 | | bool isVoidType() const; // C99 6.2.5p19 |
2159 | | bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) |
2160 | | bool isAggregateType() const; |
2161 | | bool isFundamentalType() const; |
2162 | | bool isCompoundType() const; |
2163 | | |
2164 | | // Type Predicates: Check to see if this type is structurally the specified |
2165 | | // type, ignoring typedefs and qualifiers. |
2166 | | bool isFunctionType() const; |
2167 | 624 | bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); } |
2168 | 232M | bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } |
2169 | | bool isPointerType() const; |
2170 | | bool isAnyPointerType() const; // Any C pointer or ObjC object pointer |
2171 | | bool isBlockPointerType() const; |
2172 | | bool isVoidPointerType() const; |
2173 | | bool isReferenceType() const; |
2174 | | bool isLValueReferenceType() const; |
2175 | | bool isRValueReferenceType() const; |
2176 | | bool isObjectPointerType() const; |
2177 | | bool isFunctionPointerType() const; |
2178 | | bool isFunctionReferenceType() const; |
2179 | | bool isMemberPointerType() const; |
2180 | | bool isMemberFunctionPointerType() const; |
2181 | | bool isMemberDataPointerType() const; |
2182 | | bool isArrayType() const; |
2183 | | bool isConstantArrayType() const; |
2184 | | bool isIncompleteArrayType() const; |
2185 | | bool isVariableArrayType() const; |
2186 | | bool isDependentSizedArrayType() const; |
2187 | | bool isRecordType() const; |
2188 | | bool isClassType() const; |
2189 | | bool isStructureType() const; |
2190 | | bool isObjCBoxableRecordType() const; |
2191 | | bool isInterfaceType() const; |
2192 | | bool isStructureOrClassType() const; |
2193 | | bool isUnionType() const; |
2194 | | bool isComplexIntegerType() const; // GCC _Complex integer type. |
2195 | | bool isVectorType() const; // GCC vector type. |
2196 | | bool isExtVectorType() const; // Extended vector type. |
2197 | | bool isExtVectorBoolType() const; // Extended vector type with bool element. |
2198 | | bool isMatrixType() const; // Matrix type. |
2199 | | bool isConstantMatrixType() const; // Constant matrix type. |
2200 | | bool isDependentAddressSpaceType() const; // value-dependent address space qualifier |
2201 | | bool isObjCObjectPointerType() const; // pointer to ObjC object |
2202 | | bool isObjCRetainableType() const; // ObjC object or block pointer |
2203 | | bool isObjCLifetimeType() const; // (array of)* retainable type |
2204 | | bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type |
2205 | | bool isObjCNSObjectType() const; // __attribute__((NSObject)) |
2206 | | bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class)) |
2207 | | // FIXME: change this to 'raw' interface type, so we can used 'interface' type |
2208 | | // for the common case. |
2209 | | bool isObjCObjectType() const; // NSString or typeof(*(id)0) |
2210 | | bool isObjCQualifiedInterfaceType() const; // NSString<foo> |
2211 | | bool isObjCQualifiedIdType() const; // id<foo> |
2212 | | bool isObjCQualifiedClassType() const; // Class<foo> |
2213 | | bool isObjCObjectOrInterfaceType() const; |
2214 | | bool isObjCIdType() const; // id |
2215 | | bool isDecltypeType() const; |
2216 | | /// Was this type written with the special inert-in-ARC __unsafe_unretained |
2217 | | /// qualifier? |
2218 | | /// |
2219 | | /// This approximates the answer to the following question: if this |
2220 | | /// translation unit were compiled in ARC, would this type be qualified |
2221 | | /// with __unsafe_unretained? |
2222 | 169 | bool isObjCInertUnsafeUnretainedType() const { |
2223 | 169 | return hasAttr(attr::ObjCInertUnsafeUnretained); |
2224 | 169 | } |
2225 | | |
2226 | | /// Whether the type is Objective-C 'id' or a __kindof type of an |
2227 | | /// object type, e.g., __kindof NSView * or __kindof id |
2228 | | /// <NSCopying>. |
2229 | | /// |
2230 | | /// \param bound Will be set to the bound on non-id subtype types, |
2231 | | /// which will be (possibly specialized) Objective-C class type, or |
2232 | | /// null for 'id. |
2233 | | bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, |
2234 | | const ObjCObjectType *&bound) const; |
2235 | | |
2236 | | bool isObjCClassType() const; // Class |
2237 | | |
2238 | | /// Whether the type is Objective-C 'Class' or a __kindof type of an |
2239 | | /// Class type, e.g., __kindof Class <NSCopying>. |
2240 | | /// |
2241 | | /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound |
2242 | | /// here because Objective-C's type system cannot express "a class |
2243 | | /// object for a subclass of NSFoo". |
2244 | | bool isObjCClassOrClassKindOfType() const; |
2245 | | |
2246 | | bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const; |
2247 | | bool isObjCSelType() const; // Class |
2248 | | bool isObjCBuiltinType() const; // 'id' or 'Class' |
2249 | | bool isObjCARCBridgableType() const; |
2250 | | bool isCARCBridgableType() const; |
2251 | | bool isTemplateTypeParmType() const; // C++ template type parameter |
2252 | | bool isNullPtrType() const; // C++11 std::nullptr_t or |
2253 | | // C2x nullptr_t |
2254 | | bool isNothrowT() const; // C++ std::nothrow_t |
2255 | | bool isAlignValT() const; // C++17 std::align_val_t |
2256 | | bool isStdByteType() const; // C++17 std::byte |
2257 | | bool isAtomicType() const; // C11 _Atomic() |
2258 | | bool isUndeducedAutoType() const; // C++11 auto or |
2259 | | // C++14 decltype(auto) |
2260 | | bool isTypedefNameType() const; // typedef or alias template |
2261 | | |
2262 | | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ |
2263 | | bool is##Id##Type() const; |
2264 | | #include "clang/Basic/OpenCLImageTypes.def" |
2265 | | |
2266 | | bool isImageType() const; // Any OpenCL image type |
2267 | | |
2268 | | bool isSamplerT() const; // OpenCL sampler_t |
2269 | | bool isEventT() const; // OpenCL event_t |
2270 | | bool isClkEventT() const; // OpenCL clk_event_t |
2271 | | bool isQueueT() const; // OpenCL queue_t |
2272 | | bool isReserveIDT() const; // OpenCL reserve_id_t |
2273 | | |
2274 | | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
2275 | | bool is##Id##Type() const; |
2276 | | #include "clang/Basic/OpenCLExtensionTypes.def" |
2277 | | // Type defined in cl_intel_device_side_avc_motion_estimation OpenCL extension |
2278 | | bool isOCLIntelSubgroupAVCType() const; |
2279 | | bool isOCLExtOpaqueType() const; // Any OpenCL extension type |
2280 | | |
2281 | | bool isPipeType() const; // OpenCL pipe type |
2282 | | bool isBitIntType() const; // Bit-precise integer type |
2283 | | bool isOpenCLSpecificType() const; // Any OpenCL specific type |
2284 | | |
2285 | | /// Determines if this type, which must satisfy |
2286 | | /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather |
2287 | | /// than implicitly __strong. |
2288 | | bool isObjCARCImplicitlyUnretainedType() const; |
2289 | | |
2290 | | /// Check if the type is the CUDA device builtin surface type. |
2291 | | bool isCUDADeviceBuiltinSurfaceType() const; |
2292 | | /// Check if the type is the CUDA device builtin texture type. |
2293 | | bool isCUDADeviceBuiltinTextureType() const; |
2294 | | |
2295 | | bool isRVVType() const; |
2296 | | |
2297 | | bool isRVVType(unsigned Bitwidth, bool IsFloat) const; |
2298 | | |
2299 | | /// Return the implicit lifetime for this type, which must not be dependent. |
2300 | | Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; |
2301 | | |
2302 | | enum ScalarTypeKind { |
2303 | | STK_CPointer, |
2304 | | STK_BlockPointer, |
2305 | | STK_ObjCObjectPointer, |
2306 | | STK_MemberPointer, |
2307 | | STK_Bool, |
2308 | | STK_Integral, |
2309 | | STK_Floating, |
2310 | | STK_IntegralComplex, |
2311 | | STK_FloatingComplex, |
2312 | | STK_FixedPoint |
2313 | | }; |
2314 | | |
2315 | | /// Given that this is a scalar type, classify it. |
2316 | | ScalarTypeKind getScalarTypeKind() const; |
2317 | | |
2318 | 1.19G | TypeDependence getDependence() const { |
2319 | 1.19G | return static_cast<TypeDependence>(TypeBits.Dependence); |
2320 | 1.19G | } |
2321 | | |
2322 | | /// Whether this type is an error type. |
2323 | 145M | bool containsErrors() const { |
2324 | 145M | return getDependence() & TypeDependence::Error; |
2325 | 145M | } |
2326 | | |
2327 | | /// Whether this type is a dependent type, meaning that its definition |
2328 | | /// somehow depends on a template parameter (C++ [temp.dep.type]). |
2329 | 417M | bool isDependentType() const { |
2330 | 417M | return getDependence() & TypeDependence::Dependent; |
2331 | 417M | } |
2332 | | |
2333 | | /// Determine whether this type is an instantiation-dependent type, |
2334 | | /// meaning that the type involves a template parameter (even if the |
2335 | | /// definition does not actually depend on the type substituted for that |
2336 | | /// template parameter). |
2337 | 75.2M | bool isInstantiationDependentType() const { |
2338 | 75.2M | return getDependence() & TypeDependence::Instantiation; |
2339 | 75.2M | } |
2340 | | |
2341 | | /// Determine whether this type is an undeduced type, meaning that |
2342 | | /// it somehow involves a C++11 'auto' type or similar which has not yet been |
2343 | | /// deduced. |
2344 | | bool isUndeducedType() const; |
2345 | | |
2346 | | /// Whether this type is a variably-modified type (C99 6.7.5). |
2347 | 158M | bool isVariablyModifiedType() const { |
2348 | 158M | return getDependence() & TypeDependence::VariablyModified; |
2349 | 158M | } |
2350 | | |
2351 | | /// Whether this type involves a variable-length array type |
2352 | | /// with a definite size. |
2353 | | bool hasSizedVLAType() const; |
2354 | | |
2355 | | /// Whether this type is or contains a local or unnamed type. |
2356 | | bool hasUnnamedOrLocalType() const; |
2357 | | |
2358 | | bool isOverloadableType() const; |
2359 | | |
2360 | | /// Determine wither this type is a C++ elaborated-type-specifier. |
2361 | | bool isElaboratedTypeSpecifier() const; |
2362 | | |
2363 | | bool canDecayToPointerType() const; |
2364 | | |
2365 | | /// Whether this type is represented natively as a pointer. This includes |
2366 | | /// pointers, references, block pointers, and Objective-C interface, |
2367 | | /// qualified id, and qualified interface types, as well as nullptr_t. |
2368 | | bool hasPointerRepresentation() const; |
2369 | | |
2370 | | /// Whether this type can represent an objective pointer type for the |
2371 | | /// purpose of GC'ability |
2372 | | bool hasObjCPointerRepresentation() const; |
2373 | | |
2374 | | /// Determine whether this type has an integer representation |
2375 | | /// of some sort, e.g., it is an integer type or a vector. |
2376 | | bool hasIntegerRepresentation() const; |
2377 | | |
2378 | | /// Determine whether this type has an signed integer representation |
2379 | | /// of some sort, e.g., it is an signed integer type or a vector. |
2380 | | bool hasSignedIntegerRepresentation() const; |
2381 | | |
2382 | | /// Determine whether this type has an unsigned integer representation |
2383 | | /// of some sort, e.g., it is an unsigned integer type or a vector. |
2384 | | bool hasUnsignedIntegerRepresentation() const; |
2385 | | |
2386 | | /// Determine whether this type has a floating-point representation |
2387 | | /// of some sort, e.g., it is a floating-point type or a vector thereof. |
2388 | | bool hasFloatingRepresentation() const; |
2389 | | |
2390 | | // Type Checking Functions: Check to see if this type is structurally the |
2391 | | // specified type, ignoring typedefs and qualifiers, and return a pointer to |
2392 | | // the best type we can. |
2393 | | const RecordType *getAsStructureType() const; |
2394 | | /// NOTE: getAs*ArrayType are methods on ASTContext. |
2395 | | const RecordType *getAsUnionType() const; |
2396 | | const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. |
2397 | | const ObjCObjectType *getAsObjCInterfaceType() const; |
2398 | | |
2399 | | // The following is a convenience method that returns an ObjCObjectPointerType |
2400 | | // for object declared using an interface. |
2401 | | const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; |
2402 | | const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; |
2403 | | const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; |
2404 | | const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; |
2405 | | |
2406 | | /// Retrieves the CXXRecordDecl that this type refers to, either |
2407 | | /// because the type is a RecordType or because it is the injected-class-name |
2408 | | /// type of a class template or class template partial specialization. |
2409 | | CXXRecordDecl *getAsCXXRecordDecl() const; |
2410 | | |
2411 | | /// Retrieves the RecordDecl this type refers to. |
2412 | | RecordDecl *getAsRecordDecl() const; |
2413 | | |
2414 | | /// Retrieves the TagDecl that this type refers to, either |
2415 | | /// because the type is a TagType or because it is the injected-class-name |
2416 | | /// type of a class template or class template partial specialization. |
2417 | | TagDecl *getAsTagDecl() const; |
2418 | | |
2419 | | /// If this is a pointer or reference to a RecordType, return the |
2420 | | /// CXXRecordDecl that the type refers to. |
2421 | | /// |
2422 | | /// If this is not a pointer or reference, or the type being pointed to does |
2423 | | /// not refer to a CXXRecordDecl, returns NULL. |
2424 | | const CXXRecordDecl *getPointeeCXXRecordDecl() const; |
2425 | | |
2426 | | /// Get the DeducedType whose type will be deduced for a variable with |
2427 | | /// an initializer of this type. This looks through declarators like pointer |
2428 | | /// types, but not through decltype or typedefs. |
2429 | | DeducedType *getContainedDeducedType() const; |
2430 | | |
2431 | | /// Get the AutoType whose type will be deduced for a variable with |
2432 | | /// an initializer of this type. This looks through declarators like pointer |
2433 | | /// types, but not through decltype or typedefs. |
2434 | 5.14M | AutoType *getContainedAutoType() const { |
2435 | 5.14M | return dyn_cast_or_null<AutoType>(getContainedDeducedType()); |
2436 | 5.14M | } |
2437 | | |
2438 | | /// Determine whether this type was written with a leading 'auto' |
2439 | | /// corresponding to a trailing return type (possibly for a nested |
2440 | | /// function type within a pointer to function type or similar). |
2441 | | bool hasAutoForTrailingReturnType() const; |
2442 | | |
2443 | | /// Member-template getAs<specific type>'. Look through sugar for |
2444 | | /// an instance of \<specific type>. This scheme will eventually |
2445 | | /// replace the specific getAsXXXX methods above. |
2446 | | /// |
2447 | | /// There are some specializations of this member template listed |
2448 | | /// immediately following this class. |
2449 | | template <typename T> const T *getAs() const; |
2450 | | |
2451 | | /// Member-template getAsAdjusted<specific type>. Look through specific kinds |
2452 | | /// of sugar (parens, attributes, etc) for an instance of \<specific type>. |
2453 | | /// This is used when you need to walk over sugar nodes that represent some |
2454 | | /// kind of type adjustment from a type that was written as a \<specific type> |
2455 | | /// to another type that is still canonically a \<specific type>. |
2456 | | template <typename T> const T *getAsAdjusted() const; |
2457 | | |
2458 | | /// A variant of getAs<> for array types which silently discards |
2459 | | /// qualifiers from the outermost type. |
2460 | | const ArrayType *getAsArrayTypeUnsafe() const; |
2461 | | |
2462 | | /// Member-template castAs<specific type>. Look through sugar for |
2463 | | /// the underlying instance of \<specific type>. |
2464 | | /// |
2465 | | /// This method has the same relationship to getAs<T> as cast<T> has |
2466 | | /// to dyn_cast<T>; which is to say, the underlying type *must* |
2467 | | /// have the intended type, and this method will never return null. |
2468 | | template <typename T> const T *castAs() const; |
2469 | | |
2470 | | /// A variant of castAs<> for array type which silently discards |
2471 | | /// qualifiers from the outermost type. |
2472 | | const ArrayType *castAsArrayTypeUnsafe() const; |
2473 | | |
2474 | | /// Determine whether this type had the specified attribute applied to it |
2475 | | /// (looking through top-level type sugar). |
2476 | | bool hasAttr(attr::Kind AK) const; |
2477 | | |
2478 | | /// Get the base element type of this type, potentially discarding type |
2479 | | /// qualifiers. This should never be used when type qualifiers |
2480 | | /// are meaningful. |
2481 | | const Type *getBaseElementTypeUnsafe() const; |
2482 | | |
2483 | | /// If this is an array type, return the element type of the array, |
2484 | | /// potentially with type qualifiers missing. |
2485 | | /// This should never be used when type qualifiers are meaningful. |
2486 | | const Type *getArrayElementTypeNoTypeQual() const; |
2487 | | |
2488 | | /// If this is a pointer type, return the pointee type. |
2489 | | /// If this is an array type, return the array element type. |
2490 | | /// This should never be used when type qualifiers are meaningful. |
2491 | | const Type *getPointeeOrArrayElementType() const; |
2492 | | |
2493 | | /// If this is a pointer, ObjC object pointer, or block |
2494 | | /// pointer, this returns the respective pointee. |
2495 | | QualType getPointeeType() const; |
2496 | | |
2497 | | /// Return the specified type with any "sugar" removed from the type, |
2498 | | /// removing any typedefs, typeofs, etc., as well as any qualifiers. |
2499 | | const Type *getUnqualifiedDesugaredType() const; |
2500 | | |
2501 | | /// Return true if this is an integer type that is |
2502 | | /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], |
2503 | | /// or an enum decl which has a signed representation. |
2504 | | bool isSignedIntegerType() const; |
2505 | | |
2506 | | /// Return true if this is an integer type that is |
2507 | | /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], |
2508 | | /// or an enum decl which has an unsigned representation. |
2509 | | bool isUnsignedIntegerType() const; |
2510 | | |
2511 | | /// Determines whether this is an integer type that is signed or an |
2512 | | /// enumeration types whose underlying type is a signed integer type. |
2513 | | bool isSignedIntegerOrEnumerationType() const; |
2514 | | |
2515 | | /// Determines whether this is an integer type that is unsigned or an |
2516 | | /// enumeration types whose underlying type is a unsigned integer type. |
2517 | | bool isUnsignedIntegerOrEnumerationType() const; |
2518 | | |
2519 | | /// Return true if this is a fixed point type according to |
2520 | | /// ISO/IEC JTC1 SC22 WG14 N1169. |
2521 | | bool isFixedPointType() const; |
2522 | | |
2523 | | /// Return true if this is a fixed point or integer type. |
2524 | | bool isFixedPointOrIntegerType() const; |
2525 | | |
2526 | | /// Return true if this is a saturated fixed point type according to |
2527 | | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. |
2528 | | bool isSaturatedFixedPointType() const; |
2529 | | |
2530 | | /// Return true if this is a saturated fixed point type according to |
2531 | | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. |
2532 | | bool isUnsaturatedFixedPointType() const; |
2533 | | |
2534 | | /// Return true if this is a fixed point type that is signed according |
2535 | | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. |
2536 | | bool isSignedFixedPointType() const; |
2537 | | |
2538 | | /// Return true if this is a fixed point type that is unsigned according |
2539 | | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. |
2540 | | bool isUnsignedFixedPointType() const; |
2541 | | |
2542 | | /// Return true if this is not a variable sized type, |
2543 | | /// according to the rules of C99 6.7.5p3. It is not legal to call this on |
2544 | | /// incomplete types. |
2545 | | bool isConstantSizeType() const; |
2546 | | |
2547 | | /// Returns true if this type can be represented by some |
2548 | | /// set of type specifiers. |
2549 | | bool isSpecifierType() const; |
2550 | | |
2551 | | /// Determine the linkage of this type. |
2552 | | Linkage getLinkage() const; |
2553 | | |
2554 | | /// Determine the visibility of this type. |
2555 | 2.16k | Visibility getVisibility() const { |
2556 | 2.16k | return getLinkageAndVisibility().getVisibility(); |
2557 | 2.16k | } |
2558 | | |
2559 | | /// Return true if the visibility was explicitly set is the code. |
2560 | 0 | bool isVisibilityExplicit() const { |
2561 | 0 | return getLinkageAndVisibility().isVisibilityExplicit(); |
2562 | 0 | } |
2563 | | |
2564 | | /// Determine the linkage and visibility of this type. |
2565 | | LinkageInfo getLinkageAndVisibility() const; |
2566 | | |
2567 | | /// True if the computed linkage is valid. Used for consistency |
2568 | | /// checking. Should always return true. |
2569 | | bool isLinkageValid() const; |
2570 | | |
2571 | | /// Determine the nullability of the given type. |
2572 | | /// |
2573 | | /// Note that nullability is only captured as sugar within the type |
2574 | | /// system, not as part of the canonical type, so nullability will |
2575 | | /// be lost by canonicalization and desugaring. |
2576 | | std::optional<NullabilityKind> getNullability() const; |
2577 | | |
2578 | | /// Determine whether the given type can have a nullability |
2579 | | /// specifier applied to it, i.e., if it is any kind of pointer type. |
2580 | | /// |
2581 | | /// \param ResultIfUnknown The value to return if we don't yet know whether |
2582 | | /// this type can have nullability because it is dependent. |
2583 | | bool canHaveNullability(bool ResultIfUnknown = true) const; |
2584 | | |
2585 | | /// Retrieve the set of substitutions required when accessing a member |
2586 | | /// of the Objective-C receiver type that is declared in the given context. |
2587 | | /// |
2588 | | /// \c *this is the type of the object we're operating on, e.g., the |
2589 | | /// receiver for a message send or the base of a property access, and is |
2590 | | /// expected to be of some object or object pointer type. |
2591 | | /// |
2592 | | /// \param dc The declaration context for which we are building up a |
2593 | | /// substitution mapping, which should be an Objective-C class, extension, |
2594 | | /// category, or method within. |
2595 | | /// |
2596 | | /// \returns an array of type arguments that can be substituted for |
2597 | | /// the type parameters of the given declaration context in any type described |
2598 | | /// within that context, or an empty optional to indicate that no |
2599 | | /// substitution is required. |
2600 | | std::optional<ArrayRef<QualType>> |
2601 | | getObjCSubstitutions(const DeclContext *dc) const; |
2602 | | |
2603 | | /// Determines if this is an ObjC interface type that may accept type |
2604 | | /// parameters. |
2605 | | bool acceptsObjCTypeParams() const; |
2606 | | |
2607 | | const char *getTypeClassName() const; |
2608 | | |
2609 | 1.01G | QualType getCanonicalTypeInternal() const { |
2610 | 1.01G | return CanonicalType; |
2611 | 1.01G | } |
2612 | | |
2613 | | CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h |
2614 | | void dump() const; |
2615 | | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; |
2616 | | }; |
2617 | | |
2618 | | /// This will check for a TypedefType by removing any existing sugar |
2619 | | /// until it reaches a TypedefType or a non-sugared type. |
2620 | | template <> const TypedefType *Type::getAs() const; |
2621 | | template <> const UsingType *Type::getAs() const; |
2622 | | |
2623 | | /// This will check for a TemplateSpecializationType by removing any |
2624 | | /// existing sugar until it reaches a TemplateSpecializationType or a |
2625 | | /// non-sugared type. |
2626 | | template <> const TemplateSpecializationType *Type::getAs() const; |
2627 | | |
2628 | | /// This will check for an AttributedType by removing any existing sugar |
2629 | | /// until it reaches an AttributedType or a non-sugared type. |
2630 | | template <> const AttributedType *Type::getAs() const; |
2631 | | |
2632 | | // We can do canonical leaf types faster, because we don't have to |
2633 | | // worry about preserving child type decoration. |
2634 | | #define TYPE(Class, Base) |
2635 | | #define LEAF_TYPE(Class) \ |
2636 | 3.54G | template <> inline const Class##Type *Type::getAs() const { \ |
2637 | 3.54G | return dyn_cast<Class##Type>(CanonicalType); \ |
2638 | 3.54G | } \ clang::BuiltinType const* clang::Type::getAs<clang::BuiltinType>() const Line | Count | Source | 2636 | 2.88G | template <> inline const Class##Type *Type::getAs() const { \ | 2637 | 2.88G | return dyn_cast<Class##Type>(CanonicalType); \ | 2638 | 2.88G | } \ |
clang::EnumType const* clang::Type::getAs<clang::EnumType>() const Line | Count | Source | 2636 | 107M | template <> inline const Class##Type *Type::getAs() const { \ | 2637 | 107M | return dyn_cast<Class##Type>(CanonicalType); \ | 2638 | 107M | } \ |
clang::InjectedClassNameType const* clang::Type::getAs<clang::InjectedClassNameType>() const Line | Count | Source | 2636 | 326M | template <> inline const Class##Type *Type::getAs() const { \ | 2637 | 326M | return dyn_cast<Class##Type>(CanonicalType); \ | 2638 | 326M | } \ |
clang::ObjCInterfaceType const* clang::Type::getAs<clang::ObjCInterfaceType>() const Line | Count | Source | 2636 | 117M | template <> inline const Class##Type *Type::getAs() const { \ | 2637 | 117M | return dyn_cast<Class##Type>(CanonicalType); \ | 2638 | 117M | } \ |
clang::RecordType const* clang::Type::getAs<clang::RecordType>() const Line | Count | Source | 2636 | 101M | template <> inline const Class##Type *Type::getAs() const { \ | 2637 | 101M | return dyn_cast<Class##Type>(CanonicalType); \ | 2638 | 101M | } \ |
clang::TemplateTypeParmType const* clang::Type::getAs<clang::TemplateTypeParmType>() const Line | Count | Source | 2636 | 6.75M | template <> inline const Class##Type *Type::getAs() const { \ | 2637 | 6.75M | return dyn_cast<Class##Type>(CanonicalType); \ | 2638 | 6.75M | } \ |
|
2639 | 324M | template <> inline const Class##Type *Type::castAs() const { \ |
2640 | 324M | return cast<Class##Type>(CanonicalType); \ |
2641 | 324M | } clang::BuiltinType const* clang::Type::castAs<clang::BuiltinType>() const Line | Count | Source | 2639 | 2.52M | template <> inline const Class##Type *Type::castAs() const { \ | 2640 | 2.52M | return cast<Class##Type>(CanonicalType); \ | 2641 | 2.52M | } |
clang::EnumType const* clang::Type::castAs<clang::EnumType>() const Line | Count | Source | 2639 | 629k | template <> inline const Class##Type *Type::castAs() const { \ | 2640 | 629k | return cast<Class##Type>(CanonicalType); \ | 2641 | 629k | } |
clang::ObjCInterfaceType const* clang::Type::castAs<clang::ObjCInterfaceType>() const Line | Count | Source | 2639 | 21.3k | template <> inline const Class##Type *Type::castAs() const { \ | 2640 | 21.3k | return cast<Class##Type>(CanonicalType); \ | 2641 | 21.3k | } |
clang::RecordType const* clang::Type::castAs<clang::RecordType>() const Line | Count | Source | 2639 | 11.5M | template <> inline const Class##Type *Type::castAs() const { \ | 2640 | 11.5M | return cast<Class##Type>(CanonicalType); \ | 2641 | 11.5M | } |
clang::TemplateTypeParmType const* clang::Type::castAs<clang::TemplateTypeParmType>() const Line | Count | Source | 2639 | 309M | template <> inline const Class##Type *Type::castAs() const { \ | 2640 | 309M | return cast<Class##Type>(CanonicalType); \ | 2641 | 309M | } |
|
2642 | | #include "clang/AST/TypeNodes.inc" |
2643 | | |
2644 | | /// This class is used for builtin types like 'int'. Builtin |
2645 | | /// types are always canonical and have a literal name field. |
2646 | | class BuiltinType : public Type { |
2647 | | public: |
2648 | | enum Kind { |
2649 | | // OpenCL image types |
2650 | | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id, |
2651 | | #include "clang/Basic/OpenCLImageTypes.def" |
2652 | | // OpenCL extension types |
2653 | | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id, |
2654 | | #include "clang/Basic/OpenCLExtensionTypes.def" |
2655 | | // SVE Types |
2656 | | #define SVE_TYPE(Name, Id, SingletonId) Id, |
2657 | | #include "clang/Basic/AArch64SVEACLETypes.def" |
2658 | | // PPC MMA Types |
2659 | | #define PPC_VECTOR_TYPE(Name, Id, Size) Id, |
2660 | | #include "clang/Basic/PPCTypes.def" |
2661 | | // RVV Types |
2662 | | #define RVV_TYPE(Name, Id, SingletonId) Id, |
2663 | | #include "clang/Basic/RISCVVTypes.def" |
2664 | | // WebAssembly reference types |
2665 | | #define WASM_TYPE(Name, Id, SingletonId) Id, |
2666 | | #include "clang/Basic/WebAssemblyReferenceTypes.def" |
2667 | | // All other builtin types |
2668 | | #define BUILTIN_TYPE(Id, SingletonId) Id, |
2669 | | #define LAST_BUILTIN_TYPE(Id) LastKind = Id |
2670 | | #include "clang/AST/BuiltinTypes.def" |
2671 | | }; |
2672 | | |
2673 | | private: |
2674 | | friend class ASTContext; // ASTContext creates these. |
2675 | | |
2676 | | BuiltinType(Kind K) |
2677 | | : Type(Builtin, QualType(), |
2678 | | K == Dependent ? TypeDependence::DependentInstantiation |
2679 | 6.01M | : TypeDependence::None) { |
2680 | 6.01M | BuiltinTypeBits.Kind = K; |
2681 | 6.01M | } |
2682 | | |
2683 | | public: |
2684 | 2.66G | Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } |
2685 | | StringRef getName(const PrintingPolicy &Policy) const; |
2686 | | |
2687 | 3.20k | const char *getNameAsCString(const PrintingPolicy &Policy) const { |
2688 | | // The StringRef is null-terminated. |
2689 | 3.20k | StringRef str = getName(Policy); |
2690 | 3.20k | assert(!str.empty() && str.data()[str.size()] == '\0'); |
2691 | 3.20k | return str.data(); |
2692 | 3.20k | } |
2693 | | |
2694 | 91.4M | bool isSugared() const { return false; } |
2695 | 0 | QualType desugar() const { return QualType(this, 0); } |
2696 | | |
2697 | 4.92M | bool isInteger() const { |
2698 | 4.92M | return getKind() >= Bool && getKind() <= Int1284.92M ; |
2699 | 4.92M | } |
2700 | | |
2701 | 254k | bool isSignedInteger() const { |
2702 | 254k | return getKind() >= Char_S && getKind() <= Int128175k ; |
2703 | 254k | } |
2704 | | |
2705 | 3.57M | bool isUnsignedInteger() const { |
2706 | 3.57M | return getKind() >= Bool && getKind() <= UInt128; |
2707 | 3.57M | } |
2708 | | |
2709 | 11.8M | bool isFloatingPoint() const { |
2710 | 11.8M | return getKind() >= Half && getKind() <= Ibm1287.01M ; |
2711 | 11.8M | } |
2712 | | |
2713 | 2.62k | bool isSVEBool() const { return getKind() == Kind::SveBool; } |
2714 | | |
2715 | 0 | bool isSVECount() const { return getKind() == Kind::SveCount; } |
2716 | | |
2717 | | /// Determines whether the given kind corresponds to a placeholder type. |
2718 | 87.9M | static bool isPlaceholderTypeKind(Kind K) { |
2719 | 87.9M | return K >= Overload; |
2720 | 87.9M | } |
2721 | | |
2722 | | /// Determines whether this type is a placeholder type, i.e. a type |
2723 | | /// which cannot appear in arbitrary positions in a fully-formed |
2724 | | /// expression. |
2725 | 81.3M | bool isPlaceholderType() const { |
2726 | 81.3M | return isPlaceholderTypeKind(getKind()); |
2727 | 81.3M | } |
2728 | | |
2729 | | /// Determines whether this type is a placeholder type other than |
2730 | | /// Overload. Most placeholder types require only syntactic |
2731 | | /// information about their context in order to be resolved (e.g. |
2732 | | /// whether it is a call expression), which means they can (and |
2733 | | /// should) be resolved in an earlier "phase" of analysis. |
2734 | | /// Overload expressions sometimes pick up further information |
2735 | | /// from their context, like whether the context expects a |
2736 | | /// specific function-pointer type, and so frequently need |
2737 | | /// special treatment. |
2738 | 6.07M | bool isNonOverloadPlaceholderType() const { |
2739 | 6.07M | return getKind() > Overload; |
2740 | 6.07M | } |
2741 | | |
2742 | 4.22G | static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } |
2743 | | }; |
2744 | | |
2745 | | /// Complex values, per C99 6.2.5p11. This supports the C99 complex |
2746 | | /// types (_Complex float etc) as well as the GCC integer complex extensions. |
2747 | | class ComplexType : public Type, public llvm::FoldingSetNode { |
2748 | | friend class ASTContext; // ASTContext creates these. |
2749 | | |
2750 | | QualType ElementType; |
2751 | | |
2752 | | ComplexType(QualType Element, QualType CanonicalPtr) |
2753 | | : Type(Complex, CanonicalPtr, Element->getDependence()), |
2754 | 1.54k | ElementType(Element) {} |
2755 | | |
2756 | | public: |
2757 | 42.5k | QualType getElementType() const { return ElementType; } |
2758 | | |
2759 | 12.7k | bool isSugared() const { return false; } |
2760 | 0 | QualType desugar() const { return QualType(this, 0); } |
2761 | | |
2762 | 10.7k | void Profile(llvm::FoldingSetNodeID &ID) { |
2763 | 10.7k | Profile(ID, getElementType()); |
2764 | 10.7k | } |
2765 | | |
2766 | 22.7k | static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { |
2767 | 22.7k | ID.AddPointer(Element.getAsOpaquePtr()); |
2768 | 22.7k | } |
2769 | | |
2770 | 96.7M | static bool classof(const Type *T) { return T->getTypeClass() == Complex; } |
2771 | | }; |
2772 | | |
2773 | | /// Sugar for parentheses used when specifying types. |
2774 | | class ParenType : public Type, public llvm::FoldingSetNode { |
2775 | | friend class ASTContext; // ASTContext creates these. |
2776 | | |
2777 | | QualType Inner; |
2778 | | |
2779 | | ParenType(QualType InnerType, QualType CanonType) |
2780 | 209k | : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {} |
2781 | | |
2782 | | public: |
2783 | 2.77M | QualType getInnerType() const { return Inner; } |
2784 | | |
2785 | 498k | bool isSugared() const { return true; } |
2786 | 500k | QualType desugar() const { return getInnerType(); } |
2787 | | |
2788 | 271k | void Profile(llvm::FoldingSetNodeID &ID) { |
2789 | 271k | Profile(ID, getInnerType()); |
2790 | 271k | } |
2791 | | |
2792 | 594k | static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { |
2793 | 594k | Inner.Profile(ID); |
2794 | 594k | } |
2795 | | |
2796 | 44.4M | static bool classof(const Type *T) { return T->getTypeClass() == Paren; } |
2797 | | }; |
2798 | | |
2799 | | /// PointerType - C99 6.7.5.1 - Pointer Declarators. |
2800 | | class PointerType : public Type, public llvm::FoldingSetNode { |
2801 | | friend class ASTContext; // ASTContext creates these. |
2802 | | |
2803 | | QualType PointeeType; |
2804 | | |
2805 | | PointerType(QualType Pointee, QualType CanonicalPtr) |
2806 | | : Type(Pointer, CanonicalPtr, Pointee->getDependence()), |
2807 | 5.87M | PointeeType(Pointee) {} |
2808 | | |
2809 | | public: |
2810 | 160M | QualType getPointeeType() const { return PointeeType; } |
2811 | | |
2812 | 21.9M | bool isSugared() const { return false; } |
2813 | 0 | QualType desugar() const { return QualType(this, 0); } |
2814 | | |
2815 | 47.1M | void Profile(llvm::FoldingSetNodeID &ID) { |
2816 | 47.1M | Profile(ID, getPointeeType()); |
2817 | 47.1M | } |
2818 | | |
2819 | 82.9M | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { |
2820 | 82.9M | ID.AddPointer(Pointee.getAsOpaquePtr()); |
2821 | 82.9M | } |
2822 | | |
2823 | 1.23G | static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } |
2824 | | }; |
2825 | | |
2826 | | /// Represents a type which was implicitly adjusted by the semantic |
2827 | | /// engine for arbitrary reasons. For example, array and function types can |
2828 | | /// decay, and function types can have their calling conventions adjusted. |
2829 | | class AdjustedType : public Type, public llvm::FoldingSetNode { |
2830 | | QualType OriginalTy; |
2831 | | QualType AdjustedTy; |
2832 | | |
2833 | | protected: |
2834 | | friend class ASTContext; // ASTContext creates these. |
2835 | | |
2836 | | AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, |
2837 | | QualType CanonicalPtr) |
2838 | | : Type(TC, CanonicalPtr, OriginalTy->getDependence()), |
2839 | 32.9k | OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} |
2840 | | |
2841 | | public: |
2842 | 40.2k | QualType getOriginalType() const { return OriginalTy; } |
2843 | 45.1k | QualType getAdjustedType() const { return AdjustedTy; } |
2844 | | |
2845 | 79.4k | bool isSugared() const { return true; } |
2846 | 79.5k | QualType desugar() const { return AdjustedTy; } |
2847 | | |
2848 | 99.4k | void Profile(llvm::FoldingSetNodeID &ID) { |
2849 | 99.4k | Profile(ID, OriginalTy, AdjustedTy); |
2850 | 99.4k | } |
2851 | | |
2852 | 195k | static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) { |
2853 | 195k | ID.AddPointer(Orig.getAsOpaquePtr()); |
2854 | 195k | ID.AddPointer(New.getAsOpaquePtr()); |
2855 | 195k | } |
2856 | | |
2857 | 32.2M | static bool classof(const Type *T) { |
2858 | 32.2M | return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed32.2M ; |
2859 | 32.2M | } |
2860 | | }; |
2861 | | |
2862 | | /// Represents a pointer type decayed from an array or function type. |
2863 | | class DecayedType : public AdjustedType { |
2864 | | friend class ASTContext; // ASTContext creates these. |
2865 | | |
2866 | | inline |
2867 | | DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical); |
2868 | | |
2869 | | public: |
2870 | 238 | QualType getDecayedType() const { return getAdjustedType(); } |
2871 | | |
2872 | | inline QualType getPointeeType() const; |
2873 | | |
2874 | 23.7M | static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } |
2875 | | }; |
2876 | | |
2877 | | /// Pointer to a block type. |
2878 | | /// This type is to represent types syntactically represented as |
2879 | | /// "void (^)(int)", etc. Pointee is required to always be a function type. |
2880 | | class BlockPointerType : public Type, public llvm::FoldingSetNode { |
2881 | | friend class ASTContext; // ASTContext creates these. |
2882 | | |
2883 | | // Block is some kind of pointer type |
2884 | | QualType PointeeType; |
2885 | | |
2886 | | BlockPointerType(QualType Pointee, QualType CanonicalCls) |
2887 | | : Type(BlockPointer, CanonicalCls, Pointee->getDependence()), |
2888 | 63.8k | PointeeType(Pointee) {} |
2889 | | |
2890 | | public: |
2891 | | // Get the pointee type. Pointee is required to always be a function type. |
2892 | 525k | QualType getPointeeType() const { return PointeeType; } |
2893 | | |
2894 | 140k | bool isSugared() const { return false; } |
2895 | 0 | QualType desugar() const { return QualType(this, 0); } |
2896 | | |
2897 | 175k | void Profile(llvm::FoldingSetNodeID &ID) { |
2898 | 175k | Profile(ID, getPointeeType()); |
2899 | 175k | } |
2900 | | |
2901 | 272k | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { |
2902 | 272k | ID.AddPointer(Pointee.getAsOpaquePtr()); |
2903 | 272k | } |
2904 | | |
2905 | 344M | static bool classof(const Type *T) { |
2906 | 344M | return T->getTypeClass() == BlockPointer; |
2907 | 344M | } |
2908 | | }; |
2909 | | |
2910 | | /// Base for LValueReferenceType and RValueReferenceType |
2911 | | class ReferenceType : public Type, public llvm::FoldingSetNode { |
2912 | | QualType PointeeType; |
2913 | | |
2914 | | protected: |
2915 | | ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, |
2916 | | bool SpelledAsLValue) |
2917 | | : Type(tc, CanonicalRef, Referencee->getDependence()), |
2918 | 4.10M | PointeeType(Referencee) { |
2919 | 4.10M | ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; |
2920 | 4.10M | ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); |
2921 | 4.10M | } |
2922 | | |
2923 | | public: |
2924 | 33.0M | bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; } |
2925 | 31.0M | bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } |
2926 | | |
2927 | 46.2M | QualType getPointeeTypeAsWritten() const { return PointeeType; } |
2928 | | |
2929 | 29.5M | QualType getPointeeType() const { |
2930 | | // FIXME: this might strip inner qualifiers; okay? |
2931 | 29.5M | const ReferenceType *T = this; |
2932 | 30.1M | while (T->isInnerRef()) |
2933 | 518k | T = T->PointeeType->castAs<ReferenceType>(); |
2934 | 29.5M | return T->PointeeType; |
2935 | 29.5M | } |
2936 | | |
2937 | 30.5M | void Profile(llvm::FoldingSetNodeID &ID) { |
2938 | 30.5M | Profile(ID, PointeeType, isSpelledAsLValue()); |
2939 | 30.5M | } |
2940 | | |
2941 | | static void Profile(llvm::FoldingSetNodeID &ID, |
2942 | | QualType Referencee, |
2943 | 46.5M | bool SpelledAsLValue) { |
2944 | 46.5M | ID.AddPointer(Referencee.getAsOpaquePtr()); |
2945 | 46.5M | ID.AddBoolean(SpelledAsLValue); |
2946 | 46.5M | } |
2947 | | |
2948 | 794M | static bool classof(const Type *T) { |
2949 | 794M | return T->getTypeClass() == LValueReference || |
2950 | 794M | T->getTypeClass() == RValueReference715M ; |
2951 | 794M | } |
2952 | | }; |
2953 | | |
2954 | | /// An lvalue reference type, per C++11 [dcl.ref]. |
2955 | | class LValueReferenceType : public ReferenceType { |
2956 | | friend class ASTContext; // ASTContext creates these |
2957 | | |
2958 | | LValueReferenceType(QualType Referencee, QualType CanonicalRef, |
2959 | | bool SpelledAsLValue) |
2960 | | : ReferenceType(LValueReference, Referencee, CanonicalRef, |
2961 | 3.04M | SpelledAsLValue) {} |
2962 | | |
2963 | | public: |
2964 | 3.02M | bool isSugared() const { return false; } |
2965 | 0 | QualType desugar() const { return QualType(this, 0); } |
2966 | | |
2967 | 58.8M | static bool classof(const Type *T) { |
2968 | 58.8M | return T->getTypeClass() == LValueReference; |
2969 | 58.8M | } |
2970 | | }; |
2971 | | |
2972 | | /// An rvalue reference type, per C++11 [dcl.ref]. |
2973 | | class RValueReferenceType : public ReferenceType { |
2974 | | friend class ASTContext; // ASTContext creates these |
2975 | | |
2976 | | RValueReferenceType(QualType Referencee, QualType CanonicalRef) |
2977 | 1.05M | : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {} |
2978 | | |
2979 | | public: |
2980 | 444k | bool isSugared() const { return false; } |
2981 | 0 | QualType desugar() const { return QualType(this, 0); } |
2982 | | |
2983 | 30.5M | static bool classof(const Type *T) { |
2984 | 30.5M | return T->getTypeClass() == RValueReference; |
2985 | 30.5M | } |
2986 | | }; |
2987 | | |
2988 | | /// A pointer to member type per C++ 8.3.3 - Pointers to members. |
2989 | | /// |
2990 | | /// This includes both pointers to data members and pointer to member functions. |
2991 | | class MemberPointerType : public Type, public llvm::FoldingSetNode { |
2992 | | friend class ASTContext; // ASTContext creates these. |
2993 | | |
2994 | | QualType PointeeType; |
2995 | | |
2996 | | /// The class of which the pointee is a member. Must ultimately be a |
2997 | | /// RecordType, but could be a typedef or a template parameter too. |
2998 | | const Type *Class; |
2999 | | |
3000 | | MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) |
3001 | | : Type(MemberPointer, CanonicalPtr, |
3002 | | (Cls->getDependence() & ~TypeDependence::VariablyModified) | |
3003 | | Pointee->getDependence()), |
3004 | 51.9k | PointeeType(Pointee), Class(Cls) {} |
3005 | | |
3006 | | public: |
3007 | 641k | QualType getPointeeType() const { return PointeeType; } |
3008 | | |
3009 | | /// Returns true if the member type (i.e. the pointee type) is a |
3010 | | /// function type rather than a data-member type. |
3011 | 6.13k | bool isMemberFunctionPointer() const { |
3012 | 6.13k | return PointeeType->isFunctionProtoType(); |
3013 | 6.13k | } |
3014 | | |
3015 | | /// Returns true if the member type (i.e. the pointee type) is a |
3016 | | /// data type rather than a function type. |
3017 | 1.69k | bool isMemberDataPointer() const { |
3018 | 1.69k | return !PointeeType->isFunctionProtoType(); |
3019 | 1.69k | } |
3020 | | |
3021 | 233k | const Type *getClass() const { return Class; } |
3022 | | CXXRecordDecl *getMostRecentCXXRecordDecl() const; |
3023 | | |
3024 | 40.8k | bool isSugared() const { return false; } |
3025 | 0 | QualType desugar() const { return QualType(this, 0); } |
3026 | | |
3027 | 66.8k | void Profile(llvm::FoldingSetNodeID &ID) { |
3028 | 66.8k | Profile(ID, getPointeeType(), getClass()); |
3029 | 66.8k | } |
3030 | | |
3031 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, |
3032 | 133k | const Type *Class) { |
3033 | 133k | ID.AddPointer(Pointee.getAsOpaquePtr()); |
3034 | 133k | ID.AddPointer(Class); |
3035 | 133k | } |
3036 | | |
3037 | 505M | static bool classof(const Type *T) { |
3038 | 505M | return T->getTypeClass() == MemberPointer; |
3039 | 505M | } |
3040 | | }; |
3041 | | |
3042 | | /// Represents an array type, per C99 6.7.5.2 - Array Declarators. |
3043 | | class ArrayType : public Type, public llvm::FoldingSetNode { |
3044 | | public: |
3045 | | /// Capture whether this is a normal array (e.g. int X[4]) |
3046 | | /// an array with a static size (e.g. int X[static 4]), or an array |
3047 | | /// with a star size (e.g. int X[*]). |
3048 | | /// 'static' is only allowed on function parameters. |
3049 | | enum ArraySizeModifier { |
3050 | | Normal, Static, Star |
3051 | | }; |
3052 | | |
3053 | | private: |
3054 | | /// The element type of the array. |
3055 | | QualType ElementType; |
3056 | | |
3057 | | protected: |
3058 | | friend class ASTContext; // ASTContext creates these. |
3059 | | |
3060 | | ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm, |
3061 | | unsigned tq, const Expr *sz = nullptr); |
3062 | | |
3063 | | public: |
3064 | 19.1M | QualType getElementType() const { return ElementType; } |
3065 | | |
3066 | 11.1M | ArraySizeModifier getSizeModifier() const { |
3067 | 11.1M | return ArraySizeModifier(ArrayTypeBits.SizeModifier); |
3068 | 11.1M | } |
3069 | | |
3070 | 623k | Qualifiers getIndexTypeQualifiers() const { |
3071 | 623k | return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers()); |
3072 | 623k | } |
3073 | | |
3074 | 11.7M | unsigned getIndexTypeCVRQualifiers() const { |
3075 | 11.7M | return ArrayTypeBits.IndexTypeQuals; |
3076 | 11.7M | } |
3077 | | |
3078 | 1.29G | static bool classof(const Type *T) { |
3079 | 1.29G | return T->getTypeClass() == ConstantArray || |
3080 | 1.29G | T->getTypeClass() == VariableArray1.28G || |
3081 | 1.29G | T->getTypeClass() == IncompleteArray1.28G || |
3082 | 1.29G | T->getTypeClass() == DependentSizedArray1.28G ; |
3083 | 1.29G | } |
3084 | | }; |
3085 | | |
3086 | | /// Represents the canonical version of C arrays with a specified constant size. |
3087 | | /// For example, the canonical type for 'int A[4 + 4*100]' is a |
3088 | | /// ConstantArrayType where the element type is 'int' and the size is 404. |
3089 | | class ConstantArrayType final |
3090 | | : public ArrayType, |
3091 | | private llvm::TrailingObjects<ConstantArrayType, const Expr *> { |
3092 | | friend class ASTContext; // ASTContext creates these. |
3093 | | friend TrailingObjects; |
3094 | | |
3095 | | llvm::APInt Size; // Allows us to unique the type. |
3096 | | |
3097 | | ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, |
3098 | | const Expr *sz, ArraySizeModifier sm, unsigned tq) |
3099 | 547k | : ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) { |
3100 | 547k | ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr; |
3101 | 547k | if (ConstantArrayTypeBits.HasStoredSizeExpr) { |
3102 | 100 | assert(!can.isNull() && "canonical constant array should not have size"); |
3103 | 100 | *getTrailingObjects<const Expr*>() = sz; |
3104 | 100 | } |
3105 | 547k | } |
3106 | | |
3107 | 0 | unsigned numTrailingObjects(OverloadToken<const Expr*>) const { |
3108 | 0 | return ConstantArrayTypeBits.HasStoredSizeExpr; |
3109 | 0 | } |
3110 | | |
3111 | | public: |
3112 | 11.9M | const llvm::APInt &getSize() const { return Size; } |
3113 | 10.9M | const Expr *getSizeExpr() const { |
3114 | 10.9M | return ConstantArrayTypeBits.HasStoredSizeExpr |
3115 | 10.9M | ? *getTrailingObjects<const Expr *>()126 |
3116 | 10.9M | : nullptr10.9M ; |
3117 | 10.9M | } |
3118 | 2.25M | bool isSugared() const { return false; } |
3119 | 148 | QualType desugar() const { return QualType(this, 0); } |
3120 | | |
3121 | | /// Determine the number of bits required to address a member of |
3122 | | // an array with the given element type and number of elements. |
3123 | | static unsigned getNumAddressingBits(const ASTContext &Context, |
3124 | | QualType ElementType, |
3125 | | const llvm::APInt &NumElements); |
3126 | | |
3127 | | /// Determine the maximum number of active bits that an array's size |
3128 | | /// can require, which limits the maximum size of the array. |
3129 | | static unsigned getMaxSizeBits(const ASTContext &Context); |
3130 | | |
3131 | 10.8M | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { |
3132 | 10.8M | Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(), |
3133 | 10.8M | getSizeModifier(), getIndexTypeCVRQualifiers()); |
3134 | 10.8M | } |
3135 | | |
3136 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx, |
3137 | | QualType ET, const llvm::APInt &ArraySize, |
3138 | | const Expr *SizeExpr, ArraySizeModifier SizeMod, |
3139 | | unsigned TypeQuals); |
3140 | | |
3141 | 26.0M | static bool classof(const Type *T) { |
3142 | 26.0M | return T->getTypeClass() == ConstantArray; |
3143 | 26.0M | } |
3144 | | }; |
3145 | | |
3146 | | /// Represents a C array with an unspecified size. For example 'int A[]' has |
3147 | | /// an IncompleteArrayType where the element type is 'int' and the size is |
3148 | | /// unspecified. |
3149 | | class IncompleteArrayType : public ArrayType { |
3150 | | friend class ASTContext; // ASTContext creates these. |
3151 | | |
3152 | | IncompleteArrayType(QualType et, QualType can, |
3153 | | ArraySizeModifier sm, unsigned tq) |
3154 | 51.1k | : ArrayType(IncompleteArray, et, can, sm, tq) {} |
3155 | | |
3156 | | public: |
3157 | | friend class StmtIteratorBase; |
3158 | | |
3159 | 81.6k | bool isSugared() const { return false; } |
3160 | 0 | QualType desugar() const { return QualType(this, 0); } |
3161 | | |
3162 | 42.2M | static bool classof(const Type *T) { |
3163 | 42.2M | return T->getTypeClass() == IncompleteArray; |
3164 | 42.2M | } |
3165 | | |
3166 | 70.2k | void Profile(llvm::FoldingSetNodeID &ID) { |
3167 | 70.2k | Profile(ID, getElementType(), getSizeModifier(), |
3168 | 70.2k | getIndexTypeCVRQualifiers()); |
3169 | 70.2k | } |
3170 | | |
3171 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, |
3172 | 163k | ArraySizeModifier SizeMod, unsigned TypeQuals) { |
3173 | 163k | ID.AddPointer(ET.getAsOpaquePtr()); |
3174 | 163k | ID.AddInteger(SizeMod); |
3175 | 163k | ID.AddInteger(TypeQuals); |
3176 | 163k | } |
3177 | | }; |
3178 | | |
3179 | | /// Represents a C array with a specified size that is not an |
3180 | | /// integer-constant-expression. For example, 'int s[x+foo()]'. |
3181 | | /// Since the size expression is an arbitrary expression, we store it as such. |
3182 | | /// |
3183 | | /// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and |
3184 | | /// should not be: two lexically equivalent variable array types could mean |
3185 | | /// different things, for example, these variables do not have the same type |
3186 | | /// dynamically: |
3187 | | /// |
3188 | | /// void foo(int x) { |
3189 | | /// int Y[x]; |
3190 | | /// ++x; |
3191 | | /// int Z[x]; |
3192 | | /// } |
3193 | | class VariableArrayType : public ArrayType { |
3194 | | friend class ASTContext; // ASTContext creates these. |
3195 | | |
3196 | | /// An assignment-expression. VLA's are only permitted within |
3197 | | /// a function block. |
3198 | | Stmt *SizeExpr; |
3199 | | |
3200 | | /// The range spanned by the left and right array brackets. |
3201 | | SourceRange Brackets; |
3202 | | |
3203 | | VariableArrayType(QualType et, QualType can, Expr *e, |
3204 | | ArraySizeModifier sm, unsigned tq, |
3205 | | SourceRange brackets) |
3206 | | : ArrayType(VariableArray, et, can, sm, tq, e), |
3207 | 8.27k | SizeExpr((Stmt*) e), Brackets(brackets) {} |
3208 | | |
3209 | | public: |
3210 | | friend class StmtIteratorBase; |
3211 | | |
3212 | 63.7k | Expr *getSizeExpr() const { |
3213 | | // We use C-style casts instead of cast<> here because we do not wish |
3214 | | // to have a dependency of Type.h on Stmt.h/Expr.h. |
3215 | 63.7k | return (Expr*) SizeExpr; |
3216 | 63.7k | } |
3217 | | |
3218 | 312 | SourceRange getBracketsRange() const { return Brackets; } |
3219 | 1.60k | SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } |
3220 | 1.60k | SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } |
3221 | | |
3222 | 49.4k | bool isSugared() const { return false; } |
3223 | 33 | QualType desugar() const { return QualType(this, 0); } |
3224 | | |
3225 | 34.9M | static bool classof(const Type *T) { |
3226 | 34.9M | return T->getTypeClass() == VariableArray; |
3227 | 34.9M | } |
3228 | | |
3229 | 0 | void Profile(llvm::FoldingSetNodeID &ID) { |
3230 | 0 | llvm_unreachable("Cannot unique VariableArrayTypes."); |
3231 | 0 | } |
3232 | | }; |
3233 | | |
3234 | | /// Represents an array type in C++ whose size is a value-dependent expression. |
3235 | | /// |
3236 | | /// For example: |
3237 | | /// \code |
3238 | | /// template<typename T, int Size> |
3239 | | /// class array { |
3240 | | /// T data[Size]; |
3241 | | /// }; |
3242 | | /// \endcode |
3243 | | /// |
3244 | | /// For these types, we won't actually know what the array bound is |
3245 | | /// until template instantiation occurs, at which point this will |
3246 | | /// become either a ConstantArrayType or a VariableArrayType. |
3247 | | class DependentSizedArrayType : public ArrayType { |
3248 | | friend class ASTContext; // ASTContext creates these. |
3249 | | |
3250 | | const ASTContext &Context; |
3251 | | |
3252 | | /// An assignment expression that will instantiate to the |
3253 | | /// size of the array. |
3254 | | /// |
3255 | | /// The expression itself might be null, in which case the array |
3256 | | /// type will have its size deduced from an initializer. |
3257 | | Stmt *SizeExpr; |
3258 | | |
3259 | | /// The range spanned by the left and right array brackets. |
3260 | | SourceRange Brackets; |
3261 | | |
3262 | | DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can, |
3263 | | Expr *e, ArraySizeModifier sm, unsigned tq, |
3264 | | SourceRange brackets); |
3265 | | |
3266 | | public: |
3267 | | friend class StmtIteratorBase; |
3268 | | |
3269 | 49.7k | Expr *getSizeExpr() const { |
3270 | | // We use C-style casts instead of cast<> here because we do not wish |
3271 | | // to have a dependency of Type.h on Stmt.h/Expr.h. |
3272 | 49.7k | return (Expr*) SizeExpr; |
3273 | 49.7k | } |
3274 | | |
3275 | 1.32k | SourceRange getBracketsRange() const { return Brackets; } |
3276 | 922 | SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } |
3277 | 922 | SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } |
3278 | | |
3279 | 53.1k | bool isSugared() const { return false; } |
3280 | 0 | QualType desugar() const { return QualType(this, 0); } |
3281 | | |
3282 | 318k | static bool classof(const Type *T) { |
3283 | 318k | return T->getTypeClass() == DependentSizedArray; |
3284 | 318k | } |
3285 | | |
3286 | 12.2k | void Profile(llvm::FoldingSetNodeID &ID) { |
3287 | 12.2k | Profile(ID, Context, getElementType(), |
3288 | 12.2k | getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr()); |
3289 | 12.2k | } |
3290 | | |
3291 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
3292 | | QualType ET, ArraySizeModifier SizeMod, |
3293 | | unsigned TypeQuals, Expr *E); |
3294 | | }; |
3295 | | |
3296 | | /// Represents an extended address space qualifier where the input address space |
3297 | | /// value is dependent. Non-dependent address spaces are not represented with a |
3298 | | /// special Type subclass; they are stored on an ExtQuals node as part of a QualType. |
3299 | | /// |
3300 | | /// For example: |
3301 | | /// \code |
3302 | | /// template<typename T, int AddrSpace> |
3303 | | /// class AddressSpace { |
3304 | | /// typedef T __attribute__((address_space(AddrSpace))) type; |
3305 | | /// } |
3306 | | /// \endcode |
3307 | | class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode { |
3308 | | friend class ASTContext; |
3309 | | |
3310 | | const ASTContext &Context; |
3311 | | Expr *AddrSpaceExpr; |
3312 | | QualType PointeeType; |
3313 | | SourceLocation loc; |
3314 | | |
3315 | | DependentAddressSpaceType(const ASTContext &Context, QualType PointeeType, |
3316 | | QualType can, Expr *AddrSpaceExpr, |
3317 | | SourceLocation loc); |
3318 | | |
3319 | | public: |
3320 | 149 | Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; } |
3321 | 493 | QualType getPointeeType() const { return PointeeType; } |
3322 | 37 | SourceLocation getAttributeLoc() const { return loc; } |
3323 | | |
3324 | 13 | bool isSugared() const { return false; } |
3325 | 0 | QualType desugar() const { return QualType(this, 0); } |
3326 | | |
3327 | 14.4M | static bool classof(const Type *T) { |
3328 | 14.4M | return T->getTypeClass() == DependentAddressSpace; |
3329 | 14.4M | } |
3330 | | |
3331 | 19 | void Profile(llvm::FoldingSetNodeID &ID) { |
3332 | 19 | Profile(ID, Context, getPointeeType(), getAddrSpaceExpr()); |
3333 | 19 | } |
3334 | | |
3335 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
3336 | | QualType PointeeType, Expr *AddrSpaceExpr); |
3337 | | }; |
3338 | | |
3339 | | /// Represents an extended vector type where either the type or size is |
3340 | | /// dependent. |
3341 | | /// |
3342 | | /// For example: |
3343 | | /// \code |
3344 | | /// template<typename T, int Size> |
3345 | | /// class vector { |
3346 | | /// typedef T __attribute__((ext_vector_type(Size))) type; |
3347 | | /// } |
3348 | | /// \endcode |
3349 | | class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { |
3350 | | friend class ASTContext; |
3351 | | |
3352 | | const ASTContext &Context; |
3353 | | Expr *SizeExpr; |
3354 | | |
3355 | | /// The element type of the array. |
3356 | | QualType ElementType; |
3357 | | |
3358 | | SourceLocation loc; |
3359 | | |
3360 | | DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType, |
3361 | | QualType can, Expr *SizeExpr, SourceLocation loc); |
3362 | | |
3363 | | public: |
3364 | 1.38k | Expr *getSizeExpr() const { return SizeExpr; } |
3365 | 13.5k | QualType getElementType() const { return ElementType; } |
3366 | 1.18k | SourceLocation getAttributeLoc() const { return loc; } |
3367 | | |
3368 | 123 | bool isSugared() const { return false; } |
3369 | 0 | QualType desugar() const { return QualType(this, 0); } |
3370 | | |
3371 | 28.1k | static bool classof(const Type *T) { |
3372 | 28.1k | return T->getTypeClass() == DependentSizedExtVector; |
3373 | 28.1k | } |
3374 | | |
3375 | 11 | void Profile(llvm::FoldingSetNodeID &ID) { |
3376 | 11 | Profile(ID, Context, getElementType(), getSizeExpr()); |
3377 | 11 | } |
3378 | | |
3379 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
3380 | | QualType ElementType, Expr *SizeExpr); |
3381 | | }; |
3382 | | |
3383 | | |
3384 | | /// Represents a GCC generic vector type. This type is created using |
3385 | | /// __attribute__((vector_size(n)), where "n" specifies the vector size in |
3386 | | /// bytes; or from an Altivec __vector or vector declaration. |
3387 | | /// Since the constructor takes the number of vector elements, the |
3388 | | /// client is responsible for converting the size into the number of elements. |
3389 | | class VectorType : public Type, public llvm::FoldingSetNode { |
3390 | | public: |
3391 | | enum VectorKind { |
3392 | | /// not a target-specific vector type |
3393 | | GenericVector, |
3394 | | |
3395 | | /// is AltiVec vector |
3396 | | AltiVecVector, |
3397 | | |
3398 | | /// is AltiVec 'vector Pixel' |
3399 | | AltiVecPixel, |
3400 | | |
3401 | | /// is AltiVec 'vector bool ...' |
3402 | | AltiVecBool, |
3403 | | |
3404 | | /// is ARM Neon vector |
3405 | | NeonVector, |
3406 | | |
3407 | | /// is ARM Neon polynomial vector |
3408 | | NeonPolyVector, |
3409 | | |
3410 | | /// is AArch64 SVE fixed-length data vector |
3411 | | SveFixedLengthDataVector, |
3412 | | |
3413 | | /// is AArch64 SVE fixed-length predicate vector |
3414 | | SveFixedLengthPredicateVector, |
3415 | | |
3416 | | /// is RISC-V RVV fixed-length data vector |
3417 | | RVVFixedLengthDataVector, |
3418 | | }; |
3419 | | |
3420 | | protected: |
3421 | | friend class ASTContext; // ASTContext creates these. |
3422 | | |
3423 | | /// The element type of the vector. |
3424 | | QualType ElementType; |
3425 | | |
3426 | | VectorType(QualType vecType, unsigned nElements, QualType canonType, |
3427 | | VectorKind vecKind); |
3428 | | |
3429 | | VectorType(TypeClass tc, QualType vecType, unsigned nElements, |
3430 | | QualType canonType, VectorKind vecKind); |
3431 | | |
3432 | | public: |
3433 | 24.6M | QualType getElementType() const { return ElementType; } |
3434 | 25.3M | unsigned getNumElements() const { return VectorTypeBits.NumElements; } |
3435 | | |
3436 | 31.0M | bool isSugared() const { return false; } |
3437 | 0 | QualType desugar() const { return QualType(this, 0); } |
3438 | | |
3439 | 20.2M | VectorKind getVectorKind() const { |
3440 | 20.2M | return VectorKind(VectorTypeBits.VecKind); |
3441 | 20.2M | } |
3442 | | |
3443 | 9.23M | void Profile(llvm::FoldingSetNodeID &ID) { |
3444 | 9.23M | Profile(ID, getElementType(), getNumElements(), |
3445 | 9.23M | getTypeClass(), getVectorKind()); |
3446 | 9.23M | } |
3447 | | |
3448 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, |
3449 | | unsigned NumElements, TypeClass TypeClass, |
3450 | 15.7M | VectorKind VecKind) { |
3451 | 15.7M | ID.AddPointer(ElementType.getAsOpaquePtr()); |
3452 | 15.7M | ID.AddInteger(NumElements); |
3453 | 15.7M | ID.AddInteger(TypeClass); |
3454 | 15.7M | ID.AddInteger(VecKind); |
3455 | 15.7M | } |
3456 | | |
3457 | 301M | static bool classof(const Type *T) { |
3458 | 301M | return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector172M ; |
3459 | 301M | } |
3460 | | }; |
3461 | | |
3462 | | /// Represents a vector type where either the type or size is dependent. |
3463 | | //// |
3464 | | /// For example: |
3465 | | /// \code |
3466 | | /// template<typename T, int Size> |
3467 | | /// class vector { |
3468 | | /// typedef T __attribute__((vector_size(Size))) type; |
3469 | | /// } |
3470 | | /// \endcode |
3471 | | class DependentVectorType : public Type, public llvm::FoldingSetNode { |
3472 | | friend class ASTContext; |
3473 | | |
3474 | | const ASTContext &Context; |
3475 | | QualType ElementType; |
3476 | | Expr *SizeExpr; |
3477 | | SourceLocation Loc; |
3478 | | |
3479 | | DependentVectorType(const ASTContext &Context, QualType ElementType, |
3480 | | QualType CanonType, Expr *SizeExpr, |
3481 | | SourceLocation Loc, VectorType::VectorKind vecKind); |
3482 | | |
3483 | | public: |
3484 | 123 | Expr *getSizeExpr() const { return SizeExpr; } |
3485 | 945 | QualType getElementType() const { return ElementType; } |
3486 | 102 | SourceLocation getAttributeLoc() const { return Loc; } |
3487 | 117 | VectorType::VectorKind getVectorKind() const { |
3488 | 117 | return VectorType::VectorKind(VectorTypeBits.VecKind); |
3489 | 117 | } |
3490 | | |
3491 | 72 | bool isSugared() const { return false; } |
3492 | 0 | QualType desugar() const { return QualType(this, 0); } |
3493 | | |
3494 | 1.93k | static bool classof(const Type *T) { |
3495 | 1.93k | return T->getTypeClass() == DependentVector; |
3496 | 1.93k | } |
3497 | | |
3498 | 15 | void Profile(llvm::FoldingSetNodeID &ID) { |
3499 | 15 | Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind()); |
3500 | 15 | } |
3501 | | |
3502 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
3503 | | QualType ElementType, const Expr *SizeExpr, |
3504 | | VectorType::VectorKind VecKind); |
3505 | | }; |
3506 | | |
3507 | | /// ExtVectorType - Extended vector type. This type is created using |
3508 | | /// __attribute__((ext_vector_type(n)), where "n" is the number of elements. |
3509 | | /// Unlike vector_size, ext_vector_type is only allowed on typedef's. This |
3510 | | /// class enables syntactic extensions, like Vector Components for accessing |
3511 | | /// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL |
3512 | | /// Shading Language). |
3513 | | class ExtVectorType : public VectorType { |
3514 | | friend class ASTContext; // ASTContext creates these. |
3515 | | |
3516 | | ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) |
3517 | 9.15k | : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} |
3518 | | |
3519 | | public: |
3520 | 1.97k | static int getPointAccessorIdx(char c) { |
3521 | 1.97k | switch (c) { |
3522 | 8 | default: return -1; |
3523 | 892 | case 'x': 802 case 'r': return 0; |
3524 | 665 | case 'y': 593 case 'g': return 1; |
3525 | 230 | case 'z': 164 case 'b': return 2; |
3526 | 178 | case 'w': 147 case 'a': return 3; |
3527 | 1.97k | } |
3528 | 1.97k | } |
3529 | | |
3530 | 124 | static int getNumericAccessorIdx(char c) { |
3531 | 124 | switch (c) { |
3532 | 30 | default: return -1; |
3533 | 28 | case '0': return 0; |
3534 | 11 | case '1': return 1; |
3535 | 10 | case '2': return 2; |
3536 | 10 | case '3': return 3; |
3537 | 6 | case '4': return 4; |
3538 | 0 | case '5': return 5; |
3539 | 4 | case '6': return 6; |
3540 | 0 | case '7': return 7; |
3541 | 0 | case '8': return 8; |
3542 | 0 | case '9': return 9; |
3543 | 0 | case 'A': |
3544 | 3 | case 'a': return 10; |
3545 | 0 | case 'B': |
3546 | 8 | case 'b': return 11; |
3547 | 0 | case 'C': |
3548 | 3 | case 'c': return 12; |
3549 | 0 | case 'D': |
3550 | 3 | case 'd': return 13; |
3551 | 0 | case 'E': |
3552 | 0 | case 'e': return 14; |
3553 | 4 | case 'F': |
3554 | 8 | case 'f': return 15; |
3555 | 124 | } |
3556 | 124 | } |
3557 | | |
3558 | 1.21k | static int getAccessorIdx(char c, bool isNumericAccessor) { |
3559 | 1.21k | if (isNumericAccessor) |
3560 | 53 | return getNumericAccessorIdx(c); |
3561 | 1.16k | else |
3562 | 1.16k | return getPointAccessorIdx(c); |
3563 | 1.21k | } |
3564 | | |
3565 | 807 | bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const { |
3566 | 807 | if (int idx = getAccessorIdx(c, isNumericAccessor)+1) |
3567 | 807 | return unsigned(idx-1) < getNumElements(); |
3568 | 0 | return false; |
3569 | 807 | } |
3570 | | |
3571 | 605k | bool isSugared() const { return false; } |
3572 | 0 | QualType desugar() const { return QualType(this, 0); } |
3573 | | |
3574 | 15.2M | static bool classof(const Type *T) { |
3575 | 15.2M | return T->getTypeClass() == ExtVector; |
3576 | 15.2M | } |
3577 | | }; |
3578 | | |
3579 | | /// Represents a matrix type, as defined in the Matrix Types clang extensions. |
3580 | | /// __attribute__((matrix_type(rows, columns))), where "rows" specifies |
3581 | | /// number of rows and "columns" specifies the number of columns. |
3582 | | class MatrixType : public Type, public llvm::FoldingSetNode { |
3583 | | protected: |
3584 | | friend class ASTContext; |
3585 | | |
3586 | | /// The element type of the matrix. |
3587 | | QualType ElementType; |
3588 | | |
3589 | | MatrixType(QualType ElementTy, QualType CanonElementTy); |
3590 | | |
3591 | | MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy, |
3592 | | const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr); |
3593 | | |
3594 | | public: |
3595 | | /// Returns type of the elements being stored in the matrix |
3596 | 5.81k | QualType getElementType() const { return ElementType; } |
3597 | | |
3598 | | /// Valid elements types are the following: |
3599 | | /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types |
3600 | | /// and _Bool |
3601 | | /// * the standard floating types float or double |
3602 | | /// * a half-precision floating point type, if one is supported on the target |
3603 | 1.40k | static bool isValidElementType(QualType T) { |
3604 | 1.40k | return T->isDependentType() || |
3605 | 1.40k | (1.39k T->isRealType()1.39k && !T->isBooleanType()1.37k && !T->isEnumeralType()1.37k ); |
3606 | 1.40k | } |
3607 | | |
3608 | 4.76k | bool isSugared() const { return false; } |
3609 | 0 | QualType desugar() const { return QualType(this, 0); } |
3610 | | |
3611 | 38.0M | static bool classof(const Type *T) { |
3612 | 38.0M | return T->getTypeClass() == ConstantMatrix || |
3613 | 38.0M | T->getTypeClass() == DependentSizedMatrix38.0M ; |
3614 | 38.0M | } |
3615 | | }; |
3616 | | |
3617 | | /// Represents a concrete matrix type with constant number of rows and columns |
3618 | | class ConstantMatrixType final : public MatrixType { |
3619 | | protected: |
3620 | | friend class ASTContext; |
3621 | | |
3622 | | /// Number of rows and columns. |
3623 | | unsigned NumRows; |
3624 | | unsigned NumColumns; |
3625 | | |
3626 | | static constexpr unsigned MaxElementsPerDimension = (1 << 20) - 1; |
3627 | | |
3628 | | ConstantMatrixType(QualType MatrixElementType, unsigned NRows, |
3629 | | unsigned NColumns, QualType CanonElementType); |
3630 | | |
3631 | | ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows, |
3632 | | unsigned NColumns, QualType CanonElementType); |
3633 | | |
3634 | | public: |
3635 | | /// Returns the number of rows in the matrix. |
3636 | 3.46k | unsigned getNumRows() const { return NumRows; } |
3637 | | |
3638 | | /// Returns the number of columns in the matrix. |
3639 | 3.36k | unsigned getNumColumns() const { return NumColumns; } |
3640 | | |
3641 | | /// Returns the number of elements required to embed the matrix into a vector. |
3642 | 30 | unsigned getNumElementsFlattened() const { |
3643 | 30 | return getNumRows() * getNumColumns(); |
3644 | 30 | } |
3645 | | |
3646 | | /// Returns true if \p NumElements is a valid matrix dimension. |
3647 | 2.16k | static constexpr bool isDimensionValid(size_t NumElements) { |
3648 | 2.16k | return NumElements > 0 && NumElements <= MaxElementsPerDimension; |
3649 | 2.16k | } |
3650 | | |
3651 | | /// Returns the maximum number of elements per dimension. |
3652 | 6 | static constexpr unsigned getMaxElementsPerDimension() { |
3653 | 6 | return MaxElementsPerDimension; |
3654 | 6 | } |
3655 | | |
3656 | 399 | void Profile(llvm::FoldingSetNodeID &ID) { |
3657 | 399 | Profile(ID, getElementType(), getNumRows(), getNumColumns(), |
3658 | 399 | getTypeClass()); |
3659 | 399 | } |
3660 | | |
3661 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, |
3662 | | unsigned NumRows, unsigned NumColumns, |
3663 | 1.08k | TypeClass TypeClass) { |
3664 | 1.08k | ID.AddPointer(ElementType.getAsOpaquePtr()); |
3665 | 1.08k | ID.AddInteger(NumRows); |
3666 | 1.08k | ID.AddInteger(NumColumns); |
3667 | 1.08k | ID.AddInteger(TypeClass); |
3668 | 1.08k | } |
3669 | | |
3670 | 13.1M | static bool classof(const Type *T) { |
3671 | 13.1M | return T->getTypeClass() == ConstantMatrix; |
3672 | 13.1M | } |
3673 | | }; |
3674 | | |
3675 | | /// Represents a matrix type where the type and the number of rows and columns |
3676 | | /// is dependent on a template. |
3677 | | class DependentSizedMatrixType final : public MatrixType { |
3678 | | friend class ASTContext; |
3679 | | |
3680 | | const ASTContext &Context; |
3681 | | Expr *RowExpr; |
3682 | | Expr *ColumnExpr; |
3683 | | |
3684 | | SourceLocation loc; |
3685 | | |
3686 | | DependentSizedMatrixType(const ASTContext &Context, QualType ElementType, |
3687 | | QualType CanonicalType, Expr *RowExpr, |
3688 | | Expr *ColumnExpr, SourceLocation loc); |
3689 | | |
3690 | | public: |
3691 | 518 | Expr *getRowExpr() const { return RowExpr; } |
3692 | 445 | Expr *getColumnExpr() const { return ColumnExpr; } |
3693 | 237 | SourceLocation getAttributeLoc() const { return loc; } |
3694 | | |
3695 | 4.11k | static bool classof(const Type *T) { |
3696 | 4.11k | return T->getTypeClass() == DependentSizedMatrix; |
3697 | 4.11k | } |
3698 | | |
3699 | 31 | void Profile(llvm::FoldingSetNodeID &ID) { |
3700 | 31 | Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr()); |
3701 | 31 | } |
3702 | | |
3703 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
3704 | | QualType ElementType, Expr *RowExpr, Expr *ColumnExpr); |
3705 | | }; |
3706 | | |
3707 | | /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base |
3708 | | /// class of FunctionNoProtoType and FunctionProtoType. |
3709 | | class FunctionType : public Type { |
3710 | | // The type returned by the function. |
3711 | | QualType ResultType; |
3712 | | |
3713 | | public: |
3714 | | /// Interesting information about a specific parameter that can't simply |
3715 | | /// be reflected in parameter's type. This is only used by FunctionProtoType |
3716 | | /// but is in FunctionType to make this class available during the |
3717 | | /// specification of the bases of FunctionProtoType. |
3718 | | /// |
3719 | | /// It makes sense to model language features this way when there's some |
3720 | | /// sort of parameter-specific override (such as an attribute) that |
3721 | | /// affects how the function is called. For example, the ARC ns_consumed |
3722 | | /// attribute changes whether a parameter is passed at +0 (the default) |
3723 | | /// or +1 (ns_consumed). This must be reflected in the function type, |
3724 | | /// but isn't really a change to the parameter type. |
3725 | | /// |
3726 | | /// One serious disadvantage of modelling language features this way is |
3727 | | /// that they generally do not work with language features that attempt |
3728 | | /// to destructure types. For example, template argument deduction will |
3729 | | /// not be able to match a parameter declared as |
3730 | | /// T (*)(U) |
3731 | | /// against an argument of type |
3732 | | /// void (*)(__attribute__((ns_consumed)) id) |
3733 | | /// because the substitution of T=void, U=id into the former will |
3734 | | /// not produce the latter. |
3735 | | class ExtParameterInfo { |
3736 | | enum { |
3737 | | ABIMask = 0x0F, |
3738 | | IsConsumed = 0x10, |
3739 | | HasPassObjSize = 0x20, |
3740 | | IsNoEscape = 0x40, |
3741 | | }; |
3742 | | unsigned char Data = 0; |
3743 | | |
3744 | | public: |
3745 | 94.5M | ExtParameterInfo() = default; |
3746 | | |
3747 | | /// Return the ABI treatment of this parameter. |
3748 | 2.19M | ParameterABI getABI() const { return ParameterABI(Data & ABIMask); } |
3749 | 324 | ExtParameterInfo withABI(ParameterABI kind) const { |
3750 | 324 | ExtParameterInfo copy = *this; |
3751 | 324 | copy.Data = (copy.Data & ~ABIMask) | unsigned(kind); |
3752 | 324 | return copy; |
3753 | 324 | } |
3754 | | |
3755 | | /// Is this parameter considered "consumed" by Objective-C ARC? |
3756 | | /// Consumed parameters must have retainable object type. |
3757 | 37.4k | bool isConsumed() const { return (Data & IsConsumed); } |
3758 | 78 | ExtParameterInfo withIsConsumed(bool consumed) const { |
3759 | 78 | ExtParameterInfo copy = *this; |
3760 | 78 | if (consumed) |
3761 | 78 | copy.Data |= IsConsumed; |
3762 | 0 | else |
3763 | 0 | copy.Data &= ~IsConsumed; |
3764 | 78 | return copy; |
3765 | 78 | } |
3766 | | |
3767 | 3.51k | bool hasPassObjectSize() const { return Data & HasPassObjSize; } |
3768 | 128 | ExtParameterInfo withHasPassObjectSize() const { |
3769 | 128 | ExtParameterInfo Copy = *this; |
3770 | 128 | Copy.Data |= HasPassObjSize; |
3771 | 128 | return Copy; |
3772 | 128 | } |
3773 | | |
3774 | 8.63M | bool isNoEscape() const { return Data & IsNoEscape; } |
3775 | 18.2k | ExtParameterInfo withIsNoEscape(bool NoEscape) const { |
3776 | 18.2k | ExtParameterInfo Copy = *this; |
3777 | 18.2k | if (NoEscape) |
3778 | 8.34k | Copy.Data |= IsNoEscape; |
3779 | 9.87k | else |
3780 | 9.87k | Copy.Data &= ~IsNoEscape; |
3781 | 18.2k | return Copy; |
3782 | 18.2k | } |
3783 | | |
3784 | 270k | unsigned char getOpaqueValue() const { return Data; } |
3785 | 4 | static ExtParameterInfo getFromOpaqueValue(unsigned char data) { |
3786 | 4 | ExtParameterInfo result; |
3787 | 4 | result.Data = data; |
3788 | 4 | return result; |
3789 | 4 | } |
3790 | | |
3791 | 84 | friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) { |
3792 | 84 | return lhs.Data == rhs.Data; |
3793 | 84 | } |
3794 | | |
3795 | 196 | friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) { |
3796 | 196 | return lhs.Data != rhs.Data; |
3797 | 196 | } |
3798 | | }; |
3799 | | |
3800 | | /// A class which abstracts out some details necessary for |
3801 | | /// making a call. |
3802 | | /// |
3803 | | /// It is not actually used directly for storing this information in |
3804 | | /// a FunctionType, although FunctionType does currently use the |
3805 | | /// same bit-pattern. |
3806 | | /// |
3807 | | // If you add a field (say Foo), other than the obvious places (both, |
3808 | | // constructors, compile failures), what you need to update is |
3809 | | // * Operator== |
3810 | | // * getFoo |
3811 | | // * withFoo |
3812 | | // * functionType. Add Foo, getFoo. |
3813 | | // * ASTContext::getFooType |
3814 | | // * ASTContext::mergeFunctionTypes |
3815 | | // * FunctionNoProtoType::Profile |
3816 | | // * FunctionProtoType::Profile |
3817 | | // * TypePrinter::PrintFunctionProto |
3818 | | // * AST read and write |
3819 | | // * Codegen |
3820 | | class ExtInfo { |
3821 | | friend class FunctionType; |
3822 | | |
3823 | | // Feel free to rearrange or add bits, but if you go over 16, you'll need to |
3824 | | // adjust the Bits field below, and if you add bits, you'll need to adjust |
3825 | | // Type::FunctionTypeBitfields::ExtInfo as well. |
3826 | | |
3827 | | // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall| |
3828 | | // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | 12 | |
3829 | | // |
3830 | | // regparm is either 0 (no regparm attribute) or the regparm value+1. |
3831 | | enum { CallConvMask = 0x1F }; |
3832 | | enum { NoReturnMask = 0x20 }; |
3833 | | enum { ProducesResultMask = 0x40 }; |
3834 | | enum { NoCallerSavedRegsMask = 0x80 }; |
3835 | | enum { |
3836 | | RegParmMask = 0x700, |
3837 | | RegParmOffset = 8 |
3838 | | }; |
3839 | | enum { NoCfCheckMask = 0x800 }; |
3840 | | enum { CmseNSCallMask = 0x1000 }; |
3841 | | uint16_t Bits = CC_C; |
3842 | | |
3843 | 132M | ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} |
3844 | | |
3845 | | public: |
3846 | | // Constructor with no defaults. Use this when you know that you |
3847 | | // have all the elements (when reading an AST file for example). |
3848 | | ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, |
3849 | | bool producesResult, bool noCallerSavedRegs, bool NoCfCheck, |
3850 | 503k | bool cmseNSCall) { |
3851 | 503k | assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); |
3852 | 503k | Bits = ((unsigned)cc) | (noReturn ? NoReturnMask321 : 0503k ) | |
3853 | 503k | (producesResult ? ProducesResultMask0 : 0) | |
3854 | 503k | (noCallerSavedRegs ? NoCallerSavedRegsMask0 : 0) | |
3855 | 503k | (hasRegParm ? ((regParm + 1) << RegParmOffset)0 : 0) | |
3856 | 503k | (NoCfCheck ? NoCfCheckMask0 : 0) | |
3857 | 503k | (cmseNSCall ? CmseNSCallMask1 : 0503k ); |
3858 | 503k | } |
3859 | | |
3860 | | // Constructor with all defaults. Use when for example creating a |
3861 | | // function known to use defaults. |
3862 | 111M | ExtInfo() = default; |
3863 | | |
3864 | | // Constructor with just the calling convention, which is an important part |
3865 | | // of the canonical type. |
3866 | 36.6M | ExtInfo(CallingConv CC) : Bits(CC) {} |
3867 | | |
3868 | 11.3M | bool getNoReturn() const { return Bits & NoReturnMask; } |
3869 | 4.54M | bool getProducesResult() const { return Bits & ProducesResultMask; } |
3870 | 37.8M | bool getCmseNSCall() const { return Bits & CmseNSCallMask; } |
3871 | 3.01M | bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; } |
3872 | 2.22M | bool getNoCfCheck() const { return Bits & NoCfCheckMask; } |
3873 | 2.96M | bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; } |
3874 | | |
3875 | 3.01M | unsigned getRegParm() const { |
3876 | 3.01M | unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset; |
3877 | 3.01M | if (RegParm > 0) |
3878 | 208 | --RegParm; |
3879 | 3.01M | return RegParm; |
3880 | 3.01M | } |
3881 | | |
3882 | 11.2M | CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } |
3883 | | |
3884 | 1.68M | bool operator==(ExtInfo Other) const { |
3885 | 1.68M | return Bits == Other.Bits; |
3886 | 1.68M | } |
3887 | 17 | bool operator!=(ExtInfo Other) const { |
3888 | 17 | return Bits != Other.Bits; |
3889 | 17 | } |
3890 | | |
3891 | | // Note that we don't have setters. That is by design, use |
3892 | | // the following with methods instead of mutating these objects. |
3893 | | |
3894 | 21.5k | ExtInfo withNoReturn(bool noReturn) const { |
3895 | 21.5k | if (noReturn) |
3896 | 13.1k | return ExtInfo(Bits | NoReturnMask); |
3897 | 8.37k | else |
3898 | 8.37k | return ExtInfo(Bits & ~NoReturnMask); |
3899 | 21.5k | } |
3900 | | |
3901 | 533 | ExtInfo withProducesResult(bool producesResult) const { |
3902 | 533 | if (producesResult) |
3903 | 533 | return ExtInfo(Bits | ProducesResultMask); |
3904 | 0 | else |
3905 | 0 | return ExtInfo(Bits & ~ProducesResultMask); |
3906 | 533 | } |
3907 | | |
3908 | 77 | ExtInfo withCmseNSCall(bool cmseNSCall) const { |
3909 | 77 | if (cmseNSCall) |
3910 | 77 | return ExtInfo(Bits | CmseNSCallMask); |
3911 | 0 | else |
3912 | 0 | return ExtInfo(Bits & ~CmseNSCallMask); |
3913 | 77 | } |
3914 | | |
3915 | 24 | ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const { |
3916 | 24 | if (noCallerSavedRegs) |
3917 | 24 | return ExtInfo(Bits | NoCallerSavedRegsMask); |
3918 | 0 | else |
3919 | 0 | return ExtInfo(Bits & ~NoCallerSavedRegsMask); |
3920 | 24 | } |
3921 | | |
3922 | 6 | ExtInfo withNoCfCheck(bool noCfCheck) const { |
3923 | 6 | if (noCfCheck) |
3924 | 6 | return ExtInfo(Bits | NoCfCheckMask); |
3925 | 0 | else |
3926 | 0 | return ExtInfo(Bits & ~NoCfCheckMask); |
3927 | 6 | } |
3928 | | |
3929 | 85 | ExtInfo withRegParm(unsigned RegParm) const { |
3930 | 85 | assert(RegParm < 7 && "Invalid regparm value"); |
3931 | 85 | return ExtInfo((Bits & ~RegParmMask) | |
3932 | 85 | ((RegParm + 1) << RegParmOffset)); |
3933 | 85 | } |
3934 | | |
3935 | 602k | ExtInfo withCallingConv(CallingConv cc) const { |
3936 | 602k | return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc); |
3937 | 602k | } |
3938 | | |
3939 | 118M | void Profile(llvm::FoldingSetNodeID &ID) const { |
3940 | 118M | ID.AddInteger(Bits); |
3941 | 118M | } |
3942 | | }; |
3943 | | |
3944 | | /// A simple holder for a QualType representing a type in an |
3945 | | /// exception specification. Unfortunately needed by FunctionProtoType |
3946 | | /// because TrailingObjects cannot handle repeated types. |
3947 | | struct ExceptionType { QualType Type; }; |
3948 | | |
3949 | | /// A simple holder for various uncommon bits which do not fit in |
3950 | | /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the |
3951 | | /// alignment of subsequent objects in TrailingObjects. |
3952 | | struct alignas(void *) FunctionTypeExtraBitfields { |
3953 | | /// The number of types in the exception specification. |
3954 | | /// A whole unsigned is not needed here and according to |
3955 | | /// [implimits] 8 bits would be enough here. |
3956 | | unsigned NumExceptionType = 0; |
3957 | | }; |
3958 | | |
3959 | | protected: |
3960 | | FunctionType(TypeClass tc, QualType res, QualType Canonical, |
3961 | | TypeDependence Dependence, ExtInfo Info) |
3962 | 17.5M | : Type(tc, Canonical, Dependence), ResultType(res) { |
3963 | 17.5M | FunctionTypeBits.ExtInfo = Info.Bits; |
3964 | 17.5M | } |
3965 | | |
3966 | 90.8M | Qualifiers getFastTypeQuals() const { |
3967 | 90.8M | if (isFunctionProtoType()) |
3968 | 90.8M | return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals); |
3969 | | |
3970 | 12 | return Qualifiers(); |
3971 | 90.8M | } |
3972 | | |
3973 | | public: |
3974 | 421M | QualType getReturnType() const { return ResultType; } |
3975 | | |
3976 | 159 | bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } |
3977 | 12 | unsigned getRegParmType() const { return getExtInfo().getRegParm(); } |
3978 | | |
3979 | | /// Determine whether this function type includes the GNU noreturn |
3980 | | /// attribute. The C++11 [[noreturn]] attribute does not affect the function |
3981 | | /// type. |
3982 | 7.70M | bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } |
3983 | | |
3984 | 36.0M | bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); } |
3985 | 6.80M | CallingConv getCallConv() const { return getExtInfo().getCC(); } |
3986 | 132M | ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } |
3987 | | |
3988 | | static_assert((~Qualifiers::FastMask & Qualifiers::CVRMask) == 0, |
3989 | | "Const, volatile and restrict are assumed to be a subset of " |
3990 | | "the fast qualifiers."); |
3991 | | |
3992 | 929k | bool isConst() const { return getFastTypeQuals().hasConst(); } |
3993 | 824k | bool isVolatile() const { return getFastTypeQuals().hasVolatile(); } |
3994 | 28.5k | bool isRestrict() const { return getFastTypeQuals().hasRestrict(); } |
3995 | | |
3996 | | /// Determine the type of an expression that calls a function of |
3997 | | /// this type. |
3998 | 6.59M | QualType getCallResultType(const ASTContext &Context) const { |
3999 | 6.59M | return getReturnType().getNonLValueExprType(Context); |
4000 | 6.59M | } |
4001 | | |
4002 | | static StringRef getNameForCallConv(CallingConv CC); |
4003 | | |
4004 | 1.48G | static bool classof(const Type *T) { |
4005 | 1.48G | return T->getTypeClass() == FunctionNoProto || |
4006 | 1.48G | T->getTypeClass() == FunctionProto1.48G ; |
4007 | 1.48G | } |
4008 | | }; |
4009 | | |
4010 | | /// Represents a K&R-style 'int foo()' function, which has |
4011 | | /// no information available about its arguments. |
4012 | | class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { |
4013 | | friend class ASTContext; // ASTContext creates these. |
4014 | | |
4015 | | FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) |
4016 | | : FunctionType(FunctionNoProto, Result, Canonical, |
4017 | | Result->getDependence() & |
4018 | | ~(TypeDependence::DependentInstantiation | |
4019 | | TypeDependence::UnexpandedPack), |
4020 | 8.59k | Info) {} |
4021 | | |
4022 | | public: |
4023 | | // No additional state past what FunctionType provides. |
4024 | | |
4025 | 2.50k | bool isSugared() const { return false; } |
4026 | 0 | QualType desugar() const { return QualType(this, 0); } |
4027 | | |
4028 | 227k | void Profile(llvm::FoldingSetNodeID &ID) { |
4029 | 227k | Profile(ID, getReturnType(), getExtInfo()); |
4030 | 227k | } |
4031 | | |
4032 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, |
4033 | 462k | ExtInfo Info) { |
4034 | 462k | Info.Profile(ID); |
4035 | 462k | ID.AddPointer(ResultType.getAsOpaquePtr()); |
4036 | 462k | } |
4037 | | |
4038 | 378M | static bool classof(const Type *T) { |
4039 | 378M | return T->getTypeClass() == FunctionNoProto; |
4040 | 378M | } |
4041 | | }; |
4042 | | |
4043 | | /// Represents a prototype with parameter type info, e.g. |
4044 | | /// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no |
4045 | | /// parameters, not as having a single void parameter. Such a type can have |
4046 | | /// an exception specification, but this specification is not part of the |
4047 | | /// canonical type. FunctionProtoType has several trailing objects, some of |
4048 | | /// which optional. For more information about the trailing objects see |
4049 | | /// the first comment inside FunctionProtoType. |
4050 | | class FunctionProtoType final |
4051 | | : public FunctionType, |
4052 | | public llvm::FoldingSetNode, |
4053 | | private llvm::TrailingObjects< |
4054 | | FunctionProtoType, QualType, SourceLocation, |
4055 | | FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType, |
4056 | | Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> { |
4057 | | friend class ASTContext; // ASTContext creates these. |
4058 | | friend TrailingObjects; |
4059 | | |
4060 | | // FunctionProtoType is followed by several trailing objects, some of |
4061 | | // which optional. They are in order: |
4062 | | // |
4063 | | // * An array of getNumParams() QualType holding the parameter types. |
4064 | | // Always present. Note that for the vast majority of FunctionProtoType, |
4065 | | // these will be the only trailing objects. |
4066 | | // |
4067 | | // * Optionally if the function is variadic, the SourceLocation of the |
4068 | | // ellipsis. |
4069 | | // |
4070 | | // * Optionally if some extra data is stored in FunctionTypeExtraBitfields |
4071 | | // (see FunctionTypeExtraBitfields and FunctionTypeBitfields): |
4072 | | // a single FunctionTypeExtraBitfields. Present if and only if |
4073 | | // hasExtraBitfields() is true. |
4074 | | // |
4075 | | // * Optionally exactly one of: |
4076 | | // * an array of getNumExceptions() ExceptionType, |
4077 | | // * a single Expr *, |
4078 | | // * a pair of FunctionDecl *, |
4079 | | // * a single FunctionDecl * |
4080 | | // used to store information about the various types of exception |
4081 | | // specification. See getExceptionSpecSize for the details. |
4082 | | // |
4083 | | // * Optionally an array of getNumParams() ExtParameterInfo holding |
4084 | | // an ExtParameterInfo for each of the parameters. Present if and |
4085 | | // only if hasExtParameterInfos() is true. |
4086 | | // |
4087 | | // * Optionally a Qualifiers object to represent extra qualifiers that can't |
4088 | | // be represented by FunctionTypeBitfields.FastTypeQuals. Present if and only |
4089 | | // if hasExtQualifiers() is true. |
4090 | | // |
4091 | | // The optional FunctionTypeExtraBitfields has to be before the data |
4092 | | // related to the exception specification since it contains the number |
4093 | | // of exception types. |
4094 | | // |
4095 | | // We put the ExtParameterInfos last. If all were equal, it would make |
4096 | | // more sense to put these before the exception specification, because |
4097 | | // it's much easier to skip past them compared to the elaborate switch |
4098 | | // required to skip the exception specification. However, all is not |
4099 | | // equal; ExtParameterInfos are used to model very uncommon features, |
4100 | | // and it's better not to burden the more common paths. |
4101 | | |
4102 | | public: |
4103 | | /// Holds information about the various types of exception specification. |
4104 | | /// ExceptionSpecInfo is not stored as such in FunctionProtoType but is |
4105 | | /// used to group together the various bits of information about the |
4106 | | /// exception specification. |
4107 | | struct ExceptionSpecInfo { |
4108 | | /// The kind of exception specification this is. |
4109 | | ExceptionSpecificationType Type = EST_None; |
4110 | | |
4111 | | /// Explicitly-specified list of exception types. |
4112 | | ArrayRef<QualType> Exceptions; |
4113 | | |
4114 | | /// Noexcept expression, if this is a computed noexcept specification. |
4115 | | Expr *NoexceptExpr = nullptr; |
4116 | | |
4117 | | /// The function whose exception specification this is, for |
4118 | | /// EST_Unevaluated and EST_Uninstantiated. |
4119 | | FunctionDecl *SourceDecl = nullptr; |
4120 | | |
4121 | | /// The function template whose exception specification this is instantiated |
4122 | | /// from, for EST_Uninstantiated. |
4123 | | FunctionDecl *SourceTemplate = nullptr; |
4124 | | |
4125 | 188M | ExceptionSpecInfo() = default; |
4126 | | |
4127 | 95.8k | ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {} |
4128 | | }; |
4129 | | |
4130 | | /// Extra information about a function prototype. ExtProtoInfo is not |
4131 | | /// stored as such in FunctionProtoType but is used to group together |
4132 | | /// the various bits of extra information about a function prototype. |
4133 | | struct ExtProtoInfo { |
4134 | | FunctionType::ExtInfo ExtInfo; |
4135 | | bool Variadic : 1; |
4136 | | bool HasTrailingReturn : 1; |
4137 | | Qualifiers TypeQuals; |
4138 | | RefQualifierKind RefQualifier = RQ_None; |
4139 | | ExceptionSpecInfo ExceptionSpec; |
4140 | | const ExtParameterInfo *ExtParameterInfos = nullptr; |
4141 | | SourceLocation EllipsisLoc; |
4142 | | |
4143 | 111M | ExtProtoInfo() : Variadic(false), HasTrailingReturn(false) {} |
4144 | | |
4145 | | ExtProtoInfo(CallingConv CC) |
4146 | 554k | : ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {} |
4147 | | |
4148 | 919k | ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) { |
4149 | 919k | ExtProtoInfo Result(*this); |
4150 | 919k | Result.ExceptionSpec = ESI; |
4151 | 919k | return Result; |
4152 | 919k | } |
4153 | | |
4154 | 35.0M | bool requiresFunctionProtoTypeExtraBitfields() const { |
4155 | 35.0M | return ExceptionSpec.Type == EST_Dynamic; |
4156 | 35.0M | } |
4157 | | }; |
4158 | | |
4159 | | private: |
4160 | 7.55M | unsigned numTrailingObjects(OverloadToken<QualType>) const { |
4161 | 7.55M | return getNumParams(); |
4162 | 7.55M | } |
4163 | | |
4164 | 6.84M | unsigned numTrailingObjects(OverloadToken<SourceLocation>) const { |
4165 | 6.84M | return isVariadic(); |
4166 | 6.84M | } |
4167 | | |
4168 | 6.84M | unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const { |
4169 | 6.84M | return hasExtraBitfields(); |
4170 | 6.84M | } |
4171 | | |
4172 | 4.87M | unsigned numTrailingObjects(OverloadToken<ExceptionType>) const { |
4173 | 4.87M | return getExceptionSpecSize().NumExceptionType; |
4174 | 4.87M | } |
4175 | | |
4176 | 3.18M | unsigned numTrailingObjects(OverloadToken<Expr *>) const { |
4177 | 3.18M | return getExceptionSpecSize().NumExprPtr; |
4178 | 3.18M | } |
4179 | | |
4180 | 67.9k | unsigned numTrailingObjects(OverloadToken<FunctionDecl *>) const { |
4181 | 67.9k | return getExceptionSpecSize().NumFunctionDeclPtr; |
4182 | 67.9k | } |
4183 | | |
4184 | 3.65k | unsigned numTrailingObjects(OverloadToken<ExtParameterInfo>) const { |
4185 | 3.65k | return hasExtParameterInfos() ? getNumParams()0 : 0; |
4186 | 3.65k | } |
4187 | | |
4188 | | /// Determine whether there are any argument types that |
4189 | | /// contain an unexpanded parameter pack. |
4190 | | static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, |
4191 | 0 | unsigned numArgs) { |
4192 | 0 | for (unsigned Idx = 0; Idx < numArgs; ++Idx) |
4193 | 0 | if (ArgArray[Idx]->containsUnexpandedParameterPack()) |
4194 | 0 | return true; |
4195 | 0 |
|
4196 | 0 | return false; |
4197 | 0 | } |
4198 | | |
4199 | | FunctionProtoType(QualType result, ArrayRef<QualType> params, |
4200 | | QualType canonical, const ExtProtoInfo &epi); |
4201 | | |
4202 | | /// This struct is returned by getExceptionSpecSize and is used to |
4203 | | /// translate an ExceptionSpecificationType to the number and kind |
4204 | | /// of trailing objects related to the exception specification. |
4205 | | struct ExceptionSpecSizeHolder { |
4206 | | unsigned NumExceptionType; |
4207 | | unsigned NumExprPtr; |
4208 | | unsigned NumFunctionDeclPtr; |
4209 | | }; |
4210 | | |
4211 | | /// Return the number and kind of trailing objects |
4212 | | /// related to the exception specification. |
4213 | | static ExceptionSpecSizeHolder |
4214 | 25.6M | getExceptionSpecSize(ExceptionSpecificationType EST, unsigned NumExceptions) { |
4215 | 25.6M | switch (EST) { |
4216 | 15.1M | case EST_None: |
4217 | 15.1M | case EST_DynamicNone: |
4218 | 15.1M | case EST_MSAny: |
4219 | 16.5M | case EST_BasicNoexcept: |
4220 | 16.5M | case EST_Unparsed: |
4221 | 16.5M | case EST_NoThrow: |
4222 | 16.5M | return {0, 0, 0}; |
4223 | | |
4224 | 646 | case EST_Dynamic: |
4225 | 646 | return {NumExceptions, 0, 0}; |
4226 | | |
4227 | 1.85M | case EST_DependentNoexcept: |
4228 | 1.87M | case EST_NoexceptFalse: |
4229 | 1.99M | case EST_NoexceptTrue: |
4230 | 1.99M | return {0, 1, 0}; |
4231 | | |
4232 | 1.57M | case EST_Uninstantiated: |
4233 | 1.57M | return {0, 0, 2}; |
4234 | | |
4235 | 5.49M | case EST_Unevaluated: |
4236 | 5.49M | return {0, 0, 1}; |
4237 | 25.6M | } |
4238 | 0 | llvm_unreachable("bad exception specification kind"); |
4239 | 0 | } |
4240 | | |
4241 | | /// Return the number and kind of trailing objects |
4242 | | /// related to the exception specification. |
4243 | 8.12M | ExceptionSpecSizeHolder getExceptionSpecSize() const { |
4244 | 8.12M | return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions()); |
4245 | 8.12M | } |
4246 | | |
4247 | | /// Whether the trailing FunctionTypeExtraBitfields is present. |
4248 | 6.84M | bool hasExtraBitfields() const { |
4249 | 6.84M | assert((getExceptionSpecType() != EST_Dynamic || |
4250 | 6.84M | FunctionTypeBits.HasExtraBitfields) && |
4251 | 6.84M | "ExtraBitfields are required for given ExceptionSpecType"); |
4252 | 6.84M | return FunctionTypeBits.HasExtraBitfields; |
4253 | | |
4254 | 6.84M | } |
4255 | | |
4256 | 89.0M | bool hasExtQualifiers() const { |
4257 | 89.0M | return FunctionTypeBits.HasExtQuals; |
4258 | 89.0M | } |
4259 | | |
4260 | | public: |
4261 | 1.37G | unsigned getNumParams() const { return FunctionTypeBits.NumParams; } |
4262 | | |
4263 | 271M | QualType getParamType(unsigned i) const { |
4264 | 271M | assert(i < getNumParams() && "invalid parameter index"); |
4265 | 271M | return param_type_begin()[i]; |
4266 | 271M | } |
4267 | | |
4268 | 2.96M | ArrayRef<QualType> getParamTypes() const { |
4269 | 2.96M | return llvm::ArrayRef(param_type_begin(), param_type_end()); |
4270 | 2.96M | } |
4271 | | |
4272 | 73.4M | ExtProtoInfo getExtProtoInfo() const { |
4273 | 73.4M | ExtProtoInfo EPI; |
4274 | 73.4M | EPI.ExtInfo = getExtInfo(); |
4275 | 73.4M | EPI.Variadic = isVariadic(); |
4276 | 73.4M | EPI.EllipsisLoc = getEllipsisLoc(); |
4277 | 73.4M | EPI.HasTrailingReturn = hasTrailingReturn(); |
4278 | 73.4M | EPI.ExceptionSpec = getExceptionSpecInfo(); |
4279 | 73.4M | EPI.TypeQuals = getMethodQuals(); |
4280 | 73.4M | EPI.RefQualifier = getRefQualifier(); |
4281 | 73.4M | EPI.ExtParameterInfos = getExtParameterInfosOrNull(); |
4282 | 73.4M | return EPI; |
4283 | 73.4M | } |
4284 | | |
4285 | | /// Get the kind of exception specification on this function. |
4286 | 385M | ExceptionSpecificationType getExceptionSpecType() const { |
4287 | 385M | return static_cast<ExceptionSpecificationType>( |
4288 | 385M | FunctionTypeBits.ExceptionSpecType); |
4289 | 385M | } |
4290 | | |
4291 | | /// Return whether this function has any kind of exception spec. |
4292 | 165M | bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; } |
4293 | | |
4294 | | /// Return whether this function has a dynamic (throw) exception spec. |
4295 | 53.9k | bool hasDynamicExceptionSpec() const { |
4296 | 53.9k | return isDynamicExceptionSpec(getExceptionSpecType()); |
4297 | 53.9k | } |
4298 | | |
4299 | | /// Return whether this function has a noexcept exception spec. |
4300 | 0 | bool hasNoexceptExceptionSpec() const { |
4301 | 0 | return isNoexceptExceptionSpec(getExceptionSpecType()); |
4302 | 0 | } |
4303 | | |
4304 | | /// Return whether this function has a dependent exception spec. |
4305 | | bool hasDependentExceptionSpec() const; |
4306 | | |
4307 | | /// Return whether this function has an instantiation-dependent exception |
4308 | | /// spec. |
4309 | | bool hasInstantiationDependentExceptionSpec() const; |
4310 | | |
4311 | | /// Return all the available information about this type's exception spec. |
4312 | 73.5M | ExceptionSpecInfo getExceptionSpecInfo() const { |
4313 | 73.5M | ExceptionSpecInfo Result; |
4314 | 73.5M | Result.Type = getExceptionSpecType(); |
4315 | 73.5M | if (Result.Type == EST_Dynamic) { |
4316 | 1.08k | Result.Exceptions = exceptions(); |
4317 | 73.5M | } else if (isComputedNoexcept(Result.Type)) { |
4318 | 1.33M | Result.NoexceptExpr = getNoexceptExpr(); |
4319 | 72.2M | } else if (Result.Type == EST_Uninstantiated) { |
4320 | 274k | Result.SourceDecl = getExceptionSpecDecl(); |
4321 | 274k | Result.SourceTemplate = getExceptionSpecTemplate(); |
4322 | 71.9M | } else if (Result.Type == EST_Unevaluated) { |
4323 | 1.42M | Result.SourceDecl = getExceptionSpecDecl(); |
4324 | 1.42M | } |
4325 | 73.5M | return Result; |
4326 | 73.5M | } |
4327 | | |
4328 | | /// Return the number of types in the exception specification. |
4329 | 9.10M | unsigned getNumExceptions() const { |
4330 | 9.10M | return getExceptionSpecType() == EST_Dynamic |
4331 | 9.10M | ? getTrailingObjects<FunctionTypeExtraBitfields>() |
4332 | 3.49k | ->NumExceptionType |
4333 | 9.10M | : 09.10M ; |
4334 | 9.10M | } |
4335 | | |
4336 | | /// Return the ith exception type, where 0 <= i < getNumExceptions(). |
4337 | 855 | QualType getExceptionType(unsigned i) const { |
4338 | 855 | assert(i < getNumExceptions() && "Invalid exception number!"); |
4339 | 855 | return exception_begin()[i]; |
4340 | 855 | } |
4341 | | |
4342 | | /// Return the expression inside noexcept(expression), or a null pointer |
4343 | | /// if there is none (because the exception spec is not of this form). |
4344 | 1.91M | Expr *getNoexceptExpr() const { |
4345 | 1.91M | if (!isComputedNoexcept(getExceptionSpecType())) |
4346 | 539k | return nullptr; |
4347 | 1.37M | return *getTrailingObjects<Expr *>(); |
4348 | 1.91M | } |
4349 | | |
4350 | | /// If this function type has an exception specification which hasn't |
4351 | | /// been determined yet (either because it has not been evaluated or because |
4352 | | /// it has not been instantiated), this is the function whose exception |
4353 | | /// specification is represented by this type. |
4354 | 1.99M | FunctionDecl *getExceptionSpecDecl() const { |
4355 | 1.99M | if (getExceptionSpecType() != EST_Uninstantiated && |
4356 | 1.99M | getExceptionSpecType() != EST_Unevaluated1.70M ) |
4357 | 0 | return nullptr; |
4358 | 1.99M | return getTrailingObjects<FunctionDecl *>()[0]; |
4359 | 1.99M | } |
4360 | | |
4361 | | /// If this function type has an uninstantiated exception |
4362 | | /// specification, this is the function whose exception specification |
4363 | | /// should be instantiated to find the exception specification for |
4364 | | /// this type. |
4365 | 286k | FunctionDecl *getExceptionSpecTemplate() const { |
4366 | 286k | if (getExceptionSpecType() != EST_Uninstantiated) |
4367 | 0 | return nullptr; |
4368 | 286k | return getTrailingObjects<FunctionDecl *>()[1]; |
4369 | 286k | } |
4370 | | |
4371 | | /// Determine whether this function type has a non-throwing exception |
4372 | | /// specification. |
4373 | | CanThrowResult canThrow() const; |
4374 | | |
4375 | | /// Determine whether this function type has a non-throwing exception |
4376 | | /// specification. If this depends on template arguments, returns |
4377 | | /// \c ResultIfDependent. |
4378 | 1.15M | bool isNothrow(bool ResultIfDependent = false) const { |
4379 | 1.15M | return ResultIfDependent ? canThrow() != CT_Can1.97k : canThrow() == CT_Cannot1.15M ; |
4380 | 1.15M | } |
4381 | | |
4382 | | /// Whether this function prototype is variadic. |
4383 | 315M | bool isVariadic() const { return FunctionTypeBits.Variadic; } |
4384 | | |
4385 | 73.4M | SourceLocation getEllipsisLoc() const { |
4386 | 73.4M | return isVariadic() ? *getTrailingObjects<SourceLocation>()583k |
4387 | 73.4M | : SourceLocation()72.8M ; |
4388 | 73.4M | } |
4389 | | |
4390 | | /// Determines whether this function prototype contains a |
4391 | | /// parameter pack at the end. |
4392 | | /// |
4393 | | /// A function template whose last parameter is a parameter pack can be |
4394 | | /// called with an arbitrary number of arguments, much like a variadic |
4395 | | /// function. |
4396 | | bool isTemplateVariadic() const; |
4397 | | |
4398 | | /// Whether this function prototype has a trailing return type. |
4399 | 82.1M | bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; } |
4400 | | |
4401 | 89.0M | Qualifiers getMethodQuals() const { |
4402 | 89.0M | if (hasExtQualifiers()) |
4403 | 3.00k | return *getTrailingObjects<Qualifiers>(); |
4404 | 89.0M | else |
4405 | 89.0M | return getFastTypeQuals(); |
4406 | 89.0M | } |
4407 | | |
4408 | | /// Retrieve the ref-qualifier associated with this function type. |
4409 | 82.3M | RefQualifierKind getRefQualifier() const { |
4410 | 82.3M | return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier); |
4411 | 82.3M | } |
4412 | | |
4413 | | using param_type_iterator = const QualType *; |
4414 | | |
4415 | 17.8M | ArrayRef<QualType> param_types() const { |
4416 | 17.8M | return llvm::ArrayRef(param_type_begin(), param_type_end()); |
4417 | 17.8M | } |
4418 | | |
4419 | 384M | param_type_iterator param_type_begin() const { |
4420 | 384M | return getTrailingObjects<QualType>(); |
4421 | 384M | } |
4422 | | |
4423 | 22.3M | param_type_iterator param_type_end() const { |
4424 | 22.3M | return param_type_begin() + getNumParams(); |
4425 | 22.3M | } |
4426 | | |
4427 | | using exception_iterator = const QualType *; |
4428 | | |
4429 | 985k | ArrayRef<QualType> exceptions() const { |
4430 | 985k | return llvm::ArrayRef(exception_begin(), exception_end()); |
4431 | 985k | } |
4432 | | |
4433 | 1.97M | exception_iterator exception_begin() const { |
4434 | 1.97M | return reinterpret_cast<exception_iterator>( |
4435 | 1.97M | getTrailingObjects<ExceptionType>()); |
4436 | 1.97M | } |
4437 | | |
4438 | 985k | exception_iterator exception_end() const { |
4439 | 985k | return exception_begin() + getNumExceptions(); |
4440 | 985k | } |
4441 | | |
4442 | | /// Is there any interesting extra information for any of the parameters |
4443 | | /// of this function type? |
4444 | 86.3M | bool hasExtParameterInfos() const { |
4445 | 86.3M | return FunctionTypeBits.HasExtParameterInfos; |
4446 | 86.3M | } |
4447 | | |
4448 | 2.24k | ArrayRef<ExtParameterInfo> getExtParameterInfos() const { |
4449 | 2.24k | assert(hasExtParameterInfos()); |
4450 | 2.24k | return ArrayRef<ExtParameterInfo>(getTrailingObjects<ExtParameterInfo>(), |
4451 | 2.24k | getNumParams()); |
4452 | 2.24k | } |
4453 | | |
4454 | | /// Return a pointer to the beginning of the array of extra parameter |
4455 | | /// information, if present, or else null if none of the parameters |
4456 | | /// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos. |
4457 | 75.3M | const ExtParameterInfo *getExtParameterInfosOrNull() const { |
4458 | 75.3M | if (!hasExtParameterInfos()) |
4459 | 75.3M | return nullptr; |
4460 | 47.1k | return getTrailingObjects<ExtParameterInfo>(); |
4461 | 75.3M | } |
4462 | | |
4463 | 7.53M | ExtParameterInfo getExtParameterInfo(unsigned I) const { |
4464 | 7.53M | assert(I < getNumParams() && "parameter index out of range"); |
4465 | 7.53M | if (hasExtParameterInfos()) |
4466 | 1.52k | return getTrailingObjects<ExtParameterInfo>()[I]; |
4467 | 7.53M | return ExtParameterInfo(); |
4468 | 7.53M | } |
4469 | | |
4470 | 0 | ParameterABI getParameterABI(unsigned I) const { |
4471 | 0 | assert(I < getNumParams() && "parameter index out of range"); |
4472 | 0 | if (hasExtParameterInfos()) |
4473 | 0 | return getTrailingObjects<ExtParameterInfo>()[I].getABI(); |
4474 | 0 | return ParameterABI::Ordinary; |
4475 | 0 | } |
4476 | | |
4477 | 24.1k | bool isParamConsumed(unsigned I) const { |
4478 | 24.1k | assert(I < getNumParams() && "parameter index out of range"); |
4479 | 24.1k | if (hasExtParameterInfos()) |
4480 | 34 | return getTrailingObjects<ExtParameterInfo>()[I].isConsumed(); |
4481 | 24.1k | return false; |
4482 | 24.1k | } |
4483 | | |
4484 | 3.57M | bool isSugared() const { return false; } |
4485 | 145 | QualType desugar() const { return QualType(this, 0); } |
4486 | | |
4487 | | void printExceptionSpecification(raw_ostream &OS, |
4488 | | const PrintingPolicy &Policy) const; |
4489 | | |
4490 | 1.69G | static bool classof(const Type *T) { |
4491 | 1.69G | return T->getTypeClass() == FunctionProto; |
4492 | 1.69G | } |
4493 | | |
4494 | | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); |
4495 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, |
4496 | | param_type_iterator ArgTys, unsigned NumArgs, |
4497 | | const ExtProtoInfo &EPI, const ASTContext &Context, |
4498 | | bool Canonical); |
4499 | | }; |
4500 | | |
4501 | | /// Represents the dependent type named by a dependently-scoped |
4502 | | /// typename using declaration, e.g. |
4503 | | /// using typename Base<T>::foo; |
4504 | | /// |
4505 | | /// Template instantiation turns these into the underlying type. |
4506 | | class UnresolvedUsingType : public Type { |
4507 | | friend class ASTContext; // ASTContext creates these. |
4508 | | |
4509 | | UnresolvedUsingTypenameDecl *Decl; |
4510 | | |
4511 | | UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) |
4512 | | : Type(UnresolvedUsing, QualType(), |
4513 | | TypeDependence::DependentInstantiation), |
4514 | 237 | Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {} |
4515 | | |
4516 | | public: |
4517 | 356 | UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } |
4518 | | |
4519 | 178 | bool isSugared() const { return false; } |
4520 | 0 | QualType desugar() const { return QualType(this, 0); } |
4521 | | |
4522 | 10.0k | static bool classof(const Type *T) { |
4523 | 10.0k | return T->getTypeClass() == UnresolvedUsing; |
4524 | 10.0k | } |
4525 | | |
4526 | 0 | void Profile(llvm::FoldingSetNodeID &ID) { |
4527 | 0 | return Profile(ID, Decl); |
4528 | 0 | } |
4529 | | |
4530 | | static void Profile(llvm::FoldingSetNodeID &ID, |
4531 | 0 | UnresolvedUsingTypenameDecl *D) { |
4532 | 0 | ID.AddPointer(D); |
4533 | 0 | } |
4534 | | }; |
4535 | | |
4536 | | class UsingType final : public Type, |
4537 | | public llvm::FoldingSetNode, |
4538 | | private llvm::TrailingObjects<UsingType, QualType> { |
4539 | | UsingShadowDecl *Found; |
4540 | | friend class ASTContext; // ASTContext creates these. |
4541 | | friend TrailingObjects; |
4542 | | |
4543 | | UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon); |
4544 | | |
4545 | | public: |
4546 | 284k | UsingShadowDecl *getFoundDecl() const { return Found; } |
4547 | | QualType getUnderlyingType() const; |
4548 | | |
4549 | 1.89M | bool isSugared() const { return true; } |
4550 | | |
4551 | | // This always has the 'same' type as declared, but not necessarily identical. |
4552 | 2.05M | QualType desugar() const { return getUnderlyingType(); } |
4553 | | |
4554 | | // Internal helper, for debugging purposes. |
4555 | 52.7M | bool typeMatchesDecl() const { return !UsingBits.hasTypeDifferentFromDecl; } |
4556 | | |
4557 | 49.8M | void Profile(llvm::FoldingSetNodeID &ID) { |
4558 | 49.8M | Profile(ID, Found, typeMatchesDecl() ? QualType() : getUnderlyingType()0 ); |
4559 | 49.8M | } |
4560 | | static void Profile(llvm::FoldingSetNodeID &ID, const UsingShadowDecl *Found, |
4561 | 50.5M | QualType Underlying) { |
4562 | 50.5M | ID.AddPointer(Found); |
4563 | 50.5M | if (!Underlying.isNull()) |
4564 | 698k | Underlying.Profile(ID); |
4565 | 50.5M | } |
4566 | 9.64M | static bool classof(const Type *T) { return T->getTypeClass() == Using; } |
4567 | | }; |
4568 | | |
4569 | | class TypedefType final : public Type, |
4570 | | public llvm::FoldingSetNode, |
4571 | | private llvm::TrailingObjects<TypedefType, QualType> { |
4572 | | TypedefNameDecl *Decl; |
4573 | | friend class ASTContext; // ASTContext creates these. |
4574 | | friend TrailingObjects; |
4575 | | |
4576 | | TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying, |
4577 | | QualType can); |
4578 | | |
4579 | | public: |
4580 | 15.0M | TypedefNameDecl *getDecl() const { return Decl; } |
4581 | | |
4582 | 128M | bool isSugared() const { return true; } |
4583 | | |
4584 | | // This always has the 'same' type as declared, but not necessarily identical. |
4585 | | QualType desugar() const; |
4586 | | |
4587 | | // Internal helper, for debugging purposes. |
4588 | 135M | bool typeMatchesDecl() const { return !TypedefBits.hasTypeDifferentFromDecl; } |
4589 | | |
4590 | 0 | void Profile(llvm::FoldingSetNodeID &ID) { |
4591 | 0 | Profile(ID, Decl, typeMatchesDecl() ? QualType() : desugar()); |
4592 | 0 | } |
4593 | | static void Profile(llvm::FoldingSetNodeID &ID, const TypedefNameDecl *Decl, |
4594 | 6 | QualType Underlying) { |
4595 | 6 | ID.AddPointer(Decl); |
4596 | 6 | if (!Underlying.isNull()) |
4597 | 6 | Underlying.Profile(ID); |
4598 | 6 | } |
4599 | | |
4600 | 999M | static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } |
4601 | | }; |
4602 | | |
4603 | | /// Sugar type that represents a type that was qualified by a qualifier written |
4604 | | /// as a macro invocation. |
4605 | | class MacroQualifiedType : public Type { |
4606 | | friend class ASTContext; // ASTContext creates these. |
4607 | | |
4608 | | QualType UnderlyingTy; |
4609 | | const IdentifierInfo *MacroII; |
4610 | | |
4611 | | MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, |
4612 | | const IdentifierInfo *MacroII) |
4613 | | : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()), |
4614 | 236k | UnderlyingTy(UnderlyingTy), MacroII(MacroII) { |
4615 | 236k | assert(isa<AttributedType>(UnderlyingTy) && |
4616 | 236k | "Expected a macro qualified type to only wrap attributed types."); |
4617 | 236k | } |
4618 | | |
4619 | | public: |
4620 | 5.73k | const IdentifierInfo *getMacroIdentifier() const { return MacroII; } |
4621 | 1.97M | QualType getUnderlyingType() const { return UnderlyingTy; } |
4622 | | |
4623 | | /// Return this attributed type's modified type with no qualifiers attached to |
4624 | | /// it. |
4625 | | QualType getModifiedType() const; |
4626 | | |
4627 | 425k | bool isSugared() const { return true; } |
4628 | | QualType desugar() const; |
4629 | | |
4630 | 36.7M | static bool classof(const Type *T) { |
4631 | 36.7M | return T->getTypeClass() == MacroQualified; |
4632 | 36.7M | } |
4633 | | }; |
4634 | | |
4635 | | /// Represents a `typeof` (or __typeof__) expression (a C2x feature and GCC |
4636 | | /// extension) or a `typeof_unqual` expression (a C2x feature). |
4637 | | class TypeOfExprType : public Type { |
4638 | | Expr *TOExpr; |
4639 | | |
4640 | | protected: |
4641 | | friend class ASTContext; // ASTContext creates these. |
4642 | | |
4643 | | TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can = QualType()); |
4644 | | |
4645 | | public: |
4646 | 21.2k | Expr *getUnderlyingExpr() const { return TOExpr; } |
4647 | | |
4648 | | /// Returns the kind of 'typeof' type this is. |
4649 | 1.57k | TypeOfKind getKind() const { |
4650 | 1.57k | return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified8 |
4651 | 1.57k | : TypeOfKind::Qualified1.56k ; |
4652 | 1.57k | } |
4653 | | |
4654 | | /// Remove a single level of sugar. |
4655 | | QualType desugar() const; |
4656 | | |
4657 | | /// Returns whether this type directly provides sugar. |
4658 | | bool isSugared() const; |
4659 | | |
4660 | 116k | static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } |
4661 | | }; |
4662 | | |
4663 | | /// Internal representation of canonical, dependent |
4664 | | /// `typeof(expr)` types. |
4665 | | /// |
4666 | | /// This class is used internally by the ASTContext to manage |
4667 | | /// canonical, dependent types, only. Clients will only see instances |
4668 | | /// of this class via TypeOfExprType nodes. |
4669 | | class DependentTypeOfExprType |
4670 | | : public TypeOfExprType, public llvm::FoldingSetNode { |
4671 | | const ASTContext &Context; |
4672 | | |
4673 | | public: |
4674 | | DependentTypeOfExprType(const ASTContext &Context, Expr *E, TypeOfKind Kind) |
4675 | 191 | : TypeOfExprType(E, Kind), Context(Context) {} |
4676 | | |
4677 | 1.05k | void Profile(llvm::FoldingSetNodeID &ID) { |
4678 | 1.05k | Profile(ID, Context, getUnderlyingExpr(), |
4679 | 1.05k | getKind() == TypeOfKind::Unqualified); |
4680 | 1.05k | } |
4681 | | |
4682 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
4683 | | Expr *E, bool IsUnqual); |
4684 | | }; |
4685 | | |
4686 | | /// Represents `typeof(type)`, a C2x feature and GCC extension, or |
4687 | | /// `typeof_unqual(type), a C2x feature. |
4688 | | class TypeOfType : public Type { |
4689 | | friend class ASTContext; // ASTContext creates these. |
4690 | | |
4691 | | QualType TOType; |
4692 | | |
4693 | | TypeOfType(QualType T, QualType Can, TypeOfKind Kind) |
4694 | | : Type(TypeOf, |
4695 | | Kind == TypeOfKind::Unqualified ? Can.getAtomicUnqualifiedType() |
4696 | | : Can, |
4697 | | T->getDependence()), |
4698 | 178 | TOType(T) { |
4699 | 178 | TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified; |
4700 | 178 | } |
4701 | | |
4702 | | public: |
4703 | 726 | QualType getUnmodifiedType() const { return TOType; } |
4704 | | |
4705 | | /// Remove a single level of sugar. |
4706 | 677 | QualType desugar() const { |
4707 | 677 | QualType QT = getUnmodifiedType(); |
4708 | 677 | return TypeOfBits.IsUnqual ? QT.getAtomicUnqualifiedType()11 : QT666 ; |
4709 | 677 | } |
4710 | | |
4711 | | /// Returns whether this type directly provides sugar. |
4712 | 642 | bool isSugared() const { return true; } |
4713 | | |
4714 | | /// Returns the kind of 'typeof' type this is. |
4715 | 35 | TypeOfKind getKind() const { |
4716 | 35 | return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified3 |
4717 | 35 | : TypeOfKind::Qualified32 ; |
4718 | 35 | } |
4719 | | |
4720 | 1.66k | static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } |
4721 | | }; |
4722 | | |
4723 | | /// Represents the type `decltype(expr)` (C++11). |
4724 | | class DecltypeType : public Type { |
4725 | | Expr *E; |
4726 | | QualType UnderlyingType; |
4727 | | |
4728 | | protected: |
4729 | | friend class ASTContext; // ASTContext creates these. |
4730 | | |
4731 | | DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType()); |
4732 | | |
4733 | | public: |
4734 | 532k | Expr *getUnderlyingExpr() const { return E; } |
4735 | 329k | QualType getUnderlyingType() const { return UnderlyingType; } |
4736 | | |
4737 | | /// Remove a single level of sugar. |
4738 | | QualType desugar() const; |
4739 | | |
4740 | | /// Returns whether this type directly provides sugar. |
4741 | | bool isSugared() const; |
4742 | | |
4743 | 6.79M | static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } |
4744 | | }; |
4745 | | |
4746 | | /// Internal representation of canonical, dependent |
4747 | | /// decltype(expr) types. |
4748 | | /// |
4749 | | /// This class is used internally by the ASTContext to manage |
4750 | | /// canonical, dependent types, only. Clients will only see instances |
4751 | | /// of this class via DecltypeType nodes. |
4752 | | class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { |
4753 | | const ASTContext &Context; |
4754 | | |
4755 | | public: |
4756 | | DependentDecltypeType(const ASTContext &Context, Expr *E); |
4757 | | |
4758 | 161k | void Profile(llvm::FoldingSetNodeID &ID) { |
4759 | 161k | Profile(ID, Context, getUnderlyingExpr()); |
4760 | 161k | } |
4761 | | |
4762 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
4763 | | Expr *E); |
4764 | | }; |
4765 | | |
4766 | | /// A unary type transform, which is a type constructed from another. |
4767 | | class UnaryTransformType : public Type { |
4768 | | public: |
4769 | | enum UTTKind { |
4770 | | #define TRANSFORM_TYPE_TRAIT_DEF(Enum, _) Enum, |
4771 | | #include "clang/Basic/TransformTypeTraits.def" |
4772 | | }; |
4773 | | |
4774 | | private: |
4775 | | /// The untransformed type. |
4776 | | QualType BaseType; |
4777 | | |
4778 | | /// The transformed type if not dependent, otherwise the same as BaseType. |
4779 | | QualType UnderlyingType; |
4780 | | |
4781 | | UTTKind UKind; |
4782 | | |
4783 | | protected: |
4784 | | friend class ASTContext; |
4785 | | |
4786 | | UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, |
4787 | | QualType CanonicalTy); |
4788 | | |
4789 | | public: |
4790 | 484k | bool isSugared() const { return !isDependentType(); } |
4791 | 486k | QualType desugar() const { return UnderlyingType; } |
4792 | | |
4793 | 26.8k | QualType getUnderlyingType() const { return UnderlyingType; } |
4794 | 603k | QualType getBaseType() const { return BaseType; } |
4795 | | |
4796 | 603k | UTTKind getUTTKind() const { return UKind; } |
4797 | | |
4798 | 9.05M | static bool classof(const Type *T) { |
4799 | 9.05M | return T->getTypeClass() == UnaryTransform; |
4800 | 9.05M | } |
4801 | | }; |
4802 | | |
4803 | | /// Internal representation of canonical, dependent |
4804 | | /// __underlying_type(type) types. |
4805 | | /// |
4806 | | /// This class is used internally by the ASTContext to manage |
4807 | | /// canonical, dependent types, only. Clients will only see instances |
4808 | | /// of this class via UnaryTransformType nodes. |
4809 | | class DependentUnaryTransformType : public UnaryTransformType, |
4810 | | public llvm::FoldingSetNode { |
4811 | | public: |
4812 | | DependentUnaryTransformType(const ASTContext &C, QualType BaseType, |
4813 | | UTTKind UKind); |
4814 | | |
4815 | 204k | void Profile(llvm::FoldingSetNodeID &ID) { |
4816 | 204k | Profile(ID, getBaseType(), getUTTKind()); |
4817 | 204k | } |
4818 | | |
4819 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType, |
4820 | 388k | UTTKind UKind) { |
4821 | 388k | ID.AddPointer(BaseType.getAsOpaquePtr()); |
4822 | 388k | ID.AddInteger((unsigned)UKind); |
4823 | 388k | } |
4824 | | }; |
4825 | | |
4826 | | class TagType : public Type { |
4827 | | friend class ASTReader; |
4828 | | template <class T> friend class serialization::AbstractTypeReader; |
4829 | | |
4830 | | /// Stores the TagDecl associated with this type. The decl may point to any |
4831 | | /// TagDecl that declares the entity. |
4832 | | TagDecl *decl; |
4833 | | |
4834 | | protected: |
4835 | | TagType(TypeClass TC, const TagDecl *D, QualType can); |
4836 | | |
4837 | | public: |
4838 | | TagDecl *getDecl() const; |
4839 | | |
4840 | | /// Determines whether this type is in the process of being defined. |
4841 | | bool isBeingDefined() const; |
4842 | | |
4843 | 1.06G | static bool classof(const Type *T) { |
4844 | 1.06G | return T->getTypeClass() == Enum || T->getTypeClass() == Record1.05G ; |
4845 | 1.06G | } |
4846 | | }; |
4847 | | |
4848 | | /// A helper class that allows the use of isa/cast/dyncast |
4849 | | /// to detect TagType objects of structs/unions/classes. |
4850 | | class RecordType : public TagType { |
4851 | | protected: |
4852 | | friend class ASTContext; // ASTContext creates these. |
4853 | | |
4854 | | explicit RecordType(const RecordDecl *D) |
4855 | 2.94M | : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) {} |
4856 | | explicit RecordType(TypeClass TC, RecordDecl *D) |
4857 | 0 | : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) {} |
4858 | | |
4859 | | public: |
4860 | 70.1M | RecordDecl *getDecl() const { |
4861 | 70.1M | return reinterpret_cast<RecordDecl*>(TagType::getDecl()); |
4862 | 70.1M | } |
4863 | | |
4864 | | /// Recursively check all fields in the record for const-ness. If any field |
4865 | | /// is declared const, return true. Otherwise, return false. |
4866 | | bool hasConstFields() const; |
4867 | | |
4868 | 41.7M | bool isSugared() const { return false; } |
4869 | 0 | QualType desugar() const { return QualType(this, 0); } |
4870 | | |
4871 | 468M | static bool classof(const Type *T) { return T->getTypeClass() == Record; } |
4872 | | }; |
4873 | | |
4874 | | /// A helper class that allows the use of isa/cast/dyncast |
4875 | | /// to detect TagType objects of enums. |
4876 | | class EnumType : public TagType { |
4877 | | friend class ASTContext; // ASTContext creates these. |
4878 | | |
4879 | | explicit EnumType(const EnumDecl *D) |
4880 | 480k | : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) {} |
4881 | | |
4882 | | public: |
4883 | 84.0M | EnumDecl *getDecl() const { |
4884 | 84.0M | return reinterpret_cast<EnumDecl*>(TagType::getDecl()); |
4885 | 84.0M | } |
4886 | | |
4887 | 5.17M | bool isSugared() const { return false; } |
4888 | 0 | QualType desugar() const { return QualType(this, 0); } |
4889 | | |
4890 | 247M | static bool classof(const Type *T) { return T->getTypeClass() == Enum; } |
4891 | | }; |
4892 | | |
4893 | | /// An attributed type is a type to which a type attribute has been applied. |
4894 | | /// |
4895 | | /// The "modified type" is the fully-sugared type to which the attributed |
4896 | | /// type was applied; generally it is not canonically equivalent to the |
4897 | | /// attributed type. The "equivalent type" is the minimally-desugared type |
4898 | | /// which the type is canonically equivalent to. |
4899 | | /// |
4900 | | /// For example, in the following attributed type: |
4901 | | /// int32_t __attribute__((vector_size(16))) |
4902 | | /// - the modified type is the TypedefType for int32_t |
4903 | | /// - the equivalent type is VectorType(16, int32_t) |
4904 | | /// - the canonical type is VectorType(16, int) |
4905 | | class AttributedType : public Type, public llvm::FoldingSetNode { |
4906 | | public: |
4907 | | using Kind = attr::Kind; |
4908 | | |
4909 | | private: |
4910 | | friend class ASTContext; // ASTContext creates these |
4911 | | |
4912 | | QualType ModifiedType; |
4913 | | QualType EquivalentType; |
4914 | | |
4915 | | AttributedType(QualType canon, attr::Kind attrKind, QualType modified, |
4916 | | QualType equivalent) |
4917 | | : Type(Attributed, canon, equivalent->getDependence()), |
4918 | 396k | ModifiedType(modified), EquivalentType(equivalent) { |
4919 | 396k | AttributedTypeBits.AttrKind = attrKind; |
4920 | 396k | } |
4921 | | |
4922 | | public: |
4923 | 7.15M | Kind getAttrKind() const { |
4924 | 7.15M | return static_cast<Kind>(AttributedTypeBits.AttrKind); |
4925 | 7.15M | } |
4926 | | |
4927 | 17.6M | QualType getModifiedType() const { return ModifiedType; } |
4928 | 2.81M | QualType getEquivalentType() const { return EquivalentType; } |
4929 | | |
4930 | 2.67M | bool isSugared() const { return true; } |
4931 | 2.67M | QualType desugar() const { return getEquivalentType(); } |
4932 | | |
4933 | | /// Does this attribute behave like a type qualifier? |
4934 | | /// |
4935 | | /// A type qualifier adjusts a type to provide specialized rules for |
4936 | | /// a specific object, like the standard const and volatile qualifiers. |
4937 | | /// This includes attributes controlling things like nullability, |
4938 | | /// address spaces, and ARC ownership. The value of the object is still |
4939 | | /// largely described by the modified type. |
4940 | | /// |
4941 | | /// In contrast, many type attributes "rewrite" their modified type to |
4942 | | /// produce a fundamentally different type, not necessarily related in any |
4943 | | /// formalizable way to the original type. For example, calling convention |
4944 | | /// and vector attributes are not simple type qualifiers. |
4945 | | /// |
4946 | | /// Type qualifiers are often, but not always, reflected in the canonical |
4947 | | /// type. |
4948 | | bool isQualifier() const; |
4949 | | |
4950 | | bool isMSTypeSpec() const; |
4951 | | |
4952 | | bool isWebAssemblyFuncrefSpec() const; |
4953 | | |
4954 | | bool isCallingConv() const; |
4955 | | |
4956 | | std::optional<NullabilityKind> getImmediateNullability() const; |
4957 | | |
4958 | | /// Retrieve the attribute kind corresponding to the given |
4959 | | /// nullability kind. |
4960 | 15.9k | static Kind getNullabilityAttrKind(NullabilityKind kind) { |
4961 | 15.9k | switch (kind) { |
4962 | 8.36k | case NullabilityKind::NonNull: |
4963 | 8.36k | return attr::TypeNonNull; |
4964 | | |
4965 | 7.53k | case NullabilityKind::Nullable: |
4966 | 7.53k | return attr::TypeNullable; |
4967 | | |
4968 | 0 | case NullabilityKind::NullableResult: |
4969 | 0 | return attr::TypeNullableResult; |
4970 | | |
4971 | 3 | case NullabilityKind::Unspecified: |
4972 | 3 | return attr::TypeNullUnspecified; |
4973 | 15.9k | } |
4974 | 0 | llvm_unreachable("Unknown nullability kind."); |
4975 | 0 | } |
4976 | | |
4977 | | /// Strip off the top-level nullability annotation on the given |
4978 | | /// type, if it's there. |
4979 | | /// |
4980 | | /// \param T The type to strip. If the type is exactly an |
4981 | | /// AttributedType specifying nullability (without looking through |
4982 | | /// type sugar), the nullability is returned and this type changed |
4983 | | /// to the underlying modified type. |
4984 | | /// |
4985 | | /// \returns the top-level nullability, if present. |
4986 | | static std::optional<NullabilityKind> stripOuterNullability(QualType &T); |
4987 | | |
4988 | 5.25M | void Profile(llvm::FoldingSetNodeID &ID) { |
4989 | 5.25M | Profile(ID, getAttrKind(), ModifiedType, EquivalentType); |
4990 | 5.25M | } |
4991 | | |
4992 | | static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind, |
4993 | 8.55M | QualType modified, QualType equivalent) { |
4994 | 8.55M | ID.AddInteger(attrKind); |
4995 | 8.55M | ID.AddPointer(modified.getAsOpaquePtr()); |
4996 | 8.55M | ID.AddPointer(equivalent.getAsOpaquePtr()); |
4997 | 8.55M | } |
4998 | | |
4999 | 326M | static bool classof(const Type *T) { |
5000 | 326M | return T->getTypeClass() == Attributed; |
5001 | 326M | } |
5002 | | }; |
5003 | | |
5004 | | class BTFTagAttributedType : public Type, public llvm::FoldingSetNode { |
5005 | | private: |
5006 | | friend class ASTContext; // ASTContext creates these |
5007 | | |
5008 | | QualType WrappedType; |
5009 | | const BTFTypeTagAttr *BTFAttr; |
5010 | | |
5011 | | BTFTagAttributedType(QualType Canon, QualType Wrapped, |
5012 | | const BTFTypeTagAttr *BTFAttr) |
5013 | | : Type(BTFTagAttributed, Canon, Wrapped->getDependence()), |
5014 | 69 | WrappedType(Wrapped), BTFAttr(BTFAttr) {} |
5015 | | |
5016 | | public: |
5017 | 482 | QualType getWrappedType() const { return WrappedType; } |
5018 | 80 | const BTFTypeTagAttr *getAttr() const { return BTFAttr; } |
5019 | | |
5020 | 90 | bool isSugared() const { return true; } |
5021 | 90 | QualType desugar() const { return getWrappedType(); } |
5022 | | |
5023 | 13 | void Profile(llvm::FoldingSetNodeID &ID) { |
5024 | 13 | Profile(ID, WrappedType, BTFAttr); |
5025 | 13 | } |
5026 | | |
5027 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped, |
5028 | 83 | const BTFTypeTagAttr *BTFAttr) { |
5029 | 83 | ID.AddPointer(Wrapped.getAsOpaquePtr()); |
5030 | 83 | ID.AddPointer(BTFAttr); |
5031 | 83 | } |
5032 | | |
5033 | 32.2M | static bool classof(const Type *T) { |
5034 | 32.2M | return T->getTypeClass() == BTFTagAttributed; |
5035 | 32.2M | } |
5036 | | }; |
5037 | | |
5038 | | class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { |
5039 | | friend class ASTContext; // ASTContext creates these |
5040 | | |
5041 | | // Helper data collector for canonical types. |
5042 | | struct CanonicalTTPTInfo { |
5043 | | unsigned Depth : 15; |
5044 | | unsigned ParameterPack : 1; |
5045 | | unsigned Index : 16; |
5046 | | }; |
5047 | | |
5048 | | union { |
5049 | | // Info for the canonical type. |
5050 | | CanonicalTTPTInfo CanTTPTInfo; |
5051 | | |
5052 | | // Info for the non-canonical type. |
5053 | | TemplateTypeParmDecl *TTPDecl; |
5054 | | }; |
5055 | | |
5056 | | /// Build a non-canonical type. |
5057 | | TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) |
5058 | | : Type(TemplateTypeParm, Canon, |
5059 | | TypeDependence::DependentInstantiation | |
5060 | | (Canon->getDependence() & TypeDependence::UnexpandedPack)), |
5061 | 4.69M | TTPDecl(TTPDecl) {} |
5062 | | |
5063 | | /// Build the canonical type. |
5064 | | TemplateTypeParmType(unsigned D, unsigned I, bool PP) |
5065 | | : Type(TemplateTypeParm, QualType(this, 0), |
5066 | | TypeDependence::DependentInstantiation | |
5067 | 60.3k | (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)) { |
5068 | 60.3k | CanTTPTInfo.Depth = D; |
5069 | 60.3k | CanTTPTInfo.Index = I; |
5070 | 60.3k | CanTTPTInfo.ParameterPack = PP; |
5071 | 60.3k | } |
5072 | | |
5073 | 241M | const CanonicalTTPTInfo& getCanTTPTInfo() const { |
5074 | 241M | QualType Can = getCanonicalTypeInternal(); |
5075 | 241M | return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo; |
5076 | 241M | } |
5077 | | |
5078 | | public: |
5079 | 90.9M | unsigned getDepth() const { return getCanTTPTInfo().Depth; } |
5080 | 62.1M | unsigned getIndex() const { return getCanTTPTInfo().Index; } |
5081 | 88.0M | bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; } |
5082 | | |
5083 | 32.2M | TemplateTypeParmDecl *getDecl() const { |
5084 | 32.2M | return isCanonicalUnqualified() ? nullptr4.89M : TTPDecl27.3M ; |
5085 | 32.2M | } |
5086 | | |
5087 | | IdentifierInfo *getIdentifier() const; |
5088 | | |
5089 | 3.93M | bool isSugared() const { return false; } |
5090 | 0 | QualType desugar() const { return QualType(this, 0); } |
5091 | | |
5092 | 28.8M | void Profile(llvm::FoldingSetNodeID &ID) { |
5093 | 28.8M | Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl()); |
5094 | 28.8M | } |
5095 | | |
5096 | | static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, |
5097 | | unsigned Index, bool ParameterPack, |
5098 | 39.5M | TemplateTypeParmDecl *TTPDecl) { |
5099 | 39.5M | ID.AddInteger(Depth); |
5100 | 39.5M | ID.AddInteger(Index); |
5101 | 39.5M | ID.AddBoolean(ParameterPack); |
5102 | 39.5M | ID.AddPointer(TTPDecl); |
5103 | 39.5M | } |
5104 | | |
5105 | 536M | static bool classof(const Type *T) { |
5106 | 536M | return T->getTypeClass() == TemplateTypeParm; |
5107 | 536M | } |
5108 | | }; |
5109 | | |
5110 | | /// Represents the result of substituting a type for a template |
5111 | | /// type parameter. |
5112 | | /// |
5113 | | /// Within an instantiated template, all template type parameters have |
5114 | | /// been replaced with these. They are used solely to record that a |
5115 | | /// type was originally written as a template type parameter; |
5116 | | /// therefore they are never canonical. |
5117 | | class SubstTemplateTypeParmType final |
5118 | | : public Type, |
5119 | | public llvm::FoldingSetNode, |
5120 | | private llvm::TrailingObjects<SubstTemplateTypeParmType, QualType> { |
5121 | | friend class ASTContext; |
5122 | | friend class llvm::TrailingObjects<SubstTemplateTypeParmType, QualType>; |
5123 | | |
5124 | | Decl *AssociatedDecl; |
5125 | | |
5126 | | SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, |
5127 | | unsigned Index, std::optional<unsigned> PackIndex); |
5128 | | |
5129 | | public: |
5130 | | /// Gets the type that was substituted for the template |
5131 | | /// parameter. |
5132 | 18.1M | QualType getReplacementType() const { |
5133 | 18.1M | return SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType |
5134 | 18.1M | ? *getTrailingObjects<QualType>()21.0k |
5135 | 18.1M | : getCanonicalTypeInternal()18.1M ; |
5136 | 18.1M | } |
5137 | | |
5138 | | /// A template-like entity which owns the whole pattern being substituted. |
5139 | | /// This will usually own a set of template parameters, or in some |
5140 | | /// cases might even be a template parameter itself. |
5141 | 9.12M | Decl *getAssociatedDecl() const { return AssociatedDecl; } |
5142 | | |
5143 | | /// Gets the template parameter declaration that was substituted for. |
5144 | | const TemplateTypeParmDecl *getReplacedParameter() const; |
5145 | | |
5146 | | /// Returns the index of the replaced parameter in the associated declaration. |
5147 | | /// This should match the result of `getReplacedParameter()->getIndex()`. |
5148 | 9.08M | unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; } |
5149 | | |
5150 | 9.08M | std::optional<unsigned> getPackIndex() const { |
5151 | 9.08M | if (SubstTemplateTypeParmTypeBits.PackIndex == 0) |
5152 | 7.75M | return std::nullopt; |
5153 | 1.33M | return SubstTemplateTypeParmTypeBits.PackIndex - 1; |
5154 | 9.08M | } |
5155 | | |
5156 | 6.96M | bool isSugared() const { return true; } |
5157 | 6.98M | QualType desugar() const { return getReplacementType(); } |
5158 | | |
5159 | 8.99M | void Profile(llvm::FoldingSetNodeID &ID) { |
5160 | 8.99M | Profile(ID, getReplacementType(), getAssociatedDecl(), getIndex(), |
5161 | 8.99M | getPackIndex()); |
5162 | 8.99M | } |
5163 | | |
5164 | | static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement, |
5165 | | const Decl *AssociatedDecl, unsigned Index, |
5166 | 13.7M | std::optional<unsigned> PackIndex) { |
5167 | 13.7M | Replacement.Profile(ID); |
5168 | 13.7M | ID.AddPointer(AssociatedDecl); |
5169 | 13.7M | ID.AddInteger(Index); |
5170 | 13.7M | ID.AddInteger(PackIndex ? *PackIndex - 11.90M : 011.8M ); |
5171 | 13.7M | } |
5172 | | |
5173 | 96.1M | static bool classof(const Type *T) { |
5174 | 96.1M | return T->getTypeClass() == SubstTemplateTypeParm; |
5175 | 96.1M | } |
5176 | | }; |
5177 | | |
5178 | | /// Represents the result of substituting a set of types for a template |
5179 | | /// type parameter pack. |
5180 | | /// |
5181 | | /// When a pack expansion in the source code contains multiple parameter packs |
5182 | | /// and those parameter packs correspond to different levels of template |
5183 | | /// parameter lists, this type node is used to represent a template type |
5184 | | /// parameter pack from an outer level, which has already had its argument pack |
5185 | | /// substituted but that still lives within a pack expansion that itself |
5186 | | /// could not be instantiated. When actually performing a substitution into |
5187 | | /// that pack expansion (e.g., when all template parameters have corresponding |
5188 | | /// arguments), this type will be replaced with the \c SubstTemplateTypeParmType |
5189 | | /// at the current pack substitution index. |
5190 | | class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { |
5191 | | friend class ASTContext; |
5192 | | |
5193 | | /// A pointer to the set of template arguments that this |
5194 | | /// parameter pack is instantiated with. |
5195 | | const TemplateArgument *Arguments; |
5196 | | |
5197 | | llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal; |
5198 | | |
5199 | | SubstTemplateTypeParmPackType(QualType Canon, Decl *AssociatedDecl, |
5200 | | unsigned Index, bool Final, |
5201 | | const TemplateArgument &ArgPack); |
5202 | | |
5203 | | public: |
5204 | | IdentifierInfo *getIdentifier() const; |
5205 | | |
5206 | | /// A template-like entity which owns the whole pattern being substituted. |
5207 | | /// This will usually own a set of template parameters, or in some |
5208 | | /// cases might even be a template parameter itself. |
5209 | | Decl *getAssociatedDecl() const; |
5210 | | |
5211 | | /// Gets the template parameter declaration that was substituted for. |
5212 | | const TemplateTypeParmDecl *getReplacedParameter() const; |
5213 | | |
5214 | | /// Returns the index of the replaced parameter in the associated declaration. |
5215 | | /// This should match the result of `getReplacedParameter()->getIndex()`. |
5216 | 20.8k | unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; } |
5217 | | |
5218 | | // When true the substitution will be 'Final' (subst node won't be placed). |
5219 | | bool getFinal() const; |
5220 | | |
5221 | 41.5k | unsigned getNumArgs() const { |
5222 | 41.5k | return SubstTemplateTypeParmPackTypeBits.NumArgs; |
5223 | 41.5k | } |
5224 | | |
5225 | 22 | bool isSugared() const { return false; } |
5226 | 0 | QualType desugar() const { return QualType(this, 0); } |
5227 | | |
5228 | | TemplateArgument getArgumentPack() const; |
5229 | | |
5230 | | void Profile(llvm::FoldingSetNodeID &ID); |
5231 | | static void Profile(llvm::FoldingSetNodeID &ID, const Decl *AssociatedDecl, |
5232 | | unsigned Index, bool Final, |
5233 | | const TemplateArgument &ArgPack); |
5234 | | |
5235 | 5.97M | static bool classof(const Type *T) { |
5236 | 5.97M | return T->getTypeClass() == SubstTemplateTypeParmPack; |
5237 | 5.97M | } |
5238 | | }; |
5239 | | |
5240 | | /// Common base class for placeholders for types that get replaced by |
5241 | | /// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced |
5242 | | /// class template types, and constrained type names. |
5243 | | /// |
5244 | | /// These types are usually a placeholder for a deduced type. However, before |
5245 | | /// the initializer is attached, or (usually) if the initializer is |
5246 | | /// type-dependent, there is no deduced type and the type is canonical. In |
5247 | | /// the latter case, it is also a dependent type. |
5248 | | class DeducedType : public Type { |
5249 | | QualType DeducedAsType; |
5250 | | |
5251 | | protected: |
5252 | | DeducedType(TypeClass TC, QualType DeducedAsType, |
5253 | | TypeDependence ExtraDependence, QualType Canon) |
5254 | | : Type(TC, Canon, |
5255 | | ExtraDependence | (DeducedAsType.isNull() |
5256 | | ? TypeDependence::None |
5257 | | : DeducedAsType->getDependence() & |
5258 | | ~TypeDependence::VariablyModified)), |
5259 | 77.7k | DeducedAsType(DeducedAsType) {} |
5260 | | |
5261 | | public: |
5262 | 961k | bool isSugared() const { return !DeducedAsType.isNull(); } |
5263 | 451k | QualType desugar() const { |
5264 | 451k | return isSugared() ? DeducedAsType449k : QualType(this, 0)1.85k ; |
5265 | 451k | } |
5266 | | |
5267 | | /// Get the type deduced for this placeholder type, or null if it |
5268 | | /// has not been deduced. |
5269 | 261k | QualType getDeducedType() const { return DeducedAsType; } |
5270 | 353k | bool isDeduced() const { |
5271 | 353k | return !DeducedAsType.isNull() || isDependentType()277k ; |
5272 | 353k | } |
5273 | | |
5274 | 281M | static bool classof(const Type *T) { |
5275 | 281M | return T->getTypeClass() == Auto || |
5276 | 281M | T->getTypeClass() == DeducedTemplateSpecialization278M ; |
5277 | 281M | } |
5278 | | }; |
5279 | | |
5280 | | /// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained |
5281 | | /// by a type-constraint. |
5282 | | class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode { |
5283 | | friend class ASTContext; // ASTContext creates these |
5284 | | |
5285 | | ConceptDecl *TypeConstraintConcept; |
5286 | | |
5287 | | AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, |
5288 | | TypeDependence ExtraDependence, QualType Canon, ConceptDecl *CD, |
5289 | | ArrayRef<TemplateArgument> TypeConstraintArgs); |
5290 | | |
5291 | | public: |
5292 | 1.30M | ArrayRef<TemplateArgument> getTypeConstraintArguments() const { |
5293 | 1.30M | return {reinterpret_cast<const TemplateArgument *>(this + 1), |
5294 | 1.30M | AutoTypeBits.NumArgs}; |
5295 | 1.30M | } |
5296 | | |
5297 | 314k | ConceptDecl *getTypeConstraintConcept() const { |
5298 | 314k | return TypeConstraintConcept; |
5299 | 314k | } |
5300 | | |
5301 | 214k | bool isConstrained() const { |
5302 | 214k | return TypeConstraintConcept != nullptr; |
5303 | 214k | } |
5304 | | |
5305 | 361k | bool isDecltypeAuto() const { |
5306 | 361k | return getKeyword() == AutoTypeKeyword::DecltypeAuto; |
5307 | 361k | } |
5308 | | |
5309 | 11 | bool isGNUAutoType() const { |
5310 | 11 | return getKeyword() == AutoTypeKeyword::GNUAutoType; |
5311 | 11 | } |
5312 | | |
5313 | 780k | AutoTypeKeyword getKeyword() const { |
5314 | 780k | return (AutoTypeKeyword)AutoTypeBits.Keyword; |
5315 | 780k | } |
5316 | | |
5317 | | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context); |
5318 | | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
5319 | | QualType Deduced, AutoTypeKeyword Keyword, |
5320 | | bool IsDependent, ConceptDecl *CD, |
5321 | | ArrayRef<TemplateArgument> Arguments); |
5322 | | |
5323 | 20.8M | static bool classof(const Type *T) { |
5324 | 20.8M | return T->getTypeClass() == Auto; |
5325 | 20.8M | } |
5326 | | }; |
5327 | | |
5328 | | /// Represents a C++17 deduced template specialization type. |
5329 | | class DeducedTemplateSpecializationType : public DeducedType, |
5330 | | public llvm::FoldingSetNode { |
5331 | | friend class ASTContext; // ASTContext creates these |
5332 | | |
5333 | | /// The name of the template whose arguments will be deduced. |
5334 | | TemplateName Template; |
5335 | | |
5336 | | DeducedTemplateSpecializationType(TemplateName Template, |
5337 | | QualType DeducedAsType, |
5338 | | bool IsDeducedAsDependent) |
5339 | | : DeducedType(DeducedTemplateSpecialization, DeducedAsType, |
5340 | | toTypeDependence(Template.getDependence()) | |
5341 | | (IsDeducedAsDependent |
5342 | | ? TypeDependence::DependentInstantiation |
5343 | | : TypeDependence::None), |
5344 | | DeducedAsType.isNull() ? QualType(this, 0) |
5345 | | : DeducedAsType.getCanonicalType()), |
5346 | 2.32k | Template(Template) {} |
5347 | | |
5348 | | public: |
5349 | | /// Retrieve the name of the template that we are deducing. |
5350 | 9.44k | TemplateName getTemplateName() const { return Template;} |
5351 | | |
5352 | 5.89k | void Profile(llvm::FoldingSetNodeID &ID) { |
5353 | 5.89k | Profile(ID, getTemplateName(), getDeducedType(), isDependentType()); |
5354 | 5.89k | } |
5355 | | |
5356 | | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template, |
5357 | 10.2k | QualType Deduced, bool IsDependent) { |
5358 | 10.2k | Template.Profile(ID); |
5359 | 10.2k | QualType CanonicalType = |
5360 | 10.2k | Deduced.isNull() ? Deduced9.01k : Deduced.getCanonicalType()1.26k ; |
5361 | 10.2k | ID.AddPointer(CanonicalType.getAsOpaquePtr()); |
5362 | 10.2k | ID.AddBoolean(IsDependent || Template.isDependent()9.22k ); |
5363 | 10.2k | } |
5364 | | |
5365 | 8.87M | static bool classof(const Type *T) { |
5366 | 8.87M | return T->getTypeClass() == DeducedTemplateSpecialization; |
5367 | 8.87M | } |
5368 | | }; |
5369 | | |
5370 | | /// Represents a type template specialization; the template |
5371 | | /// must be a class template, a type alias template, or a template |
5372 | | /// template parameter. A template which cannot be resolved to one of |
5373 | | /// these, e.g. because it is written with a dependent scope |
5374 | | /// specifier, is instead represented as a |
5375 | | /// @c DependentTemplateSpecializationType. |
5376 | | /// |
5377 | | /// A non-dependent template specialization type is always "sugar", |
|