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/LangOptions.h" |
29 | #include "clang/Basic/Linkage.h" |
30 | #include "clang/Basic/PartialDiagnostic.h" |
31 | #include "clang/Basic/PointerAuthOptions.h" |
32 | #include "clang/Basic/SourceLocation.h" |
33 | #include "clang/Basic/Specifiers.h" |
34 | #include "clang/Basic/Visibility.h" |
35 | #include "llvm/ADT/APInt.h" |
36 | #include "llvm/ADT/APSInt.h" |
37 | #include "llvm/ADT/ArrayRef.h" |
38 | #include "llvm/ADT/FoldingSet.h" |
39 | #include "llvm/ADT/PointerIntPair.h" |
40 | #include "llvm/ADT/PointerUnion.h" |
41 | #include "llvm/ADT/STLForwardCompat.h" |
42 | #include "llvm/ADT/StringRef.h" |
43 | #include "llvm/ADT/Twine.h" |
44 | #include "llvm/ADT/iterator_range.h" |
45 | #include "llvm/Support/Casting.h" |
46 | #include "llvm/Support/Compiler.h" |
47 | #include "llvm/Support/DXILABI.h" |
48 | #include "llvm/Support/ErrorHandling.h" |
49 | #include "llvm/Support/PointerLikeTypeTraits.h" |
50 | #include "llvm/Support/TrailingObjects.h" |
51 | #include "llvm/Support/type_traits.h" |
52 | #include <bitset> |
53 | #include <cassert> |
54 | #include <cstddef> |
55 | #include <cstdint> |
56 | #include <cstring> |
57 | #include <optional> |
58 | #include <string> |
59 | #include <type_traits> |
60 | #include <utility> |
61 | |
62 | namespace clang { |
63 | |
64 | class BTFTypeTagAttr; |
65 | class ExtQuals; |
66 | class QualType; |
67 | class ConceptDecl; |
68 | class ValueDecl; |
69 | class TagDecl; |
70 | class TemplateParameterList; |
71 | class Type; |
72 | class Attr; |
73 | |
74 | enum { |
75 | TypeAlignmentInBits = 4, |
76 | TypeAlignment = 1 << TypeAlignmentInBits |
77 | }; |
78 | |
79 | namespace serialization { |
80 | template <class T> class AbstractTypeReader; |
81 | template <class T> class AbstractTypeWriter; |
82 | } |
83 | |
84 | } // namespace clang |
85 | |
86 | namespace llvm { |
87 | |
88 | template <typename T> |
89 | struct PointerLikeTypeTraits; |
90 | template<> |
91 | struct PointerLikeTypeTraits< ::clang::Type*> { |
92 | static inline void *getAsVoidPointer(::clang::Type *P) { return P; } |
93 | |
94 | static inline ::clang::Type *getFromVoidPointer(void *P) { |
95 | return static_cast< ::clang::Type*>(P); |
96 | } |
97 | |
98 | static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; |
99 | }; |
100 | |
101 | template<> |
102 | struct PointerLikeTypeTraits< ::clang::ExtQuals*> { |
103 | static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; } |
104 | |
105 | static inline ::clang::ExtQuals *getFromVoidPointer(void *P) { |
106 | return static_cast< ::clang::ExtQuals*>(P); |
107 | } |
108 | |
109 | static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; |
110 | }; |
111 | |
112 | } // namespace llvm |
113 | |
114 | namespace clang { |
115 | |
116 | class ASTContext; |
117 | template <typename> class CanQual; |
118 | class CXXRecordDecl; |
119 | class DeclContext; |
120 | class EnumDecl; |
121 | class Expr; |
122 | class ExtQualsTypeCommonBase; |
123 | class FunctionDecl; |
124 | class FunctionEffectsRef; |
125 | class FunctionEffectKindSet; |
126 | class FunctionEffectSet; |
127 | class IdentifierInfo; |
128 | class NamedDecl; |
129 | class ObjCInterfaceDecl; |
130 | class ObjCProtocolDecl; |
131 | class ObjCTypeParamDecl; |
132 | struct PrintingPolicy; |
133 | class RecordDecl; |
134 | class Stmt; |
135 | class TagDecl; |
136 | class TemplateArgument; |
137 | class TemplateArgumentListInfo; |
138 | class TemplateArgumentLoc; |
139 | class TemplateTypeParmDecl; |
140 | class TypedefNameDecl; |
141 | class UnresolvedUsingTypenameDecl; |
142 | class UsingShadowDecl; |
143 | |
144 | using CanQualType = CanQual<Type>; |
145 | |
146 | // Provide forward declarations for all of the *Type classes. |
147 | #define TYPE(Class, Base) class Class##Type; |
148 | #include "clang/AST/TypeNodes.inc" |
149 | |
150 | /// Pointer-authentication qualifiers. |
151 | class PointerAuthQualifier { |
152 | enum : uint32_t { |
153 | EnabledShift = 0, |
154 | EnabledBits = 1, |
155 | EnabledMask = 1 << EnabledShift, |
156 | AddressDiscriminatedShift = EnabledShift + EnabledBits, |
157 | AddressDiscriminatedBits = 1, |
158 | AddressDiscriminatedMask = 1 << AddressDiscriminatedShift, |
159 | AuthenticationModeShift = |
160 | AddressDiscriminatedShift + AddressDiscriminatedBits, |
161 | AuthenticationModeBits = 2, |
162 | AuthenticationModeMask = ((1 << AuthenticationModeBits) - 1) |
163 | << AuthenticationModeShift, |
164 | IsaPointerShift = AuthenticationModeShift + AuthenticationModeBits, |
165 | IsaPointerBits = 1, |
166 | IsaPointerMask = ((1 << IsaPointerBits) - 1) << IsaPointerShift, |
167 | AuthenticatesNullValuesShift = IsaPointerShift + IsaPointerBits, |
168 | AuthenticatesNullValuesBits = 1, |
169 | AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1) |
170 | << AuthenticatesNullValuesShift, |
171 | KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits, |
172 | KeyBits = 10, |
173 | KeyMask = ((1 << KeyBits) - 1) << KeyShift, |
174 | DiscriminatorShift = KeyShift + KeyBits, |
175 | DiscriminatorBits = 16, |
176 | DiscriminatorMask = ((1u << DiscriminatorBits) - 1) << DiscriminatorShift, |
177 | }; |
178 | |
179 | // bits: |0 |1 |2..3 |4 | |
180 | // |Enabled|Address|AuthenticationMode|ISA pointer| |
181 | // bits: |5 |6..15| 16...31 | |
182 | // |AuthenticatesNull|Key |Discriminator| |
183 | uint32_t Data = 0; |
184 | |
185 | // The following static assertions check that each of the 32 bits is present |
186 | // exactly in one of the constants. |
187 | static_assert((EnabledBits + AddressDiscriminatedBits + |
188 | AuthenticationModeBits + IsaPointerBits + |
189 | AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) == |
190 | 32, |
191 | "PointerAuthQualifier should be exactly 32 bits" ); |
192 | static_assert((EnabledMask + AddressDiscriminatedMask + |
193 | AuthenticationModeMask + IsaPointerMask + |
194 | AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) == |
195 | 0xFFFFFFFF, |
196 | "All masks should cover the entire bits" ); |
197 | static_assert((EnabledMask ^ AddressDiscriminatedMask ^ |
198 | AuthenticationModeMask ^ IsaPointerMask ^ |
199 | AuthenticatesNullValuesMask ^ KeyMask ^ DiscriminatorMask) == |
200 | 0xFFFFFFFF, |
201 | "All masks should cover the entire bits" ); |
202 | |
203 | PointerAuthQualifier(unsigned Key, bool IsAddressDiscriminated, |
204 | unsigned , |
205 | PointerAuthenticationMode AuthenticationMode, |
206 | bool IsIsaPointer, bool AuthenticatesNullValues) |
207 | : Data(EnabledMask | |
208 | (IsAddressDiscriminated |
209 | ? llvm::to_underlying(AddressDiscriminatedMask) |
210 | : 0) | |
211 | (Key << KeyShift) | |
212 | (llvm::to_underlying(AuthenticationMode) |
213 | << AuthenticationModeShift) | |
214 | (ExtraDiscriminator << DiscriminatorShift) | |
215 | (IsIsaPointer << IsaPointerShift) | |
216 | (AuthenticatesNullValues << AuthenticatesNullValuesShift)) { |
217 | assert(Key <= KeyNoneInternal); |
218 | assert(ExtraDiscriminator <= MaxDiscriminator); |
219 | assert((Data == 0) == |
220 | (getAuthenticationMode() == PointerAuthenticationMode::None)); |
221 | } |
222 | |
223 | public: |
224 | enum { |
225 | KeyNoneInternal = (1u << KeyBits) - 1, |
226 | |
227 | /// The maximum supported pointer-authentication key. |
228 | MaxKey = KeyNoneInternal - 1, |
229 | |
230 | /// The maximum supported pointer-authentication discriminator. |
231 | MaxDiscriminator = (1u << DiscriminatorBits) - 1 |
232 | }; |
233 | |
234 | public: |
235 | PointerAuthQualifier() = default; |
236 | |
237 | static PointerAuthQualifier |
238 | Create(unsigned Key, bool IsAddressDiscriminated, unsigned , |
239 | PointerAuthenticationMode AuthenticationMode, bool IsIsaPointer, |
240 | bool AuthenticatesNullValues) { |
241 | if (Key == PointerAuthKeyNone) |
242 | Key = KeyNoneInternal; |
243 | assert(Key <= KeyNoneInternal && "out-of-range key value" ); |
244 | return PointerAuthQualifier(Key, IsAddressDiscriminated, ExtraDiscriminator, |
245 | AuthenticationMode, IsIsaPointer, |
246 | AuthenticatesNullValues); |
247 | } |
248 | |
249 | bool isPresent() const { |
250 | assert((Data == 0) == |
251 | (getAuthenticationMode() == PointerAuthenticationMode::None)); |
252 | return Data != 0; |
253 | } |
254 | |
255 | explicit operator bool() const { return isPresent(); } |
256 | |
257 | unsigned getKey() const { |
258 | assert(isPresent()); |
259 | return (Data & KeyMask) >> KeyShift; |
260 | } |
261 | |
262 | bool hasKeyNone() const { return isPresent() && getKey() == KeyNoneInternal; } |
263 | |
264 | bool isAddressDiscriminated() const { |
265 | assert(isPresent()); |
266 | return (Data & AddressDiscriminatedMask) >> AddressDiscriminatedShift; |
267 | } |
268 | |
269 | unsigned () const { |
270 | assert(isPresent()); |
271 | return (Data >> DiscriminatorShift); |
272 | } |
273 | |
274 | PointerAuthenticationMode getAuthenticationMode() const { |
275 | return PointerAuthenticationMode((Data & AuthenticationModeMask) >> |
276 | AuthenticationModeShift); |
277 | } |
278 | |
279 | bool isIsaPointer() const { |
280 | assert(isPresent()); |
281 | return (Data & IsaPointerMask) >> IsaPointerShift; |
282 | } |
283 | |
284 | bool authenticatesNullValues() const { |
285 | assert(isPresent()); |
286 | return (Data & AuthenticatesNullValuesMask) >> AuthenticatesNullValuesShift; |
287 | } |
288 | |
289 | PointerAuthQualifier withoutKeyNone() const { |
290 | return hasKeyNone() ? PointerAuthQualifier() : *this; |
291 | } |
292 | |
293 | friend bool operator==(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) { |
294 | return Lhs.Data == Rhs.Data; |
295 | } |
296 | friend bool operator!=(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) { |
297 | return Lhs.Data != Rhs.Data; |
298 | } |
299 | |
300 | bool isEquivalent(PointerAuthQualifier Other) const { |
301 | return withoutKeyNone() == Other.withoutKeyNone(); |
302 | } |
303 | |
304 | uint32_t getAsOpaqueValue() const { return Data; } |
305 | |
306 | // Deserialize pointer-auth qualifiers from an opaque representation. |
307 | static PointerAuthQualifier fromOpaqueValue(uint32_t Opaque) { |
308 | PointerAuthQualifier Result; |
309 | Result.Data = Opaque; |
310 | assert((Result.Data == 0) == |
311 | (Result.getAuthenticationMode() == PointerAuthenticationMode::None)); |
312 | return Result; |
313 | } |
314 | |
315 | std::string getAsString() const; |
316 | std::string getAsString(const PrintingPolicy &Policy) const; |
317 | |
318 | bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; |
319 | void print(raw_ostream &OS, const PrintingPolicy &Policy) const; |
320 | |
321 | void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(I: Data); } |
322 | }; |
323 | |
324 | /// The collection of all-type qualifiers we support. |
325 | /// Clang supports five independent qualifiers: |
326 | /// * C99: const, volatile, and restrict |
327 | /// * MS: __unaligned |
328 | /// * Embedded C (TR18037): address spaces |
329 | /// * Objective C: the GC attributes (none, weak, or strong) |
330 | class Qualifiers { |
331 | public: |
332 | Qualifiers() = default; |
333 | enum TQ : uint64_t { |
334 | // NOTE: These flags must be kept in sync with DeclSpec::TQ. |
335 | Const = 0x1, |
336 | Restrict = 0x2, |
337 | Volatile = 0x4, |
338 | CVRMask = Const | Volatile | Restrict |
339 | }; |
340 | |
341 | enum GC { |
342 | GCNone = 0, |
343 | Weak, |
344 | Strong |
345 | }; |
346 | |
347 | enum ObjCLifetime { |
348 | /// There is no lifetime qualification on this type. |
349 | OCL_None, |
350 | |
351 | /// This object can be modified without requiring retains or |
352 | /// releases. |
353 | OCL_ExplicitNone, |
354 | |
355 | /// Assigning into this object requires the old value to be |
356 | /// released and the new value to be retained. The timing of the |
357 | /// release of the old value is inexact: it may be moved to |
358 | /// immediately after the last known point where the value is |
359 | /// live. |
360 | OCL_Strong, |
361 | |
362 | /// Reading or writing from this object requires a barrier call. |
363 | OCL_Weak, |
364 | |
365 | /// Assigning into this object requires a lifetime extension. |
366 | OCL_Autoreleasing |
367 | }; |
368 | |
369 | enum : uint64_t { |
370 | /// The maximum supported address space number. |
371 | /// 23 bits should be enough for anyone. |
372 | MaxAddressSpace = 0x7fffffu, |
373 | |
374 | /// The width of the "fast" qualifier mask. |
375 | FastWidth = 3, |
376 | |
377 | /// The fast qualifier mask. |
378 | FastMask = (1 << FastWidth) - 1 |
379 | }; |
380 | |
381 | /// Returns the common set of qualifiers while removing them from |
382 | /// the given sets. |
383 | static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { |
384 | Qualifiers Q; |
385 | PointerAuthQualifier LPtrAuth = L.getPointerAuth(); |
386 | if (LPtrAuth.isPresent() && |
387 | LPtrAuth.getKey() != PointerAuthQualifier::KeyNoneInternal && |
388 | LPtrAuth == R.getPointerAuth()) { |
389 | Q.setPointerAuth(LPtrAuth); |
390 | PointerAuthQualifier Empty; |
391 | L.setPointerAuth(Empty); |
392 | R.setPointerAuth(Empty); |
393 | } |
394 | |
395 | // If both are only CVR-qualified, bit operations are sufficient. |
396 | if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { |
397 | Q.Mask = L.Mask & R.Mask; |
398 | L.Mask &= ~Q.Mask; |
399 | R.Mask &= ~Q.Mask; |
400 | return Q; |
401 | } |
402 | |
403 | unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); |
404 | Q.addCVRQualifiers(mask: CommonCRV); |
405 | L.removeCVRQualifiers(mask: CommonCRV); |
406 | R.removeCVRQualifiers(mask: CommonCRV); |
407 | |
408 | if (L.getObjCGCAttr() == R.getObjCGCAttr()) { |
409 | Q.setObjCGCAttr(L.getObjCGCAttr()); |
410 | L.removeObjCGCAttr(); |
411 | R.removeObjCGCAttr(); |
412 | } |
413 | |
414 | if (L.getObjCLifetime() == R.getObjCLifetime()) { |
415 | Q.setObjCLifetime(L.getObjCLifetime()); |
416 | L.removeObjCLifetime(); |
417 | R.removeObjCLifetime(); |
418 | } |
419 | |
420 | if (L.getAddressSpace() == R.getAddressSpace()) { |
421 | Q.setAddressSpace(L.getAddressSpace()); |
422 | L.removeAddressSpace(); |
423 | R.removeAddressSpace(); |
424 | } |
425 | return Q; |
426 | } |
427 | |
428 | static Qualifiers fromFastMask(unsigned Mask) { |
429 | Qualifiers Qs; |
430 | Qs.addFastQualifiers(mask: Mask); |
431 | return Qs; |
432 | } |
433 | |
434 | static Qualifiers fromCVRMask(unsigned CVR) { |
435 | Qualifiers Qs; |
436 | Qs.addCVRQualifiers(mask: CVR); |
437 | return Qs; |
438 | } |
439 | |
440 | static Qualifiers fromCVRUMask(unsigned CVRU) { |
441 | Qualifiers Qs; |
442 | Qs.addCVRUQualifiers(mask: CVRU); |
443 | return Qs; |
444 | } |
445 | |
446 | // Deserialize qualifiers from an opaque representation. |
447 | static Qualifiers fromOpaqueValue(uint64_t opaque) { |
448 | Qualifiers Qs; |
449 | Qs.Mask = opaque; |
450 | return Qs; |
451 | } |
452 | |
453 | // Serialize these qualifiers into an opaque representation. |
454 | uint64_t getAsOpaqueValue() const { return Mask; } |
455 | |
456 | bool hasConst() const { return Mask & Const; } |
457 | bool hasOnlyConst() const { return Mask == Const; } |
458 | void removeConst() { Mask &= ~Const; } |
459 | void addConst() { Mask |= Const; } |
460 | Qualifiers withConst() const { |
461 | Qualifiers Qs = *this; |
462 | Qs.addConst(); |
463 | return Qs; |
464 | } |
465 | |
466 | bool hasVolatile() const { return Mask & Volatile; } |
467 | bool hasOnlyVolatile() const { return Mask == Volatile; } |
468 | void removeVolatile() { Mask &= ~Volatile; } |
469 | void addVolatile() { Mask |= Volatile; } |
470 | Qualifiers withVolatile() const { |
471 | Qualifiers Qs = *this; |
472 | Qs.addVolatile(); |
473 | return Qs; |
474 | } |
475 | |
476 | bool hasRestrict() const { return Mask & Restrict; } |
477 | bool hasOnlyRestrict() const { return Mask == Restrict; } |
478 | void removeRestrict() { Mask &= ~Restrict; } |
479 | void addRestrict() { Mask |= Restrict; } |
480 | Qualifiers withRestrict() const { |
481 | Qualifiers Qs = *this; |
482 | Qs.addRestrict(); |
483 | return Qs; |
484 | } |
485 | |
486 | bool hasCVRQualifiers() const { return getCVRQualifiers(); } |
487 | unsigned getCVRQualifiers() const { return Mask & CVRMask; } |
488 | unsigned getCVRUQualifiers() const { return Mask & (CVRMask | UMask); } |
489 | |
490 | void setCVRQualifiers(unsigned mask) { |
491 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ); |
492 | Mask = (Mask & ~CVRMask) | mask; |
493 | } |
494 | void removeCVRQualifiers(unsigned mask) { |
495 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ); |
496 | Mask &= ~static_cast<uint64_t>(mask); |
497 | } |
498 | void removeCVRQualifiers() { |
499 | removeCVRQualifiers(mask: CVRMask); |
500 | } |
501 | void addCVRQualifiers(unsigned mask) { |
502 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ); |
503 | Mask |= mask; |
504 | } |
505 | void addCVRUQualifiers(unsigned mask) { |
506 | assert(!(mask & ~CVRMask & ~UMask) && "bitmask contains non-CVRU bits" ); |
507 | Mask |= mask; |
508 | } |
509 | |
510 | bool hasUnaligned() const { return Mask & UMask; } |
511 | void setUnaligned(bool flag) { |
512 | Mask = (Mask & ~UMask) | (flag ? UMask : 0); |
513 | } |
514 | void removeUnaligned() { Mask &= ~UMask; } |
515 | void addUnaligned() { Mask |= UMask; } |
516 | |
517 | bool hasObjCGCAttr() const { return Mask & GCAttrMask; } |
518 | GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } |
519 | void setObjCGCAttr(GC type) { |
520 | Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift); |
521 | } |
522 | void removeObjCGCAttr() { setObjCGCAttr(GCNone); } |
523 | void addObjCGCAttr(GC type) { |
524 | assert(type); |
525 | setObjCGCAttr(type); |
526 | } |
527 | Qualifiers withoutObjCGCAttr() const { |
528 | Qualifiers qs = *this; |
529 | qs.removeObjCGCAttr(); |
530 | return qs; |
531 | } |
532 | Qualifiers withoutObjCLifetime() const { |
533 | Qualifiers qs = *this; |
534 | qs.removeObjCLifetime(); |
535 | return qs; |
536 | } |
537 | Qualifiers withoutAddressSpace() const { |
538 | Qualifiers qs = *this; |
539 | qs.removeAddressSpace(); |
540 | return qs; |
541 | } |
542 | |
543 | bool hasObjCLifetime() const { return Mask & LifetimeMask; } |
544 | ObjCLifetime getObjCLifetime() const { |
545 | return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift); |
546 | } |
547 | void setObjCLifetime(ObjCLifetime type) { |
548 | Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift); |
549 | } |
550 | void removeObjCLifetime() { setObjCLifetime(OCL_None); } |
551 | void addObjCLifetime(ObjCLifetime type) { |
552 | assert(type); |
553 | assert(!hasObjCLifetime()); |
554 | Mask |= (type << LifetimeShift); |
555 | } |
556 | |
557 | /// True if the lifetime is neither None or ExplicitNone. |
558 | bool hasNonTrivialObjCLifetime() const { |
559 | ObjCLifetime lifetime = getObjCLifetime(); |
560 | return (lifetime > OCL_ExplicitNone); |
561 | } |
562 | |
563 | /// True if the lifetime is either strong or weak. |
564 | bool hasStrongOrWeakObjCLifetime() const { |
565 | ObjCLifetime lifetime = getObjCLifetime(); |
566 | return (lifetime == OCL_Strong || lifetime == OCL_Weak); |
567 | } |
568 | |
569 | bool hasAddressSpace() const { return Mask & AddressSpaceMask; } |
570 | LangAS getAddressSpace() const { |
571 | return static_cast<LangAS>((Mask & AddressSpaceMask) >> AddressSpaceShift); |
572 | } |
573 | bool hasTargetSpecificAddressSpace() const { |
574 | return isTargetAddressSpace(AS: getAddressSpace()); |
575 | } |
576 | /// Get the address space attribute value to be printed by diagnostics. |
577 | unsigned getAddressSpaceAttributePrintValue() const { |
578 | auto Addr = getAddressSpace(); |
579 | // This function is not supposed to be used with language specific |
580 | // address spaces. If that happens, the diagnostic message should consider |
581 | // printing the QualType instead of the address space value. |
582 | assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace()); |
583 | if (Addr != LangAS::Default) |
584 | return toTargetAddressSpace(AS: Addr); |
585 | // TODO: The diagnostic messages where Addr may be 0 should be fixed |
586 | // since it cannot differentiate the situation where 0 denotes the default |
587 | // address space or user specified __attribute__((address_space(0))). |
588 | return 0; |
589 | } |
590 | void setAddressSpace(LangAS space) { |
591 | assert((unsigned)space <= MaxAddressSpace); |
592 | Mask = (Mask & ~AddressSpaceMask) |
593 | | (((uint32_t) space) << AddressSpaceShift); |
594 | } |
595 | void removeAddressSpace() { setAddressSpace(LangAS::Default); } |
596 | void addAddressSpace(LangAS space) { |
597 | assert(space != LangAS::Default); |
598 | setAddressSpace(space); |
599 | } |
600 | |
601 | bool hasPointerAuth() const { return Mask & PtrAuthMask; } |
602 | PointerAuthQualifier getPointerAuth() const { |
603 | return PointerAuthQualifier::fromOpaqueValue(Opaque: Mask >> PtrAuthShift); |
604 | } |
605 | void setPointerAuth(PointerAuthQualifier Q) { |
606 | Mask = (Mask & ~PtrAuthMask) | |
607 | (uint64_t(Q.getAsOpaqueValue()) << PtrAuthShift); |
608 | } |
609 | void removePointerAuth() { Mask &= ~PtrAuthMask; } |
610 | void addPointerAuth(PointerAuthQualifier Q) { |
611 | assert(Q.isPresent()); |
612 | setPointerAuth(Q); |
613 | } |
614 | |
615 | // Fast qualifiers are those that can be allocated directly |
616 | // on a QualType object. |
617 | bool hasFastQualifiers() const { return getFastQualifiers(); } |
618 | unsigned getFastQualifiers() const { return Mask & FastMask; } |
619 | void setFastQualifiers(unsigned mask) { |
620 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits" ); |
621 | Mask = (Mask & ~FastMask) | mask; |
622 | } |
623 | void removeFastQualifiers(unsigned mask) { |
624 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits" ); |
625 | Mask &= ~static_cast<uint64_t>(mask); |
626 | } |
627 | void removeFastQualifiers() { |
628 | removeFastQualifiers(mask: FastMask); |
629 | } |
630 | void addFastQualifiers(unsigned mask) { |
631 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits" ); |
632 | Mask |= mask; |
633 | } |
634 | |
635 | /// Return true if the set contains any qualifiers which require an ExtQuals |
636 | /// node to be allocated. |
637 | bool hasNonFastQualifiers() const { return Mask & ~FastMask; } |
638 | Qualifiers getNonFastQualifiers() const { |
639 | Qualifiers Quals = *this; |
640 | Quals.setFastQualifiers(0); |
641 | return Quals; |
642 | } |
643 | |
644 | /// Return true if the set contains any qualifiers. |
645 | bool hasQualifiers() const { return Mask; } |
646 | bool empty() const { return !Mask; } |
647 | |
648 | /// Add the qualifiers from the given set to this set. |
649 | void addQualifiers(Qualifiers Q) { |
650 | // If the other set doesn't have any non-boolean qualifiers, just |
651 | // bit-or it in. |
652 | if (!(Q.Mask & ~CVRMask)) |
653 | Mask |= Q.Mask; |
654 | else { |
655 | Mask |= (Q.Mask & CVRMask); |
656 | if (Q.hasAddressSpace()) |
657 | addAddressSpace(space: Q.getAddressSpace()); |
658 | if (Q.hasObjCGCAttr()) |
659 | addObjCGCAttr(type: Q.getObjCGCAttr()); |
660 | if (Q.hasObjCLifetime()) |
661 | addObjCLifetime(type: Q.getObjCLifetime()); |
662 | if (Q.hasPointerAuth()) |
663 | addPointerAuth(Q: Q.getPointerAuth()); |
664 | } |
665 | } |
666 | |
667 | /// Remove the qualifiers from the given set from this set. |
668 | void removeQualifiers(Qualifiers Q) { |
669 | // If the other set doesn't have any non-boolean qualifiers, just |
670 | // bit-and the inverse in. |
671 | if (!(Q.Mask & ~CVRMask)) |
672 | Mask &= ~Q.Mask; |
673 | else { |
674 | Mask &= ~(Q.Mask & CVRMask); |
675 | if (getObjCGCAttr() == Q.getObjCGCAttr()) |
676 | removeObjCGCAttr(); |
677 | if (getObjCLifetime() == Q.getObjCLifetime()) |
678 | removeObjCLifetime(); |
679 | if (getAddressSpace() == Q.getAddressSpace()) |
680 | removeAddressSpace(); |
681 | if (getPointerAuth() == Q.getPointerAuth()) |
682 | removePointerAuth(); |
683 | } |
684 | } |
685 | |
686 | /// Add the qualifiers from the given set to this set, given that |
687 | /// they don't conflict. |
688 | void addConsistentQualifiers(Qualifiers qs) { |
689 | assert(getAddressSpace() == qs.getAddressSpace() || |
690 | !hasAddressSpace() || !qs.hasAddressSpace()); |
691 | assert(getObjCGCAttr() == qs.getObjCGCAttr() || |
692 | !hasObjCGCAttr() || !qs.hasObjCGCAttr()); |
693 | assert(getObjCLifetime() == qs.getObjCLifetime() || |
694 | !hasObjCLifetime() || !qs.hasObjCLifetime()); |
695 | assert(!hasPointerAuth() || !qs.hasPointerAuth() || |
696 | getPointerAuth() == qs.getPointerAuth()); |
697 | Mask |= qs.Mask; |
698 | } |
699 | |
700 | /// Returns true if address space A is equal to or a superset of B. |
701 | /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of |
702 | /// overlapping address spaces. |
703 | /// CL1.1 or CL1.2: |
704 | /// every address space is a superset of itself. |
705 | /// CL2.0 adds: |
706 | /// __generic is a superset of any address space except for __constant. |
707 | static bool isAddressSpaceSupersetOf(LangAS A, LangAS B, |
708 | const ASTContext &Ctx) { |
709 | // Address spaces must match exactly. |
710 | return A == B || isTargetAddressSpaceSupersetOf(A, B, Ctx); |
711 | } |
712 | |
713 | static bool isTargetAddressSpaceSupersetOf(LangAS A, LangAS B, |
714 | const ASTContext &Ctx); |
715 | |
716 | /// Returns true if the address space in these qualifiers is equal to or |
717 | /// a superset of the address space in the argument qualifiers. |
718 | bool isAddressSpaceSupersetOf(Qualifiers other, const ASTContext &Ctx) const { |
719 | return isAddressSpaceSupersetOf(A: getAddressSpace(), B: other.getAddressSpace(), |
720 | Ctx); |
721 | } |
722 | |
723 | /// Determines if these qualifiers compatibly include another set. |
724 | /// Generally this answers the question of whether an object with the other |
725 | /// qualifiers can be safely used as an object with these qualifiers. |
726 | bool compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const { |
727 | return isAddressSpaceSupersetOf(other, Ctx) && |
728 | // ObjC GC qualifiers can match, be added, or be removed, but can't |
729 | // be changed. |
730 | (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || |
731 | !other.hasObjCGCAttr()) && |
732 | // Pointer-auth qualifiers must match exactly. |
733 | getPointerAuth() == other.getPointerAuth() && |
734 | // ObjC lifetime qualifiers must match exactly. |
735 | getObjCLifetime() == other.getObjCLifetime() && |
736 | // CVR qualifiers may subset. |
737 | (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) && |
738 | // U qualifier may superset. |
739 | (!other.hasUnaligned() || hasUnaligned()); |
740 | } |
741 | |
742 | /// Determines if these qualifiers compatibly include another set of |
743 | /// qualifiers from the narrow perspective of Objective-C ARC lifetime. |
744 | /// |
745 | /// One set of Objective-C lifetime qualifiers compatibly includes the other |
746 | /// if the lifetime qualifiers match, or if both are non-__weak and the |
747 | /// including set also contains the 'const' qualifier, or both are non-__weak |
748 | /// and one is None (which can only happen in non-ARC modes). |
749 | bool compatiblyIncludesObjCLifetime(Qualifiers other) const { |
750 | if (getObjCLifetime() == other.getObjCLifetime()) |
751 | return true; |
752 | |
753 | if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) |
754 | return false; |
755 | |
756 | if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None) |
757 | return true; |
758 | |
759 | return hasConst(); |
760 | } |
761 | |
762 | /// Determine whether this set of qualifiers is a strict superset of |
763 | /// another set of qualifiers, not considering qualifier compatibility. |
764 | bool isStrictSupersetOf(Qualifiers Other) const; |
765 | |
766 | bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } |
767 | bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } |
768 | |
769 | explicit operator bool() const { return hasQualifiers(); } |
770 | |
771 | Qualifiers &operator+=(Qualifiers R) { |
772 | addQualifiers(Q: R); |
773 | return *this; |
774 | } |
775 | |
776 | // Union two qualifier sets. If an enumerated qualifier appears |
777 | // in both sets, use the one from the right. |
778 | friend Qualifiers operator+(Qualifiers L, Qualifiers R) { |
779 | L += R; |
780 | return L; |
781 | } |
782 | |
783 | Qualifiers &operator-=(Qualifiers R) { |
784 | removeQualifiers(Q: R); |
785 | return *this; |
786 | } |
787 | |
788 | /// Compute the difference between two qualifier sets. |
789 | friend Qualifiers operator-(Qualifiers L, Qualifiers R) { |
790 | L -= R; |
791 | return L; |
792 | } |
793 | |
794 | std::string getAsString() const; |
795 | std::string getAsString(const PrintingPolicy &Policy) const; |
796 | |
797 | static std::string getAddrSpaceAsString(LangAS AS); |
798 | |
799 | bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; |
800 | void print(raw_ostream &OS, const PrintingPolicy &Policy, |
801 | bool appendSpaceIfNonEmpty = false) const; |
802 | |
803 | void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(I: Mask); } |
804 | |
805 | private: |
806 | // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|32 ... 63| |
807 | // |C R V|U|GCAttr|Lifetime|AddressSpace| PtrAuth | |
808 | uint64_t Mask = 0; |
809 | static_assert(sizeof(PointerAuthQualifier) == sizeof(uint32_t), |
810 | "PointerAuthQualifier must be 32 bits" ); |
811 | |
812 | static constexpr uint64_t PtrAuthShift = 32; |
813 | static constexpr uint64_t PtrAuthMask = UINT64_C(0xffffffff) << PtrAuthShift; |
814 | |
815 | static constexpr uint64_t UMask = 0x8; |
816 | static constexpr uint64_t UShift = 3; |
817 | static constexpr uint64_t GCAttrMask = 0x30; |
818 | static constexpr uint64_t GCAttrShift = 4; |
819 | static constexpr uint64_t LifetimeMask = 0x1C0; |
820 | static constexpr uint64_t LifetimeShift = 6; |
821 | static constexpr uint64_t AddressSpaceMask = |
822 | ~(CVRMask | UMask | GCAttrMask | LifetimeMask | PtrAuthMask); |
823 | static constexpr uint64_t AddressSpaceShift = 9; |
824 | }; |
825 | |
826 | class QualifiersAndAtomic { |
827 | Qualifiers Quals; |
828 | bool HasAtomic; |
829 | |
830 | public: |
831 | QualifiersAndAtomic() : HasAtomic(false) {} |
832 | QualifiersAndAtomic(Qualifiers Quals, bool HasAtomic) |
833 | : Quals(Quals), HasAtomic(HasAtomic) {} |
834 | |
835 | operator Qualifiers() const { return Quals; } |
836 | |
837 | bool hasVolatile() const { return Quals.hasVolatile(); } |
838 | bool hasConst() const { return Quals.hasConst(); } |
839 | bool hasRestrict() const { return Quals.hasRestrict(); } |
840 | bool hasAtomic() const { return HasAtomic; } |
841 | |
842 | void addVolatile() { Quals.addVolatile(); } |
843 | void addConst() { Quals.addConst(); } |
844 | void addRestrict() { Quals.addRestrict(); } |
845 | void addAtomic() { HasAtomic = true; } |
846 | |
847 | void removeVolatile() { Quals.removeVolatile(); } |
848 | void removeConst() { Quals.removeConst(); } |
849 | void removeRestrict() { Quals.removeRestrict(); } |
850 | void removeAtomic() { HasAtomic = false; } |
851 | |
852 | QualifiersAndAtomic withVolatile() { |
853 | return {Quals.withVolatile(), HasAtomic}; |
854 | } |
855 | QualifiersAndAtomic withConst() { return {Quals.withConst(), HasAtomic}; } |
856 | QualifiersAndAtomic withRestrict() { |
857 | return {Quals.withRestrict(), HasAtomic}; |
858 | } |
859 | QualifiersAndAtomic withAtomic() { return {Quals, true}; } |
860 | |
861 | QualifiersAndAtomic &operator+=(Qualifiers RHS) { |
862 | Quals += RHS; |
863 | return *this; |
864 | } |
865 | }; |
866 | |
867 | /// A std::pair-like structure for storing a qualified type split |
868 | /// into its local qualifiers and its locally-unqualified type. |
869 | struct SplitQualType { |
870 | /// The locally-unqualified type. |
871 | const Type *Ty = nullptr; |
872 | |
873 | /// The local qualifiers. |
874 | Qualifiers Quals; |
875 | |
876 | SplitQualType() = default; |
877 | SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {} |
878 | |
879 | SplitQualType getSingleStepDesugaredType() const; // end of this file |
880 | |
881 | // Make std::tie work. |
882 | std::pair<const Type *,Qualifiers> asPair() const { |
883 | return std::pair<const Type *, Qualifiers>(Ty, Quals); |
884 | } |
885 | |
886 | friend bool operator==(SplitQualType a, SplitQualType b) { |
887 | return a.Ty == b.Ty && a.Quals == b.Quals; |
888 | } |
889 | friend bool operator!=(SplitQualType a, SplitQualType b) { |
890 | return a.Ty != b.Ty || a.Quals != b.Quals; |
891 | } |
892 | }; |
893 | |
894 | /// The kind of type we are substituting Objective-C type arguments into. |
895 | /// |
896 | /// The kind of substitution affects the replacement of type parameters when |
897 | /// no concrete type information is provided, e.g., when dealing with an |
898 | /// unspecialized type. |
899 | enum class ObjCSubstitutionContext { |
900 | /// An ordinary type. |
901 | Ordinary, |
902 | |
903 | /// The result type of a method or function. |
904 | Result, |
905 | |
906 | /// The parameter type of a method or function. |
907 | Parameter, |
908 | |
909 | /// The type of a property. |
910 | Property, |
911 | |
912 | /// The superclass of a type. |
913 | Superclass, |
914 | }; |
915 | |
916 | /// The kind of 'typeof' expression we're after. |
917 | enum class TypeOfKind : uint8_t { |
918 | Qualified, |
919 | Unqualified, |
920 | }; |
921 | |
922 | /// A (possibly-)qualified type. |
923 | /// |
924 | /// For efficiency, we don't store CV-qualified types as nodes on their |
925 | /// own: instead each reference to a type stores the qualifiers. This |
926 | /// greatly reduces the number of nodes we need to allocate for types (for |
927 | /// example we only need one for 'int', 'const int', 'volatile int', |
928 | /// 'const volatile int', etc). |
929 | /// |
930 | /// As an added efficiency bonus, instead of making this a pair, we |
931 | /// just store the two bits we care about in the low bits of the |
932 | /// pointer. To handle the packing/unpacking, we make QualType be a |
933 | /// simple wrapper class that acts like a smart pointer. A third bit |
934 | /// indicates whether there are extended qualifiers present, in which |
935 | /// case the pointer points to a special structure. |
936 | class QualType { |
937 | friend class QualifierCollector; |
938 | |
939 | // Thankfully, these are efficiently composable. |
940 | llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>, |
941 | Qualifiers::FastWidth> Value; |
942 | |
943 | const ExtQuals *getExtQualsUnsafe() const { |
944 | return cast<const ExtQuals *>(Value.getPointer()); |
945 | } |
946 | |
947 | const Type *getTypePtrUnsafe() const { |
948 | return cast<const Type *>(Value.getPointer()); |
949 | } |
950 | |
951 | const ExtQualsTypeCommonBase *getCommonPtr() const { |
952 | assert(!isNull() && "Cannot retrieve a NULL type pointer" ); |
953 | auto CommonPtrVal = reinterpret_cast<uintptr_t>(Value.getOpaqueValue()); |
954 | CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1); |
955 | return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal); |
956 | } |
957 | |
958 | public: |
959 | QualType() = default; |
960 | QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {} |
961 | QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {} |
962 | |
963 | unsigned getLocalFastQualifiers() const { return Value.getInt(); } |
964 | void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } |
965 | |
966 | bool UseExcessPrecision(const ASTContext &Ctx); |
967 | |
968 | /// Retrieves a pointer to the underlying (unqualified) type. |
969 | /// |
970 | /// This function requires that the type not be NULL. If the type might be |
971 | /// NULL, use the (slightly less efficient) \c getTypePtrOrNull(). |
972 | const Type *getTypePtr() const; |
973 | |
974 | const Type *getTypePtrOrNull() const; |
975 | |
976 | /// Retrieves a pointer to the name of the base type. |
977 | const IdentifierInfo *getBaseTypeIdentifier() const; |
978 | |
979 | /// Divides a QualType into its unqualified type and a set of local |
980 | /// qualifiers. |
981 | SplitQualType split() const; |
982 | |
983 | void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } |
984 | |
985 | static QualType getFromOpaquePtr(const void *Ptr) { |
986 | QualType T; |
987 | T.Value.setFromOpaqueValue(const_cast<void*>(Ptr)); |
988 | return T; |
989 | } |
990 | |
991 | const Type &operator*() const { |
992 | return *getTypePtr(); |
993 | } |
994 | |
995 | const Type *operator->() const { |
996 | return getTypePtr(); |
997 | } |
998 | |
999 | bool isCanonical() const; |
1000 | bool isCanonicalAsParam() const; |
1001 | |
1002 | /// Return true if this QualType doesn't point to a type yet. |
1003 | bool isNull() const { |
1004 | return Value.getPointer().isNull(); |
1005 | } |
1006 | |
1007 | // Determines if a type can form `T&`. |
1008 | bool isReferenceable() const; |
1009 | |
1010 | /// Determine whether this particular QualType instance has the |
1011 | /// "const" qualifier set, without looking through typedefs that may have |
1012 | /// added "const" at a different level. |
1013 | bool isLocalConstQualified() const { |
1014 | return (getLocalFastQualifiers() & Qualifiers::Const); |
1015 | } |
1016 | |
1017 | /// Determine whether this type is const-qualified. |
1018 | bool isConstQualified() const; |
1019 | |
1020 | enum class NonConstantStorageReason { |
1021 | MutableField, |
1022 | NonConstNonReferenceType, |
1023 | NonTrivialCtor, |
1024 | NonTrivialDtor, |
1025 | }; |
1026 | /// Determine whether instances of this type can be placed in immutable |
1027 | /// storage. |
1028 | /// If ExcludeCtor is true, the duration when the object's constructor runs |
1029 | /// will not be considered. The caller will need to verify that the object is |
1030 | /// not written to during its construction. ExcludeDtor works similarly. |
1031 | std::optional<NonConstantStorageReason> |
1032 | isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, |
1033 | bool ExcludeDtor); |
1034 | |
1035 | bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, |
1036 | bool ExcludeDtor) { |
1037 | return !isNonConstantStorage(Ctx, ExcludeCtor, ExcludeDtor); |
1038 | } |
1039 | |
1040 | /// Determine whether this particular QualType instance has the |
1041 | /// "restrict" qualifier set, without looking through typedefs that may have |
1042 | /// added "restrict" at a different level. |
1043 | bool isLocalRestrictQualified() const { |
1044 | return (getLocalFastQualifiers() & Qualifiers::Restrict); |
1045 | } |
1046 | |
1047 | /// Determine whether this type is restrict-qualified. |
1048 | bool isRestrictQualified() const; |
1049 | |
1050 | /// Determine whether this particular QualType instance has the |
1051 | /// "volatile" qualifier set, without looking through typedefs that may have |
1052 | /// added "volatile" at a different level. |
1053 | bool isLocalVolatileQualified() const { |
1054 | return (getLocalFastQualifiers() & Qualifiers::Volatile); |
1055 | } |
1056 | |
1057 | /// Determine whether this type is volatile-qualified. |
1058 | bool isVolatileQualified() const; |
1059 | |
1060 | /// Determine whether this particular QualType instance has any |
1061 | /// qualifiers, without looking through any typedefs that might add |
1062 | /// qualifiers at a different level. |
1063 | bool hasLocalQualifiers() const { |
1064 | return getLocalFastQualifiers() || hasLocalNonFastQualifiers(); |
1065 | } |
1066 | |
1067 | /// Determine whether this type has any qualifiers. |
1068 | bool hasQualifiers() const; |
1069 | |
1070 | /// Determine whether this particular QualType instance has any |
1071 | /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType |
1072 | /// instance. |
1073 | bool hasLocalNonFastQualifiers() const { |
1074 | return isa<const ExtQuals *>(Value.getPointer()); |
1075 | } |
1076 | |
1077 | /// Retrieve the set of qualifiers local to this particular QualType |
1078 | /// instance, not including any qualifiers acquired through typedefs or |
1079 | /// other sugar. |
1080 | Qualifiers getLocalQualifiers() const; |
1081 | |
1082 | /// Retrieve the set of qualifiers applied to this type. |
1083 | Qualifiers getQualifiers() const; |
1084 | |
1085 | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers |
1086 | /// local to this particular QualType instance, not including any qualifiers |
1087 | /// acquired through typedefs or other sugar. |
1088 | unsigned getLocalCVRQualifiers() const { |
1089 | return getLocalFastQualifiers(); |
1090 | } |
1091 | |
1092 | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers |
1093 | /// applied to this type. |
1094 | unsigned getCVRQualifiers() const; |
1095 | |
1096 | bool isConstant(const ASTContext& Ctx) const { |
1097 | return QualType::isConstant(T: *this, Ctx); |
1098 | } |
1099 | |
1100 | /// Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). |
1101 | bool isPODType(const ASTContext &Context) const; |
1102 | |
1103 | /// Return true if this is a POD type according to the rules of the C++98 |
1104 | /// standard, regardless of the current compilation's language. |
1105 | bool isCXX98PODType(const ASTContext &Context) const; |
1106 | |
1107 | /// Return true if this is a POD type according to the more relaxed rules |
1108 | /// of the C++11 standard, regardless of the current compilation's language. |
1109 | /// (C++0x [basic.types]p9). Note that, unlike |
1110 | /// CXXRecordDecl::isCXX11StandardLayout, this takes DRs into account. |
1111 | bool isCXX11PODType(const ASTContext &Context) const; |
1112 | |
1113 | /// Return true if this is a trivial type per (C++0x [basic.types]p9) |
1114 | bool isTrivialType(const ASTContext &Context) const; |
1115 | |
1116 | /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) |
1117 | bool isTriviallyCopyableType(const ASTContext &Context) const; |
1118 | |
1119 | /// Return true if the type is safe to bitwise copy using memcpy/memmove. |
1120 | /// |
1121 | /// This is an extension in clang: bitwise cloneable types act as trivially |
1122 | /// copyable types, meaning their underlying bytes can be safely copied by |
1123 | /// memcpy or memmove. After the copy, the destination object has the same |
1124 | /// object representation. |
1125 | /// |
1126 | /// However, there are cases where it is not safe to copy: |
1127 | /// - When sanitizers, such as AddressSanitizer, add padding with poison, |
1128 | /// which can cause issues if those poisoned padding bits are accessed. |
1129 | /// - Types with Objective-C lifetimes, where specific runtime |
1130 | /// semantics may not be preserved during a bitwise copy. |
1131 | bool isBitwiseCloneableType(const ASTContext &Context) const; |
1132 | |
1133 | /// Return true if this is a trivially copyable type |
1134 | bool isTriviallyCopyConstructibleType(const ASTContext &Context) const; |
1135 | |
1136 | /// Returns true if it is a class and it might be dynamic. |
1137 | bool mayBeDynamicClass() const; |
1138 | |
1139 | /// Returns true if it is not a class or if the class might not be dynamic. |
1140 | bool mayBeNotDynamicClass() const; |
1141 | |
1142 | /// Returns true if it is a WebAssembly Reference Type. |
1143 | bool isWebAssemblyReferenceType() const; |
1144 | |
1145 | /// Returns true if it is a WebAssembly Externref Type. |
1146 | bool isWebAssemblyExternrefType() const; |
1147 | |
1148 | /// Returns true if it is a WebAssembly Funcref Type. |
1149 | bool isWebAssemblyFuncrefType() const; |
1150 | |
1151 | // Don't promise in the API that anything besides 'const' can be |
1152 | // easily added. |
1153 | |
1154 | /// Add the `const` type qualifier to this QualType. |
1155 | void addConst() { |
1156 | addFastQualifiers(TQs: Qualifiers::Const); |
1157 | } |
1158 | QualType withConst() const { |
1159 | return withFastQualifiers(TQs: Qualifiers::Const); |
1160 | } |
1161 | |
1162 | /// Add the `volatile` type qualifier to this QualType. |
1163 | void addVolatile() { |
1164 | addFastQualifiers(TQs: Qualifiers::Volatile); |
1165 | } |
1166 | QualType withVolatile() const { |
1167 | return withFastQualifiers(TQs: Qualifiers::Volatile); |
1168 | } |
1169 | |
1170 | /// Add the `restrict` qualifier to this QualType. |
1171 | void addRestrict() { |
1172 | addFastQualifiers(TQs: Qualifiers::Restrict); |
1173 | } |
1174 | QualType withRestrict() const { |
1175 | return withFastQualifiers(TQs: Qualifiers::Restrict); |
1176 | } |
1177 | |
1178 | QualType withCVRQualifiers(unsigned CVR) const { |
1179 | return withFastQualifiers(TQs: CVR); |
1180 | } |
1181 | |
1182 | void addFastQualifiers(unsigned TQs) { |
1183 | assert(!(TQs & ~Qualifiers::FastMask) |
1184 | && "non-fast qualifier bits set in mask!" ); |
1185 | Value.setInt(Value.getInt() | TQs); |
1186 | } |
1187 | |
1188 | void removeLocalConst(); |
1189 | void removeLocalVolatile(); |
1190 | void removeLocalRestrict(); |
1191 | |
1192 | void removeLocalFastQualifiers() { Value.setInt(0); } |
1193 | void removeLocalFastQualifiers(unsigned Mask) { |
1194 | assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers" ); |
1195 | Value.setInt(Value.getInt() & ~Mask); |
1196 | } |
1197 | |
1198 | // Creates a type with the given qualifiers in addition to any |
1199 | // qualifiers already on this type. |
1200 | QualType withFastQualifiers(unsigned TQs) const { |
1201 | QualType T = *this; |
1202 | T.addFastQualifiers(TQs); |
1203 | return T; |
1204 | } |
1205 | |
1206 | // Creates a type with exactly the given fast qualifiers, removing |
1207 | // any existing fast qualifiers. |
1208 | QualType withExactLocalFastQualifiers(unsigned TQs) const { |
1209 | return withoutLocalFastQualifiers().withFastQualifiers(TQs); |
1210 | } |
1211 | |
1212 | // Removes fast qualifiers, but leaves any extended qualifiers in place. |
1213 | QualType withoutLocalFastQualifiers() const { |
1214 | QualType T = *this; |
1215 | T.removeLocalFastQualifiers(); |
1216 | return T; |
1217 | } |
1218 | |
1219 | QualType getCanonicalType() const; |
1220 | |
1221 | /// Return this type with all of the instance-specific qualifiers |
1222 | /// removed, but without removing any qualifiers that may have been applied |
1223 | /// through typedefs. |
1224 | QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); } |
1225 | |
1226 | /// Retrieve the unqualified variant of the given type, |
1227 | /// removing as little sugar as possible. |
1228 | /// |
1229 | /// This routine looks through various kinds of sugar to find the |
1230 | /// least-desugared type that is unqualified. For example, given: |
1231 | /// |
1232 | /// \code |
1233 | /// typedef int Integer; |
1234 | /// typedef const Integer CInteger; |
1235 | /// typedef CInteger DifferenceType; |
1236 | /// \endcode |
1237 | /// |
1238 | /// Executing \c getUnqualifiedType() on the type \c DifferenceType will |
1239 | /// desugar until we hit the type \c Integer, which has no qualifiers on it. |
1240 | /// |
1241 | /// The resulting type might still be qualified if it's sugar for an array |
1242 | /// type. To strip qualifiers even from within a sugared array type, use |
1243 | /// ASTContext::getUnqualifiedArrayType. |
1244 | /// |
1245 | /// Note: In C, the _Atomic qualifier is special (see C23 6.2.5p32 for |
1246 | /// details), and it is not stripped by this function. Use |
1247 | /// getAtomicUnqualifiedType() to strip qualifiers including _Atomic. |
1248 | inline QualType getUnqualifiedType() const; |
1249 | |
1250 | /// Retrieve the unqualified variant of the given type, removing as little |
1251 | /// sugar as possible. |
1252 | /// |
1253 | /// Like getUnqualifiedType(), but also returns the set of |
1254 | /// qualifiers that were built up. |
1255 | /// |
1256 | /// The resulting type might still be qualified if it's sugar for an array |
1257 | /// type. To strip qualifiers even from within a sugared array type, use |
1258 | /// ASTContext::getUnqualifiedArrayType. |
1259 | inline SplitQualType getSplitUnqualifiedType() const; |
1260 | |
1261 | /// Determine whether this type is more qualified than the other |
1262 | /// given type, requiring exact equality for non-CVR qualifiers. |
1263 | bool isMoreQualifiedThan(QualType Other, const ASTContext &Ctx) const; |
1264 | |
1265 | /// Determine whether this type is at least as qualified as the other |
1266 | /// given type, requiring exact equality for non-CVR qualifiers. |
1267 | bool isAtLeastAsQualifiedAs(QualType Other, const ASTContext &Ctx) const; |
1268 | |
1269 | QualType getNonReferenceType() const; |
1270 | |
1271 | /// Determine the type of a (typically non-lvalue) expression with the |
1272 | /// specified result type. |
1273 | /// |
1274 | /// This routine should be used for expressions for which the return type is |
1275 | /// explicitly specified (e.g., in a cast or call) and isn't necessarily |
1276 | /// an lvalue. It removes a top-level reference (since there are no |
1277 | /// expressions of reference type) and deletes top-level cvr-qualifiers |
1278 | /// from non-class types (in C++) or all types (in C). |
1279 | QualType getNonLValueExprType(const ASTContext &Context) const; |
1280 | |
1281 | /// Remove an outer pack expansion type (if any) from this type. Used as part |
1282 | /// of converting the type of a declaration to the type of an expression that |
1283 | /// references that expression. It's meaningless for an expression to have a |
1284 | /// pack expansion type. |
1285 | QualType getNonPackExpansionType() const; |
1286 | |
1287 | /// Return the specified type with any "sugar" removed from |
1288 | /// the type. This takes off typedefs, typeof's etc. If the outer level of |
1289 | /// the type is already concrete, it returns it unmodified. This is similar |
1290 | /// to getting the canonical type, but it doesn't remove *all* typedefs. For |
1291 | /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is |
1292 | /// concrete. |
1293 | /// |
1294 | /// Qualifiers are left in place. |
1295 | QualType getDesugaredType(const ASTContext &Context) const { |
1296 | return getDesugaredType(T: *this, Context); |
1297 | } |
1298 | |
1299 | SplitQualType getSplitDesugaredType() const { |
1300 | return getSplitDesugaredType(T: *this); |
1301 | } |
1302 | |
1303 | /// Return the specified type with one level of "sugar" removed from |
1304 | /// the type. |
1305 | /// |
1306 | /// This routine takes off the first typedef, typeof, etc. If the outer level |
1307 | /// of the type is already concrete, it returns it unmodified. |
1308 | QualType getSingleStepDesugaredType(const ASTContext &Context) const { |
1309 | return getSingleStepDesugaredTypeImpl(type: *this, C: Context); |
1310 | } |
1311 | |
1312 | /// Returns the specified type after dropping any |
1313 | /// outer-level parentheses. |
1314 | QualType IgnoreParens() const { |
1315 | if (isa<ParenType>(*this)) |
1316 | return QualType::IgnoreParens(T: *this); |
1317 | return *this; |
1318 | } |
1319 | |
1320 | /// Indicate whether the specified types and qualifiers are identical. |
1321 | friend bool operator==(const QualType &LHS, const QualType &RHS) { |
1322 | return LHS.Value == RHS.Value; |
1323 | } |
1324 | friend bool operator!=(const QualType &LHS, const QualType &RHS) { |
1325 | return LHS.Value != RHS.Value; |
1326 | } |
1327 | friend bool operator<(const QualType &LHS, const QualType &RHS) { |
1328 | return LHS.Value < RHS.Value; |
1329 | } |
1330 | |
1331 | static std::string getAsString(SplitQualType split, |
1332 | const PrintingPolicy &Policy) { |
1333 | return getAsString(ty: split.Ty, qs: split.Quals, Policy); |
1334 | } |
1335 | static std::string getAsString(const Type *ty, Qualifiers qs, |
1336 | const PrintingPolicy &Policy); |
1337 | |
1338 | std::string getAsString() const; |
1339 | std::string getAsString(const PrintingPolicy &Policy) const; |
1340 | |
1341 | void print(raw_ostream &OS, const PrintingPolicy &Policy, |
1342 | const Twine &PlaceHolder = Twine(), |
1343 | unsigned Indentation = 0) const; |
1344 | |
1345 | static void print(SplitQualType split, raw_ostream &OS, |
1346 | const PrintingPolicy &policy, const Twine &PlaceHolder, |
1347 | unsigned Indentation = 0) { |
1348 | return print(ty: split.Ty, qs: split.Quals, OS, policy, PlaceHolder, Indentation); |
1349 | } |
1350 | |
1351 | static void print(const Type *ty, Qualifiers qs, |
1352 | raw_ostream &OS, const PrintingPolicy &policy, |
1353 | const Twine &PlaceHolder, |
1354 | unsigned Indentation = 0); |
1355 | |
1356 | void getAsStringInternal(std::string &Str, |
1357 | const PrintingPolicy &Policy) const; |
1358 | |
1359 | static void getAsStringInternal(SplitQualType split, std::string &out, |
1360 | const PrintingPolicy &policy) { |
1361 | return getAsStringInternal(ty: split.Ty, qs: split.Quals, out, policy); |
1362 | } |
1363 | |
1364 | static void getAsStringInternal(const Type *ty, Qualifiers qs, |
1365 | std::string &out, |
1366 | const PrintingPolicy &policy); |
1367 | |
1368 | class StreamedQualTypeHelper { |
1369 | const QualType &T; |
1370 | const PrintingPolicy &Policy; |
1371 | const Twine &PlaceHolder; |
1372 | unsigned Indentation; |
1373 | |
1374 | public: |
1375 | StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, |
1376 | const Twine &PlaceHolder, unsigned Indentation) |
1377 | : T(T), Policy(Policy), PlaceHolder(PlaceHolder), |
1378 | Indentation(Indentation) {} |
1379 | |
1380 | friend raw_ostream &operator<<(raw_ostream &OS, |
1381 | const StreamedQualTypeHelper &SQT) { |
1382 | SQT.T.print(OS, Policy: SQT.Policy, PlaceHolder: SQT.PlaceHolder, Indentation: SQT.Indentation); |
1383 | return OS; |
1384 | } |
1385 | }; |
1386 | |
1387 | StreamedQualTypeHelper stream(const PrintingPolicy &Policy, |
1388 | const Twine &PlaceHolder = Twine(), |
1389 | unsigned Indentation = 0) const { |
1390 | return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation); |
1391 | } |
1392 | |
1393 | void dump(const char *s) const; |
1394 | void dump() const; |
1395 | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; |
1396 | |
1397 | void Profile(llvm::FoldingSetNodeID &ID) const { |
1398 | ID.AddPointer(Ptr: getAsOpaquePtr()); |
1399 | } |
1400 | |
1401 | /// Check if this type has any address space qualifier. |
1402 | inline bool hasAddressSpace() const; |
1403 | |
1404 | /// Return the address space of this type. |
1405 | inline LangAS getAddressSpace() const; |
1406 | |
1407 | /// Returns true if address space qualifiers overlap with T address space |
1408 | /// qualifiers. |
1409 | /// OpenCL C defines conversion rules for pointers to different address spaces |
1410 | /// and notion of overlapping address spaces. |
1411 | /// CL1.1 or CL1.2: |
1412 | /// address spaces overlap iff they are they same. |
1413 | /// OpenCL C v2.0 s6.5.5 adds: |
1414 | /// __generic overlaps with any address space except for __constant. |
1415 | bool isAddressSpaceOverlapping(QualType T, const ASTContext &Ctx) const { |
1416 | Qualifiers Q = getQualifiers(); |
1417 | Qualifiers TQ = T.getQualifiers(); |
1418 | // Address spaces overlap if at least one of them is a superset of another |
1419 | return Q.isAddressSpaceSupersetOf(other: TQ, Ctx) || |
1420 | TQ.isAddressSpaceSupersetOf(other: Q, Ctx); |
1421 | } |
1422 | |
1423 | /// Returns gc attribute of this type. |
1424 | inline Qualifiers::GC getObjCGCAttr() const; |
1425 | |
1426 | /// true when Type is objc's weak. |
1427 | bool isObjCGCWeak() const { |
1428 | return getObjCGCAttr() == Qualifiers::Weak; |
1429 | } |
1430 | |
1431 | /// true when Type is objc's strong. |
1432 | bool isObjCGCStrong() const { |
1433 | return getObjCGCAttr() == Qualifiers::Strong; |
1434 | } |
1435 | |
1436 | /// Returns lifetime attribute of this type. |
1437 | Qualifiers::ObjCLifetime getObjCLifetime() const { |
1438 | return getQualifiers().getObjCLifetime(); |
1439 | } |
1440 | |
1441 | bool hasNonTrivialObjCLifetime() const { |
1442 | return getQualifiers().hasNonTrivialObjCLifetime(); |
1443 | } |
1444 | |
1445 | bool hasStrongOrWeakObjCLifetime() const { |
1446 | return getQualifiers().hasStrongOrWeakObjCLifetime(); |
1447 | } |
1448 | |
1449 | // true when Type is objc's weak and weak is enabled but ARC isn't. |
1450 | bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const; |
1451 | |
1452 | PointerAuthQualifier getPointerAuth() const { |
1453 | return getQualifiers().getPointerAuth(); |
1454 | } |
1455 | |
1456 | bool hasAddressDiscriminatedPointerAuth() const { |
1457 | if (PointerAuthQualifier PtrAuth = getPointerAuth()) |
1458 | return PtrAuth.isAddressDiscriminated(); |
1459 | return false; |
1460 | } |
1461 | |
1462 | enum PrimitiveDefaultInitializeKind { |
1463 | /// The type does not fall into any of the following categories. Note that |
1464 | /// this case is zero-valued so that values of this enum can be used as a |
1465 | /// boolean condition for non-triviality. |
1466 | PDIK_Trivial, |
1467 | |
1468 | /// The type is an Objective-C retainable pointer type that is qualified |
1469 | /// with the ARC __strong qualifier. |
1470 | PDIK_ARCStrong, |
1471 | |
1472 | /// The type is an Objective-C retainable pointer type that is qualified |
1473 | /// with the ARC __weak qualifier. |
1474 | PDIK_ARCWeak, |
1475 | |
1476 | /// The type is a struct containing a field whose type is not PCK_Trivial. |
1477 | PDIK_Struct |
1478 | }; |
1479 | |
1480 | /// Functions to query basic properties of non-trivial C struct types. |
1481 | |
1482 | /// Check if this is a non-trivial type that would cause a C struct |
1483 | /// transitively containing this type to be non-trivial to default initialize |
1484 | /// and return the kind. |
1485 | PrimitiveDefaultInitializeKind |
1486 | isNonTrivialToPrimitiveDefaultInitialize() const; |
1487 | |
1488 | enum PrimitiveCopyKind { |
1489 | /// The type does not fall into any of the following categories. Note that |
1490 | /// this case is zero-valued so that values of this enum can be used as a |
1491 | /// boolean condition for non-triviality. |
1492 | PCK_Trivial, |
1493 | |
1494 | /// The type would be trivial except that it is volatile-qualified. Types |
1495 | /// that fall into one of the other non-trivial cases may additionally be |
1496 | /// volatile-qualified. |
1497 | PCK_VolatileTrivial, |
1498 | |
1499 | /// The type is an Objective-C retainable pointer type that is qualified |
1500 | /// with the ARC __strong qualifier. |
1501 | PCK_ARCStrong, |
1502 | |
1503 | /// The type is an Objective-C retainable pointer type that is qualified |
1504 | /// with the ARC __weak qualifier. |
1505 | PCK_ARCWeak, |
1506 | |
1507 | /// The type is an address-discriminated signed pointer type. |
1508 | PCK_PtrAuth, |
1509 | |
1510 | /// The type is a struct containing a field whose type is neither |
1511 | /// PCK_Trivial nor PCK_VolatileTrivial. |
1512 | /// Note that a C++ struct type does not necessarily match this; C++ copying |
1513 | /// semantics are too complex to express here, in part because they depend |
1514 | /// on the exact constructor or assignment operator that is chosen by |
1515 | /// overload resolution to do the copy. |
1516 | PCK_Struct |
1517 | }; |
1518 | |
1519 | /// Check if this is a non-trivial type that would cause a C struct |
1520 | /// transitively containing this type to be non-trivial to copy and return the |
1521 | /// kind. |
1522 | PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const; |
1523 | |
1524 | /// Check if this is a non-trivial type that would cause a C struct |
1525 | /// transitively containing this type to be non-trivial to destructively |
1526 | /// move and return the kind. Destructive move in this context is a C++-style |
1527 | /// move in which the source object is placed in a valid but unspecified state |
1528 | /// after it is moved, as opposed to a truly destructive move in which the |
1529 | /// source object is placed in an uninitialized state. |
1530 | PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const; |
1531 | |
1532 | enum DestructionKind { |
1533 | DK_none, |
1534 | DK_cxx_destructor, |
1535 | DK_objc_strong_lifetime, |
1536 | DK_objc_weak_lifetime, |
1537 | DK_nontrivial_c_struct |
1538 | }; |
1539 | |
1540 | /// Returns a nonzero value if objects of this type require |
1541 | /// non-trivial work to clean up after. Non-zero because it's |
1542 | /// conceivable that qualifiers (objc_gc(weak)?) could make |
1543 | /// something require destruction. |
1544 | DestructionKind isDestructedType() const { |
1545 | return isDestructedTypeImpl(type: *this); |
1546 | } |
1547 | |
1548 | /// Check if this is or contains a C union that is non-trivial to |
1549 | /// default-initialize, which is a union that has a member that is non-trivial |
1550 | /// to default-initialize. If this returns true, |
1551 | /// isNonTrivialToPrimitiveDefaultInitialize returns PDIK_Struct. |
1552 | bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const; |
1553 | |
1554 | /// Check if this is or contains a C union that is non-trivial to destruct, |
1555 | /// which is a union that has a member that is non-trivial to destruct. If |
1556 | /// this returns true, isDestructedType returns DK_nontrivial_c_struct. |
1557 | bool hasNonTrivialToPrimitiveDestructCUnion() const; |
1558 | |
1559 | /// Check if this is or contains a C union that is non-trivial to copy, which |
1560 | /// is a union that has a member that is non-trivial to copy. If this returns |
1561 | /// true, isNonTrivialToPrimitiveCopy returns PCK_Struct. |
1562 | bool hasNonTrivialToPrimitiveCopyCUnion() const; |
1563 | |
1564 | /// Determine whether expressions of the given type are forbidden |
1565 | /// from being lvalues in C. |
1566 | /// |
1567 | /// The expression types that are forbidden to be lvalues are: |
1568 | /// - 'void', but not qualified void |
1569 | /// - function types |
1570 | /// |
1571 | /// The exact rule here is C99 6.3.2.1: |
1572 | /// An lvalue is an expression with an object type or an incomplete |
1573 | /// type other than void. |
1574 | bool isCForbiddenLValueType() const; |
1575 | |
1576 | /// Substitute type arguments for the Objective-C type parameters used in the |
1577 | /// subject type. |
1578 | /// |
1579 | /// \param ctx ASTContext in which the type exists. |
1580 | /// |
1581 | /// \param typeArgs The type arguments that will be substituted for the |
1582 | /// Objective-C type parameters in the subject type, which are generally |
1583 | /// computed via \c Type::getObjCSubstitutions. If empty, the type |
1584 | /// parameters will be replaced with their bounds or id/Class, as appropriate |
1585 | /// for the context. |
1586 | /// |
1587 | /// \param context The context in which the subject type was written. |
1588 | /// |
1589 | /// \returns the resulting type. |
1590 | QualType substObjCTypeArgs(ASTContext &ctx, |
1591 | ArrayRef<QualType> typeArgs, |
1592 | ObjCSubstitutionContext context) const; |
1593 | |
1594 | /// Substitute type arguments from an object type for the Objective-C type |
1595 | /// parameters used in the subject type. |
1596 | /// |
1597 | /// This operation combines the computation of type arguments for |
1598 | /// substitution (\c Type::getObjCSubstitutions) with the actual process of |
1599 | /// substitution (\c QualType::substObjCTypeArgs) for the convenience of |
1600 | /// callers that need to perform a single substitution in isolation. |
1601 | /// |
1602 | /// \param objectType The type of the object whose member type we're |
1603 | /// substituting into. For example, this might be the receiver of a message |
1604 | /// or the base of a property access. |
1605 | /// |
1606 | /// \param dc The declaration context from which the subject type was |
1607 | /// retrieved, which indicates (for example) which type parameters should |
1608 | /// be substituted. |
1609 | /// |
1610 | /// \param context The context in which the subject type was written. |
1611 | /// |
1612 | /// \returns the subject type after replacing all of the Objective-C type |
1613 | /// parameters with their corresponding arguments. |
1614 | QualType substObjCMemberType(QualType objectType, |
1615 | const DeclContext *dc, |
1616 | ObjCSubstitutionContext context) const; |
1617 | |
1618 | /// Strip Objective-C "__kindof" types from the given type. |
1619 | QualType stripObjCKindOfType(const ASTContext &ctx) const; |
1620 | |
1621 | /// Remove all qualifiers including _Atomic. |
1622 | /// |
1623 | /// Like getUnqualifiedType(), the type may still be qualified if it is a |
1624 | /// sugared array type. To strip qualifiers even from within a sugared array |
1625 | /// type, use in conjunction with ASTContext::getUnqualifiedArrayType. |
1626 | QualType getAtomicUnqualifiedType() const; |
1627 | |
1628 | private: |
1629 | // These methods are implemented in a separate translation unit; |
1630 | // "static"-ize them to avoid creating temporary QualTypes in the |
1631 | // caller. |
1632 | static bool isConstant(QualType T, const ASTContext& Ctx); |
1633 | static QualType getDesugaredType(QualType T, const ASTContext &Context); |
1634 | static SplitQualType getSplitDesugaredType(QualType T); |
1635 | static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); |
1636 | static QualType getSingleStepDesugaredTypeImpl(QualType type, |
1637 | const ASTContext &C); |
1638 | static QualType IgnoreParens(QualType T); |
1639 | static DestructionKind isDestructedTypeImpl(QualType type); |
1640 | |
1641 | /// Check if \param RD is or contains a non-trivial C union. |
1642 | static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD); |
1643 | static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD); |
1644 | static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD); |
1645 | }; |
1646 | |
1647 | raw_ostream &operator<<(raw_ostream &OS, QualType QT); |
1648 | |
1649 | } // namespace clang |
1650 | |
1651 | namespace llvm { |
1652 | |
1653 | /// Implement simplify_type for QualType, so that we can dyn_cast from QualType |
1654 | /// to a specific Type class. |
1655 | template<> struct simplify_type< ::clang::QualType> { |
1656 | using SimpleType = const ::clang::Type *; |
1657 | |
1658 | static SimpleType getSimplifiedValue(::clang::QualType Val) { |
1659 | return Val.getTypePtr(); |
1660 | } |
1661 | }; |
1662 | |
1663 | // Teach SmallPtrSet that QualType is "basically a pointer". |
1664 | template<> |
1665 | struct PointerLikeTypeTraits<clang::QualType> { |
1666 | static inline void *getAsVoidPointer(clang::QualType P) { |
1667 | return P.getAsOpaquePtr(); |
1668 | } |
1669 | |
1670 | static inline clang::QualType getFromVoidPointer(void *P) { |
1671 | return clang::QualType::getFromOpaquePtr(Ptr: P); |
1672 | } |
1673 | |
1674 | // Various qualifiers go in low bits. |
1675 | static constexpr int NumLowBitsAvailable = 0; |
1676 | }; |
1677 | |
1678 | } // namespace llvm |
1679 | |
1680 | namespace clang { |
1681 | |
1682 | /// Base class that is common to both the \c ExtQuals and \c Type |
1683 | /// classes, which allows \c QualType to access the common fields between the |
1684 | /// two. |
1685 | class ExtQualsTypeCommonBase { |
1686 | friend class ExtQuals; |
1687 | friend class QualType; |
1688 | friend class Type; |
1689 | friend class ASTReader; |
1690 | |
1691 | /// The "base" type of an extended qualifiers type (\c ExtQuals) or |
1692 | /// a self-referential pointer (for \c Type). |
1693 | /// |
1694 | /// This pointer allows an efficient mapping from a QualType to its |
1695 | /// underlying type pointer. |
1696 | const Type *const BaseType; |
1697 | |
1698 | /// The canonical type of this type. A QualType. |
1699 | QualType CanonicalType; |
1700 | |
1701 | ExtQualsTypeCommonBase(const Type *baseType, QualType canon) |
1702 | : BaseType(baseType), CanonicalType(canon) {} |
1703 | }; |
1704 | |
1705 | /// We can encode up to four bits in the low bits of a |
1706 | /// type pointer, but there are many more type qualifiers that we want |
1707 | /// to be able to apply to an arbitrary type. Therefore we have this |
1708 | /// struct, intended to be heap-allocated and used by QualType to |
1709 | /// store qualifiers. |
1710 | /// |
1711 | /// The current design tags the 'const', 'restrict', and 'volatile' qualifiers |
1712 | /// in three low bits on the QualType pointer; a fourth bit records whether |
1713 | /// the pointer is an ExtQuals node. The extended qualifiers (address spaces, |
1714 | /// Objective-C GC attributes) are much more rare. |
1715 | class alignas(TypeAlignment) ExtQuals : public ExtQualsTypeCommonBase, |
1716 | public llvm::FoldingSetNode { |
1717 | // NOTE: changing the fast qualifiers should be straightforward as |
1718 | // long as you don't make 'const' non-fast. |
1719 | // 1. Qualifiers: |
1720 | // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ). |
1721 | // Fast qualifiers must occupy the low-order bits. |
1722 | // b) Update Qualifiers::FastWidth and FastMask. |
1723 | // 2. QualType: |
1724 | // a) Update is{Volatile,Restrict}Qualified(), defined inline. |
1725 | // b) Update remove{Volatile,Restrict}, defined near the end of |
1726 | // this header. |
1727 | // 3. ASTContext: |
1728 | // a) Update get{Volatile,Restrict}Type. |
1729 | |
1730 | /// The immutable set of qualifiers applied by this node. Always contains |
1731 | /// extended qualifiers. |
1732 | Qualifiers Quals; |
1733 | |
1734 | ExtQuals *this_() { return this; } |
1735 | |
1736 | public: |
1737 | ExtQuals(const Type *baseType, QualType canon, Qualifiers quals) |
1738 | : ExtQualsTypeCommonBase(baseType, |
1739 | canon.isNull() ? QualType(this_(), 0) : canon), |
1740 | Quals(quals) { |
1741 | assert(Quals.hasNonFastQualifiers() |
1742 | && "ExtQuals created with no fast qualifiers" ); |
1743 | assert(!Quals.hasFastQualifiers() |
1744 | && "ExtQuals created with fast qualifiers" ); |
1745 | } |
1746 | |
1747 | Qualifiers getQualifiers() const { return Quals; } |
1748 | |
1749 | bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); } |
1750 | Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); } |
1751 | |
1752 | bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); } |
1753 | Qualifiers::ObjCLifetime getObjCLifetime() const { |
1754 | return Quals.getObjCLifetime(); |
1755 | } |
1756 | |
1757 | bool hasAddressSpace() const { return Quals.hasAddressSpace(); } |
1758 | LangAS getAddressSpace() const { return Quals.getAddressSpace(); } |
1759 | |
1760 | const Type *getBaseType() const { return BaseType; } |
1761 | |
1762 | public: |
1763 | void Profile(llvm::FoldingSetNodeID &ID) const { |
1764 | Profile(ID, BaseType: getBaseType(), Quals); |
1765 | } |
1766 | |
1767 | static void Profile(llvm::FoldingSetNodeID &ID, |
1768 | const Type *BaseType, |
1769 | Qualifiers Quals) { |
1770 | assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!" ); |
1771 | ID.AddPointer(Ptr: BaseType); |
1772 | Quals.Profile(ID); |
1773 | } |
1774 | }; |
1775 | |
1776 | /// The kind of C++11 ref-qualifier associated with a function type. |
1777 | /// This determines whether a member function's "this" object can be an |
1778 | /// lvalue, rvalue, or neither. |
1779 | enum RefQualifierKind { |
1780 | /// No ref-qualifier was provided. |
1781 | RQ_None = 0, |
1782 | |
1783 | /// An lvalue ref-qualifier was provided (\c &). |
1784 | RQ_LValue, |
1785 | |
1786 | /// An rvalue ref-qualifier was provided (\c &&). |
1787 | RQ_RValue |
1788 | }; |
1789 | |
1790 | /// Which keyword(s) were used to create an AutoType. |
1791 | enum class AutoTypeKeyword { |
1792 | /// auto |
1793 | Auto, |
1794 | |
1795 | /// decltype(auto) |
1796 | DecltypeAuto, |
1797 | |
1798 | /// __auto_type (GNU extension) |
1799 | GNUAutoType |
1800 | }; |
1801 | |
1802 | enum class ArraySizeModifier; |
1803 | enum class ElaboratedTypeKeyword; |
1804 | enum class VectorKind; |
1805 | |
1806 | /// The base class of the type hierarchy. |
1807 | /// |
1808 | /// A central concept with types is that each type always has a canonical |
1809 | /// type. A canonical type is the type with any typedef names stripped out |
1810 | /// of it or the types it references. For example, consider: |
1811 | /// |
1812 | /// typedef int foo; |
1813 | /// typedef foo* bar; |
1814 | /// 'int *' 'foo *' 'bar' |
1815 | /// |
1816 | /// There will be a Type object created for 'int'. Since int is canonical, its |
1817 | /// CanonicalType pointer points to itself. There is also a Type for 'foo' (a |
1818 | /// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next |
1819 | /// there is a PointerType that represents 'int*', which, like 'int', is |
1820 | /// canonical. Finally, there is a PointerType type for 'foo*' whose canonical |
1821 | /// type is 'int*', and there is a TypedefType for 'bar', whose canonical type |
1822 | /// is also 'int*'. |
1823 | /// |
1824 | /// Non-canonical types are useful for emitting diagnostics, without losing |
1825 | /// information about typedefs being used. Canonical types are useful for type |
1826 | /// comparisons (they allow by-pointer equality tests) and useful for reasoning |
1827 | /// about whether something has a particular form (e.g. is a function type), |
1828 | /// because they implicitly, recursively, strip all typedefs out of a type. |
1829 | /// |
1830 | /// Types, once created, are immutable. |
1831 | /// |
1832 | class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { |
1833 | public: |
1834 | enum TypeClass { |
1835 | #define TYPE(Class, Base) Class, |
1836 | #define LAST_TYPE(Class) TypeLast = Class |
1837 | #define ABSTRACT_TYPE(Class, Base) |
1838 | #include "clang/AST/TypeNodes.inc" |
1839 | }; |
1840 | |
1841 | private: |
1842 | /// Bitfields required by the Type class. |
1843 | class TypeBitfields { |
1844 | friend class Type; |
1845 | template <class T> friend class TypePropertyCache; |
1846 | |
1847 | /// TypeClass bitfield - Enum that specifies what subclass this belongs to. |
1848 | LLVM_PREFERRED_TYPE(TypeClass) |
1849 | unsigned TC : 8; |
1850 | |
1851 | /// Store information on the type dependency. |
1852 | LLVM_PREFERRED_TYPE(TypeDependence) |
1853 | unsigned Dependence : llvm::BitWidth<TypeDependence>; |
1854 | |
1855 | /// True if the cache (i.e. the bitfields here starting with |
1856 | /// 'Cache') is valid. |
1857 | LLVM_PREFERRED_TYPE(bool) |
1858 | mutable unsigned CacheValid : 1; |
1859 | |
1860 | /// Linkage of this type. |
1861 | LLVM_PREFERRED_TYPE(Linkage) |
1862 | mutable unsigned CachedLinkage : 3; |
1863 | |
1864 | /// Whether this type involves and local or unnamed types. |
1865 | LLVM_PREFERRED_TYPE(bool) |
1866 | mutable unsigned CachedLocalOrUnnamed : 1; |
1867 | |
1868 | /// Whether this type comes from an AST file. |
1869 | LLVM_PREFERRED_TYPE(bool) |
1870 | mutable unsigned FromAST : 1; |
1871 | |
1872 | bool isCacheValid() const { |
1873 | return CacheValid; |
1874 | } |
1875 | |
1876 | Linkage getLinkage() const { |
1877 | assert(isCacheValid() && "getting linkage from invalid cache" ); |
1878 | return static_cast<Linkage>(CachedLinkage); |
1879 | } |
1880 | |
1881 | bool hasLocalOrUnnamedType() const { |
1882 | assert(isCacheValid() && "getting linkage from invalid cache" ); |
1883 | return CachedLocalOrUnnamed; |
1884 | } |
1885 | }; |
1886 | enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 }; |
1887 | |
1888 | protected: |
1889 | // These classes allow subclasses to somewhat cleanly pack bitfields |
1890 | // into Type. |
1891 | |
1892 | class ArrayTypeBitfields { |
1893 | friend class ArrayType; |
1894 | |
1895 | LLVM_PREFERRED_TYPE(TypeBitfields) |
1896 | unsigned : NumTypeBits; |
1897 | |
1898 | /// CVR qualifiers from declarations like |
1899 | /// 'int X[static restrict 4]'. For function parameters only. |
1900 | LLVM_PREFERRED_TYPE(Qualifiers) |
1901 | unsigned IndexTypeQuals : 3; |
1902 | |
1903 | /// Storage class qualifiers from declarations like |
1904 | /// 'int X[static restrict 4]'. For function parameters only. |
1905 | LLVM_PREFERRED_TYPE(ArraySizeModifier) |
1906 | unsigned SizeModifier : 3; |
1907 | }; |
1908 | enum { NumArrayTypeBits = NumTypeBits + 6 }; |
1909 | |
1910 | class ConstantArrayTypeBitfields { |
1911 | friend class ConstantArrayType; |
1912 | |
1913 | LLVM_PREFERRED_TYPE(ArrayTypeBitfields) |
1914 | unsigned : NumArrayTypeBits; |
1915 | |
1916 | /// Whether we have a stored size expression. |
1917 | LLVM_PREFERRED_TYPE(bool) |
1918 | unsigned HasExternalSize : 1; |
1919 | |
1920 | LLVM_PREFERRED_TYPE(unsigned) |
1921 | unsigned SizeWidth : 5; |
1922 | }; |
1923 | |
1924 | class BuiltinTypeBitfields { |
1925 | friend class BuiltinType; |
1926 | |
1927 | LLVM_PREFERRED_TYPE(TypeBitfields) |
1928 | unsigned : NumTypeBits; |
1929 | |
1930 | /// The kind (BuiltinType::Kind) of builtin type this is. |
1931 | static constexpr unsigned NumOfBuiltinTypeBits = 9; |
1932 | unsigned Kind : NumOfBuiltinTypeBits; |
1933 | }; |
1934 | |
1935 | public: |
1936 | static constexpr int FunctionTypeNumParamsWidth = 16; |
1937 | static constexpr int FunctionTypeNumParamsLimit = (1 << 16) - 1; |
1938 | |
1939 | protected: |
1940 | /// FunctionTypeBitfields store various bits belonging to FunctionProtoType. |
1941 | /// Only common bits are stored here. Additional uncommon bits are stored |
1942 | /// in a trailing object after FunctionProtoType. |
1943 | class FunctionTypeBitfields { |
1944 | friend class FunctionProtoType; |
1945 | friend class FunctionType; |
1946 | |
1947 | LLVM_PREFERRED_TYPE(TypeBitfields) |
1948 | unsigned : NumTypeBits; |
1949 | |
1950 | /// The ref-qualifier associated with a \c FunctionProtoType. |
1951 | /// |
1952 | /// This is a value of type \c RefQualifierKind. |
1953 | LLVM_PREFERRED_TYPE(RefQualifierKind) |
1954 | unsigned RefQualifier : 2; |
1955 | |
1956 | /// Used only by FunctionProtoType, put here to pack with the |
1957 | /// other bitfields. |
1958 | /// The qualifiers are part of FunctionProtoType because... |
1959 | /// |
1960 | /// C++ 8.3.5p4: The return type, the parameter type list and the |
1961 | /// cv-qualifier-seq, [...], are part of the function type. |
1962 | LLVM_PREFERRED_TYPE(Qualifiers) |
1963 | unsigned FastTypeQuals : Qualifiers::FastWidth; |
1964 | /// Whether this function has extended Qualifiers. |
1965 | LLVM_PREFERRED_TYPE(bool) |
1966 | unsigned HasExtQuals : 1; |
1967 | |
1968 | /// The type of exception specification this function has. |
1969 | LLVM_PREFERRED_TYPE(ExceptionSpecificationType) |
1970 | unsigned ExceptionSpecType : 4; |
1971 | |
1972 | /// Whether this function has extended parameter information. |
1973 | LLVM_PREFERRED_TYPE(bool) |
1974 | unsigned HasExtParameterInfos : 1; |
1975 | |
1976 | /// Whether this function has extra bitfields for the prototype. |
1977 | LLVM_PREFERRED_TYPE(bool) |
1978 | unsigned : 1; |
1979 | |
1980 | /// Whether the function is variadic. |
1981 | LLVM_PREFERRED_TYPE(bool) |
1982 | unsigned Variadic : 1; |
1983 | |
1984 | /// Whether this function has a trailing return type. |
1985 | LLVM_PREFERRED_TYPE(bool) |
1986 | unsigned HasTrailingReturn : 1; |
1987 | |
1988 | /// Whether this function has is a cfi unchecked callee. |
1989 | LLVM_PREFERRED_TYPE(bool) |
1990 | unsigned CFIUncheckedCallee : 1; |
1991 | |
1992 | /// Extra information which affects how the function is called, like |
1993 | /// regparm and the calling convention. |
1994 | LLVM_PREFERRED_TYPE(CallingConv) |
1995 | unsigned ExtInfo : 14; |
1996 | |
1997 | /// The number of parameters this function has, not counting '...'. |
1998 | /// According to [implimits] 8 bits should be enough here but this is |
1999 | /// somewhat easy to exceed with metaprogramming and so we would like to |
2000 | /// keep NumParams as wide as reasonably possible. |
2001 | unsigned NumParams : FunctionTypeNumParamsWidth; |
2002 | }; |
2003 | |
2004 | class ObjCObjectTypeBitfields { |
2005 | friend class ObjCObjectType; |
2006 | |
2007 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2008 | unsigned : NumTypeBits; |
2009 | |
2010 | /// The number of type arguments stored directly on this object type. |
2011 | unsigned NumTypeArgs : 7; |
2012 | |
2013 | /// The number of protocols stored directly on this object type. |
2014 | unsigned NumProtocols : 6; |
2015 | |
2016 | /// Whether this is a "kindof" type. |
2017 | LLVM_PREFERRED_TYPE(bool) |
2018 | unsigned IsKindOf : 1; |
2019 | }; |
2020 | |
2021 | class ReferenceTypeBitfields { |
2022 | friend class ReferenceType; |
2023 | |
2024 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2025 | unsigned : NumTypeBits; |
2026 | |
2027 | /// True if the type was originally spelled with an lvalue sigil. |
2028 | /// This is never true of rvalue references but can also be false |
2029 | /// on lvalue references because of C++0x [dcl.typedef]p9, |
2030 | /// as follows: |
2031 | /// |
2032 | /// typedef int &ref; // lvalue, spelled lvalue |
2033 | /// typedef int &&rvref; // rvalue |
2034 | /// ref &a; // lvalue, inner ref, spelled lvalue |
2035 | /// ref &&a; // lvalue, inner ref |
2036 | /// rvref &a; // lvalue, inner ref, spelled lvalue |
2037 | /// rvref &&a; // rvalue, inner ref |
2038 | LLVM_PREFERRED_TYPE(bool) |
2039 | unsigned SpelledAsLValue : 1; |
2040 | |
2041 | /// True if the inner type is a reference type. This only happens |
2042 | /// in non-canonical forms. |
2043 | LLVM_PREFERRED_TYPE(bool) |
2044 | unsigned InnerRef : 1; |
2045 | }; |
2046 | |
2047 | class TypeWithKeywordBitfields { |
2048 | friend class TypeWithKeyword; |
2049 | |
2050 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2051 | unsigned : NumTypeBits; |
2052 | |
2053 | /// An ElaboratedTypeKeyword. 8 bits for efficient access. |
2054 | LLVM_PREFERRED_TYPE(ElaboratedTypeKeyword) |
2055 | unsigned Keyword : 8; |
2056 | }; |
2057 | |
2058 | enum { NumTypeWithKeywordBits = NumTypeBits + 8 }; |
2059 | |
2060 | class ElaboratedTypeBitfields { |
2061 | friend class ElaboratedType; |
2062 | |
2063 | LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields) |
2064 | unsigned : NumTypeWithKeywordBits; |
2065 | |
2066 | /// Whether the ElaboratedType has a trailing OwnedTagDecl. |
2067 | LLVM_PREFERRED_TYPE(bool) |
2068 | unsigned HasOwnedTagDecl : 1; |
2069 | }; |
2070 | |
2071 | class VectorTypeBitfields { |
2072 | friend class VectorType; |
2073 | friend class DependentVectorType; |
2074 | |
2075 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2076 | unsigned : NumTypeBits; |
2077 | |
2078 | /// The kind of vector, either a generic vector type or some |
2079 | /// target-specific vector type such as for AltiVec or Neon. |
2080 | LLVM_PREFERRED_TYPE(VectorKind) |
2081 | unsigned VecKind : 4; |
2082 | /// The number of elements in the vector. |
2083 | uint32_t NumElements; |
2084 | }; |
2085 | |
2086 | class AttributedTypeBitfields { |
2087 | friend class AttributedType; |
2088 | |
2089 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2090 | unsigned : NumTypeBits; |
2091 | |
2092 | LLVM_PREFERRED_TYPE(attr::Kind) |
2093 | unsigned AttrKind : 32 - NumTypeBits; |
2094 | }; |
2095 | |
2096 | class AutoTypeBitfields { |
2097 | friend class AutoType; |
2098 | |
2099 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2100 | unsigned : NumTypeBits; |
2101 | |
2102 | /// Was this placeholder type spelled as 'auto', 'decltype(auto)', |
2103 | /// or '__auto_type'? AutoTypeKeyword value. |
2104 | LLVM_PREFERRED_TYPE(AutoTypeKeyword) |
2105 | unsigned Keyword : 2; |
2106 | |
2107 | /// The number of template arguments in the type-constraints, which is |
2108 | /// expected to be able to hold at least 1024 according to [implimits]. |
2109 | /// However as this limit is somewhat easy to hit with template |
2110 | /// metaprogramming we'd prefer to keep it as large as possible. |
2111 | /// At the moment it has been left as a non-bitfield since this type |
2112 | /// safely fits in 64 bits as an unsigned, so there is no reason to |
2113 | /// introduce the performance impact of a bitfield. |
2114 | unsigned NumArgs; |
2115 | }; |
2116 | |
2117 | class TypeOfBitfields { |
2118 | friend class TypeOfType; |
2119 | friend class TypeOfExprType; |
2120 | |
2121 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2122 | unsigned : NumTypeBits; |
2123 | LLVM_PREFERRED_TYPE(TypeOfKind) |
2124 | unsigned Kind : 1; |
2125 | }; |
2126 | |
2127 | class UsingBitfields { |
2128 | friend class UsingType; |
2129 | |
2130 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2131 | unsigned : NumTypeBits; |
2132 | |
2133 | /// True if the underlying type is different from the declared one. |
2134 | LLVM_PREFERRED_TYPE(bool) |
2135 | unsigned hasTypeDifferentFromDecl : 1; |
2136 | }; |
2137 | |
2138 | class TypedefBitfields { |
2139 | friend class TypedefType; |
2140 | |
2141 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2142 | unsigned : NumTypeBits; |
2143 | |
2144 | /// True if the underlying type is different from the declared one. |
2145 | LLVM_PREFERRED_TYPE(bool) |
2146 | unsigned hasTypeDifferentFromDecl : 1; |
2147 | }; |
2148 | |
2149 | class TemplateTypeParmTypeBitfields { |
2150 | friend class TemplateTypeParmType; |
2151 | |
2152 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2153 | unsigned : NumTypeBits; |
2154 | |
2155 | /// The depth of the template parameter. |
2156 | unsigned Depth : 15; |
2157 | |
2158 | /// Whether this is a template parameter pack. |
2159 | LLVM_PREFERRED_TYPE(bool) |
2160 | unsigned ParameterPack : 1; |
2161 | |
2162 | /// The index of the template parameter. |
2163 | unsigned Index : 16; |
2164 | }; |
2165 | |
2166 | class SubstTemplateTypeParmTypeBitfields { |
2167 | friend class SubstTemplateTypeParmType; |
2168 | |
2169 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2170 | unsigned : NumTypeBits; |
2171 | |
2172 | LLVM_PREFERRED_TYPE(bool) |
2173 | unsigned HasNonCanonicalUnderlyingType : 1; |
2174 | |
2175 | // The index of the template parameter this substitution represents. |
2176 | unsigned Index : 15; |
2177 | |
2178 | LLVM_PREFERRED_TYPE(bool) |
2179 | unsigned Final : 1; |
2180 | |
2181 | /// Represents the index within a pack if this represents a substitution |
2182 | /// from a pack expansion. This index starts at the end of the pack and |
2183 | /// increments towards the beginning. |
2184 | /// Positive non-zero number represents the index + 1. |
2185 | /// Zero means this is not substituted from an expansion. |
2186 | unsigned PackIndex : 15; |
2187 | }; |
2188 | |
2189 | class SubstTemplateTypeParmPackTypeBitfields { |
2190 | friend class SubstTemplateTypeParmPackType; |
2191 | |
2192 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2193 | unsigned : NumTypeBits; |
2194 | |
2195 | // The index of the template parameter this substitution represents. |
2196 | unsigned Index : 16; |
2197 | |
2198 | /// The number of template arguments in \c Arguments, which is |
2199 | /// expected to be able to hold at least 1024 according to [implimits]. |
2200 | /// However as this limit is somewhat easy to hit with template |
2201 | /// metaprogramming we'd prefer to keep it as large as possible. |
2202 | unsigned NumArgs : 16; |
2203 | }; |
2204 | |
2205 | class TemplateSpecializationTypeBitfields { |
2206 | friend class TemplateSpecializationType; |
2207 | |
2208 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2209 | unsigned : NumTypeBits; |
2210 | |
2211 | /// Whether this template specialization type is a substituted type alias. |
2212 | LLVM_PREFERRED_TYPE(bool) |
2213 | unsigned TypeAlias : 1; |
2214 | |
2215 | /// The number of template arguments named in this class template |
2216 | /// specialization, which is expected to be able to hold at least 1024 |
2217 | /// according to [implimits]. However, as this limit is somewhat easy to |
2218 | /// hit with template metaprogramming we'd prefer to keep it as large |
2219 | /// as possible. At the moment it has been left as a non-bitfield since |
2220 | /// this type safely fits in 64 bits as an unsigned, so there is no reason |
2221 | /// to introduce the performance impact of a bitfield. |
2222 | unsigned NumArgs; |
2223 | }; |
2224 | |
2225 | class DependentTemplateSpecializationTypeBitfields { |
2226 | friend class DependentTemplateSpecializationType; |
2227 | |
2228 | LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields) |
2229 | unsigned : NumTypeWithKeywordBits; |
2230 | |
2231 | /// The number of template arguments named in this class template |
2232 | /// specialization, which is expected to be able to hold at least 1024 |
2233 | /// according to [implimits]. However, as this limit is somewhat easy to |
2234 | /// hit with template metaprogramming we'd prefer to keep it as large |
2235 | /// as possible. At the moment it has been left as a non-bitfield since |
2236 | /// this type safely fits in 64 bits as an unsigned, so there is no reason |
2237 | /// to introduce the performance impact of a bitfield. |
2238 | unsigned NumArgs; |
2239 | }; |
2240 | |
2241 | class PackExpansionTypeBitfields { |
2242 | friend class PackExpansionType; |
2243 | |
2244 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2245 | unsigned : NumTypeBits; |
2246 | |
2247 | /// The number of expansions that this pack expansion will |
2248 | /// generate when substituted (+1), which is expected to be able to |
2249 | /// hold at least 1024 according to [implimits]. However, as this limit |
2250 | /// is somewhat easy to hit with template metaprogramming we'd prefer to |
2251 | /// keep it as large as possible. At the moment it has been left as a |
2252 | /// non-bitfield since this type safely fits in 64 bits as an unsigned, so |
2253 | /// there is no reason to introduce the performance impact of a bitfield. |
2254 | /// |
2255 | /// This field will only have a non-zero value when some of the parameter |
2256 | /// packs that occur within the pattern have been substituted but others |
2257 | /// have not. |
2258 | unsigned NumExpansions; |
2259 | }; |
2260 | |
2261 | class CountAttributedTypeBitfields { |
2262 | friend class CountAttributedType; |
2263 | |
2264 | LLVM_PREFERRED_TYPE(TypeBitfields) |
2265 | unsigned : NumTypeBits; |
2266 | |
2267 | static constexpr unsigned NumCoupledDeclsBits = 4; |
2268 | unsigned NumCoupledDecls : NumCoupledDeclsBits; |
2269 | LLVM_PREFERRED_TYPE(bool) |
2270 | unsigned CountInBytes : 1; |
2271 | LLVM_PREFERRED_TYPE(bool) |
2272 | unsigned OrNull : 1; |
2273 | }; |
2274 | static_assert(sizeof(CountAttributedTypeBitfields) <= sizeof(unsigned)); |
2275 | |
2276 | union { |
2277 | TypeBitfields TypeBits; |
2278 | ArrayTypeBitfields ArrayTypeBits; |
2279 | ConstantArrayTypeBitfields ConstantArrayTypeBits; |
2280 | AttributedTypeBitfields AttributedTypeBits; |
2281 | AutoTypeBitfields AutoTypeBits; |
2282 | TypeOfBitfields TypeOfBits; |
2283 | TypedefBitfields TypedefBits; |
2284 | UsingBitfields UsingBits; |
2285 | BuiltinTypeBitfields BuiltinTypeBits; |
2286 | FunctionTypeBitfields FunctionTypeBits; |
2287 | ObjCObjectTypeBitfields ObjCObjectTypeBits; |
2288 | ReferenceTypeBitfields ReferenceTypeBits; |
2289 | TypeWithKeywordBitfields TypeWithKeywordBits; |
2290 | ElaboratedTypeBitfields ElaboratedTypeBits; |
2291 | VectorTypeBitfields VectorTypeBits; |
2292 | TemplateTypeParmTypeBitfields TemplateTypeParmTypeBits; |
2293 | SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits; |
2294 | SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; |
2295 | TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; |
2296 | DependentTemplateSpecializationTypeBitfields |
2297 | DependentTemplateSpecializationTypeBits; |
2298 | PackExpansionTypeBitfields PackExpansionTypeBits; |
2299 | CountAttributedTypeBitfields CountAttributedTypeBits; |
2300 | }; |
2301 | |
2302 | private: |
2303 | template <class T> friend class TypePropertyCache; |
2304 | |
2305 | /// Set whether this type comes from an AST file. |
2306 | void setFromAST(bool V = true) const { |
2307 | TypeBits.FromAST = V; |
2308 | } |
2309 | |
2310 | protected: |
2311 | friend class ASTContext; |
2312 | |
2313 | Type(TypeClass tc, QualType canon, TypeDependence Dependence) |
2314 | : ExtQualsTypeCommonBase(this, |
2315 | canon.isNull() ? QualType(this_(), 0) : canon) { |
2316 | static_assert(sizeof(*this) <= |
2317 | alignof(decltype(*this)) + sizeof(ExtQualsTypeCommonBase), |
2318 | "changing bitfields changed sizeof(Type)!" ); |
2319 | static_assert(alignof(decltype(*this)) % TypeAlignment == 0, |
2320 | "Insufficient alignment!" ); |
2321 | TypeBits.TC = tc; |
2322 | TypeBits.Dependence = static_cast<unsigned>(Dependence); |
2323 | TypeBits.CacheValid = false; |
2324 | TypeBits.CachedLocalOrUnnamed = false; |
2325 | TypeBits.CachedLinkage = llvm::to_underlying(Linkage::Invalid); |
2326 | TypeBits.FromAST = false; |
2327 | } |
2328 | |
2329 | // silence VC++ warning C4355: 'this' : used in base member initializer list |
2330 | Type *this_() { return this; } |
2331 | |
2332 | void setDependence(TypeDependence D) { |
2333 | TypeBits.Dependence = static_cast<unsigned>(D); |
2334 | } |
2335 | |
2336 | void addDependence(TypeDependence D) { setDependence(getDependence() | D); } |
2337 | |
2338 | public: |
2339 | friend class ASTReader; |
2340 | friend class ASTWriter; |
2341 | template <class T> friend class serialization::AbstractTypeReader; |
2342 | template <class T> friend class serialization::AbstractTypeWriter; |
2343 | |
2344 | Type(const Type &) = delete; |
2345 | Type(Type &&) = delete; |
2346 | Type &operator=(const Type &) = delete; |
2347 | Type &operator=(Type &&) = delete; |
2348 | |
2349 | TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } |
2350 | |
2351 | /// Whether this type comes from an AST file. |
2352 | bool isFromAST() const { return TypeBits.FromAST; } |
2353 | |
2354 | /// Whether this type is or contains an unexpanded parameter |
2355 | /// pack, used to support C++0x variadic templates. |
2356 | /// |
2357 | /// A type that contains a parameter pack shall be expanded by the |
2358 | /// ellipsis operator at some point. For example, the typedef in the |
2359 | /// following example contains an unexpanded parameter pack 'T': |
2360 | /// |
2361 | /// \code |
2362 | /// template<typename ...T> |
2363 | /// struct X { |
2364 | /// typedef T* pointer_types; // ill-formed; T is a parameter pack. |
2365 | /// }; |
2366 | /// \endcode |
2367 | /// |
2368 | /// Note that this routine does not specify which |
2369 | bool containsUnexpandedParameterPack() const { |
2370 | return getDependence() & TypeDependence::UnexpandedPack; |
2371 | } |
2372 | |
2373 | /// Determines if this type would be canonical if it had no further |
2374 | /// qualification. |
2375 | bool isCanonicalUnqualified() const { |
2376 | return CanonicalType == QualType(this, 0); |
2377 | } |
2378 | |
2379 | /// Pull a single level of sugar off of this locally-unqualified type. |
2380 | /// Users should generally prefer SplitQualType::getSingleStepDesugaredType() |
2381 | /// or QualType::getSingleStepDesugaredType(const ASTContext&). |
2382 | QualType getLocallyUnqualifiedSingleStepDesugaredType() const; |
2383 | |
2384 | /// As an extension, we classify types as one of "sized" or "sizeless"; |
2385 | /// every type is one or the other. Standard types are all sized; |
2386 | /// sizeless types are purely an extension. |
2387 | /// |
2388 | /// Sizeless types contain data with no specified size, alignment, |
2389 | /// or layout. |
2390 | bool isSizelessType() const; |
2391 | bool isSizelessBuiltinType() const; |
2392 | |
2393 | /// Returns true for all scalable vector types. |
2394 | bool isSizelessVectorType() const; |
2395 | |
2396 | /// Returns true for SVE scalable vector types. |
2397 | bool isSVESizelessBuiltinType() const; |
2398 | |
2399 | /// Returns true for RVV scalable vector types. |
2400 | bool isRVVSizelessBuiltinType() const; |
2401 | |
2402 | /// Check if this is a WebAssembly Externref Type. |
2403 | bool isWebAssemblyExternrefType() const; |
2404 | |
2405 | /// Returns true if this is a WebAssembly table type: either an array of |
2406 | /// reference types, or a pointer to a reference type (which can only be |
2407 | /// created by array to pointer decay). |
2408 | bool isWebAssemblyTableType() const; |
2409 | |
2410 | /// Determines if this is a sizeless type supported by the |
2411 | /// 'arm_sve_vector_bits' type attribute, which can be applied to a single |
2412 | /// SVE vector or predicate, excluding tuple types such as svint32x4_t. |
2413 | bool isSveVLSBuiltinType() const; |
2414 | |
2415 | /// Returns the representative type for the element of an SVE builtin type. |
2416 | /// This is used to represent fixed-length SVE vectors created with the |
2417 | /// 'arm_sve_vector_bits' type attribute as VectorType. |
2418 | QualType getSveEltType(const ASTContext &Ctx) const; |
2419 | |
2420 | /// Determines if this is a sizeless type supported by the |
2421 | /// 'riscv_rvv_vector_bits' type attribute, which can be applied to a single |
2422 | /// RVV vector or mask. |
2423 | bool isRVVVLSBuiltinType() const; |
2424 | |
2425 | /// Returns the representative type for the element of an RVV builtin type. |
2426 | /// This is used to represent fixed-length RVV vectors created with the |
2427 | /// 'riscv_rvv_vector_bits' type attribute as VectorType. |
2428 | QualType getRVVEltType(const ASTContext &Ctx) const; |
2429 | |
2430 | /// Returns the representative type for the element of a sizeless vector |
2431 | /// builtin type. |
2432 | QualType getSizelessVectorEltType(const ASTContext &Ctx) const; |
2433 | |
2434 | /// Types are partitioned into 3 broad categories (C99 6.2.5p1): |
2435 | /// object types, function types, and incomplete types. |
2436 | |
2437 | /// Return true if this is an incomplete type. |
2438 | /// A type that can describe objects, but which lacks information needed to |
2439 | /// determine its size (e.g. void, or a fwd declared struct). Clients of this |
2440 | /// routine will need to determine if the size is actually required. |
2441 | /// |
2442 | /// Def If non-null, and the type refers to some kind of declaration |
2443 | /// that can be completed (such as a C struct, C++ class, or Objective-C |
2444 | /// class), will be set to the declaration. |
2445 | bool isIncompleteType(NamedDecl **Def = nullptr) const; |
2446 | |
2447 | /// Return true if this is an incomplete or object |
2448 | /// type, in other words, not a function type. |
2449 | bool isIncompleteOrObjectType() const { |
2450 | return !isFunctionType(); |
2451 | } |
2452 | |
2453 | /// \returns True if the type is incomplete and it is also a type that |
2454 | /// cannot be completed by a later type definition. |
2455 | /// |
2456 | /// E.g. For `void` this is true but for `struct ForwardDecl;` this is false |
2457 | /// because a definition for `ForwardDecl` could be provided later on in the |
2458 | /// translation unit. |
2459 | /// |
2460 | /// Note even for types that this function returns true for it is still |
2461 | /// possible for the declarations that contain this type to later have a |
2462 | /// complete type in a translation unit. E.g.: |
2463 | /// |
2464 | /// \code{.c} |
2465 | /// // This decl has type 'char[]' which is incomplete and cannot be later |
2466 | /// // completed by another by another type declaration. |
2467 | /// extern char foo[]; |
2468 | /// // This decl now has complete type 'char[5]'. |
2469 | /// char foo[5]; // foo has a complete type |
2470 | /// \endcode |
2471 | bool isAlwaysIncompleteType() const; |
2472 | |
2473 | /// Determine whether this type is an object type. |
2474 | bool isObjectType() const { |
2475 | // C++ [basic.types]p8: |
2476 | // An object type is a (possibly cv-qualified) type that is not a |
2477 | // function type, not a reference type, and not a void type. |
2478 | return !isReferenceType() && !isFunctionType() && !isVoidType(); |
2479 | } |
2480 | |
2481 | /// Return true if this is a literal type |
2482 | /// (C++11 [basic.types]p10) |
2483 | bool isLiteralType(const ASTContext &Ctx) const; |
2484 | |
2485 | /// Determine if this type is a structural type, per C++20 [temp.param]p7. |
2486 | bool isStructuralType() const; |
2487 | |
2488 | /// Test if this type is a standard-layout type. |
2489 | /// (C++0x [basic.type]p9) |
2490 | bool isStandardLayoutType() const; |
2491 | |
2492 | /// Helper methods to distinguish type categories. All type predicates |
2493 | /// operate on the canonical type, ignoring typedefs and qualifiers. |
2494 | |
2495 | /// Returns true if the type is a builtin type. |
2496 | bool isBuiltinType() const; |
2497 | |
2498 | /// Test for a particular builtin type. |
2499 | bool isSpecificBuiltinType(unsigned K) const; |
2500 | |
2501 | /// Test for a type which does not represent an actual type-system type but |
2502 | /// is instead used as a placeholder for various convenient purposes within |
2503 | /// Clang. All such types are BuiltinTypes. |
2504 | bool isPlaceholderType() const; |
2505 | const BuiltinType *getAsPlaceholderType() const; |
2506 | |
2507 | /// Test for a specific placeholder type. |
2508 | bool isSpecificPlaceholderType(unsigned K) const; |
2509 | |
2510 | /// Test for a placeholder type other than Overload; see |
2511 | /// BuiltinType::isNonOverloadPlaceholderType. |
2512 | bool isNonOverloadPlaceholderType() const; |
2513 | |
2514 | /// isIntegerType() does *not* include complex integers (a GCC extension). |
2515 | /// isComplexIntegerType() can be used to test for complex integers. |
2516 | bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) |
2517 | bool isEnumeralType() const; |
2518 | |
2519 | /// Determine whether this type is a scoped enumeration type. |
2520 | bool isScopedEnumeralType() const; |
2521 | bool isBooleanType() const; |
2522 | bool isCharType() const; |
2523 | bool isWideCharType() const; |
2524 | bool isChar8Type() const; |
2525 | bool isChar16Type() const; |
2526 | bool isChar32Type() const; |
2527 | bool isAnyCharacterType() const; |
2528 | bool isUnicodeCharacterType() const; |
2529 | bool isIntegralType(const ASTContext &Ctx) const; |
2530 | |
2531 | /// Determine whether this type is an integral or enumeration type. |
2532 | bool isIntegralOrEnumerationType() const; |
2533 | |
2534 | /// Determine whether this type is an integral or unscoped enumeration type. |
2535 | bool isIntegralOrUnscopedEnumerationType() const; |
2536 | bool isUnscopedEnumerationType() const; |
2537 | |
2538 | /// Floating point categories. |
2539 | bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) |
2540 | /// isComplexType() does *not* include complex integers (a GCC extension). |
2541 | /// isComplexIntegerType() can be used to test for complex integers. |
2542 | bool isComplexType() const; // C99 6.2.5p11 (complex) |
2543 | bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. |
2544 | bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) |
2545 | bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) |
2546 | bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 |
2547 | bool isFloat32Type() const; |
2548 | bool isDoubleType() const; |
2549 | bool isBFloat16Type() const; |
2550 | bool isMFloat8Type() const; |
2551 | bool isFloat128Type() const; |
2552 | bool isIbm128Type() const; |
2553 | bool isRealType() const; // C99 6.2.5p17 (real floating + integer) |
2554 | bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) |
2555 | bool isVoidType() const; // C99 6.2.5p19 |
2556 | bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) |
2557 | bool isAggregateType() const; |
2558 | bool isFundamentalType() const; |
2559 | bool isCompoundType() const; |
2560 | |
2561 | // Type Predicates: Check to see if this type is structurally the specified |
2562 | // type, ignoring typedefs and qualifiers. |
2563 | bool isFunctionType() const; |
2564 | bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); } |
2565 | bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } |
2566 | bool isPointerType() const; |
2567 | bool isPointerOrReferenceType() const; |
2568 | bool isSignableType(const ASTContext &Ctx) const; |
2569 | bool isSignablePointerType() const; |
2570 | bool isSignableIntegerType(const ASTContext &Ctx) const; |
2571 | bool isAnyPointerType() const; // Any C pointer or ObjC object pointer |
2572 | bool isCountAttributedType() const; |
2573 | bool isCFIUncheckedCalleeFunctionType() const; |
2574 | bool hasPointeeToToCFIUncheckedCalleeFunctionType() const; |
2575 | bool isBlockPointerType() const; |
2576 | bool isVoidPointerType() const; |
2577 | bool isReferenceType() const; |
2578 | bool isLValueReferenceType() const; |
2579 | bool isRValueReferenceType() const; |
2580 | bool isObjectPointerType() const; |
2581 | bool isFunctionPointerType() const; |
2582 | bool isFunctionReferenceType() const; |
2583 | bool isMemberPointerType() const; |
2584 | bool isMemberFunctionPointerType() const; |
2585 | bool isMemberDataPointerType() const; |
2586 | bool isArrayType() const; |
2587 | bool isConstantArrayType() const; |
2588 | bool isIncompleteArrayType() const; |
2589 | bool isVariableArrayType() const; |
2590 | bool isArrayParameterType() const; |
2591 | bool isDependentSizedArrayType() const; |
2592 | bool isRecordType() const; |
2593 | bool isClassType() const; |
2594 | bool isStructureType() const; |
2595 | bool isStructureTypeWithFlexibleArrayMember() const; |
2596 | bool isObjCBoxableRecordType() const; |
2597 | bool isInterfaceType() const; |
2598 | bool isStructureOrClassType() const; |
2599 | bool isUnionType() const; |
2600 | bool isComplexIntegerType() const; // GCC _Complex integer type. |
2601 | bool isVectorType() const; // GCC vector type. |
2602 | bool isExtVectorType() const; // Extended vector type. |
2603 | bool isExtVectorBoolType() const; // Extended vector type with bool element. |
2604 | // Extended vector type with bool element that is packed. HLSL doesn't pack |
2605 | // its bool vectors. |
2606 | bool isPackedVectorBoolType(const ASTContext &ctx) const; |
2607 | bool isSubscriptableVectorType() const; |
2608 | bool isMatrixType() const; // Matrix type. |
2609 | bool isConstantMatrixType() const; // Constant matrix type. |
2610 | bool isDependentAddressSpaceType() const; // value-dependent address space qualifier |
2611 | bool isObjCObjectPointerType() const; // pointer to ObjC object |
2612 | bool isObjCRetainableType() const; // ObjC object or block pointer |
2613 | bool isObjCLifetimeType() const; // (array of)* retainable type |
2614 | bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type |
2615 | bool isObjCNSObjectType() const; // __attribute__((NSObject)) |
2616 | bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class)) |
2617 | // FIXME: change this to 'raw' interface type, so we can used 'interface' type |
2618 | // for the common case. |
2619 | bool isObjCObjectType() const; // NSString or typeof(*(id)0) |
2620 | bool isObjCQualifiedInterfaceType() const; // NSString<foo> |
2621 | bool isObjCQualifiedIdType() const; // id<foo> |
2622 | bool isObjCQualifiedClassType() const; // Class<foo> |
2623 | bool isObjCObjectOrInterfaceType() const; |
2624 | bool isObjCIdType() const; // id |
2625 | bool isDecltypeType() const; |
2626 | /// Was this type written with the special inert-in-ARC __unsafe_unretained |
2627 | /// qualifier? |
2628 | /// |
2629 | /// This approximates the answer to the following question: if this |
2630 | /// translation unit were compiled in ARC, would this type be qualified |
2631 | /// with __unsafe_unretained? |
2632 | bool isObjCInertUnsafeUnretainedType() const { |
2633 | return hasAttr(attr::ObjCInertUnsafeUnretained); |
2634 | } |
2635 | |
2636 | /// Whether the type is Objective-C 'id' or a __kindof type of an |
2637 | /// object type, e.g., __kindof NSView * or __kindof id |
2638 | /// <NSCopying>. |
2639 | /// |
2640 | /// \param bound Will be set to the bound on non-id subtype types, |
2641 | /// which will be (possibly specialized) Objective-C class type, or |
2642 | /// null for 'id. |
2643 | bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, |
2644 | const ObjCObjectType *&bound) const; |
2645 | |
2646 | bool isObjCClassType() const; // Class |
2647 | |
2648 | /// Whether the type is Objective-C 'Class' or a __kindof type of an |
2649 | /// Class type, e.g., __kindof Class <NSCopying>. |
2650 | /// |
2651 | /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound |
2652 | /// here because Objective-C's type system cannot express "a class |
2653 | /// object for a subclass of NSFoo". |
2654 | bool isObjCClassOrClassKindOfType() const; |
2655 | |
2656 | bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const; |
2657 | bool isObjCSelType() const; // Class |
2658 | bool isObjCBuiltinType() const; // 'id' or 'Class' |
2659 | bool isObjCARCBridgableType() const; |
2660 | bool isCARCBridgableType() const; |
2661 | bool isTemplateTypeParmType() const; // C++ template type parameter |
2662 | bool isNullPtrType() const; // C++11 std::nullptr_t or |
2663 | // C23 nullptr_t |
2664 | bool isNothrowT() const; // C++ std::nothrow_t |
2665 | bool isAlignValT() const; // C++17 std::align_val_t |
2666 | bool isStdByteType() const; // C++17 std::byte |
2667 | bool isAtomicType() const; // C11 _Atomic() |
2668 | bool isUndeducedAutoType() const; // C++11 auto or |
2669 | // C++14 decltype(auto) |
2670 | bool isTypedefNameType() const; // typedef or alias template |
2671 | |
2672 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ |
2673 | bool is##Id##Type() const; |
2674 | #include "clang/Basic/OpenCLImageTypes.def" |
2675 | |
2676 | bool isImageType() const; // Any OpenCL image type |
2677 | |
2678 | bool isSamplerT() const; // OpenCL sampler_t |
2679 | bool isEventT() const; // OpenCL event_t |
2680 | bool isClkEventT() const; // OpenCL clk_event_t |
2681 | bool isQueueT() const; // OpenCL queue_t |
2682 | bool isReserveIDT() const; // OpenCL reserve_id_t |
2683 | |
2684 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
2685 | bool is##Id##Type() const; |
2686 | #include "clang/Basic/OpenCLExtensionTypes.def" |
2687 | // Type defined in cl_intel_device_side_avc_motion_estimation OpenCL extension |
2688 | bool isOCLIntelSubgroupAVCType() const; |
2689 | bool isOCLExtOpaqueType() const; // Any OpenCL extension type |
2690 | |
2691 | bool isPipeType() const; // OpenCL pipe type |
2692 | bool isBitIntType() const; // Bit-precise integer type |
2693 | bool isOpenCLSpecificType() const; // Any OpenCL specific type |
2694 | |
2695 | #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) bool is##Id##Type() const; |
2696 | #include "clang/Basic/HLSLIntangibleTypes.def" |
2697 | bool isHLSLSpecificType() const; // Any HLSL specific type |
2698 | bool isHLSLBuiltinIntangibleType() const; // Any HLSL builtin intangible type |
2699 | bool isHLSLAttributedResourceType() const; |
2700 | bool isHLSLInlineSpirvType() const; |
2701 | bool isHLSLResourceRecord() const; |
2702 | bool isHLSLIntangibleType() |
2703 | const; // Any HLSL intangible type (builtin, array, class) |
2704 | |
2705 | /// Determines if this type, which must satisfy |
2706 | /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather |
2707 | /// than implicitly __strong. |
2708 | bool isObjCARCImplicitlyUnretainedType() const; |
2709 | |
2710 | /// Check if the type is the CUDA device builtin surface type. |
2711 | bool isCUDADeviceBuiltinSurfaceType() const; |
2712 | /// Check if the type is the CUDA device builtin texture type. |
2713 | bool isCUDADeviceBuiltinTextureType() const; |
2714 | |
2715 | /// Return the implicit lifetime for this type, which must not be dependent. |
2716 | Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; |
2717 | |
2718 | enum ScalarTypeKind { |
2719 | STK_CPointer, |
2720 | STK_BlockPointer, |
2721 | STK_ObjCObjectPointer, |
2722 | STK_MemberPointer, |
2723 | STK_Bool, |
2724 | STK_Integral, |
2725 | STK_Floating, |
2726 | STK_IntegralComplex, |
2727 | STK_FloatingComplex, |
2728 | STK_FixedPoint |
2729 | }; |
2730 | |
2731 | /// Given that this is a scalar type, classify it. |
2732 | ScalarTypeKind getScalarTypeKind() const; |
2733 | |
2734 | TypeDependence getDependence() const { |
2735 | return static_cast<TypeDependence>(TypeBits.Dependence); |
2736 | } |
2737 | |
2738 | /// Whether this type is an error type. |
2739 | bool containsErrors() const { |
2740 | return getDependence() & TypeDependence::Error; |
2741 | } |
2742 | |
2743 | /// Whether this type is a dependent type, meaning that its definition |
2744 | /// somehow depends on a template parameter (C++ [temp.dep.type]). |
2745 | bool isDependentType() const { |
2746 | return getDependence() & TypeDependence::Dependent; |
2747 | } |
2748 | |
2749 | /// Determine whether this type is an instantiation-dependent type, |
2750 | /// meaning that the type involves a template parameter (even if the |
2751 | /// definition does not actually depend on the type substituted for that |
2752 | /// template parameter). |
2753 | bool isInstantiationDependentType() const { |
2754 | return getDependence() & TypeDependence::Instantiation; |
2755 | } |
2756 | |
2757 | /// Determine whether this type is an undeduced type, meaning that |
2758 | /// it somehow involves a C++11 'auto' type or similar which has not yet been |
2759 | /// deduced. |
2760 | bool isUndeducedType() const; |
2761 | |
2762 | /// Whether this type is a variably-modified type (C99 6.7.5). |
2763 | bool isVariablyModifiedType() const { |
2764 | return getDependence() & TypeDependence::VariablyModified; |
2765 | } |
2766 | |
2767 | /// Whether this type involves a variable-length array type |
2768 | /// with a definite size. |
2769 | bool hasSizedVLAType() const; |
2770 | |
2771 | /// Whether this type is or contains a local or unnamed type. |
2772 | bool hasUnnamedOrLocalType() const; |
2773 | |
2774 | bool isOverloadableType() const; |
2775 | |
2776 | /// Determine wither this type is a C++ elaborated-type-specifier. |
2777 | bool isElaboratedTypeSpecifier() const; |
2778 | |
2779 | bool canDecayToPointerType() const; |
2780 | |
2781 | /// Whether this type is represented natively as a pointer. This includes |
2782 | /// pointers, references, block pointers, and Objective-C interface, |
2783 | /// qualified id, and qualified interface types, as well as nullptr_t. |
2784 | bool hasPointerRepresentation() const; |
2785 | |
2786 | /// Whether this type can represent an objective pointer type for the |
2787 | /// purpose of GC'ability |
2788 | bool hasObjCPointerRepresentation() const; |
2789 | |
2790 | /// Determine whether this type has an integer representation |
2791 | /// of some sort, e.g., it is an integer type or a vector. |
2792 | bool hasIntegerRepresentation() const; |
2793 | |
2794 | /// Determine whether this type has an signed integer representation |
2795 | /// of some sort, e.g., it is an signed integer type or a vector. |
2796 | bool hasSignedIntegerRepresentation() const; |
2797 | |
2798 | /// Determine whether this type has an unsigned integer representation |
2799 | /// of some sort, e.g., it is an unsigned integer type or a vector. |
2800 | bool hasUnsignedIntegerRepresentation() const; |
2801 | |
2802 | /// Determine whether this type has a floating-point representation |
2803 | /// of some sort, e.g., it is a floating-point type or a vector thereof. |
2804 | bool hasFloatingRepresentation() const; |
2805 | |
2806 | /// Determine whether this type has a boolean representation -- i.e., it is a |
2807 | /// boolean type, an enum type whose underlying type is a boolean type, or a |
2808 | /// vector of booleans. |
2809 | bool hasBooleanRepresentation() const; |
2810 | |
2811 | // Type Checking Functions: Check to see if this type is structurally the |
2812 | // specified type, ignoring typedefs and qualifiers, and return a pointer to |
2813 | // the best type we can. |
2814 | const RecordType *getAsStructureType() const; |
2815 | /// NOTE: getAs*ArrayType are methods on ASTContext. |
2816 | const RecordType *getAsUnionType() const; |
2817 | const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. |
2818 | const ObjCObjectType *getAsObjCInterfaceType() const; |
2819 | |
2820 | // The following is a convenience method that returns an ObjCObjectPointerType |
2821 | // for object declared using an interface. |
2822 | const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; |
2823 | const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; |
2824 | const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; |
2825 | const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; |
2826 | |
2827 | /// Retrieves the CXXRecordDecl that this type refers to, either |
2828 | /// because the type is a RecordType or because it is the injected-class-name |
2829 | /// type of a class template or class template partial specialization. |
2830 | CXXRecordDecl *getAsCXXRecordDecl() const; |
2831 | |
2832 | /// Retrieves the RecordDecl this type refers to. |
2833 | RecordDecl *getAsRecordDecl() const; |
2834 | |
2835 | /// Retrieves the TagDecl that this type refers to, either |
2836 | /// because the type is a TagType or because it is the injected-class-name |
2837 | /// type of a class template or class template partial specialization. |
2838 | TagDecl *getAsTagDecl() const; |
2839 | |
2840 | /// If this is a pointer or reference to a RecordType, return the |
2841 | /// CXXRecordDecl that the type refers to. |
2842 | /// |
2843 | /// If this is not a pointer or reference, or the type being pointed to does |
2844 | /// not refer to a CXXRecordDecl, returns NULL. |
2845 | const CXXRecordDecl *getPointeeCXXRecordDecl() const; |
2846 | |
2847 | /// Get the DeducedType whose type will be deduced for a variable with |
2848 | /// an initializer of this type. This looks through declarators like pointer |
2849 | /// types, but not through decltype or typedefs. |
2850 | DeducedType *getContainedDeducedType() const; |
2851 | |
2852 | /// Get the AutoType whose type will be deduced for a variable with |
2853 | /// an initializer of this type. This looks through declarators like pointer |
2854 | /// types, but not through decltype or typedefs. |
2855 | AutoType *getContainedAutoType() const { |
2856 | return dyn_cast_or_null<AutoType>(getContainedDeducedType()); |
2857 | } |
2858 | |
2859 | /// Determine whether this type was written with a leading 'auto' |
2860 | /// corresponding to a trailing return type (possibly for a nested |
2861 | /// function type within a pointer to function type or similar). |
2862 | bool hasAutoForTrailingReturnType() const; |
2863 | |
2864 | /// Member-template getAs<specific type>'. Look through sugar for |
2865 | /// an instance of \<specific type>. This scheme will eventually |
2866 | /// replace the specific getAsXXXX methods above. |
2867 | /// |
2868 | /// There are some specializations of this member template listed |
2869 | /// immediately following this class. |
2870 | template <typename T> const T *getAs() const; |
2871 | |
2872 | /// Look through sugar for an instance of TemplateSpecializationType which |
2873 | /// is not a type alias, or null if there is no such type. |
2874 | /// This is used when you want as-written template arguments or the template |
2875 | /// name for a class template specialization. |
2876 | const TemplateSpecializationType * |
2877 | getAsNonAliasTemplateSpecializationType() const; |
2878 | |
2879 | const TemplateSpecializationType * |
2880 | castAsNonAliasTemplateSpecializationType() const { |
2881 | const auto *TST = getAsNonAliasTemplateSpecializationType(); |
2882 | assert(TST && "not a TemplateSpecializationType" ); |
2883 | return TST; |
2884 | } |
2885 | |
2886 | /// Member-template getAsAdjusted<specific type>. Look through specific kinds |
2887 | /// of sugar (parens, attributes, etc) for an instance of \<specific type>. |
2888 | /// This is used when you need to walk over sugar nodes that represent some |
2889 | /// kind of type adjustment from a type that was written as a \<specific type> |
2890 | /// to another type that is still canonically a \<specific type>. |
2891 | template <typename T> const T *getAsAdjusted() const; |
2892 | |
2893 | /// A variant of getAs<> for array types which silently discards |
2894 | /// qualifiers from the outermost type. |
2895 | const ArrayType *getAsArrayTypeUnsafe() const; |
2896 | |
2897 | /// Member-template castAs<specific type>. Look through sugar for |
2898 | /// the underlying instance of \<specific type>. |
2899 | /// |
2900 | /// This method has the same relationship to getAs<T> as cast<T> has |
2901 | /// to dyn_cast<T>; which is to say, the underlying type *must* |
2902 | /// have the intended type, and this method will never return null. |
2903 | template <typename T> const T *castAs() const; |
2904 | |
2905 | /// A variant of castAs<> for array type which silently discards |
2906 | /// qualifiers from the outermost type. |
2907 | const ArrayType *castAsArrayTypeUnsafe() const; |
2908 | |
2909 | /// Determine whether this type had the specified attribute applied to it |
2910 | /// (looking through top-level type sugar). |
2911 | bool hasAttr(attr::Kind AK) const; |
2912 | |
2913 | /// Get the base element type of this type, potentially discarding type |
2914 | /// qualifiers. This should never be used when type qualifiers |
2915 | /// are meaningful. |
2916 | const Type *getBaseElementTypeUnsafe() const; |
2917 | |
2918 | /// If this is an array type, return the element type of the array, |
2919 | /// potentially with type qualifiers missing. |
2920 | /// This should never be used when type qualifiers are meaningful. |
2921 | const Type *getArrayElementTypeNoTypeQual() const; |
2922 | |
2923 | /// If this is a pointer type, return the pointee type. |
2924 | /// If this is an array type, return the array element type. |
2925 | /// This should never be used when type qualifiers are meaningful. |
2926 | const Type *getPointeeOrArrayElementType() const; |
2927 | |
2928 | /// If this is a pointer, ObjC object pointer, or block |
2929 | /// pointer, this returns the respective pointee. |
2930 | QualType getPointeeType() const; |
2931 | |
2932 | /// Return the specified type with any "sugar" removed from the type, |
2933 | /// removing any typedefs, typeofs, etc., as well as any qualifiers. |
2934 | const Type *getUnqualifiedDesugaredType() const; |
2935 | |
2936 | /// Return true if this is an integer type that is |
2937 | /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], |
2938 | /// or an enum decl which has a signed representation. |
2939 | bool isSignedIntegerType() const; |
2940 | |
2941 | /// Return true if this is an integer type that is |
2942 | /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], |
2943 | /// or an enum decl which has an unsigned representation. |
2944 | bool isUnsignedIntegerType() const; |
2945 | |
2946 | /// Determines whether this is an integer type that is signed or an |
2947 | /// enumeration types whose underlying type is a signed integer type. |
2948 | bool isSignedIntegerOrEnumerationType() const; |
2949 | |
2950 | /// Determines whether this is an integer type that is unsigned or an |
2951 | /// enumeration types whose underlying type is a unsigned integer type. |
2952 | bool isUnsignedIntegerOrEnumerationType() const; |
2953 | |
2954 | /// Return true if this is a fixed point type according to |
2955 | /// ISO/IEC JTC1 SC22 WG14 N1169. |
2956 | bool isFixedPointType() const; |
2957 | |
2958 | /// Return true if this is a fixed point or integer type. |
2959 | bool isFixedPointOrIntegerType() const; |
2960 | |
2961 | /// Return true if this can be converted to (or from) a fixed point type. |
2962 | bool isConvertibleToFixedPointType() const; |
2963 | |
2964 | /// Return true if this is a saturated fixed point type according to |
2965 | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. |
2966 | bool isSaturatedFixedPointType() const; |
2967 | |
2968 | /// Return true if this is a saturated fixed point type according to |
2969 | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. |
2970 | bool isUnsaturatedFixedPointType() const; |
2971 | |
2972 | /// Return true if this is a fixed point type that is signed according |
2973 | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. |
2974 | bool isSignedFixedPointType() const; |
2975 | |
2976 | /// Return true if this is a fixed point type that is unsigned according |
2977 | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. |
2978 | bool isUnsignedFixedPointType() const; |
2979 | |
2980 | /// Return true if this is not a variable sized type, |
2981 | /// according to the rules of C99 6.7.5p3. It is not legal to call this on |
2982 | /// incomplete types. |
2983 | bool isConstantSizeType() const; |
2984 | |
2985 | /// Returns true if this type can be represented by some |
2986 | /// set of type specifiers. |
2987 | bool isSpecifierType() const; |
2988 | |
2989 | /// Determine the linkage of this type. |
2990 | Linkage getLinkage() const; |
2991 | |
2992 | /// Determine the visibility of this type. |
2993 | Visibility getVisibility() const { |
2994 | return getLinkageAndVisibility().getVisibility(); |
2995 | } |
2996 | |
2997 | /// Return true if the visibility was explicitly set is the code. |
2998 | bool isVisibilityExplicit() const { |
2999 | return getLinkageAndVisibility().isVisibilityExplicit(); |
3000 | } |
3001 | |
3002 | /// Determine the linkage and visibility of this type. |
3003 | LinkageInfo getLinkageAndVisibility() const; |
3004 | |
3005 | /// True if the computed linkage is valid. Used for consistency |
3006 | /// checking. Should always return true. |
3007 | bool isLinkageValid() const; |
3008 | |
3009 | /// Determine the nullability of the given type. |
3010 | /// |
3011 | /// Note that nullability is only captured as sugar within the type |
3012 | /// system, not as part of the canonical type, so nullability will |
3013 | /// be lost by canonicalization and desugaring. |
3014 | std::optional<NullabilityKind> getNullability() const; |
3015 | |
3016 | /// Determine whether the given type can have a nullability |
3017 | /// specifier applied to it, i.e., if it is any kind of pointer type. |
3018 | /// |
3019 | /// \param ResultIfUnknown The value to return if we don't yet know whether |
3020 | /// this type can have nullability because it is dependent. |
3021 | bool canHaveNullability(bool ResultIfUnknown = true) const; |
3022 | |
3023 | /// Retrieve the set of substitutions required when accessing a member |
3024 | /// of the Objective-C receiver type that is declared in the given context. |
3025 | /// |
3026 | /// \c *this is the type of the object we're operating on, e.g., the |
3027 | /// receiver for a message send or the base of a property access, and is |
3028 | /// expected to be of some object or object pointer type. |
3029 | /// |
3030 | /// \param dc The declaration context for which we are building up a |
3031 | /// substitution mapping, which should be an Objective-C class, extension, |
3032 | /// category, or method within. |
3033 | /// |
3034 | /// \returns an array of type arguments that can be substituted for |
3035 | /// the type parameters of the given declaration context in any type described |
3036 | /// within that context, or an empty optional to indicate that no |
3037 | /// substitution is required. |
3038 | std::optional<ArrayRef<QualType>> |
3039 | getObjCSubstitutions(const DeclContext *dc) const; |
3040 | |
3041 | /// Determines if this is an ObjC interface type that may accept type |
3042 | /// parameters. |
3043 | bool acceptsObjCTypeParams() const; |
3044 | |
3045 | const char *getTypeClassName() const; |
3046 | |
3047 | QualType getCanonicalTypeInternal() const { |
3048 | return CanonicalType; |
3049 | } |
3050 | |
3051 | CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h |
3052 | void dump() const; |
3053 | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; |
3054 | }; |
3055 | |
3056 | /// This will check for a TypedefType by removing any existing sugar |
3057 | /// until it reaches a TypedefType or a non-sugared type. |
3058 | template <> const TypedefType *Type::getAs() const; |
3059 | template <> const UsingType *Type::getAs() const; |
3060 | |
3061 | /// This will check for a TemplateSpecializationType by removing any |
3062 | /// existing sugar until it reaches a TemplateSpecializationType or a |
3063 | /// non-sugared type. |
3064 | template <> const TemplateSpecializationType *Type::getAs() const; |
3065 | |
3066 | /// This will check for an AttributedType by removing any existing sugar |
3067 | /// until it reaches an AttributedType or a non-sugared type. |
3068 | template <> const AttributedType *Type::getAs() const; |
3069 | |
3070 | /// This will check for a BoundsAttributedType by removing any existing |
3071 | /// sugar until it reaches an BoundsAttributedType or a non-sugared type. |
3072 | template <> const BoundsAttributedType *Type::getAs() const; |
3073 | |
3074 | /// This will check for a CountAttributedType by removing any existing |
3075 | /// sugar until it reaches an CountAttributedType or a non-sugared type. |
3076 | template <> const CountAttributedType *Type::getAs() const; |
3077 | |
3078 | // We can do canonical leaf types faster, because we don't have to |
3079 | // worry about preserving child type decoration. |
3080 | #define TYPE(Class, Base) |
3081 | #define LEAF_TYPE(Class) \ |
3082 | template <> inline const Class##Type *Type::getAs() const { \ |
3083 | return dyn_cast<Class##Type>(CanonicalType); \ |
3084 | } \ |
3085 | template <> inline const Class##Type *Type::castAs() const { \ |
3086 | return cast<Class##Type>(CanonicalType); \ |
3087 | } |
3088 | #include "clang/AST/TypeNodes.inc" |
3089 | |
3090 | /// This class is used for builtin types like 'int'. Builtin |
3091 | /// types are always canonical and have a literal name field. |
3092 | class BuiltinType : public Type { |
3093 | public: |
3094 | enum Kind { |
3095 | // OpenCL image types |
3096 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id, |
3097 | #include "clang/Basic/OpenCLImageTypes.def" |
3098 | // OpenCL extension types |
3099 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id, |
3100 | #include "clang/Basic/OpenCLExtensionTypes.def" |
3101 | // SVE Types |
3102 | #define SVE_TYPE(Name, Id, SingletonId) Id, |
3103 | #include "clang/Basic/AArch64ACLETypes.def" |
3104 | // PPC MMA Types |
3105 | #define PPC_VECTOR_TYPE(Name, Id, Size) Id, |
3106 | #include "clang/Basic/PPCTypes.def" |
3107 | // RVV Types |
3108 | #define RVV_TYPE(Name, Id, SingletonId) Id, |
3109 | #include "clang/Basic/RISCVVTypes.def" |
3110 | // WebAssembly reference types |
3111 | #define WASM_TYPE(Name, Id, SingletonId) Id, |
3112 | #include "clang/Basic/WebAssemblyReferenceTypes.def" |
3113 | // AMDGPU types |
3114 | #define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) Id, |
3115 | #include "clang/Basic/AMDGPUTypes.def" |
3116 | // HLSL intangible Types |
3117 | #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) Id, |
3118 | #include "clang/Basic/HLSLIntangibleTypes.def" |
3119 | // All other builtin types |
3120 | #define BUILTIN_TYPE(Id, SingletonId) Id, |
3121 | #define LAST_BUILTIN_TYPE(Id) LastKind = Id |
3122 | #include "clang/AST/BuiltinTypes.def" |
3123 | }; |
3124 | |
3125 | private: |
3126 | friend class ASTContext; // ASTContext creates these. |
3127 | |
3128 | BuiltinType(Kind K) |
3129 | : Type(Builtin, QualType(), |
3130 | K == Dependent ? TypeDependence::DependentInstantiation |
3131 | : TypeDependence::None) { |
3132 | static_assert(Kind::LastKind < |
3133 | (1 << BuiltinTypeBitfields::NumOfBuiltinTypeBits) && |
3134 | "Defined builtin type exceeds the allocated space for serial " |
3135 | "numbering" ); |
3136 | BuiltinTypeBits.Kind = K; |
3137 | } |
3138 | |
3139 | public: |
3140 | Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } |
3141 | StringRef getName(const PrintingPolicy &Policy) const; |
3142 | |
3143 | const char *getNameAsCString(const PrintingPolicy &Policy) const { |
3144 | // The StringRef is null-terminated. |
3145 | StringRef str = getName(Policy); |
3146 | assert(!str.empty() && str.data()[str.size()] == '\0'); |
3147 | return str.data(); |
3148 | } |
3149 | |
3150 | bool isSugared() const { return false; } |
3151 | QualType desugar() const { return QualType(this, 0); } |
3152 | |
3153 | bool isInteger() const { |
3154 | return getKind() >= Bool && getKind() <= Int128; |
3155 | } |
3156 | |
3157 | bool isSignedInteger() const { |
3158 | return getKind() >= Char_S && getKind() <= Int128; |
3159 | } |
3160 | |
3161 | bool isUnsignedInteger() const { |
3162 | return getKind() >= Bool && getKind() <= UInt128; |
3163 | } |
3164 | |
3165 | bool isFloatingPoint() const { |
3166 | return getKind() >= Half && getKind() <= Ibm128; |
3167 | } |
3168 | |
3169 | bool isSVEBool() const { return getKind() == Kind::SveBool; } |
3170 | |
3171 | bool isSVECount() const { return getKind() == Kind::SveCount; } |
3172 | |
3173 | /// Determines whether the given kind corresponds to a placeholder type. |
3174 | static bool isPlaceholderTypeKind(Kind K) { |
3175 | return K >= Overload; |
3176 | } |
3177 | |
3178 | /// Determines whether this type is a placeholder type, i.e. a type |
3179 | /// which cannot appear in arbitrary positions in a fully-formed |
3180 | /// expression. |
3181 | bool isPlaceholderType() const { |
3182 | return isPlaceholderTypeKind(K: getKind()); |
3183 | } |
3184 | |
3185 | /// Determines whether this type is a placeholder type other than |
3186 | /// Overload. Most placeholder types require only syntactic |
3187 | /// information about their context in order to be resolved (e.g. |
3188 | /// whether it is a call expression), which means they can (and |
3189 | /// should) be resolved in an earlier "phase" of analysis. |
3190 | /// Overload expressions sometimes pick up further information |
3191 | /// from their context, like whether the context expects a |
3192 | /// specific function-pointer type, and so frequently need |
3193 | /// special treatment. |
3194 | bool isNonOverloadPlaceholderType() const { |
3195 | return getKind() > Overload; |
3196 | } |
3197 | |
3198 | static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } |
3199 | }; |
3200 | |
3201 | /// Complex values, per C99 6.2.5p11. This supports the C99 complex |
3202 | /// types (_Complex float etc) as well as the GCC integer complex extensions. |
3203 | class ComplexType : public Type, public llvm::FoldingSetNode { |
3204 | friend class ASTContext; // ASTContext creates these. |
3205 | |
3206 | QualType ElementType; |
3207 | |
3208 | ComplexType(QualType Element, QualType CanonicalPtr) |
3209 | : Type(Complex, CanonicalPtr, Element->getDependence()), |
3210 | ElementType(Element) {} |
3211 | |
3212 | public: |
3213 | QualType getElementType() const { return ElementType; } |
3214 | |
3215 | bool isSugared() const { return false; } |
3216 | QualType desugar() const { return QualType(this, 0); } |
3217 | |
3218 | void Profile(llvm::FoldingSetNodeID &ID) { |
3219 | Profile(ID, Element: getElementType()); |
3220 | } |
3221 | |
3222 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { |
3223 | ID.AddPointer(Ptr: Element.getAsOpaquePtr()); |
3224 | } |
3225 | |
3226 | static bool classof(const Type *T) { return T->getTypeClass() == Complex; } |
3227 | }; |
3228 | |
3229 | /// Sugar for parentheses used when specifying types. |
3230 | class ParenType : public Type, public llvm::FoldingSetNode { |
3231 | friend class ASTContext; // ASTContext creates these. |
3232 | |
3233 | QualType Inner; |
3234 | |
3235 | ParenType(QualType InnerType, QualType CanonType) |
3236 | : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {} |
3237 | |
3238 | public: |
3239 | QualType getInnerType() const { return Inner; } |
3240 | |
3241 | bool isSugared() const { return true; } |
3242 | QualType desugar() const { return getInnerType(); } |
3243 | |
3244 | void Profile(llvm::FoldingSetNodeID &ID) { |
3245 | Profile(ID, Inner: getInnerType()); |
3246 | } |
3247 | |
3248 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { |
3249 | Inner.Profile(ID); |
3250 | } |
3251 | |
3252 | static bool classof(const Type *T) { return T->getTypeClass() == Paren; } |
3253 | }; |
3254 | |
3255 | /// PointerType - C99 6.7.5.1 - Pointer Declarators. |
3256 | class PointerType : public Type, public llvm::FoldingSetNode { |
3257 | friend class ASTContext; // ASTContext creates these. |
3258 | |
3259 | QualType PointeeType; |
3260 | |
3261 | PointerType(QualType Pointee, QualType CanonicalPtr) |
3262 | : Type(Pointer, CanonicalPtr, Pointee->getDependence()), |
3263 | PointeeType(Pointee) {} |
3264 | |
3265 | public: |
3266 | QualType getPointeeType() const { return PointeeType; } |
3267 | |
3268 | bool isSugared() const { return false; } |
3269 | QualType desugar() const { return QualType(this, 0); } |
3270 | |
3271 | void Profile(llvm::FoldingSetNodeID &ID) { |
3272 | Profile(ID, Pointee: getPointeeType()); |
3273 | } |
3274 | |
3275 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { |
3276 | ID.AddPointer(Ptr: Pointee.getAsOpaquePtr()); |
3277 | } |
3278 | |
3279 | static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } |
3280 | }; |
3281 | |
3282 | /// [BoundsSafety] Represents information of declarations referenced by the |
3283 | /// arguments of the `counted_by` attribute and the likes. |
3284 | class TypeCoupledDeclRefInfo { |
3285 | public: |
3286 | using BaseTy = llvm::PointerIntPair<ValueDecl *, 1, unsigned>; |
3287 | |
3288 | private: |
3289 | enum { |
3290 | DerefShift = 0, |
3291 | DerefMask = 1, |
3292 | }; |
3293 | BaseTy Data; |
3294 | |
3295 | public: |
3296 | /// \p D is to a declaration referenced by the argument of attribute. \p Deref |
3297 | /// indicates whether \p D is referenced as a dereferenced form, e.g., \p |
3298 | /// Deref is true for `*n` in `int *__counted_by(*n)`. |
3299 | TypeCoupledDeclRefInfo(ValueDecl *D = nullptr, bool Deref = false); |
3300 | |
3301 | bool isDeref() const; |
3302 | ValueDecl *getDecl() const; |
3303 | unsigned getInt() const; |
3304 | void *getOpaqueValue() const; |
3305 | bool operator==(const TypeCoupledDeclRefInfo &Other) const; |
3306 | void setFromOpaqueValue(void *V); |
3307 | }; |
3308 | |
3309 | /// [BoundsSafety] Represents a parent type class for CountAttributedType and |
3310 | /// similar sugar types that will be introduced to represent a type with a |
3311 | /// bounds attribute. |
3312 | /// |
3313 | /// Provides a common interface to navigate declarations referred to by the |
3314 | /// bounds expression. |
3315 | |
3316 | class BoundsAttributedType : public Type, public llvm::FoldingSetNode { |
3317 | QualType WrappedTy; |
3318 | |
3319 | protected: |
3320 | ArrayRef<TypeCoupledDeclRefInfo> Decls; // stored in trailing objects |
3321 | |
3322 | BoundsAttributedType(TypeClass TC, QualType Wrapped, QualType Canon); |
3323 | |
3324 | public: |
3325 | bool isSugared() const { return true; } |
3326 | QualType desugar() const { return WrappedTy; } |
3327 | |
3328 | using decl_iterator = const TypeCoupledDeclRefInfo *; |
3329 | using decl_range = llvm::iterator_range<decl_iterator>; |
3330 | |
3331 | decl_iterator dependent_decl_begin() const { return Decls.begin(); } |
3332 | decl_iterator dependent_decl_end() const { return Decls.end(); } |
3333 | |
3334 | unsigned getNumCoupledDecls() const { return Decls.size(); } |
3335 | |
3336 | decl_range dependent_decls() const { |
3337 | return decl_range(dependent_decl_begin(), dependent_decl_end()); |
3338 | } |
3339 | |
3340 | ArrayRef<TypeCoupledDeclRefInfo> getCoupledDecls() const { |
3341 | return {dependent_decl_begin(), dependent_decl_end()}; |
3342 | } |
3343 | |
3344 | bool referencesFieldDecls() const; |
3345 | |
3346 | static bool classof(const Type *T) { |
3347 | // Currently, only `class CountAttributedType` inherits |
3348 | // `BoundsAttributedType` but the subclass will grow as we add more bounds |
3349 | // annotations. |
3350 | switch (T->getTypeClass()) { |
3351 | case CountAttributed: |
3352 | return true; |
3353 | default: |
3354 | return false; |
3355 | } |
3356 | } |
3357 | }; |
3358 | |
3359 | /// Represents a sugar type with `__counted_by` or `__sized_by` annotations, |
3360 | /// including their `_or_null` variants. |
3361 | class CountAttributedType final |
3362 | : public BoundsAttributedType, |
3363 | public llvm::TrailingObjects<CountAttributedType, |
3364 | TypeCoupledDeclRefInfo> { |
3365 | friend class ASTContext; |
3366 | |
3367 | Expr *CountExpr; |
3368 | /// \p CountExpr represents the argument of __counted_by or the likes. \p |
3369 | /// CountInBytes indicates that \p CountExpr is a byte count (i.e., |
3370 | /// __sized_by(_or_null)) \p OrNull means it's an or_null variant (i.e., |
3371 | /// __counted_by_or_null or __sized_by_or_null) \p CoupledDecls contains the |
3372 | /// list of declarations referenced by \p CountExpr, which the type depends on |
3373 | /// for the bounds information. |
3374 | CountAttributedType(QualType Wrapped, QualType Canon, Expr *CountExpr, |
3375 | bool CountInBytes, bool OrNull, |
3376 | ArrayRef<TypeCoupledDeclRefInfo> CoupledDecls); |
3377 | |
3378 | unsigned numTrailingObjects(OverloadToken<TypeCoupledDeclRefInfo>) const { |
3379 | return CountAttributedTypeBits.NumCoupledDecls; |
3380 | } |
3381 | |
3382 | public: |
3383 | enum DynamicCountPointerKind { |
3384 | CountedBy = 0, |
3385 | SizedBy, |
3386 | CountedByOrNull, |
3387 | SizedByOrNull, |
3388 | }; |
3389 | |
3390 | Expr *getCountExpr() const { return CountExpr; } |
3391 | bool isCountInBytes() const { return CountAttributedTypeBits.CountInBytes; } |
3392 | bool isOrNull() const { return CountAttributedTypeBits.OrNull; } |
3393 | |
3394 | DynamicCountPointerKind getKind() const { |
3395 | if (isOrNull()) |
3396 | return isCountInBytes() ? SizedByOrNull : CountedByOrNull; |
3397 | return isCountInBytes() ? SizedBy : CountedBy; |
3398 | } |
3399 | |
3400 | void Profile(llvm::FoldingSetNodeID &ID) { |
3401 | Profile(ID, desugar(), CountExpr, isCountInBytes(), isOrNull()); |
3402 | } |
3403 | |
3404 | static void Profile(llvm::FoldingSetNodeID &ID, QualType WrappedTy, |
3405 | Expr *CountExpr, bool CountInBytes, bool Nullable); |
3406 | |
3407 | static bool classof(const Type *T) { |
3408 | return T->getTypeClass() == CountAttributed; |
3409 | } |
3410 | |
3411 | StringRef getAttributeName(bool WithMacroPrefix) const; |
3412 | }; |
3413 | |
3414 | /// Represents a type which was implicitly adjusted by the semantic |
3415 | /// engine for arbitrary reasons. For example, array and function types can |
3416 | /// decay, and function types can have their calling conventions adjusted. |
3417 | class AdjustedType : public Type, public llvm::FoldingSetNode { |
3418 | QualType OriginalTy; |
3419 | QualType AdjustedTy; |
3420 | |
3421 | protected: |
3422 | friend class ASTContext; // ASTContext creates these. |
3423 | |
3424 | AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, |
3425 | QualType CanonicalPtr) |
3426 | : Type(TC, CanonicalPtr, OriginalTy->getDependence()), |
3427 | OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} |
3428 | |
3429 | public: |
3430 | QualType getOriginalType() const { return OriginalTy; } |
3431 | QualType getAdjustedType() const { return AdjustedTy; } |
3432 | |
3433 | bool isSugared() const { return true; } |
3434 | QualType desugar() const { return AdjustedTy; } |
3435 | |
3436 | void Profile(llvm::FoldingSetNodeID &ID) { |
3437 | Profile(ID, OriginalTy, AdjustedTy); |
3438 | } |
3439 | |
3440 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) { |
3441 | ID.AddPointer(Ptr: Orig.getAsOpaquePtr()); |
3442 | ID.AddPointer(Ptr: New.getAsOpaquePtr()); |
3443 | } |
3444 | |
3445 | static bool classof(const Type *T) { |
3446 | return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed; |
3447 | } |
3448 | }; |
3449 | |
3450 | /// Represents a pointer type decayed from an array or function type. |
3451 | class DecayedType : public AdjustedType { |
3452 | friend class ASTContext; // ASTContext creates these. |
3453 | |
3454 | inline |
3455 | DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical); |
3456 | |
3457 | public: |
3458 | QualType getDecayedType() const { return getAdjustedType(); } |
3459 | |
3460 | inline QualType getPointeeType() const; |
3461 | |
3462 | static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } |
3463 | }; |
3464 | |
3465 | /// Pointer to a block type. |
3466 | /// This type is to represent types syntactically represented as |
3467 | /// "void (^)(int)", etc. Pointee is required to always be a function type. |
3468 | class BlockPointerType : public Type, public llvm::FoldingSetNode { |
3469 | friend class ASTContext; // ASTContext creates these. |
3470 | |
3471 | // Block is some kind of pointer type |
3472 | QualType PointeeType; |
3473 | |
3474 | BlockPointerType(QualType Pointee, QualType CanonicalCls) |
3475 | : Type(BlockPointer, CanonicalCls, Pointee->getDependence()), |
3476 | PointeeType(Pointee) {} |
3477 | |
3478 | public: |
3479 | // Get the pointee type. Pointee is required to always be a function type. |
3480 | QualType getPointeeType() const { return PointeeType; } |
3481 | |
3482 | bool isSugared() const { return false; } |
3483 | QualType desugar() const { return QualType(this, 0); } |
3484 | |
3485 | void Profile(llvm::FoldingSetNodeID &ID) { |
3486 | Profile(ID, Pointee: getPointeeType()); |
3487 | } |
3488 | |
3489 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { |
3490 | ID.AddPointer(Ptr: Pointee.getAsOpaquePtr()); |
3491 | } |
3492 | |
3493 | static bool classof(const Type *T) { |
3494 | return T->getTypeClass() == BlockPointer; |
3495 | } |
3496 | }; |
3497 | |
3498 | /// Base for LValueReferenceType and RValueReferenceType |
3499 | class ReferenceType : public Type, public llvm::FoldingSetNode { |
3500 | QualType PointeeType; |
3501 | |
3502 | protected: |
3503 | ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, |
3504 | bool SpelledAsLValue) |
3505 | : Type(tc, CanonicalRef, Referencee->getDependence()), |
3506 | PointeeType(Referencee) { |
3507 | ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; |
3508 | ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); |
3509 | } |
3510 | |
3511 | public: |
3512 | bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; } |
3513 | bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } |
3514 | |
3515 | QualType getPointeeTypeAsWritten() const { return PointeeType; } |
3516 | |
3517 | QualType getPointeeType() const { |
3518 | // FIXME: this might strip inner qualifiers; okay? |
3519 | const ReferenceType *T = this; |
3520 | while (T->isInnerRef()) |
3521 | T = T->PointeeType->castAs<ReferenceType>(); |
3522 | return T->PointeeType; |
3523 | } |
3524 | |
3525 | void Profile(llvm::FoldingSetNodeID &ID) { |
3526 | Profile(ID, PointeeType, isSpelledAsLValue()); |
3527 | } |
3528 | |
3529 | static void Profile(llvm::FoldingSetNodeID &ID, |
3530 | QualType Referencee, |
3531 | bool SpelledAsLValue) { |
3532 | ID.AddPointer(Ptr: Referencee.getAsOpaquePtr()); |
3533 | ID.AddBoolean(B: SpelledAsLValue); |
3534 | } |
3535 | |
3536 | static bool classof(const Type *T) { |
3537 | return T->getTypeClass() == LValueReference || |
3538 | T->getTypeClass() == RValueReference; |
3539 | } |
3540 | }; |
3541 | |
3542 | /// An lvalue reference type, per C++11 [dcl.ref]. |
3543 | class LValueReferenceType : public ReferenceType { |
3544 | friend class ASTContext; // ASTContext creates these |
3545 | |
3546 | LValueReferenceType(QualType Referencee, QualType CanonicalRef, |
3547 | bool SpelledAsLValue) |
3548 | : ReferenceType(LValueReference, Referencee, CanonicalRef, |
3549 | SpelledAsLValue) {} |
3550 | |
3551 | public: |
3552 | bool isSugared() const { return false; } |
3553 | QualType desugar() const { return QualType(this, 0); } |
3554 | |
3555 | static bool classof(const Type *T) { |
3556 | return T->getTypeClass() == LValueReference; |
3557 | } |
3558 | }; |
3559 | |
3560 | /// An rvalue reference type, per C++11 [dcl.ref]. |
3561 | class RValueReferenceType : public ReferenceType { |
3562 | friend class ASTContext; // ASTContext creates these |
3563 | |
3564 | RValueReferenceType(QualType Referencee, QualType CanonicalRef) |
3565 | : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {} |
3566 | |
3567 | public: |
3568 | bool isSugared() const { return false; } |
3569 | QualType desugar() const { return QualType(this, 0); } |
3570 | |
3571 | static bool classof(const Type *T) { |
3572 | return T->getTypeClass() == RValueReference; |
3573 | } |
3574 | }; |
3575 | |
3576 | /// A pointer to member type per C++ 8.3.3 - Pointers to members. |
3577 | /// |
3578 | /// This includes both pointers to data members and pointer to member functions. |
3579 | class MemberPointerType : public Type, public llvm::FoldingSetNode { |
3580 | friend class ASTContext; // ASTContext creates these. |
3581 | |
3582 | QualType PointeeType; |
3583 | |
3584 | /// The class of which the pointee is a member. Must ultimately be a |
3585 | /// CXXRecordType, but could be a typedef or a template parameter too. |
3586 | NestedNameSpecifier *Qualifier; |
3587 | |
3588 | MemberPointerType(QualType Pointee, NestedNameSpecifier *Qualifier, |
3589 | QualType CanonicalPtr) |
3590 | : Type(MemberPointer, CanonicalPtr, |
3591 | (toTypeDependence(Qualifier->getDependence()) & |
3592 | ~TypeDependence::VariablyModified) | |
3593 | Pointee->getDependence()), |
3594 | PointeeType(Pointee), Qualifier(Qualifier) {} |
3595 | |
3596 | public: |
3597 | QualType getPointeeType() const { return PointeeType; } |
3598 | |
3599 | /// Returns true if the member type (i.e. the pointee type) is a |
3600 | /// function type rather than a data-member type. |
3601 | bool isMemberFunctionPointer() const { |
3602 | return PointeeType->isFunctionProtoType(); |
3603 | } |
3604 | |
3605 | /// Returns true if the member type (i.e. the pointee type) is a |
3606 | /// data type rather than a function type. |
3607 | bool isMemberDataPointer() const { |
3608 | return !PointeeType->isFunctionProtoType(); |
3609 | } |
3610 | |
3611 | NestedNameSpecifier *getQualifier() const { return Qualifier; } |
3612 | /// Note: this can trigger extra deserialization when external AST sources are |
3613 | /// used. Prefer `getCXXRecordDecl()` unless you really need the most recent |
3614 | /// decl. |
3615 | CXXRecordDecl *getMostRecentCXXRecordDecl() const; |
3616 | |
3617 | bool isSugared() const; |
3618 | QualType desugar() const { |
3619 | return isSugared() ? getCanonicalTypeInternal() : QualType(this, 0); |
3620 | } |
3621 | |
3622 | void Profile(llvm::FoldingSetNodeID &ID) { |
3623 | // FIXME: `getMostRecentCXXRecordDecl()` should be possible to use here, |
3624 | // however when external AST sources are used it causes nondeterminism |
3625 | // issues (see https://github.com/llvm/llvm-project/pull/137910). |
3626 | Profile(ID, Pointee: getPointeeType(), Qualifier: getQualifier(), Cls: getCXXRecordDecl()); |
3627 | } |
3628 | |
3629 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, |
3630 | const NestedNameSpecifier *Qualifier, |
3631 | const CXXRecordDecl *Cls); |
3632 | |
3633 | static bool classof(const Type *T) { |
3634 | return T->getTypeClass() == MemberPointer; |
3635 | } |
3636 | |
3637 | private: |
3638 | CXXRecordDecl *getCXXRecordDecl() const; |
3639 | }; |
3640 | |
3641 | /// Capture whether this is a normal array (e.g. int X[4]) |
3642 | /// an array with a static size (e.g. int X[static 4]), or an array |
3643 | /// with a star size (e.g. int X[*]). |
3644 | /// 'static' is only allowed on function parameters. |
3645 | enum class ArraySizeModifier { Normal, Static, Star }; |
3646 | |
3647 | /// Represents an array type, per C99 6.7.5.2 - Array Declarators. |
3648 | class ArrayType : public Type, public llvm::FoldingSetNode { |
3649 | private: |
3650 | /// The element type of the array. |
3651 | QualType ElementType; |
3652 | |
3653 | protected: |
3654 | friend class ASTContext; // ASTContext creates these. |
3655 | |
3656 | ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm, |
3657 | unsigned tq, const Expr *sz = nullptr); |
3658 | |
3659 | public: |
3660 | QualType getElementType() const { return ElementType; } |
3661 | |
3662 | ArraySizeModifier getSizeModifier() const { |
3663 | return ArraySizeModifier(ArrayTypeBits.SizeModifier); |
3664 | } |
3665 | |
3666 | Qualifiers getIndexTypeQualifiers() const { |
3667 | return Qualifiers::fromCVRMask(CVR: getIndexTypeCVRQualifiers()); |
3668 | } |
3669 | |
3670 | unsigned getIndexTypeCVRQualifiers() const { |
3671 | return ArrayTypeBits.IndexTypeQuals; |
3672 | } |
3673 | |
3674 | static bool classof(const Type *T) { |
3675 | return T->getTypeClass() == ConstantArray || |
3676 | T->getTypeClass() == VariableArray || |
3677 | T->getTypeClass() == IncompleteArray || |
3678 | T->getTypeClass() == DependentSizedArray || |
3679 | T->getTypeClass() == ArrayParameter; |
3680 | } |
3681 | }; |
3682 | |
3683 | /// Represents the canonical version of C arrays with a specified constant size. |
3684 | /// For example, the canonical type for 'int A[4 + 4*100]' is a |
3685 | /// ConstantArrayType where the element type is 'int' and the size is 404. |
3686 | class ConstantArrayType : public ArrayType { |
3687 | friend class ASTContext; // ASTContext creates these. |
3688 | |
3689 | struct ExternalSize { |
3690 | ExternalSize(const llvm::APInt &Sz, const Expr *SE) |
3691 | : Size(Sz), SizeExpr(SE) {} |
3692 | llvm::APInt Size; // Allows us to unique the type. |
3693 | const Expr *SizeExpr; |
3694 | }; |
3695 | |
3696 | union { |
3697 | uint64_t Size; |
3698 | ExternalSize *SizePtr; |
3699 | }; |
3700 | |
3701 | ConstantArrayType(QualType Et, QualType Can, uint64_t Width, uint64_t Sz, |
3702 | ArraySizeModifier SM, unsigned TQ) |
3703 | : ArrayType(ConstantArray, Et, Can, SM, TQ, nullptr), Size(Sz) { |
3704 | ConstantArrayTypeBits.HasExternalSize = false; |
3705 | ConstantArrayTypeBits.SizeWidth = Width / 8; |
3706 | // The in-structure size stores the size in bytes rather than bits so we |
3707 | // drop the three least significant bits since they're always zero anyways. |
3708 | assert(Width < 0xFF && "Type width in bits must be less than 8 bits" ); |
3709 | } |
3710 | |
3711 | ConstantArrayType(QualType Et, QualType Can, ExternalSize *SzPtr, |
3712 | ArraySizeModifier SM, unsigned TQ) |
3713 | : ArrayType(ConstantArray, Et, Can, SM, TQ, SzPtr->SizeExpr), |
3714 | SizePtr(SzPtr) { |
3715 | ConstantArrayTypeBits.HasExternalSize = true; |
3716 | ConstantArrayTypeBits.SizeWidth = 0; |
3717 | |
3718 | assert((SzPtr->SizeExpr == nullptr || !Can.isNull()) && |
3719 | "canonical constant array should not have size expression" ); |
3720 | } |
3721 | |
3722 | static ConstantArrayType *Create(const ASTContext &Ctx, QualType ET, |
3723 | QualType Can, const llvm::APInt &Sz, |
3724 | const Expr *SzExpr, ArraySizeModifier SzMod, |
3725 | unsigned Qual); |
3726 | |
3727 | protected: |
3728 | ConstantArrayType(TypeClass Tc, const ConstantArrayType *ATy, QualType Can) |
3729 | : ArrayType(Tc, ATy->getElementType(), Can, ATy->getSizeModifier(), |
3730 | ATy->getIndexTypeQualifiers().getAsOpaqueValue(), nullptr) { |
3731 | ConstantArrayTypeBits.HasExternalSize = |
3732 | ATy->ConstantArrayTypeBits.HasExternalSize; |
3733 | if (!ConstantArrayTypeBits.HasExternalSize) { |
3734 | ConstantArrayTypeBits.SizeWidth = ATy->ConstantArrayTypeBits.SizeWidth; |
3735 | Size = ATy->Size; |
3736 | } else |
3737 | SizePtr = ATy->SizePtr; |
3738 | } |
3739 | |
3740 | public: |
3741 | /// Return the constant array size as an APInt. |
3742 | llvm::APInt getSize() const { |
3743 | return ConstantArrayTypeBits.HasExternalSize |
3744 | ? SizePtr->Size |
3745 | : llvm::APInt(ConstantArrayTypeBits.SizeWidth * 8, Size); |
3746 | } |
3747 | |
3748 | /// Return the bit width of the size type. |
3749 | unsigned getSizeBitWidth() const { |
3750 | return ConstantArrayTypeBits.HasExternalSize |
3751 | ? SizePtr->Size.getBitWidth() |
3752 | : static_cast<unsigned>(ConstantArrayTypeBits.SizeWidth * 8); |
3753 | } |
3754 | |
3755 | /// Return true if the size is zero. |
3756 | bool isZeroSize() const { |
3757 | return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.isZero() |
3758 | : 0 == Size; |
3759 | } |
3760 | |
3761 | /// Return the size zero-extended as a uint64_t. |
3762 | uint64_t getZExtSize() const { |
3763 | return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getZExtValue() |
3764 | : Size; |
3765 | } |
3766 | |
3767 | /// Return the size sign-extended as a uint64_t. |
3768 | int64_t getSExtSize() const { |
3769 | return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getSExtValue() |
3770 | : static_cast<int64_t>(Size); |
3771 | } |
3772 | |
3773 | /// Return the size zero-extended to uint64_t or UINT64_MAX if the value is |
3774 | /// larger than UINT64_MAX. |
3775 | uint64_t getLimitedSize() const { |
3776 | return ConstantArrayTypeBits.HasExternalSize |
3777 | ? SizePtr->Size.getLimitedValue() |
3778 | : Size; |
3779 | } |
3780 | |
3781 | /// Return a pointer to the size expression. |
3782 | const Expr *getSizeExpr() const { |
3783 | return ConstantArrayTypeBits.HasExternalSize ? SizePtr->SizeExpr : nullptr; |
3784 | } |
3785 | |
3786 | bool isSugared() const { return false; } |
3787 | QualType desugar() const { return QualType(this, 0); } |
3788 | |
3789 | /// Determine the number of bits required to address a member of |
3790 | // an array with the given element type and number of elements. |
3791 | static unsigned getNumAddressingBits(const ASTContext &Context, |
3792 | QualType ElementType, |
3793 | const llvm::APInt &NumElements); |
3794 | |
3795 | unsigned getNumAddressingBits(const ASTContext &Context) const; |
3796 | |
3797 | /// Determine the maximum number of active bits that an array's size |
3798 | /// can require, which limits the maximum size of the array. |
3799 | static unsigned getMaxSizeBits(const ASTContext &Context); |
3800 | |
3801 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { |
3802 | Profile(ID, Ctx, getElementType(), getZExtSize(), getSizeExpr(), |
3803 | getSizeModifier(), getIndexTypeCVRQualifiers()); |
3804 | } |
3805 | |
3806 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx, |
3807 | QualType ET, uint64_t ArraySize, const Expr *SizeExpr, |
3808 | ArraySizeModifier SizeMod, unsigned TypeQuals); |
3809 | |
3810 | static bool classof(const Type *T) { |
3811 | return T->getTypeClass() == ConstantArray || |
3812 | T->getTypeClass() == ArrayParameter; |
3813 | } |
3814 | }; |
3815 | |
3816 | /// Represents a constant array type that does not decay to a pointer when used |
3817 | /// as a function parameter. |
3818 | class ArrayParameterType : public ConstantArrayType { |
3819 | friend class ASTContext; // ASTContext creates these. |
3820 | |
3821 | ArrayParameterType(const ConstantArrayType *ATy, QualType CanTy) |
3822 | : ConstantArrayType(ArrayParameter, ATy, CanTy) {} |
3823 | |
3824 | public: |
3825 | static bool classof(const Type *T) { |
3826 | return T->getTypeClass() == ArrayParameter; |
3827 | } |
3828 | |
3829 | QualType getConstantArrayType(const ASTContext &Ctx) const; |
3830 | }; |
3831 | |
3832 | /// Represents a C array with an unspecified size. For example 'int A[]' has |
3833 | /// an IncompleteArrayType where the element type is 'int' and the size is |
3834 | /// unspecified. |
3835 | class IncompleteArrayType : public ArrayType { |
3836 | friend class ASTContext; // ASTContext creates these. |
3837 | |
3838 | IncompleteArrayType(QualType et, QualType can, |
3839 | ArraySizeModifier sm, unsigned tq) |
3840 | : ArrayType(IncompleteArray, et, can, sm, tq) {} |
3841 | |
3842 | public: |
3843 | friend class StmtIteratorBase; |
3844 | |
3845 | bool isSugared() const { return false; } |
3846 | QualType desugar() const { return QualType(this, 0); } |
3847 | |
3848 | static bool classof(const Type *T) { |
3849 | return T->getTypeClass() == IncompleteArray; |
3850 | } |
3851 | |
3852 | void Profile(llvm::FoldingSetNodeID &ID) { |
3853 | Profile(ID, getElementType(), getSizeModifier(), |
3854 | getIndexTypeCVRQualifiers()); |
3855 | } |
3856 | |
3857 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, |
3858 | ArraySizeModifier SizeMod, unsigned TypeQuals) { |
3859 | ID.AddPointer(Ptr: ET.getAsOpaquePtr()); |
3860 | ID.AddInteger(llvm::to_underlying(SizeMod)); |
3861 | ID.AddInteger(I: TypeQuals); |
3862 | } |
3863 | }; |
3864 | |
3865 | /// Represents a C array with a specified size that is not an |
3866 | /// integer-constant-expression. For example, 'int s[x+foo()]'. |
3867 | /// Since the size expression is an arbitrary expression, we store it as such. |
3868 | /// |
3869 | /// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and |
3870 | /// should not be: two lexically equivalent variable array types could mean |
3871 | /// different things, for example, these variables do not have the same type |
3872 | /// dynamically: |
3873 | /// |
3874 | /// void foo(int x) { |
3875 | /// int Y[x]; |
3876 | /// ++x; |
3877 | /// int Z[x]; |
3878 | /// } |
3879 | /// |
3880 | /// FIXME: Even constant array types might be represented by a |
3881 | /// VariableArrayType, as in: |
3882 | /// |
3883 | /// void func(int n) { |
3884 | /// int array[7][n]; |
3885 | /// } |
3886 | /// |
3887 | /// Even though 'array' is a constant-size array of seven elements of type |
3888 | /// variable-length array of size 'n', it will be represented as a |
3889 | /// VariableArrayType whose 'SizeExpr' is an IntegerLiteral whose value is 7. |
3890 | /// Instead, this should be a ConstantArrayType whose element is a |
3891 | /// VariableArrayType, which models the type better. |
3892 | class VariableArrayType : public ArrayType { |
3893 | friend class ASTContext; // ASTContext creates these. |
3894 | |
3895 | /// An assignment-expression. VLA's are only permitted within |
3896 | /// a function block. |
3897 | Stmt *SizeExpr; |
3898 | |
3899 | VariableArrayType(QualType et, QualType can, Expr *e, ArraySizeModifier sm, |
3900 | unsigned tq) |
3901 | : ArrayType(VariableArray, et, can, sm, tq, e), SizeExpr((Stmt *)e) {} |
3902 | |
3903 | public: |
3904 | friend class StmtIteratorBase; |
3905 | |
3906 | Expr *getSizeExpr() const { |
3907 | // We use C-style casts instead of cast<> here because we do not wish |
3908 | // to have a dependency of Type.h on Stmt.h/Expr.h. |
3909 | return (Expr*) SizeExpr; |
3910 | } |
3911 | |
3912 | bool isSugared() const { return false; } |
3913 | QualType desugar() const { return QualType(this, 0); } |
3914 | |
3915 | static bool classof(const Type *T) { |
3916 | return T->getTypeClass() == VariableArray; |
3917 | } |
3918 | |
3919 | void Profile(llvm::FoldingSetNodeID &ID) { |
3920 | llvm_unreachable("Cannot unique VariableArrayTypes." ); |
3921 | } |
3922 | }; |
3923 | |
3924 | /// Represents an array type in C++ whose size is a value-dependent expression. |
3925 | /// |
3926 | /// For example: |
3927 | /// \code |
3928 | /// template<typename T, int Size> |
3929 | /// class array { |
3930 | /// T data[Size]; |
3931 | /// }; |
3932 | /// \endcode |
3933 | /// |
3934 | /// For these types, we won't actually know what the array bound is |
3935 | /// until template instantiation occurs, at which point this will |
3936 | /// become either a ConstantArrayType or a VariableArrayType. |
3937 | class DependentSizedArrayType : public ArrayType { |
3938 | friend class ASTContext; // ASTContext creates these. |
3939 | |
3940 | /// An assignment expression that will instantiate to the |
3941 | /// size of the array. |
3942 | /// |
3943 | /// The expression itself might be null, in which case the array |
3944 | /// type will have its size deduced from an initializer. |
3945 | Stmt *SizeExpr; |
3946 | |
3947 | DependentSizedArrayType(QualType et, QualType can, Expr *e, |
3948 | ArraySizeModifier sm, unsigned tq); |
3949 | |
3950 | public: |
3951 | friend class StmtIteratorBase; |
3952 | |
3953 | Expr *getSizeExpr() const { |
3954 | // We use C-style casts instead of cast<> here because we do not wish |
3955 | // to have a dependency of Type.h on Stmt.h/Expr.h. |
3956 | return (Expr*) SizeExpr; |
3957 | } |
3958 | |
3959 | bool isSugared() const { return false; } |
3960 | QualType desugar() const { return QualType(this, 0); } |
3961 | |
3962 | static bool classof(const Type *T) { |
3963 | return T->getTypeClass() == DependentSizedArray; |
3964 | } |
3965 | |
3966 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
3967 | Profile(ID, Context, getElementType(), |
3968 | getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr()); |
3969 | } |
3970 | |
3971 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
3972 | QualType ET, ArraySizeModifier SizeMod, |
3973 | unsigned TypeQuals, Expr *E); |
3974 | }; |
3975 | |
3976 | /// Represents an extended address space qualifier where the input address space |
3977 | /// value is dependent. Non-dependent address spaces are not represented with a |
3978 | /// special Type subclass; they are stored on an ExtQuals node as part of a QualType. |
3979 | /// |
3980 | /// For example: |
3981 | /// \code |
3982 | /// template<typename T, int AddrSpace> |
3983 | /// class AddressSpace { |
3984 | /// typedef T __attribute__((address_space(AddrSpace))) type; |
3985 | /// } |
3986 | /// \endcode |
3987 | class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode { |
3988 | friend class ASTContext; |
3989 | |
3990 | Expr *AddrSpaceExpr; |
3991 | QualType PointeeType; |
3992 | SourceLocation loc; |
3993 | |
3994 | DependentAddressSpaceType(QualType PointeeType, QualType can, |
3995 | Expr *AddrSpaceExpr, SourceLocation loc); |
3996 | |
3997 | public: |
3998 | Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; } |
3999 | QualType getPointeeType() const { return PointeeType; } |
4000 | SourceLocation getAttributeLoc() const { return loc; } |
4001 | |
4002 | bool isSugared() const { return false; } |
4003 | QualType desugar() const { return QualType(this, 0); } |
4004 | |
4005 | static bool classof(const Type *T) { |
4006 | return T->getTypeClass() == DependentAddressSpace; |
4007 | } |
4008 | |
4009 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
4010 | Profile(ID, Context, PointeeType: getPointeeType(), AddrSpaceExpr: getAddrSpaceExpr()); |
4011 | } |
4012 | |
4013 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
4014 | QualType PointeeType, Expr *AddrSpaceExpr); |
4015 | }; |
4016 | |
4017 | /// Represents an extended vector type where either the type or size is |
4018 | /// dependent. |
4019 | /// |
4020 | /// For example: |
4021 | /// \code |
4022 | /// template<typename T, int Size> |
4023 | /// class vector { |
4024 | /// typedef T __attribute__((ext_vector_type(Size))) type; |
4025 | /// } |
4026 | /// \endcode |
4027 | class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { |
4028 | friend class ASTContext; |
4029 | |
4030 | Expr *SizeExpr; |
4031 | |
4032 | /// The element type of the array. |
4033 | QualType ElementType; |
4034 | |
4035 | SourceLocation loc; |
4036 | |
4037 | DependentSizedExtVectorType(QualType ElementType, QualType can, |
4038 | Expr *SizeExpr, SourceLocation loc); |
4039 | |
4040 | public: |
4041 | Expr *getSizeExpr() const { return SizeExpr; } |
4042 | QualType getElementType() const { return ElementType; } |
4043 | SourceLocation getAttributeLoc() const { return loc; } |
4044 | |
4045 | bool isSugared() const { return false; } |
4046 | QualType desugar() const { return QualType(this, 0); } |
4047 | |
4048 | static bool classof(const Type *T) { |
4049 | return T->getTypeClass() == DependentSizedExtVector; |
4050 | } |
4051 | |
4052 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
4053 | Profile(ID, Context, ElementType: getElementType(), SizeExpr: getSizeExpr()); |
4054 | } |
4055 | |
4056 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
4057 | QualType ElementType, Expr *SizeExpr); |
4058 | }; |
4059 | |
4060 | enum class VectorKind { |
4061 | /// not a target-specific vector type |
4062 | Generic, |
4063 | |
4064 | /// is AltiVec vector |
4065 | AltiVecVector, |
4066 | |
4067 | /// is AltiVec 'vector Pixel' |
4068 | AltiVecPixel, |
4069 | |
4070 | /// is AltiVec 'vector bool ...' |
4071 | AltiVecBool, |
4072 | |
4073 | /// is ARM Neon vector |
4074 | Neon, |
4075 | |
4076 | /// is ARM Neon polynomial vector |
4077 | NeonPoly, |
4078 | |
4079 | /// is AArch64 SVE fixed-length data vector |
4080 | SveFixedLengthData, |
4081 | |
4082 | /// is AArch64 SVE fixed-length predicate vector |
4083 | SveFixedLengthPredicate, |
4084 | |
4085 | /// is RISC-V RVV fixed-length data vector |
4086 | RVVFixedLengthData, |
4087 | |
4088 | /// is RISC-V RVV fixed-length mask vector |
4089 | RVVFixedLengthMask, |
4090 | |
4091 | RVVFixedLengthMask_1, |
4092 | RVVFixedLengthMask_2, |
4093 | RVVFixedLengthMask_4 |
4094 | }; |
4095 | |
4096 | /// Represents a GCC generic vector type. This type is created using |
4097 | /// __attribute__((vector_size(n)), where "n" specifies the vector size in |
4098 | /// bytes; or from an Altivec __vector or vector declaration. |
4099 | /// Since the constructor takes the number of vector elements, the |
4100 | /// client is responsible for converting the size into the number of elements. |
4101 | class VectorType : public Type, public llvm::FoldingSetNode { |
4102 | protected: |
4103 | friend class ASTContext; // ASTContext creates these. |
4104 | |
4105 | /// The element type of the vector. |
4106 | QualType ElementType; |
4107 | |
4108 | VectorType(QualType vecType, unsigned nElements, QualType canonType, |
4109 | VectorKind vecKind); |
4110 | |
4111 | VectorType(TypeClass tc, QualType vecType, unsigned nElements, |
4112 | QualType canonType, VectorKind vecKind); |
4113 | |
4114 | public: |
4115 | QualType getElementType() const { return ElementType; } |
4116 | unsigned getNumElements() const { return VectorTypeBits.NumElements; } |
4117 | |
4118 | bool isSugared() const { return false; } |
4119 | QualType desugar() const { return QualType(this, 0); } |
4120 | |
4121 | VectorKind getVectorKind() const { |
4122 | return VectorKind(VectorTypeBits.VecKind); |
4123 | } |
4124 | |
4125 | void Profile(llvm::FoldingSetNodeID &ID) { |
4126 | Profile(ID, getElementType(), getNumElements(), |
4127 | getTypeClass(), getVectorKind()); |
4128 | } |
4129 | |
4130 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, |
4131 | unsigned NumElements, TypeClass TypeClass, |
4132 | VectorKind VecKind) { |
4133 | ID.AddPointer(Ptr: ElementType.getAsOpaquePtr()); |
4134 | ID.AddInteger(I: NumElements); |
4135 | ID.AddInteger(I: TypeClass); |
4136 | ID.AddInteger(llvm::to_underlying(VecKind)); |
4137 | } |
4138 | |
4139 | static bool classof(const Type *T) { |
4140 | return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; |
4141 | } |
4142 | }; |
4143 | |
4144 | /// Represents a vector type where either the type or size is dependent. |
4145 | //// |
4146 | /// For example: |
4147 | /// \code |
4148 | /// template<typename T, int Size> |
4149 | /// class vector { |
4150 | /// typedef T __attribute__((vector_size(Size))) type; |
4151 | /// } |
4152 | /// \endcode |
4153 | class DependentVectorType : public Type, public llvm::FoldingSetNode { |
4154 | friend class ASTContext; |
4155 | |
4156 | QualType ElementType; |
4157 | Expr *SizeExpr; |
4158 | SourceLocation Loc; |
4159 | |
4160 | DependentVectorType(QualType ElementType, QualType CanonType, Expr *SizeExpr, |
4161 | SourceLocation Loc, VectorKind vecKind); |
4162 | |
4163 | public: |
4164 | Expr *getSizeExpr() const { return SizeExpr; } |
4165 | QualType getElementType() const { return ElementType; } |
4166 | SourceLocation getAttributeLoc() const { return Loc; } |
4167 | VectorKind getVectorKind() const { |
4168 | return VectorKind(VectorTypeBits.VecKind); |
4169 | } |
4170 | |
4171 | bool isSugared() const { return false; } |
4172 | QualType desugar() const { return QualType(this, 0); } |
4173 | |
4174 | static bool classof(const Type *T) { |
4175 | return T->getTypeClass() == DependentVector; |
4176 | } |
4177 | |
4178 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
4179 | Profile(ID, Context, ElementType: getElementType(), SizeExpr: getSizeExpr(), VecKind: getVectorKind()); |
4180 | } |
4181 | |
4182 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
4183 | QualType ElementType, const Expr *SizeExpr, |
4184 | VectorKind VecKind); |
4185 | }; |
4186 | |
4187 | /// ExtVectorType - Extended vector type. This type is created using |
4188 | /// __attribute__((ext_vector_type(n)), where "n" is the number of elements. |
4189 | /// Unlike vector_size, ext_vector_type is only allowed on typedef's. This |
4190 | /// class enables syntactic extensions, like Vector Components for accessing |
4191 | /// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL |
4192 | /// Shading Language). |
4193 | class ExtVectorType : public VectorType { |
4194 | friend class ASTContext; // ASTContext creates these. |
4195 | |
4196 | ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) |
4197 | : VectorType(ExtVector, vecType, nElements, canonType, |
4198 | VectorKind::Generic) {} |
4199 | |
4200 | public: |
4201 | static int getPointAccessorIdx(char c) { |
4202 | switch (c) { |
4203 | default: return -1; |
4204 | case 'x': case 'r': return 0; |
4205 | case 'y': case 'g': return 1; |
4206 | case 'z': case 'b': return 2; |
4207 | case 'w': case 'a': return 3; |
4208 | } |
4209 | } |
4210 | |
4211 | static int getNumericAccessorIdx(char c) { |
4212 | switch (c) { |
4213 | default: return -1; |
4214 | case '0': return 0; |
4215 | case '1': return 1; |
4216 | case '2': return 2; |
4217 | case '3': return 3; |
4218 | case '4': return 4; |
4219 | case '5': return 5; |
4220 | case '6': return 6; |
4221 | case '7': return 7; |
4222 | case '8': return 8; |
4223 | case '9': return 9; |
4224 | case 'A': |
4225 | case 'a': return 10; |
4226 | case 'B': |
4227 | case 'b': return 11; |
4228 | case 'C': |
4229 | case 'c': return 12; |
4230 | case 'D': |
4231 | case 'd': return 13; |
4232 | case 'E': |
4233 | case 'e': return 14; |
4234 | case 'F': |
4235 | case 'f': return 15; |
4236 | } |
4237 | } |
4238 | |
4239 | static int getAccessorIdx(char c, bool isNumericAccessor) { |
4240 | if (isNumericAccessor) |
4241 | return getNumericAccessorIdx(c); |
4242 | else |
4243 | return getPointAccessorIdx(c); |
4244 | } |
4245 | |
4246 | bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const { |
4247 | if (int idx = getAccessorIdx(c, isNumericAccessor)+1) |
4248 | return unsigned(idx-1) < getNumElements(); |
4249 | return false; |
4250 | } |
4251 | |
4252 | bool isSugared() const { return false; } |
4253 | QualType desugar() const { return QualType(this, 0); } |
4254 | |
4255 | static bool classof(const Type *T) { |
4256 | return T->getTypeClass() == ExtVector; |
4257 | } |
4258 | }; |
4259 | |
4260 | /// Represents a matrix type, as defined in the Matrix Types clang extensions. |
4261 | /// __attribute__((matrix_type(rows, columns))), where "rows" specifies |
4262 | /// number of rows and "columns" specifies the number of columns. |
4263 | class MatrixType : public Type, public llvm::FoldingSetNode { |
4264 | protected: |
4265 | friend class ASTContext; |
4266 | |
4267 | /// The element type of the matrix. |
4268 | QualType ElementType; |
4269 | |
4270 | MatrixType(QualType ElementTy, QualType CanonElementTy); |
4271 | |
4272 | MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy, |
4273 | const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr); |
4274 | |
4275 | public: |
4276 | /// Returns type of the elements being stored in the matrix |
4277 | QualType getElementType() const { return ElementType; } |
4278 | |
4279 | /// Valid elements types are the following: |
4280 | /// * an integer type (as in C23 6.2.5p22), but excluding enumerated types |
4281 | /// and _Bool |
4282 | /// * the standard floating types float or double |
4283 | /// * a half-precision floating point type, if one is supported on the target |
4284 | static bool isValidElementType(QualType T) { |
4285 | return T->isDependentType() || |
4286 | (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType()); |
4287 | } |
4288 | |
4289 | bool isSugared() const { return false; } |
4290 | QualType desugar() const { return QualType(this, 0); } |
4291 | |
4292 | static bool classof(const Type *T) { |
4293 | return T->getTypeClass() == ConstantMatrix || |
4294 | T->getTypeClass() == DependentSizedMatrix; |
4295 | } |
4296 | }; |
4297 | |
4298 | /// Represents a concrete matrix type with constant number of rows and columns |
4299 | class ConstantMatrixType final : public MatrixType { |
4300 | protected: |
4301 | friend class ASTContext; |
4302 | |
4303 | /// Number of rows and columns. |
4304 | unsigned NumRows; |
4305 | unsigned NumColumns; |
4306 | |
4307 | static constexpr unsigned MaxElementsPerDimension = (1 << 20) - 1; |
4308 | |
4309 | ConstantMatrixType(QualType MatrixElementType, unsigned NRows, |
4310 | unsigned NColumns, QualType CanonElementType); |
4311 | |
4312 | ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows, |
4313 | unsigned NColumns, QualType CanonElementType); |
4314 | |
4315 | public: |
4316 | /// Returns the number of rows in the matrix. |
4317 | unsigned getNumRows() const { return NumRows; } |
4318 | |
4319 | /// Returns the number of columns in the matrix. |
4320 | unsigned getNumColumns() const { return NumColumns; } |
4321 | |
4322 | /// Returns the number of elements required to embed the matrix into a vector. |
4323 | unsigned getNumElementsFlattened() const { |
4324 | return getNumRows() * getNumColumns(); |
4325 | } |
4326 | |
4327 | /// Returns true if \p NumElements is a valid matrix dimension. |
4328 | static constexpr bool isDimensionValid(size_t NumElements) { |
4329 | return NumElements > 0 && NumElements <= MaxElementsPerDimension; |
4330 | } |
4331 | |
4332 | /// Returns the maximum number of elements per dimension. |
4333 | static constexpr unsigned getMaxElementsPerDimension() { |
4334 | return MaxElementsPerDimension; |
4335 | } |
4336 | |
4337 | void Profile(llvm::FoldingSetNodeID &ID) { |
4338 | Profile(ID, getElementType(), getNumRows(), getNumColumns(), |
4339 | getTypeClass()); |
4340 | } |
4341 | |
4342 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, |
4343 | unsigned NumRows, unsigned NumColumns, |
4344 | TypeClass TypeClass) { |
4345 | ID.AddPointer(Ptr: ElementType.getAsOpaquePtr()); |
4346 | ID.AddInteger(I: NumRows); |
4347 | ID.AddInteger(I: NumColumns); |
4348 | ID.AddInteger(I: TypeClass); |
4349 | } |
4350 | |
4351 | static bool classof(const Type *T) { |
4352 | return T->getTypeClass() == ConstantMatrix; |
4353 | } |
4354 | }; |
4355 | |
4356 | /// Represents a matrix type where the type and the number of rows and columns |
4357 | /// is dependent on a template. |
4358 | class DependentSizedMatrixType final : public MatrixType { |
4359 | friend class ASTContext; |
4360 | |
4361 | Expr *RowExpr; |
4362 | Expr *ColumnExpr; |
4363 | |
4364 | SourceLocation loc; |
4365 | |
4366 | DependentSizedMatrixType(QualType ElementType, QualType CanonicalType, |
4367 | Expr *RowExpr, Expr *ColumnExpr, SourceLocation loc); |
4368 | |
4369 | public: |
4370 | Expr *getRowExpr() const { return RowExpr; } |
4371 | Expr *getColumnExpr() const { return ColumnExpr; } |
4372 | SourceLocation getAttributeLoc() const { return loc; } |
4373 | |
4374 | static bool classof(const Type *T) { |
4375 | return T->getTypeClass() == DependentSizedMatrix; |
4376 | } |
4377 | |
4378 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
4379 | Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr()); |
4380 | } |
4381 | |
4382 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
4383 | QualType ElementType, Expr *RowExpr, Expr *ColumnExpr); |
4384 | }; |
4385 | |
4386 | /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base |
4387 | /// class of FunctionNoProtoType and FunctionProtoType. |
4388 | class FunctionType : public Type { |
4389 | // The type returned by the function. |
4390 | QualType ResultType; |
4391 | |
4392 | public: |
4393 | /// Interesting information about a specific parameter that can't simply |
4394 | /// be reflected in parameter's type. This is only used by FunctionProtoType |
4395 | /// but is in FunctionType to make this class available during the |
4396 | /// specification of the bases of FunctionProtoType. |
4397 | /// |
4398 | /// It makes sense to model language features this way when there's some |
4399 | /// sort of parameter-specific override (such as an attribute) that |
4400 | /// affects how the function is called. For example, the ARC ns_consumed |
4401 | /// attribute changes whether a parameter is passed at +0 (the default) |
4402 | /// or +1 (ns_consumed). This must be reflected in the function type, |
4403 | /// but isn't really a change to the parameter type. |
4404 | /// |
4405 | /// One serious disadvantage of modelling language features this way is |
4406 | /// that they generally do not work with language features that attempt |
4407 | /// to destructure types. For example, template argument deduction will |
4408 | /// not be able to match a parameter declared as |
4409 | /// T (*)(U) |
4410 | /// against an argument of type |
4411 | /// void (*)(__attribute__((ns_consumed)) id) |
4412 | /// because the substitution of T=void, U=id into the former will |
4413 | /// not produce the latter. |
4414 | class ExtParameterInfo { |
4415 | enum { |
4416 | ABIMask = 0x0F, |
4417 | IsConsumed = 0x10, |
4418 | HasPassObjSize = 0x20, |
4419 | IsNoEscape = 0x40, |
4420 | }; |
4421 | unsigned char Data = 0; |
4422 | |
4423 | public: |
4424 | ExtParameterInfo() = default; |
4425 | |
4426 | /// Return the ABI treatment of this parameter. |
4427 | ParameterABI getABI() const { return ParameterABI(Data & ABIMask); } |
4428 | ExtParameterInfo withABI(ParameterABI kind) const { |
4429 | ExtParameterInfo copy = *this; |
4430 | copy.Data = (copy.Data & ~ABIMask) | unsigned(kind); |
4431 | return copy; |
4432 | } |
4433 | |
4434 | /// Is this parameter considered "consumed" by Objective-C ARC? |
4435 | /// Consumed parameters must have retainable object type. |
4436 | bool isConsumed() const { return (Data & IsConsumed); } |
4437 | ExtParameterInfo withIsConsumed(bool consumed) const { |
4438 | ExtParameterInfo copy = *this; |
4439 | if (consumed) |
4440 | copy.Data |= IsConsumed; |
4441 | else |
4442 | copy.Data &= ~IsConsumed; |
4443 | return copy; |
4444 | } |
4445 | |
4446 | bool hasPassObjectSize() const { return Data & HasPassObjSize; } |
4447 | ExtParameterInfo withHasPassObjectSize() const { |
4448 | ExtParameterInfo Copy = *this; |
4449 | Copy.Data |= HasPassObjSize; |
4450 | return Copy; |
4451 | } |
4452 | |
4453 | bool isNoEscape() const { return Data & IsNoEscape; } |
4454 | ExtParameterInfo withIsNoEscape(bool NoEscape) const { |
4455 | ExtParameterInfo Copy = *this; |
4456 | if (NoEscape) |
4457 | Copy.Data |= IsNoEscape; |
4458 | else |
4459 | Copy.Data &= ~IsNoEscape; |
4460 | return Copy; |
4461 | } |
4462 | |
4463 | unsigned char getOpaqueValue() const { return Data; } |
4464 | static ExtParameterInfo getFromOpaqueValue(unsigned char data) { |
4465 | ExtParameterInfo result; |
4466 | result.Data = data; |
4467 | return result; |
4468 | } |
4469 | |
4470 | friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) { |
4471 | return lhs.Data == rhs.Data; |
4472 | } |
4473 | |
4474 | friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) { |
4475 | return lhs.Data != rhs.Data; |
4476 | } |
4477 | }; |
4478 | |
4479 | /// A class which abstracts out some details necessary for |
4480 | /// making a call. |
4481 | /// |
4482 | /// It is not actually used directly for storing this information in |
4483 | /// a FunctionType, although FunctionType does currently use the |
4484 | /// same bit-pattern. |
4485 | /// |
4486 | // If you add a field (say Foo), other than the obvious places (both, |
4487 | // constructors, compile failures), what you need to update is |
4488 | // * Operator== |
4489 | // * getFoo |
4490 | // * withFoo |
4491 | // * functionType. Add Foo, getFoo. |
4492 | // * ASTContext::getFooType |
4493 | // * ASTContext::mergeFunctionTypes |
4494 | // * FunctionNoProtoType::Profile |
4495 | // * FunctionProtoType::Profile |
4496 | // * TypePrinter::PrintFunctionProto |
4497 | // * AST read and write |
4498 | // * Codegen |
4499 | class ExtInfo { |
4500 | friend class FunctionType; |
4501 | |
4502 | // Feel free to rearrange or add bits, but if you go over 16, you'll need to |
4503 | // adjust the Bits field below, and if you add bits, you'll need to adjust |
4504 | // Type::FunctionTypeBitfields::ExtInfo as well. |
4505 | |
4506 | // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall| |
4507 | // |0 .. 5| 6 | 7 | 8 |9 .. 11| 12 | 13 | |
4508 | // |
4509 | // regparm is either 0 (no regparm attribute) or the regparm value+1. |
4510 | enum { CallConvMask = 0x3F }; |
4511 | enum { NoReturnMask = 0x40 }; |
4512 | enum { ProducesResultMask = 0x80 }; |
4513 | enum { NoCallerSavedRegsMask = 0x100 }; |
4514 | enum { RegParmMask = 0xe00, RegParmOffset = 9 }; |
4515 | enum { NoCfCheckMask = 0x1000 }; |
4516 | enum { CmseNSCallMask = 0x2000 }; |
4517 | uint16_t Bits = CC_C; |
4518 | |
4519 | ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} |
4520 | |
4521 | public: |
4522 | // Constructor with no defaults. Use this when you know that you |
4523 | // have all the elements (when reading an AST file for example). |
4524 | ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, |
4525 | bool producesResult, bool noCallerSavedRegs, bool NoCfCheck, |
4526 | bool cmseNSCall) { |
4527 | assert((!hasRegParm || regParm < 7) && "Invalid regparm value" ); |
4528 | Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) | |
4529 | (producesResult ? ProducesResultMask : 0) | |
4530 | (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) | |
4531 | (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | |
4532 | (NoCfCheck ? NoCfCheckMask : 0) | |
4533 | (cmseNSCall ? CmseNSCallMask : 0); |
4534 | } |
4535 | |
4536 | // Constructor with all defaults. Use when for example creating a |
4537 | // function known to use defaults. |
4538 | ExtInfo() = default; |
4539 | |
4540 | // Constructor with just the calling convention, which is an important part |
4541 | // of the canonical type. |
4542 | ExtInfo(CallingConv CC) : Bits(CC) {} |
4543 | |
4544 | bool getNoReturn() const { return Bits & NoReturnMask; } |
4545 | bool getProducesResult() const { return Bits & ProducesResultMask; } |
4546 | bool getCmseNSCall() const { return Bits & CmseNSCallMask; } |
4547 | bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; } |
4548 | bool getNoCfCheck() const { return Bits & NoCfCheckMask; } |
4549 | bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; } |
4550 | |
4551 | unsigned getRegParm() const { |
4552 | unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset; |
4553 | if (RegParm > 0) |
4554 | --RegParm; |
4555 | return RegParm; |
4556 | } |
4557 | |
4558 | CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } |
4559 | |
4560 | bool operator==(ExtInfo Other) const { |
4561 | return Bits == Other.Bits; |
4562 | } |
4563 | bool operator!=(ExtInfo Other) const { |
4564 | return Bits != Other.Bits; |
4565 | } |
4566 | |
4567 | // Note that we don't have setters. That is by design, use |
4568 | // the following with methods instead of mutating these objects. |
4569 | |
4570 | ExtInfo withNoReturn(bool noReturn) const { |
4571 | if (noReturn) |
4572 | return ExtInfo(Bits | NoReturnMask); |
4573 | else |
4574 | return ExtInfo(Bits & ~NoReturnMask); |
4575 | } |
4576 | |
4577 | ExtInfo withProducesResult(bool producesResult) const { |
4578 | if (producesResult) |
4579 | return ExtInfo(Bits | ProducesResultMask); |
4580 | else |
4581 | return ExtInfo(Bits & ~ProducesResultMask); |
4582 | } |
4583 | |
4584 | ExtInfo withCmseNSCall(bool cmseNSCall) const { |
4585 | if (cmseNSCall) |
4586 | return ExtInfo(Bits | CmseNSCallMask); |
4587 | else |
4588 | return ExtInfo(Bits & ~CmseNSCallMask); |
4589 | } |
4590 | |
4591 | ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const { |
4592 | if (noCallerSavedRegs) |
4593 | return ExtInfo(Bits | NoCallerSavedRegsMask); |
4594 | else |
4595 | return ExtInfo(Bits & ~NoCallerSavedRegsMask); |
4596 | } |
4597 | |
4598 | ExtInfo withNoCfCheck(bool noCfCheck) const { |
4599 | if (noCfCheck) |
4600 | return ExtInfo(Bits | NoCfCheckMask); |
4601 | else |
4602 | return ExtInfo(Bits & ~NoCfCheckMask); |
4603 | } |
4604 | |
4605 | ExtInfo withRegParm(unsigned RegParm) const { |
4606 | assert(RegParm < 7 && "Invalid regparm value" ); |
4607 | return ExtInfo((Bits & ~RegParmMask) | |
4608 | ((RegParm + 1) << RegParmOffset)); |
4609 | } |
4610 | |
4611 | ExtInfo withCallingConv(CallingConv cc) const { |
4612 | return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc); |
4613 | } |
4614 | |
4615 | void Profile(llvm::FoldingSetNodeID &ID) const { |
4616 | ID.AddInteger(I: Bits); |
4617 | } |
4618 | }; |
4619 | |
4620 | /// A simple holder for a QualType representing a type in an |
4621 | /// exception specification. Unfortunately needed by FunctionProtoType |
4622 | /// because TrailingObjects cannot handle repeated types. |
4623 | struct ExceptionType { QualType Type; }; |
4624 | |
4625 | /// A simple holder for various uncommon bits which do not fit in |
4626 | /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the |
4627 | /// alignment of subsequent objects in TrailingObjects. |
4628 | struct alignas(void *) { |
4629 | /// The number of types in the exception specification. |
4630 | /// A whole unsigned is not needed here and according to |
4631 | /// [implimits] 8 bits would be enough here. |
4632 | unsigned : 10; |
4633 | |
4634 | LLVM_PREFERRED_TYPE(bool) |
4635 | unsigned : 1; |
4636 | |
4637 | LLVM_PREFERRED_TYPE(bool) |
4638 | unsigned : 1; |
4639 | unsigned : 4; |
4640 | |
4641 | () |
4642 | : NumExceptionType(0), HasArmTypeAttributes(false), |
4643 | EffectsHaveConditions(false), NumFunctionEffects(0) {} |
4644 | }; |
4645 | |
4646 | /// The AArch64 SME ACLE (Arm C/C++ Language Extensions) define a number |
4647 | /// of function type attributes that can be set on function types, including |
4648 | /// function pointers. |
4649 | enum AArch64SMETypeAttributes : unsigned { |
4650 | SME_NormalFunction = 0, |
4651 | SME_PStateSMEnabledMask = 1 << 0, |
4652 | SME_PStateSMCompatibleMask = 1 << 1, |
4653 | |
4654 | // Describes the value of the state using ArmStateValue. |
4655 | SME_ZAShift = 2, |
4656 | SME_ZAMask = 0b111 << SME_ZAShift, |
4657 | SME_ZT0Shift = 5, |
4658 | SME_ZT0Mask = 0b111 << SME_ZT0Shift, |
4659 | |
4660 | // A bit to tell whether a function is agnostic about sme ZA state. |
4661 | SME_AgnosticZAStateShift = 8, |
4662 | SME_AgnosticZAStateMask = 1 << SME_AgnosticZAStateShift, |
4663 | |
4664 | SME_AttributeMask = |
4665 | 0b1'111'111'11 // We can't support more than 9 bits because of |
4666 | // the bitmask in FunctionTypeArmAttributes |
4667 | // and ExtProtoInfo. |
4668 | }; |
4669 | |
4670 | enum ArmStateValue : unsigned { |
4671 | ARM_None = 0, |
4672 | ARM_Preserves = 1, |
4673 | ARM_In = 2, |
4674 | ARM_Out = 3, |
4675 | ARM_InOut = 4, |
4676 | }; |
4677 | |
4678 | static ArmStateValue getArmZAState(unsigned AttrBits) { |
4679 | return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift); |
4680 | } |
4681 | |
4682 | static ArmStateValue getArmZT0State(unsigned AttrBits) { |
4683 | return (ArmStateValue)((AttrBits & SME_ZT0Mask) >> SME_ZT0Shift); |
4684 | } |
4685 | |
4686 | /// A holder for Arm type attributes as described in the Arm C/C++ |
4687 | /// Language extensions which are not particularly common to all |
4688 | /// types and therefore accounted separately from FunctionTypeBitfields. |
4689 | struct alignas(void *) FunctionTypeArmAttributes { |
4690 | /// Any AArch64 SME ACLE type attributes that need to be propagated |
4691 | /// on declarations and function pointers. |
4692 | unsigned AArch64SMEAttributes : 9; |
4693 | |
4694 | FunctionTypeArmAttributes() : AArch64SMEAttributes(SME_NormalFunction) {} |
4695 | }; |
4696 | |
4697 | protected: |
4698 | FunctionType(TypeClass tc, QualType res, QualType Canonical, |
4699 | TypeDependence Dependence, ExtInfo Info) |
4700 | : Type(tc, Canonical, Dependence), ResultType(res) { |
4701 | FunctionTypeBits.ExtInfo = Info.Bits; |
4702 | } |
4703 | |
4704 | Qualifiers getFastTypeQuals() const { |
4705 | if (isFunctionProtoType()) |
4706 | return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals); |
4707 | |
4708 | return Qualifiers(); |
4709 | } |
4710 | |
4711 | public: |
4712 | QualType getReturnType() const { return ResultType; } |
4713 | |
4714 | bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } |
4715 | unsigned getRegParmType() const { return getExtInfo().getRegParm(); } |
4716 | |
4717 | /// Determine whether this function type includes the GNU noreturn |
4718 | /// attribute. The C++11 [[noreturn]] attribute does not affect the function |
4719 | /// type. |
4720 | bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } |
4721 | |
4722 | /// Determine whether this is a function prototype that includes the |
4723 | /// cfi_unchecked_callee attribute. |
4724 | bool getCFIUncheckedCalleeAttr() const; |
4725 | |
4726 | bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); } |
4727 | CallingConv getCallConv() const { return getExtInfo().getCC(); } |
4728 | ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } |
4729 | |
4730 | static_assert((~Qualifiers::FastMask & Qualifiers::CVRMask) == 0, |
4731 | "Const, volatile and restrict are assumed to be a subset of " |
4732 | "the fast qualifiers." ); |
4733 | |
4734 | bool isConst() const { return getFastTypeQuals().hasConst(); } |
4735 | bool isVolatile() const { return getFastTypeQuals().hasVolatile(); } |
4736 | bool isRestrict() const { return getFastTypeQuals().hasRestrict(); } |
4737 | |
4738 | /// Determine the type of an expression that calls a function of |
4739 | /// this type. |
4740 | QualType getCallResultType(const ASTContext &Context) const { |
4741 | return getReturnType().getNonLValueExprType(Context); |
4742 | } |
4743 | |
4744 | static StringRef getNameForCallConv(CallingConv CC); |
4745 | |
4746 | static bool classof(const Type *T) { |
4747 | return T->getTypeClass() == FunctionNoProto || |
4748 | T->getTypeClass() == FunctionProto; |
4749 | } |
4750 | }; |
4751 | |
4752 | /// Represents a K&R-style 'int foo()' function, which has |
4753 | /// no information available about its arguments. |
4754 | class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { |
4755 | friend class ASTContext; // ASTContext creates these. |
4756 | |
4757 | FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) |
4758 | : FunctionType(FunctionNoProto, Result, Canonical, |
4759 | Result->getDependence() & |
4760 | ~(TypeDependence::DependentInstantiation | |
4761 | TypeDependence::UnexpandedPack), |
4762 | Info) {} |
4763 | |
4764 | public: |
4765 | // No additional state past what FunctionType provides. |
4766 | |
4767 | bool isSugared() const { return false; } |
4768 | QualType desugar() const { return QualType(this, 0); } |
4769 | |
4770 | void Profile(llvm::FoldingSetNodeID &ID) { |
4771 | Profile(ID, getReturnType(), getExtInfo()); |
4772 | } |
4773 | |
4774 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, |
4775 | ExtInfo Info) { |
4776 | Info.Profile(ID); |
4777 | ID.AddPointer(Ptr: ResultType.getAsOpaquePtr()); |
4778 | } |
4779 | |
4780 | static bool classof(const Type *T) { |
4781 | return T->getTypeClass() == FunctionNoProto; |
4782 | } |
4783 | }; |
4784 | |
4785 | // ------------------------------------------------------------------------------ |
4786 | |
4787 | /// Represents an abstract function effect, using just an enumeration describing |
4788 | /// its kind. |
4789 | class FunctionEffect { |
4790 | public: |
4791 | /// Identifies the particular effect. |
4792 | enum class Kind : uint8_t { |
4793 | NonBlocking, |
4794 | NonAllocating, |
4795 | Blocking, |
4796 | Allocating, |
4797 | Last = Allocating |
4798 | }; |
4799 | constexpr static size_t KindCount = static_cast<size_t>(Kind::Last) + 1; |
4800 | |
4801 | /// Flags describing some behaviors of the effect. |
4802 | using Flags = unsigned; |
4803 | enum FlagBit : Flags { |
4804 | // Can verification inspect callees' implementations? (e.g. nonblocking: |
4805 | // yes, tcb+types: no). This also implies the need for 2nd-pass |
4806 | // verification. |
4807 | FE_InferrableOnCallees = 0x1, |
4808 | |
4809 | // Language constructs which effects can diagnose as disallowed. |
4810 | FE_ExcludeThrow = 0x2, |
4811 | FE_ExcludeCatch = 0x4, |
4812 | FE_ExcludeObjCMessageSend = 0x8, |
4813 | FE_ExcludeStaticLocalVars = 0x10, |
4814 | FE_ExcludeThreadLocalVars = 0x20 |
4815 | }; |
4816 | |
4817 | private: |
4818 | Kind FKind; |
4819 | |
4820 | // Expansion: for hypothetical TCB+types, there could be one Kind for TCB, |
4821 | // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would |
4822 | // be considered for uniqueness. |
4823 | |
4824 | public: |
4825 | explicit FunctionEffect(Kind K) : FKind(K) {} |
4826 | |
4827 | /// The kind of the effect. |
4828 | Kind kind() const { return FKind; } |
4829 | |
4830 | /// Return the opposite kind, for effects which have opposites. |
4831 | Kind oppositeKind() const; |
4832 | |
4833 | /// For serialization. |
4834 | uint32_t toOpaqueInt32() const { return uint32_t(FKind); } |
4835 | static FunctionEffect fromOpaqueInt32(uint32_t Value) { |
4836 | return FunctionEffect(Kind(Value)); |
4837 | } |
4838 | |
4839 | /// Flags describing some behaviors of the effect. |
4840 | Flags flags() const { |
4841 | switch (kind()) { |
4842 | case Kind::NonBlocking: |
4843 | return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | |
4844 | FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars | |
4845 | FE_ExcludeThreadLocalVars; |
4846 | case Kind::NonAllocating: |
4847 | // Same as NonBlocking, except without FE_ExcludeStaticLocalVars. |
4848 | return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | |
4849 | FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars; |
4850 | case Kind::Blocking: |
4851 | case Kind::Allocating: |
4852 | return 0; |
4853 | } |
4854 | llvm_unreachable("unknown effect kind" ); |
4855 | } |
4856 | |
4857 | /// The description printed in diagnostics, e.g. 'nonblocking'. |
4858 | StringRef name() const; |
4859 | |
4860 | friend raw_ostream &operator<<(raw_ostream &OS, |
4861 | const FunctionEffect &Effect) { |
4862 | OS << Effect.name(); |
4863 | return OS; |
4864 | } |
4865 | |
4866 | /// Determine whether the effect is allowed to be inferred on the callee, |
4867 | /// which is either a FunctionDecl or BlockDecl. If the returned optional |
4868 | /// is empty, inference is permitted; otherwise it holds the effect which |
4869 | /// blocked inference. |
4870 | /// Example: This allows nonblocking(false) to prevent inference for the |
4871 | /// function. |
4872 | std::optional<FunctionEffect> |
4873 | effectProhibitingInference(const Decl &Callee, |
4874 | FunctionEffectKindSet CalleeFX) const; |
4875 | |
4876 | // Return false for success. When true is returned for a direct call, then the |
4877 | // FE_InferrableOnCallees flag may trigger inference rather than an immediate |
4878 | // diagnostic. Caller should be assumed to have the effect (it may not have it |
4879 | // explicitly when inferring). |
4880 | bool shouldDiagnoseFunctionCall(bool Direct, |
4881 | FunctionEffectKindSet CalleeFX) const; |
4882 | |
4883 | friend bool operator==(FunctionEffect LHS, FunctionEffect RHS) { |
4884 | return LHS.FKind == RHS.FKind; |
4885 | } |
4886 | friend bool operator!=(FunctionEffect LHS, FunctionEffect RHS) { |
4887 | return !(LHS == RHS); |
4888 | } |
4889 | friend bool operator<(FunctionEffect LHS, FunctionEffect RHS) { |
4890 | return LHS.FKind < RHS.FKind; |
4891 | } |
4892 | }; |
4893 | |
4894 | /// Wrap a function effect's condition expression in another struct so |
4895 | /// that FunctionProtoType's TrailingObjects can treat it separately. |
4896 | class EffectConditionExpr { |
4897 | Expr *Cond = nullptr; // if null, unconditional. |
4898 | |
4899 | public: |
4900 | EffectConditionExpr() = default; |
4901 | EffectConditionExpr(Expr *E) : Cond(E) {} |
4902 | |
4903 | Expr *getCondition() const { return Cond; } |
4904 | |
4905 | bool operator==(const EffectConditionExpr &RHS) const { |
4906 | return Cond == RHS.Cond; |
4907 | } |
4908 | }; |
4909 | |
4910 | /// A FunctionEffect plus a potential boolean expression determining whether |
4911 | /// the effect is declared (e.g. nonblocking(expr)). Generally the condition |
4912 | /// expression when present, is dependent. |
4913 | struct FunctionEffectWithCondition { |
4914 | FunctionEffect Effect; |
4915 | EffectConditionExpr Cond; |
4916 | |
4917 | FunctionEffectWithCondition(FunctionEffect E, const EffectConditionExpr &C) |
4918 | : Effect(E), Cond(C) {} |
4919 | |
4920 | /// Return a textual description of the effect, and its condition, if any. |
4921 | std::string description() const; |
4922 | |
4923 | friend raw_ostream &operator<<(raw_ostream &OS, |
4924 | const FunctionEffectWithCondition &CFE); |
4925 | }; |
4926 | |
4927 | /// Support iteration in parallel through a pair of FunctionEffect and |
4928 | /// EffectConditionExpr containers. |
4929 | template <typename Container> class FunctionEffectIterator { |
4930 | friend Container; |
4931 | |
4932 | const Container *Outer = nullptr; |
4933 | size_t Idx = 0; |
4934 | |
4935 | public: |
4936 | FunctionEffectIterator(); |
4937 | FunctionEffectIterator(const Container &O, size_t I) : Outer(&O), Idx(I) {} |
4938 | bool operator==(const FunctionEffectIterator &Other) const { |
4939 | return Idx == Other.Idx; |
4940 | } |
4941 | bool operator!=(const FunctionEffectIterator &Other) const { |
4942 | return Idx != Other.Idx; |
4943 | } |
4944 | |
4945 | FunctionEffectIterator operator++() { |
4946 | ++Idx; |
4947 | return *this; |
4948 | } |
4949 | |
4950 | FunctionEffectWithCondition operator*() const { |
4951 | assert(Outer != nullptr && "invalid FunctionEffectIterator" ); |
4952 | bool HasConds = !Outer->Conditions.empty(); |
4953 | return FunctionEffectWithCondition{Outer->Effects[Idx], |
4954 | HasConds ? Outer->Conditions[Idx] |
4955 | : EffectConditionExpr()}; |
4956 | } |
4957 | }; |
4958 | |
4959 | /// An immutable set of FunctionEffects and possibly conditions attached to |
4960 | /// them. The effects and conditions reside in memory not managed by this object |
4961 | /// (typically, trailing objects in FunctionProtoType, or borrowed references |
4962 | /// from a FunctionEffectSet). |
4963 | /// |
4964 | /// Invariants: |
4965 | /// - there is never more than one instance of any given effect. |
4966 | /// - the array of conditions is either empty or has the same size as the |
4967 | /// array of effects. |
4968 | /// - some conditions may be null expressions; each condition pertains to |
4969 | /// the effect at the same array index. |
4970 | /// |
4971 | /// Also, if there are any conditions, at least one of those expressions will be |
4972 | /// dependent, but this is only asserted in the constructor of |
4973 | /// FunctionProtoType. |
4974 | /// |
4975 | /// See also FunctionEffectSet, in Sema, which provides a mutable set. |
4976 | class FunctionEffectsRef { |
4977 | // Restrict classes which can call the private constructor -- these friends |
4978 | // all maintain the required invariants. FunctionEffectSet is generally the |
4979 | // only way in which the arrays are created; FunctionProtoType will not |
4980 | // reorder them. |
4981 | friend FunctionProtoType; |
4982 | friend FunctionEffectSet; |
4983 | |
4984 | ArrayRef<FunctionEffect> Effects; |
4985 | ArrayRef<EffectConditionExpr> Conditions; |
4986 | |
4987 | // The arrays are expected to have been sorted by the caller, with the |
4988 | // effects in order. The conditions array must be empty or the same size |
4989 | // as the effects array, since the conditions are associated with the effects |
4990 | // at the same array indices. |
4991 | FunctionEffectsRef(ArrayRef<FunctionEffect> FX, |
4992 | ArrayRef<EffectConditionExpr> Conds) |
4993 | : Effects(FX), Conditions(Conds) {} |
4994 | |
4995 | public: |
4996 | /// Extract the effects from a Type if it is a function, block, or member |
4997 | /// function pointer, or a reference or pointer to one. |
4998 | static FunctionEffectsRef get(QualType QT); |
4999 | |
5000 | /// Asserts invariants. |
5001 | static FunctionEffectsRef create(ArrayRef<FunctionEffect> FX, |
5002 | ArrayRef<EffectConditionExpr> Conds); |
5003 | |
5004 | FunctionEffectsRef() = default; |
5005 | |
5006 | bool empty() const { return Effects.empty(); } |
5007 | size_t size() const { return Effects.size(); } |
5008 | |
5009 | ArrayRef<FunctionEffect> effects() const { return Effects; } |
5010 | ArrayRef<EffectConditionExpr> conditions() const { return Conditions; } |
5011 | |
5012 | using iterator = FunctionEffectIterator<FunctionEffectsRef>; |
5013 | friend iterator; |
5014 | iterator begin() const { return iterator(*this, 0); } |
5015 | iterator end() const { return iterator(*this, size()); } |
5016 | |
5017 | friend bool operator==(const FunctionEffectsRef &LHS, |
5018 | const FunctionEffectsRef &RHS) { |
5019 | return LHS.Effects == RHS.Effects && LHS.Conditions == RHS.Conditions; |
5020 | } |
5021 | friend bool operator!=(const FunctionEffectsRef &LHS, |
5022 | const FunctionEffectsRef &RHS) { |
5023 | return !(LHS == RHS); |
5024 | } |
5025 | |
5026 | void dump(llvm::raw_ostream &OS) const; |
5027 | }; |
5028 | |
5029 | /// A mutable set of FunctionEffect::Kind. |
5030 | class FunctionEffectKindSet { |
5031 | // For now this only needs to be a bitmap. |
5032 | constexpr static size_t EndBitPos = FunctionEffect::KindCount; |
5033 | using KindBitsT = std::bitset<EndBitPos>; |
5034 | |
5035 | KindBitsT KindBits{}; |
5036 | |
5037 | explicit FunctionEffectKindSet(KindBitsT KB) : KindBits(KB) {} |
5038 | |
5039 | // Functions to translate between an effect kind, starting at 1, and a |
5040 | // position in the bitset. |
5041 | |
5042 | constexpr static size_t kindToPos(FunctionEffect::Kind K) { |
5043 | return static_cast<size_t>(K); |
5044 | } |
5045 | |
5046 | constexpr static FunctionEffect::Kind posToKind(size_t Pos) { |
5047 | return static_cast<FunctionEffect::Kind>(Pos); |
5048 | } |
5049 | |
5050 | // Iterates through the bits which are set. |
5051 | class iterator { |
5052 | const FunctionEffectKindSet *Outer = nullptr; |
5053 | size_t Idx = 0; |
5054 | |
5055 | // If Idx does not reference a set bit, advance it until it does, |
5056 | // or until it reaches EndBitPos. |
5057 | void advanceToNextSetBit() { |
5058 | while (Idx < EndBitPos && !Outer->KindBits.test(Idx)) |
5059 | ++Idx; |
5060 | } |
5061 | |
5062 | public: |
5063 | iterator(); |
5064 | iterator(const FunctionEffectKindSet &O, size_t I) : Outer(&O), Idx(I) { |
5065 | advanceToNextSetBit(); |
5066 | } |
5067 | bool operator==(const iterator &Other) const { return Idx == Other.Idx; } |
5068 | bool operator!=(const iterator &Other) const { return Idx != Other.Idx; } |
5069 | |
5070 | iterator operator++() { |
5071 | ++Idx; |
5072 | advanceToNextSetBit(); |
5073 | return *this; |
5074 | } |
5075 | |
5076 | FunctionEffect operator*() const { |
5077 | assert(Idx < EndBitPos && "Dereference of end iterator" ); |
5078 | return FunctionEffect(posToKind(Pos: Idx)); |
5079 | } |
5080 | }; |
5081 | |
5082 | public: |
5083 | FunctionEffectKindSet() = default; |
5084 | explicit FunctionEffectKindSet(FunctionEffectsRef FX) { insert(FX); } |
5085 | |
5086 | iterator begin() const { return iterator(*this, 0); } |
5087 | iterator end() const { return iterator(*this, EndBitPos); } |
5088 | |
5089 | void insert(FunctionEffect Effect) { KindBits.set(kindToPos(Effect.kind())); } |
5090 | void insert(FunctionEffectsRef FX) { |
5091 | for (FunctionEffect Item : FX.effects()) |
5092 | insert(Item); |
5093 | } |
5094 | void insert(FunctionEffectKindSet Set) { KindBits |= Set.KindBits; } |
5095 | |
5096 | bool empty() const { return KindBits.none(); } |
5097 | bool contains(const FunctionEffect::Kind EK) const { |
5098 | return KindBits.test(kindToPos(EK)); |
5099 | } |
5100 | void dump(llvm::raw_ostream &OS) const; |
5101 | |
5102 | static FunctionEffectKindSet difference(FunctionEffectKindSet LHS, |
5103 | FunctionEffectKindSet RHS) { |
5104 | return FunctionEffectKindSet(LHS.KindBits & ~RHS.KindBits); |
5105 | } |
5106 | }; |
5107 | |
5108 | /// A mutable set of FunctionEffects and possibly conditions attached to them. |
5109 | /// Used to compare and merge effects on declarations. |
5110 | /// |
5111 | /// Has the same invariants as FunctionEffectsRef. |
5112 | class FunctionEffectSet { |
5113 | SmallVector<FunctionEffect> Effects; |
5114 | SmallVector<EffectConditionExpr> Conditions; |
5115 | |
5116 | public: |
5117 | FunctionEffectSet() = default; |
5118 | |
5119 | explicit FunctionEffectSet(const FunctionEffectsRef &FX) |
5120 | : Effects(FX.effects()), Conditions(FX.conditions()) {} |
5121 | |
5122 | bool empty() const { return Effects.empty(); } |
5123 | size_t size() const { return Effects.size(); } |
5124 | |
5125 | using iterator = FunctionEffectIterator<FunctionEffectSet>; |
5126 | friend iterator; |
5127 | iterator begin() const { return iterator(*this, 0); } |
5128 | iterator end() const { return iterator(*this, size()); } |
5129 | |
5130 | operator FunctionEffectsRef() const { return {Effects, Conditions}; } |
5131 | |
5132 | void dump(llvm::raw_ostream &OS) const; |
5133 | |
5134 | // Mutators |
5135 | |
5136 | // On insertion, a conflict occurs when attempting to insert an |
5137 | // effect which is opposite an effect already in the set, or attempting |
5138 | // to insert an effect which is already in the set but with a condition |
5139 | // which is not identical. |
5140 | struct Conflict { |
5141 | FunctionEffectWithCondition Kept; |
5142 | FunctionEffectWithCondition Rejected; |
5143 | }; |
5144 | using Conflicts = SmallVector<Conflict>; |
5145 | |
5146 | // Returns true for success (obviating a check of Errs.empty()). |
5147 | bool insert(const FunctionEffectWithCondition &NewEC, Conflicts &Errs); |
5148 | |
5149 | // Returns true for success (obviating a check of Errs.empty()). |
5150 | bool insert(const FunctionEffectsRef &Set, Conflicts &Errs); |
5151 | |
5152 | // Set operations |
5153 | |
5154 | static FunctionEffectSet getUnion(FunctionEffectsRef LHS, |
5155 | FunctionEffectsRef RHS, Conflicts &Errs); |
5156 | static FunctionEffectSet getIntersection(FunctionEffectsRef LHS, |
5157 | FunctionEffectsRef RHS); |
5158 | }; |
5159 | |
5160 | /// Represents a prototype with parameter type info, e.g. |
5161 | /// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no |
5162 | /// parameters, not as having a single void parameter. Such a type can have |
5163 | /// an exception specification, but this specification is not part of the |
5164 | /// canonical type. FunctionProtoType has several trailing objects, some of |
5165 | /// which optional. For more information about the trailing objects see |
5166 | /// the first comment inside FunctionProtoType. |
5167 | class FunctionProtoType final |
5168 | : public FunctionType, |
5169 | public llvm::FoldingSetNode, |
5170 | private llvm::TrailingObjects< |
5171 | FunctionProtoType, QualType, SourceLocation, |
5172 | FunctionType::FunctionTypeExtraBitfields, |
5173 | FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType, |
5174 | Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers, |
5175 | FunctionEffect, EffectConditionExpr> { |
5176 | friend class ASTContext; // ASTContext creates these. |
5177 | friend TrailingObjects; |
5178 | |
5179 | // FunctionProtoType is followed by several trailing objects, some of |
5180 | // which optional. They are in order: |
5181 | // |
5182 | // * An array of getNumParams() QualType holding the parameter types. |
5183 | // Always present. Note that for the vast majority of FunctionProtoType, |
5184 | // these will be the only trailing objects. |
5185 | // |
5186 | // * Optionally if the function is variadic, the SourceLocation of the |
5187 | // ellipsis. |
5188 | // |
5189 | // * Optionally if some extra data is stored in FunctionTypeExtraBitfields |
5190 | // (see FunctionTypeExtraBitfields and FunctionTypeBitfields): |
5191 | // a single FunctionTypeExtraBitfields. Present if and only if |
5192 | // hasExtraBitfields() is true. |
5193 | // |
5194 | // * Optionally exactly one of: |
5195 | // * an array of getNumExceptions() ExceptionType, |
5196 | // * a single Expr *, |
5197 | // * a pair of FunctionDecl *, |
5198 | // * a single FunctionDecl * |
5199 | // used to store information about the various types of exception |
5200 | // specification. See getExceptionSpecSize for the details. |
5201 | // |
5202 | // * Optionally an array of getNumParams() ExtParameterInfo holding |
5203 | // an ExtParameterInfo for each of the parameters. Present if and |
5204 | // only if hasExtParameterInfos() is true. |
5205 | // |
5206 | // * Optionally a Qualifiers object to represent extra qualifiers that can't |
5207 | // be represented by FunctionTypeBitfields.FastTypeQuals. Present if and |
5208 | // only if hasExtQualifiers() is true. |
5209 | // |
5210 | // * Optionally, an array of getNumFunctionEffects() FunctionEffect. |
5211 | // Present only when getNumFunctionEffects() > 0 |
5212 | // |
5213 | // * Optionally, an array of getNumFunctionEffects() EffectConditionExpr. |
5214 | // Present only when getNumFunctionEffectConditions() > 0. |
5215 | // |
5216 | // The optional FunctionTypeExtraBitfields has to be before the data |
5217 | // related to the exception specification since it contains the number |
5218 | // of exception types. |
5219 | // |
5220 | // We put the ExtParameterInfos later. If all were equal, it would make |
5221 | // more sense to put these before the exception specification, because |
5222 | // it's much easier to skip past them compared to the elaborate switch |
5223 | // required to skip the exception specification. However, all is not |
5224 | // equal; ExtParameterInfos are used to model very uncommon features, |
5225 | // and it's better not to burden the more common paths. |
5226 | |
5227 | public: |
5228 | /// Holds information about the various types of exception specification. |
5229 | /// ExceptionSpecInfo is not stored as such in FunctionProtoType but is |
5230 | /// used to group together the various bits of information about the |
5231 | /// exception specification. |
5232 | struct ExceptionSpecInfo { |
5233 | /// The kind of exception specification this is. |
5234 | ExceptionSpecificationType Type = EST_None; |
5235 | |
5236 | /// Explicitly-specified list of exception types. |
5237 | ArrayRef<QualType> Exceptions; |
5238 | |
5239 | /// Noexcept expression, if this is a computed noexcept specification. |
5240 | Expr *NoexceptExpr = nullptr; |
5241 | |
5242 | /// The function whose exception specification this is, for |
5243 | /// EST_Unevaluated and EST_Uninstantiated. |
5244 | FunctionDecl *SourceDecl = nullptr; |
5245 | |
5246 | /// The function template whose exception specification this is instantiated |
5247 | /// from, for EST_Uninstantiated. |
5248 | FunctionDecl *SourceTemplate = nullptr; |
5249 | |
5250 | ExceptionSpecInfo() = default; |
5251 | |
5252 | ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {} |
5253 | |
5254 | void instantiate(); |
5255 | }; |
5256 | |
5257 | /// Extra information about a function prototype. ExtProtoInfo is not |
5258 | /// stored as such in FunctionProtoType but is used to group together |
5259 | /// the various bits of extra information about a function prototype. |
5260 | struct ExtProtoInfo { |
5261 | FunctionType::ExtInfo ExtInfo; |
5262 | LLVM_PREFERRED_TYPE(bool) |
5263 | unsigned Variadic : 1; |
5264 | LLVM_PREFERRED_TYPE(bool) |
5265 | unsigned HasTrailingReturn : 1; |
5266 | LLVM_PREFERRED_TYPE(bool) |
5267 | unsigned CFIUncheckedCallee : 1; |
5268 | unsigned AArch64SMEAttributes : 9; |
5269 | Qualifiers TypeQuals; |
5270 | RefQualifierKind RefQualifier = RQ_None; |
5271 | ExceptionSpecInfo ExceptionSpec; |
5272 | const ExtParameterInfo *ExtParameterInfos = nullptr; |
5273 | SourceLocation EllipsisLoc; |
5274 | FunctionEffectsRef FunctionEffects; |
5275 | |
5276 | ExtProtoInfo() |
5277 | : Variadic(false), HasTrailingReturn(false), CFIUncheckedCallee(false), |
5278 | AArch64SMEAttributes(SME_NormalFunction) {} |
5279 | |
5280 | ExtProtoInfo(CallingConv CC) |
5281 | : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), |
5282 | CFIUncheckedCallee(false), AArch64SMEAttributes(SME_NormalFunction) {} |
5283 | |
5284 | ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) { |
5285 | ExtProtoInfo Result(*this); |
5286 | Result.ExceptionSpec = ESI; |
5287 | return Result; |
5288 | } |
5289 | |
5290 | ExtProtoInfo withCFIUncheckedCallee(bool CFIUncheckedCallee) { |
5291 | ExtProtoInfo Result(*this); |
5292 | Result.CFIUncheckedCallee = CFIUncheckedCallee; |
5293 | return Result; |
5294 | } |
5295 | |
5296 | bool () const { |
5297 | return ExceptionSpec.Type == EST_Dynamic || |
5298 | requiresFunctionProtoTypeArmAttributes() || |
5299 | !FunctionEffects.empty(); |
5300 | } |
5301 | |
5302 | bool requiresFunctionProtoTypeArmAttributes() const { |
5303 | return AArch64SMEAttributes != SME_NormalFunction; |
5304 | } |
5305 | |
5306 | void setArmSMEAttribute(AArch64SMETypeAttributes Kind, bool Enable = true) { |
5307 | if (Enable) |
5308 | AArch64SMEAttributes |= Kind; |
5309 | else |
5310 | AArch64SMEAttributes &= ~Kind; |
5311 | } |
5312 | }; |
5313 | |
5314 | private: |
5315 | unsigned numTrailingObjects(OverloadToken<QualType>) const { |
5316 | return getNumParams(); |
5317 | } |
5318 | |
5319 | unsigned numTrailingObjects(OverloadToken<SourceLocation>) const { |
5320 | return isVariadic(); |
5321 | } |
5322 | |
5323 | unsigned numTrailingObjects(OverloadToken<FunctionTypeArmAttributes>) const { |
5324 | return hasArmTypeAttributes(); |
5325 | } |
5326 | |
5327 | unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const { |
5328 | return hasExtraBitfields(); |
5329 | } |
5330 | |
5331 | unsigned numTrailingObjects(OverloadToken<ExceptionType>) const { |
5332 | return getExceptionSpecSize().NumExceptionType; |
5333 | } |
5334 | |
5335 | unsigned numTrailingObjects(OverloadToken<Expr *>) const { |
5336 | return getExceptionSpecSize().NumExprPtr; |
5337 | } |
5338 | |
5339 | unsigned numTrailingObjects(OverloadToken<FunctionDecl *>) const { |
5340 | return getExceptionSpecSize().NumFunctionDeclPtr; |
5341 | } |
5342 | |
5343 | unsigned numTrailingObjects(OverloadToken<ExtParameterInfo>) const { |
5344 | return hasExtParameterInfos() ? getNumParams() : 0; |
5345 | } |
5346 | |
5347 | unsigned numTrailingObjects(OverloadToken<Qualifiers>) const { |
5348 | return hasExtQualifiers() ? 1 : 0; |
5349 | } |
5350 | |
5351 | unsigned numTrailingObjects(OverloadToken<FunctionEffect>) const { |
5352 | return getNumFunctionEffects(); |
5353 | } |
5354 | |
5355 | /// Determine whether there are any argument types that |
5356 | /// contain an unexpanded parameter pack. |
5357 | static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, |
5358 | unsigned numArgs) { |
5359 | for (unsigned Idx = 0; Idx < numArgs; ++Idx) |
5360 | if (ArgArray[Idx]->containsUnexpandedParameterPack()) |
5361 | return true; |
5362 | |
5363 | return false; |
5364 | } |
5365 | |
5366 | FunctionProtoType(QualType result, ArrayRef<QualType> params, |
5367 | QualType canonical, const ExtProtoInfo &epi); |
5368 | |
5369 | /// This struct is returned by getExceptionSpecSize and is used to |
5370 | /// translate an ExceptionSpecificationType to the number and kind |
5371 | /// of trailing objects related to the exception specification. |
5372 | struct ExceptionSpecSizeHolder { |
5373 | unsigned NumExceptionType; |
5374 | unsigned NumExprPtr; |
5375 | unsigned NumFunctionDeclPtr; |
5376 | }; |
5377 | |
5378 | /// Return the number and kind of trailing objects |
5379 | /// related to the exception specification. |
5380 | static ExceptionSpecSizeHolder |
5381 | getExceptionSpecSize(ExceptionSpecificationType EST, unsigned NumExceptions) { |
5382 | switch (EST) { |
5383 | case EST_None: |
5384 | case EST_DynamicNone: |
5385 | case EST_MSAny: |
5386 | case EST_BasicNoexcept: |
5387 | case EST_Unparsed: |
5388 | case EST_NoThrow: |
5389 | return {.NumExceptionType: 0, .NumExprPtr: 0, .NumFunctionDeclPtr: 0}; |
5390 | |
5391 | case EST_Dynamic: |
5392 | return {.NumExceptionType: NumExceptions, .NumExprPtr: 0, .NumFunctionDeclPtr: 0}; |
5393 | |
5394 | case EST_DependentNoexcept: |
5395 | case EST_NoexceptFalse: |
5396 | case EST_NoexceptTrue: |
5397 | return {.NumExceptionType: 0, .NumExprPtr: 1, .NumFunctionDeclPtr: 0}; |
5398 | |
5399 | case EST_Uninstantiated: |
5400 | return {.NumExceptionType: 0, .NumExprPtr: 0, .NumFunctionDeclPtr: 2}; |
5401 | |
5402 | case EST_Unevaluated: |
5403 | return {.NumExceptionType: 0, .NumExprPtr: 0, .NumFunctionDeclPtr: 1}; |
5404 | } |
5405 | llvm_unreachable("bad exception specification kind" ); |
5406 | } |
5407 | |
5408 | /// Return the number and kind of trailing objects |
5409 | /// related to the exception specification. |
5410 | ExceptionSpecSizeHolder getExceptionSpecSize() const { |
5411 | return getExceptionSpecSize(EST: getExceptionSpecType(), NumExceptions: getNumExceptions()); |
5412 | } |
5413 | |
5414 | /// Whether the trailing FunctionTypeExtraBitfields is present. |
5415 | bool () const { |
5416 | assert((getExceptionSpecType() != EST_Dynamic || |
5417 | FunctionTypeBits.HasExtraBitfields) && |
5418 | "ExtraBitfields are required for given ExceptionSpecType" ); |
5419 | return FunctionTypeBits.HasExtraBitfields; |
5420 | |
5421 | } |
5422 | |
5423 | bool hasArmTypeAttributes() const { |
5424 | return FunctionTypeBits.HasExtraBitfields && |
5425 | getTrailingObjects<FunctionTypeExtraBitfields>() |
5426 | ->HasArmTypeAttributes; |
5427 | } |
5428 | |
5429 | bool hasExtQualifiers() const { |
5430 | return FunctionTypeBits.HasExtQuals; |
5431 | } |
5432 | |
5433 | public: |
5434 | unsigned getNumParams() const { return FunctionTypeBits.NumParams; } |
5435 | |
5436 | QualType getParamType(unsigned i) const { |
5437 | assert(i < getNumParams() && "invalid parameter index" ); |
5438 | return param_type_begin()[i]; |
5439 | } |
5440 | |
5441 | ArrayRef<QualType> getParamTypes() const { |
5442 | return llvm::ArrayRef(param_type_begin(), param_type_end()); |
5443 | } |
5444 | |
5445 | ExtProtoInfo getExtProtoInfo() const { |
5446 | ExtProtoInfo EPI; |
5447 | EPI.ExtInfo = getExtInfo(); |
5448 | EPI.Variadic = isVariadic(); |
5449 | EPI.EllipsisLoc = getEllipsisLoc(); |
5450 | EPI.HasTrailingReturn = hasTrailingReturn(); |
5451 | EPI.CFIUncheckedCallee = hasCFIUncheckedCallee(); |
5452 | EPI.ExceptionSpec = getExceptionSpecInfo(); |
5453 | EPI.TypeQuals = getMethodQuals(); |
5454 | EPI.RefQualifier = getRefQualifier(); |
5455 | EPI.ExtParameterInfos = getExtParameterInfosOrNull(); |
5456 | EPI.AArch64SMEAttributes = getAArch64SMEAttributes(); |
5457 | EPI.FunctionEffects = getFunctionEffects(); |
5458 | return EPI; |
5459 | } |
5460 | |
5461 | /// Get the kind of exception specification on this function. |
5462 | ExceptionSpecificationType getExceptionSpecType() const { |
5463 | return static_cast<ExceptionSpecificationType>( |
5464 | FunctionTypeBits.ExceptionSpecType); |
5465 | } |
5466 | |
5467 | /// Return whether this function has any kind of exception spec. |
5468 | bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; } |
5469 | |
5470 | /// Return whether this function has a dynamic (throw) exception spec. |
5471 | bool hasDynamicExceptionSpec() const { |
5472 | return isDynamicExceptionSpec(ESpecType: getExceptionSpecType()); |
5473 | } |
5474 | |
5475 | /// Return whether this function has a noexcept exception spec. |
5476 | bool hasNoexceptExceptionSpec() const { |
5477 | return isNoexceptExceptionSpec(ESpecType: getExceptionSpecType()); |
5478 | } |
5479 | |
5480 | /// Return whether this function has a dependent exception spec. |
5481 | bool hasDependentExceptionSpec() const; |
5482 | |
5483 | /// Return whether this function has an instantiation-dependent exception |
5484 | /// spec. |
5485 | bool hasInstantiationDependentExceptionSpec() const; |
5486 | |
5487 | /// Return all the available information about this type's exception spec. |
5488 | ExceptionSpecInfo getExceptionSpecInfo() const { |
5489 | ExceptionSpecInfo Result; |
5490 | Result.Type = getExceptionSpecType(); |
5491 | if (Result.Type == EST_Dynamic) { |
5492 | Result.Exceptions = exceptions(); |
5493 | } else if (isComputedNoexcept(ESpecType: Result.Type)) { |
5494 | Result.NoexceptExpr = getNoexceptExpr(); |
5495 | } else if (Result.Type == EST_Uninstantiated) { |
5496 | Result.SourceDecl = getExceptionSpecDecl(); |
5497 | Result.SourceTemplate = getExceptionSpecTemplate(); |
5498 | } else if (Result.Type == EST_Unevaluated) { |
5499 | Result.SourceDecl = getExceptionSpecDecl(); |
5500 | } |
5501 | return Result; |
5502 | } |
5503 | |
5504 | /// Return the number of types in the exception specification. |
5505 | unsigned getNumExceptions() const { |
5506 | return getExceptionSpecType() == EST_Dynamic |
5507 | ? getTrailingObjects<FunctionTypeExtraBitfields>() |
5508 | ->NumExceptionType |
5509 | : 0; |
5510 | } |
5511 | |
5512 | /// Return the ith exception type, where 0 <= i < getNumExceptions(). |
5513 | QualType getExceptionType(unsigned i) const { |
5514 | assert(i < getNumExceptions() && "Invalid exception number!" ); |
5515 | return exception_begin()[i]; |
5516 | } |
5517 | |
5518 | /// Return the expression inside noexcept(expression), or a null pointer |
5519 | /// if there is none (because the exception spec is not of this form). |
5520 | Expr *getNoexceptExpr() const { |
5521 | if (!isComputedNoexcept(ESpecType: getExceptionSpecType())) |
5522 | return nullptr; |
5523 | return *getTrailingObjects<Expr *>(); |
5524 | } |
5525 | |
5526 | /// If this function type has an exception specification which hasn't |
5527 | /// been determined yet (either because it has not been evaluated or because |
5528 | /// it has not been instantiated), this is the function whose exception |
5529 | /// specification is represented by this type. |
5530 | FunctionDecl *getExceptionSpecDecl() const { |
5531 | if (getExceptionSpecType() != EST_Uninstantiated && |
5532 | getExceptionSpecType() != EST_Unevaluated) |
5533 | return nullptr; |
5534 | return getTrailingObjects<FunctionDecl *>()[0]; |
5535 | } |
5536 | |
5537 | /// If this function type has an uninstantiated exception |
5538 | /// specification, this is the function whose exception specification |
5539 | /// should be instantiated to find the exception specification for |
5540 | /// this type. |
5541 | FunctionDecl *getExceptionSpecTemplate() const { |
5542 | if (getExceptionSpecType() != EST_Uninstantiated) |
5543 | return nullptr; |
5544 | return getTrailingObjects<FunctionDecl *>()[1]; |
5545 | } |
5546 | |
5547 | /// Determine whether this function type has a non-throwing exception |
5548 | /// specification. |
5549 | CanThrowResult canThrow() const; |
5550 | |
5551 | /// Determine whether this function type has a non-throwing exception |
5552 | /// specification. If this depends on template arguments, returns |
5553 | /// \c ResultIfDependent. |
5554 | bool isNothrow(bool ResultIfDependent = false) const { |
5555 | return ResultIfDependent ? canThrow() != CT_Can : canThrow() == CT_Cannot; |
5556 | } |
5557 | |
5558 | /// Whether this function prototype is variadic. |
5559 | bool isVariadic() const { return FunctionTypeBits.Variadic; } |
5560 | |
5561 | SourceLocation getEllipsisLoc() const { |
5562 | return isVariadic() ? *getTrailingObjects<SourceLocation>() |
5563 | : SourceLocation(); |
5564 | } |
5565 | |
5566 | /// Determines whether this function prototype contains a |
5567 | /// parameter pack at the end. |
5568 | /// |
5569 | /// A function template whose last parameter is a parameter pack can be |
5570 | /// called with an arbitrary number of arguments, much like a variadic |
5571 | /// function. |
5572 | bool isTemplateVariadic() const; |
5573 | |
5574 | /// Whether this function prototype has a trailing return type. |
5575 | bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; } |
5576 | |
5577 | bool hasCFIUncheckedCallee() const { |
5578 | return FunctionTypeBits.CFIUncheckedCallee; |
5579 | } |
5580 | |
5581 | Qualifiers getMethodQuals() const { |
5582 | if (hasExtQualifiers()) |
5583 | return *getTrailingObjects<Qualifiers>(); |
5584 | else |
5585 | return getFastTypeQuals(); |
5586 | } |
5587 | |
5588 | /// Retrieve the ref-qualifier associated with this function type. |
5589 | RefQualifierKind getRefQualifier() const { |
5590 | return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier); |
5591 | } |
5592 | |
5593 | using param_type_iterator = const QualType *; |
5594 | |
5595 | ArrayRef<QualType> param_types() const { |
5596 | return llvm::ArrayRef(param_type_begin(), param_type_end()); |
5597 | } |
5598 | |
5599 | param_type_iterator param_type_begin() const { |
5600 | return getTrailingObjects<QualType>(); |
5601 | } |
5602 | |
5603 | param_type_iterator param_type_end() const { |
5604 | return param_type_begin() + getNumParams(); |
5605 | } |
5606 | |
5607 | using exception_iterator = const QualType *; |
5608 | |
5609 | ArrayRef<QualType> exceptions() const { |
5610 | return llvm::ArrayRef(exception_begin(), exception_end()); |
5611 | } |
5612 | |
5613 | exception_iterator exception_begin() const { |
5614 | return reinterpret_cast<exception_iterator>( |
5615 | getTrailingObjects<ExceptionType>()); |
5616 | } |
5617 | |
5618 | exception_iterator exception_end() const { |
5619 | return exception_begin() + getNumExceptions(); |
5620 | } |
5621 | |
5622 | /// Is there any interesting extra information for any of the parameters |
5623 | /// of this function type? |
5624 | bool hasExtParameterInfos() const { |
5625 | return FunctionTypeBits.HasExtParameterInfos; |
5626 | } |
5627 | |
5628 | ArrayRef<ExtParameterInfo> getExtParameterInfos() const { |
5629 | assert(hasExtParameterInfos()); |
5630 | return ArrayRef<ExtParameterInfo>(getTrailingObjects<ExtParameterInfo>(), |
5631 | getNumParams()); |
5632 | } |
5633 | |
5634 | /// Return a pointer to the beginning of the array of extra parameter |
5635 | /// information, if present, or else null if none of the parameters |
5636 | /// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos. |
5637 | const ExtParameterInfo *getExtParameterInfosOrNull() const { |
5638 | if (!hasExtParameterInfos()) |
5639 | return nullptr; |
5640 | return getTrailingObjects<ExtParameterInfo>(); |
5641 | } |
5642 | |
5643 | /// Return a bitmask describing the SME attributes on the function type, see |
5644 | /// AArch64SMETypeAttributes for their values. |
5645 | unsigned getAArch64SMEAttributes() const { |
5646 | if (!hasArmTypeAttributes()) |
5647 | return SME_NormalFunction; |
5648 | return getTrailingObjects<FunctionTypeArmAttributes>() |
5649 | ->AArch64SMEAttributes; |
5650 | } |
5651 | |
5652 | ExtParameterInfo getExtParameterInfo(unsigned I) const { |
5653 | assert(I < getNumParams() && "parameter index out of range" ); |
5654 | if (hasExtParameterInfos()) |
5655 | return getTrailingObjects<ExtParameterInfo>()[I]; |
5656 | return ExtParameterInfo(); |
5657 | } |
5658 | |
5659 | ParameterABI getParameterABI(unsigned I) const { |
5660 | assert(I < getNumParams() && "parameter index out of range" ); |
5661 | if (hasExtParameterInfos()) |
5662 | return getTrailingObjects<ExtParameterInfo>()[I].getABI(); |
5663 | return ParameterABI::Ordinary; |
5664 | } |
5665 | |
5666 | bool isParamConsumed(unsigned I) const { |
5667 | assert(I < getNumParams() && "parameter index out of range" ); |
5668 | if (hasExtParameterInfos()) |
5669 | return getTrailingObjects<ExtParameterInfo>()[I].isConsumed(); |
5670 | return false; |
5671 | } |
5672 | |
5673 | unsigned getNumFunctionEffects() const { |
5674 | return hasExtraBitfields() |
5675 | ? getTrailingObjects<FunctionTypeExtraBitfields>() |
5676 | ->NumFunctionEffects |
5677 | : 0; |
5678 | } |
5679 | |
5680 | // For serialization. |
5681 | ArrayRef<FunctionEffect> getFunctionEffectsWithoutConditions() const { |
5682 | if (hasExtraBitfields()) { |
5683 | const auto *Bitfields = getTrailingObjects<FunctionTypeExtraBitfields>(); |
5684 | if (Bitfields->NumFunctionEffects > 0) |
5685 | return getTrailingObjects<FunctionEffect>( |
5686 | Bitfields->NumFunctionEffects); |
5687 | } |
5688 | return {}; |
5689 | } |
5690 | |
5691 | unsigned getNumFunctionEffectConditions() const { |
5692 | if (hasExtraBitfields()) { |
5693 | const auto *Bitfields = getTrailingObjects<FunctionTypeExtraBitfields>(); |
5694 | if (Bitfields->EffectsHaveConditions) |
5695 | return Bitfields->NumFunctionEffects; |
5696 | } |
5697 | return 0; |
5698 | } |
5699 | |
5700 | // For serialization. |
5701 | ArrayRef<EffectConditionExpr> getFunctionEffectConditions() const { |
5702 | if (hasExtraBitfields()) { |
5703 | const auto *Bitfields = getTrailingObjects<FunctionTypeExtraBitfields>(); |
5704 | if (Bitfields->EffectsHaveConditions) |
5705 | return getTrailingObjects<EffectConditionExpr>( |
5706 | Bitfields->NumFunctionEffects); |
5707 | } |
5708 | return {}; |
5709 | } |
5710 | |
5711 | // Combines effects with their conditions. |
5712 | FunctionEffectsRef getFunctionEffects() const { |
5713 | if (hasExtraBitfields()) { |
5714 | const auto *Bitfields = getTrailingObjects<FunctionTypeExtraBitfields>(); |
5715 | if (Bitfields->NumFunctionEffects > 0) { |
5716 | const size_t NumConds = Bitfields->EffectsHaveConditions |
5717 | ? Bitfields->NumFunctionEffects |
5718 | : 0; |
5719 | return FunctionEffectsRef( |
5720 | getTrailingObjects<FunctionEffect>(Bitfields->NumFunctionEffects), |
5721 | {NumConds ? getTrailingObjects<EffectConditionExpr>() : nullptr, |
5722 | NumConds}); |
5723 | } |
5724 | } |
5725 | return {}; |
5726 | } |
5727 | |
5728 | bool isSugared() const { return false; } |
5729 | QualType desugar() const { return QualType(this, 0); } |
5730 | |
5731 | void printExceptionSpecification(raw_ostream &OS, |
5732 | const PrintingPolicy &Policy) const; |
5733 | |
5734 | static bool classof(const Type *T) { |
5735 | return T->getTypeClass() == FunctionProto; |
5736 | } |
5737 | |
5738 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); |
5739 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, |
5740 | param_type_iterator ArgTys, unsigned NumArgs, |
5741 | const ExtProtoInfo &EPI, const ASTContext &Context, |
5742 | bool Canonical); |
5743 | }; |
5744 | |
5745 | /// Represents the dependent type named by a dependently-scoped |
5746 | /// typename using declaration, e.g. |
5747 | /// using typename Base<T>::foo; |
5748 | /// |
5749 | /// Template instantiation turns these into the underlying type. |
5750 | class UnresolvedUsingType : public Type { |
5751 | friend class ASTContext; // ASTContext creates these. |
5752 | |
5753 | UnresolvedUsingTypenameDecl *Decl; |
5754 | |
5755 | UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) |
5756 | : Type(UnresolvedUsing, QualType(), |
5757 | TypeDependence::DependentInstantiation), |
5758 | Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {} |
5759 | |
5760 | public: |
5761 | UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } |
5762 | |
5763 | bool isSugared() const { return false; } |
5764 | QualType desugar() const { return QualType(this, 0); } |
5765 | |
5766 | static bool classof(const Type *T) { |
5767 | return T->getTypeClass() == UnresolvedUsing; |
5768 | } |
5769 | |
5770 | void Profile(llvm::FoldingSetNodeID &ID) { |
5771 | return Profile(ID, D: Decl); |
5772 | } |
5773 | |
5774 | static void Profile(llvm::FoldingSetNodeID &ID, |
5775 | UnresolvedUsingTypenameDecl *D) { |
5776 | ID.AddPointer(Ptr: D); |
5777 | } |
5778 | }; |
5779 | |
5780 | class UsingType final : public Type, |
5781 | public llvm::FoldingSetNode, |
5782 | private llvm::TrailingObjects<UsingType, QualType> { |
5783 | UsingShadowDecl *Found; |
5784 | friend class ASTContext; // ASTContext creates these. |
5785 | friend TrailingObjects; |
5786 | |
5787 | UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon); |
5788 | |
5789 | public: |
5790 | UsingShadowDecl *getFoundDecl() const { return Found; } |
5791 | QualType getUnderlyingType() const; |
5792 | |
5793 | bool isSugared() const { return true; } |
5794 | |
5795 | // This always has the 'same' type as declared, but not necessarily identical. |
5796 | QualType desugar() const { return getUnderlyingType(); } |
5797 | |
5798 | // Internal helper, for debugging purposes. |
5799 | bool typeMatchesDecl() const { return !UsingBits.hasTypeDifferentFromDecl; } |
5800 | |
5801 | void Profile(llvm::FoldingSetNodeID &ID) { |
5802 | Profile(ID, Found, Underlying: getUnderlyingType()); |
5803 | } |
5804 | static void Profile(llvm::FoldingSetNodeID &ID, const UsingShadowDecl *Found, |
5805 | QualType Underlying) { |
5806 | ID.AddPointer(Ptr: Found); |
5807 | Underlying.Profile(ID); |
5808 | } |
5809 | static bool classof(const Type *T) { return T->getTypeClass() == Using; } |
5810 | }; |
5811 | |
5812 | class TypedefType final : public Type, |
5813 | public llvm::FoldingSetNode, |
5814 | private llvm::TrailingObjects<TypedefType, QualType> { |
5815 | TypedefNameDecl *Decl; |
5816 | friend class ASTContext; // ASTContext creates these. |
5817 | friend TrailingObjects; |
5818 | |
5819 | TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType UnderlyingType, |
5820 | bool HasTypeDifferentFromDecl); |
5821 | |
5822 | public: |
5823 | TypedefNameDecl *getDecl() const { return Decl; } |
5824 | |
5825 | bool isSugared() const { return true; } |
5826 | |
5827 | // This always has the 'same' type as declared, but not necessarily identical. |
5828 | QualType desugar() const; |
5829 | |
5830 | // Internal helper, for debugging purposes. |
5831 | bool typeMatchesDecl() const { return !TypedefBits.hasTypeDifferentFromDecl; } |
5832 | |
5833 | void Profile(llvm::FoldingSetNodeID &ID) { |
5834 | Profile(ID, Decl, Underlying: typeMatchesDecl() ? QualType() : desugar()); |
5835 | } |
5836 | static void Profile(llvm::FoldingSetNodeID &ID, const TypedefNameDecl *Decl, |
5837 | QualType Underlying) { |
5838 | ID.AddPointer(Ptr: Decl); |
5839 | if (!Underlying.isNull()) |
5840 | Underlying.Profile(ID); |
5841 | } |
5842 | |
5843 | static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } |
5844 | }; |
5845 | |
5846 | /// Sugar type that represents a type that was qualified by a qualifier written |
5847 | /// as a macro invocation. |
5848 | class MacroQualifiedType : public Type { |
5849 | friend class ASTContext; // ASTContext creates these. |
5850 | |
5851 | QualType UnderlyingTy; |
5852 | const IdentifierInfo *MacroII; |
5853 | |
5854 | MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, |
5855 | const IdentifierInfo *MacroII) |
5856 | : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()), |
5857 | UnderlyingTy(UnderlyingTy), MacroII(MacroII) { |
5858 | assert(isa<AttributedType>(UnderlyingTy) && |
5859 | "Expected a macro qualified type to only wrap attributed types." ); |
5860 | } |
5861 | |
5862 | public: |
5863 | const IdentifierInfo *getMacroIdentifier() const { return MacroII; } |
5864 | QualType getUnderlyingType() const { return UnderlyingTy; } |
5865 | |
5866 | /// Return this attributed type's modified type with no qualifiers attached to |
5867 | /// it. |
5868 | QualType getModifiedType() const; |
5869 | |
5870 | bool isSugared() const { return true; } |
5871 | QualType desugar() const; |
5872 | |
5873 | static bool classof(const Type *T) { |
5874 | return T->getTypeClass() == MacroQualified; |
5875 | } |
5876 | }; |
5877 | |
5878 | /// Represents a `typeof` (or __typeof__) expression (a C23 feature and GCC |
5879 | /// extension) or a `typeof_unqual` expression (a C23 feature). |
5880 | class TypeOfExprType : public Type { |
5881 | Expr *TOExpr; |
5882 | const ASTContext &Context; |
5883 | |
5884 | protected: |
5885 | friend class ASTContext; // ASTContext creates these. |
5886 | |
5887 | TypeOfExprType(const ASTContext &Context, Expr *E, TypeOfKind Kind, |
5888 | QualType Can = QualType()); |
5889 | |
5890 | public: |
5891 | Expr *getUnderlyingExpr() const { return TOExpr; } |
5892 | |
5893 | /// Returns the kind of 'typeof' type this is. |
5894 | TypeOfKind getKind() const { |
5895 | return static_cast<TypeOfKind>(TypeOfBits.Kind); |
5896 | } |
5897 | |
5898 | /// Remove a single level of sugar. |
5899 | QualType desugar() const; |
5900 | |
5901 | /// Returns whether this type directly provides sugar. |
5902 | bool isSugared() const; |
5903 | |
5904 | static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } |
5905 | }; |
5906 | |
5907 | /// Internal representation of canonical, dependent |
5908 | /// `typeof(expr)` types. |
5909 | /// |
5910 | /// This class is used internally by the ASTContext to manage |
5911 | /// canonical, dependent types, only. Clients will only see instances |
5912 | /// of this class via TypeOfExprType nodes. |
5913 | class DependentTypeOfExprType : public TypeOfExprType, |
5914 | public llvm::FoldingSetNode { |
5915 | public: |
5916 | DependentTypeOfExprType(const ASTContext &Context, Expr *E, TypeOfKind Kind) |
5917 | : TypeOfExprType(Context, E, Kind) {} |
5918 | |
5919 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
5920 | Profile(ID, Context, getUnderlyingExpr(), |
5921 | getKind() == TypeOfKind::Unqualified); |
5922 | } |
5923 | |
5924 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
5925 | Expr *E, bool IsUnqual); |
5926 | }; |
5927 | |
5928 | /// Represents `typeof(type)`, a C23 feature and GCC extension, or |
5929 | /// `typeof_unqual(type), a C23 feature. |
5930 | class TypeOfType : public Type { |
5931 | friend class ASTContext; // ASTContext creates these. |
5932 | |
5933 | QualType TOType; |
5934 | const ASTContext &Context; |
5935 | |
5936 | TypeOfType(const ASTContext &Context, QualType T, QualType Can, |
5937 | TypeOfKind Kind); |
5938 | |
5939 | public: |
5940 | QualType getUnmodifiedType() const { return TOType; } |
5941 | |
5942 | /// Remove a single level of sugar. |
5943 | QualType desugar() const; |
5944 | |
5945 | /// Returns whether this type directly provides sugar. |
5946 | bool isSugared() const { return true; } |
5947 | |
5948 | /// Returns the kind of 'typeof' type this is. |
5949 | TypeOfKind getKind() const { |
5950 | return static_cast<TypeOfKind>(TypeOfBits.Kind); |
5951 | } |
5952 | |
5953 | static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } |
5954 | }; |
5955 | |
5956 | /// Represents the type `decltype(expr)` (C++11). |
5957 | class DecltypeType : public Type { |
5958 | Expr *E; |
5959 | QualType UnderlyingType; |
5960 | |
5961 | protected: |
5962 | friend class ASTContext; // ASTContext creates these. |
5963 | |
5964 | DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType()); |
5965 | |
5966 | public: |
5967 | Expr *getUnderlyingExpr() const { return E; } |
5968 | QualType getUnderlyingType() const { return UnderlyingType; } |
5969 | |
5970 | /// Remove a single level of sugar. |
5971 | QualType desugar() const; |
5972 | |
5973 | /// Returns whether this type directly provides sugar. |
5974 | bool isSugared() const; |
5975 | |
5976 | static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } |
5977 | }; |
5978 | |
5979 | /// Internal representation of canonical, dependent |
5980 | /// decltype(expr) types. |
5981 | /// |
5982 | /// This class is used internally by the ASTContext to manage |
5983 | /// canonical, dependent types, only. Clients will only see instances |
5984 | /// of this class via DecltypeType nodes. |
5985 | class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { |
5986 | public: |
5987 | DependentDecltypeType(Expr *E); |
5988 | |
5989 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
5990 | Profile(ID, Context, getUnderlyingExpr()); |
5991 | } |
5992 | |
5993 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
5994 | Expr *E); |
5995 | }; |
5996 | |
5997 | class PackIndexingType final |
5998 | : public Type, |
5999 | public llvm::FoldingSetNode, |
6000 | private llvm::TrailingObjects<PackIndexingType, QualType> { |
6001 | friend TrailingObjects; |
6002 | |
6003 | QualType Pattern; |
6004 | Expr *IndexExpr; |
6005 | |
6006 | unsigned Size : 31; |
6007 | |
6008 | LLVM_PREFERRED_TYPE(bool) |
6009 | unsigned FullySubstituted : 1; |
6010 | |
6011 | protected: |
6012 | friend class ASTContext; // ASTContext creates these. |
6013 | PackIndexingType(QualType Canonical, QualType Pattern, Expr *IndexExpr, |
6014 | bool FullySubstituted, ArrayRef<QualType> Expansions = {}); |
6015 | |
6016 | public: |
6017 | Expr *getIndexExpr() const { return IndexExpr; } |
6018 | QualType getPattern() const { return Pattern; } |
6019 | |
6020 | bool isSugared() const { return hasSelectedType(); } |
6021 | |
6022 | QualType desugar() const { |
6023 | if (hasSelectedType()) |
6024 | return getSelectedType(); |
6025 | return QualType(this, 0); |
6026 | } |
6027 | |
6028 | QualType getSelectedType() const { |
6029 | assert(hasSelectedType() && "Type is dependant" ); |
6030 | return *(getExpansionsPtr() + *getSelectedIndex()); |
6031 | } |
6032 | |
6033 | UnsignedOrNone getSelectedIndex() const; |
6034 | |
6035 | bool hasSelectedType() const { return getSelectedIndex() != std::nullopt; } |
6036 | |
6037 | bool isFullySubstituted() const { return FullySubstituted; } |
6038 | |
6039 | bool expandsToEmptyPack() const { return isFullySubstituted() && Size == 0; } |
6040 | |
6041 | ArrayRef<QualType> getExpansions() const { |
6042 | return {getExpansionsPtr(), Size}; |
6043 | } |
6044 | |
6045 | static bool classof(const Type *T) { |
6046 | return T->getTypeClass() == PackIndexing; |
6047 | } |
6048 | |
6049 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context); |
6050 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
6051 | QualType Pattern, Expr *E, bool FullySubstituted, |
6052 | ArrayRef<QualType> Expansions); |
6053 | |
6054 | private: |
6055 | const QualType *getExpansionsPtr() const { |
6056 | return getTrailingObjects<QualType>(); |
6057 | } |
6058 | |
6059 | static TypeDependence computeDependence(QualType Pattern, Expr *IndexExpr, |
6060 | ArrayRef<QualType> Expansions = {}); |
6061 | }; |
6062 | |
6063 | /// A unary type transform, which is a type constructed from another. |
6064 | class UnaryTransformType : public Type, public llvm::FoldingSetNode { |
6065 | public: |
6066 | enum UTTKind { |
6067 | #define TRANSFORM_TYPE_TRAIT_DEF(Enum, _) Enum, |
6068 | #include "clang/Basic/TransformTypeTraits.def" |
6069 | }; |
6070 | |
6071 | private: |
6072 | /// The untransformed type. |
6073 | QualType BaseType; |
6074 | |
6075 | /// The transformed type if not dependent, otherwise the same as BaseType. |
6076 | QualType UnderlyingType; |
6077 | |
6078 | UTTKind UKind; |
6079 | |
6080 | protected: |
6081 | friend class ASTContext; |
6082 | |
6083 | UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, |
6084 | QualType CanonicalTy); |
6085 | |
6086 | public: |
6087 | bool isSugared() const { return !isDependentType(); } |
6088 | QualType desugar() const { return UnderlyingType; } |
6089 | |
6090 | QualType getUnderlyingType() const { return UnderlyingType; } |
6091 | QualType getBaseType() const { return BaseType; } |
6092 | |
6093 | UTTKind getUTTKind() const { return UKind; } |
6094 | |
6095 | static bool classof(const Type *T) { |
6096 | return T->getTypeClass() == UnaryTransform; |
6097 | } |
6098 | |
6099 | void Profile(llvm::FoldingSetNodeID &ID) { |
6100 | Profile(ID, BaseType: getBaseType(), UnderlyingType: getUnderlyingType(), UKind: getUTTKind()); |
6101 | } |
6102 | |
6103 | static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType, |
6104 | QualType UnderlyingType, UTTKind UKind) { |
6105 | BaseType.Profile(ID); |
6106 | UnderlyingType.Profile(ID); |
6107 | ID.AddInteger(I: UKind); |
6108 | } |
6109 | }; |
6110 | |
6111 | class TagType : public Type { |
6112 | friend class ASTReader; |
6113 | template <class T> friend class serialization::AbstractTypeReader; |
6114 | |
6115 | /// Stores the TagDecl associated with this type. The decl may point to any |
6116 | /// TagDecl that declares the entity. |
6117 | TagDecl *decl; |
6118 | |
6119 | protected: |
6120 | TagType(TypeClass TC, const TagDecl *D, QualType can); |
6121 | |
6122 | public: |
6123 | TagDecl *getDecl() const; |
6124 | |
6125 | /// Determines whether this type is in the process of being defined. |
6126 | bool isBeingDefined() const; |
6127 | |
6128 | static bool classof(const Type *T) { |
6129 | return T->getTypeClass() == Enum || T->getTypeClass() == Record; |
6130 | } |
6131 | }; |
6132 | |
6133 | /// A helper class that allows the use of isa/cast/dyncast |
6134 | /// to detect TagType objects of structs/unions/classes. |
6135 | class RecordType : public TagType { |
6136 | protected: |
6137 | friend class ASTContext; // ASTContext creates these. |
6138 | |
6139 | explicit RecordType(const RecordDecl *D) |
6140 | : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) {} |
6141 | explicit RecordType(TypeClass TC, RecordDecl *D) |
6142 | : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) {} |
6143 | |
6144 | public: |
6145 | RecordDecl *getDecl() const { |
6146 | return reinterpret_cast<RecordDecl*>(TagType::getDecl()); |
6147 | } |
6148 | |
6149 | /// Recursively check all fields in the record for const-ness. If any field |
6150 | /// is declared const, return true. Otherwise, return false. |
6151 | bool hasConstFields() const; |
6152 | |
6153 | bool isSugared() const { return false; } |
6154 | QualType desugar() const { return QualType(this, 0); } |
6155 | |
6156 | static bool classof(const Type *T) { return T->getTypeClass() == Record; } |
6157 | }; |
6158 | |
6159 | /// A helper class that allows the use of isa/cast/dyncast |
6160 | /// to detect TagType objects of enums. |
6161 | class EnumType : public TagType { |
6162 | friend class ASTContext; // ASTContext creates these. |
6163 | |
6164 | explicit EnumType(const EnumDecl *D) |
6165 | : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) {} |
6166 | |
6167 | public: |
6168 | EnumDecl *getDecl() const { |
6169 | return reinterpret_cast<EnumDecl*>(TagType::getDecl()); |
6170 | } |
6171 | |
6172 | bool isSugared() const { return false; } |
6173 | QualType desugar() const { return QualType(this, 0); } |
6174 | |
6175 | static bool classof(const Type *T) { return T->getTypeClass() == Enum; } |
6176 | }; |
6177 | |
6178 | /// An attributed type is a type to which a type attribute has been applied. |
6179 | /// |
6180 | /// The "modified type" is the fully-sugared type to which the attributed |
6181 | /// type was applied; generally it is not canonically equivalent to the |
6182 | /// attributed type. The "equivalent type" is the minimally-desugared type |
6183 | /// which the type is canonically equivalent to. |
6184 | /// |
6185 | /// For example, in the following attributed type: |
6186 | /// int32_t __attribute__((vector_size(16))) |
6187 | /// - the modified type is the TypedefType for int32_t |
6188 | /// - the equivalent type is VectorType(16, int32_t) |
6189 | /// - the canonical type is VectorType(16, int) |
6190 | class AttributedType : public Type, public llvm::FoldingSetNode { |
6191 | public: |
6192 | using Kind = attr::Kind; |
6193 | |
6194 | private: |
6195 | friend class ASTContext; // ASTContext creates these |
6196 | |
6197 | const Attr *Attribute; |
6198 | |
6199 | QualType ModifiedType; |
6200 | QualType EquivalentType; |
6201 | |
6202 | AttributedType(QualType canon, attr::Kind attrKind, QualType modified, |
6203 | QualType equivalent) |
6204 | : AttributedType(canon, attrKind, nullptr, modified, equivalent) {} |
6205 | |
6206 | AttributedType(QualType canon, const Attr *attr, QualType modified, |
6207 | QualType equivalent); |
6208 | |
6209 | private: |
6210 | AttributedType(QualType canon, attr::Kind attrKind, const Attr *attr, |
6211 | QualType modified, QualType equivalent); |
6212 | |
6213 | public: |
6214 | Kind getAttrKind() const { |
6215 | return static_cast<Kind>(AttributedTypeBits.AttrKind); |
6216 | } |
6217 | |
6218 | const Attr *getAttr() const { return Attribute; } |
6219 | |
6220 | QualType getModifiedType() const { return ModifiedType; } |
6221 | QualType getEquivalentType() const { return EquivalentType; } |
6222 | |
6223 | bool isSugared() const { return true; } |
6224 | QualType desugar() const { return getEquivalentType(); } |
6225 | |
6226 | /// Does this attribute behave like a type qualifier? |
6227 | /// |
6228 | /// A type qualifier adjusts a type to provide specialized rules for |
6229 | /// a specific object, like the standard const and volatile qualifiers. |
6230 | /// This includes attributes controlling things like nullability, |
6231 | /// address spaces, and ARC ownership. The value of the object is still |
6232 | /// largely described by the modified type. |
6233 | /// |
6234 | /// In contrast, many type attributes "rewrite" their modified type to |
6235 | /// produce a fundamentally different type, not necessarily related in any |
6236 | /// formalizable way to the original type. For example, calling convention |
6237 | /// and vector attributes are not simple type qualifiers. |
6238 | /// |
6239 | /// Type qualifiers are often, but not always, reflected in the canonical |
6240 | /// type. |
6241 | bool isQualifier() const; |
6242 | |
6243 | bool isMSTypeSpec() const; |
6244 | |
6245 | bool isWebAssemblyFuncrefSpec() const; |
6246 | |
6247 | bool isCallingConv() const; |
6248 | |
6249 | std::optional<NullabilityKind> getImmediateNullability() const; |
6250 | |
6251 | /// Strip off the top-level nullability annotation on the given |
6252 | /// type, if it's there. |
6253 | /// |
6254 | /// \param T The type to strip. If the type is exactly an |
6255 | /// AttributedType specifying nullability (without looking through |
6256 | /// type sugar), the nullability is returned and this type changed |
6257 | /// to the underlying modified type. |
6258 | /// |
6259 | /// \returns the top-level nullability, if present. |
6260 | static std::optional<NullabilityKind> stripOuterNullability(QualType &T); |
6261 | |
6262 | void Profile(llvm::FoldingSetNodeID &ID) { |
6263 | Profile(ID, getAttrKind(), ModifiedType, EquivalentType, Attribute); |
6264 | } |
6265 | |
6266 | static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind, |
6267 | QualType modified, QualType equivalent, |
6268 | const Attr *attr) { |
6269 | ID.AddInteger(I: attrKind); |
6270 | ID.AddPointer(Ptr: modified.getAsOpaquePtr()); |
6271 | ID.AddPointer(Ptr: equivalent.getAsOpaquePtr()); |
6272 | ID.AddPointer(Ptr: attr); |
6273 | } |
6274 | |
6275 | static bool classof(const Type *T) { |
6276 | return T->getTypeClass() == Attributed; |
6277 | } |
6278 | }; |
6279 | |
6280 | class BTFTagAttributedType : public Type, public llvm::FoldingSetNode { |
6281 | private: |
6282 | friend class ASTContext; // ASTContext creates these |
6283 | |
6284 | QualType WrappedType; |
6285 | const BTFTypeTagAttr *BTFAttr; |
6286 | |
6287 | BTFTagAttributedType(QualType Canon, QualType Wrapped, |
6288 | const BTFTypeTagAttr *BTFAttr) |
6289 | : Type(BTFTagAttributed, Canon, Wrapped->getDependence()), |
6290 | WrappedType(Wrapped), BTFAttr(BTFAttr) {} |
6291 | |
6292 | public: |
6293 | QualType getWrappedType() const { return WrappedType; } |
6294 | const BTFTypeTagAttr *getAttr() const { return BTFAttr; } |
6295 | |
6296 | bool isSugared() const { return true; } |
6297 | QualType desugar() const { return getWrappedType(); } |
6298 | |
6299 | void Profile(llvm::FoldingSetNodeID &ID) { |
6300 | Profile(ID, WrappedType, BTFAttr); |
6301 | } |
6302 | |
6303 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped, |
6304 | const BTFTypeTagAttr *BTFAttr) { |
6305 | ID.AddPointer(Ptr: Wrapped.getAsOpaquePtr()); |
6306 | ID.AddPointer(Ptr: BTFAttr); |
6307 | } |
6308 | |
6309 | static bool classof(const Type *T) { |
6310 | return T->getTypeClass() == BTFTagAttributed; |
6311 | } |
6312 | }; |
6313 | |
6314 | class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode { |
6315 | public: |
6316 | struct Attributes { |
6317 | // Data gathered from HLSL resource attributes |
6318 | llvm::dxil::ResourceClass ResourceClass; |
6319 | |
6320 | LLVM_PREFERRED_TYPE(bool) |
6321 | uint8_t IsROV : 1; |
6322 | |
6323 | LLVM_PREFERRED_TYPE(bool) |
6324 | uint8_t RawBuffer : 1; |
6325 | |
6326 | Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV = false, |
6327 | bool RawBuffer = false) |
6328 | : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {} |
6329 | |
6330 | Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {} |
6331 | |
6332 | friend bool operator==(const Attributes &LHS, const Attributes &RHS) { |
6333 | return std::tie(LHS.ResourceClass, LHS.IsROV, LHS.RawBuffer) == |
6334 | std::tie(RHS.ResourceClass, RHS.IsROV, RHS.RawBuffer); |
6335 | } |
6336 | friend bool operator!=(const Attributes &LHS, const Attributes &RHS) { |
6337 | return !(LHS == RHS); |
6338 | } |
6339 | }; |
6340 | |
6341 | private: |
6342 | friend class ASTContext; // ASTContext creates these |
6343 | |
6344 | QualType WrappedType; |
6345 | QualType ContainedType; |
6346 | const Attributes Attrs; |
6347 | |
6348 | HLSLAttributedResourceType(QualType Wrapped, QualType Contained, |
6349 | const Attributes &Attrs) |
6350 | : Type(HLSLAttributedResource, QualType(), |
6351 | Contained.isNull() ? TypeDependence::None |
6352 | : Contained->getDependence()), |
6353 | WrappedType(Wrapped), ContainedType(Contained), Attrs(Attrs) {} |
6354 | |
6355 | public: |
6356 | QualType getWrappedType() const { return WrappedType; } |
6357 | QualType getContainedType() const { return ContainedType; } |
6358 | bool hasContainedType() const { return !ContainedType.isNull(); } |
6359 | const Attributes &getAttrs() const { return Attrs; } |
6360 | |
6361 | bool isSugared() const { return false; } |
6362 | QualType desugar() const { return QualType(this, 0); } |
6363 | |
6364 | void Profile(llvm::FoldingSetNodeID &ID) { |
6365 | Profile(ID, WrappedType, ContainedType, Attrs); |
6366 | } |
6367 | |
6368 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped, |
6369 | QualType Contained, const Attributes &Attrs) { |
6370 | ID.AddPointer(Ptr: Wrapped.getAsOpaquePtr()); |
6371 | ID.AddPointer(Ptr: Contained.getAsOpaquePtr()); |
6372 | ID.AddInteger(I: static_cast<uint32_t>(Attrs.ResourceClass)); |
6373 | ID.AddBoolean(B: Attrs.IsROV); |
6374 | ID.AddBoolean(B: Attrs.RawBuffer); |
6375 | } |
6376 | |
6377 | static bool classof(const Type *T) { |
6378 | return T->getTypeClass() == HLSLAttributedResource; |
6379 | } |
6380 | |
6381 | // Returns handle type from HLSL resource, if the type is a resource |
6382 | static const HLSLAttributedResourceType * |
6383 | findHandleTypeOnResource(const Type *RT); |
6384 | }; |
6385 | |
6386 | /// Instances of this class represent operands to a SPIR-V type instruction. |
6387 | class SpirvOperand { |
6388 | public: |
6389 | enum SpirvOperandKind : unsigned char { |
6390 | Invalid, ///< Uninitialized. |
6391 | ConstantId, ///< Integral value to represent as a SPIR-V OpConstant |
6392 | ///< instruction ID. |
6393 | Literal, ///< Integral value to represent as an immediate literal. |
6394 | TypeId, ///< Type to represent as a SPIR-V type ID. |
6395 | |
6396 | Max, |
6397 | }; |
6398 | |
6399 | private: |
6400 | SpirvOperandKind Kind = Invalid; |
6401 | |
6402 | QualType ResultType; |
6403 | llvm::APInt Value; // Signedness of constants is represented by ResultType. |
6404 | |
6405 | public: |
6406 | SpirvOperand() : Kind(Invalid), ResultType(), Value() {} |
6407 | |
6408 | SpirvOperand(SpirvOperandKind Kind, QualType ResultType, llvm::APInt Value) |
6409 | : Kind(Kind), ResultType(ResultType), Value(Value) {} |
6410 | |
6411 | SpirvOperand(const SpirvOperand &Other) { *this = Other; } |
6412 | ~SpirvOperand() {} |
6413 | |
6414 | SpirvOperand &operator=(const SpirvOperand &Other) { |
6415 | this->Kind = Other.Kind; |
6416 | this->ResultType = Other.ResultType; |
6417 | this->Value = Other.Value; |
6418 | return *this; |
6419 | } |
6420 | |
6421 | bool operator==(const SpirvOperand &Other) const { |
6422 | return Kind == Other.Kind && ResultType == Other.ResultType && |
6423 | Value == Other.Value; |
6424 | } |
6425 | |
6426 | bool operator!=(const SpirvOperand &Other) const { return !(*this == Other); } |
6427 | |
6428 | SpirvOperandKind getKind() const { return Kind; } |
6429 | |
6430 | bool isValid() const { return Kind != Invalid && Kind < Max; } |
6431 | bool isConstant() const { return Kind == ConstantId; } |
6432 | bool isLiteral() const { return Kind == Literal; } |
6433 | bool isType() const { return Kind == TypeId; } |
6434 | |
6435 | llvm::APInt getValue() const { |
6436 | assert((isConstant() || isLiteral()) && |
6437 | "This is not an operand with a value!" ); |
6438 | return Value; |
6439 | } |
6440 | |
6441 | QualType getResultType() const { |
6442 | assert((isConstant() || isType()) && |
6443 | "This is not an operand with a result type!" ); |
6444 | return ResultType; |
6445 | } |
6446 | |
6447 | static SpirvOperand createConstant(QualType ResultType, llvm::APInt Val) { |
6448 | return SpirvOperand(ConstantId, ResultType, Val); |
6449 | } |
6450 | |
6451 | static SpirvOperand createLiteral(llvm::APInt Val) { |
6452 | return SpirvOperand(Literal, QualType(), Val); |
6453 | } |
6454 | |
6455 | static SpirvOperand createType(QualType T) { |
6456 | return SpirvOperand(TypeId, T, llvm::APSInt()); |
6457 | } |
6458 | |
6459 | void Profile(llvm::FoldingSetNodeID &ID) const { |
6460 | ID.AddInteger(I: Kind); |
6461 | ID.AddPointer(ResultType.getAsOpaquePtr()); |
6462 | Value.Profile(id&: ID); |
6463 | } |
6464 | }; |
6465 | |
6466 | /// Represents an arbitrary, user-specified SPIR-V type instruction. |
6467 | class HLSLInlineSpirvType final |
6468 | : public Type, |
6469 | public llvm::FoldingSetNode, |
6470 | private llvm::TrailingObjects<HLSLInlineSpirvType, SpirvOperand> { |
6471 | friend class ASTContext; // ASTContext creates these |
6472 | friend TrailingObjects; |
6473 | |
6474 | private: |
6475 | uint32_t Opcode; |
6476 | uint32_t Size; |
6477 | uint32_t Alignment; |
6478 | size_t NumOperands; |
6479 | |
6480 | HLSLInlineSpirvType(uint32_t Opcode, uint32_t Size, uint32_t Alignment, |
6481 | ArrayRef<SpirvOperand> Operands) |
6482 | : Type(HLSLInlineSpirv, QualType(), TypeDependence::None), Opcode(Opcode), |
6483 | Size(Size), Alignment(Alignment), NumOperands(Operands.size()) { |
6484 | for (size_t I = 0; I < NumOperands; I++) { |
6485 | // Since Operands are stored as a trailing object, they have not been |
6486 | // initialized yet. Call the constructor manually. |
6487 | auto *Operand = new (&getTrailingObjects()[I]) SpirvOperand(); |
6488 | *Operand = Operands[I]; |
6489 | } |
6490 | } |
6491 | |
6492 | public: |
6493 | uint32_t getOpcode() const { return Opcode; } |
6494 | uint32_t getSize() const { return Size; } |
6495 | uint32_t getAlignment() const { return Alignment; } |
6496 | ArrayRef<SpirvOperand> getOperands() const { |
6497 | return getTrailingObjects<SpirvOperand>(NumOperands); |
6498 | } |
6499 | |
6500 | bool isSugared() const { return false; } |
6501 | QualType desugar() const { return QualType(this, 0); } |
6502 | |
6503 | void Profile(llvm::FoldingSetNodeID &ID) { |
6504 | Profile(ID, Opcode, Size, Alignment, getOperands()); |
6505 | } |
6506 | |
6507 | static void Profile(llvm::FoldingSetNodeID &ID, uint32_t Opcode, |
6508 | uint32_t Size, uint32_t Alignment, |
6509 | ArrayRef<SpirvOperand> Operands) { |
6510 | ID.AddInteger(I: Opcode); |
6511 | ID.AddInteger(I: Size); |
6512 | ID.AddInteger(I: Alignment); |
6513 | for (auto &Operand : Operands) |
6514 | Operand.Profile(ID); |
6515 | } |
6516 | |
6517 | static bool classof(const Type *T) { |
6518 | return T->getTypeClass() == HLSLInlineSpirv; |
6519 | } |
6520 | }; |
6521 | |
6522 | class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { |
6523 | friend class ASTContext; // ASTContext creates these |
6524 | |
6525 | // The associated TemplateTypeParmDecl for the non-canonical type. |
6526 | TemplateTypeParmDecl *TTPDecl; |
6527 | |
6528 | TemplateTypeParmType(unsigned D, unsigned I, bool PP, |
6529 | TemplateTypeParmDecl *TTPDecl, QualType Canon) |
6530 | : Type(TemplateTypeParm, Canon, |
6531 | TypeDependence::DependentInstantiation | |
6532 | (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)), |
6533 | TTPDecl(TTPDecl) { |
6534 | assert(!TTPDecl == Canon.isNull()); |
6535 | TemplateTypeParmTypeBits.Depth = D; |
6536 | TemplateTypeParmTypeBits.Index = I; |
6537 | TemplateTypeParmTypeBits.ParameterPack = PP; |
6538 | } |
6539 | |
6540 | public: |
6541 | unsigned getDepth() const { return TemplateTypeParmTypeBits.Depth; } |
6542 | unsigned getIndex() const { return TemplateTypeParmTypeBits.Index; } |
6543 | bool isParameterPack() const { |
6544 | return TemplateTypeParmTypeBits.ParameterPack; |
6545 | } |
6546 | |
6547 | TemplateTypeParmDecl *getDecl() const { return TTPDecl; } |
6548 | |
6549 | IdentifierInfo *getIdentifier() const; |
6550 | |
6551 | bool isSugared() const { return false; } |
6552 | QualType desugar() const { return QualType(this, 0); } |
6553 | |
6554 | void Profile(llvm::FoldingSetNodeID &ID) { |
6555 | Profile(ID, Depth: getDepth(), Index: getIndex(), ParameterPack: isParameterPack(), TTPDecl: getDecl()); |
6556 | } |
6557 | |
6558 | static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, |
6559 | unsigned Index, bool ParameterPack, |
6560 | TemplateTypeParmDecl *TTPDecl) { |
6561 | ID.AddInteger(I: Depth); |
6562 | ID.AddInteger(I: Index); |
6563 | ID.AddBoolean(B: ParameterPack); |
6564 | ID.AddPointer(Ptr: TTPDecl); |
6565 | } |
6566 | |
6567 | static bool classof(const Type *T) { |
6568 | return T->getTypeClass() == TemplateTypeParm; |
6569 | } |
6570 | }; |
6571 | |
6572 | /// Represents the result of substituting a type for a template |
6573 | /// type parameter. |
6574 | /// |
6575 | /// Within an instantiated template, all template type parameters have |
6576 | /// been replaced with these. They are used solely to record that a |
6577 | /// type was originally written as a template type parameter; |
6578 | /// therefore they are never canonical. |
6579 | class SubstTemplateTypeParmType final |
6580 | : public Type, |
6581 | public llvm::FoldingSetNode, |
6582 | private llvm::TrailingObjects<SubstTemplateTypeParmType, QualType> { |
6583 | friend class ASTContext; |
6584 | friend class llvm::TrailingObjects<SubstTemplateTypeParmType, QualType>; |
6585 | |
6586 | Decl *AssociatedDecl; |
6587 | |
6588 | SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, |
6589 | unsigned Index, UnsignedOrNone PackIndex, |
6590 | bool Final); |
6591 | |
6592 | public: |
6593 | /// Gets the type that was substituted for the template |
6594 | /// parameter. |
6595 | QualType getReplacementType() const { |
6596 | return SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType |
6597 | ? *getTrailingObjects() |
6598 | : getCanonicalTypeInternal(); |
6599 | } |
6600 | |
6601 | /// A template-like entity which owns the whole pattern being substituted. |
6602 | /// This will usually own a set of template parameters, or in some |
6603 | /// cases might even be a template parameter itself. |
6604 | Decl *getAssociatedDecl() const { return AssociatedDecl; } |
6605 | |
6606 | /// Gets the template parameter declaration that was substituted for. |
6607 | const TemplateTypeParmDecl *getReplacedParameter() const; |
6608 | |
6609 | /// Returns the index of the replaced parameter in the associated declaration. |
6610 | /// This should match the result of `getReplacedParameter()->getIndex()`. |
6611 | unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; } |
6612 | |
6613 | // This substitution is Final, which means the substitution is fully |
6614 | // sugared: it doesn't need to be resugared later. |
6615 | unsigned getFinal() const { return SubstTemplateTypeParmTypeBits.Final; } |
6616 | |
6617 | UnsignedOrNone getPackIndex() const { |
6618 | return UnsignedOrNone::fromInternalRepresentation( |
6619 | SubstTemplateTypeParmTypeBits.PackIndex); |
6620 | } |
6621 | |
6622 | bool isSugared() const { return true; } |
6623 | QualType desugar() const { return getReplacementType(); } |
6624 | |
6625 | void Profile(llvm::FoldingSetNodeID &ID) { |
6626 | Profile(ID, Replacement: getReplacementType(), AssociatedDecl: getAssociatedDecl(), Index: getIndex(), |
6627 | PackIndex: getPackIndex(), Final: getFinal()); |
6628 | } |
6629 | |
6630 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement, |
6631 | const Decl *AssociatedDecl, unsigned Index, |
6632 | UnsignedOrNone PackIndex, bool Final); |
6633 | |
6634 | static bool classof(const Type *T) { |
6635 | return T->getTypeClass() == SubstTemplateTypeParm; |
6636 | } |
6637 | }; |
6638 | |
6639 | /// Represents the result of substituting a set of types for a template |
6640 | /// type parameter pack. |
6641 | /// |
6642 | /// When a pack expansion in the source code contains multiple parameter packs |
6643 | /// and those parameter packs correspond to different levels of template |
6644 | /// parameter lists, this type node is used to represent a template type |
6645 | /// parameter pack from an outer level, which has already had its argument pack |
6646 | /// substituted but that still lives within a pack expansion that itself |
6647 | /// could not be instantiated. When actually performing a substitution into |
6648 | /// that pack expansion (e.g., when all template parameters have corresponding |
6649 | /// arguments), this type will be replaced with the \c SubstTemplateTypeParmType |
6650 | /// at the current pack substitution index. |
6651 | class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { |
6652 | friend class ASTContext; |
6653 | |
6654 | /// A pointer to the set of template arguments that this |
6655 | /// parameter pack is instantiated with. |
6656 | const TemplateArgument *Arguments; |
6657 | |
6658 | llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal; |
6659 | |
6660 | SubstTemplateTypeParmPackType(QualType Canon, Decl *AssociatedDecl, |
6661 | unsigned Index, bool Final, |
6662 | const TemplateArgument &ArgPack); |
6663 | |
6664 | public: |
6665 | IdentifierInfo *getIdentifier() const; |
6666 | |
6667 | /// A template-like entity which owns the whole pattern being substituted. |
6668 | /// This will usually own a set of template parameters, or in some |
6669 | /// cases might even be a template parameter itself. |
6670 | Decl *getAssociatedDecl() const; |
6671 | |
6672 | /// Gets the template parameter declaration that was substituted for. |
6673 | const TemplateTypeParmDecl *getReplacedParameter() const; |
6674 | |
6675 | /// Returns the index of the replaced parameter in the associated declaration. |
6676 | /// This should match the result of `getReplacedParameter()->getIndex()`. |
6677 | unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; } |
6678 | |
6679 | // This substitution will be Final, which means the substitution will be fully |
6680 | // sugared: it doesn't need to be resugared later. |
6681 | bool getFinal() const; |
6682 | |
6683 | unsigned getNumArgs() const { |
6684 | return SubstTemplateTypeParmPackTypeBits.NumArgs; |
6685 | } |
6686 | |
6687 | bool isSugared() const { return false; } |
6688 | QualType desugar() const { return QualType(this, 0); } |
6689 | |
6690 | TemplateArgument getArgumentPack() const; |
6691 | |
6692 | void Profile(llvm::FoldingSetNodeID &ID); |
6693 | static void Profile(llvm::FoldingSetNodeID &ID, const Decl *AssociatedDecl, |
6694 | unsigned Index, bool Final, |
6695 | const TemplateArgument &ArgPack); |
6696 | |
6697 | static bool classof(const Type *T) { |
6698 | return T->getTypeClass() == SubstTemplateTypeParmPack; |
6699 | } |
6700 | }; |
6701 | |
6702 | /// Common base class for placeholders for types that get replaced by |
6703 | /// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced |
6704 | /// class template types, and constrained type names. |
6705 | /// |
6706 | /// These types are usually a placeholder for a deduced type. However, before |
6707 | /// the initializer is attached, or (usually) if the initializer is |
6708 | /// type-dependent, there is no deduced type and the type is canonical. In |
6709 | /// the latter case, it is also a dependent type. |
6710 | class DeducedType : public Type { |
6711 | QualType DeducedAsType; |
6712 | |
6713 | protected: |
6714 | DeducedType(TypeClass TC, QualType DeducedAsType, |
6715 | TypeDependence , QualType Canon) |
6716 | : Type(TC, Canon, |
6717 | ExtraDependence | (DeducedAsType.isNull() |
6718 | ? TypeDependence::None |
6719 | : DeducedAsType->getDependence() & |
6720 | ~TypeDependence::VariablyModified)), |
6721 | DeducedAsType(DeducedAsType) {} |
6722 | |
6723 | public: |
6724 | bool isSugared() const { return !DeducedAsType.isNull(); } |
6725 | QualType desugar() const { |
6726 | return isSugared() ? DeducedAsType : QualType(this, 0); |
6727 | } |
6728 | |
6729 | /// Get the type deduced for this placeholder type, or null if it |
6730 | /// has not been deduced. |
6731 | QualType getDeducedType() const { return DeducedAsType; } |
6732 | bool isDeduced() const { |
6733 | return !DeducedAsType.isNull() || isDependentType(); |
6734 | } |
6735 | |
6736 | static bool classof(const Type *T) { |
6737 | return T->getTypeClass() == Auto || |
6738 | T->getTypeClass() == DeducedTemplateSpecialization; |
6739 | } |
6740 | }; |
6741 | |
6742 | /// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained |
6743 | /// by a type-constraint. |
6744 | class AutoType : public DeducedType { |
6745 | friend class ASTContext; // ASTContext creates these |
6746 | |
6747 | ConceptDecl *TypeConstraintConcept; |
6748 | |
6749 | AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, |
6750 | TypeDependence , QualType Canon, ConceptDecl *CD, |
6751 | ArrayRef<TemplateArgument> TypeConstraintArgs); |
6752 | |
6753 | public: |
6754 | ArrayRef<TemplateArgument> getTypeConstraintArguments() const { |
6755 | return {reinterpret_cast<const TemplateArgument *>(this + 1), |
6756 | AutoTypeBits.NumArgs}; |
6757 | } |
6758 | |
6759 | ConceptDecl *getTypeConstraintConcept() const { |
6760 | return TypeConstraintConcept; |
6761 | } |
6762 | |
6763 | bool isConstrained() const { |
6764 | return TypeConstraintConcept != nullptr; |
6765 | } |
6766 | |
6767 | bool isDecltypeAuto() const { |
6768 | return getKeyword() == AutoTypeKeyword::DecltypeAuto; |
6769 | } |
6770 | |
6771 | bool isGNUAutoType() const { |
6772 | return getKeyword() == AutoTypeKeyword::GNUAutoType; |
6773 | } |
6774 | |
6775 | AutoTypeKeyword getKeyword() const { |
6776 | return (AutoTypeKeyword)AutoTypeBits.Keyword; |
6777 | } |
6778 | |
6779 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context); |
6780 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
6781 | QualType Deduced, AutoTypeKeyword Keyword, |
6782 | bool IsDependent, ConceptDecl *CD, |
6783 | ArrayRef<TemplateArgument> Arguments); |
6784 | |
6785 | static bool classof(const Type *T) { |
6786 | return T->getTypeClass() == Auto; |
6787 | } |
6788 | }; |
6789 | |
6790 | /// Represents a C++17 deduced template specialization type. |
6791 | class DeducedTemplateSpecializationType : public DeducedType, |
6792 | public llvm::FoldingSetNode { |
6793 | friend class ASTContext; // ASTContext creates these |
6794 | |
6795 | /// The name of the template whose arguments will be deduced. |
6796 | TemplateName Template; |
6797 | |
6798 | DeducedTemplateSpecializationType(TemplateName Template, |
6799 | QualType DeducedAsType, |
6800 | bool IsDeducedAsDependent, QualType Canon) |
6801 | : DeducedType(DeducedTemplateSpecialization, DeducedAsType, |
6802 | toTypeDependence(Template.getDependence()) | |
6803 | (IsDeducedAsDependent |
6804 | ? TypeDependence::DependentInstantiation |
6805 | : TypeDependence::None), |
6806 | Canon), |
6807 | Template(Template) {} |
6808 | |
6809 | public: |
6810 | /// Retrieve the name of the template that we are deducing. |
6811 | TemplateName getTemplateName() const { return Template;} |
6812 | |
6813 | void Profile(llvm::FoldingSetNodeID &ID) const { |
6814 | Profile(ID, getTemplateName(), getDeducedType(), isDependentType()); |
6815 | } |
6816 | |
6817 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template, |
6818 | QualType Deduced, bool IsDependent) { |
6819 | Template.Profile(ID); |
6820 | Deduced.Profile(ID); |
6821 | ID.AddBoolean(B: IsDependent || Template.isDependent()); |
6822 | } |
6823 | |
6824 | static bool classof(const Type *T) { |
6825 | return T->getTypeClass() == DeducedTemplateSpecialization; |
6826 | } |
6827 | }; |
6828 | |
6829 | /// Represents a type template specialization; the template |
6830 | /// must be a class template, a type alias template, or a template |
6831 | /// template parameter. A template which cannot be resolved to one of |
6832 | /// these, e.g. because it is written with a dependent scope |
6833 | /// specifier, is instead represented as a |
6834 | /// @c DependentTemplateSpecializationType. |
6835 | /// |
6836 | /// A non-dependent template specialization type is always "sugar", |
6837 | /// typically for a \c RecordType. For example, a class template |
6838 | /// specialization type of \c vector<int> will refer to a tag type for |
6839 | /// the instantiation \c std::vector<int, std::allocator<int>> |
6840 | /// |
6841 | /// Template specializations are dependent if either the template or |
6842 | /// any of the template arguments are dependent, in which case the |
6843 | /// type may also be canonical. |
6844 | /// |
6845 | /// Instances of this type are allocated with a trailing array of |
6846 | /// TemplateArguments, followed by a QualType representing the |
6847 | /// non-canonical aliased type when the template is a type alias |
6848 | /// template. |
6849 | class TemplateSpecializationType : public Type, public llvm::FoldingSetNode { |
6850 | friend class ASTContext; // ASTContext creates these |
6851 | |
6852 | /// The name of the template being specialized. This is |
6853 | /// either a TemplateName::Template (in which case it is a |
6854 | /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a |
6855 | /// TypeAliasTemplateDecl*), a |
6856 | /// TemplateName::SubstTemplateTemplateParmPack, or a |
6857 | /// TemplateName::SubstTemplateTemplateParm (in which case the |
6858 | /// replacement must, recursively, be one of these). |
6859 | TemplateName Template; |
6860 | |
6861 | TemplateSpecializationType(TemplateName T, bool IsAlias, |
6862 | ArrayRef<TemplateArgument> Args, |
6863 | QualType Underlying); |
6864 | |
6865 | public: |
6866 | /// Determine whether any of the given template arguments are dependent. |
6867 | /// |
6868 | /// The converted arguments should be supplied when known; whether an |
6869 | /// argument is dependent can depend on the conversions performed on it |
6870 | /// (for example, a 'const int' passed as a template argument might be |
6871 | /// dependent if the parameter is a reference but non-dependent if the |
6872 | /// parameter is an int). |
6873 | /// |
6874 | /// Note that the \p Args parameter is unused: this is intentional, to remind |
6875 | /// the caller that they need to pass in the converted arguments, not the |
6876 | /// specified arguments. |
6877 | static bool |
6878 | anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args, |
6879 | ArrayRef<TemplateArgument> Converted); |
6880 | static bool |
6881 | anyDependentTemplateArguments(const TemplateArgumentListInfo &, |
6882 | ArrayRef<TemplateArgument> Converted); |
6883 | static bool anyInstantiationDependentTemplateArguments( |
6884 | ArrayRef<TemplateArgumentLoc> Args); |
6885 | |
6886 | /// True if this template specialization type matches a current |
6887 | /// instantiation in the context in which it is found. |
6888 | bool isCurrentInstantiation() const { |
6889 | return isa<InjectedClassNameType>(getCanonicalTypeInternal()); |
6890 | } |
6891 | |
6892 | /// Determine if this template specialization type is for a type alias |
6893 | /// template that has been substituted. |
6894 | /// |
6895 | /// Nearly every template specialization type whose template is an alias |
6896 | /// template will be substituted. However, this is not the case when |
6897 | /// the specialization contains a pack expansion but the template alias |
6898 | /// does not have a corresponding parameter pack, e.g., |
6899 | /// |
6900 | /// \code |
6901 | /// template<typename T, typename U, typename V> struct S; |
6902 | /// template<typename T, typename U> using A = S<T, int, U>; |
6903 | /// template<typename... Ts> struct X { |
6904 | /// typedef A<Ts...> type; // not a type alias |
6905 | /// }; |
6906 | /// \endcode |
6907 | bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; } |
6908 | |
6909 | /// Get the aliased type, if this is a specialization of a type alias |
6910 | /// template. |
6911 | QualType getAliasedType() const; |
6912 | |
6913 | /// Retrieve the name of the template that we are specializing. |
6914 | TemplateName getTemplateName() const { return Template; } |
6915 | |
6916 | ArrayRef<TemplateArgument> template_arguments() const { |
6917 | return {reinterpret_cast<const TemplateArgument *>(this + 1), |
6918 | TemplateSpecializationTypeBits.NumArgs}; |
6919 | } |
6920 | |
6921 | bool isSugared() const { |
6922 | return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); |
6923 | } |
6924 | |
6925 | QualType desugar() const { |
6926 | return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal(); |
6927 | } |
6928 | |
6929 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); |
6930 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, |
6931 | ArrayRef<TemplateArgument> Args, QualType Underlying, |
6932 | const ASTContext &Context); |
6933 | |
6934 | static bool classof(const Type *T) { |
6935 | return T->getTypeClass() == TemplateSpecialization; |
6936 | } |
6937 | }; |
6938 | |
6939 | /// Print a template argument list, including the '<' and '>' |
6940 | /// enclosing the template arguments. |
6941 | void printTemplateArgumentList(raw_ostream &OS, |
6942 | ArrayRef<TemplateArgument> Args, |
6943 | const PrintingPolicy &Policy, |
6944 | const TemplateParameterList *TPL = nullptr); |
6945 | |
6946 | void printTemplateArgumentList(raw_ostream &OS, |
6947 | ArrayRef<TemplateArgumentLoc> Args, |
6948 | const PrintingPolicy &Policy, |
6949 | const TemplateParameterList *TPL = nullptr); |
6950 | |
6951 | void printTemplateArgumentList(raw_ostream &OS, |
6952 | const TemplateArgumentListInfo &Args, |
6953 | const PrintingPolicy &Policy, |
6954 | const TemplateParameterList *TPL = nullptr); |
6955 | |
6956 | /// Make a best-effort determination of whether the type T can be produced by |
6957 | /// substituting Args into the default argument of Param. |
6958 | bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg, |
6959 | const NamedDecl *Param, |
6960 | ArrayRef<TemplateArgument> Args, |
6961 | unsigned Depth); |
6962 | |
6963 | /// The injected class name of a C++ class template or class |
6964 | /// template partial specialization. Used to record that a type was |
6965 | /// spelled with a bare identifier rather than as a template-id; the |
6966 | /// equivalent for non-templated classes is just RecordType. |
6967 | /// |
6968 | /// Injected class name types are always dependent. Template |
6969 | /// instantiation turns these into RecordTypes. |
6970 | /// |
6971 | /// Injected class name types are always canonical. This works |
6972 | /// because it is impossible to compare an injected class name type |
6973 | /// with the corresponding non-injected template type, for the same |
6974 | /// reason that it is impossible to directly compare template |
6975 | /// parameters from different dependent contexts: injected class name |
6976 | /// types can only occur within the scope of a particular templated |
6977 | /// declaration, and within that scope every template specialization |
6978 | /// will canonicalize to the injected class name (when appropriate |
6979 | /// according to the rules of the language). |
6980 | class InjectedClassNameType : public Type { |
6981 | friend class ASTContext; // ASTContext creates these. |
6982 | friend class ASTNodeImporter; |
6983 | friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not |
6984 | // currently suitable for AST reading, too much |
6985 | // interdependencies. |
6986 | template <class T> friend class serialization::AbstractTypeReader; |
6987 | |
6988 | CXXRecordDecl *Decl; |
6989 | |
6990 | /// The template specialization which this type represents. |
6991 | /// For example, in |
6992 | /// template <class T> class A { ... }; |
6993 | /// this is A<T>, whereas in |
6994 | /// template <class X, class Y> class A<B<X,Y> > { ... }; |
6995 | /// this is A<B<X,Y> >. |
6996 | /// |
6997 | /// It is always unqualified, always a template specialization type, |
6998 | /// and always dependent. |
6999 | QualType InjectedType; |
7000 | |
7001 | InjectedClassNameType(CXXRecordDecl *D, QualType TST) |
7002 | : Type(InjectedClassName, QualType(), |
7003 | TypeDependence::DependentInstantiation), |
7004 | Decl(D), InjectedType(TST) { |
7005 | assert(isa<TemplateSpecializationType>(TST)); |
7006 | assert(!TST.hasQualifiers()); |
7007 | assert(TST->isDependentType()); |
7008 | } |
7009 | |
7010 | public: |
7011 | QualType getInjectedSpecializationType() const { return InjectedType; } |
7012 | |
7013 | const TemplateSpecializationType *getInjectedTST() const { |
7014 | return cast<TemplateSpecializationType>(InjectedType.getTypePtr()); |
7015 | } |
7016 | |
7017 | TemplateName getTemplateName() const { |
7018 | return getInjectedTST()->getTemplateName(); |
7019 | } |
7020 | |
7021 | CXXRecordDecl *getDecl() const; |
7022 | |
7023 | bool isSugared() const { return false; } |
7024 | QualType desugar() const { return QualType(this, 0); } |
7025 | |
7026 | static bool classof(const Type *T) { |
7027 | return T->getTypeClass() == InjectedClassName; |
7028 | } |
7029 | }; |
7030 | |
7031 | /// The elaboration keyword that precedes a qualified type name or |
7032 | /// introduces an elaborated-type-specifier. |
7033 | enum class ElaboratedTypeKeyword { |
7034 | /// The "struct" keyword introduces the elaborated-type-specifier. |
7035 | Struct, |
7036 | |
7037 | /// The "__interface" keyword introduces the elaborated-type-specifier. |
7038 | Interface, |
7039 | |
7040 | /// The "union" keyword introduces the elaborated-type-specifier. |
7041 | Union, |
7042 | |
7043 | /// The "class" keyword introduces the elaborated-type-specifier. |
7044 | Class, |
7045 | |
7046 | /// The "enum" keyword introduces the elaborated-type-specifier. |
7047 | Enum, |
7048 | |
7049 | /// The "typename" keyword precedes the qualified type name, e.g., |
7050 | /// \c typename T::type. |
7051 | Typename, |
7052 | |
7053 | /// No keyword precedes the qualified type name. |
7054 | None |
7055 | }; |
7056 | |
7057 | /// The kind of a tag type. |
7058 | enum class TagTypeKind { |
7059 | /// The "struct" keyword. |
7060 | Struct, |
7061 | |
7062 | /// The "__interface" keyword. |
7063 | Interface, |
7064 | |
7065 | /// The "union" keyword. |
7066 | Union, |
7067 | |
7068 | /// The "class" keyword. |
7069 | Class, |
7070 | |
7071 | /// The "enum" keyword. |
7072 | Enum |
7073 | }; |
7074 | |
7075 | /// A helper class for Type nodes having an ElaboratedTypeKeyword. |
7076 | /// The keyword in stored in the free bits of the base class. |
7077 | /// Also provides a few static helpers for converting and printing |
7078 | /// elaborated type keyword and tag type kind enumerations. |
7079 | class TypeWithKeyword : public Type { |
7080 | protected: |
7081 | TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, |
7082 | QualType Canonical, TypeDependence Dependence) |
7083 | : Type(tc, Canonical, Dependence) { |
7084 | TypeWithKeywordBits.Keyword = llvm::to_underlying(Keyword); |
7085 | } |
7086 | |
7087 | public: |
7088 | ElaboratedTypeKeyword getKeyword() const { |
7089 | return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword); |
7090 | } |
7091 | |
7092 | /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword. |
7093 | static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec); |
7094 | |
7095 | /// Converts a type specifier (DeclSpec::TST) into a tag type kind. |
7096 | /// It is an error to provide a type specifier which *isn't* a tag kind here. |
7097 | static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec); |
7098 | |
7099 | /// Converts a TagTypeKind into an elaborated type keyword. |
7100 | static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag); |
7101 | |
7102 | /// Converts an elaborated type keyword into a TagTypeKind. |
7103 | /// It is an error to provide an elaborated type keyword |
7104 | /// which *isn't* a tag kind here. |
7105 | static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword); |
7106 | |
7107 | static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword); |
7108 | |
7109 | static StringRef getKeywordName(ElaboratedTypeKeyword Keyword); |
7110 | |
7111 | static StringRef getTagTypeKindName(TagTypeKind Kind) { |
7112 | return getKeywordName(Keyword: getKeywordForTagTypeKind(Tag: Kind)); |
7113 | } |
7114 | |
7115 | class CannotCastToThisType {}; |
7116 | static CannotCastToThisType classof(const Type *); |
7117 | }; |
7118 | |
7119 | /// Represents a type that was referred to using an elaborated type |
7120 | /// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, |
7121 | /// or both. |
7122 | /// |
7123 | /// This type is used to keep track of a type name as written in the |
7124 | /// source code, including tag keywords and any nested-name-specifiers. |
7125 | /// The type itself is always "sugar", used to express what was written |
7126 | /// in the source code but containing no additional semantic information. |
7127 | class ElaboratedType final |
7128 | : public TypeWithKeyword, |
7129 | public llvm::FoldingSetNode, |
7130 | private llvm::TrailingObjects<ElaboratedType, TagDecl *> { |
7131 | friend class ASTContext; // ASTContext creates these |
7132 | friend TrailingObjects; |
7133 | |
7134 | /// The nested name specifier containing the qualifier. |
7135 | NestedNameSpecifier *NNS; |
7136 | |
7137 | /// The type that this qualified name refers to. |
7138 | QualType NamedType; |
7139 | |
7140 | /// The (re)declaration of this tag type owned by this occurrence is stored |
7141 | /// as a trailing object if there is one. Use getOwnedTagDecl to obtain |
7142 | /// it, or obtain a null pointer if there is none. |
7143 | |
7144 | ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, |
7145 | QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl) |
7146 | : TypeWithKeyword(Keyword, Elaborated, CanonType, |
7147 | // Any semantic dependence on the qualifier will have |
7148 | // been incorporated into NamedType. We still need to |
7149 | // track syntactic (instantiation / error / pack) |
7150 | // dependence on the qualifier. |
7151 | NamedType->getDependence() | |
7152 | (NNS ? toSyntacticDependence( |
7153 | toTypeDependence(NNS->getDependence())) |
7154 | : TypeDependence::None)), |
7155 | NNS(NNS), NamedType(NamedType) { |
7156 | ElaboratedTypeBits.HasOwnedTagDecl = false; |
7157 | if (OwnedTagDecl) { |
7158 | ElaboratedTypeBits.HasOwnedTagDecl = true; |
7159 | *getTrailingObjects() = OwnedTagDecl; |
7160 | } |
7161 | } |
7162 | |
7163 | public: |
7164 | /// Retrieve the qualification on this type. |
7165 | NestedNameSpecifier *getQualifier() const { return NNS; } |
7166 | |
7167 | /// Retrieve the type named by the qualified-id. |
7168 | QualType getNamedType() const { return NamedType; } |
7169 | |
7170 | /// Remove a single level of sugar. |
7171 | QualType desugar() const { return getNamedType(); } |
7172 | |
7173 | /// Returns whether this type directly provides sugar. |
7174 | bool isSugared() const { return true; } |
7175 | |
7176 | /// Return the (re)declaration of this type owned by this occurrence of this |
7177 | /// type, or nullptr if there is none. |
7178 | TagDecl *getOwnedTagDecl() const { |
7179 | return ElaboratedTypeBits.HasOwnedTagDecl ? *getTrailingObjects() : nullptr; |
7180 | } |
7181 | |
7182 | void Profile(llvm::FoldingSetNodeID &ID) { |
7183 | Profile(ID, getKeyword(), NNS, NamedType, getOwnedTagDecl()); |
7184 | } |
7185 | |
7186 | static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, |
7187 | NestedNameSpecifier *NNS, QualType NamedType, |
7188 | TagDecl *OwnedTagDecl) { |
7189 | ID.AddInteger(llvm::to_underlying(Keyword)); |
7190 | ID.AddPointer(Ptr: NNS); |
7191 | NamedType.Profile(ID); |
7192 | ID.AddPointer(Ptr: OwnedTagDecl); |
7193 | } |
7194 | |
7195 | static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; } |
7196 | }; |
7197 | |
7198 | /// Represents a qualified type name for which the type name is |
7199 | /// dependent. |
7200 | /// |
7201 | /// DependentNameType represents a class of dependent types that involve a |
7202 | /// possibly dependent nested-name-specifier (e.g., "T::") followed by a |
7203 | /// name of a type. The DependentNameType may start with a "typename" (for a |
7204 | /// typename-specifier), "class", "struct", "union", or "enum" (for a |
7205 | /// dependent elaborated-type-specifier), or nothing (in contexts where we |
7206 | /// know that we must be referring to a type, e.g., in a base class specifier). |
7207 | /// Typically the nested-name-specifier is dependent, but in MSVC compatibility |
7208 | /// mode, this type is used with non-dependent names to delay name lookup until |
7209 | /// instantiation. |
7210 | class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { |
7211 | friend class ASTContext; // ASTContext creates these |
7212 | |
7213 | /// The nested name specifier containing the qualifier. |
7214 | NestedNameSpecifier *NNS; |
7215 | |
7216 | /// The type that this typename specifier refers to. |
7217 | const IdentifierInfo *Name; |
7218 | |
7219 | DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, |
7220 | const IdentifierInfo *Name, QualType CanonType) |
7221 | : TypeWithKeyword(Keyword, DependentName, CanonType, |
7222 | TypeDependence::DependentInstantiation | |
7223 | toTypeDependence(NNS->getDependence())), |
7224 | NNS(NNS), Name(Name) { |
7225 | assert(NNS); |
7226 | assert(Name); |
7227 | } |
7228 | |
7229 | public: |
7230 | /// Retrieve the qualification on this type. |
7231 | NestedNameSpecifier *getQualifier() const { return NNS; } |
7232 | |
7233 | /// Retrieve the identifier that terminates this type name. |
7234 | /// For example, "type" in "typename T::type". |
7235 | const IdentifierInfo *getIdentifier() const { |
7236 | return Name; |
7237 | } |
7238 | |
7239 | bool isSugared() const { return false; } |
7240 | QualType desugar() const { return QualType(this, 0); } |
7241 | |
7242 | void Profile(llvm::FoldingSetNodeID &ID) { |
7243 | Profile(ID, getKeyword(), NNS, Name); |
7244 | } |
7245 | |
7246 | static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, |
7247 | NestedNameSpecifier *NNS, const IdentifierInfo *Name) { |
7248 | ID.AddInteger(llvm::to_underlying(Keyword)); |
7249 | ID.AddPointer(Ptr: NNS); |
7250 | ID.AddPointer(Ptr: Name); |
7251 | } |
7252 | |
7253 | static bool classof(const Type *T) { |
7254 | return T->getTypeClass() == DependentName; |
7255 | } |
7256 | }; |
7257 | |
7258 | /// Represents a template specialization type whose template cannot be |
7259 | /// resolved, e.g. |
7260 | /// A<T>::template B<T> |
7261 | class DependentTemplateSpecializationType : public TypeWithKeyword, |
7262 | public llvm::FoldingSetNode { |
7263 | friend class ASTContext; // ASTContext creates these |
7264 | |
7265 | DependentTemplateStorage Name; |
7266 | |
7267 | DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, |
7268 | const DependentTemplateStorage &Name, |
7269 | ArrayRef<TemplateArgument> Args, |
7270 | QualType Canon); |
7271 | |
7272 | public: |
7273 | const DependentTemplateStorage &getDependentTemplateName() const { |
7274 | return Name; |
7275 | } |
7276 | |
7277 | ArrayRef<TemplateArgument> template_arguments() const { |
7278 | return {reinterpret_cast<const TemplateArgument *>(this + 1), |
7279 | DependentTemplateSpecializationTypeBits.NumArgs}; |
7280 | } |
7281 | |
7282 | bool isSugared() const { return false; } |
7283 | QualType desugar() const { return QualType(this, 0); } |
7284 | |
7285 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
7286 | Profile(ID, Context, getKeyword(), Name, template_arguments()); |
7287 | } |
7288 | |
7289 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
7290 | ElaboratedTypeKeyword Keyword, |
7291 | const DependentTemplateStorage &Name, |
7292 | ArrayRef<TemplateArgument> Args); |
7293 | |
7294 | static bool classof(const Type *T) { |
7295 | return T->getTypeClass() == DependentTemplateSpecialization; |
7296 | } |
7297 | }; |
7298 | |
7299 | /// Represents a pack expansion of types. |
7300 | /// |
7301 | /// Pack expansions are part of C++11 variadic templates. A pack |
7302 | /// expansion contains a pattern, which itself contains one or more |
7303 | /// "unexpanded" parameter packs. When instantiated, a pack expansion |
7304 | /// produces a series of types, each instantiated from the pattern of |
7305 | /// the expansion, where the Ith instantiation of the pattern uses the |
7306 | /// Ith arguments bound to each of the unexpanded parameter packs. The |
7307 | /// pack expansion is considered to "expand" these unexpanded |
7308 | /// parameter packs. |
7309 | /// |
7310 | /// \code |
7311 | /// template<typename ...Types> struct tuple; |
7312 | /// |
7313 | /// template<typename ...Types> |
7314 | /// struct tuple_of_references { |
7315 | /// typedef tuple<Types&...> type; |
7316 | /// }; |
7317 | /// \endcode |
7318 | /// |
7319 | /// Here, the pack expansion \c Types&... is represented via a |
7320 | /// PackExpansionType whose pattern is Types&. |
7321 | class PackExpansionType : public Type, public llvm::FoldingSetNode { |
7322 | friend class ASTContext; // ASTContext creates these |
7323 | |
7324 | /// The pattern of the pack expansion. |
7325 | QualType Pattern; |
7326 | |
7327 | PackExpansionType(QualType Pattern, QualType Canon, |
7328 | UnsignedOrNone NumExpansions) |
7329 | : Type(PackExpansion, Canon, |
7330 | (Pattern->getDependence() | TypeDependence::Dependent | |
7331 | TypeDependence::Instantiation) & |
7332 | ~TypeDependence::UnexpandedPack), |
7333 | Pattern(Pattern) { |
7334 | PackExpansionTypeBits.NumExpansions = |
7335 | NumExpansions ? *NumExpansions + 1 : 0; |
7336 | } |
7337 | |
7338 | public: |
7339 | /// Retrieve the pattern of this pack expansion, which is the |
7340 | /// type that will be repeatedly instantiated when instantiating the |
7341 | /// pack expansion itself. |
7342 | QualType getPattern() const { return Pattern; } |
7343 | |
7344 | /// Retrieve the number of expansions that this pack expansion will |
7345 | /// generate, if known. |
7346 | UnsignedOrNone getNumExpansions() const { |
7347 | if (PackExpansionTypeBits.NumExpansions) |
7348 | return PackExpansionTypeBits.NumExpansions - 1; |
7349 | return std::nullopt; |
7350 | } |
7351 | |
7352 | bool isSugared() const { return false; } |
7353 | QualType desugar() const { return QualType(this, 0); } |
7354 | |
7355 | void Profile(llvm::FoldingSetNodeID &ID) { |
7356 | Profile(ID, Pattern: getPattern(), NumExpansions: getNumExpansions()); |
7357 | } |
7358 | |
7359 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern, |
7360 | UnsignedOrNone NumExpansions) { |
7361 | ID.AddPointer(Ptr: Pattern.getAsOpaquePtr()); |
7362 | ID.AddInteger(I: NumExpansions.toInternalRepresentation()); |
7363 | } |
7364 | |
7365 | static bool classof(const Type *T) { |
7366 | return T->getTypeClass() == PackExpansion; |
7367 | } |
7368 | }; |
7369 | |
7370 | /// This class wraps the list of protocol qualifiers. For types that can |
7371 | /// take ObjC protocol qualifers, they can subclass this class. |
7372 | template <class T> |
7373 | class ObjCProtocolQualifiers { |
7374 | protected: |
7375 | ObjCProtocolQualifiers() = default; |
7376 | |
7377 | ObjCProtocolDecl * const *getProtocolStorage() const { |
7378 | return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage(); |
7379 | } |
7380 | |
7381 | ObjCProtocolDecl **getProtocolStorage() { |
7382 | return static_cast<T*>(this)->getProtocolStorageImpl(); |
7383 | } |
7384 | |
7385 | void setNumProtocols(unsigned N) { |
7386 | static_cast<T*>(this)->setNumProtocolsImpl(N); |
7387 | } |
7388 | |
7389 | void initialize(ArrayRef<ObjCProtocolDecl *> protocols) { |
7390 | setNumProtocols(protocols.size()); |
7391 | assert(getNumProtocols() == protocols.size() && |
7392 | "bitfield overflow in protocol count" ); |
7393 | if (!protocols.empty()) |
7394 | memcpy(getProtocolStorage(), protocols.data(), |
7395 | protocols.size() * sizeof(ObjCProtocolDecl*)); |
7396 | } |
7397 | |
7398 | public: |
7399 | using qual_iterator = ObjCProtocolDecl * const *; |
7400 | using qual_range = llvm::iterator_range<qual_iterator>; |
7401 | |
7402 | qual_range quals() const { return qual_range(qual_begin(), qual_end()); } |
7403 | qual_iterator qual_begin() const { return getProtocolStorage(); } |
7404 | qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); } |
7405 | |
7406 | bool qual_empty() const { return getNumProtocols() == 0; } |
7407 | |
7408 | /// Return the number of qualifying protocols in this type, or 0 if |
7409 | /// there are none. |
7410 | unsigned getNumProtocols() const { |
7411 | return static_cast<const T*>(this)->getNumProtocolsImpl(); |
7412 | } |
7413 | |
7414 | /// Fetch a protocol by index. |
7415 | ObjCProtocolDecl *getProtocol(unsigned I) const { |
7416 | assert(I < getNumProtocols() && "Out-of-range protocol access" ); |
7417 | return qual_begin()[I]; |
7418 | } |
7419 | |
7420 | /// Retrieve all of the protocol qualifiers. |
7421 | ArrayRef<ObjCProtocolDecl *> getProtocols() const { |
7422 | return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols()); |
7423 | } |
7424 | }; |
7425 | |
7426 | /// Represents a type parameter type in Objective C. It can take |
7427 | /// a list of protocols. |
7428 | class ObjCTypeParamType : public Type, |
7429 | public ObjCProtocolQualifiers<ObjCTypeParamType>, |
7430 | public llvm::FoldingSetNode { |
7431 | friend class ASTContext; |
7432 | friend class ObjCProtocolQualifiers<ObjCTypeParamType>; |
7433 | |
7434 | /// The number of protocols stored on this type. |
7435 | unsigned NumProtocols : 6; |
7436 | |
7437 | ObjCTypeParamDecl *OTPDecl; |
7438 | |
7439 | /// The protocols are stored after the ObjCTypeParamType node. In the |
7440 | /// canonical type, the list of protocols are sorted alphabetically |
7441 | /// and uniqued. |
7442 | ObjCProtocolDecl **getProtocolStorageImpl(); |
7443 | |
7444 | /// Return the number of qualifying protocols in this interface type, |
7445 | /// or 0 if there are none. |
7446 | unsigned getNumProtocolsImpl() const { |
7447 | return NumProtocols; |
7448 | } |
7449 | |
7450 | void setNumProtocolsImpl(unsigned N) { |
7451 | NumProtocols = N; |
7452 | } |
7453 | |
7454 | ObjCTypeParamType(const ObjCTypeParamDecl *D, |
7455 | QualType can, |
7456 | ArrayRef<ObjCProtocolDecl *> protocols); |
7457 | |
7458 | public: |
7459 | bool isSugared() const { return true; } |
7460 | QualType desugar() const { return getCanonicalTypeInternal(); } |
7461 | |
7462 | static bool classof(const Type *T) { |
7463 | return T->getTypeClass() == ObjCTypeParam; |
7464 | } |
7465 | |
7466 | void Profile(llvm::FoldingSetNodeID &ID); |
7467 | static void Profile(llvm::FoldingSetNodeID &ID, |
7468 | const ObjCTypeParamDecl *OTPDecl, |
7469 | QualType CanonicalType, |
7470 | ArrayRef<ObjCProtocolDecl *> protocols); |
7471 | |
7472 | ObjCTypeParamDecl *getDecl() const { return OTPDecl; } |
7473 | }; |
7474 | |
7475 | /// Represents a class type in Objective C. |
7476 | /// |
7477 | /// Every Objective C type is a combination of a base type, a set of |
7478 | /// type arguments (optional, for parameterized classes) and a list of |
7479 | /// protocols. |
7480 | /// |
7481 | /// Given the following declarations: |
7482 | /// \code |
7483 | /// \@class C<T>; |
7484 | /// \@protocol P; |
7485 | /// \endcode |
7486 | /// |
7487 | /// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType |
7488 | /// with base C and no protocols. |
7489 | /// |
7490 | /// 'C<P>' is an unspecialized ObjCObjectType with base C and protocol list [P]. |
7491 | /// 'C<C*>' is a specialized ObjCObjectType with type arguments 'C*' and no |
7492 | /// protocol list. |
7493 | /// 'C<C*><P>' is a specialized ObjCObjectType with base C, type arguments 'C*', |
7494 | /// and protocol list [P]. |
7495 | /// |
7496 | /// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose |
7497 | /// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType |
7498 | /// and no protocols. |
7499 | /// |
7500 | /// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType |
7501 | /// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually |
7502 | /// this should get its own sugar class to better represent the source. |
7503 | class ObjCObjectType : public Type, |
7504 | public ObjCProtocolQualifiers<ObjCObjectType> { |
7505 | friend class ObjCProtocolQualifiers<ObjCObjectType>; |
7506 | |
7507 | // ObjCObjectType.NumTypeArgs - the number of type arguments stored |
7508 | // after the ObjCObjectPointerType node. |
7509 | // ObjCObjectType.NumProtocols - the number of protocols stored |
7510 | // after the type arguments of ObjCObjectPointerType node. |
7511 | // |
7512 | // These protocols are those written directly on the type. If |
7513 | // protocol qualifiers ever become additive, the iterators will need |
7514 | // to get kindof complicated. |
7515 | // |
7516 | // In the canonical object type, these are sorted alphabetically |
7517 | // and uniqued. |
7518 | |
7519 | /// Either a BuiltinType or an InterfaceType or sugar for either. |
7520 | QualType BaseType; |
7521 | |
7522 | /// Cached superclass type. |
7523 | mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool> |
7524 | CachedSuperClassType; |
7525 | |
7526 | QualType *getTypeArgStorage(); |
7527 | const QualType *getTypeArgStorage() const { |
7528 | return const_cast<ObjCObjectType *>(this)->getTypeArgStorage(); |
7529 | } |
7530 | |
7531 | ObjCProtocolDecl **getProtocolStorageImpl(); |
7532 | /// Return the number of qualifying protocols in this interface type, |
7533 | /// or 0 if there are none. |
7534 | unsigned getNumProtocolsImpl() const { |
7535 | return ObjCObjectTypeBits.NumProtocols; |
7536 | } |
7537 | void setNumProtocolsImpl(unsigned N) { |
7538 | ObjCObjectTypeBits.NumProtocols = N; |
7539 | } |
7540 | |
7541 | protected: |
7542 | enum Nonce_ObjCInterface { Nonce_ObjCInterface }; |
7543 | |
7544 | ObjCObjectType(QualType Canonical, QualType Base, |
7545 | ArrayRef<QualType> typeArgs, |
7546 | ArrayRef<ObjCProtocolDecl *> protocols, |
7547 | bool isKindOf); |
7548 | |
7549 | ObjCObjectType(enum Nonce_ObjCInterface) |
7550 | : Type(ObjCInterface, QualType(), TypeDependence::None), |
7551 | BaseType(QualType(this_(), 0)) { |
7552 | ObjCObjectTypeBits.NumProtocols = 0; |
7553 | ObjCObjectTypeBits.NumTypeArgs = 0; |
7554 | ObjCObjectTypeBits.IsKindOf = 0; |
7555 | } |
7556 | |
7557 | void computeSuperClassTypeSlow() const; |
7558 | |
7559 | public: |
7560 | /// Gets the base type of this object type. This is always (possibly |
7561 | /// sugar for) one of: |
7562 | /// - the 'id' builtin type (as opposed to the 'id' type visible to the |
7563 | /// user, which is a typedef for an ObjCObjectPointerType) |
7564 | /// - the 'Class' builtin type (same caveat) |
7565 | /// - an ObjCObjectType (currently always an ObjCInterfaceType) |
7566 | QualType getBaseType() const { return BaseType; } |
7567 | |
7568 | bool isObjCId() const { |
7569 | return getBaseType()->isSpecificBuiltinType(K: BuiltinType::ObjCId); |
7570 | } |
7571 | |
7572 | bool isObjCClass() const { |
7573 | return getBaseType()->isSpecificBuiltinType(K: BuiltinType::ObjCClass); |
7574 | } |
7575 | |
7576 | bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } |
7577 | bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } |
7578 | bool isObjCUnqualifiedIdOrClass() const { |
7579 | if (!qual_empty()) return false; |
7580 | if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>()) |
7581 | return T->getKind() == BuiltinType::ObjCId || |
7582 | T->getKind() == BuiltinType::ObjCClass; |
7583 | return false; |
7584 | } |
7585 | bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); } |
7586 | bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); } |
7587 | |
7588 | /// Gets the interface declaration for this object type, if the base type |
7589 | /// really is an interface. |
7590 | ObjCInterfaceDecl *getInterface() const; |
7591 | |
7592 | /// Determine whether this object type is "specialized", meaning |
7593 | /// that it has type arguments. |
7594 | bool isSpecialized() const; |
7595 | |
7596 | /// Determine whether this object type was written with type arguments. |
7597 | bool isSpecializedAsWritten() const { |
7598 | return ObjCObjectTypeBits.NumTypeArgs > 0; |
7599 | } |
7600 | |
7601 | /// Determine whether this object type is "unspecialized", meaning |
7602 | /// that it has no type arguments. |
7603 | bool isUnspecialized() const { return !isSpecialized(); } |
7604 | |
7605 | /// Determine whether this object type is "unspecialized" as |
7606 | /// written, meaning that it has no type arguments. |
7607 | bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } |
7608 | |
7609 | /// Retrieve the type arguments of this object type (semantically). |
7610 | ArrayRef<QualType> getTypeArgs() const; |
7611 | |
7612 | /// Retrieve the type arguments of this object type as they were |
7613 | /// written. |
7614 | ArrayRef<QualType> getTypeArgsAsWritten() const { |
7615 | return llvm::ArrayRef(getTypeArgStorage(), ObjCObjectTypeBits.NumTypeArgs); |
7616 | } |
7617 | |
7618 | /// Whether this is a "__kindof" type as written. |
7619 | bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; } |
7620 | |
7621 | /// Whether this ia a "__kindof" type (semantically). |
7622 | bool isKindOfType() const; |
7623 | |
7624 | /// Retrieve the type of the superclass of this object type. |
7625 | /// |
7626 | /// This operation substitutes any type arguments into the |
7627 | /// superclass of the current class type, potentially producing a |
7628 | /// specialization of the superclass type. Produces a null type if |
7629 | /// there is no superclass. |
7630 | QualType getSuperClassType() const { |
7631 | if (!CachedSuperClassType.getInt()) |
7632 | computeSuperClassTypeSlow(); |
7633 | |
7634 | assert(CachedSuperClassType.getInt() && "Superclass not set?" ); |
7635 | return QualType(CachedSuperClassType.getPointer(), 0); |
7636 | } |
7637 | |
7638 | /// Strip off the Objective-C "kindof" type and (with it) any |
7639 | /// protocol qualifiers. |
7640 | QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const; |
7641 | |
7642 | bool isSugared() const { return false; } |
7643 | QualType desugar() const { return QualType(this, 0); } |
7644 | |
7645 | static bool classof(const Type *T) { |
7646 | return T->getTypeClass() == ObjCObject || |
7647 | T->getTypeClass() == ObjCInterface; |
7648 | } |
7649 | }; |
7650 | |
7651 | /// A class providing a concrete implementation |
7652 | /// of ObjCObjectType, so as to not increase the footprint of |
7653 | /// ObjCInterfaceType. Code outside of ASTContext and the core type |
7654 | /// system should not reference this type. |
7655 | class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { |
7656 | friend class ASTContext; |
7657 | |
7658 | // If anyone adds fields here, ObjCObjectType::getProtocolStorage() |
7659 | // will need to be modified. |
7660 | |
7661 | ObjCObjectTypeImpl(QualType Canonical, QualType Base, |
7662 | ArrayRef<QualType> typeArgs, |
7663 | ArrayRef<ObjCProtocolDecl *> protocols, |
7664 | bool isKindOf) |
7665 | : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {} |
7666 | |
7667 | public: |
7668 | void Profile(llvm::FoldingSetNodeID &ID); |
7669 | static void Profile(llvm::FoldingSetNodeID &ID, |
7670 | QualType Base, |
7671 | ArrayRef<QualType> typeArgs, |
7672 | ArrayRef<ObjCProtocolDecl *> protocols, |
7673 | bool isKindOf); |
7674 | }; |
7675 | |
7676 | inline QualType *ObjCObjectType::getTypeArgStorage() { |
7677 | return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1); |
7678 | } |
7679 | |
7680 | inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() { |
7681 | return reinterpret_cast<ObjCProtocolDecl**>( |
7682 | getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs); |
7683 | } |
7684 | |
7685 | inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() { |
7686 | return reinterpret_cast<ObjCProtocolDecl**>( |
7687 | static_cast<ObjCTypeParamType*>(this)+1); |
7688 | } |
7689 | |
7690 | /// Interfaces are the core concept in Objective-C for object oriented design. |
7691 | /// They basically correspond to C++ classes. There are two kinds of interface |
7692 | /// types: normal interfaces like `NSString`, and qualified interfaces, which |
7693 | /// are qualified with a protocol list like `NSString<NSCopyable, NSAmazing>`. |
7694 | /// |
7695 | /// ObjCInterfaceType guarantees the following properties when considered |
7696 | /// as a subtype of its superclass, ObjCObjectType: |
7697 | /// - There are no protocol qualifiers. To reinforce this, code which |
7698 | /// tries to invoke the protocol methods via an ObjCInterfaceType will |
7699 | /// fail to compile. |
7700 | /// - It is its own base type. That is, if T is an ObjCInterfaceType*, |
7701 | /// T->getBaseType() == QualType(T, 0). |
7702 | class ObjCInterfaceType : public ObjCObjectType { |
7703 | friend class ASTContext; // ASTContext creates these. |
7704 | friend class ASTReader; |
7705 | template <class T> friend class serialization::AbstractTypeReader; |
7706 | |
7707 | ObjCInterfaceDecl *Decl; |
7708 | |
7709 | ObjCInterfaceType(const ObjCInterfaceDecl *D) |
7710 | : ObjCObjectType(Nonce_ObjCInterface), |
7711 | Decl(const_cast<ObjCInterfaceDecl*>(D)) {} |
7712 | |
7713 | public: |
7714 | /// Get the declaration of this interface. |
7715 | ObjCInterfaceDecl *getDecl() const; |
7716 | |
7717 | bool isSugared() const { return false; } |
7718 | QualType desugar() const { return QualType(this, 0); } |
7719 | |
7720 | static bool classof(const Type *T) { |
7721 | return T->getTypeClass() == ObjCInterface; |
7722 | } |
7723 | |
7724 | // Nonsense to "hide" certain members of ObjCObjectType within this |
7725 | // class. People asking for protocols on an ObjCInterfaceType are |
7726 | // not going to get what they want: ObjCInterfaceTypes are |
7727 | // guaranteed to have no protocols. |
7728 | enum { |
7729 | qual_iterator, |
7730 | qual_begin, |
7731 | qual_end, |
7732 | getNumProtocols, |
7733 | getProtocol |
7734 | }; |
7735 | }; |
7736 | |
7737 | inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { |
7738 | QualType baseType = getBaseType(); |
7739 | while (const auto *ObjT = baseType->getAs<ObjCObjectType>()) { |
7740 | if (const auto *T = dyn_cast<ObjCInterfaceType>(ObjT)) |
7741 | return T->getDecl(); |
7742 | |
7743 | baseType = ObjT->getBaseType(); |
7744 | } |
7745 | |
7746 | return nullptr; |
7747 | } |
7748 | |
7749 | /// Represents a pointer to an Objective C object. |
7750 | /// |
7751 | /// These are constructed from pointer declarators when the pointee type is |
7752 | /// an ObjCObjectType (or sugar for one). In addition, the 'id' and 'Class' |
7753 | /// types are typedefs for these, and the protocol-qualified types 'id<P>' |
7754 | /// and 'Class<P>' are translated into these. |
7755 | /// |
7756 | /// Pointers to pointers to Objective C objects are still PointerTypes; |
7757 | /// only the first level of pointer gets it own type implementation. |
7758 | class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { |
7759 | friend class ASTContext; // ASTContext creates these. |
7760 | |
7761 | QualType PointeeType; |
7762 | |
7763 | ObjCObjectPointerType(QualType Canonical, QualType Pointee) |
7764 | : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()), |
7765 | PointeeType(Pointee) {} |
7766 | |
7767 | public: |
7768 | /// Gets the type pointed to by this ObjC pointer. |
7769 | /// The result will always be an ObjCObjectType or sugar thereof. |
7770 | QualType getPointeeType() const { return PointeeType; } |
7771 | |
7772 | /// Gets the type pointed to by this ObjC pointer. Always returns non-null. |
7773 | /// |
7774 | /// This method is equivalent to getPointeeType() except that |
7775 | /// it discards any typedefs (or other sugar) between this |
7776 | /// type and the "outermost" object type. So for: |
7777 | /// \code |
7778 | /// \@class A; \@protocol P; \@protocol Q; |
7779 | /// typedef A<P> AP; |
7780 | /// typedef A A1; |
7781 | /// typedef A1<P> A1P; |
7782 | /// typedef A1P<Q> A1PQ; |
7783 | /// \endcode |
7784 | /// For 'A*', getObjectType() will return 'A'. |
7785 | /// For 'A<P>*', getObjectType() will return 'A<P>'. |
7786 | /// For 'AP*', getObjectType() will return 'A<P>'. |
7787 | /// For 'A1*', getObjectType() will return 'A'. |
7788 | /// For 'A1<P>*', getObjectType() will return 'A1<P>'. |
7789 | /// For 'A1P*', getObjectType() will return 'A1<P>'. |
7790 | /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because |
7791 | /// adding protocols to a protocol-qualified base discards the |
7792 | /// old qualifiers (for now). But if it didn't, getObjectType() |
7793 | /// would return 'A1P<Q>' (and we'd have to make iterating over |
7794 | /// qualifiers more complicated). |
7795 | const ObjCObjectType *getObjectType() const { |
7796 | return PointeeType->castAs<ObjCObjectType>(); |
7797 | } |
7798 | |
7799 | /// If this pointer points to an Objective C |
7800 | /// \@interface type, gets the type for that interface. Any protocol |
7801 | /// qualifiers on the interface are ignored. |
7802 | /// |
7803 | /// \return null if the base type for this pointer is 'id' or 'Class' |
7804 | const ObjCInterfaceType *getInterfaceType() const; |
7805 | |
7806 | /// If this pointer points to an Objective \@interface |
7807 | /// type, gets the declaration for that interface. |
7808 | /// |
7809 | /// \return null if the base type for this pointer is 'id' or 'Class' |
7810 | ObjCInterfaceDecl *getInterfaceDecl() const { |
7811 | return getObjectType()->getInterface(); |
7812 | } |
7813 | |
7814 | /// True if this is equivalent to the 'id' type, i.e. if |
7815 | /// its object type is the primitive 'id' type with no protocols. |
7816 | bool isObjCIdType() const { |
7817 | return getObjectType()->isObjCUnqualifiedId(); |
7818 | } |
7819 | |
7820 | /// True if this is equivalent to the 'Class' type, |
7821 | /// i.e. if its object tive is the primitive 'Class' type with no protocols. |
7822 | bool isObjCClassType() const { |
7823 | return getObjectType()->isObjCUnqualifiedClass(); |
7824 | } |
7825 | |
7826 | /// True if this is equivalent to the 'id' or 'Class' type, |
7827 | bool isObjCIdOrClassType() const { |
7828 | return getObjectType()->isObjCUnqualifiedIdOrClass(); |
7829 | } |
7830 | |
7831 | /// True if this is equivalent to 'id<P>' for some non-empty set of |
7832 | /// protocols. |
7833 | bool isObjCQualifiedIdType() const { |
7834 | return getObjectType()->isObjCQualifiedId(); |
7835 | } |
7836 | |
7837 | /// True if this is equivalent to 'Class<P>' for some non-empty set of |
7838 | /// protocols. |
7839 | bool isObjCQualifiedClassType() const { |
7840 | return getObjectType()->isObjCQualifiedClass(); |
7841 | } |
7842 | |
7843 | /// Whether this is a "__kindof" type. |
7844 | bool isKindOfType() const { return getObjectType()->isKindOfType(); } |
7845 | |
7846 | /// Whether this type is specialized, meaning that it has type arguments. |
7847 | bool isSpecialized() const { return getObjectType()->isSpecialized(); } |
7848 | |
7849 | /// Whether this type is specialized, meaning that it has type arguments. |
7850 | bool isSpecializedAsWritten() const { |
7851 | return getObjectType()->isSpecializedAsWritten(); |
7852 | } |
7853 | |
7854 | /// Whether this type is unspecialized, meaning that is has no type arguments. |
7855 | bool isUnspecialized() const { return getObjectType()->isUnspecialized(); } |
7856 | |
7857 | /// Determine whether this object type is "unspecialized" as |
7858 | /// written, meaning that it has no type arguments. |
7859 | bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } |
7860 | |
7861 | /// Retrieve the type arguments for this type. |
7862 | ArrayRef<QualType> getTypeArgs() const { |
7863 | return getObjectType()->getTypeArgs(); |
7864 | } |
7865 | |
7866 | /// Retrieve the type arguments for this type. |
7867 | ArrayRef<QualType> getTypeArgsAsWritten() const { |
7868 | return getObjectType()->getTypeArgsAsWritten(); |
7869 | } |
7870 | |
7871 | /// An iterator over the qualifiers on the object type. Provided |
7872 | /// for convenience. This will always iterate over the full set of |
7873 | /// protocols on a type, not just those provided directly. |
7874 | using qual_iterator = ObjCObjectType::qual_iterator; |
7875 | using qual_range = llvm::iterator_range<qual_iterator>; |
7876 | |
7877 | qual_range quals() const { return qual_range(qual_begin(), qual_end()); } |
7878 | |
7879 | qual_iterator qual_begin() const { |
7880 | return getObjectType()->qual_begin(); |
7881 | } |
7882 | |
7883 | qual_iterator qual_end() const { |
7884 | return getObjectType()->qual_end(); |
7885 | } |
7886 | |
7887 | bool qual_empty() const { return getObjectType()->qual_empty(); } |
7888 | |
7889 | /// Return the number of qualifying protocols on the object type. |
7890 | unsigned getNumProtocols() const { |
7891 | return getObjectType()->getNumProtocols(); |
7892 | } |
7893 | |
7894 | /// Retrieve a qualifying protocol by index on the object type. |
7895 | ObjCProtocolDecl *getProtocol(unsigned I) const { |
7896 | return getObjectType()->getProtocol(I); |
7897 | } |
7898 | |
7899 | bool isSugared() const { return false; } |
7900 | QualType desugar() const { return QualType(this, 0); } |
7901 | |
7902 | /// Retrieve the type of the superclass of this object pointer type. |
7903 | /// |
7904 | /// This operation substitutes any type arguments into the |
7905 | /// superclass of the current class type, potentially producing a |
7906 | /// pointer to a specialization of the superclass type. Produces a |
7907 | /// null type if there is no superclass. |
7908 | QualType getSuperClassType() const; |
7909 | |
7910 | /// Strip off the Objective-C "kindof" type and (with it) any |
7911 | /// protocol qualifiers. |
7912 | const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals( |
7913 | const ASTContext &ctx) const; |
7914 | |
7915 | void Profile(llvm::FoldingSetNodeID &ID) { |
7916 | Profile(ID, T: getPointeeType()); |
7917 | } |
7918 | |
7919 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { |
7920 | ID.AddPointer(Ptr: T.getAsOpaquePtr()); |
7921 | } |
7922 | |
7923 | static bool classof(const Type *T) { |
7924 | return T->getTypeClass() == ObjCObjectPointer; |
7925 | } |
7926 | }; |
7927 | |
7928 | class AtomicType : public Type, public llvm::FoldingSetNode { |
7929 | friend class ASTContext; // ASTContext creates these. |
7930 | |
7931 | QualType ValueType; |
7932 | |
7933 | AtomicType(QualType ValTy, QualType Canonical) |
7934 | : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {} |
7935 | |
7936 | public: |
7937 | /// Gets the type contained by this atomic type, i.e. |
7938 | /// the type returned by performing an atomic load of this atomic type. |
7939 | QualType getValueType() const { return ValueType; } |
7940 | |
7941 | bool isSugared() const { return false; } |
7942 | QualType desugar() const { return QualType(this, 0); } |
7943 | |
7944 | void Profile(llvm::FoldingSetNodeID &ID) { |
7945 | Profile(ID, T: getValueType()); |
7946 | } |
7947 | |
7948 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { |
7949 | ID.AddPointer(Ptr: T.getAsOpaquePtr()); |
7950 | } |
7951 | |
7952 | static bool classof(const Type *T) { |
7953 | return T->getTypeClass() == Atomic; |
7954 | } |
7955 | }; |
7956 | |
7957 | /// PipeType - OpenCL20. |
7958 | class PipeType : public Type, public llvm::FoldingSetNode { |
7959 | friend class ASTContext; // ASTContext creates these. |
7960 | |
7961 | QualType ElementType; |
7962 | bool isRead; |
7963 | |
7964 | PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) |
7965 | : Type(Pipe, CanonicalPtr, elemType->getDependence()), |
7966 | ElementType(elemType), isRead(isRead) {} |
7967 | |
7968 | public: |
7969 | QualType getElementType() const { return ElementType; } |
7970 | |
7971 | bool isSugared() const { return false; } |
7972 | |
7973 | QualType desugar() const { return QualType(this, 0); } |
7974 | |
7975 | void Profile(llvm::FoldingSetNodeID &ID) { |
7976 | Profile(ID, T: getElementType(), isRead: isReadOnly()); |
7977 | } |
7978 | |
7979 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T, bool isRead) { |
7980 | ID.AddPointer(Ptr: T.getAsOpaquePtr()); |
7981 | ID.AddBoolean(B: isRead); |
7982 | } |
7983 | |
7984 | static bool classof(const Type *T) { |
7985 | return T->getTypeClass() == Pipe; |
7986 | } |
7987 | |
7988 | bool isReadOnly() const { return isRead; } |
7989 | }; |
7990 | |
7991 | /// A fixed int type of a specified bitwidth. |
7992 | class BitIntType final : public Type, public llvm::FoldingSetNode { |
7993 | friend class ASTContext; |
7994 | LLVM_PREFERRED_TYPE(bool) |
7995 | unsigned IsUnsigned : 1; |
7996 | unsigned NumBits : 24; |
7997 | |
7998 | protected: |
7999 | BitIntType(bool isUnsigned, unsigned NumBits); |
8000 | |
8001 | public: |
8002 | bool isUnsigned() const { return IsUnsigned; } |
8003 | bool isSigned() const { return !IsUnsigned; } |
8004 | unsigned getNumBits() const { return NumBits; } |
8005 | |
8006 | bool isSugared() const { return false; } |
8007 | QualType desugar() const { return QualType(this, 0); } |
8008 | |
8009 | void Profile(llvm::FoldingSetNodeID &ID) const { |
8010 | Profile(ID, IsUnsigned: isUnsigned(), NumBits: getNumBits()); |
8011 | } |
8012 | |
8013 | static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned, |
8014 | unsigned NumBits) { |
8015 | ID.AddBoolean(B: IsUnsigned); |
8016 | ID.AddInteger(I: NumBits); |
8017 | } |
8018 | |
8019 | static bool classof(const Type *T) { return T->getTypeClass() == BitInt; } |
8020 | }; |
8021 | |
8022 | class DependentBitIntType final : public Type, public llvm::FoldingSetNode { |
8023 | friend class ASTContext; |
8024 | llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned; |
8025 | |
8026 | protected: |
8027 | DependentBitIntType(bool IsUnsigned, Expr *NumBits); |
8028 | |
8029 | public: |
8030 | bool isUnsigned() const; |
8031 | bool isSigned() const { return !isUnsigned(); } |
8032 | Expr *getNumBitsExpr() const; |
8033 | |
8034 | bool isSugared() const { return false; } |
8035 | QualType desugar() const { return QualType(this, 0); } |
8036 | |
8037 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { |
8038 | Profile(ID, Context, IsUnsigned: isUnsigned(), NumBitsExpr: getNumBitsExpr()); |
8039 | } |
8040 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, |
8041 | bool IsUnsigned, Expr *NumBitsExpr); |
8042 | |
8043 | static bool classof(const Type *T) { |
8044 | return T->getTypeClass() == DependentBitInt; |
8045 | } |
8046 | }; |
8047 | |
8048 | /// A qualifier set is used to build a set of qualifiers. |
8049 | class QualifierCollector : public Qualifiers { |
8050 | public: |
8051 | QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {} |
8052 | |
8053 | /// Collect any qualifiers on the given type and return an |
8054 | /// unqualified type. The qualifiers are assumed to be consistent |
8055 | /// with those already in the type. |
8056 | const Type *strip(QualType type) { |
8057 | addFastQualifiers(mask: type.getLocalFastQualifiers()); |
8058 | if (!type.hasLocalNonFastQualifiers()) |
8059 | return type.getTypePtrUnsafe(); |
8060 | |
8061 | const ExtQuals *extQuals = type.getExtQualsUnsafe(); |
8062 | addConsistentQualifiers(qs: extQuals->getQualifiers()); |
8063 | return extQuals->getBaseType(); |
8064 | } |
8065 | |
8066 | /// Apply the collected qualifiers to the given type. |
8067 | QualType apply(const ASTContext &Context, QualType QT) const; |
8068 | |
8069 | /// Apply the collected qualifiers to the given type. |
8070 | QualType apply(const ASTContext &Context, const Type* T) const; |
8071 | }; |
8072 | |
8073 | /// A container of type source information. |
8074 | /// |
8075 | /// A client can read the relevant info using TypeLoc wrappers, e.g: |
8076 | /// @code |
8077 | /// TypeLoc TL = TypeSourceInfo->getTypeLoc(); |
8078 | /// TL.getBeginLoc().print(OS, SrcMgr); |
8079 | /// @endcode |
8080 | class alignas(8) TypeSourceInfo { |
8081 | // Contains a memory block after the class, used for type source information, |
8082 | // allocated by ASTContext. |
8083 | friend class ASTContext; |
8084 | |
8085 | QualType Ty; |
8086 | |
8087 | TypeSourceInfo(QualType ty, size_t DataSize); // implemented in TypeLoc.h |
8088 | |
8089 | public: |
8090 | /// Return the type wrapped by this type source info. |
8091 | QualType getType() const { return Ty; } |
8092 | |
8093 | /// Return the TypeLoc wrapper for the type source info. |
8094 | TypeLoc getTypeLoc() const; // implemented in TypeLoc.h |
8095 | |
8096 | /// Override the type stored in this TypeSourceInfo. Use with caution! |
8097 | void overrideType(QualType T) { Ty = T; } |
8098 | }; |
8099 | |
8100 | // Inline function definitions. |
8101 | |
8102 | inline SplitQualType SplitQualType::getSingleStepDesugaredType() const { |
8103 | SplitQualType desugar = |
8104 | Ty->getLocallyUnqualifiedSingleStepDesugaredType().split(); |
8105 | desugar.Quals.addConsistentQualifiers(qs: Quals); |
8106 | return desugar; |
8107 | } |
8108 | |
8109 | inline const Type *QualType::getTypePtr() const { |
8110 | return getCommonPtr()->BaseType; |
8111 | } |
8112 | |
8113 | inline const Type *QualType::getTypePtrOrNull() const { |
8114 | return (isNull() ? nullptr : getCommonPtr()->BaseType); |
8115 | } |
8116 | |
8117 | inline bool QualType::isReferenceable() const { |
8118 | // C++ [defns.referenceable] |
8119 | // type that is either an object type, a function type that does not have |
8120 | // cv-qualifiers or a ref-qualifier, or a reference type. |
8121 | const Type &Self = **this; |
8122 | if (Self.isObjectType() || Self.isReferenceType()) |
8123 | return true; |
8124 | if (const auto *F = Self.getAs<FunctionProtoType>()) |
8125 | return F->getMethodQuals().empty() && F->getRefQualifier() == RQ_None; |
8126 | |
8127 | return false; |
8128 | } |
8129 | |
8130 | inline SplitQualType QualType::split() const { |
8131 | if (!hasLocalNonFastQualifiers()) |
8132 | return SplitQualType(getTypePtrUnsafe(), |
8133 | Qualifiers::fromFastMask(Mask: getLocalFastQualifiers())); |
8134 | |
8135 | const ExtQuals *eq = getExtQualsUnsafe(); |
8136 | Qualifiers qs = eq->getQualifiers(); |
8137 | qs.addFastQualifiers(mask: getLocalFastQualifiers()); |
8138 | return SplitQualType(eq->getBaseType(), qs); |
8139 | } |
8140 | |
8141 | inline Qualifiers QualType::getLocalQualifiers() const { |
8142 | Qualifiers Quals; |
8143 | if (hasLocalNonFastQualifiers()) |
8144 | Quals = getExtQualsUnsafe()->getQualifiers(); |
8145 | Quals.addFastQualifiers(mask: getLocalFastQualifiers()); |
8146 | return Quals; |
8147 | } |
8148 | |
8149 | inline Qualifiers QualType::getQualifiers() const { |
8150 | Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers(); |
8151 | quals.addFastQualifiers(mask: getLocalFastQualifiers()); |
8152 | return quals; |
8153 | } |
8154 | |
8155 | inline unsigned QualType::getCVRQualifiers() const { |
8156 | unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers(); |
8157 | cvr |= getLocalCVRQualifiers(); |
8158 | return cvr; |
8159 | } |
8160 | |
8161 | inline QualType QualType::getCanonicalType() const { |
8162 | QualType canon = getCommonPtr()->CanonicalType; |
8163 | return canon.withFastQualifiers(TQs: getLocalFastQualifiers()); |
8164 | } |
8165 | |
8166 | inline bool QualType::isCanonical() const { |
8167 | return getTypePtr()->isCanonicalUnqualified(); |
8168 | } |
8169 | |
8170 | inline bool QualType::isCanonicalAsParam() const { |
8171 | if (!isCanonical()) return false; |
8172 | if (hasLocalQualifiers()) return false; |
8173 | |
8174 | const Type *T = getTypePtr(); |
8175 | if (T->isVariablyModifiedType() && T->hasSizedVLAType()) |
8176 | return false; |
8177 | |
8178 | return !isa<FunctionType>(T) && |
8179 | (!isa<ArrayType>(T) || isa<ArrayParameterType>(T)); |
8180 | } |
8181 | |
8182 | inline bool QualType::isConstQualified() const { |
8183 | return isLocalConstQualified() || |
8184 | getCommonPtr()->CanonicalType.isLocalConstQualified(); |
8185 | } |
8186 | |
8187 | inline bool QualType::isRestrictQualified() const { |
8188 | return isLocalRestrictQualified() || |
8189 | getCommonPtr()->CanonicalType.isLocalRestrictQualified(); |
8190 | } |
8191 | |
8192 | |
8193 | inline bool QualType::isVolatileQualified() const { |
8194 | return isLocalVolatileQualified() || |
8195 | getCommonPtr()->CanonicalType.isLocalVolatileQualified(); |
8196 | } |
8197 | |
8198 | inline bool QualType::hasQualifiers() const { |
8199 | return hasLocalQualifiers() || |
8200 | getCommonPtr()->CanonicalType.hasLocalQualifiers(); |
8201 | } |
8202 | |
8203 | inline QualType QualType::getUnqualifiedType() const { |
8204 | if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) |
8205 | return QualType(getTypePtr(), 0); |
8206 | |
8207 | return QualType(getSplitUnqualifiedTypeImpl(type: *this).Ty, 0); |
8208 | } |
8209 | |
8210 | inline SplitQualType QualType::getSplitUnqualifiedType() const { |
8211 | if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) |
8212 | return split(); |
8213 | |
8214 | return getSplitUnqualifiedTypeImpl(type: *this); |
8215 | } |
8216 | |
8217 | inline void QualType::removeLocalConst() { |
8218 | removeLocalFastQualifiers(Mask: Qualifiers::Const); |
8219 | } |
8220 | |
8221 | inline void QualType::removeLocalRestrict() { |
8222 | removeLocalFastQualifiers(Mask: Qualifiers::Restrict); |
8223 | } |
8224 | |
8225 | inline void QualType::removeLocalVolatile() { |
8226 | removeLocalFastQualifiers(Mask: Qualifiers::Volatile); |
8227 | } |
8228 | |
8229 | /// Check if this type has any address space qualifier. |
8230 | inline bool QualType::hasAddressSpace() const { |
8231 | return getQualifiers().hasAddressSpace(); |
8232 | } |
8233 | |
8234 | /// Return the address space of this type. |
8235 | inline LangAS QualType::getAddressSpace() const { |
8236 | return getQualifiers().getAddressSpace(); |
8237 | } |
8238 | |
8239 | /// Return the gc attribute of this type. |
8240 | inline Qualifiers::GC QualType::getObjCGCAttr() const { |
8241 | return getQualifiers().getObjCGCAttr(); |
8242 | } |
8243 | |
8244 | inline bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion() const { |
8245 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) |
8246 | return hasNonTrivialToPrimitiveDefaultInitializeCUnion(RD); |
8247 | return false; |
8248 | } |
8249 | |
8250 | inline bool QualType::hasNonTrivialToPrimitiveDestructCUnion() const { |
8251 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) |
8252 | return hasNonTrivialToPrimitiveDestructCUnion(RD); |
8253 | return false; |
8254 | } |
8255 | |
8256 | inline bool QualType::hasNonTrivialToPrimitiveCopyCUnion() const { |
8257 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) |
8258 | return hasNonTrivialToPrimitiveCopyCUnion(RD); |
8259 | return false; |
8260 | } |
8261 | |
8262 | inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { |
8263 | if (const auto *PT = t.getAs<PointerType>()) { |
8264 | if (const auto *FT = PT->getPointeeType()->getAs<FunctionType>()) |
8265 | return FT->getExtInfo(); |
8266 | } else if (const auto *FT = t.getAs<FunctionType>()) |
8267 | return FT->getExtInfo(); |
8268 | |
8269 | return FunctionType::ExtInfo(); |
8270 | } |
8271 | |
8272 | inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { |
8273 | return getFunctionExtInfo(t: *t); |
8274 | } |
8275 | |
8276 | /// Determine whether this type is more |
8277 | /// qualified than the Other type. For example, "const volatile int" |
8278 | /// is more qualified than "const int", "volatile int", and |
8279 | /// "int". However, it is not more qualified than "const volatile |
8280 | /// int". |
8281 | inline bool QualType::isMoreQualifiedThan(QualType other, |
8282 | const ASTContext &Ctx) const { |
8283 | Qualifiers MyQuals = getQualifiers(); |
8284 | Qualifiers OtherQuals = other.getQualifiers(); |
8285 | return (MyQuals != OtherQuals && MyQuals.compatiblyIncludes(other: OtherQuals, Ctx)); |
8286 | } |
8287 | |
8288 | /// Determine whether this type is at last |
8289 | /// as qualified as the Other type. For example, "const volatile |
8290 | /// int" is at least as qualified as "const int", "volatile int", |
8291 | /// "int", and "const volatile int". |
8292 | inline bool QualType::isAtLeastAsQualifiedAs(QualType other, |
8293 | const ASTContext &Ctx) const { |
8294 | Qualifiers OtherQuals = other.getQualifiers(); |
8295 | |
8296 | // Ignore __unaligned qualifier if this type is a void. |
8297 | if (getUnqualifiedType()->isVoidType()) |
8298 | OtherQuals.removeUnaligned(); |
8299 | |
8300 | return getQualifiers().compatiblyIncludes(other: OtherQuals, Ctx); |
8301 | } |
8302 | |
8303 | /// If Type is a reference type (e.g., const |
8304 | /// int&), returns the type that the reference refers to ("const |
8305 | /// int"). Otherwise, returns the type itself. This routine is used |
8306 | /// throughout Sema to implement C++ 5p6: |
8307 | /// |
8308 | /// If an expression initially has the type "reference to T" (8.3.2, |
8309 | /// 8.5.3), the type is adjusted to "T" prior to any further |
8310 | /// analysis, the expression designates the object or function |
8311 | /// denoted by the reference, and the expression is an lvalue. |
8312 | inline QualType QualType::getNonReferenceType() const { |
8313 | if (const auto *RefType = (*this)->getAs<ReferenceType>()) |
8314 | return RefType->getPointeeType(); |
8315 | else |
8316 | return *this; |
8317 | } |
8318 | |
8319 | inline bool QualType::isCForbiddenLValueType() const { |
8320 | return ((getTypePtr()->isVoidType() && !hasQualifiers()) || |
8321 | getTypePtr()->isFunctionType()); |
8322 | } |
8323 | |
8324 | /// Tests whether the type is categorized as a fundamental type. |
8325 | /// |
8326 | /// \returns True for types specified in C++0x [basic.fundamental]. |
8327 | inline bool Type::isFundamentalType() const { |
8328 | return isVoidType() || |
8329 | isNullPtrType() || |
8330 | // FIXME: It's really annoying that we don't have an |
8331 | // 'isArithmeticType()' which agrees with the standard definition. |
8332 | (isArithmeticType() && !isEnumeralType()); |
8333 | } |
8334 | |
8335 | /// Tests whether the type is categorized as a compound type. |
8336 | /// |
8337 | /// \returns True for types specified in C++0x [basic.compound]. |
8338 | inline bool Type::isCompoundType() const { |
8339 | // C++0x [basic.compound]p1: |
8340 | // Compound types can be constructed in the following ways: |
8341 | // -- arrays of objects of a given type [...]; |
8342 | return isArrayType() || |
8343 | // -- functions, which have parameters of given types [...]; |
8344 | isFunctionType() || |
8345 | // -- pointers to void or objects or functions [...]; |
8346 | isPointerType() || |
8347 | // -- references to objects or functions of a given type. [...] |
8348 | isReferenceType() || |
8349 | // -- classes containing a sequence of objects of various types, [...]; |
8350 | isRecordType() || |
8351 | // -- unions, which are classes capable of containing objects of different |
8352 | // types at different times; |
8353 | isUnionType() || |
8354 | // -- enumerations, which comprise a set of named constant values. [...]; |
8355 | isEnumeralType() || |
8356 | // -- pointers to non-static class members, [...]. |
8357 | isMemberPointerType(); |
8358 | } |
8359 | |
8360 | inline bool Type::isFunctionType() const { |
8361 | return isa<FunctionType>(CanonicalType); |
8362 | } |
8363 | |
8364 | inline bool Type::isPointerType() const { |
8365 | return isa<PointerType>(CanonicalType); |
8366 | } |
8367 | |
8368 | inline bool Type::isPointerOrReferenceType() const { |
8369 | return isPointerType() || isReferenceType(); |
8370 | } |
8371 | |
8372 | inline bool Type::isAnyPointerType() const { |
8373 | return isPointerType() || isObjCObjectPointerType(); |
8374 | } |
8375 | |
8376 | inline bool Type::isSignableType(const ASTContext &Ctx) const { |
8377 | return isSignablePointerType() || isSignableIntegerType(Ctx); |
8378 | } |
8379 | |
8380 | inline bool Type::isSignablePointerType() const { |
8381 | return isPointerType() || isObjCClassType() || isObjCQualifiedClassType(); |
8382 | } |
8383 | |
8384 | inline bool Type::isBlockPointerType() const { |
8385 | return isa<BlockPointerType>(CanonicalType); |
8386 | } |
8387 | |
8388 | inline bool Type::isReferenceType() const { |
8389 | return isa<ReferenceType>(CanonicalType); |
8390 | } |
8391 | |
8392 | inline bool Type::isLValueReferenceType() const { |
8393 | return isa<LValueReferenceType>(CanonicalType); |
8394 | } |
8395 | |
8396 | inline bool Type::isRValueReferenceType() const { |
8397 | return isa<RValueReferenceType>(CanonicalType); |
8398 | } |
8399 | |
8400 | inline bool Type::isObjectPointerType() const { |
8401 | // Note: an "object pointer type" is not the same thing as a pointer to an |
8402 | // object type; rather, it is a pointer to an object type or a pointer to cv |
8403 | // void. |
8404 | if (const auto *T = getAs<PointerType>()) |
8405 | return !T->getPointeeType()->isFunctionType(); |
8406 | else |
8407 | return false; |
8408 | } |
8409 | |
8410 | inline bool Type::isCFIUncheckedCalleeFunctionType() const { |
8411 | if (const auto *Fn = getAs<FunctionProtoType>()) |
8412 | return Fn->hasCFIUncheckedCallee(); |
8413 | return false; |
8414 | } |
8415 | |
8416 | inline bool Type::hasPointeeToToCFIUncheckedCalleeFunctionType() const { |
8417 | QualType Pointee; |
8418 | if (const auto *PT = getAs<PointerType>()) |
8419 | Pointee = PT->getPointeeType(); |
8420 | else if (const auto *RT = getAs<ReferenceType>()) |
8421 | Pointee = RT->getPointeeType(); |
8422 | else if (const auto *MPT = getAs<MemberPointerType>()) |
8423 | Pointee = MPT->getPointeeType(); |
8424 | else if (const auto *DT = getAs<DecayedType>()) |
8425 | Pointee = DT->getPointeeType(); |
8426 | else |
8427 | return false; |
8428 | return Pointee->isCFIUncheckedCalleeFunctionType(); |
8429 | } |
8430 | |
8431 | inline bool Type::isFunctionPointerType() const { |
8432 | if (const auto *T = getAs<PointerType>()) |
8433 | return T->getPointeeType()->isFunctionType(); |
8434 | else |
8435 | return false; |
8436 | } |
8437 | |
8438 | inline bool Type::isFunctionReferenceType() const { |
8439 | if (const auto *T = getAs<ReferenceType>()) |
8440 | return T->getPointeeType()->isFunctionType(); |
8441 | else |
8442 | return false; |
8443 | } |
8444 | |
8445 | inline bool Type::isMemberPointerType() const { |
8446 | return isa<MemberPointerType>(CanonicalType); |
8447 | } |
8448 | |
8449 | inline bool Type::isMemberFunctionPointerType() const { |
8450 | if (const auto *T = getAs<MemberPointerType>()) |
8451 | return T->isMemberFunctionPointer(); |
8452 | else |
8453 | return false; |
8454 | } |
8455 | |
8456 | inline bool Type::isMemberDataPointerType() const { |
8457 | if (const auto *T = getAs<MemberPointerType>()) |
8458 | return T->isMemberDataPointer(); |
8459 | else |
8460 | return false; |
8461 | } |
8462 | |
8463 | inline bool Type::isArrayType() const { |
8464 | return isa<ArrayType>(CanonicalType); |
8465 | } |
8466 | |
8467 | inline bool Type::isConstantArrayType() const { |
8468 | return isa<ConstantArrayType>(CanonicalType); |
8469 | } |
8470 | |
8471 | inline bool Type::isIncompleteArrayType() const { |
8472 | return isa<IncompleteArrayType>(CanonicalType); |
8473 | } |
8474 | |
8475 | inline bool Type::isVariableArrayType() const { |
8476 | return isa<VariableArrayType>(CanonicalType); |
8477 | } |
8478 | |
8479 | inline bool Type::isArrayParameterType() const { |
8480 | return isa<ArrayParameterType>(CanonicalType); |
8481 | } |
8482 | |
8483 | inline bool Type::isDependentSizedArrayType() const { |
8484 | return isa<DependentSizedArrayType>(CanonicalType); |
8485 | } |
8486 | |
8487 | inline bool Type::isBuiltinType() const { |
8488 | return isa<BuiltinType>(CanonicalType); |
8489 | } |
8490 | |
8491 | inline bool Type::isRecordType() const { |
8492 | return isa<RecordType>(CanonicalType); |
8493 | } |
8494 | |
8495 | inline bool Type::isEnumeralType() const { |
8496 | return isa<EnumType>(CanonicalType); |
8497 | } |
8498 | |
8499 | inline bool Type::isAnyComplexType() const { |
8500 | return isa<ComplexType>(CanonicalType); |
8501 | } |
8502 | |
8503 | inline bool Type::isVectorType() const { |
8504 | return isa<VectorType>(CanonicalType); |
8505 | } |
8506 | |
8507 | inline bool Type::isExtVectorType() const { |
8508 | return isa<ExtVectorType>(CanonicalType); |
8509 | } |
8510 | |
8511 | inline bool Type::isExtVectorBoolType() const { |
8512 | if (!isExtVectorType()) |
8513 | return false; |
8514 | return cast<ExtVectorType>(CanonicalType)->getElementType()->isBooleanType(); |
8515 | } |
8516 | |
8517 | inline bool Type::isSubscriptableVectorType() const { |
8518 | return isVectorType() || isSveVLSBuiltinType(); |
8519 | } |
8520 | |
8521 | inline bool Type::isMatrixType() const { |
8522 | return isa<MatrixType>(CanonicalType); |
8523 | } |
8524 | |
8525 | inline bool Type::isConstantMatrixType() const { |
8526 | return isa<ConstantMatrixType>(CanonicalType); |
8527 | } |
8528 | |
8529 | inline bool Type::isDependentAddressSpaceType() const { |
8530 | return isa<DependentAddressSpaceType>(CanonicalType); |
8531 | } |
8532 | |
8533 | inline bool Type::isObjCObjectPointerType() const { |
8534 | return isa<ObjCObjectPointerType>(CanonicalType); |
8535 | } |
8536 | |
8537 | inline bool Type::isObjCObjectType() const { |
8538 | return isa<ObjCObjectType>(CanonicalType); |
8539 | } |
8540 | |
8541 | inline bool Type::isObjCObjectOrInterfaceType() const { |
8542 | return isa<ObjCInterfaceType>(CanonicalType) || |
8543 | isa<ObjCObjectType>(CanonicalType); |
8544 | } |
8545 | |
8546 | inline bool Type::isAtomicType() const { |
8547 | return isa<AtomicType>(CanonicalType); |
8548 | } |
8549 | |
8550 | inline bool Type::isUndeducedAutoType() const { |
8551 | return isa<AutoType>(CanonicalType); |
8552 | } |
8553 | |
8554 | inline bool Type::isObjCQualifiedIdType() const { |
8555 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) |
8556 | return OPT->isObjCQualifiedIdType(); |
8557 | return false; |
8558 | } |
8559 | |
8560 | inline bool Type::isObjCQualifiedClassType() const { |
8561 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) |
8562 | return OPT->isObjCQualifiedClassType(); |
8563 | return false; |
8564 | } |
8565 | |
8566 | inline bool Type::isObjCIdType() const { |
8567 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) |
8568 | return OPT->isObjCIdType(); |
8569 | return false; |
8570 | } |
8571 | |
8572 | inline bool Type::isObjCClassType() const { |
8573 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) |
8574 | return OPT->isObjCClassType(); |
8575 | return false; |
8576 | } |
8577 | |
8578 | inline bool Type::isObjCSelType() const { |
8579 | if (const auto *OPT = getAs<PointerType>()) |
8580 | return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel); |
8581 | return false; |
8582 | } |
8583 | |
8584 | inline bool Type::isObjCBuiltinType() const { |
8585 | return isObjCIdType() || isObjCClassType() || isObjCSelType(); |
8586 | } |
8587 | |
8588 | inline bool Type::isDecltypeType() const { |
8589 | return isa<DecltypeType>(this); |
8590 | } |
8591 | |
8592 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ |
8593 | inline bool Type::is##Id##Type() const { \ |
8594 | return isSpecificBuiltinType(BuiltinType::Id); \ |
8595 | } |
8596 | #include "clang/Basic/OpenCLImageTypes.def" |
8597 | |
8598 | inline bool Type::isSamplerT() const { |
8599 | return isSpecificBuiltinType(K: BuiltinType::OCLSampler); |
8600 | } |
8601 | |
8602 | inline bool Type::isEventT() const { |
8603 | return isSpecificBuiltinType(K: BuiltinType::OCLEvent); |
8604 | } |
8605 | |
8606 | inline bool Type::isClkEventT() const { |
8607 | return isSpecificBuiltinType(K: BuiltinType::OCLClkEvent); |
8608 | } |
8609 | |
8610 | inline bool Type::isQueueT() const { |
8611 | return isSpecificBuiltinType(K: BuiltinType::OCLQueue); |
8612 | } |
8613 | |
8614 | inline bool Type::isReserveIDT() const { |
8615 | return isSpecificBuiltinType(K: BuiltinType::OCLReserveID); |
8616 | } |
8617 | |
8618 | inline bool Type::isImageType() const { |
8619 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() || |
8620 | return |
8621 | #include "clang/Basic/OpenCLImageTypes.def" |
8622 | false; // end boolean or operation |
8623 | } |
8624 | |
8625 | inline bool Type::isPipeType() const { |
8626 | return isa<PipeType>(CanonicalType); |
8627 | } |
8628 | |
8629 | inline bool Type::isBitIntType() const { |
8630 | return isa<BitIntType>(CanonicalType); |
8631 | } |
8632 | |
8633 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
8634 | inline bool Type::is##Id##Type() const { \ |
8635 | return isSpecificBuiltinType(BuiltinType::Id); \ |
8636 | } |
8637 | #include "clang/Basic/OpenCLExtensionTypes.def" |
8638 | |
8639 | inline bool Type::isOCLIntelSubgroupAVCType() const { |
8640 | #define INTEL_SUBGROUP_AVC_TYPE(ExtType, Id) \ |
8641 | isOCLIntelSubgroupAVC##Id##Type() || |
8642 | return |
8643 | #include "clang/Basic/OpenCLExtensionTypes.def" |
8644 | false; // end of boolean or operation |
8645 | } |
8646 | |
8647 | inline bool Type::isOCLExtOpaqueType() const { |
8648 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) is##Id##Type() || |
8649 | return |
8650 | #include "clang/Basic/OpenCLExtensionTypes.def" |
8651 | false; // end of boolean or operation |
8652 | } |
8653 | |
8654 | inline bool Type::isOpenCLSpecificType() const { |
8655 | return isSamplerT() || isEventT() || isImageType() || isClkEventT() || |
8656 | isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType(); |
8657 | } |
8658 | |
8659 | #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \ |
8660 | inline bool Type::is##Id##Type() const { \ |
8661 | return isSpecificBuiltinType(BuiltinType::Id); \ |
8662 | } |
8663 | #include "clang/Basic/HLSLIntangibleTypes.def" |
8664 | |
8665 | inline bool Type::isHLSLBuiltinIntangibleType() const { |
8666 | #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) is##Id##Type() || |
8667 | return |
8668 | #include "clang/Basic/HLSLIntangibleTypes.def" |
8669 | false; |
8670 | } |
8671 | |
8672 | inline bool Type::isHLSLSpecificType() const { |
8673 | return isHLSLBuiltinIntangibleType() || isHLSLAttributedResourceType() || |
8674 | isHLSLInlineSpirvType(); |
8675 | } |
8676 | |
8677 | inline bool Type::isHLSLAttributedResourceType() const { |
8678 | return isa<HLSLAttributedResourceType>(this); |
8679 | } |
8680 | |
8681 | inline bool Type::isHLSLInlineSpirvType() const { |
8682 | return isa<HLSLInlineSpirvType>(this); |
8683 | } |
8684 | |
8685 | inline bool Type::isTemplateTypeParmType() const { |
8686 | return isa<TemplateTypeParmType>(CanonicalType); |
8687 | } |
8688 | |
8689 | inline bool Type::isSpecificBuiltinType(unsigned K) const { |
8690 | if (const BuiltinType *BT = getAs<BuiltinType>()) { |
8691 | return BT->getKind() == static_cast<BuiltinType::Kind>(K); |
8692 | } |
8693 | return false; |
8694 | } |
8695 | |
8696 | inline bool Type::isPlaceholderType() const { |
8697 | if (const auto *BT = dyn_cast<BuiltinType>(this)) |
8698 | return BT->isPlaceholderType(); |
8699 | return false; |
8700 | } |
8701 | |
8702 | inline const BuiltinType *Type::getAsPlaceholderType() const { |
8703 | if (const auto *BT = dyn_cast<BuiltinType>(this)) |
8704 | if (BT->isPlaceholderType()) |
8705 | return BT; |
8706 | return nullptr; |
8707 | } |
8708 | |
8709 | inline bool Type::isSpecificPlaceholderType(unsigned K) const { |
8710 | assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K)); |
8711 | return isSpecificBuiltinType(K); |
8712 | } |
8713 | |
8714 | inline bool Type::isNonOverloadPlaceholderType() const { |
8715 | if (const auto *BT = dyn_cast<BuiltinType>(this)) |
8716 | return BT->isNonOverloadPlaceholderType(); |
8717 | return false; |
8718 | } |
8719 | |
8720 | inline bool Type::isVoidType() const { |
8721 | return isSpecificBuiltinType(K: BuiltinType::Void); |
8722 | } |
8723 | |
8724 | inline bool Type::isHalfType() const { |
8725 | // FIXME: Should we allow complex __fp16? Probably not. |
8726 | return isSpecificBuiltinType(K: BuiltinType::Half); |
8727 | } |
8728 | |
8729 | inline bool Type::isFloat16Type() const { |
8730 | return isSpecificBuiltinType(K: BuiltinType::Float16); |
8731 | } |
8732 | |
8733 | inline bool Type::isFloat32Type() const { |
8734 | return isSpecificBuiltinType(K: BuiltinType::Float); |
8735 | } |
8736 | |
8737 | inline bool Type::isDoubleType() const { |
8738 | return isSpecificBuiltinType(K: BuiltinType::Double); |
8739 | } |
8740 | |
8741 | inline bool Type::isBFloat16Type() const { |
8742 | return isSpecificBuiltinType(K: BuiltinType::BFloat16); |
8743 | } |
8744 | |
8745 | inline bool Type::isMFloat8Type() const { |
8746 | return isSpecificBuiltinType(K: BuiltinType::MFloat8); |
8747 | } |
8748 | |
8749 | inline bool Type::isFloat128Type() const { |
8750 | return isSpecificBuiltinType(K: BuiltinType::Float128); |
8751 | } |
8752 | |
8753 | inline bool Type::isIbm128Type() const { |
8754 | return isSpecificBuiltinType(K: BuiltinType::Ibm128); |
8755 | } |
8756 | |
8757 | inline bool Type::isNullPtrType() const { |
8758 | return isSpecificBuiltinType(K: BuiltinType::NullPtr); |
8759 | } |
8760 | |
8761 | bool IsEnumDeclComplete(EnumDecl *); |
8762 | bool IsEnumDeclScoped(EnumDecl *); |
8763 | |
8764 | inline bool Type::isIntegerType() const { |
8765 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
8766 | return BT->isInteger(); |
8767 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { |
8768 | // Incomplete enum types are not treated as integer types. |
8769 | // FIXME: In C++, enum types are never integer types. |
8770 | return IsEnumDeclComplete(ET->getDecl()) && |
8771 | !IsEnumDeclScoped(ET->getDecl()); |
8772 | } |
8773 | return isBitIntType(); |
8774 | } |
8775 | |
8776 | inline bool Type::isFixedPointType() const { |
8777 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
8778 | return BT->getKind() >= BuiltinType::ShortAccum && |
8779 | BT->getKind() <= BuiltinType::SatULongFract; |
8780 | } |
8781 | return false; |
8782 | } |
8783 | |
8784 | inline bool Type::isFixedPointOrIntegerType() const { |
8785 | return isFixedPointType() || isIntegerType(); |
8786 | } |
8787 | |
8788 | inline bool Type::isConvertibleToFixedPointType() const { |
8789 | return isRealFloatingType() || isFixedPointOrIntegerType(); |
8790 | } |
8791 | |
8792 | inline bool Type::isSaturatedFixedPointType() const { |
8793 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
8794 | return BT->getKind() >= BuiltinType::SatShortAccum && |
8795 | BT->getKind() <= BuiltinType::SatULongFract; |
8796 | } |
8797 | return false; |
8798 | } |
8799 | |
8800 | inline bool Type::isUnsaturatedFixedPointType() const { |
8801 | return isFixedPointType() && !isSaturatedFixedPointType(); |
8802 | } |
8803 | |
8804 | inline bool Type::isSignedFixedPointType() const { |
8805 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { |
8806 | return ((BT->getKind() >= BuiltinType::ShortAccum && |
8807 | BT->getKind() <= BuiltinType::LongAccum) || |
8808 | (BT->getKind() >= BuiltinType::ShortFract && |
8809 | BT->getKind() <= BuiltinType::LongFract) || |
8810 | (BT->getKind() >= BuiltinType::SatShortAccum && |
8811 | BT->getKind() <= BuiltinType::SatLongAccum) || |
8812 | (BT->getKind() >= BuiltinType::SatShortFract && |
8813 | BT->getKind() <= BuiltinType::SatLongFract)); |
8814 | } |
8815 | return false; |
8816 | } |
8817 | |
8818 | inline bool Type::isUnsignedFixedPointType() const { |
8819 | return isFixedPointType() && !isSignedFixedPointType(); |
8820 | } |
8821 | |
8822 | inline bool Type::isScalarType() const { |
8823 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
8824 | return BT->getKind() > BuiltinType::Void && |
8825 | BT->getKind() <= BuiltinType::NullPtr; |
8826 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) |
8827 | // Enums are scalar types, but only if they are defined. Incomplete enums |
8828 | // are not treated as scalar types. |
8829 | return IsEnumDeclComplete(ET->getDecl()); |
8830 | return isa<PointerType>(CanonicalType) || |
8831 | isa<BlockPointerType>(CanonicalType) || |
8832 | isa<MemberPointerType>(CanonicalType) || |
8833 | isa<ComplexType>(CanonicalType) || |
8834 | isa<ObjCObjectPointerType>(CanonicalType) || |
8835 | isBitIntType(); |
8836 | } |
8837 | |
8838 | inline bool Type::isIntegralOrEnumerationType() const { |
8839 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
8840 | return BT->isInteger(); |
8841 | |
8842 | // Check for a complete enum type; incomplete enum types are not properly an |
8843 | // enumeration type in the sense required here. |
8844 | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) |
8845 | return IsEnumDeclComplete(ET->getDecl()); |
8846 | |
8847 | return isBitIntType(); |
8848 | } |
8849 | |
8850 | inline bool Type::isBooleanType() const { |
8851 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) |
8852 | return BT->getKind() == BuiltinType::Bool; |
8853 | return false; |
8854 | } |
8855 | |
8856 | inline bool Type::isUndeducedType() const { |
8857 | auto *DT = getContainedDeducedType(); |
8858 | return DT && !DT->isDeduced(); |
8859 | } |
8860 | |
8861 | /// Determines whether this is a type for which one can define |
8862 | /// an overloaded operator. |
8863 | inline bool Type::isOverloadableType() const { |
8864 | if (!isDependentType()) |
8865 | return isRecordType() || isEnumeralType(); |
8866 | return !isArrayType() && !isFunctionType() && !isAnyPointerType() && |
8867 | !isMemberPointerType(); |
8868 | } |
8869 | |
8870 | /// Determines whether this type is written as a typedef-name. |
8871 | inline bool Type::isTypedefNameType() const { |
8872 | if (getAs<TypedefType>()) |
8873 | return true; |
8874 | if (auto *TST = getAs<TemplateSpecializationType>()) |
8875 | return TST->isTypeAlias(); |
8876 | return false; |
8877 | } |
8878 | |
8879 | /// Determines whether this type can decay to a pointer type. |
8880 | inline bool Type::canDecayToPointerType() const { |
8881 | return isFunctionType() || (isArrayType() && !isArrayParameterType()); |
8882 | } |
8883 | |
8884 | inline bool Type::hasPointerRepresentation() const { |
8885 | return (isPointerType() || isReferenceType() || isBlockPointerType() || |
8886 | isObjCObjectPointerType() || isNullPtrType()); |
8887 | } |
8888 | |
8889 | inline bool Type::hasObjCPointerRepresentation() const { |
8890 | return isObjCObjectPointerType(); |
8891 | } |
8892 | |
8893 | inline const Type *Type::getBaseElementTypeUnsafe() const { |
8894 | const Type *type = this; |
8895 | while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe()) |
8896 | type = arrayType->getElementType().getTypePtr(); |
8897 | return type; |
8898 | } |
8899 | |
8900 | inline const Type *Type::getPointeeOrArrayElementType() const { |
8901 | const Type *type = this; |
8902 | if (type->isAnyPointerType()) |
8903 | return type->getPointeeType().getTypePtr(); |
8904 | else if (type->isArrayType()) |
8905 | return type->getBaseElementTypeUnsafe(); |
8906 | return type; |
8907 | } |
8908 | /// Insertion operator for partial diagnostics. This allows sending adress |
8909 | /// spaces into a diagnostic with <<. |
8910 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, |
8911 | LangAS AS) { |
8912 | PD.AddTaggedVal(V: llvm::to_underlying(AS), |
8913 | Kind: DiagnosticsEngine::ArgumentKind::ak_addrspace); |
8914 | return PD; |
8915 | } |
8916 | |
8917 | /// Insertion operator for partial diagnostics. This allows sending Qualifiers |
8918 | /// into a diagnostic with <<. |
8919 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, |
8920 | Qualifiers Q) { |
8921 | PD.AddTaggedVal(V: Q.getAsOpaqueValue(), |
8922 | Kind: DiagnosticsEngine::ArgumentKind::ak_qual); |
8923 | return PD; |
8924 | } |
8925 | |
8926 | /// Insertion operator for partial diagnostics. This allows sending QualType's |
8927 | /// into a diagnostic with <<. |
8928 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, |
8929 | QualType T) { |
8930 | PD.AddTaggedVal(V: reinterpret_cast<uint64_t>(T.getAsOpaquePtr()), |
8931 | Kind: DiagnosticsEngine::ak_qualtype); |
8932 | return PD; |
8933 | } |
8934 | |
8935 | // Helper class template that is used by Type::getAs to ensure that one does |
8936 | // not try to look through a qualified type to get to an array type. |
8937 | template <typename T> |
8938 | using TypeIsArrayType = |
8939 | std::integral_constant<bool, std::is_same<T, ArrayType>::value || |
8940 | std::is_base_of<ArrayType, T>::value>; |
8941 | |
8942 | // Member-template getAs<specific type>'. |
8943 | template <typename T> const T *Type::getAs() const { |
8944 | static_assert(!TypeIsArrayType<T>::value, |
8945 | "ArrayType cannot be used with getAs!" ); |
8946 | |
8947 | // If this is directly a T type, return it. |
8948 | if (const auto *Ty = dyn_cast<T>(this)) |
8949 | return Ty; |
8950 | |
8951 | // If the canonical form of this type isn't the right kind, reject it. |
8952 | if (!isa<T>(CanonicalType)) |
8953 | return nullptr; |
8954 | |
8955 | // If this is a typedef for the type, strip the typedef off without |
8956 | // losing all typedef information. |
8957 | return cast<T>(getUnqualifiedDesugaredType()); |
8958 | } |
8959 | |
8960 | template <typename T> const T *Type::getAsAdjusted() const { |
8961 | static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!" ); |
8962 | |
8963 | // If this is directly a T type, return it. |
8964 | if (const auto *Ty = dyn_cast<T>(this)) |
8965 | return Ty; |
8966 | |
8967 | // If the canonical form of this type isn't the right kind, reject it. |
8968 | if (!isa<T>(CanonicalType)) |
8969 | return nullptr; |
8970 | |
8971 | // Strip off type adjustments that do not modify the underlying nature of the |
8972 | // type. |
8973 | const Type *Ty = this; |
8974 | while (Ty) { |
8975 | if (const auto *A = dyn_cast<AttributedType>(Ty)) |
8976 | Ty = A->getModifiedType().getTypePtr(); |
8977 | else if (const auto *A = dyn_cast<BTFTagAttributedType>(Ty)) |
8978 | Ty = A->getWrappedType().getTypePtr(); |
8979 | else if (const auto *A = dyn_cast<HLSLAttributedResourceType>(Ty)) |
8980 | Ty = A->getWrappedType().getTypePtr(); |
8981 | else if (const auto *E = dyn_cast<ElaboratedType>(Ty)) |
8982 | Ty = E->desugar().getTypePtr(); |
8983 | else if (const auto *P = dyn_cast<ParenType>(Ty)) |
8984 | Ty = P->desugar().getTypePtr(); |
8985 | else if (const auto *A = dyn_cast<AdjustedType>(Ty)) |
8986 | Ty = A->desugar().getTypePtr(); |
8987 | else if (const auto *M = dyn_cast<MacroQualifiedType>(Ty)) |
8988 | Ty = M->desugar().getTypePtr(); |
8989 | else |
8990 | break; |
8991 | } |
8992 | |
8993 | // Just because the canonical type is correct does not mean we can use cast<>, |
8994 | // since we may not have stripped off all the sugar down to the base type. |
8995 | return dyn_cast<T>(Ty); |
8996 | } |
8997 | |
8998 | inline const ArrayType *Type::getAsArrayTypeUnsafe() const { |
8999 | // If this is directly an array type, return it. |
9000 | if (const auto *arr = dyn_cast<ArrayType>(this)) |
9001 | return arr; |
9002 | |
9003 | // If the canonical form of this type isn't the right kind, reject it. |
9004 | if (!isa<ArrayType>(CanonicalType)) |
9005 | return nullptr; |
9006 | |
9007 | // If this is a typedef for the type, strip the typedef off without |
9008 | // losing all typedef information. |
9009 | return cast<ArrayType>(getUnqualifiedDesugaredType()); |
9010 | } |
9011 | |
9012 | template <typename T> const T *Type::castAs() const { |
9013 | static_assert(!TypeIsArrayType<T>::value, |
9014 | "ArrayType cannot be used with castAs!" ); |
9015 | |
9016 | if (const auto *ty = dyn_cast<T>(this)) return ty; |
9017 | assert(isa<T>(CanonicalType)); |
9018 | return cast<T>(getUnqualifiedDesugaredType()); |
9019 | } |
9020 | |
9021 | inline const ArrayType *Type::castAsArrayTypeUnsafe() const { |
9022 | assert(isa<ArrayType>(CanonicalType)); |
9023 | if (const auto *arr = dyn_cast<ArrayType>(this)) return arr; |
9024 | return cast<ArrayType>(getUnqualifiedDesugaredType()); |
9025 | } |
9026 | |
9027 | DecayedType::DecayedType(QualType OriginalType, QualType DecayedPtr, |
9028 | QualType CanonicalPtr) |
9029 | : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) { |
9030 | #ifndef NDEBUG |
9031 | QualType Adjusted = getAdjustedType(); |
9032 | (void)AttributedType::stripOuterNullability(Adjusted); |
9033 | assert(isa<PointerType>(Adjusted)); |
9034 | #endif |
9035 | } |
9036 | |
9037 | QualType DecayedType::getPointeeType() const { |
9038 | QualType Decayed = getDecayedType(); |
9039 | (void)AttributedType::stripOuterNullability(Decayed); |
9040 | return cast<PointerType>(Decayed)->getPointeeType(); |
9041 | } |
9042 | |
9043 | // Get the decimal string representation of a fixed point type, represented |
9044 | // as a scaled integer. |
9045 | // TODO: At some point, we should change the arguments to instead just accept an |
9046 | // APFixedPoint instead of APSInt and scale. |
9047 | void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val, |
9048 | unsigned Scale); |
9049 | |
9050 | inline FunctionEffectsRef FunctionEffectsRef::get(QualType QT) { |
9051 | const Type *TypePtr = QT.getTypePtr(); |
9052 | while (true) { |
9053 | if (QualType Pointee = TypePtr->getPointeeType(); !Pointee.isNull()) |
9054 | TypePtr = Pointee.getTypePtr(); |
9055 | else if (TypePtr->isArrayType()) |
9056 | TypePtr = TypePtr->getBaseElementTypeUnsafe(); |
9057 | else |
9058 | break; |
9059 | } |
9060 | if (const auto *FPT = TypePtr->getAs<FunctionProtoType>()) |
9061 | return FPT->getFunctionEffects(); |
9062 | return {}; |
9063 | } |
9064 | |
9065 | } // namespace clang |
9066 | |
9067 | #endif // LLVM_CLANG_AST_TYPE_H |
9068 | |