File: | clang/lib/Sema/SemaCast.cpp |
Warning: | line 1358, column 14 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- SemaCast.cpp - Semantic Analysis for Casts -----------------------===// | ||||||
2 | // | ||||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||
6 | // | ||||||
7 | //===----------------------------------------------------------------------===// | ||||||
8 | // | ||||||
9 | // This file implements semantic analysis for cast expressions, including | ||||||
10 | // 1) C-style casts like '(int) x' | ||||||
11 | // 2) C++ functional casts like 'int(x)' | ||||||
12 | // 3) C++ named casts like 'static_cast<int>(x)' | ||||||
13 | // | ||||||
14 | //===----------------------------------------------------------------------===// | ||||||
15 | |||||||
16 | #include "clang/AST/ASTContext.h" | ||||||
17 | #include "clang/AST/ASTStructuralEquivalence.h" | ||||||
18 | #include "clang/AST/CXXInheritance.h" | ||||||
19 | #include "clang/AST/ExprCXX.h" | ||||||
20 | #include "clang/AST/ExprObjC.h" | ||||||
21 | #include "clang/AST/RecordLayout.h" | ||||||
22 | #include "clang/Basic/PartialDiagnostic.h" | ||||||
23 | #include "clang/Basic/TargetInfo.h" | ||||||
24 | #include "clang/Lex/Preprocessor.h" | ||||||
25 | #include "clang/Sema/Initialization.h" | ||||||
26 | #include "clang/Sema/SemaInternal.h" | ||||||
27 | #include "llvm/ADT/SmallVector.h" | ||||||
28 | #include <set> | ||||||
29 | using namespace clang; | ||||||
30 | |||||||
31 | |||||||
32 | |||||||
33 | enum TryCastResult { | ||||||
34 | TC_NotApplicable, ///< The cast method is not applicable. | ||||||
35 | TC_Success, ///< The cast method is appropriate and successful. | ||||||
36 | TC_Extension, ///< The cast method is appropriate and accepted as a | ||||||
37 | ///< language extension. | ||||||
38 | TC_Failed ///< The cast method is appropriate, but failed. A | ||||||
39 | ///< diagnostic has been emitted. | ||||||
40 | }; | ||||||
41 | |||||||
42 | static bool isValidCast(TryCastResult TCR) { | ||||||
43 | return TCR == TC_Success || TCR == TC_Extension; | ||||||
44 | } | ||||||
45 | |||||||
46 | enum CastType { | ||||||
47 | CT_Const, ///< const_cast | ||||||
48 | CT_Static, ///< static_cast | ||||||
49 | CT_Reinterpret, ///< reinterpret_cast | ||||||
50 | CT_Dynamic, ///< dynamic_cast | ||||||
51 | CT_CStyle, ///< (Type)expr | ||||||
52 | CT_Functional, ///< Type(expr) | ||||||
53 | CT_Addrspace ///< addrspace_cast | ||||||
54 | }; | ||||||
55 | |||||||
56 | namespace { | ||||||
57 | struct CastOperation { | ||||||
58 | CastOperation(Sema &S, QualType destType, ExprResult src) | ||||||
59 | : Self(S), SrcExpr(src), DestType(destType), | ||||||
60 | ResultType(destType.getNonLValueExprType(S.Context)), | ||||||
61 | ValueKind(Expr::getValueKindForType(destType)), | ||||||
62 | Kind(CK_Dependent), IsARCUnbridgedCast(false) { | ||||||
63 | |||||||
64 | // C++ [expr.type]/8.2.2: | ||||||
65 | // If a pr-value initially has the type cv-T, where T is a | ||||||
66 | // cv-unqualified non-class, non-array type, the type of the | ||||||
67 | // expression is adjusted to T prior to any further analysis. | ||||||
68 | if (!S.Context.getLangOpts().ObjC && !DestType->isRecordType() && | ||||||
69 | !DestType->isArrayType()) { | ||||||
70 | DestType = DestType.getUnqualifiedType(); | ||||||
71 | } | ||||||
72 | |||||||
73 | if (const BuiltinType *placeholder = | ||||||
74 | src.get()->getType()->getAsPlaceholderType()) { | ||||||
75 | PlaceholderKind = placeholder->getKind(); | ||||||
76 | } else { | ||||||
77 | PlaceholderKind = (BuiltinType::Kind) 0; | ||||||
78 | } | ||||||
79 | } | ||||||
80 | |||||||
81 | Sema &Self; | ||||||
82 | ExprResult SrcExpr; | ||||||
83 | QualType DestType; | ||||||
84 | QualType ResultType; | ||||||
85 | ExprValueKind ValueKind; | ||||||
86 | CastKind Kind; | ||||||
87 | BuiltinType::Kind PlaceholderKind; | ||||||
88 | CXXCastPath BasePath; | ||||||
89 | bool IsARCUnbridgedCast; | ||||||
90 | |||||||
91 | SourceRange OpRange; | ||||||
92 | SourceRange DestRange; | ||||||
93 | |||||||
94 | // Top-level semantics-checking routines. | ||||||
95 | void CheckConstCast(); | ||||||
96 | void CheckReinterpretCast(); | ||||||
97 | void CheckStaticCast(); | ||||||
98 | void CheckDynamicCast(); | ||||||
99 | void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization); | ||||||
100 | void CheckCStyleCast(); | ||||||
101 | void CheckBuiltinBitCast(); | ||||||
102 | void CheckAddrspaceCast(); | ||||||
103 | |||||||
104 | void updatePartOfExplicitCastFlags(CastExpr *CE) { | ||||||
105 | // Walk down from the CE to the OrigSrcExpr, and mark all immediate | ||||||
106 | // ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE | ||||||
107 | // (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched. | ||||||
108 | for (; auto *ICE = dyn_cast<ImplicitCastExpr>(CE->getSubExpr()); CE = ICE) | ||||||
109 | ICE->setIsPartOfExplicitCast(true); | ||||||
110 | } | ||||||
111 | |||||||
112 | /// Complete an apparently-successful cast operation that yields | ||||||
113 | /// the given expression. | ||||||
114 | ExprResult complete(CastExpr *castExpr) { | ||||||
115 | // If this is an unbridged cast, wrap the result in an implicit | ||||||
116 | // cast that yields the unbridged-cast placeholder type. | ||||||
117 | if (IsARCUnbridgedCast) { | ||||||
118 | castExpr = ImplicitCastExpr::Create( | ||||||
119 | Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent, | ||||||
120 | castExpr, nullptr, castExpr->getValueKind(), | ||||||
121 | Self.CurFPFeatureOverrides()); | ||||||
122 | } | ||||||
123 | updatePartOfExplicitCastFlags(castExpr); | ||||||
124 | return castExpr; | ||||||
125 | } | ||||||
126 | |||||||
127 | // Internal convenience methods. | ||||||
128 | |||||||
129 | /// Try to handle the given placeholder expression kind. Return | ||||||
130 | /// true if the source expression has the appropriate placeholder | ||||||
131 | /// kind. A placeholder can only be claimed once. | ||||||
132 | bool claimPlaceholder(BuiltinType::Kind K) { | ||||||
133 | if (PlaceholderKind != K) return false; | ||||||
134 | |||||||
135 | PlaceholderKind = (BuiltinType::Kind) 0; | ||||||
136 | return true; | ||||||
137 | } | ||||||
138 | |||||||
139 | bool isPlaceholder() const { | ||||||
140 | return PlaceholderKind != 0; | ||||||
141 | } | ||||||
142 | bool isPlaceholder(BuiltinType::Kind K) const { | ||||||
143 | return PlaceholderKind == K; | ||||||
144 | } | ||||||
145 | |||||||
146 | // Language specific cast restrictions for address spaces. | ||||||
147 | void checkAddressSpaceCast(QualType SrcType, QualType DestType); | ||||||
148 | |||||||
149 | void checkCastAlign() { | ||||||
150 | Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange); | ||||||
151 | } | ||||||
152 | |||||||
153 | void checkObjCConversion(Sema::CheckedConversionKind CCK) { | ||||||
154 | assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())(static_cast <bool> (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers ()) ? void (0) : __assert_fail ("Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 154, __extension__ __PRETTY_FUNCTION__)); | ||||||
155 | |||||||
156 | Expr *src = SrcExpr.get(); | ||||||
157 | if (Self.CheckObjCConversion(OpRange, DestType, src, CCK) == | ||||||
158 | Sema::ACR_unbridged) | ||||||
159 | IsARCUnbridgedCast = true; | ||||||
160 | SrcExpr = src; | ||||||
161 | } | ||||||
162 | |||||||
163 | /// Check for and handle non-overload placeholder expressions. | ||||||
164 | void checkNonOverloadPlaceholders() { | ||||||
165 | if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload)) | ||||||
166 | return; | ||||||
167 | |||||||
168 | SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get()); | ||||||
169 | if (SrcExpr.isInvalid()) | ||||||
170 | return; | ||||||
171 | PlaceholderKind = (BuiltinType::Kind) 0; | ||||||
172 | } | ||||||
173 | }; | ||||||
174 | |||||||
175 | void CheckNoDeref(Sema &S, const QualType FromType, const QualType ToType, | ||||||
176 | SourceLocation OpLoc) { | ||||||
177 | if (const auto *PtrType = dyn_cast<PointerType>(FromType)) { | ||||||
178 | if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) { | ||||||
179 | if (const auto *DestType = dyn_cast<PointerType>(ToType)) { | ||||||
180 | if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) { | ||||||
181 | S.Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer); | ||||||
182 | } | ||||||
183 | } | ||||||
184 | } | ||||||
185 | } | ||||||
186 | } | ||||||
187 | |||||||
188 | struct CheckNoDerefRAII { | ||||||
189 | CheckNoDerefRAII(CastOperation &Op) : Op(Op) {} | ||||||
190 | ~CheckNoDerefRAII() { | ||||||
191 | if (!Op.SrcExpr.isInvalid()) | ||||||
192 | CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType, | ||||||
193 | Op.OpRange.getBegin()); | ||||||
194 | } | ||||||
195 | |||||||
196 | CastOperation &Op; | ||||||
197 | }; | ||||||
198 | } | ||||||
199 | |||||||
200 | static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr, | ||||||
201 | QualType DestType); | ||||||
202 | |||||||
203 | // The Try functions attempt a specific way of casting. If they succeed, they | ||||||
204 | // return TC_Success. If their way of casting is not appropriate for the given | ||||||
205 | // arguments, they return TC_NotApplicable and *may* set diag to a diagnostic | ||||||
206 | // to emit if no other way succeeds. If their way of casting is appropriate but | ||||||
207 | // fails, they return TC_Failed and *must* set diag; they can set it to 0 if | ||||||
208 | // they emit a specialized diagnostic. | ||||||
209 | // All diagnostics returned by these functions must expect the same three | ||||||
210 | // arguments: | ||||||
211 | // %0: Cast Type (a value from the CastType enumeration) | ||||||
212 | // %1: Source Type | ||||||
213 | // %2: Destination Type | ||||||
214 | static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, | ||||||
215 | QualType DestType, bool CStyle, | ||||||
216 | CastKind &Kind, | ||||||
217 | CXXCastPath &BasePath, | ||||||
218 | unsigned &msg); | ||||||
219 | static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, | ||||||
220 | QualType DestType, bool CStyle, | ||||||
221 | SourceRange OpRange, | ||||||
222 | unsigned &msg, | ||||||
223 | CastKind &Kind, | ||||||
224 | CXXCastPath &BasePath); | ||||||
225 | static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, | ||||||
226 | QualType DestType, bool CStyle, | ||||||
227 | SourceRange OpRange, | ||||||
228 | unsigned &msg, | ||||||
229 | CastKind &Kind, | ||||||
230 | CXXCastPath &BasePath); | ||||||
231 | static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, | ||||||
232 | CanQualType DestType, bool CStyle, | ||||||
233 | SourceRange OpRange, | ||||||
234 | QualType OrigSrcType, | ||||||
235 | QualType OrigDestType, unsigned &msg, | ||||||
236 | CastKind &Kind, | ||||||
237 | CXXCastPath &BasePath); | ||||||
238 | static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, | ||||||
239 | QualType SrcType, | ||||||
240 | QualType DestType,bool CStyle, | ||||||
241 | SourceRange OpRange, | ||||||
242 | unsigned &msg, | ||||||
243 | CastKind &Kind, | ||||||
244 | CXXCastPath &BasePath); | ||||||
245 | |||||||
246 | static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, | ||||||
247 | QualType DestType, | ||||||
248 | Sema::CheckedConversionKind CCK, | ||||||
249 | SourceRange OpRange, | ||||||
250 | unsigned &msg, CastKind &Kind, | ||||||
251 | bool ListInitialization); | ||||||
252 | static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, | ||||||
253 | QualType DestType, | ||||||
254 | Sema::CheckedConversionKind CCK, | ||||||
255 | SourceRange OpRange, | ||||||
256 | unsigned &msg, CastKind &Kind, | ||||||
257 | CXXCastPath &BasePath, | ||||||
258 | bool ListInitialization); | ||||||
259 | static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr, | ||||||
260 | QualType DestType, bool CStyle, | ||||||
261 | unsigned &msg); | ||||||
262 | static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, | ||||||
263 | QualType DestType, bool CStyle, | ||||||
264 | SourceRange OpRange, unsigned &msg, | ||||||
265 | CastKind &Kind); | ||||||
266 | static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr, | ||||||
267 | QualType DestType, bool CStyle, | ||||||
268 | unsigned &msg, CastKind &Kind); | ||||||
269 | |||||||
270 | /// ActOnCXXNamedCast - Parse | ||||||
271 | /// {dynamic,static,reinterpret,const,addrspace}_cast's. | ||||||
272 | ExprResult | ||||||
273 | Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, | ||||||
274 | SourceLocation LAngleBracketLoc, Declarator &D, | ||||||
275 | SourceLocation RAngleBracketLoc, | ||||||
276 | SourceLocation LParenLoc, Expr *E, | ||||||
277 | SourceLocation RParenLoc) { | ||||||
278 | |||||||
279 | assert(!D.isInvalidType())(static_cast <bool> (!D.isInvalidType()) ? void (0) : __assert_fail ("!D.isInvalidType()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 279, __extension__ __PRETTY_FUNCTION__)); | ||||||
280 | |||||||
281 | TypeSourceInfo *TInfo = GetTypeForDeclaratorCast(D, E->getType()); | ||||||
282 | if (D.isInvalidType()) | ||||||
283 | return ExprError(); | ||||||
284 | |||||||
285 | if (getLangOpts().CPlusPlus) { | ||||||
286 | // Check that there are no default arguments (C++ only). | ||||||
287 | CheckExtraCXXDefaultArguments(D); | ||||||
288 | } | ||||||
289 | |||||||
290 | return BuildCXXNamedCast(OpLoc, Kind, TInfo, E, | ||||||
291 | SourceRange(LAngleBracketLoc, RAngleBracketLoc), | ||||||
292 | SourceRange(LParenLoc, RParenLoc)); | ||||||
293 | } | ||||||
294 | |||||||
295 | ExprResult | ||||||
296 | Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, | ||||||
297 | TypeSourceInfo *DestTInfo, Expr *E, | ||||||
298 | SourceRange AngleBrackets, SourceRange Parens) { | ||||||
299 | ExprResult Ex = E; | ||||||
300 | QualType DestType = DestTInfo->getType(); | ||||||
301 | |||||||
302 | // If the type is dependent, we won't do the semantic analysis now. | ||||||
303 | bool TypeDependent = | ||||||
304 | DestType->isDependentType() || Ex.get()->isTypeDependent(); | ||||||
305 | |||||||
306 | CastOperation Op(*this, DestType, E); | ||||||
307 | Op.OpRange = SourceRange(OpLoc, Parens.getEnd()); | ||||||
308 | Op.DestRange = AngleBrackets; | ||||||
309 | |||||||
310 | switch (Kind) { | ||||||
311 | default: llvm_unreachable("Unknown C++ cast!")::llvm::llvm_unreachable_internal("Unknown C++ cast!", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 311); | ||||||
312 | |||||||
313 | case tok::kw_addrspace_cast: | ||||||
314 | if (!TypeDependent) { | ||||||
315 | Op.CheckAddrspaceCast(); | ||||||
316 | if (Op.SrcExpr.isInvalid()) | ||||||
317 | return ExprError(); | ||||||
318 | } | ||||||
319 | return Op.complete(CXXAddrspaceCastExpr::Create( | ||||||
320 | Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(), | ||||||
321 | DestTInfo, OpLoc, Parens.getEnd(), AngleBrackets)); | ||||||
322 | |||||||
323 | case tok::kw_const_cast: | ||||||
324 | if (!TypeDependent) { | ||||||
325 | Op.CheckConstCast(); | ||||||
326 | if (Op.SrcExpr.isInvalid()) | ||||||
327 | return ExprError(); | ||||||
328 | DiscardMisalignedMemberAddress(DestType.getTypePtr(), E); | ||||||
329 | } | ||||||
330 | return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType, | ||||||
331 | Op.ValueKind, Op.SrcExpr.get(), DestTInfo, | ||||||
332 | OpLoc, Parens.getEnd(), | ||||||
333 | AngleBrackets)); | ||||||
334 | |||||||
335 | case tok::kw_dynamic_cast: { | ||||||
336 | // dynamic_cast is not supported in C++ for OpenCL. | ||||||
337 | if (getLangOpts().OpenCLCPlusPlus) { | ||||||
338 | return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported) | ||||||
339 | << "dynamic_cast"); | ||||||
340 | } | ||||||
341 | |||||||
342 | if (!TypeDependent) { | ||||||
343 | Op.CheckDynamicCast(); | ||||||
344 | if (Op.SrcExpr.isInvalid()) | ||||||
345 | return ExprError(); | ||||||
346 | } | ||||||
347 | return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType, | ||||||
348 | Op.ValueKind, Op.Kind, Op.SrcExpr.get(), | ||||||
349 | &Op.BasePath, DestTInfo, | ||||||
350 | OpLoc, Parens.getEnd(), | ||||||
351 | AngleBrackets)); | ||||||
352 | } | ||||||
353 | case tok::kw_reinterpret_cast: { | ||||||
354 | if (!TypeDependent) { | ||||||
355 | Op.CheckReinterpretCast(); | ||||||
356 | if (Op.SrcExpr.isInvalid()) | ||||||
357 | return ExprError(); | ||||||
358 | DiscardMisalignedMemberAddress(DestType.getTypePtr(), E); | ||||||
359 | } | ||||||
360 | return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType, | ||||||
361 | Op.ValueKind, Op.Kind, Op.SrcExpr.get(), | ||||||
362 | nullptr, DestTInfo, OpLoc, | ||||||
363 | Parens.getEnd(), | ||||||
364 | AngleBrackets)); | ||||||
365 | } | ||||||
366 | case tok::kw_static_cast: { | ||||||
367 | if (!TypeDependent) { | ||||||
368 | Op.CheckStaticCast(); | ||||||
369 | if (Op.SrcExpr.isInvalid()) | ||||||
370 | return ExprError(); | ||||||
371 | DiscardMisalignedMemberAddress(DestType.getTypePtr(), E); | ||||||
372 | } | ||||||
373 | |||||||
374 | return Op.complete(CXXStaticCastExpr::Create( | ||||||
375 | Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(), | ||||||
376 | &Op.BasePath, DestTInfo, CurFPFeatureOverrides(), OpLoc, | ||||||
377 | Parens.getEnd(), AngleBrackets)); | ||||||
378 | } | ||||||
379 | } | ||||||
380 | } | ||||||
381 | |||||||
382 | ExprResult Sema::ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &D, | ||||||
383 | ExprResult Operand, | ||||||
384 | SourceLocation RParenLoc) { | ||||||
385 | assert(!D.isInvalidType())(static_cast <bool> (!D.isInvalidType()) ? void (0) : __assert_fail ("!D.isInvalidType()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 385, __extension__ __PRETTY_FUNCTION__)); | ||||||
386 | |||||||
387 | TypeSourceInfo *TInfo = GetTypeForDeclaratorCast(D, Operand.get()->getType()); | ||||||
388 | if (D.isInvalidType()) | ||||||
389 | return ExprError(); | ||||||
390 | |||||||
391 | return BuildBuiltinBitCastExpr(KWLoc, TInfo, Operand.get(), RParenLoc); | ||||||
392 | } | ||||||
393 | |||||||
394 | ExprResult Sema::BuildBuiltinBitCastExpr(SourceLocation KWLoc, | ||||||
395 | TypeSourceInfo *TSI, Expr *Operand, | ||||||
396 | SourceLocation RParenLoc) { | ||||||
397 | CastOperation Op(*this, TSI->getType(), Operand); | ||||||
398 | Op.OpRange = SourceRange(KWLoc, RParenLoc); | ||||||
399 | TypeLoc TL = TSI->getTypeLoc(); | ||||||
400 | Op.DestRange = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); | ||||||
401 | |||||||
402 | if (!Operand->isTypeDependent() && !TSI->getType()->isDependentType()) { | ||||||
403 | Op.CheckBuiltinBitCast(); | ||||||
404 | if (Op.SrcExpr.isInvalid()) | ||||||
405 | return ExprError(); | ||||||
406 | } | ||||||
407 | |||||||
408 | BuiltinBitCastExpr *BCE = | ||||||
409 | new (Context) BuiltinBitCastExpr(Op.ResultType, Op.ValueKind, Op.Kind, | ||||||
410 | Op.SrcExpr.get(), TSI, KWLoc, RParenLoc); | ||||||
411 | return Op.complete(BCE); | ||||||
412 | } | ||||||
413 | |||||||
414 | /// Try to diagnose a failed overloaded cast. Returns true if | ||||||
415 | /// diagnostics were emitted. | ||||||
416 | static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, | ||||||
417 | SourceRange range, Expr *src, | ||||||
418 | QualType destType, | ||||||
419 | bool listInitialization) { | ||||||
420 | switch (CT) { | ||||||
421 | // These cast kinds don't consider user-defined conversions. | ||||||
422 | case CT_Const: | ||||||
423 | case CT_Reinterpret: | ||||||
424 | case CT_Dynamic: | ||||||
425 | case CT_Addrspace: | ||||||
426 | return false; | ||||||
427 | |||||||
428 | // These do. | ||||||
429 | case CT_Static: | ||||||
430 | case CT_CStyle: | ||||||
431 | case CT_Functional: | ||||||
432 | break; | ||||||
433 | } | ||||||
434 | |||||||
435 | QualType srcType = src->getType(); | ||||||
436 | if (!destType->isRecordType() && !srcType->isRecordType()) | ||||||
437 | return false; | ||||||
438 | |||||||
439 | InitializedEntity entity = InitializedEntity::InitializeTemporary(destType); | ||||||
440 | InitializationKind initKind | ||||||
441 | = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(), | ||||||
442 | range, listInitialization) | ||||||
443 | : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range, | ||||||
444 | listInitialization) | ||||||
445 | : InitializationKind::CreateCast(/*type range?*/ range); | ||||||
446 | InitializationSequence sequence(S, entity, initKind, src); | ||||||
447 | |||||||
448 | assert(sequence.Failed() && "initialization succeeded on second try?")(static_cast <bool> (sequence.Failed() && "initialization succeeded on second try?" ) ? void (0) : __assert_fail ("sequence.Failed() && \"initialization succeeded on second try?\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 448, __extension__ __PRETTY_FUNCTION__)); | ||||||
449 | switch (sequence.getFailureKind()) { | ||||||
450 | default: return false; | ||||||
451 | |||||||
452 | case InitializationSequence::FK_ConstructorOverloadFailed: | ||||||
453 | case InitializationSequence::FK_UserConversionOverloadFailed: | ||||||
454 | break; | ||||||
455 | } | ||||||
456 | |||||||
457 | OverloadCandidateSet &candidates = sequence.getFailedCandidateSet(); | ||||||
458 | |||||||
459 | unsigned msg = 0; | ||||||
460 | OverloadCandidateDisplayKind howManyCandidates = OCD_AllCandidates; | ||||||
461 | |||||||
462 | switch (sequence.getFailedOverloadResult()) { | ||||||
463 | case OR_Success: llvm_unreachable("successful failed overload")::llvm::llvm_unreachable_internal("successful failed overload" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 463); | ||||||
464 | case OR_No_Viable_Function: | ||||||
465 | if (candidates.empty()) | ||||||
466 | msg = diag::err_ovl_no_conversion_in_cast; | ||||||
467 | else | ||||||
468 | msg = diag::err_ovl_no_viable_conversion_in_cast; | ||||||
469 | howManyCandidates = OCD_AllCandidates; | ||||||
470 | break; | ||||||
471 | |||||||
472 | case OR_Ambiguous: | ||||||
473 | msg = diag::err_ovl_ambiguous_conversion_in_cast; | ||||||
474 | howManyCandidates = OCD_AmbiguousCandidates; | ||||||
475 | break; | ||||||
476 | |||||||
477 | case OR_Deleted: | ||||||
478 | msg = diag::err_ovl_deleted_conversion_in_cast; | ||||||
479 | howManyCandidates = OCD_ViableCandidates; | ||||||
480 | break; | ||||||
481 | } | ||||||
482 | |||||||
483 | candidates.NoteCandidates( | ||||||
484 | PartialDiagnosticAt(range.getBegin(), | ||||||
485 | S.PDiag(msg) << CT << srcType << destType << range | ||||||
486 | << src->getSourceRange()), | ||||||
487 | S, howManyCandidates, src); | ||||||
488 | |||||||
489 | return true; | ||||||
490 | } | ||||||
491 | |||||||
492 | /// Diagnose a failed cast. | ||||||
493 | static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, | ||||||
494 | SourceRange opRange, Expr *src, QualType destType, | ||||||
495 | bool listInitialization) { | ||||||
496 | if (msg == diag::err_bad_cxx_cast_generic && | ||||||
497 | tryDiagnoseOverloadedCast(S, castType, opRange, src, destType, | ||||||
498 | listInitialization)) | ||||||
499 | return; | ||||||
500 | |||||||
501 | S.Diag(opRange.getBegin(), msg) << castType | ||||||
502 | << src->getType() << destType << opRange << src->getSourceRange(); | ||||||
503 | |||||||
504 | // Detect if both types are (ptr to) class, and note any incompleteness. | ||||||
505 | int DifferentPtrness = 0; | ||||||
506 | QualType From = destType; | ||||||
507 | if (auto Ptr = From->getAs<PointerType>()) { | ||||||
508 | From = Ptr->getPointeeType(); | ||||||
509 | DifferentPtrness++; | ||||||
510 | } | ||||||
511 | QualType To = src->getType(); | ||||||
512 | if (auto Ptr = To->getAs<PointerType>()) { | ||||||
513 | To = Ptr->getPointeeType(); | ||||||
514 | DifferentPtrness--; | ||||||
515 | } | ||||||
516 | if (!DifferentPtrness) { | ||||||
517 | auto RecFrom = From->getAs<RecordType>(); | ||||||
518 | auto RecTo = To->getAs<RecordType>(); | ||||||
519 | if (RecFrom && RecTo) { | ||||||
520 | auto DeclFrom = RecFrom->getAsCXXRecordDecl(); | ||||||
521 | if (!DeclFrom->isCompleteDefinition()) | ||||||
522 | S.Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom; | ||||||
523 | auto DeclTo = RecTo->getAsCXXRecordDecl(); | ||||||
524 | if (!DeclTo->isCompleteDefinition()) | ||||||
525 | S.Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo; | ||||||
526 | } | ||||||
527 | } | ||||||
528 | } | ||||||
529 | |||||||
530 | namespace { | ||||||
531 | /// The kind of unwrapping we did when determining whether a conversion casts | ||||||
532 | /// away constness. | ||||||
533 | enum CastAwayConstnessKind { | ||||||
534 | /// The conversion does not cast away constness. | ||||||
535 | CACK_None = 0, | ||||||
536 | /// We unwrapped similar types. | ||||||
537 | CACK_Similar = 1, | ||||||
538 | /// We unwrapped dissimilar types with similar representations (eg, a pointer | ||||||
539 | /// versus an Objective-C object pointer). | ||||||
540 | CACK_SimilarKind = 2, | ||||||
541 | /// We unwrapped representationally-unrelated types, such as a pointer versus | ||||||
542 | /// a pointer-to-member. | ||||||
543 | CACK_Incoherent = 3, | ||||||
544 | }; | ||||||
545 | } | ||||||
546 | |||||||
547 | /// Unwrap one level of types for CastsAwayConstness. | ||||||
548 | /// | ||||||
549 | /// Like Sema::UnwrapSimilarTypes, this removes one level of indirection from | ||||||
550 | /// both types, provided that they're both pointer-like or array-like. Unlike | ||||||
551 | /// the Sema function, doesn't care if the unwrapped pieces are related. | ||||||
552 | /// | ||||||
553 | /// This function may remove additional levels as necessary for correctness: | ||||||
554 | /// the resulting T1 is unwrapped sufficiently that it is never an array type, | ||||||
555 | /// so that its qualifiers can be directly compared to those of T2 (which will | ||||||
556 | /// have the combined set of qualifiers from all indermediate levels of T2), | ||||||
557 | /// as (effectively) required by [expr.const.cast]p7 replacing T1's qualifiers | ||||||
558 | /// with those from T2. | ||||||
559 | static CastAwayConstnessKind | ||||||
560 | unwrapCastAwayConstnessLevel(ASTContext &Context, QualType &T1, QualType &T2) { | ||||||
561 | enum { None, Ptr, MemPtr, BlockPtr, Array }; | ||||||
562 | auto Classify = [](QualType T) { | ||||||
563 | if (T->isAnyPointerType()) return Ptr; | ||||||
564 | if (T->isMemberPointerType()) return MemPtr; | ||||||
565 | if (T->isBlockPointerType()) return BlockPtr; | ||||||
566 | // We somewhat-arbitrarily don't look through VLA types here. This is at | ||||||
567 | // least consistent with the behavior of UnwrapSimilarTypes. | ||||||
568 | if (T->isConstantArrayType() || T->isIncompleteArrayType()) return Array; | ||||||
569 | return None; | ||||||
570 | }; | ||||||
571 | |||||||
572 | auto Unwrap = [&](QualType T) { | ||||||
573 | if (auto *AT = Context.getAsArrayType(T)) | ||||||
574 | return AT->getElementType(); | ||||||
575 | return T->getPointeeType(); | ||||||
576 | }; | ||||||
577 | |||||||
578 | CastAwayConstnessKind Kind; | ||||||
579 | |||||||
580 | if (T2->isReferenceType()) { | ||||||
581 | // Special case: if the destination type is a reference type, unwrap it as | ||||||
582 | // the first level. (The source will have been an lvalue expression in this | ||||||
583 | // case, so there is no corresponding "reference to" in T1 to remove.) This | ||||||
584 | // simulates removing a "pointer to" from both sides. | ||||||
585 | T2 = T2->getPointeeType(); | ||||||
586 | Kind = CastAwayConstnessKind::CACK_Similar; | ||||||
587 | } else if (Context.UnwrapSimilarTypes(T1, T2)) { | ||||||
588 | Kind = CastAwayConstnessKind::CACK_Similar; | ||||||
589 | } else { | ||||||
590 | // Try unwrapping mismatching levels. | ||||||
591 | int T1Class = Classify(T1); | ||||||
592 | if (T1Class == None) | ||||||
593 | return CastAwayConstnessKind::CACK_None; | ||||||
594 | |||||||
595 | int T2Class = Classify(T2); | ||||||
596 | if (T2Class == None) | ||||||
597 | return CastAwayConstnessKind::CACK_None; | ||||||
598 | |||||||
599 | T1 = Unwrap(T1); | ||||||
600 | T2 = Unwrap(T2); | ||||||
601 | Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind | ||||||
602 | : CastAwayConstnessKind::CACK_Incoherent; | ||||||
603 | } | ||||||
604 | |||||||
605 | // We've unwrapped at least one level. If the resulting T1 is a (possibly | ||||||
606 | // multidimensional) array type, any qualifier on any matching layer of | ||||||
607 | // T2 is considered to correspond to T1. Decompose down to the element | ||||||
608 | // type of T1 so that we can compare properly. | ||||||
609 | while (true) { | ||||||
610 | Context.UnwrapSimilarArrayTypes(T1, T2); | ||||||
611 | |||||||
612 | if (Classify(T1) != Array) | ||||||
613 | break; | ||||||
614 | |||||||
615 | auto T2Class = Classify(T2); | ||||||
616 | if (T2Class == None) | ||||||
617 | break; | ||||||
618 | |||||||
619 | if (T2Class != Array) | ||||||
620 | Kind = CastAwayConstnessKind::CACK_Incoherent; | ||||||
621 | else if (Kind != CastAwayConstnessKind::CACK_Incoherent) | ||||||
622 | Kind = CastAwayConstnessKind::CACK_SimilarKind; | ||||||
623 | |||||||
624 | T1 = Unwrap(T1); | ||||||
625 | T2 = Unwrap(T2).withCVRQualifiers(T2.getCVRQualifiers()); | ||||||
626 | } | ||||||
627 | |||||||
628 | return Kind; | ||||||
629 | } | ||||||
630 | |||||||
631 | /// Check if the pointer conversion from SrcType to DestType casts away | ||||||
632 | /// constness as defined in C++ [expr.const.cast]. This is used by the cast | ||||||
633 | /// checkers. Both arguments must denote pointer (possibly to member) types. | ||||||
634 | /// | ||||||
635 | /// \param CheckCVR Whether to check for const/volatile/restrict qualifiers. | ||||||
636 | /// \param CheckObjCLifetime Whether to check Objective-C lifetime qualifiers. | ||||||
637 | static CastAwayConstnessKind | ||||||
638 | CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, | ||||||
639 | bool CheckCVR, bool CheckObjCLifetime, | ||||||
640 | QualType *TheOffendingSrcType = nullptr, | ||||||
641 | QualType *TheOffendingDestType = nullptr, | ||||||
642 | Qualifiers *CastAwayQualifiers = nullptr) { | ||||||
643 | // If the only checking we care about is for Objective-C lifetime qualifiers, | ||||||
644 | // and we're not in ObjC mode, there's nothing to check. | ||||||
645 | if (!CheckCVR && CheckObjCLifetime && !Self.Context.getLangOpts().ObjC) | ||||||
646 | return CastAwayConstnessKind::CACK_None; | ||||||
647 | |||||||
648 | if (!DestType->isReferenceType()) { | ||||||
649 | assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() ||(static_cast <bool> ((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() || SrcType->isBlockPointerType ()) && "Source type is not pointer or pointer to member." ) ? void (0) : __assert_fail ("(SrcType->isAnyPointerType() || SrcType->isMemberPointerType() || SrcType->isBlockPointerType()) && \"Source type is not pointer or pointer to member.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 651, __extension__ __PRETTY_FUNCTION__)) | ||||||
650 | SrcType->isBlockPointerType()) &&(static_cast <bool> ((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() || SrcType->isBlockPointerType ()) && "Source type is not pointer or pointer to member." ) ? void (0) : __assert_fail ("(SrcType->isAnyPointerType() || SrcType->isMemberPointerType() || SrcType->isBlockPointerType()) && \"Source type is not pointer or pointer to member.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 651, __extension__ __PRETTY_FUNCTION__)) | ||||||
651 | "Source type is not pointer or pointer to member.")(static_cast <bool> ((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() || SrcType->isBlockPointerType ()) && "Source type is not pointer or pointer to member." ) ? void (0) : __assert_fail ("(SrcType->isAnyPointerType() || SrcType->isMemberPointerType() || SrcType->isBlockPointerType()) && \"Source type is not pointer or pointer to member.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 651, __extension__ __PRETTY_FUNCTION__)); | ||||||
652 | assert((DestType->isAnyPointerType() || DestType->isMemberPointerType() ||(static_cast <bool> ((DestType->isAnyPointerType() || DestType->isMemberPointerType() || DestType->isBlockPointerType ()) && "Destination type is not pointer or pointer to member." ) ? void (0) : __assert_fail ("(DestType->isAnyPointerType() || DestType->isMemberPointerType() || DestType->isBlockPointerType()) && \"Destination type is not pointer or pointer to member.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 654, __extension__ __PRETTY_FUNCTION__)) | ||||||
653 | DestType->isBlockPointerType()) &&(static_cast <bool> ((DestType->isAnyPointerType() || DestType->isMemberPointerType() || DestType->isBlockPointerType ()) && "Destination type is not pointer or pointer to member." ) ? void (0) : __assert_fail ("(DestType->isAnyPointerType() || DestType->isMemberPointerType() || DestType->isBlockPointerType()) && \"Destination type is not pointer or pointer to member.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 654, __extension__ __PRETTY_FUNCTION__)) | ||||||
654 | "Destination type is not pointer or pointer to member.")(static_cast <bool> ((DestType->isAnyPointerType() || DestType->isMemberPointerType() || DestType->isBlockPointerType ()) && "Destination type is not pointer or pointer to member." ) ? void (0) : __assert_fail ("(DestType->isAnyPointerType() || DestType->isMemberPointerType() || DestType->isBlockPointerType()) && \"Destination type is not pointer or pointer to member.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 654, __extension__ __PRETTY_FUNCTION__)); | ||||||
655 | } | ||||||
656 | |||||||
657 | QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType), | ||||||
658 | UnwrappedDestType = Self.Context.getCanonicalType(DestType); | ||||||
659 | |||||||
660 | // Find the qualifiers. We only care about cvr-qualifiers for the | ||||||
661 | // purpose of this check, because other qualifiers (address spaces, | ||||||
662 | // Objective-C GC, etc.) are part of the type's identity. | ||||||
663 | QualType PrevUnwrappedSrcType = UnwrappedSrcType; | ||||||
664 | QualType PrevUnwrappedDestType = UnwrappedDestType; | ||||||
665 | auto WorstKind = CastAwayConstnessKind::CACK_Similar; | ||||||
666 | bool AllConstSoFar = true; | ||||||
667 | while (auto Kind = unwrapCastAwayConstnessLevel( | ||||||
668 | Self.Context, UnwrappedSrcType, UnwrappedDestType)) { | ||||||
669 | // Track the worst kind of unwrap we needed to do before we found a | ||||||
670 | // problem. | ||||||
671 | if (Kind > WorstKind) | ||||||
672 | WorstKind = Kind; | ||||||
673 | |||||||
674 | // Determine the relevant qualifiers at this level. | ||||||
675 | Qualifiers SrcQuals, DestQuals; | ||||||
676 | Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals); | ||||||
677 | Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals); | ||||||
678 | |||||||
679 | // We do not meaningfully track object const-ness of Objective-C object | ||||||
680 | // types. Remove const from the source type if either the source or | ||||||
681 | // the destination is an Objective-C object type. | ||||||
682 | if (UnwrappedSrcType->isObjCObjectType() || | ||||||
683 | UnwrappedDestType->isObjCObjectType()) | ||||||
684 | SrcQuals.removeConst(); | ||||||
685 | |||||||
686 | if (CheckCVR) { | ||||||
687 | Qualifiers SrcCvrQuals = | ||||||
688 | Qualifiers::fromCVRMask(SrcQuals.getCVRQualifiers()); | ||||||
689 | Qualifiers DestCvrQuals = | ||||||
690 | Qualifiers::fromCVRMask(DestQuals.getCVRQualifiers()); | ||||||
691 | |||||||
692 | if (SrcCvrQuals != DestCvrQuals) { | ||||||
693 | if (CastAwayQualifiers) | ||||||
694 | *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals; | ||||||
695 | |||||||
696 | // If we removed a cvr-qualifier, this is casting away 'constness'. | ||||||
697 | if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals)) { | ||||||
698 | if (TheOffendingSrcType) | ||||||
699 | *TheOffendingSrcType = PrevUnwrappedSrcType; | ||||||
700 | if (TheOffendingDestType) | ||||||
701 | *TheOffendingDestType = PrevUnwrappedDestType; | ||||||
702 | return WorstKind; | ||||||
703 | } | ||||||
704 | |||||||
705 | // If any prior level was not 'const', this is also casting away | ||||||
706 | // 'constness'. We noted the outermost type missing a 'const' already. | ||||||
707 | if (!AllConstSoFar) | ||||||
708 | return WorstKind; | ||||||
709 | } | ||||||
710 | } | ||||||
711 | |||||||
712 | if (CheckObjCLifetime && | ||||||
713 | !DestQuals.compatiblyIncludesObjCLifetime(SrcQuals)) | ||||||
714 | return WorstKind; | ||||||
715 | |||||||
716 | // If we found our first non-const-qualified type, this may be the place | ||||||
717 | // where things start to go wrong. | ||||||
718 | if (AllConstSoFar && !DestQuals.hasConst()) { | ||||||
719 | AllConstSoFar = false; | ||||||
720 | if (TheOffendingSrcType) | ||||||
721 | *TheOffendingSrcType = PrevUnwrappedSrcType; | ||||||
722 | if (TheOffendingDestType) | ||||||
723 | *TheOffendingDestType = PrevUnwrappedDestType; | ||||||
724 | } | ||||||
725 | |||||||
726 | PrevUnwrappedSrcType = UnwrappedSrcType; | ||||||
727 | PrevUnwrappedDestType = UnwrappedDestType; | ||||||
728 | } | ||||||
729 | |||||||
730 | return CastAwayConstnessKind::CACK_None; | ||||||
731 | } | ||||||
732 | |||||||
733 | static TryCastResult getCastAwayConstnessCastKind(CastAwayConstnessKind CACK, | ||||||
734 | unsigned &DiagID) { | ||||||
735 | switch (CACK) { | ||||||
736 | case CastAwayConstnessKind::CACK_None: | ||||||
737 | llvm_unreachable("did not cast away constness")::llvm::llvm_unreachable_internal("did not cast away constness" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 737); | ||||||
738 | |||||||
739 | case CastAwayConstnessKind::CACK_Similar: | ||||||
740 | // FIXME: Accept these as an extension too? | ||||||
741 | case CastAwayConstnessKind::CACK_SimilarKind: | ||||||
742 | DiagID = diag::err_bad_cxx_cast_qualifiers_away; | ||||||
743 | return TC_Failed; | ||||||
744 | |||||||
745 | case CastAwayConstnessKind::CACK_Incoherent: | ||||||
746 | DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent; | ||||||
747 | return TC_Extension; | ||||||
748 | } | ||||||
749 | |||||||
750 | llvm_unreachable("unexpected cast away constness kind")::llvm::llvm_unreachable_internal("unexpected cast away constness kind" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 750); | ||||||
751 | } | ||||||
752 | |||||||
753 | /// CheckDynamicCast - Check that a dynamic_cast\<DestType\>(SrcExpr) is valid. | ||||||
754 | /// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime- | ||||||
755 | /// checked downcasts in class hierarchies. | ||||||
756 | void CastOperation::CheckDynamicCast() { | ||||||
757 | CheckNoDerefRAII NoderefCheck(*this); | ||||||
758 | |||||||
759 | if (ValueKind == VK_PRValue) | ||||||
760 | SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get()); | ||||||
761 | else if (isPlaceholder()) | ||||||
762 | SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get()); | ||||||
763 | if (SrcExpr.isInvalid()) // if conversion failed, don't report another error | ||||||
764 | return; | ||||||
765 | |||||||
766 | QualType OrigSrcType = SrcExpr.get()->getType(); | ||||||
767 | QualType DestType = Self.Context.getCanonicalType(this->DestType); | ||||||
768 | |||||||
769 | // C++ 5.2.7p1: T shall be a pointer or reference to a complete class type, | ||||||
770 | // or "pointer to cv void". | ||||||
771 | |||||||
772 | QualType DestPointee; | ||||||
773 | const PointerType *DestPointer = DestType->getAs<PointerType>(); | ||||||
774 | const ReferenceType *DestReference = nullptr; | ||||||
775 | if (DestPointer) { | ||||||
776 | DestPointee = DestPointer->getPointeeType(); | ||||||
777 | } else if ((DestReference = DestType->getAs<ReferenceType>())) { | ||||||
778 | DestPointee = DestReference->getPointeeType(); | ||||||
779 | } else { | ||||||
780 | Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr) | ||||||
781 | << this->DestType << DestRange; | ||||||
782 | SrcExpr = ExprError(); | ||||||
783 | return; | ||||||
784 | } | ||||||
785 | |||||||
786 | const RecordType *DestRecord = DestPointee->getAs<RecordType>(); | ||||||
787 | if (DestPointee->isVoidType()) { | ||||||
788 | assert(DestPointer && "Reference to void is not possible")(static_cast <bool> (DestPointer && "Reference to void is not possible" ) ? void (0) : __assert_fail ("DestPointer && \"Reference to void is not possible\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 788, __extension__ __PRETTY_FUNCTION__)); | ||||||
789 | } else if (DestRecord) { | ||||||
790 | if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee, | ||||||
791 | diag::err_bad_cast_incomplete, | ||||||
792 | DestRange)) { | ||||||
793 | SrcExpr = ExprError(); | ||||||
794 | return; | ||||||
795 | } | ||||||
796 | } else { | ||||||
797 | Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class) | ||||||
798 | << DestPointee.getUnqualifiedType() << DestRange; | ||||||
799 | SrcExpr = ExprError(); | ||||||
800 | return; | ||||||
801 | } | ||||||
802 | |||||||
803 | // C++0x 5.2.7p2: If T is a pointer type, v shall be an rvalue of a pointer to | ||||||
804 | // complete class type, [...]. If T is an lvalue reference type, v shall be | ||||||
805 | // an lvalue of a complete class type, [...]. If T is an rvalue reference | ||||||
806 | // type, v shall be an expression having a complete class type, [...] | ||||||
807 | QualType SrcType = Self.Context.getCanonicalType(OrigSrcType); | ||||||
808 | QualType SrcPointee; | ||||||
809 | if (DestPointer) { | ||||||
810 | if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) { | ||||||
811 | SrcPointee = SrcPointer->getPointeeType(); | ||||||
812 | } else { | ||||||
813 | Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr) | ||||||
814 | << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange(); | ||||||
815 | SrcExpr = ExprError(); | ||||||
816 | return; | ||||||
817 | } | ||||||
818 | } else if (DestReference->isLValueReferenceType()) { | ||||||
819 | if (!SrcExpr.get()->isLValue()) { | ||||||
820 | Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue) | ||||||
821 | << CT_Dynamic << OrigSrcType << this->DestType << OpRange; | ||||||
822 | } | ||||||
823 | SrcPointee = SrcType; | ||||||
824 | } else { | ||||||
825 | // If we're dynamic_casting from a prvalue to an rvalue reference, we need | ||||||
826 | // to materialize the prvalue before we bind the reference to it. | ||||||
827 | if (SrcExpr.get()->isPRValue()) | ||||||
828 | SrcExpr = Self.CreateMaterializeTemporaryExpr( | ||||||
829 | SrcType, SrcExpr.get(), /*IsLValueReference*/ false); | ||||||
830 | SrcPointee = SrcType; | ||||||
831 | } | ||||||
832 | |||||||
833 | const RecordType *SrcRecord = SrcPointee->getAs<RecordType>(); | ||||||
834 | if (SrcRecord) { | ||||||
835 | if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee, | ||||||
836 | diag::err_bad_cast_incomplete, | ||||||
837 | SrcExpr.get())) { | ||||||
838 | SrcExpr = ExprError(); | ||||||
839 | return; | ||||||
840 | } | ||||||
841 | } else { | ||||||
842 | Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class) | ||||||
843 | << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange(); | ||||||
844 | SrcExpr = ExprError(); | ||||||
845 | return; | ||||||
846 | } | ||||||
847 | |||||||
848 | assert((DestPointer || DestReference) &&(static_cast <bool> ((DestPointer || DestReference) && "Bad destination non-ptr/ref slipped through.") ? void (0) : __assert_fail ("(DestPointer || DestReference) && \"Bad destination non-ptr/ref slipped through.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 849, __extension__ __PRETTY_FUNCTION__)) | ||||||
849 | "Bad destination non-ptr/ref slipped through.")(static_cast <bool> ((DestPointer || DestReference) && "Bad destination non-ptr/ref slipped through.") ? void (0) : __assert_fail ("(DestPointer || DestReference) && \"Bad destination non-ptr/ref slipped through.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 849, __extension__ __PRETTY_FUNCTION__)); | ||||||
850 | assert((DestRecord || DestPointee->isVoidType()) &&(static_cast <bool> ((DestRecord || DestPointee->isVoidType ()) && "Bad destination pointee slipped through.") ? void (0) : __assert_fail ("(DestRecord || DestPointee->isVoidType()) && \"Bad destination pointee slipped through.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 851, __extension__ __PRETTY_FUNCTION__)) | ||||||
851 | "Bad destination pointee slipped through.")(static_cast <bool> ((DestRecord || DestPointee->isVoidType ()) && "Bad destination pointee slipped through.") ? void (0) : __assert_fail ("(DestRecord || DestPointee->isVoidType()) && \"Bad destination pointee slipped through.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 851, __extension__ __PRETTY_FUNCTION__)); | ||||||
852 | assert(SrcRecord && "Bad source pointee slipped through.")(static_cast <bool> (SrcRecord && "Bad source pointee slipped through." ) ? void (0) : __assert_fail ("SrcRecord && \"Bad source pointee slipped through.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 852, __extension__ __PRETTY_FUNCTION__)); | ||||||
853 | |||||||
854 | // C++ 5.2.7p1: The dynamic_cast operator shall not cast away constness. | ||||||
855 | if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) { | ||||||
856 | Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away) | ||||||
857 | << CT_Dynamic << OrigSrcType << this->DestType << OpRange; | ||||||
858 | SrcExpr = ExprError(); | ||||||
859 | return; | ||||||
860 | } | ||||||
861 | |||||||
862 | // C++ 5.2.7p3: If the type of v is the same as the required result type, | ||||||
863 | // [except for cv]. | ||||||
864 | if (DestRecord == SrcRecord) { | ||||||
865 | Kind = CK_NoOp; | ||||||
866 | return; | ||||||
867 | } | ||||||
868 | |||||||
869 | // C++ 5.2.7p5 | ||||||
870 | // Upcasts are resolved statically. | ||||||
871 | if (DestRecord && | ||||||
872 | Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) { | ||||||
873 | if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee, | ||||||
874 | OpRange.getBegin(), OpRange, | ||||||
875 | &BasePath)) { | ||||||
876 | SrcExpr = ExprError(); | ||||||
877 | return; | ||||||
878 | } | ||||||
879 | |||||||
880 | Kind = CK_DerivedToBase; | ||||||
881 | return; | ||||||
882 | } | ||||||
883 | |||||||
884 | // C++ 5.2.7p6: Otherwise, v shall be [polymorphic]. | ||||||
885 | const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition(); | ||||||
886 | assert(SrcDecl && "Definition missing")(static_cast <bool> (SrcDecl && "Definition missing" ) ? void (0) : __assert_fail ("SrcDecl && \"Definition missing\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 886, __extension__ __PRETTY_FUNCTION__)); | ||||||
887 | if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) { | ||||||
888 | Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic) | ||||||
889 | << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange(); | ||||||
890 | SrcExpr = ExprError(); | ||||||
891 | } | ||||||
892 | |||||||
893 | // dynamic_cast is not available with -fno-rtti. | ||||||
894 | // As an exception, dynamic_cast to void* is available because it doesn't | ||||||
895 | // use RTTI. | ||||||
896 | if (!Self.getLangOpts().RTTI && !DestPointee->isVoidType()) { | ||||||
897 | Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti); | ||||||
898 | SrcExpr = ExprError(); | ||||||
899 | return; | ||||||
900 | } | ||||||
901 | |||||||
902 | // Warns when dynamic_cast is used with RTTI data disabled. | ||||||
903 | if (!Self.getLangOpts().RTTIData) { | ||||||
904 | bool MicrosoftABI = | ||||||
905 | Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft(); | ||||||
906 | bool isClangCL = Self.getDiagnostics().getDiagnosticOptions().getFormat() == | ||||||
907 | DiagnosticOptions::MSVC; | ||||||
908 | if (MicrosoftABI || !DestPointee->isVoidType()) | ||||||
909 | Self.Diag(OpRange.getBegin(), | ||||||
910 | diag::warn_no_dynamic_cast_with_rtti_disabled) | ||||||
911 | << isClangCL; | ||||||
912 | } | ||||||
913 | |||||||
914 | // Done. Everything else is run-time checks. | ||||||
915 | Kind = CK_Dynamic; | ||||||
916 | } | ||||||
917 | |||||||
918 | /// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid. | ||||||
919 | /// Refer to C++ 5.2.11 for details. const_cast is typically used in code | ||||||
920 | /// like this: | ||||||
921 | /// const char *str = "literal"; | ||||||
922 | /// legacy_function(const_cast\<char*\>(str)); | ||||||
923 | void CastOperation::CheckConstCast() { | ||||||
924 | CheckNoDerefRAII NoderefCheck(*this); | ||||||
925 | |||||||
926 | if (ValueKind == VK_PRValue) | ||||||
927 | SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get()); | ||||||
928 | else if (isPlaceholder()) | ||||||
929 | SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get()); | ||||||
930 | if (SrcExpr.isInvalid()) // if conversion failed, don't report another error | ||||||
931 | return; | ||||||
932 | |||||||
933 | unsigned msg = diag::err_bad_cxx_cast_generic; | ||||||
934 | auto TCR = TryConstCast(Self, SrcExpr, DestType, /*CStyle*/ false, msg); | ||||||
935 | if (TCR != TC_Success && msg != 0) { | ||||||
936 | Self.Diag(OpRange.getBegin(), msg) << CT_Const | ||||||
937 | << SrcExpr.get()->getType() << DestType << OpRange; | ||||||
938 | } | ||||||
939 | if (!isValidCast(TCR)) | ||||||
940 | SrcExpr = ExprError(); | ||||||
941 | } | ||||||
942 | |||||||
943 | void CastOperation::CheckAddrspaceCast() { | ||||||
944 | unsigned msg = diag::err_bad_cxx_cast_generic; | ||||||
945 | auto TCR = | ||||||
946 | TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ false, msg, Kind); | ||||||
947 | if (TCR != TC_Success && msg != 0) { | ||||||
948 | Self.Diag(OpRange.getBegin(), msg) | ||||||
949 | << CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange; | ||||||
950 | } | ||||||
951 | if (!isValidCast(TCR)) | ||||||
952 | SrcExpr = ExprError(); | ||||||
953 | } | ||||||
954 | |||||||
955 | /// Check that a reinterpret_cast\<DestType\>(SrcExpr) is not used as upcast | ||||||
956 | /// or downcast between respective pointers or references. | ||||||
957 | static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, | ||||||
958 | QualType DestType, | ||||||
959 | SourceRange OpRange) { | ||||||
960 | QualType SrcType = SrcExpr->getType(); | ||||||
961 | // When casting from pointer or reference, get pointee type; use original | ||||||
962 | // type otherwise. | ||||||
963 | const CXXRecordDecl *SrcPointeeRD = SrcType->getPointeeCXXRecordDecl(); | ||||||
964 | const CXXRecordDecl *SrcRD = | ||||||
965 | SrcPointeeRD ? SrcPointeeRD : SrcType->getAsCXXRecordDecl(); | ||||||
966 | |||||||
967 | // Examining subobjects for records is only possible if the complete and | ||||||
968 | // valid definition is available. Also, template instantiation is not | ||||||
969 | // allowed here. | ||||||
970 | if (!SrcRD || !SrcRD->isCompleteDefinition() || SrcRD->isInvalidDecl()) | ||||||
971 | return; | ||||||
972 | |||||||
973 | const CXXRecordDecl *DestRD = DestType->getPointeeCXXRecordDecl(); | ||||||
974 | |||||||
975 | if (!DestRD || !DestRD->isCompleteDefinition() || DestRD->isInvalidDecl()) | ||||||
976 | return; | ||||||
977 | |||||||
978 | enum { | ||||||
979 | ReinterpretUpcast, | ||||||
980 | ReinterpretDowncast | ||||||
981 | } ReinterpretKind; | ||||||
982 | |||||||
983 | CXXBasePaths BasePaths; | ||||||
984 | |||||||
985 | if (SrcRD->isDerivedFrom(DestRD, BasePaths)) | ||||||
986 | ReinterpretKind = ReinterpretUpcast; | ||||||
987 | else if (DestRD->isDerivedFrom(SrcRD, BasePaths)) | ||||||
988 | ReinterpretKind = ReinterpretDowncast; | ||||||
989 | else | ||||||
990 | return; | ||||||
991 | |||||||
992 | bool VirtualBase = true; | ||||||
993 | bool NonZeroOffset = false; | ||||||
994 | for (CXXBasePaths::const_paths_iterator I = BasePaths.begin(), | ||||||
995 | E = BasePaths.end(); | ||||||
996 | I != E; ++I) { | ||||||
997 | const CXXBasePath &Path = *I; | ||||||
998 | CharUnits Offset = CharUnits::Zero(); | ||||||
999 | bool IsVirtual = false; | ||||||
1000 | for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end(); | ||||||
1001 | IElem != EElem; ++IElem) { | ||||||
1002 | IsVirtual = IElem->Base->isVirtual(); | ||||||
1003 | if (IsVirtual) | ||||||
1004 | break; | ||||||
1005 | const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl(); | ||||||
1006 | assert(BaseRD && "Base type should be a valid unqualified class type")(static_cast <bool> (BaseRD && "Base type should be a valid unqualified class type" ) ? void (0) : __assert_fail ("BaseRD && \"Base type should be a valid unqualified class type\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 1006, __extension__ __PRETTY_FUNCTION__)); | ||||||
1007 | // Don't check if any base has invalid declaration or has no definition | ||||||
1008 | // since it has no layout info. | ||||||
1009 | const CXXRecordDecl *Class = IElem->Class, | ||||||
1010 | *ClassDefinition = Class->getDefinition(); | ||||||
1011 | if (Class->isInvalidDecl() || !ClassDefinition || | ||||||
1012 | !ClassDefinition->isCompleteDefinition()) | ||||||
1013 | return; | ||||||
1014 | |||||||
1015 | const ASTRecordLayout &DerivedLayout = | ||||||
1016 | Self.Context.getASTRecordLayout(Class); | ||||||
1017 | Offset += DerivedLayout.getBaseClassOffset(BaseRD); | ||||||
1018 | } | ||||||
1019 | if (!IsVirtual) { | ||||||
1020 | // Don't warn if any path is a non-virtually derived base at offset zero. | ||||||
1021 | if (Offset.isZero()) | ||||||
1022 | return; | ||||||
1023 | // Offset makes sense only for non-virtual bases. | ||||||
1024 | else | ||||||
1025 | NonZeroOffset = true; | ||||||
1026 | } | ||||||
1027 | VirtualBase = VirtualBase && IsVirtual; | ||||||
1028 | } | ||||||
1029 | |||||||
1030 | (void) NonZeroOffset; // Silence set but not used warning. | ||||||
1031 | assert((VirtualBase || NonZeroOffset) &&(static_cast <bool> ((VirtualBase || NonZeroOffset) && "Should have returned if has non-virtual base with zero offset" ) ? void (0) : __assert_fail ("(VirtualBase || NonZeroOffset) && \"Should have returned if has non-virtual base with zero offset\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 1032, __extension__ __PRETTY_FUNCTION__)) | ||||||
1032 | "Should have returned if has non-virtual base with zero offset")(static_cast <bool> ((VirtualBase || NonZeroOffset) && "Should have returned if has non-virtual base with zero offset" ) ? void (0) : __assert_fail ("(VirtualBase || NonZeroOffset) && \"Should have returned if has non-virtual base with zero offset\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 1032, __extension__ __PRETTY_FUNCTION__)); | ||||||
1033 | |||||||
1034 | QualType BaseType = | ||||||
1035 | ReinterpretKind == ReinterpretUpcast? DestType : SrcType; | ||||||
1036 | QualType DerivedType = | ||||||
1037 | ReinterpretKind == ReinterpretUpcast? SrcType : DestType; | ||||||
1038 | |||||||
1039 | SourceLocation BeginLoc = OpRange.getBegin(); | ||||||
1040 | Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static) | ||||||
1041 | << DerivedType << BaseType << !VirtualBase << int(ReinterpretKind) | ||||||
1042 | << OpRange; | ||||||
1043 | Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static) | ||||||
1044 | << int(ReinterpretKind) | ||||||
1045 | << FixItHint::CreateReplacement(BeginLoc, "static_cast"); | ||||||
1046 | } | ||||||
1047 | |||||||
1048 | static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType, | ||||||
1049 | ASTContext &Context) { | ||||||
1050 | if (SrcType->isPointerType() && DestType->isPointerType()) | ||||||
1051 | return true; | ||||||
1052 | |||||||
1053 | // Allow integral type mismatch if their size are equal. | ||||||
1054 | if (SrcType->isIntegralType(Context) && DestType->isIntegralType(Context)) | ||||||
1055 | if (Context.getTypeInfoInChars(SrcType).Width == | ||||||
1056 | Context.getTypeInfoInChars(DestType).Width) | ||||||
1057 | return true; | ||||||
1058 | |||||||
1059 | return Context.hasSameUnqualifiedType(SrcType, DestType); | ||||||
1060 | } | ||||||
1061 | |||||||
1062 | static bool checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, | ||||||
1063 | QualType DestType) { | ||||||
1064 | if (Self.Diags.isIgnored(diag::warn_cast_function_type, | ||||||
1065 | SrcExpr.get()->getExprLoc())) | ||||||
1066 | return true; | ||||||
1067 | |||||||
1068 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
1069 | const FunctionType *SrcFTy = nullptr; | ||||||
1070 | const FunctionType *DstFTy = nullptr; | ||||||
1071 | if (((SrcType->isBlockPointerType() || SrcType->isFunctionPointerType()) && | ||||||
1072 | DestType->isFunctionPointerType()) || | ||||||
1073 | (SrcType->isMemberFunctionPointerType() && | ||||||
1074 | DestType->isMemberFunctionPointerType())) { | ||||||
1075 | SrcFTy = SrcType->getPointeeType()->castAs<FunctionType>(); | ||||||
1076 | DstFTy = DestType->getPointeeType()->castAs<FunctionType>(); | ||||||
1077 | } else if (SrcType->isFunctionType() && DestType->isFunctionReferenceType()) { | ||||||
1078 | SrcFTy = SrcType->castAs<FunctionType>(); | ||||||
1079 | DstFTy = DestType.getNonReferenceType()->castAs<FunctionType>(); | ||||||
1080 | } else { | ||||||
1081 | return true; | ||||||
1082 | } | ||||||
1083 | assert(SrcFTy && DstFTy)(static_cast <bool> (SrcFTy && DstFTy) ? void ( 0) : __assert_fail ("SrcFTy && DstFTy", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 1083, __extension__ __PRETTY_FUNCTION__)); | ||||||
1084 | |||||||
1085 | auto IsVoidVoid = [](const FunctionType *T) { | ||||||
1086 | if (!T->getReturnType()->isVoidType()) | ||||||
1087 | return false; | ||||||
1088 | if (const auto *PT = T->getAs<FunctionProtoType>()) | ||||||
1089 | return !PT->isVariadic() && PT->getNumParams() == 0; | ||||||
1090 | return false; | ||||||
1091 | }; | ||||||
1092 | |||||||
1093 | // Skip if either function type is void(*)(void) | ||||||
1094 | if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy)) | ||||||
1095 | return true; | ||||||
1096 | |||||||
1097 | // Check return type. | ||||||
1098 | if (!argTypeIsABIEquivalent(SrcFTy->getReturnType(), DstFTy->getReturnType(), | ||||||
1099 | Self.Context)) | ||||||
1100 | return false; | ||||||
1101 | |||||||
1102 | // Check if either has unspecified number of parameters | ||||||
1103 | if (SrcFTy->isFunctionNoProtoType() || DstFTy->isFunctionNoProtoType()) | ||||||
1104 | return true; | ||||||
1105 | |||||||
1106 | // Check parameter types. | ||||||
1107 | |||||||
1108 | const auto *SrcFPTy = cast<FunctionProtoType>(SrcFTy); | ||||||
1109 | const auto *DstFPTy = cast<FunctionProtoType>(DstFTy); | ||||||
1110 | |||||||
1111 | // In a cast involving function types with a variable argument list only the | ||||||
1112 | // types of initial arguments that are provided are considered. | ||||||
1113 | unsigned NumParams = SrcFPTy->getNumParams(); | ||||||
1114 | unsigned DstNumParams = DstFPTy->getNumParams(); | ||||||
1115 | if (NumParams > DstNumParams) { | ||||||
1116 | if (!DstFPTy->isVariadic()) | ||||||
1117 | return false; | ||||||
1118 | NumParams = DstNumParams; | ||||||
1119 | } else if (NumParams < DstNumParams) { | ||||||
1120 | if (!SrcFPTy->isVariadic()) | ||||||
1121 | return false; | ||||||
1122 | } | ||||||
1123 | |||||||
1124 | for (unsigned i = 0; i < NumParams; ++i) | ||||||
1125 | if (!argTypeIsABIEquivalent(SrcFPTy->getParamType(i), | ||||||
1126 | DstFPTy->getParamType(i), Self.Context)) | ||||||
1127 | return false; | ||||||
1128 | |||||||
1129 | return true; | ||||||
1130 | } | ||||||
1131 | |||||||
1132 | /// CheckReinterpretCast - Check that a reinterpret_cast\<DestType\>(SrcExpr) is | ||||||
1133 | /// valid. | ||||||
1134 | /// Refer to C++ 5.2.10 for details. reinterpret_cast is typically used in code | ||||||
1135 | /// like this: | ||||||
1136 | /// char *bytes = reinterpret_cast\<char*\>(int_ptr); | ||||||
1137 | void CastOperation::CheckReinterpretCast() { | ||||||
1138 | if (ValueKind == VK_PRValue && !isPlaceholder(BuiltinType::Overload)) | ||||||
1139 | SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get()); | ||||||
1140 | else | ||||||
1141 | checkNonOverloadPlaceholders(); | ||||||
1142 | if (SrcExpr.isInvalid()) // if conversion failed, don't report another error | ||||||
1143 | return; | ||||||
1144 | |||||||
1145 | unsigned msg = diag::err_bad_cxx_cast_generic; | ||||||
1146 | TryCastResult tcr = | ||||||
1147 | TryReinterpretCast(Self, SrcExpr, DestType, | ||||||
1148 | /*CStyle*/false, OpRange, msg, Kind); | ||||||
1149 | if (tcr != TC_Success && msg != 0) { | ||||||
1150 | if (SrcExpr.isInvalid()) // if conversion failed, don't report another error | ||||||
1151 | return; | ||||||
1152 | if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { | ||||||
1153 | //FIXME: &f<int>; is overloaded and resolvable | ||||||
1154 | Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload) | ||||||
1155 | << OverloadExpr::find(SrcExpr.get()).Expression->getName() | ||||||
1156 | << DestType << OpRange; | ||||||
1157 | Self.NoteAllOverloadCandidates(SrcExpr.get()); | ||||||
1158 | |||||||
1159 | } else { | ||||||
1160 | diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), | ||||||
1161 | DestType, /*listInitialization=*/false); | ||||||
1162 | } | ||||||
1163 | } | ||||||
1164 | |||||||
1165 | if (isValidCast(tcr)) { | ||||||
1166 | if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) | ||||||
1167 | checkObjCConversion(Sema::CCK_OtherCast); | ||||||
1168 | DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange); | ||||||
1169 | |||||||
1170 | if (!checkCastFunctionType(Self, SrcExpr, DestType)) | ||||||
1171 | Self.Diag(OpRange.getBegin(), diag::warn_cast_function_type) | ||||||
1172 | << SrcExpr.get()->getType() << DestType << OpRange; | ||||||
1173 | } else { | ||||||
1174 | SrcExpr = ExprError(); | ||||||
1175 | } | ||||||
1176 | } | ||||||
1177 | |||||||
1178 | |||||||
1179 | /// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid. | ||||||
1180 | /// Refer to C++ 5.2.9 for details. Static casts are mostly used for making | ||||||
1181 | /// implicit conversions explicit and getting rid of data loss warnings. | ||||||
1182 | void CastOperation::CheckStaticCast() { | ||||||
1183 | CheckNoDerefRAII NoderefCheck(*this); | ||||||
1184 | |||||||
1185 | if (isPlaceholder()) { | ||||||
| |||||||
1186 | checkNonOverloadPlaceholders(); | ||||||
1187 | if (SrcExpr.isInvalid()) | ||||||
1188 | return; | ||||||
1189 | } | ||||||
1190 | |||||||
1191 | // This test is outside everything else because it's the only case where | ||||||
1192 | // a non-lvalue-reference target type does not lead to decay. | ||||||
1193 | // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". | ||||||
1194 | if (DestType->isVoidType()) { | ||||||
1195 | Kind = CK_ToVoid; | ||||||
1196 | |||||||
1197 | if (claimPlaceholder(BuiltinType::Overload)) { | ||||||
1198 | Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr, | ||||||
1199 | false, // Decay Function to ptr | ||||||
1200 | true, // Complain | ||||||
1201 | OpRange, DestType, diag::err_bad_static_cast_overload); | ||||||
1202 | if (SrcExpr.isInvalid()) | ||||||
1203 | return; | ||||||
1204 | } | ||||||
1205 | |||||||
1206 | SrcExpr = Self.IgnoredValueConversions(SrcExpr.get()); | ||||||
1207 | return; | ||||||
1208 | } | ||||||
1209 | |||||||
1210 | if (ValueKind == VK_PRValue && !DestType->isRecordType() && | ||||||
1211 | !isPlaceholder(BuiltinType::Overload)) { | ||||||
1212 | SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get()); | ||||||
1213 | if (SrcExpr.isInvalid()) // if conversion failed, don't report another error | ||||||
1214 | return; | ||||||
1215 | } | ||||||
1216 | |||||||
1217 | unsigned msg = diag::err_bad_cxx_cast_generic; | ||||||
1218 | TryCastResult tcr | ||||||
1219 | = TryStaticCast(Self, SrcExpr, DestType, Sema::CCK_OtherCast, OpRange, msg, | ||||||
1220 | Kind, BasePath, /*ListInitialization=*/false); | ||||||
1221 | if (tcr != TC_Success && msg != 0) { | ||||||
1222 | if (SrcExpr.isInvalid()) | ||||||
1223 | return; | ||||||
1224 | if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { | ||||||
1225 | OverloadExpr* oe = OverloadExpr::find(SrcExpr.get()).Expression; | ||||||
1226 | Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload) | ||||||
1227 | << oe->getName() << DestType << OpRange | ||||||
1228 | << oe->getQualifierLoc().getSourceRange(); | ||||||
1229 | Self.NoteAllOverloadCandidates(SrcExpr.get()); | ||||||
1230 | } else { | ||||||
1231 | diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType, | ||||||
1232 | /*listInitialization=*/false); | ||||||
1233 | } | ||||||
1234 | } | ||||||
1235 | |||||||
1236 | if (isValidCast(tcr)) { | ||||||
1237 | if (Kind == CK_BitCast) | ||||||
1238 | checkCastAlign(); | ||||||
1239 | if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) | ||||||
1240 | checkObjCConversion(Sema::CCK_OtherCast); | ||||||
1241 | } else { | ||||||
1242 | SrcExpr = ExprError(); | ||||||
1243 | } | ||||||
1244 | } | ||||||
1245 | |||||||
1246 | static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) { | ||||||
1247 | auto *SrcPtrType = SrcType->getAs<PointerType>(); | ||||||
1248 | if (!SrcPtrType) | ||||||
1249 | return false; | ||||||
1250 | auto *DestPtrType = DestType->getAs<PointerType>(); | ||||||
1251 | if (!DestPtrType) | ||||||
1252 | return false; | ||||||
1253 | return SrcPtrType->getPointeeType().getAddressSpace() != | ||||||
1254 | DestPtrType->getPointeeType().getAddressSpace(); | ||||||
1255 | } | ||||||
1256 | |||||||
1257 | /// TryStaticCast - Check if a static cast can be performed, and do so if | ||||||
1258 | /// possible. If @p CStyle, ignore access restrictions on hierarchy casting | ||||||
1259 | /// and casting away constness. | ||||||
1260 | static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, | ||||||
1261 | QualType DestType, | ||||||
1262 | Sema::CheckedConversionKind CCK, | ||||||
1263 | SourceRange OpRange, unsigned &msg, | ||||||
1264 | CastKind &Kind, CXXCastPath &BasePath, | ||||||
1265 | bool ListInitialization) { | ||||||
1266 | // Determine whether we have the semantics of a C-style cast. | ||||||
1267 | bool CStyle | ||||||
1268 | = (CCK
| ||||||
1269 | |||||||
1270 | // The order the tests is not entirely arbitrary. There is one conversion | ||||||
1271 | // that can be handled in two different ways. Given: | ||||||
1272 | // struct A {}; | ||||||
1273 | // struct B : public A { | ||||||
1274 | // B(); B(const A&); | ||||||
1275 | // }; | ||||||
1276 | // const A &a = B(); | ||||||
1277 | // the cast static_cast<const B&>(a) could be seen as either a static | ||||||
1278 | // reference downcast, or an explicit invocation of the user-defined | ||||||
1279 | // conversion using B's conversion constructor. | ||||||
1280 | // DR 427 specifies that the downcast is to be applied here. | ||||||
1281 | |||||||
1282 | // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". | ||||||
1283 | // Done outside this function. | ||||||
1284 | |||||||
1285 | TryCastResult tcr; | ||||||
1286 | |||||||
1287 | // C++ 5.2.9p5, reference downcast. | ||||||
1288 | // See the function for details. | ||||||
1289 | // DR 427 specifies that this is to be applied before paragraph 2. | ||||||
1290 | tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle, | ||||||
1291 | OpRange, msg, Kind, BasePath); | ||||||
1292 | if (tcr
| ||||||
1293 | return tcr; | ||||||
1294 | |||||||
1295 | // C++11 [expr.static.cast]p3: | ||||||
1296 | // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2 | ||||||
1297 | // T2" if "cv2 T2" is reference-compatible with "cv1 T1". | ||||||
1298 | tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind, | ||||||
1299 | BasePath, msg); | ||||||
1300 | if (tcr
| ||||||
1301 | return tcr; | ||||||
1302 | |||||||
1303 | // C++ 5.2.9p2: An expression e can be explicitly converted to a type T | ||||||
1304 | // [...] if the declaration "T t(e);" is well-formed, [...]. | ||||||
1305 | tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CCK, OpRange, msg, | ||||||
1306 | Kind, ListInitialization); | ||||||
1307 | if (SrcExpr.isInvalid()) | ||||||
1308 | return TC_Failed; | ||||||
1309 | if (tcr
| ||||||
1310 | return tcr; | ||||||
1311 | |||||||
1312 | // C++ 5.2.9p6: May apply the reverse of any standard conversion, except | ||||||
1313 | // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean | ||||||
1314 | // conversions, subject to further restrictions. | ||||||
1315 | // Also, C++ 5.2.9p1 forbids casting away constness, which makes reversal | ||||||
1316 | // of qualification conversions impossible. | ||||||
1317 | // In the CStyle case, the earlier attempt to const_cast should have taken | ||||||
1318 | // care of reverse qualification conversions. | ||||||
1319 | |||||||
1320 | QualType SrcType = Self.Context.getCanonicalType(SrcExpr.get()->getType()); | ||||||
1321 | |||||||
1322 | // C++0x 5.2.9p9: A value of a scoped enumeration type can be explicitly | ||||||
1323 | // converted to an integral type. [...] A value of a scoped enumeration type | ||||||
1324 | // can also be explicitly converted to a floating-point type [...]. | ||||||
1325 | if (const EnumType *Enum
| ||||||
1326 | if (Enum->getDecl()->isScoped()) { | ||||||
1327 | if (DestType->isBooleanType()) { | ||||||
1328 | Kind = CK_IntegralToBoolean; | ||||||
1329 | return TC_Success; | ||||||
1330 | } else if (DestType->isIntegralType(Self.Context)) { | ||||||
1331 | Kind = CK_IntegralCast; | ||||||
1332 | return TC_Success; | ||||||
1333 | } else if (DestType->isRealFloatingType()) { | ||||||
1334 | Kind = CK_IntegralToFloating; | ||||||
1335 | return TC_Success; | ||||||
1336 | } | ||||||
1337 | } | ||||||
1338 | } | ||||||
1339 | |||||||
1340 | // Reverse integral promotion/conversion. All such conversions are themselves | ||||||
1341 | // again integral promotions or conversions and are thus already handled by | ||||||
1342 | // p2 (TryDirectInitialization above). | ||||||
1343 | // (Note: any data loss warnings should be suppressed.) | ||||||
1344 | // The exception is the reverse of enum->integer, i.e. integer->enum (and | ||||||
1345 | // enum->enum). See also C++ 5.2.9p7. | ||||||
1346 | // The same goes for reverse floating point promotion/conversion and | ||||||
1347 | // floating-integral conversions. Again, only floating->enum is relevant. | ||||||
1348 | if (DestType->isEnumeralType()) { | ||||||
1349 | if (Self.RequireCompleteType(OpRange.getBegin(), DestType, | ||||||
1350 | diag::err_bad_cast_incomplete)) { | ||||||
1351 | SrcExpr = ExprError(); | ||||||
1352 | return TC_Failed; | ||||||
1353 | } | ||||||
1354 | if (SrcType->isIntegralOrEnumerationType()) { | ||||||
1355 | // [expr.static.cast]p10 If the enumeration type has a fixed underlying | ||||||
1356 | // type, the value is first converted to that type by integral conversion | ||||||
1357 | const EnumType *Enum = DestType->getAs<EnumType>(); | ||||||
1358 | Kind = Enum->getDecl()->isFixed() && | ||||||
| |||||||
1359 | Enum->getDecl()->getIntegerType()->isBooleanType() | ||||||
1360 | ? CK_IntegralToBoolean | ||||||
1361 | : CK_IntegralCast; | ||||||
1362 | return TC_Success; | ||||||
1363 | } else if (SrcType->isRealFloatingType()) { | ||||||
1364 | Kind = CK_FloatingToIntegral; | ||||||
1365 | return TC_Success; | ||||||
1366 | } | ||||||
1367 | } | ||||||
1368 | |||||||
1369 | // Reverse pointer upcast. C++ 4.10p3 specifies pointer upcast. | ||||||
1370 | // C++ 5.2.9p8 additionally disallows a cast path through virtual inheritance. | ||||||
1371 | tcr = TryStaticPointerDowncast(Self, SrcType, DestType, CStyle, OpRange, msg, | ||||||
1372 | Kind, BasePath); | ||||||
1373 | if (tcr != TC_NotApplicable) | ||||||
1374 | return tcr; | ||||||
1375 | |||||||
1376 | // Reverse member pointer conversion. C++ 4.11 specifies member pointer | ||||||
1377 | // conversion. C++ 5.2.9p9 has additional information. | ||||||
1378 | // DR54's access restrictions apply here also. | ||||||
1379 | tcr = TryStaticMemberPointerUpcast(Self, SrcExpr, SrcType, DestType, CStyle, | ||||||
1380 | OpRange, msg, Kind, BasePath); | ||||||
1381 | if (tcr != TC_NotApplicable) | ||||||
1382 | return tcr; | ||||||
1383 | |||||||
1384 | // Reverse pointer conversion to void*. C++ 4.10.p2 specifies conversion to | ||||||
1385 | // void*. C++ 5.2.9p10 specifies additional restrictions, which really is | ||||||
1386 | // just the usual constness stuff. | ||||||
1387 | if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) { | ||||||
1388 | QualType SrcPointee = SrcPointer->getPointeeType(); | ||||||
1389 | if (SrcPointee->isVoidType()) { | ||||||
1390 | if (const PointerType *DestPointer = DestType->getAs<PointerType>()) { | ||||||
1391 | QualType DestPointee = DestPointer->getPointeeType(); | ||||||
1392 | if (DestPointee->isIncompleteOrObjectType()) { | ||||||
1393 | // This is definitely the intended conversion, but it might fail due | ||||||
1394 | // to a qualifier violation. Note that we permit Objective-C lifetime | ||||||
1395 | // and GC qualifier mismatches here. | ||||||
1396 | if (!CStyle) { | ||||||
1397 | Qualifiers DestPointeeQuals = DestPointee.getQualifiers(); | ||||||
1398 | Qualifiers SrcPointeeQuals = SrcPointee.getQualifiers(); | ||||||
1399 | DestPointeeQuals.removeObjCGCAttr(); | ||||||
1400 | DestPointeeQuals.removeObjCLifetime(); | ||||||
1401 | SrcPointeeQuals.removeObjCGCAttr(); | ||||||
1402 | SrcPointeeQuals.removeObjCLifetime(); | ||||||
1403 | if (DestPointeeQuals != SrcPointeeQuals && | ||||||
1404 | !DestPointeeQuals.compatiblyIncludes(SrcPointeeQuals)) { | ||||||
1405 | msg = diag::err_bad_cxx_cast_qualifiers_away; | ||||||
1406 | return TC_Failed; | ||||||
1407 | } | ||||||
1408 | } | ||||||
1409 | Kind = IsAddressSpaceConversion(SrcType, DestType) | ||||||
1410 | ? CK_AddressSpaceConversion | ||||||
1411 | : CK_BitCast; | ||||||
1412 | return TC_Success; | ||||||
1413 | } | ||||||
1414 | |||||||
1415 | // Microsoft permits static_cast from 'pointer-to-void' to | ||||||
1416 | // 'pointer-to-function'. | ||||||
1417 | if (!CStyle && Self.getLangOpts().MSVCCompat && | ||||||
1418 | DestPointee->isFunctionType()) { | ||||||
1419 | Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange; | ||||||
1420 | Kind = CK_BitCast; | ||||||
1421 | return TC_Success; | ||||||
1422 | } | ||||||
1423 | } | ||||||
1424 | else if (DestType->isObjCObjectPointerType()) { | ||||||
1425 | // allow both c-style cast and static_cast of objective-c pointers as | ||||||
1426 | // they are pervasive. | ||||||
1427 | Kind = CK_CPointerToObjCPointerCast; | ||||||
1428 | return TC_Success; | ||||||
1429 | } | ||||||
1430 | else if (CStyle && DestType->isBlockPointerType()) { | ||||||
1431 | // allow c-style cast of void * to block pointers. | ||||||
1432 | Kind = CK_AnyPointerToBlockPointerCast; | ||||||
1433 | return TC_Success; | ||||||
1434 | } | ||||||
1435 | } | ||||||
1436 | } | ||||||
1437 | // Allow arbitrary objective-c pointer conversion with static casts. | ||||||
1438 | if (SrcType->isObjCObjectPointerType() && | ||||||
1439 | DestType->isObjCObjectPointerType()) { | ||||||
1440 | Kind = CK_BitCast; | ||||||
1441 | return TC_Success; | ||||||
1442 | } | ||||||
1443 | // Allow ns-pointer to cf-pointer conversion in either direction | ||||||
1444 | // with static casts. | ||||||
1445 | if (!CStyle && | ||||||
1446 | Self.CheckTollFreeBridgeStaticCast(DestType, SrcExpr.get(), Kind)) | ||||||
1447 | return TC_Success; | ||||||
1448 | |||||||
1449 | // See if it looks like the user is trying to convert between | ||||||
1450 | // related record types, and select a better diagnostic if so. | ||||||
1451 | if (auto SrcPointer = SrcType->getAs<PointerType>()) | ||||||
1452 | if (auto DestPointer = DestType->getAs<PointerType>()) | ||||||
1453 | if (SrcPointer->getPointeeType()->getAs<RecordType>() && | ||||||
1454 | DestPointer->getPointeeType()->getAs<RecordType>()) | ||||||
1455 | msg = diag::err_bad_cxx_cast_unrelated_class; | ||||||
1456 | |||||||
1457 | if (SrcType->isMatrixType() && DestType->isMatrixType()) { | ||||||
1458 | if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) { | ||||||
1459 | SrcExpr = ExprError(); | ||||||
1460 | return TC_Failed; | ||||||
1461 | } | ||||||
1462 | return TC_Success; | ||||||
1463 | } | ||||||
1464 | |||||||
1465 | // We tried everything. Everything! Nothing works! :-( | ||||||
1466 | return TC_NotApplicable; | ||||||
1467 | } | ||||||
1468 | |||||||
1469 | /// Tests whether a conversion according to N2844 is valid. | ||||||
1470 | TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, | ||||||
1471 | QualType DestType, bool CStyle, | ||||||
1472 | CastKind &Kind, CXXCastPath &BasePath, | ||||||
1473 | unsigned &msg) { | ||||||
1474 | // C++11 [expr.static.cast]p3: | ||||||
1475 | // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to | ||||||
1476 | // cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1". | ||||||
1477 | const RValueReferenceType *R = DestType->getAs<RValueReferenceType>(); | ||||||
1478 | if (!R) | ||||||
1479 | return TC_NotApplicable; | ||||||
1480 | |||||||
1481 | if (!SrcExpr->isGLValue()) | ||||||
1482 | return TC_NotApplicable; | ||||||
1483 | |||||||
1484 | // Because we try the reference downcast before this function, from now on | ||||||
1485 | // this is the only cast possibility, so we issue an error if we fail now. | ||||||
1486 | // FIXME: Should allow casting away constness if CStyle. | ||||||
1487 | QualType FromType = SrcExpr->getType(); | ||||||
1488 | QualType ToType = R->getPointeeType(); | ||||||
1489 | if (CStyle) { | ||||||
1490 | FromType = FromType.getUnqualifiedType(); | ||||||
1491 | ToType = ToType.getUnqualifiedType(); | ||||||
1492 | } | ||||||
1493 | |||||||
1494 | Sema::ReferenceConversions RefConv; | ||||||
1495 | Sema::ReferenceCompareResult RefResult = Self.CompareReferenceRelationship( | ||||||
1496 | SrcExpr->getBeginLoc(), ToType, FromType, &RefConv); | ||||||
1497 | if (RefResult != Sema::Ref_Compatible) { | ||||||
1498 | if (CStyle || RefResult == Sema::Ref_Incompatible) | ||||||
1499 | return TC_NotApplicable; | ||||||
1500 | // Diagnose types which are reference-related but not compatible here since | ||||||
1501 | // we can provide better diagnostics. In these cases forwarding to | ||||||
1502 | // [expr.static.cast]p4 should never result in a well-formed cast. | ||||||
1503 | msg = SrcExpr->isLValue() ? diag::err_bad_lvalue_to_rvalue_cast | ||||||
1504 | : diag::err_bad_rvalue_to_rvalue_cast; | ||||||
1505 | return TC_Failed; | ||||||
1506 | } | ||||||
1507 | |||||||
1508 | if (RefConv & Sema::ReferenceConversions::DerivedToBase) { | ||||||
1509 | Kind = CK_DerivedToBase; | ||||||
1510 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | ||||||
1511 | /*DetectVirtual=*/true); | ||||||
1512 | if (!Self.IsDerivedFrom(SrcExpr->getBeginLoc(), SrcExpr->getType(), | ||||||
1513 | R->getPointeeType(), Paths)) | ||||||
1514 | return TC_NotApplicable; | ||||||
1515 | |||||||
1516 | Self.BuildBasePathArray(Paths, BasePath); | ||||||
1517 | } else | ||||||
1518 | Kind = CK_NoOp; | ||||||
1519 | |||||||
1520 | return TC_Success; | ||||||
1521 | } | ||||||
1522 | |||||||
1523 | /// Tests whether a conversion according to C++ 5.2.9p5 is valid. | ||||||
1524 | TryCastResult | ||||||
1525 | TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, | ||||||
1526 | bool CStyle, SourceRange OpRange, | ||||||
1527 | unsigned &msg, CastKind &Kind, | ||||||
1528 | CXXCastPath &BasePath) { | ||||||
1529 | // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be | ||||||
1530 | // cast to type "reference to cv2 D", where D is a class derived from B, | ||||||
1531 | // if a valid standard conversion from "pointer to D" to "pointer to B" | ||||||
1532 | // exists, cv2 >= cv1, and B is not a virtual base class of D. | ||||||
1533 | // In addition, DR54 clarifies that the base must be accessible in the | ||||||
1534 | // current context. Although the wording of DR54 only applies to the pointer | ||||||
1535 | // variant of this rule, the intent is clearly for it to apply to the this | ||||||
1536 | // conversion as well. | ||||||
1537 | |||||||
1538 | const ReferenceType *DestReference = DestType->getAs<ReferenceType>(); | ||||||
1539 | if (!DestReference) { | ||||||
1540 | return TC_NotApplicable; | ||||||
1541 | } | ||||||
1542 | bool RValueRef = DestReference->isRValueReferenceType(); | ||||||
1543 | if (!RValueRef && !SrcExpr->isLValue()) { | ||||||
1544 | // We know the left side is an lvalue reference, so we can suggest a reason. | ||||||
1545 | msg = diag::err_bad_cxx_cast_rvalue; | ||||||
1546 | return TC_NotApplicable; | ||||||
1547 | } | ||||||
1548 | |||||||
1549 | QualType DestPointee = DestReference->getPointeeType(); | ||||||
1550 | |||||||
1551 | // FIXME: If the source is a prvalue, we should issue a warning (because the | ||||||
1552 | // cast always has undefined behavior), and for AST consistency, we should | ||||||
1553 | // materialize a temporary. | ||||||
1554 | return TryStaticDowncast(Self, | ||||||
1555 | Self.Context.getCanonicalType(SrcExpr->getType()), | ||||||
1556 | Self.Context.getCanonicalType(DestPointee), CStyle, | ||||||
1557 | OpRange, SrcExpr->getType(), DestType, msg, Kind, | ||||||
1558 | BasePath); | ||||||
1559 | } | ||||||
1560 | |||||||
1561 | /// Tests whether a conversion according to C++ 5.2.9p8 is valid. | ||||||
1562 | TryCastResult | ||||||
1563 | TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, | ||||||
1564 | bool CStyle, SourceRange OpRange, | ||||||
1565 | unsigned &msg, CastKind &Kind, | ||||||
1566 | CXXCastPath &BasePath) { | ||||||
1567 | // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class | ||||||
1568 | // type, can be converted to an rvalue of type "pointer to cv2 D", where D | ||||||
1569 | // is a class derived from B, if a valid standard conversion from "pointer | ||||||
1570 | // to D" to "pointer to B" exists, cv2 >= cv1, and B is not a virtual base | ||||||
1571 | // class of D. | ||||||
1572 | // In addition, DR54 clarifies that the base must be accessible in the | ||||||
1573 | // current context. | ||||||
1574 | |||||||
1575 | const PointerType *DestPointer = DestType->getAs<PointerType>(); | ||||||
1576 | if (!DestPointer) { | ||||||
1577 | return TC_NotApplicable; | ||||||
1578 | } | ||||||
1579 | |||||||
1580 | const PointerType *SrcPointer = SrcType->getAs<PointerType>(); | ||||||
1581 | if (!SrcPointer) { | ||||||
1582 | msg = diag::err_bad_static_cast_pointer_nonpointer; | ||||||
1583 | return TC_NotApplicable; | ||||||
1584 | } | ||||||
1585 | |||||||
1586 | return TryStaticDowncast(Self, | ||||||
1587 | Self.Context.getCanonicalType(SrcPointer->getPointeeType()), | ||||||
1588 | Self.Context.getCanonicalType(DestPointer->getPointeeType()), | ||||||
1589 | CStyle, OpRange, SrcType, DestType, msg, Kind, | ||||||
1590 | BasePath); | ||||||
1591 | } | ||||||
1592 | |||||||
1593 | /// TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and | ||||||
1594 | /// TryStaticPointerDowncast. Tests whether a static downcast from SrcType to | ||||||
1595 | /// DestType is possible and allowed. | ||||||
1596 | TryCastResult | ||||||
1597 | TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, | ||||||
1598 | bool CStyle, SourceRange OpRange, QualType OrigSrcType, | ||||||
1599 | QualType OrigDestType, unsigned &msg, | ||||||
1600 | CastKind &Kind, CXXCastPath &BasePath) { | ||||||
1601 | // We can only work with complete types. But don't complain if it doesn't work | ||||||
1602 | if (!Self.isCompleteType(OpRange.getBegin(), SrcType) || | ||||||
1603 | !Self.isCompleteType(OpRange.getBegin(), DestType)) | ||||||
1604 | return TC_NotApplicable; | ||||||
1605 | |||||||
1606 | // Downcast can only happen in class hierarchies, so we need classes. | ||||||
1607 | if (!DestType->getAs<RecordType>() || !SrcType->getAs<RecordType>()) { | ||||||
1608 | return TC_NotApplicable; | ||||||
1609 | } | ||||||
1610 | |||||||
1611 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | ||||||
1612 | /*DetectVirtual=*/true); | ||||||
1613 | if (!Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths)) { | ||||||
1614 | return TC_NotApplicable; | ||||||
1615 | } | ||||||
1616 | |||||||
1617 | // Target type does derive from source type. Now we're serious. If an error | ||||||
1618 | // appears now, it's not ignored. | ||||||
1619 | // This may not be entirely in line with the standard. Take for example: | ||||||
1620 | // struct A {}; | ||||||
1621 | // struct B : virtual A { | ||||||
1622 | // B(A&); | ||||||
1623 | // }; | ||||||
1624 | // | ||||||
1625 | // void f() | ||||||
1626 | // { | ||||||
1627 | // (void)static_cast<const B&>(*((A*)0)); | ||||||
1628 | // } | ||||||
1629 | // As far as the standard is concerned, p5 does not apply (A is virtual), so | ||||||
1630 | // p2 should be used instead - "const B& t(*((A*)0));" is perfectly valid. | ||||||
1631 | // However, both GCC and Comeau reject this example, and accepting it would | ||||||
1632 | // mean more complex code if we're to preserve the nice error message. | ||||||
1633 | // FIXME: Being 100% compliant here would be nice to have. | ||||||
1634 | |||||||
1635 | // Must preserve cv, as always, unless we're in C-style mode. | ||||||
1636 | if (!CStyle && !DestType.isAtLeastAsQualifiedAs(SrcType)) { | ||||||
1637 | msg = diag::err_bad_cxx_cast_qualifiers_away; | ||||||
1638 | return TC_Failed; | ||||||
1639 | } | ||||||
1640 | |||||||
1641 | if (Paths.isAmbiguous(SrcType.getUnqualifiedType())) { | ||||||
1642 | // This code is analoguous to that in CheckDerivedToBaseConversion, except | ||||||
1643 | // that it builds the paths in reverse order. | ||||||
1644 | // To sum up: record all paths to the base and build a nice string from | ||||||
1645 | // them. Use it to spice up the error message. | ||||||
1646 | if (!Paths.isRecordingPaths()) { | ||||||
1647 | Paths.clear(); | ||||||
1648 | Paths.setRecordingPaths(true); | ||||||
1649 | Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths); | ||||||
1650 | } | ||||||
1651 | std::string PathDisplayStr; | ||||||
1652 | std::set<unsigned> DisplayedPaths; | ||||||
1653 | for (clang::CXXBasePath &Path : Paths) { | ||||||
1654 | if (DisplayedPaths.insert(Path.back().SubobjectNumber).second) { | ||||||
1655 | // We haven't displayed a path to this particular base | ||||||
1656 | // class subobject yet. | ||||||
1657 | PathDisplayStr += "\n "; | ||||||
1658 | for (CXXBasePathElement &PE : llvm::reverse(Path)) | ||||||
1659 | PathDisplayStr += PE.Base->getType().getAsString() + " -> "; | ||||||
1660 | PathDisplayStr += QualType(DestType).getAsString(); | ||||||
1661 | } | ||||||
1662 | } | ||||||
1663 | |||||||
1664 | Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast) | ||||||
1665 | << QualType(SrcType).getUnqualifiedType() | ||||||
1666 | << QualType(DestType).getUnqualifiedType() | ||||||
1667 | << PathDisplayStr << OpRange; | ||||||
1668 | msg = 0; | ||||||
1669 | return TC_Failed; | ||||||
1670 | } | ||||||
1671 | |||||||
1672 | if (Paths.getDetectedVirtual() != nullptr) { | ||||||
1673 | QualType VirtualBase(Paths.getDetectedVirtual(), 0); | ||||||
1674 | Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual) | ||||||
1675 | << OrigSrcType << OrigDestType << VirtualBase << OpRange; | ||||||
1676 | msg = 0; | ||||||
1677 | return TC_Failed; | ||||||
1678 | } | ||||||
1679 | |||||||
1680 | if (!CStyle) { | ||||||
1681 | switch (Self.CheckBaseClassAccess(OpRange.getBegin(), | ||||||
1682 | SrcType, DestType, | ||||||
1683 | Paths.front(), | ||||||
1684 | diag::err_downcast_from_inaccessible_base)) { | ||||||
1685 | case Sema::AR_accessible: | ||||||
1686 | case Sema::AR_delayed: // be optimistic | ||||||
1687 | case Sema::AR_dependent: // be optimistic | ||||||
1688 | break; | ||||||
1689 | |||||||
1690 | case Sema::AR_inaccessible: | ||||||
1691 | msg = 0; | ||||||
1692 | return TC_Failed; | ||||||
1693 | } | ||||||
1694 | } | ||||||
1695 | |||||||
1696 | Self.BuildBasePathArray(Paths, BasePath); | ||||||
1697 | Kind = CK_BaseToDerived; | ||||||
1698 | return TC_Success; | ||||||
1699 | } | ||||||
1700 | |||||||
1701 | /// TryStaticMemberPointerUpcast - Tests whether a conversion according to | ||||||
1702 | /// C++ 5.2.9p9 is valid: | ||||||
1703 | /// | ||||||
1704 | /// An rvalue of type "pointer to member of D of type cv1 T" can be | ||||||
1705 | /// converted to an rvalue of type "pointer to member of B of type cv2 T", | ||||||
1706 | /// where B is a base class of D [...]. | ||||||
1707 | /// | ||||||
1708 | TryCastResult | ||||||
1709 | TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, | ||||||
1710 | QualType DestType, bool CStyle, | ||||||
1711 | SourceRange OpRange, | ||||||
1712 | unsigned &msg, CastKind &Kind, | ||||||
1713 | CXXCastPath &BasePath) { | ||||||
1714 | const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(); | ||||||
1715 | if (!DestMemPtr) | ||||||
1716 | return TC_NotApplicable; | ||||||
1717 | |||||||
1718 | bool WasOverloadedFunction = false; | ||||||
1719 | DeclAccessPair FoundOverload; | ||||||
1720 | if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { | ||||||
1721 | if (FunctionDecl *Fn | ||||||
1722 | = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false, | ||||||
1723 | FoundOverload)) { | ||||||
1724 | CXXMethodDecl *M = cast<CXXMethodDecl>(Fn); | ||||||
1725 | SrcType = Self.Context.getMemberPointerType(Fn->getType(), | ||||||
1726 | Self.Context.getTypeDeclType(M->getParent()).getTypePtr()); | ||||||
1727 | WasOverloadedFunction = true; | ||||||
1728 | } | ||||||
1729 | } | ||||||
1730 | |||||||
1731 | const MemberPointerType *SrcMemPtr = SrcType->getAs<MemberPointerType>(); | ||||||
1732 | if (!SrcMemPtr) { | ||||||
1733 | msg = diag::err_bad_static_cast_member_pointer_nonmp; | ||||||
1734 | return TC_NotApplicable; | ||||||
1735 | } | ||||||
1736 | |||||||
1737 | // Lock down the inheritance model right now in MS ABI, whether or not the | ||||||
1738 | // pointee types are the same. | ||||||
1739 | if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) { | ||||||
1740 | (void)Self.isCompleteType(OpRange.getBegin(), SrcType); | ||||||
1741 | (void)Self.isCompleteType(OpRange.getBegin(), DestType); | ||||||
1742 | } | ||||||
1743 | |||||||
1744 | // T == T, modulo cv | ||||||
1745 | if (!Self.Context.hasSameUnqualifiedType(SrcMemPtr->getPointeeType(), | ||||||
1746 | DestMemPtr->getPointeeType())) | ||||||
1747 | return TC_NotApplicable; | ||||||
1748 | |||||||
1749 | // B base of D | ||||||
1750 | QualType SrcClass(SrcMemPtr->getClass(), 0); | ||||||
1751 | QualType DestClass(DestMemPtr->getClass(), 0); | ||||||
1752 | CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | ||||||
1753 | /*DetectVirtual=*/true); | ||||||
1754 | if (!Self.IsDerivedFrom(OpRange.getBegin(), SrcClass, DestClass, Paths)) | ||||||
1755 | return TC_NotApplicable; | ||||||
1756 | |||||||
1757 | // B is a base of D. But is it an allowed base? If not, it's a hard error. | ||||||
1758 | if (Paths.isAmbiguous(Self.Context.getCanonicalType(DestClass))) { | ||||||
1759 | Paths.clear(); | ||||||
1760 | Paths.setRecordingPaths(true); | ||||||
1761 | bool StillOkay = | ||||||
1762 | Self.IsDerivedFrom(OpRange.getBegin(), SrcClass, DestClass, Paths); | ||||||
1763 | assert(StillOkay)(static_cast <bool> (StillOkay) ? void (0) : __assert_fail ("StillOkay", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 1763, __extension__ __PRETTY_FUNCTION__)); | ||||||
1764 | (void)StillOkay; | ||||||
1765 | std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths); | ||||||
1766 | Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv) | ||||||
1767 | << 1 << SrcClass << DestClass << PathDisplayStr << OpRange; | ||||||
1768 | msg = 0; | ||||||
1769 | return TC_Failed; | ||||||
1770 | } | ||||||
1771 | |||||||
1772 | if (const RecordType *VBase = Paths.getDetectedVirtual()) { | ||||||
1773 | Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual) | ||||||
1774 | << SrcClass << DestClass << QualType(VBase, 0) << OpRange; | ||||||
1775 | msg = 0; | ||||||
1776 | return TC_Failed; | ||||||
1777 | } | ||||||
1778 | |||||||
1779 | if (!CStyle) { | ||||||
1780 | switch (Self.CheckBaseClassAccess(OpRange.getBegin(), | ||||||
1781 | DestClass, SrcClass, | ||||||
1782 | Paths.front(), | ||||||
1783 | diag::err_upcast_to_inaccessible_base)) { | ||||||
1784 | case Sema::AR_accessible: | ||||||
1785 | case Sema::AR_delayed: | ||||||
1786 | case Sema::AR_dependent: | ||||||
1787 | // Optimistically assume that the delayed and dependent cases | ||||||
1788 | // will work out. | ||||||
1789 | break; | ||||||
1790 | |||||||
1791 | case Sema::AR_inaccessible: | ||||||
1792 | msg = 0; | ||||||
1793 | return TC_Failed; | ||||||
1794 | } | ||||||
1795 | } | ||||||
1796 | |||||||
1797 | if (WasOverloadedFunction) { | ||||||
1798 | // Resolve the address of the overloaded function again, this time | ||||||
1799 | // allowing complaints if something goes wrong. | ||||||
1800 | FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), | ||||||
1801 | DestType, | ||||||
1802 | true, | ||||||
1803 | FoundOverload); | ||||||
1804 | if (!Fn) { | ||||||
1805 | msg = 0; | ||||||
1806 | return TC_Failed; | ||||||
1807 | } | ||||||
1808 | |||||||
1809 | SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn); | ||||||
1810 | if (!SrcExpr.isUsable()) { | ||||||
1811 | msg = 0; | ||||||
1812 | return TC_Failed; | ||||||
1813 | } | ||||||
1814 | } | ||||||
1815 | |||||||
1816 | Self.BuildBasePathArray(Paths, BasePath); | ||||||
1817 | Kind = CK_DerivedToBaseMemberPointer; | ||||||
1818 | return TC_Success; | ||||||
1819 | } | ||||||
1820 | |||||||
1821 | /// TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2 | ||||||
1822 | /// is valid: | ||||||
1823 | /// | ||||||
1824 | /// An expression e can be explicitly converted to a type T using a | ||||||
1825 | /// @c static_cast if the declaration "T t(e);" is well-formed [...]. | ||||||
1826 | TryCastResult | ||||||
1827 | TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, | ||||||
1828 | Sema::CheckedConversionKind CCK, | ||||||
1829 | SourceRange OpRange, unsigned &msg, | ||||||
1830 | CastKind &Kind, bool ListInitialization) { | ||||||
1831 | if (DestType->isRecordType()) { | ||||||
1832 | if (Self.RequireCompleteType(OpRange.getBegin(), DestType, | ||||||
1833 | diag::err_bad_cast_incomplete) || | ||||||
1834 | Self.RequireNonAbstractType(OpRange.getBegin(), DestType, | ||||||
1835 | diag::err_allocation_of_abstract_type)) { | ||||||
1836 | msg = 0; | ||||||
1837 | return TC_Failed; | ||||||
1838 | } | ||||||
1839 | } | ||||||
1840 | |||||||
1841 | InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType); | ||||||
1842 | InitializationKind InitKind | ||||||
1843 | = (CCK == Sema::CCK_CStyleCast) | ||||||
1844 | ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange, | ||||||
1845 | ListInitialization) | ||||||
1846 | : (CCK == Sema::CCK_FunctionalCast) | ||||||
1847 | ? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization) | ||||||
1848 | : InitializationKind::CreateCast(OpRange); | ||||||
1849 | Expr *SrcExprRaw = SrcExpr.get(); | ||||||
1850 | // FIXME: Per DR242, we should check for an implicit conversion sequence | ||||||
1851 | // or for a constructor that could be invoked by direct-initialization | ||||||
1852 | // here, not for an initialization sequence. | ||||||
1853 | InitializationSequence InitSeq(Self, Entity, InitKind, SrcExprRaw); | ||||||
1854 | |||||||
1855 | // At this point of CheckStaticCast, if the destination is a reference, | ||||||
1856 | // or the expression is an overload expression this has to work. | ||||||
1857 | // There is no other way that works. | ||||||
1858 | // On the other hand, if we're checking a C-style cast, we've still got | ||||||
1859 | // the reinterpret_cast way. | ||||||
1860 | bool CStyle | ||||||
1861 | = (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast); | ||||||
1862 | if (InitSeq.Failed() && (CStyle || !DestType->isReferenceType())) | ||||||
1863 | return TC_NotApplicable; | ||||||
1864 | |||||||
1865 | ExprResult Result = InitSeq.Perform(Self, Entity, InitKind, SrcExprRaw); | ||||||
1866 | if (Result.isInvalid()) { | ||||||
1867 | msg = 0; | ||||||
1868 | return TC_Failed; | ||||||
1869 | } | ||||||
1870 | |||||||
1871 | if (InitSeq.isConstructorInitialization()) | ||||||
1872 | Kind = CK_ConstructorConversion; | ||||||
1873 | else | ||||||
1874 | Kind = CK_NoOp; | ||||||
1875 | |||||||
1876 | SrcExpr = Result; | ||||||
1877 | return TC_Success; | ||||||
1878 | } | ||||||
1879 | |||||||
1880 | /// TryConstCast - See if a const_cast from source to destination is allowed, | ||||||
1881 | /// and perform it if it is. | ||||||
1882 | static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr, | ||||||
1883 | QualType DestType, bool CStyle, | ||||||
1884 | unsigned &msg) { | ||||||
1885 | DestType = Self.Context.getCanonicalType(DestType); | ||||||
1886 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
1887 | bool NeedToMaterializeTemporary = false; | ||||||
1888 | |||||||
1889 | if (const ReferenceType *DestTypeTmp =DestType->getAs<ReferenceType>()) { | ||||||
1890 | // C++11 5.2.11p4: | ||||||
1891 | // if a pointer to T1 can be explicitly converted to the type "pointer to | ||||||
1892 | // T2" using a const_cast, then the following conversions can also be | ||||||
1893 | // made: | ||||||
1894 | // -- an lvalue of type T1 can be explicitly converted to an lvalue of | ||||||
1895 | // type T2 using the cast const_cast<T2&>; | ||||||
1896 | // -- a glvalue of type T1 can be explicitly converted to an xvalue of | ||||||
1897 | // type T2 using the cast const_cast<T2&&>; and | ||||||
1898 | // -- if T1 is a class type, a prvalue of type T1 can be explicitly | ||||||
1899 | // converted to an xvalue of type T2 using the cast const_cast<T2&&>. | ||||||
1900 | |||||||
1901 | if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.get()->isLValue()) { | ||||||
1902 | // Cannot const_cast non-lvalue to lvalue reference type. But if this | ||||||
1903 | // is C-style, static_cast might find a way, so we simply suggest a | ||||||
1904 | // message and tell the parent to keep searching. | ||||||
1905 | msg = diag::err_bad_cxx_cast_rvalue; | ||||||
1906 | return TC_NotApplicable; | ||||||
1907 | } | ||||||
1908 | |||||||
1909 | if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.get()->isPRValue()) { | ||||||
1910 | if (!SrcType->isRecordType()) { | ||||||
1911 | // Cannot const_cast non-class prvalue to rvalue reference type. But if | ||||||
1912 | // this is C-style, static_cast can do this. | ||||||
1913 | msg = diag::err_bad_cxx_cast_rvalue; | ||||||
1914 | return TC_NotApplicable; | ||||||
1915 | } | ||||||
1916 | |||||||
1917 | // Materialize the class prvalue so that the const_cast can bind a | ||||||
1918 | // reference to it. | ||||||
1919 | NeedToMaterializeTemporary = true; | ||||||
1920 | } | ||||||
1921 | |||||||
1922 | // It's not completely clear under the standard whether we can | ||||||
1923 | // const_cast bit-field gl-values. Doing so would not be | ||||||
1924 | // intrinsically complicated, but for now, we say no for | ||||||
1925 | // consistency with other compilers and await the word of the | ||||||
1926 | // committee. | ||||||
1927 | if (SrcExpr.get()->refersToBitField()) { | ||||||
1928 | msg = diag::err_bad_cxx_cast_bitfield; | ||||||
1929 | return TC_NotApplicable; | ||||||
1930 | } | ||||||
1931 | |||||||
1932 | DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType()); | ||||||
1933 | SrcType = Self.Context.getPointerType(SrcType); | ||||||
1934 | } | ||||||
1935 | |||||||
1936 | // C++ 5.2.11p5: For a const_cast involving pointers to data members [...] | ||||||
1937 | // the rules for const_cast are the same as those used for pointers. | ||||||
1938 | |||||||
1939 | if (!DestType->isPointerType() && | ||||||
1940 | !DestType->isMemberPointerType() && | ||||||
1941 | !DestType->isObjCObjectPointerType()) { | ||||||
1942 | // Cannot cast to non-pointer, non-reference type. Note that, if DestType | ||||||
1943 | // was a reference type, we converted it to a pointer above. | ||||||
1944 | // The status of rvalue references isn't entirely clear, but it looks like | ||||||
1945 | // conversion to them is simply invalid. | ||||||
1946 | // C++ 5.2.11p3: For two pointer types [...] | ||||||
1947 | if (!CStyle) | ||||||
1948 | msg = diag::err_bad_const_cast_dest; | ||||||
1949 | return TC_NotApplicable; | ||||||
1950 | } | ||||||
1951 | if (DestType->isFunctionPointerType() || | ||||||
1952 | DestType->isMemberFunctionPointerType()) { | ||||||
1953 | // Cannot cast direct function pointers. | ||||||
1954 | // C++ 5.2.11p2: [...] where T is any object type or the void type [...] | ||||||
1955 | // T is the ultimate pointee of source and target type. | ||||||
1956 | if (!CStyle) | ||||||
1957 | msg = diag::err_bad_const_cast_dest; | ||||||
1958 | return TC_NotApplicable; | ||||||
1959 | } | ||||||
1960 | |||||||
1961 | // C++ [expr.const.cast]p3: | ||||||
1962 | // "For two similar types T1 and T2, [...]" | ||||||
1963 | // | ||||||
1964 | // We only allow a const_cast to change cvr-qualifiers, not other kinds of | ||||||
1965 | // type qualifiers. (Likewise, we ignore other changes when determining | ||||||
1966 | // whether a cast casts away constness.) | ||||||
1967 | if (!Self.Context.hasCvrSimilarType(SrcType, DestType)) | ||||||
1968 | return TC_NotApplicable; | ||||||
1969 | |||||||
1970 | if (NeedToMaterializeTemporary) | ||||||
1971 | // This is a const_cast from a class prvalue to an rvalue reference type. | ||||||
1972 | // Materialize a temporary to store the result of the conversion. | ||||||
1973 | SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcExpr.get()->getType(), | ||||||
1974 | SrcExpr.get(), | ||||||
1975 | /*IsLValueReference*/ false); | ||||||
1976 | |||||||
1977 | return TC_Success; | ||||||
1978 | } | ||||||
1979 | |||||||
1980 | // Checks for undefined behavior in reinterpret_cast. | ||||||
1981 | // The cases that is checked for is: | ||||||
1982 | // *reinterpret_cast<T*>(&a) | ||||||
1983 | // reinterpret_cast<T&>(a) | ||||||
1984 | // where accessing 'a' as type 'T' will result in undefined behavior. | ||||||
1985 | void Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, | ||||||
1986 | bool IsDereference, | ||||||
1987 | SourceRange Range) { | ||||||
1988 | unsigned DiagID = IsDereference ? | ||||||
1989 | diag::warn_pointer_indirection_from_incompatible_type : | ||||||
1990 | diag::warn_undefined_reinterpret_cast; | ||||||
1991 | |||||||
1992 | if (Diags.isIgnored(DiagID, Range.getBegin())) | ||||||
1993 | return; | ||||||
1994 | |||||||
1995 | QualType SrcTy, DestTy; | ||||||
1996 | if (IsDereference) { | ||||||
1997 | if (!SrcType->getAs<PointerType>() || !DestType->getAs<PointerType>()) { | ||||||
1998 | return; | ||||||
1999 | } | ||||||
2000 | SrcTy = SrcType->getPointeeType(); | ||||||
2001 | DestTy = DestType->getPointeeType(); | ||||||
2002 | } else { | ||||||
2003 | if (!DestType->getAs<ReferenceType>()) { | ||||||
2004 | return; | ||||||
2005 | } | ||||||
2006 | SrcTy = SrcType; | ||||||
2007 | DestTy = DestType->getPointeeType(); | ||||||
2008 | } | ||||||
2009 | |||||||
2010 | // Cast is compatible if the types are the same. | ||||||
2011 | if (Context.hasSameUnqualifiedType(DestTy, SrcTy)) { | ||||||
2012 | return; | ||||||
2013 | } | ||||||
2014 | // or one of the types is a char or void type | ||||||
2015 | if (DestTy->isAnyCharacterType() || DestTy->isVoidType() || | ||||||
2016 | SrcTy->isAnyCharacterType() || SrcTy->isVoidType()) { | ||||||
2017 | return; | ||||||
2018 | } | ||||||
2019 | // or one of the types is a tag type. | ||||||
2020 | if (SrcTy->getAs<TagType>() || DestTy->getAs<TagType>()) { | ||||||
2021 | return; | ||||||
2022 | } | ||||||
2023 | |||||||
2024 | // FIXME: Scoped enums? | ||||||
2025 | if ((SrcTy->isUnsignedIntegerType() && DestTy->isSignedIntegerType()) || | ||||||
2026 | (SrcTy->isSignedIntegerType() && DestTy->isUnsignedIntegerType())) { | ||||||
2027 | if (Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) { | ||||||
2028 | return; | ||||||
2029 | } | ||||||
2030 | } | ||||||
2031 | |||||||
2032 | Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range; | ||||||
2033 | } | ||||||
2034 | |||||||
2035 | static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr, | ||||||
2036 | QualType DestType) { | ||||||
2037 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
2038 | if (Self.Context.hasSameType(SrcType, DestType)) | ||||||
2039 | return; | ||||||
2040 | if (const PointerType *SrcPtrTy = SrcType->getAs<PointerType>()) | ||||||
2041 | if (SrcPtrTy->isObjCSelType()) { | ||||||
2042 | QualType DT = DestType; | ||||||
2043 | if (isa<PointerType>(DestType)) | ||||||
2044 | DT = DestType->getPointeeType(); | ||||||
2045 | if (!DT.getUnqualifiedType()->isVoidType()) | ||||||
2046 | Self.Diag(SrcExpr.get()->getExprLoc(), | ||||||
2047 | diag::warn_cast_pointer_from_sel) | ||||||
2048 | << SrcType << DestType << SrcExpr.get()->getSourceRange(); | ||||||
2049 | } | ||||||
2050 | } | ||||||
2051 | |||||||
2052 | /// Diagnose casts that change the calling convention of a pointer to a function | ||||||
2053 | /// defined in the current TU. | ||||||
2054 | static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr, | ||||||
2055 | QualType DstType, SourceRange OpRange) { | ||||||
2056 | // Check if this cast would change the calling convention of a function | ||||||
2057 | // pointer type. | ||||||
2058 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
2059 | if (Self.Context.hasSameType(SrcType, DstType) || | ||||||
2060 | !SrcType->isFunctionPointerType() || !DstType->isFunctionPointerType()) | ||||||
2061 | return; | ||||||
2062 | const auto *SrcFTy = | ||||||
2063 | SrcType->castAs<PointerType>()->getPointeeType()->castAs<FunctionType>(); | ||||||
2064 | const auto *DstFTy = | ||||||
2065 | DstType->castAs<PointerType>()->getPointeeType()->castAs<FunctionType>(); | ||||||
2066 | CallingConv SrcCC = SrcFTy->getCallConv(); | ||||||
2067 | CallingConv DstCC = DstFTy->getCallConv(); | ||||||
2068 | if (SrcCC == DstCC) | ||||||
2069 | return; | ||||||
2070 | |||||||
2071 | // We have a calling convention cast. Check if the source is a pointer to a | ||||||
2072 | // known, specific function that has already been defined. | ||||||
2073 | Expr *Src = SrcExpr.get()->IgnoreParenImpCasts(); | ||||||
2074 | if (auto *UO = dyn_cast<UnaryOperator>(Src)) | ||||||
2075 | if (UO->getOpcode() == UO_AddrOf) | ||||||
2076 | Src = UO->getSubExpr()->IgnoreParenImpCasts(); | ||||||
2077 | auto *DRE = dyn_cast<DeclRefExpr>(Src); | ||||||
2078 | if (!DRE) | ||||||
2079 | return; | ||||||
2080 | auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl()); | ||||||
2081 | if (!FD) | ||||||
2082 | return; | ||||||
2083 | |||||||
2084 | // Only warn if we are casting from the default convention to a non-default | ||||||
2085 | // convention. This can happen when the programmer forgot to apply the calling | ||||||
2086 | // convention to the function declaration and then inserted this cast to | ||||||
2087 | // satisfy the type system. | ||||||
2088 | CallingConv DefaultCC = Self.getASTContext().getDefaultCallingConvention( | ||||||
2089 | FD->isVariadic(), FD->isCXXInstanceMember()); | ||||||
2090 | if (DstCC == DefaultCC || SrcCC != DefaultCC) | ||||||
2091 | return; | ||||||
2092 | |||||||
2093 | // Diagnose this cast, as it is probably bad. | ||||||
2094 | StringRef SrcCCName = FunctionType::getNameForCallConv(SrcCC); | ||||||
2095 | StringRef DstCCName = FunctionType::getNameForCallConv(DstCC); | ||||||
2096 | Self.Diag(OpRange.getBegin(), diag::warn_cast_calling_conv) | ||||||
2097 | << SrcCCName << DstCCName << OpRange; | ||||||
2098 | |||||||
2099 | // The checks above are cheaper than checking if the diagnostic is enabled. | ||||||
2100 | // However, it's worth checking if the warning is enabled before we construct | ||||||
2101 | // a fixit. | ||||||
2102 | if (Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.getBegin())) | ||||||
2103 | return; | ||||||
2104 | |||||||
2105 | // Try to suggest a fixit to change the calling convention of the function | ||||||
2106 | // whose address was taken. Try to use the latest macro for the convention. | ||||||
2107 | // For example, users probably want to write "WINAPI" instead of "__stdcall" | ||||||
2108 | // to match the Windows header declarations. | ||||||
2109 | SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc(); | ||||||
2110 | Preprocessor &PP = Self.getPreprocessor(); | ||||||
2111 | SmallVector<TokenValue, 6> AttrTokens; | ||||||
2112 | SmallString<64> CCAttrText; | ||||||
2113 | llvm::raw_svector_ostream OS(CCAttrText); | ||||||
2114 | if (Self.getLangOpts().MicrosoftExt) { | ||||||
2115 | // __stdcall or __vectorcall | ||||||
2116 | OS << "__" << DstCCName; | ||||||
2117 | IdentifierInfo *II = PP.getIdentifierInfo(OS.str()); | ||||||
2118 | AttrTokens.push_back(II->isKeyword(Self.getLangOpts()) | ||||||
2119 | ? TokenValue(II->getTokenID()) | ||||||
2120 | : TokenValue(II)); | ||||||
2121 | } else { | ||||||
2122 | // __attribute__((stdcall)) or __attribute__((vectorcall)) | ||||||
2123 | OS << "__attribute__((" << DstCCName << "))"; | ||||||
2124 | AttrTokens.push_back(tok::kw___attribute); | ||||||
2125 | AttrTokens.push_back(tok::l_paren); | ||||||
2126 | AttrTokens.push_back(tok::l_paren); | ||||||
2127 | IdentifierInfo *II = PP.getIdentifierInfo(DstCCName); | ||||||
2128 | AttrTokens.push_back(II->isKeyword(Self.getLangOpts()) | ||||||
2129 | ? TokenValue(II->getTokenID()) | ||||||
2130 | : TokenValue(II)); | ||||||
2131 | AttrTokens.push_back(tok::r_paren); | ||||||
2132 | AttrTokens.push_back(tok::r_paren); | ||||||
2133 | } | ||||||
2134 | StringRef AttrSpelling = PP.getLastMacroWithSpelling(NameLoc, AttrTokens); | ||||||
2135 | if (!AttrSpelling.empty()) | ||||||
2136 | CCAttrText = AttrSpelling; | ||||||
2137 | OS << ' '; | ||||||
2138 | Self.Diag(NameLoc, diag::note_change_calling_conv_fixit) | ||||||
2139 | << FD << DstCCName << FixItHint::CreateInsertion(NameLoc, CCAttrText); | ||||||
2140 | } | ||||||
2141 | |||||||
2142 | static void checkIntToPointerCast(bool CStyle, const SourceRange &OpRange, | ||||||
2143 | const Expr *SrcExpr, QualType DestType, | ||||||
2144 | Sema &Self) { | ||||||
2145 | QualType SrcType = SrcExpr->getType(); | ||||||
2146 | |||||||
2147 | // Not warning on reinterpret_cast, boolean, constant expressions, etc | ||||||
2148 | // are not explicit design choices, but consistent with GCC's behavior. | ||||||
2149 | // Feel free to modify them if you've reason/evidence for an alternative. | ||||||
2150 | if (CStyle && SrcType->isIntegralType(Self.Context) | ||||||
2151 | && !SrcType->isBooleanType() | ||||||
2152 | && !SrcType->isEnumeralType() | ||||||
2153 | && !SrcExpr->isIntegerConstantExpr(Self.Context) | ||||||
2154 | && Self.Context.getTypeSize(DestType) > | ||||||
2155 | Self.Context.getTypeSize(SrcType)) { | ||||||
2156 | // Separate between casts to void* and non-void* pointers. | ||||||
2157 | // Some APIs use (abuse) void* for something like a user context, | ||||||
2158 | // and often that value is an integer even if it isn't a pointer itself. | ||||||
2159 | // Having a separate warning flag allows users to control the warning | ||||||
2160 | // for their workflow. | ||||||
2161 | unsigned Diag = DestType->isVoidPointerType() ? | ||||||
2162 | diag::warn_int_to_void_pointer_cast | ||||||
2163 | : diag::warn_int_to_pointer_cast; | ||||||
2164 | Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange; | ||||||
2165 | } | ||||||
2166 | } | ||||||
2167 | |||||||
2168 | static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, | ||||||
2169 | ExprResult &Result) { | ||||||
2170 | // We can only fix an overloaded reinterpret_cast if | ||||||
2171 | // - it is a template with explicit arguments that resolves to an lvalue | ||||||
2172 | // unambiguously, or | ||||||
2173 | // - it is the only function in an overload set that may have its address | ||||||
2174 | // taken. | ||||||
2175 | |||||||
2176 | Expr *E = Result.get(); | ||||||
2177 | // TODO: what if this fails because of DiagnoseUseOfDecl or something | ||||||
2178 | // like it? | ||||||
2179 | if (Self.ResolveAndFixSingleFunctionTemplateSpecialization( | ||||||
2180 | Result, | ||||||
2181 | Expr::getValueKindForType(DestType) == | ||||||
2182 | VK_PRValue // Convert Fun to Ptr | ||||||
2183 | ) && | ||||||
2184 | Result.isUsable()) | ||||||
2185 | return true; | ||||||
2186 | |||||||
2187 | // No guarantees that ResolveAndFixSingleFunctionTemplateSpecialization | ||||||
2188 | // preserves Result. | ||||||
2189 | Result = E; | ||||||
2190 | if (!Self.resolveAndFixAddressOfSingleOverloadCandidate( | ||||||
2191 | Result, /*DoFunctionPointerConversion=*/true)) | ||||||
2192 | return false; | ||||||
2193 | return Result.isUsable(); | ||||||
2194 | } | ||||||
2195 | |||||||
2196 | static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, | ||||||
2197 | QualType DestType, bool CStyle, | ||||||
2198 | SourceRange OpRange, | ||||||
2199 | unsigned &msg, | ||||||
2200 | CastKind &Kind) { | ||||||
2201 | bool IsLValueCast = false; | ||||||
2202 | |||||||
2203 | DestType = Self.Context.getCanonicalType(DestType); | ||||||
2204 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
2205 | |||||||
2206 | // Is the source an overloaded name? (i.e. &foo) | ||||||
2207 | // If so, reinterpret_cast generally can not help us here (13.4, p1, bullet 5) | ||||||
2208 | if (SrcType == Self.Context.OverloadTy) { | ||||||
2209 | ExprResult FixedExpr = SrcExpr; | ||||||
2210 | if (!fixOverloadedReinterpretCastExpr(Self, DestType, FixedExpr)) | ||||||
2211 | return TC_NotApplicable; | ||||||
2212 | |||||||
2213 | assert(FixedExpr.isUsable() && "Invalid result fixing overloaded expr")(static_cast <bool> (FixedExpr.isUsable() && "Invalid result fixing overloaded expr" ) ? void (0) : __assert_fail ("FixedExpr.isUsable() && \"Invalid result fixing overloaded expr\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2213, __extension__ __PRETTY_FUNCTION__)); | ||||||
2214 | SrcExpr = FixedExpr; | ||||||
2215 | SrcType = SrcExpr.get()->getType(); | ||||||
2216 | } | ||||||
2217 | |||||||
2218 | if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) { | ||||||
2219 | if (!SrcExpr.get()->isGLValue()) { | ||||||
2220 | // Cannot cast non-glvalue to (lvalue or rvalue) reference type. See the | ||||||
2221 | // similar comment in const_cast. | ||||||
2222 | msg = diag::err_bad_cxx_cast_rvalue; | ||||||
2223 | return TC_NotApplicable; | ||||||
2224 | } | ||||||
2225 | |||||||
2226 | if (!CStyle) { | ||||||
2227 | Self.CheckCompatibleReinterpretCast(SrcType, DestType, | ||||||
2228 | /*IsDereference=*/false, OpRange); | ||||||
2229 | } | ||||||
2230 | |||||||
2231 | // C++ 5.2.10p10: [...] a reference cast reinterpret_cast<T&>(x) has the | ||||||
2232 | // same effect as the conversion *reinterpret_cast<T*>(&x) with the | ||||||
2233 | // built-in & and * operators. | ||||||
2234 | |||||||
2235 | const char *inappropriate = nullptr; | ||||||
2236 | switch (SrcExpr.get()->getObjectKind()) { | ||||||
2237 | case OK_Ordinary: | ||||||
2238 | break; | ||||||
2239 | case OK_BitField: | ||||||
2240 | msg = diag::err_bad_cxx_cast_bitfield; | ||||||
2241 | return TC_NotApplicable; | ||||||
2242 | // FIXME: Use a specific diagnostic for the rest of these cases. | ||||||
2243 | case OK_VectorComponent: inappropriate = "vector element"; break; | ||||||
2244 | case OK_MatrixComponent: | ||||||
2245 | inappropriate = "matrix element"; | ||||||
2246 | break; | ||||||
2247 | case OK_ObjCProperty: inappropriate = "property expression"; break; | ||||||
2248 | case OK_ObjCSubscript: inappropriate = "container subscripting expression"; | ||||||
2249 | break; | ||||||
2250 | } | ||||||
2251 | if (inappropriate) { | ||||||
2252 | Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference) | ||||||
2253 | << inappropriate << DestType | ||||||
2254 | << OpRange << SrcExpr.get()->getSourceRange(); | ||||||
2255 | msg = 0; SrcExpr = ExprError(); | ||||||
2256 | return TC_NotApplicable; | ||||||
2257 | } | ||||||
2258 | |||||||
2259 | // This code does this transformation for the checked types. | ||||||
2260 | DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType()); | ||||||
2261 | SrcType = Self.Context.getPointerType(SrcType); | ||||||
2262 | |||||||
2263 | IsLValueCast = true; | ||||||
2264 | } | ||||||
2265 | |||||||
2266 | // Canonicalize source for comparison. | ||||||
2267 | SrcType = Self.Context.getCanonicalType(SrcType); | ||||||
2268 | |||||||
2269 | const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(), | ||||||
2270 | *SrcMemPtr = SrcType->getAs<MemberPointerType>(); | ||||||
2271 | if (DestMemPtr && SrcMemPtr) { | ||||||
2272 | // C++ 5.2.10p9: An rvalue of type "pointer to member of X of type T1" | ||||||
2273 | // can be explicitly converted to an rvalue of type "pointer to member | ||||||
2274 | // of Y of type T2" if T1 and T2 are both function types or both object | ||||||
2275 | // types. | ||||||
2276 | if (DestMemPtr->isMemberFunctionPointer() != | ||||||
2277 | SrcMemPtr->isMemberFunctionPointer()) | ||||||
2278 | return TC_NotApplicable; | ||||||
2279 | |||||||
2280 | if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) { | ||||||
2281 | // We need to determine the inheritance model that the class will use if | ||||||
2282 | // haven't yet. | ||||||
2283 | (void)Self.isCompleteType(OpRange.getBegin(), SrcType); | ||||||
2284 | (void)Self.isCompleteType(OpRange.getBegin(), DestType); | ||||||
2285 | } | ||||||
2286 | |||||||
2287 | // Don't allow casting between member pointers of different sizes. | ||||||
2288 | if (Self.Context.getTypeSize(DestMemPtr) != | ||||||
2289 | Self.Context.getTypeSize(SrcMemPtr)) { | ||||||
2290 | msg = diag::err_bad_cxx_cast_member_pointer_size; | ||||||
2291 | return TC_Failed; | ||||||
2292 | } | ||||||
2293 | |||||||
2294 | // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away | ||||||
2295 | // constness. | ||||||
2296 | // A reinterpret_cast followed by a const_cast can, though, so in C-style, | ||||||
2297 | // we accept it. | ||||||
2298 | if (auto CACK = | ||||||
2299 | CastsAwayConstness(Self, SrcType, DestType, /*CheckCVR=*/!CStyle, | ||||||
2300 | /*CheckObjCLifetime=*/CStyle)) | ||||||
2301 | return getCastAwayConstnessCastKind(CACK, msg); | ||||||
2302 | |||||||
2303 | // A valid member pointer cast. | ||||||
2304 | assert(!IsLValueCast)(static_cast <bool> (!IsLValueCast) ? void (0) : __assert_fail ("!IsLValueCast", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2304, __extension__ __PRETTY_FUNCTION__)); | ||||||
2305 | Kind = CK_ReinterpretMemberPointer; | ||||||
2306 | return TC_Success; | ||||||
2307 | } | ||||||
2308 | |||||||
2309 | // See below for the enumeral issue. | ||||||
2310 | if (SrcType->isNullPtrType() && DestType->isIntegralType(Self.Context)) { | ||||||
2311 | // C++0x 5.2.10p4: A pointer can be explicitly converted to any integral | ||||||
2312 | // type large enough to hold it. A value of std::nullptr_t can be | ||||||
2313 | // converted to an integral type; the conversion has the same meaning | ||||||
2314 | // and validity as a conversion of (void*)0 to the integral type. | ||||||
2315 | if (Self.Context.getTypeSize(SrcType) > | ||||||
2316 | Self.Context.getTypeSize(DestType)) { | ||||||
2317 | msg = diag::err_bad_reinterpret_cast_small_int; | ||||||
2318 | return TC_Failed; | ||||||
2319 | } | ||||||
2320 | Kind = CK_PointerToIntegral; | ||||||
2321 | return TC_Success; | ||||||
2322 | } | ||||||
2323 | |||||||
2324 | // Allow reinterpret_casts between vectors of the same size and | ||||||
2325 | // between vectors and integers of the same size. | ||||||
2326 | bool destIsVector = DestType->isVectorType(); | ||||||
2327 | bool srcIsVector = SrcType->isVectorType(); | ||||||
2328 | if (srcIsVector || destIsVector) { | ||||||
2329 | // Allow bitcasting between SVE VLATs and VLSTs, and vice-versa. | ||||||
2330 | if (Self.isValidSveBitcast(SrcType, DestType)) { | ||||||
2331 | Kind = CK_BitCast; | ||||||
2332 | return TC_Success; | ||||||
2333 | } | ||||||
2334 | |||||||
2335 | // The non-vector type, if any, must have integral type. This is | ||||||
2336 | // the same rule that C vector casts use; note, however, that enum | ||||||
2337 | // types are not integral in C++. | ||||||
2338 | if ((!destIsVector && !DestType->isIntegralType(Self.Context)) || | ||||||
2339 | (!srcIsVector && !SrcType->isIntegralType(Self.Context))) | ||||||
2340 | return TC_NotApplicable; | ||||||
2341 | |||||||
2342 | // The size we want to consider is eltCount * eltSize. | ||||||
2343 | // That's exactly what the lax-conversion rules will check. | ||||||
2344 | if (Self.areLaxCompatibleVectorTypes(SrcType, DestType)) { | ||||||
2345 | Kind = CK_BitCast; | ||||||
2346 | return TC_Success; | ||||||
2347 | } | ||||||
2348 | |||||||
2349 | if (Self.LangOpts.OpenCL && !CStyle) { | ||||||
2350 | if (DestType->isExtVectorType() || SrcType->isExtVectorType()) { | ||||||
2351 | // FIXME: Allow for reinterpret cast between 3 and 4 element vectors | ||||||
2352 | if (Self.areVectorTypesSameSize(SrcType, DestType)) { | ||||||
2353 | Kind = CK_BitCast; | ||||||
2354 | return TC_Success; | ||||||
2355 | } | ||||||
2356 | } | ||||||
2357 | } | ||||||
2358 | |||||||
2359 | // Otherwise, pick a reasonable diagnostic. | ||||||
2360 | if (!destIsVector) | ||||||
2361 | msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size; | ||||||
2362 | else if (!srcIsVector) | ||||||
2363 | msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size; | ||||||
2364 | else | ||||||
2365 | msg = diag::err_bad_cxx_cast_vector_to_vector_different_size; | ||||||
2366 | |||||||
2367 | return TC_Failed; | ||||||
2368 | } | ||||||
2369 | |||||||
2370 | if (SrcType == DestType) { | ||||||
2371 | // C++ 5.2.10p2 has a note that mentions that, subject to all other | ||||||
2372 | // restrictions, a cast to the same type is allowed so long as it does not | ||||||
2373 | // cast away constness. In C++98, the intent was not entirely clear here, | ||||||
2374 | // since all other paragraphs explicitly forbid casts to the same type. | ||||||
2375 | // C++11 clarifies this case with p2. | ||||||
2376 | // | ||||||
2377 | // The only allowed types are: integral, enumeration, pointer, or | ||||||
2378 | // pointer-to-member types. We also won't restrict Obj-C pointers either. | ||||||
2379 | Kind = CK_NoOp; | ||||||
2380 | TryCastResult Result = TC_NotApplicable; | ||||||
2381 | if (SrcType->isIntegralOrEnumerationType() || | ||||||
2382 | SrcType->isAnyPointerType() || | ||||||
2383 | SrcType->isMemberPointerType() || | ||||||
2384 | SrcType->isBlockPointerType()) { | ||||||
2385 | Result = TC_Success; | ||||||
2386 | } | ||||||
2387 | return Result; | ||||||
2388 | } | ||||||
2389 | |||||||
2390 | bool destIsPtr = DestType->isAnyPointerType() || | ||||||
2391 | DestType->isBlockPointerType(); | ||||||
2392 | bool srcIsPtr = SrcType->isAnyPointerType() || | ||||||
2393 | SrcType->isBlockPointerType(); | ||||||
2394 | if (!destIsPtr && !srcIsPtr) { | ||||||
2395 | // Except for std::nullptr_t->integer and lvalue->reference, which are | ||||||
2396 | // handled above, at least one of the two arguments must be a pointer. | ||||||
2397 | return TC_NotApplicable; | ||||||
2398 | } | ||||||
2399 | |||||||
2400 | if (DestType->isIntegralType(Self.Context)) { | ||||||
2401 | assert(srcIsPtr && "One type must be a pointer")(static_cast <bool> (srcIsPtr && "One type must be a pointer" ) ? void (0) : __assert_fail ("srcIsPtr && \"One type must be a pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2401, __extension__ __PRETTY_FUNCTION__)); | ||||||
2402 | // C++ 5.2.10p4: A pointer can be explicitly converted to any integral | ||||||
2403 | // type large enough to hold it; except in Microsoft mode, where the | ||||||
2404 | // integral type size doesn't matter (except we don't allow bool). | ||||||
2405 | if ((Self.Context.getTypeSize(SrcType) > | ||||||
2406 | Self.Context.getTypeSize(DestType))) { | ||||||
2407 | bool MicrosoftException = | ||||||
2408 | Self.getLangOpts().MicrosoftExt && !DestType->isBooleanType(); | ||||||
2409 | if (MicrosoftException) { | ||||||
2410 | unsigned Diag = SrcType->isVoidPointerType() | ||||||
2411 | ? diag::warn_void_pointer_to_int_cast | ||||||
2412 | : diag::warn_pointer_to_int_cast; | ||||||
2413 | Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange; | ||||||
2414 | } else { | ||||||
2415 | msg = diag::err_bad_reinterpret_cast_small_int; | ||||||
2416 | return TC_Failed; | ||||||
2417 | } | ||||||
2418 | } | ||||||
2419 | Kind = CK_PointerToIntegral; | ||||||
2420 | return TC_Success; | ||||||
2421 | } | ||||||
2422 | |||||||
2423 | if (SrcType->isIntegralOrEnumerationType()) { | ||||||
2424 | assert(destIsPtr && "One type must be a pointer")(static_cast <bool> (destIsPtr && "One type must be a pointer" ) ? void (0) : __assert_fail ("destIsPtr && \"One type must be a pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2424, __extension__ __PRETTY_FUNCTION__)); | ||||||
2425 | checkIntToPointerCast(CStyle, OpRange, SrcExpr.get(), DestType, Self); | ||||||
2426 | // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly | ||||||
2427 | // converted to a pointer. | ||||||
2428 | // C++ 5.2.10p9: [Note: ...a null pointer constant of integral type is not | ||||||
2429 | // necessarily converted to a null pointer value.] | ||||||
2430 | Kind = CK_IntegralToPointer; | ||||||
2431 | return TC_Success; | ||||||
2432 | } | ||||||
2433 | |||||||
2434 | if (!destIsPtr || !srcIsPtr) { | ||||||
2435 | // With the valid non-pointer conversions out of the way, we can be even | ||||||
2436 | // more stringent. | ||||||
2437 | return TC_NotApplicable; | ||||||
2438 | } | ||||||
2439 | |||||||
2440 | // Cannot convert between block pointers and Objective-C object pointers. | ||||||
2441 | if ((SrcType->isBlockPointerType() && DestType->isObjCObjectPointerType()) || | ||||||
2442 | (DestType->isBlockPointerType() && SrcType->isObjCObjectPointerType())) | ||||||
2443 | return TC_NotApplicable; | ||||||
2444 | |||||||
2445 | // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away constness. | ||||||
2446 | // The C-style cast operator can. | ||||||
2447 | TryCastResult SuccessResult = TC_Success; | ||||||
2448 | if (auto CACK = | ||||||
2449 | CastsAwayConstness(Self, SrcType, DestType, /*CheckCVR=*/!CStyle, | ||||||
2450 | /*CheckObjCLifetime=*/CStyle)) | ||||||
2451 | SuccessResult = getCastAwayConstnessCastKind(CACK, msg); | ||||||
2452 | |||||||
2453 | if (IsAddressSpaceConversion(SrcType, DestType)) { | ||||||
2454 | Kind = CK_AddressSpaceConversion; | ||||||
2455 | assert(SrcType->isPointerType() && DestType->isPointerType())(static_cast <bool> (SrcType->isPointerType() && DestType->isPointerType()) ? void (0) : __assert_fail ("SrcType->isPointerType() && DestType->isPointerType()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2455, __extension__ __PRETTY_FUNCTION__)); | ||||||
2456 | if (!CStyle && | ||||||
2457 | !DestType->getPointeeType().getQualifiers().isAddressSpaceSupersetOf( | ||||||
2458 | SrcType->getPointeeType().getQualifiers())) { | ||||||
2459 | SuccessResult = TC_Failed; | ||||||
2460 | } | ||||||
2461 | } else if (IsLValueCast) { | ||||||
2462 | Kind = CK_LValueBitCast; | ||||||
2463 | } else if (DestType->isObjCObjectPointerType()) { | ||||||
2464 | Kind = Self.PrepareCastToObjCObjectPointer(SrcExpr); | ||||||
2465 | } else if (DestType->isBlockPointerType()) { | ||||||
2466 | if (!SrcType->isBlockPointerType()) { | ||||||
2467 | Kind = CK_AnyPointerToBlockPointerCast; | ||||||
2468 | } else { | ||||||
2469 | Kind = CK_BitCast; | ||||||
2470 | } | ||||||
2471 | } else { | ||||||
2472 | Kind = CK_BitCast; | ||||||
2473 | } | ||||||
2474 | |||||||
2475 | // Any pointer can be cast to an Objective-C pointer type with a C-style | ||||||
2476 | // cast. | ||||||
2477 | if (CStyle && DestType->isObjCObjectPointerType()) { | ||||||
2478 | return SuccessResult; | ||||||
2479 | } | ||||||
2480 | if (CStyle) | ||||||
2481 | DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType); | ||||||
2482 | |||||||
2483 | DiagnoseCallingConvCast(Self, SrcExpr, DestType, OpRange); | ||||||
2484 | |||||||
2485 | // Not casting away constness, so the only remaining check is for compatible | ||||||
2486 | // pointer categories. | ||||||
2487 | |||||||
2488 | if (SrcType->isFunctionPointerType()) { | ||||||
2489 | if (DestType->isFunctionPointerType()) { | ||||||
2490 | // C++ 5.2.10p6: A pointer to a function can be explicitly converted to | ||||||
2491 | // a pointer to a function of a different type. | ||||||
2492 | return SuccessResult; | ||||||
2493 | } | ||||||
2494 | |||||||
2495 | // C++0x 5.2.10p8: Converting a pointer to a function into a pointer to | ||||||
2496 | // an object type or vice versa is conditionally-supported. | ||||||
2497 | // Compilers support it in C++03 too, though, because it's necessary for | ||||||
2498 | // casting the return value of dlsym() and GetProcAddress(). | ||||||
2499 | // FIXME: Conditionally-supported behavior should be configurable in the | ||||||
2500 | // TargetInfo or similar. | ||||||
2501 | Self.Diag(OpRange.getBegin(), | ||||||
2502 | Self.getLangOpts().CPlusPlus11 ? | ||||||
2503 | diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj) | ||||||
2504 | << OpRange; | ||||||
2505 | return SuccessResult; | ||||||
2506 | } | ||||||
2507 | |||||||
2508 | if (DestType->isFunctionPointerType()) { | ||||||
2509 | // See above. | ||||||
2510 | Self.Diag(OpRange.getBegin(), | ||||||
2511 | Self.getLangOpts().CPlusPlus11 ? | ||||||
2512 | diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj) | ||||||
2513 | << OpRange; | ||||||
2514 | return SuccessResult; | ||||||
2515 | } | ||||||
2516 | |||||||
2517 | // Diagnose address space conversion in nested pointers. | ||||||
2518 | QualType DestPtee = DestType->getPointeeType().isNull() | ||||||
2519 | ? DestType->getPointeeType() | ||||||
2520 | : DestType->getPointeeType()->getPointeeType(); | ||||||
2521 | QualType SrcPtee = SrcType->getPointeeType().isNull() | ||||||
2522 | ? SrcType->getPointeeType() | ||||||
2523 | : SrcType->getPointeeType()->getPointeeType(); | ||||||
2524 | while (!DestPtee.isNull() && !SrcPtee.isNull()) { | ||||||
2525 | if (DestPtee.getAddressSpace() != SrcPtee.getAddressSpace()) { | ||||||
2526 | Self.Diag(OpRange.getBegin(), | ||||||
2527 | diag::warn_bad_cxx_cast_nested_pointer_addr_space) | ||||||
2528 | << CStyle << SrcType << DestType << SrcExpr.get()->getSourceRange(); | ||||||
2529 | break; | ||||||
2530 | } | ||||||
2531 | DestPtee = DestPtee->getPointeeType(); | ||||||
2532 | SrcPtee = SrcPtee->getPointeeType(); | ||||||
2533 | } | ||||||
2534 | |||||||
2535 | // C++ 5.2.10p7: A pointer to an object can be explicitly converted to | ||||||
2536 | // a pointer to an object of different type. | ||||||
2537 | // Void pointers are not specified, but supported by every compiler out there. | ||||||
2538 | // So we finish by allowing everything that remains - it's got to be two | ||||||
2539 | // object pointers. | ||||||
2540 | return SuccessResult; | ||||||
2541 | } | ||||||
2542 | |||||||
2543 | static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr, | ||||||
2544 | QualType DestType, bool CStyle, | ||||||
2545 | unsigned &msg, CastKind &Kind) { | ||||||
2546 | if (!Self.getLangOpts().OpenCL) | ||||||
2547 | // FIXME: As compiler doesn't have any information about overlapping addr | ||||||
2548 | // spaces at the moment we have to be permissive here. | ||||||
2549 | return TC_NotApplicable; | ||||||
2550 | // Even though the logic below is general enough and can be applied to | ||||||
2551 | // non-OpenCL mode too, we fast-path above because no other languages | ||||||
2552 | // define overlapping address spaces currently. | ||||||
2553 | auto SrcType = SrcExpr.get()->getType(); | ||||||
2554 | // FIXME: Should this be generalized to references? The reference parameter | ||||||
2555 | // however becomes a reference pointee type here and therefore rejected. | ||||||
2556 | // Perhaps this is the right behavior though according to C++. | ||||||
2557 | auto SrcPtrType = SrcType->getAs<PointerType>(); | ||||||
2558 | if (!SrcPtrType) | ||||||
2559 | return TC_NotApplicable; | ||||||
2560 | auto DestPtrType = DestType->getAs<PointerType>(); | ||||||
2561 | if (!DestPtrType) | ||||||
2562 | return TC_NotApplicable; | ||||||
2563 | auto SrcPointeeType = SrcPtrType->getPointeeType(); | ||||||
2564 | auto DestPointeeType = DestPtrType->getPointeeType(); | ||||||
2565 | if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType)) { | ||||||
2566 | msg = diag::err_bad_cxx_cast_addr_space_mismatch; | ||||||
2567 | return TC_Failed; | ||||||
2568 | } | ||||||
2569 | auto SrcPointeeTypeWithoutAS = | ||||||
2570 | Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType()); | ||||||
2571 | auto DestPointeeTypeWithoutAS = | ||||||
2572 | Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType()); | ||||||
2573 | if (Self.Context.hasSameType(SrcPointeeTypeWithoutAS, | ||||||
2574 | DestPointeeTypeWithoutAS)) { | ||||||
2575 | Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace() | ||||||
2576 | ? CK_NoOp | ||||||
2577 | : CK_AddressSpaceConversion; | ||||||
2578 | return TC_Success; | ||||||
2579 | } else { | ||||||
2580 | return TC_NotApplicable; | ||||||
2581 | } | ||||||
2582 | } | ||||||
2583 | |||||||
2584 | void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) { | ||||||
2585 | // In OpenCL only conversions between pointers to objects in overlapping | ||||||
2586 | // addr spaces are allowed. v2.0 s6.5.5 - Generic addr space overlaps | ||||||
2587 | // with any named one, except for constant. | ||||||
2588 | |||||||
2589 | // Converting the top level pointee addrspace is permitted for compatible | ||||||
2590 | // addrspaces (such as 'generic int *' to 'local int *' or vice versa), but | ||||||
2591 | // if any of the nested pointee addrspaces differ, we emit a warning | ||||||
2592 | // regardless of addrspace compatibility. This makes | ||||||
2593 | // local int ** p; | ||||||
2594 | // return (generic int **) p; | ||||||
2595 | // warn even though local -> generic is permitted. | ||||||
2596 | if (Self.getLangOpts().OpenCL) { | ||||||
2597 | const Type *DestPtr, *SrcPtr; | ||||||
2598 | bool Nested = false; | ||||||
2599 | unsigned DiagID = diag::err_typecheck_incompatible_address_space; | ||||||
2600 | DestPtr = Self.getASTContext().getCanonicalType(DestType.getTypePtr()), | ||||||
2601 | SrcPtr = Self.getASTContext().getCanonicalType(SrcType.getTypePtr()); | ||||||
2602 | |||||||
2603 | while (isa<PointerType>(DestPtr) && isa<PointerType>(SrcPtr)) { | ||||||
2604 | const PointerType *DestPPtr = cast<PointerType>(DestPtr); | ||||||
2605 | const PointerType *SrcPPtr = cast<PointerType>(SrcPtr); | ||||||
2606 | QualType DestPPointee = DestPPtr->getPointeeType(); | ||||||
2607 | QualType SrcPPointee = SrcPPtr->getPointeeType(); | ||||||
2608 | if (Nested | ||||||
2609 | ? DestPPointee.getAddressSpace() != SrcPPointee.getAddressSpace() | ||||||
2610 | : !DestPPointee.isAddressSpaceOverlapping(SrcPPointee)) { | ||||||
2611 | Self.Diag(OpRange.getBegin(), DiagID) | ||||||
2612 | << SrcType << DestType << Sema::AA_Casting | ||||||
2613 | << SrcExpr.get()->getSourceRange(); | ||||||
2614 | if (!Nested) | ||||||
2615 | SrcExpr = ExprError(); | ||||||
2616 | return; | ||||||
2617 | } | ||||||
2618 | |||||||
2619 | DestPtr = DestPPtr->getPointeeType().getTypePtr(); | ||||||
2620 | SrcPtr = SrcPPtr->getPointeeType().getTypePtr(); | ||||||
2621 | Nested = true; | ||||||
2622 | DiagID = diag::ext_nested_pointer_qualifier_mismatch; | ||||||
2623 | } | ||||||
2624 | } | ||||||
2625 | } | ||||||
2626 | |||||||
2627 | bool Sema::ShouldSplatAltivecScalarInCast(const VectorType *VecTy) { | ||||||
2628 | bool SrcCompatXL = this->getLangOpts().getAltivecSrcCompat() == | ||||||
2629 | LangOptions::AltivecSrcCompatKind::XL; | ||||||
2630 | VectorType::VectorKind VKind = VecTy->getVectorKind(); | ||||||
2631 | |||||||
2632 | if ((VKind == VectorType::AltiVecVector) || | ||||||
2633 | (SrcCompatXL && ((VKind == VectorType::AltiVecBool) || | ||||||
2634 | (VKind == VectorType::AltiVecPixel)))) { | ||||||
2635 | return true; | ||||||
2636 | } | ||||||
2637 | return false; | ||||||
2638 | } | ||||||
2639 | |||||||
2640 | bool Sema::CheckAltivecInitFromScalar(SourceRange R, QualType VecTy, | ||||||
2641 | QualType SrcTy) { | ||||||
2642 | bool SrcCompatGCC = this->getLangOpts().getAltivecSrcCompat() == | ||||||
2643 | LangOptions::AltivecSrcCompatKind::GCC; | ||||||
2644 | if (this->getLangOpts().AltiVec && SrcCompatGCC) { | ||||||
2645 | this->Diag(R.getBegin(), | ||||||
2646 | diag::err_invalid_conversion_between_vector_and_integer) | ||||||
2647 | << VecTy << SrcTy << R; | ||||||
2648 | return true; | ||||||
2649 | } | ||||||
2650 | return false; | ||||||
2651 | } | ||||||
2652 | |||||||
2653 | void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, | ||||||
2654 | bool ListInitialization) { | ||||||
2655 | assert(Self.getLangOpts().CPlusPlus)(static_cast <bool> (Self.getLangOpts().CPlusPlus) ? void (0) : __assert_fail ("Self.getLangOpts().CPlusPlus", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2655, __extension__ __PRETTY_FUNCTION__)); | ||||||
2656 | |||||||
2657 | // Handle placeholders. | ||||||
2658 | if (isPlaceholder()) { | ||||||
2659 | // C-style casts can resolve __unknown_any types. | ||||||
2660 | if (claimPlaceholder(BuiltinType::UnknownAny)) { | ||||||
2661 | SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType, | ||||||
2662 | SrcExpr.get(), Kind, | ||||||
2663 | ValueKind, BasePath); | ||||||
2664 | return; | ||||||
2665 | } | ||||||
2666 | |||||||
2667 | checkNonOverloadPlaceholders(); | ||||||
2668 | if (SrcExpr.isInvalid()) | ||||||
2669 | return; | ||||||
2670 | } | ||||||
2671 | |||||||
2672 | // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". | ||||||
2673 | // This test is outside everything else because it's the only case where | ||||||
2674 | // a non-lvalue-reference target type does not lead to decay. | ||||||
2675 | if (DestType->isVoidType()) { | ||||||
2676 | Kind = CK_ToVoid; | ||||||
2677 | |||||||
2678 | if (claimPlaceholder(BuiltinType::Overload)) { | ||||||
2679 | Self.ResolveAndFixSingleFunctionTemplateSpecialization( | ||||||
2680 | SrcExpr, /* Decay Function to ptr */ false, | ||||||
2681 | /* Complain */ true, DestRange, DestType, | ||||||
2682 | diag::err_bad_cstyle_cast_overload); | ||||||
2683 | if (SrcExpr.isInvalid()) | ||||||
2684 | return; | ||||||
2685 | } | ||||||
2686 | |||||||
2687 | SrcExpr = Self.IgnoredValueConversions(SrcExpr.get()); | ||||||
2688 | return; | ||||||
2689 | } | ||||||
2690 | |||||||
2691 | // If the type is dependent, we won't do any other semantic analysis now. | ||||||
2692 | if (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() || | ||||||
2693 | SrcExpr.get()->isValueDependent()) { | ||||||
2694 | assert(Kind == CK_Dependent)(static_cast <bool> (Kind == CK_Dependent) ? void (0) : __assert_fail ("Kind == CK_Dependent", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2694, __extension__ __PRETTY_FUNCTION__)); | ||||||
2695 | return; | ||||||
2696 | } | ||||||
2697 | |||||||
2698 | if (ValueKind == VK_PRValue && !DestType->isRecordType() && | ||||||
2699 | !isPlaceholder(BuiltinType::Overload)) { | ||||||
2700 | SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get()); | ||||||
2701 | if (SrcExpr.isInvalid()) | ||||||
2702 | return; | ||||||
2703 | } | ||||||
2704 | |||||||
2705 | // AltiVec vector initialization with a single literal. | ||||||
2706 | if (const VectorType *vecTy = DestType->getAs<VectorType>()) { | ||||||
2707 | if (Self.CheckAltivecInitFromScalar(OpRange, DestType, | ||||||
2708 | SrcExpr.get()->getType())) { | ||||||
2709 | SrcExpr = ExprError(); | ||||||
2710 | return; | ||||||
2711 | } | ||||||
2712 | if (Self.ShouldSplatAltivecScalarInCast(vecTy) && | ||||||
2713 | (SrcExpr.get()->getType()->isIntegerType() || | ||||||
2714 | SrcExpr.get()->getType()->isFloatingType())) { | ||||||
2715 | Kind = CK_VectorSplat; | ||||||
2716 | SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get()); | ||||||
2717 | return; | ||||||
2718 | } | ||||||
2719 | } | ||||||
2720 | |||||||
2721 | // C++ [expr.cast]p5: The conversions performed by | ||||||
2722 | // - a const_cast, | ||||||
2723 | // - a static_cast, | ||||||
2724 | // - a static_cast followed by a const_cast, | ||||||
2725 | // - a reinterpret_cast, or | ||||||
2726 | // - a reinterpret_cast followed by a const_cast, | ||||||
2727 | // can be performed using the cast notation of explicit type conversion. | ||||||
2728 | // [...] If a conversion can be interpreted in more than one of the ways | ||||||
2729 | // listed above, the interpretation that appears first in the list is used, | ||||||
2730 | // even if a cast resulting from that interpretation is ill-formed. | ||||||
2731 | // In plain language, this means trying a const_cast ... | ||||||
2732 | // Note that for address space we check compatibility after const_cast. | ||||||
2733 | unsigned msg = diag::err_bad_cxx_cast_generic; | ||||||
2734 | TryCastResult tcr = TryConstCast(Self, SrcExpr, DestType, | ||||||
2735 | /*CStyle*/ true, msg); | ||||||
2736 | if (SrcExpr.isInvalid()) | ||||||
2737 | return; | ||||||
2738 | if (isValidCast(tcr)) | ||||||
2739 | Kind = CK_NoOp; | ||||||
2740 | |||||||
2741 | Sema::CheckedConversionKind CCK = | ||||||
2742 | FunctionalStyle ? Sema::CCK_FunctionalCast : Sema::CCK_CStyleCast; | ||||||
2743 | if (tcr == TC_NotApplicable) { | ||||||
2744 | tcr = TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ true, msg, | ||||||
2745 | Kind); | ||||||
2746 | if (SrcExpr.isInvalid()) | ||||||
2747 | return; | ||||||
2748 | |||||||
2749 | if (tcr == TC_NotApplicable) { | ||||||
2750 | // ... or if that is not possible, a static_cast, ignoring const and | ||||||
2751 | // addr space, ... | ||||||
2752 | tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, msg, Kind, | ||||||
2753 | BasePath, ListInitialization); | ||||||
2754 | if (SrcExpr.isInvalid()) | ||||||
2755 | return; | ||||||
2756 | |||||||
2757 | if (tcr == TC_NotApplicable) { | ||||||
2758 | // ... and finally a reinterpret_cast, ignoring const and addr space. | ||||||
2759 | tcr = TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/ true, | ||||||
2760 | OpRange, msg, Kind); | ||||||
2761 | if (SrcExpr.isInvalid()) | ||||||
2762 | return; | ||||||
2763 | } | ||||||
2764 | } | ||||||
2765 | } | ||||||
2766 | |||||||
2767 | if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && | ||||||
2768 | isValidCast(tcr)) | ||||||
2769 | checkObjCConversion(CCK); | ||||||
2770 | |||||||
2771 | if (tcr != TC_Success && msg != 0) { | ||||||
2772 | if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { | ||||||
2773 | DeclAccessPair Found; | ||||||
2774 | FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), | ||||||
2775 | DestType, | ||||||
2776 | /*Complain*/ true, | ||||||
2777 | Found); | ||||||
2778 | if (Fn) { | ||||||
2779 | // If DestType is a function type (not to be confused with the function | ||||||
2780 | // pointer type), it will be possible to resolve the function address, | ||||||
2781 | // but the type cast should be considered as failure. | ||||||
2782 | OverloadExpr *OE = OverloadExpr::find(SrcExpr.get()).Expression; | ||||||
2783 | Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload) | ||||||
2784 | << OE->getName() << DestType << OpRange | ||||||
2785 | << OE->getQualifierLoc().getSourceRange(); | ||||||
2786 | Self.NoteAllOverloadCandidates(SrcExpr.get()); | ||||||
2787 | } | ||||||
2788 | } else { | ||||||
2789 | diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle), | ||||||
2790 | OpRange, SrcExpr.get(), DestType, ListInitialization); | ||||||
2791 | } | ||||||
2792 | } | ||||||
2793 | |||||||
2794 | if (isValidCast(tcr)) { | ||||||
2795 | if (Kind == CK_BitCast) | ||||||
2796 | checkCastAlign(); | ||||||
2797 | |||||||
2798 | if (!checkCastFunctionType(Self, SrcExpr, DestType)) | ||||||
2799 | Self.Diag(OpRange.getBegin(), diag::warn_cast_function_type) | ||||||
2800 | << SrcExpr.get()->getType() << DestType << OpRange; | ||||||
2801 | |||||||
2802 | } else { | ||||||
2803 | SrcExpr = ExprError(); | ||||||
2804 | } | ||||||
2805 | } | ||||||
2806 | |||||||
2807 | /// DiagnoseBadFunctionCast - Warn whenever a function call is cast to a | ||||||
2808 | /// non-matching type. Such as enum function call to int, int call to | ||||||
2809 | /// pointer; etc. Cast to 'void' is an exception. | ||||||
2810 | static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr, | ||||||
2811 | QualType DestType) { | ||||||
2812 | if (Self.Diags.isIgnored(diag::warn_bad_function_cast, | ||||||
2813 | SrcExpr.get()->getExprLoc())) | ||||||
2814 | return; | ||||||
2815 | |||||||
2816 | if (!isa<CallExpr>(SrcExpr.get())) | ||||||
2817 | return; | ||||||
2818 | |||||||
2819 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
2820 | if (DestType.getUnqualifiedType()->isVoidType()) | ||||||
2821 | return; | ||||||
2822 | if ((SrcType->isAnyPointerType() || SrcType->isBlockPointerType()) | ||||||
2823 | && (DestType->isAnyPointerType() || DestType->isBlockPointerType())) | ||||||
2824 | return; | ||||||
2825 | if (SrcType->isIntegerType() && DestType->isIntegerType() && | ||||||
2826 | (SrcType->isBooleanType() == DestType->isBooleanType()) && | ||||||
2827 | (SrcType->isEnumeralType() == DestType->isEnumeralType())) | ||||||
2828 | return; | ||||||
2829 | if (SrcType->isRealFloatingType() && DestType->isRealFloatingType()) | ||||||
2830 | return; | ||||||
2831 | if (SrcType->isEnumeralType() && DestType->isEnumeralType()) | ||||||
2832 | return; | ||||||
2833 | if (SrcType->isComplexType() && DestType->isComplexType()) | ||||||
2834 | return; | ||||||
2835 | if (SrcType->isComplexIntegerType() && DestType->isComplexIntegerType()) | ||||||
2836 | return; | ||||||
2837 | if (SrcType->isFixedPointType() && DestType->isFixedPointType()) | ||||||
2838 | return; | ||||||
2839 | |||||||
2840 | Self.Diag(SrcExpr.get()->getExprLoc(), | ||||||
2841 | diag::warn_bad_function_cast) | ||||||
2842 | << SrcType << DestType << SrcExpr.get()->getSourceRange(); | ||||||
2843 | } | ||||||
2844 | |||||||
2845 | /// Check the semantics of a C-style cast operation, in C. | ||||||
2846 | void CastOperation::CheckCStyleCast() { | ||||||
2847 | assert(!Self.getLangOpts().CPlusPlus)(static_cast <bool> (!Self.getLangOpts().CPlusPlus) ? void (0) : __assert_fail ("!Self.getLangOpts().CPlusPlus", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2847, __extension__ __PRETTY_FUNCTION__)); | ||||||
2848 | |||||||
2849 | // C-style casts can resolve __unknown_any types. | ||||||
2850 | if (claimPlaceholder(BuiltinType::UnknownAny)) { | ||||||
2851 | SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType, | ||||||
2852 | SrcExpr.get(), Kind, | ||||||
2853 | ValueKind, BasePath); | ||||||
2854 | return; | ||||||
2855 | } | ||||||
2856 | |||||||
2857 | // C99 6.5.4p2: the cast type needs to be void or scalar and the expression | ||||||
2858 | // type needs to be scalar. | ||||||
2859 | if (DestType->isVoidType()) { | ||||||
2860 | // We don't necessarily do lvalue-to-rvalue conversions on this. | ||||||
2861 | SrcExpr = Self.IgnoredValueConversions(SrcExpr.get()); | ||||||
2862 | if (SrcExpr.isInvalid()) | ||||||
2863 | return; | ||||||
2864 | |||||||
2865 | // Cast to void allows any expr type. | ||||||
2866 | Kind = CK_ToVoid; | ||||||
2867 | return; | ||||||
2868 | } | ||||||
2869 | |||||||
2870 | // If the type is dependent, we won't do any other semantic analysis now. | ||||||
2871 | if (Self.getASTContext().isDependenceAllowed() && | ||||||
2872 | (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() || | ||||||
2873 | SrcExpr.get()->isValueDependent())) { | ||||||
2874 | assert((DestType->containsErrors() || SrcExpr.get()->containsErrors() ||(static_cast <bool> ((DestType->containsErrors() || SrcExpr .get()->containsErrors() || SrcExpr.get()->containsErrors ()) && "should only occur in error-recovery path.") ? void (0) : __assert_fail ("(DestType->containsErrors() || SrcExpr.get()->containsErrors() || SrcExpr.get()->containsErrors()) && \"should only occur in error-recovery path.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2876, __extension__ __PRETTY_FUNCTION__)) | ||||||
2875 | SrcExpr.get()->containsErrors()) &&(static_cast <bool> ((DestType->containsErrors() || SrcExpr .get()->containsErrors() || SrcExpr.get()->containsErrors ()) && "should only occur in error-recovery path.") ? void (0) : __assert_fail ("(DestType->containsErrors() || SrcExpr.get()->containsErrors() || SrcExpr.get()->containsErrors()) && \"should only occur in error-recovery path.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2876, __extension__ __PRETTY_FUNCTION__)) | ||||||
2876 | "should only occur in error-recovery path.")(static_cast <bool> ((DestType->containsErrors() || SrcExpr .get()->containsErrors() || SrcExpr.get()->containsErrors ()) && "should only occur in error-recovery path.") ? void (0) : __assert_fail ("(DestType->containsErrors() || SrcExpr.get()->containsErrors() || SrcExpr.get()->containsErrors()) && \"should only occur in error-recovery path.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2876, __extension__ __PRETTY_FUNCTION__)); | ||||||
2877 | assert(Kind == CK_Dependent)(static_cast <bool> (Kind == CK_Dependent) ? void (0) : __assert_fail ("Kind == CK_Dependent", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2877, __extension__ __PRETTY_FUNCTION__)); | ||||||
2878 | return; | ||||||
2879 | } | ||||||
2880 | |||||||
2881 | // Overloads are allowed with C extensions, so we need to support them. | ||||||
2882 | if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { | ||||||
2883 | DeclAccessPair DAP; | ||||||
2884 | if (FunctionDecl *FD = Self.ResolveAddressOfOverloadedFunction( | ||||||
2885 | SrcExpr.get(), DestType, /*Complain=*/true, DAP)) | ||||||
2886 | SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD); | ||||||
2887 | else | ||||||
2888 | return; | ||||||
2889 | assert(SrcExpr.isUsable())(static_cast <bool> (SrcExpr.isUsable()) ? void (0) : __assert_fail ("SrcExpr.isUsable()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2889, __extension__ __PRETTY_FUNCTION__)); | ||||||
2890 | } | ||||||
2891 | SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get()); | ||||||
2892 | if (SrcExpr.isInvalid()) | ||||||
2893 | return; | ||||||
2894 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
2895 | |||||||
2896 | assert(!SrcType->isPlaceholderType())(static_cast <bool> (!SrcType->isPlaceholderType()) ? void (0) : __assert_fail ("!SrcType->isPlaceholderType()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 2896, __extension__ __PRETTY_FUNCTION__)); | ||||||
2897 | |||||||
2898 | checkAddressSpaceCast(SrcType, DestType); | ||||||
2899 | if (SrcExpr.isInvalid()) | ||||||
2900 | return; | ||||||
2901 | |||||||
2902 | if (Self.RequireCompleteType(OpRange.getBegin(), DestType, | ||||||
2903 | diag::err_typecheck_cast_to_incomplete)) { | ||||||
2904 | SrcExpr = ExprError(); | ||||||
2905 | return; | ||||||
2906 | } | ||||||
2907 | |||||||
2908 | // Allow casting a sizeless built-in type to itself. | ||||||
2909 | if (DestType->isSizelessBuiltinType() && | ||||||
2910 | Self.Context.hasSameUnqualifiedType(DestType, SrcType)) { | ||||||
2911 | Kind = CK_NoOp; | ||||||
2912 | return; | ||||||
2913 | } | ||||||
2914 | |||||||
2915 | // Allow bitcasting between compatible SVE vector types. | ||||||
2916 | if ((SrcType->isVectorType() || DestType->isVectorType()) && | ||||||
2917 | Self.isValidSveBitcast(SrcType, DestType)) { | ||||||
2918 | Kind = CK_BitCast; | ||||||
2919 | return; | ||||||
2920 | } | ||||||
2921 | |||||||
2922 | if (!DestType->isScalarType() && !DestType->isVectorType() && | ||||||
2923 | !DestType->isMatrixType()) { | ||||||
2924 | const RecordType *DestRecordTy = DestType->getAs<RecordType>(); | ||||||
2925 | |||||||
2926 | if (DestRecordTy && Self.Context.hasSameUnqualifiedType(DestType, SrcType)){ | ||||||
2927 | // GCC struct/union extension: allow cast to self. | ||||||
2928 | Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar) | ||||||
2929 | << DestType << SrcExpr.get()->getSourceRange(); | ||||||
2930 | Kind = CK_NoOp; | ||||||
2931 | return; | ||||||
2932 | } | ||||||
2933 | |||||||
2934 | // GCC's cast to union extension. | ||||||
2935 | if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) { | ||||||
2936 | RecordDecl *RD = DestRecordTy->getDecl(); | ||||||
2937 | if (CastExpr::getTargetFieldForToUnionCast(RD, SrcType)) { | ||||||
2938 | Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union) | ||||||
2939 | << SrcExpr.get()->getSourceRange(); | ||||||
2940 | Kind = CK_ToUnion; | ||||||
2941 | return; | ||||||
2942 | } else { | ||||||
2943 | Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type) | ||||||
2944 | << SrcType << SrcExpr.get()->getSourceRange(); | ||||||
2945 | SrcExpr = ExprError(); | ||||||
2946 | return; | ||||||
2947 | } | ||||||
2948 | } | ||||||
2949 | |||||||
2950 | // OpenCL v2.0 s6.13.10 - Allow casts from '0' to event_t type. | ||||||
2951 | if (Self.getLangOpts().OpenCL && DestType->isEventT()) { | ||||||
2952 | Expr::EvalResult Result; | ||||||
2953 | if (SrcExpr.get()->EvaluateAsInt(Result, Self.Context)) { | ||||||
2954 | llvm::APSInt CastInt = Result.Val.getInt(); | ||||||
2955 | if (0 == CastInt) { | ||||||
2956 | Kind = CK_ZeroToOCLOpaqueType; | ||||||
2957 | return; | ||||||
2958 | } | ||||||
2959 | Self.Diag(OpRange.getBegin(), | ||||||
2960 | diag::err_opencl_cast_non_zero_to_event_t) | ||||||
2961 | << toString(CastInt, 10) << SrcExpr.get()->getSourceRange(); | ||||||
2962 | SrcExpr = ExprError(); | ||||||
2963 | return; | ||||||
2964 | } | ||||||
2965 | } | ||||||
2966 | |||||||
2967 | // Reject any other conversions to non-scalar types. | ||||||
2968 | Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar) | ||||||
2969 | << DestType << SrcExpr.get()->getSourceRange(); | ||||||
2970 | SrcExpr = ExprError(); | ||||||
2971 | return; | ||||||
2972 | } | ||||||
2973 | |||||||
2974 | // The type we're casting to is known to be a scalar, a vector, or a matrix. | ||||||
2975 | |||||||
2976 | // Require the operand to be a scalar, a vector, or a matrix. | ||||||
2977 | if (!SrcType->isScalarType() && !SrcType->isVectorType() && | ||||||
2978 | !SrcType->isMatrixType()) { | ||||||
2979 | Self.Diag(SrcExpr.get()->getExprLoc(), | ||||||
2980 | diag::err_typecheck_expect_scalar_operand) | ||||||
2981 | << SrcType << SrcExpr.get()->getSourceRange(); | ||||||
2982 | SrcExpr = ExprError(); | ||||||
2983 | return; | ||||||
2984 | } | ||||||
2985 | |||||||
2986 | if (DestType->isExtVectorType()) { | ||||||
2987 | SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind); | ||||||
2988 | return; | ||||||
2989 | } | ||||||
2990 | |||||||
2991 | if (DestType->getAs<MatrixType>() || SrcType->getAs<MatrixType>()) { | ||||||
2992 | if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) | ||||||
2993 | SrcExpr = ExprError(); | ||||||
2994 | return; | ||||||
2995 | } | ||||||
2996 | |||||||
2997 | if (const VectorType *DestVecTy = DestType->getAs<VectorType>()) { | ||||||
2998 | if (Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) { | ||||||
2999 | SrcExpr = ExprError(); | ||||||
3000 | return; | ||||||
3001 | } | ||||||
3002 | if (Self.ShouldSplatAltivecScalarInCast(DestVecTy) && | ||||||
3003 | (SrcType->isIntegerType() || SrcType->isFloatingType())) { | ||||||
3004 | Kind = CK_VectorSplat; | ||||||
3005 | SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get()); | ||||||
3006 | } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) { | ||||||
3007 | SrcExpr = ExprError(); | ||||||
3008 | } | ||||||
3009 | return; | ||||||
3010 | } | ||||||
3011 | |||||||
3012 | if (SrcType->isVectorType()) { | ||||||
3013 | if (Self.CheckVectorCast(OpRange, SrcType, DestType, Kind)) | ||||||
3014 | SrcExpr = ExprError(); | ||||||
3015 | return; | ||||||
3016 | } | ||||||
3017 | |||||||
3018 | // The source and target types are both scalars, i.e. | ||||||
3019 | // - arithmetic types (fundamental, enum, and complex) | ||||||
3020 | // - all kinds of pointers | ||||||
3021 | // Note that member pointers were filtered out with C++, above. | ||||||
3022 | |||||||
3023 | if (isa<ObjCSelectorExpr>(SrcExpr.get())) { | ||||||
3024 | Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr); | ||||||
3025 | SrcExpr = ExprError(); | ||||||
3026 | return; | ||||||
3027 | } | ||||||
3028 | |||||||
3029 | // Can't cast to or from bfloat | ||||||
3030 | if (DestType->isBFloat16Type() && !SrcType->isBFloat16Type()) { | ||||||
3031 | Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_to_bfloat16) | ||||||
3032 | << SrcExpr.get()->getSourceRange(); | ||||||
3033 | SrcExpr = ExprError(); | ||||||
3034 | return; | ||||||
3035 | } | ||||||
3036 | if (SrcType->isBFloat16Type() && !DestType->isBFloat16Type()) { | ||||||
3037 | Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_from_bfloat16) | ||||||
3038 | << SrcExpr.get()->getSourceRange(); | ||||||
3039 | SrcExpr = ExprError(); | ||||||
3040 | return; | ||||||
3041 | } | ||||||
3042 | |||||||
3043 | // If either type is a pointer, the other type has to be either an | ||||||
3044 | // integer or a pointer. | ||||||
3045 | if (!DestType->isArithmeticType()) { | ||||||
3046 | if (!SrcType->isIntegralType(Self.Context) && SrcType->isArithmeticType()) { | ||||||
3047 | Self.Diag(SrcExpr.get()->getExprLoc(), | ||||||
3048 | diag::err_cast_pointer_from_non_pointer_int) | ||||||
3049 | << SrcType << SrcExpr.get()->getSourceRange(); | ||||||
3050 | SrcExpr = ExprError(); | ||||||
3051 | return; | ||||||
3052 | } | ||||||
3053 | checkIntToPointerCast(/* CStyle */ true, OpRange, SrcExpr.get(), DestType, | ||||||
3054 | Self); | ||||||
3055 | } else if (!SrcType->isArithmeticType()) { | ||||||
3056 | if (!DestType->isIntegralType(Self.Context) && | ||||||
3057 | DestType->isArithmeticType()) { | ||||||
3058 | Self.Diag(SrcExpr.get()->getBeginLoc(), | ||||||
3059 | diag::err_cast_pointer_to_non_pointer_int) | ||||||
3060 | << DestType << SrcExpr.get()->getSourceRange(); | ||||||
3061 | SrcExpr = ExprError(); | ||||||
3062 | return; | ||||||
3063 | } | ||||||
3064 | |||||||
3065 | if ((Self.Context.getTypeSize(SrcType) > | ||||||
3066 | Self.Context.getTypeSize(DestType)) && | ||||||
3067 | !DestType->isBooleanType()) { | ||||||
3068 | // C 6.3.2.3p6: Any pointer type may be converted to an integer type. | ||||||
3069 | // Except as previously specified, the result is implementation-defined. | ||||||
3070 | // If the result cannot be represented in the integer type, the behavior | ||||||
3071 | // is undefined. The result need not be in the range of values of any | ||||||
3072 | // integer type. | ||||||
3073 | unsigned Diag; | ||||||
3074 | if (SrcType->isVoidPointerType()) | ||||||
3075 | Diag = DestType->isEnumeralType() ? diag::warn_void_pointer_to_enum_cast | ||||||
3076 | : diag::warn_void_pointer_to_int_cast; | ||||||
3077 | else if (DestType->isEnumeralType()) | ||||||
3078 | Diag = diag::warn_pointer_to_enum_cast; | ||||||
3079 | else | ||||||
3080 | Diag = diag::warn_pointer_to_int_cast; | ||||||
3081 | Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange; | ||||||
3082 | } | ||||||
3083 | } | ||||||
3084 | |||||||
3085 | if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().isAvailableOption( | ||||||
3086 | "cl_khr_fp16", Self.getLangOpts())) { | ||||||
3087 | if (DestType->isHalfType()) { | ||||||
3088 | Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half) | ||||||
3089 | << DestType << SrcExpr.get()->getSourceRange(); | ||||||
3090 | SrcExpr = ExprError(); | ||||||
3091 | return; | ||||||
3092 | } | ||||||
3093 | } | ||||||
3094 | |||||||
3095 | // ARC imposes extra restrictions on casts. | ||||||
3096 | if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) { | ||||||
3097 | checkObjCConversion(Sema::CCK_CStyleCast); | ||||||
3098 | if (SrcExpr.isInvalid()) | ||||||
3099 | return; | ||||||
3100 | |||||||
3101 | const PointerType *CastPtr = DestType->getAs<PointerType>(); | ||||||
3102 | if (Self.getLangOpts().ObjCAutoRefCount && CastPtr) { | ||||||
3103 | if (const PointerType *ExprPtr = SrcType->getAs<PointerType>()) { | ||||||
3104 | Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers(); | ||||||
3105 | Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers(); | ||||||
3106 | if (CastPtr->getPointeeType()->isObjCLifetimeType() && | ||||||
3107 | ExprPtr->getPointeeType()->isObjCLifetimeType() && | ||||||
3108 | !CastQuals.compatiblyIncludesObjCLifetime(ExprQuals)) { | ||||||
3109 | Self.Diag(SrcExpr.get()->getBeginLoc(), | ||||||
3110 | diag::err_typecheck_incompatible_ownership) | ||||||
3111 | << SrcType << DestType << Sema::AA_Casting | ||||||
3112 | << SrcExpr.get()->getSourceRange(); | ||||||
3113 | return; | ||||||
3114 | } | ||||||
3115 | } | ||||||
3116 | } | ||||||
3117 | else if (!Self.CheckObjCARCUnavailableWeakConversion(DestType, SrcType)) { | ||||||
3118 | Self.Diag(SrcExpr.get()->getBeginLoc(), | ||||||
3119 | diag::err_arc_convesion_of_weak_unavailable) | ||||||
3120 | << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange(); | ||||||
3121 | SrcExpr = ExprError(); | ||||||
3122 | return; | ||||||
3123 | } | ||||||
3124 | } | ||||||
3125 | |||||||
3126 | if (!checkCastFunctionType(Self, SrcExpr, DestType)) | ||||||
3127 | Self.Diag(OpRange.getBegin(), diag::warn_cast_function_type) | ||||||
3128 | << SrcType << DestType << OpRange; | ||||||
3129 | |||||||
3130 | DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType); | ||||||
3131 | DiagnoseCallingConvCast(Self, SrcExpr, DestType, OpRange); | ||||||
3132 | DiagnoseBadFunctionCast(Self, SrcExpr, DestType); | ||||||
3133 | Kind = Self.PrepareScalarCast(SrcExpr, DestType); | ||||||
3134 | if (SrcExpr.isInvalid()) | ||||||
3135 | return; | ||||||
3136 | |||||||
3137 | if (Kind == CK_BitCast) | ||||||
3138 | checkCastAlign(); | ||||||
3139 | } | ||||||
3140 | |||||||
3141 | void CastOperation::CheckBuiltinBitCast() { | ||||||
3142 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
3143 | |||||||
3144 | if (Self.RequireCompleteType(OpRange.getBegin(), DestType, | ||||||
3145 | diag::err_typecheck_cast_to_incomplete) || | ||||||
3146 | Self.RequireCompleteType(OpRange.getBegin(), SrcType, | ||||||
3147 | diag::err_incomplete_type)) { | ||||||
3148 | SrcExpr = ExprError(); | ||||||
3149 | return; | ||||||
3150 | } | ||||||
3151 | |||||||
3152 | if (SrcExpr.get()->isPRValue()) | ||||||
3153 | SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(), | ||||||
3154 | /*IsLValueReference=*/false); | ||||||
3155 | |||||||
3156 | CharUnits DestSize = Self.Context.getTypeSizeInChars(DestType); | ||||||
3157 | CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType); | ||||||
3158 | if (DestSize != SourceSize) { | ||||||
3159 | Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch) | ||||||
3160 | << (int)SourceSize.getQuantity() << (int)DestSize.getQuantity(); | ||||||
3161 | SrcExpr = ExprError(); | ||||||
3162 | return; | ||||||
3163 | } | ||||||
3164 | |||||||
3165 | if (!DestType.isTriviallyCopyableType(Self.Context)) { | ||||||
3166 | Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable) | ||||||
3167 | << 1; | ||||||
3168 | SrcExpr = ExprError(); | ||||||
3169 | return; | ||||||
3170 | } | ||||||
3171 | |||||||
3172 | if (!SrcType.isTriviallyCopyableType(Self.Context)) { | ||||||
3173 | Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable) | ||||||
3174 | << 0; | ||||||
3175 | SrcExpr = ExprError(); | ||||||
3176 | return; | ||||||
3177 | } | ||||||
3178 | |||||||
3179 | Kind = CK_LValueToRValueBitCast; | ||||||
3180 | } | ||||||
3181 | |||||||
3182 | /// DiagnoseCastQual - Warn whenever casts discards a qualifiers, be it either | ||||||
3183 | /// const, volatile or both. | ||||||
3184 | static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr, | ||||||
3185 | QualType DestType) { | ||||||
3186 | if (SrcExpr.isInvalid()) | ||||||
3187 | return; | ||||||
3188 | |||||||
3189 | QualType SrcType = SrcExpr.get()->getType(); | ||||||
3190 | if (!((SrcType->isAnyPointerType() && DestType->isAnyPointerType()) || | ||||||
3191 | DestType->isLValueReferenceType())) | ||||||
3192 | return; | ||||||
3193 | |||||||
3194 | QualType TheOffendingSrcType, TheOffendingDestType; | ||||||
3195 | Qualifiers CastAwayQualifiers; | ||||||
3196 | if (CastsAwayConstness(Self, SrcType, DestType, true, false, | ||||||
3197 | &TheOffendingSrcType, &TheOffendingDestType, | ||||||
3198 | &CastAwayQualifiers) != | ||||||
3199 | CastAwayConstnessKind::CACK_Similar) | ||||||
3200 | return; | ||||||
3201 | |||||||
3202 | // FIXME: 'restrict' is not properly handled here. | ||||||
3203 | int qualifiers = -1; | ||||||
3204 | if (CastAwayQualifiers.hasConst() && CastAwayQualifiers.hasVolatile()) { | ||||||
3205 | qualifiers = 0; | ||||||
3206 | } else if (CastAwayQualifiers.hasConst()) { | ||||||
3207 | qualifiers = 1; | ||||||
3208 | } else if (CastAwayQualifiers.hasVolatile()) { | ||||||
3209 | qualifiers = 2; | ||||||
3210 | } | ||||||
3211 | // This is a variant of int **x; const int **y = (const int **)x; | ||||||
3212 | if (qualifiers == -1) | ||||||
3213 | Self.Diag(SrcExpr.get()->getBeginLoc(), diag::warn_cast_qual2) | ||||||
3214 | << SrcType << DestType; | ||||||
3215 | else | ||||||
3216 | Self.Diag(SrcExpr.get()->getBeginLoc(), diag::warn_cast_qual) | ||||||
3217 | << TheOffendingSrcType << TheOffendingDestType << qualifiers; | ||||||
3218 | } | ||||||
3219 | |||||||
3220 | ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc, | ||||||
3221 | TypeSourceInfo *CastTypeInfo, | ||||||
3222 | SourceLocation RPLoc, | ||||||
3223 | Expr *CastExpr) { | ||||||
3224 | CastOperation Op(*this, CastTypeInfo->getType(), CastExpr); | ||||||
3225 | Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); | ||||||
3226 | Op.OpRange = SourceRange(LPLoc, CastExpr->getEndLoc()); | ||||||
3227 | |||||||
3228 | if (getLangOpts().CPlusPlus) { | ||||||
3229 | Op.CheckCXXCStyleCast(/*FunctionalCast=*/ false, | ||||||
3230 | isa<InitListExpr>(CastExpr)); | ||||||
3231 | } else { | ||||||
3232 | Op.CheckCStyleCast(); | ||||||
3233 | } | ||||||
3234 | |||||||
3235 | if (Op.SrcExpr.isInvalid()) | ||||||
3236 | return ExprError(); | ||||||
3237 | |||||||
3238 | // -Wcast-qual | ||||||
3239 | DiagnoseCastQual(Op.Self, Op.SrcExpr, Op.DestType); | ||||||
3240 | |||||||
3241 | return Op.complete(CStyleCastExpr::Create( | ||||||
3242 | Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(), | ||||||
3243 | &Op.BasePath, CurFPFeatureOverrides(), CastTypeInfo, LPLoc, RPLoc)); | ||||||
3244 | } | ||||||
3245 | |||||||
3246 | ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo, | ||||||
3247 | QualType Type, | ||||||
3248 | SourceLocation LPLoc, | ||||||
3249 | Expr *CastExpr, | ||||||
3250 | SourceLocation RPLoc) { | ||||||
3251 | assert(LPLoc.isValid() && "List-initialization shouldn't get here.")(static_cast <bool> (LPLoc.isValid() && "List-initialization shouldn't get here." ) ? void (0) : __assert_fail ("LPLoc.isValid() && \"List-initialization shouldn't get here.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaCast.cpp" , 3251, __extension__ __PRETTY_FUNCTION__)); | ||||||
3252 | CastOperation Op(*this, Type, CastExpr); | ||||||
3253 | Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); | ||||||
3254 | Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getEndLoc()); | ||||||
3255 | |||||||
3256 | Op.CheckCXXCStyleCast(/*FunctionalCast=*/true, /*ListInit=*/false); | ||||||
3257 | if (Op.SrcExpr.isInvalid()) | ||||||
3258 | return ExprError(); | ||||||
3259 | |||||||
3260 | auto *SubExpr = Op.SrcExpr.get(); | ||||||
3261 | if (auto *BindExpr = dyn_cast<CXXBindTemporaryExpr>(SubExpr)) | ||||||
3262 | SubExpr = BindExpr->getSubExpr(); | ||||||
3263 | if (auto *ConstructExpr = dyn_cast<CXXConstructExpr>(SubExpr)) | ||||||
3264 | ConstructExpr->setParenOrBraceRange(SourceRange(LPLoc, RPLoc)); | ||||||
3265 | |||||||
3266 | return Op.complete(CXXFunctionalCastExpr::Create( | ||||||
3267 | Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind, | ||||||
3268 | Op.SrcExpr.get(), &Op.BasePath, CurFPFeatureOverrides(), LPLoc, RPLoc)); | ||||||
3269 | } |
1 | //===- Type.h - C Language Family Type Representation -----------*- C++ -*-===// | ||||||
2 | // | ||||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||
6 | // | ||||||
7 | //===----------------------------------------------------------------------===// | ||||||
8 | // | ||||||
9 | /// \file | ||||||
10 | /// C Language Family Type Representation | ||||||
11 | /// | ||||||
12 | /// This file defines the clang::Type interface and subclasses, used to | ||||||
13 | /// represent types for languages in the C family. | ||||||
14 | // | ||||||
15 | //===----------------------------------------------------------------------===// | ||||||
16 | |||||||
17 | #ifndef LLVM_CLANG_AST_TYPE_H | ||||||
18 | #define LLVM_CLANG_AST_TYPE_H | ||||||
19 | |||||||
20 | #include "clang/AST/DependenceFlags.h" | ||||||
21 | #include "clang/AST/NestedNameSpecifier.h" | ||||||
22 | #include "clang/AST/TemplateName.h" | ||||||
23 | #include "clang/Basic/AddressSpaces.h" | ||||||
24 | #include "clang/Basic/AttrKinds.h" | ||||||
25 | #include "clang/Basic/Diagnostic.h" | ||||||
26 | #include "clang/Basic/ExceptionSpecificationType.h" | ||||||
27 | #include "clang/Basic/LLVM.h" | ||||||
28 | #include "clang/Basic/Linkage.h" | ||||||
29 | #include "clang/Basic/PartialDiagnostic.h" | ||||||
30 | #include "clang/Basic/SourceLocation.h" | ||||||
31 | #include "clang/Basic/Specifiers.h" | ||||||
32 | #include "clang/Basic/Visibility.h" | ||||||
33 | #include "llvm/ADT/APInt.h" | ||||||
34 | #include "llvm/ADT/APSInt.h" | ||||||
35 | #include "llvm/ADT/ArrayRef.h" | ||||||
36 | #include "llvm/ADT/FoldingSet.h" | ||||||
37 | #include "llvm/ADT/None.h" | ||||||
38 | #include "llvm/ADT/Optional.h" | ||||||
39 | #include "llvm/ADT/PointerIntPair.h" | ||||||
40 | #include "llvm/ADT/PointerUnion.h" | ||||||
41 | #include "llvm/ADT/StringRef.h" | ||||||
42 | #include "llvm/ADT/Twine.h" | ||||||
43 | #include "llvm/ADT/iterator_range.h" | ||||||
44 | #include "llvm/Support/Casting.h" | ||||||
45 | #include "llvm/Support/Compiler.h" | ||||||
46 | #include "llvm/Support/ErrorHandling.h" | ||||||
47 | #include "llvm/Support/PointerLikeTypeTraits.h" | ||||||
48 | #include "llvm/Support/TrailingObjects.h" | ||||||
49 | #include "llvm/Support/type_traits.h" | ||||||
50 | #include <cassert> | ||||||
51 | #include <cstddef> | ||||||
52 | #include <cstdint> | ||||||
53 | #include <cstring> | ||||||
54 | #include <string> | ||||||
55 | #include <type_traits> | ||||||
56 | #include <utility> | ||||||
57 | |||||||
58 | namespace clang { | ||||||
59 | |||||||
60 | class ExtQuals; | ||||||
61 | class QualType; | ||||||
62 | class ConceptDecl; | ||||||
63 | class TagDecl; | ||||||
64 | class TemplateParameterList; | ||||||
65 | class Type; | ||||||
66 | |||||||
67 | enum { | ||||||
68 | TypeAlignmentInBits = 4, | ||||||
69 | TypeAlignment = 1 << TypeAlignmentInBits | ||||||
70 | }; | ||||||
71 | |||||||
72 | namespace serialization { | ||||||
73 | template <class T> class AbstractTypeReader; | ||||||
74 | template <class T> class AbstractTypeWriter; | ||||||
75 | } | ||||||
76 | |||||||
77 | } // namespace clang | ||||||
78 | |||||||
79 | namespace llvm { | ||||||
80 | |||||||
81 | template <typename T> | ||||||
82 | struct PointerLikeTypeTraits; | ||||||
83 | template<> | ||||||
84 | struct PointerLikeTypeTraits< ::clang::Type*> { | ||||||
85 | static inline void *getAsVoidPointer(::clang::Type *P) { return P; } | ||||||
86 | |||||||
87 | static inline ::clang::Type *getFromVoidPointer(void *P) { | ||||||
88 | return static_cast< ::clang::Type*>(P); | ||||||
89 | } | ||||||
90 | |||||||
91 | static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; | ||||||
92 | }; | ||||||
93 | |||||||
94 | template<> | ||||||
95 | struct PointerLikeTypeTraits< ::clang::ExtQuals*> { | ||||||
96 | static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; } | ||||||
97 | |||||||
98 | static inline ::clang::ExtQuals *getFromVoidPointer(void *P) { | ||||||
99 | return static_cast< ::clang::ExtQuals*>(P); | ||||||
100 | } | ||||||
101 | |||||||
102 | static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; | ||||||
103 | }; | ||||||
104 | |||||||
105 | } // namespace llvm | ||||||
106 | |||||||
107 | namespace clang { | ||||||
108 | |||||||
109 | class ASTContext; | ||||||
110 | template <typename> class CanQual; | ||||||
111 | class CXXRecordDecl; | ||||||
112 | class DeclContext; | ||||||
113 | class EnumDecl; | ||||||
114 | class Expr; | ||||||
115 | class ExtQualsTypeCommonBase; | ||||||
116 | class FunctionDecl; | ||||||
117 | class IdentifierInfo; | ||||||
118 | class NamedDecl; | ||||||
119 | class ObjCInterfaceDecl; | ||||||
120 | class ObjCProtocolDecl; | ||||||
121 | class ObjCTypeParamDecl; | ||||||
122 | struct PrintingPolicy; | ||||||
123 | class RecordDecl; | ||||||
124 | class Stmt; | ||||||
125 | class TagDecl; | ||||||
126 | class TemplateArgument; | ||||||
127 | class TemplateArgumentListInfo; | ||||||
128 | class TemplateArgumentLoc; | ||||||
129 | class TemplateTypeParmDecl; | ||||||
130 | class TypedefNameDecl; | ||||||
131 | class UnresolvedUsingTypenameDecl; | ||||||
132 | |||||||
133 | using CanQualType = CanQual<Type>; | ||||||
134 | |||||||
135 | // Provide forward declarations for all of the *Type classes. | ||||||
136 | #define TYPE(Class, Base) class Class##Type; | ||||||
137 | #include "clang/AST/TypeNodes.inc" | ||||||
138 | |||||||
139 | /// The collection of all-type qualifiers we support. | ||||||
140 | /// Clang supports five independent qualifiers: | ||||||
141 | /// * C99: const, volatile, and restrict | ||||||
142 | /// * MS: __unaligned | ||||||
143 | /// * Embedded C (TR18037): address spaces | ||||||
144 | /// * Objective C: the GC attributes (none, weak, or strong) | ||||||
145 | class Qualifiers { | ||||||
146 | public: | ||||||
147 | enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. | ||||||
148 | Const = 0x1, | ||||||
149 | Restrict = 0x2, | ||||||
150 | Volatile = 0x4, | ||||||
151 | CVRMask = Const | Volatile | Restrict | ||||||
152 | }; | ||||||
153 | |||||||
154 | enum GC { | ||||||
155 | GCNone = 0, | ||||||
156 | Weak, | ||||||
157 | Strong | ||||||
158 | }; | ||||||
159 | |||||||
160 | enum ObjCLifetime { | ||||||
161 | /// There is no lifetime qualification on this type. | ||||||
162 | OCL_None, | ||||||
163 | |||||||
164 | /// This object can be modified without requiring retains or | ||||||
165 | /// releases. | ||||||
166 | OCL_ExplicitNone, | ||||||
167 | |||||||
168 | /// Assigning into this object requires the old value to be | ||||||
169 | /// released and the new value to be retained. The timing of the | ||||||
170 | /// release of the old value is inexact: it may be moved to | ||||||
171 | /// immediately after the last known point where the value is | ||||||
172 | /// live. | ||||||
173 | OCL_Strong, | ||||||
174 | |||||||
175 | /// Reading or writing from this object requires a barrier call. | ||||||
176 | OCL_Weak, | ||||||
177 | |||||||
178 | /// Assigning into this object requires a lifetime extension. | ||||||
179 | OCL_Autoreleasing | ||||||
180 | }; | ||||||
181 | |||||||
182 | enum { | ||||||
183 | /// The maximum supported address space number. | ||||||
184 | /// 23 bits should be enough for anyone. | ||||||
185 | MaxAddressSpace = 0x7fffffu, | ||||||
186 | |||||||
187 | /// The width of the "fast" qualifier mask. | ||||||
188 | FastWidth = 3, | ||||||
189 | |||||||
190 | /// The fast qualifier mask. | ||||||
191 | FastMask = (1 << FastWidth) - 1 | ||||||
192 | }; | ||||||
193 | |||||||
194 | /// Returns the common set of qualifiers while removing them from | ||||||
195 | /// the given sets. | ||||||
196 | static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { | ||||||
197 | // If both are only CVR-qualified, bit operations are sufficient. | ||||||
198 | if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { | ||||||
199 | Qualifiers Q; | ||||||
200 | Q.Mask = L.Mask & R.Mask; | ||||||
201 | L.Mask &= ~Q.Mask; | ||||||
202 | R.Mask &= ~Q.Mask; | ||||||
203 | return Q; | ||||||
204 | } | ||||||
205 | |||||||
206 | Qualifiers Q; | ||||||
207 | unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); | ||||||
208 | Q.addCVRQualifiers(CommonCRV); | ||||||
209 | L.removeCVRQualifiers(CommonCRV); | ||||||
210 | R.removeCVRQualifiers(CommonCRV); | ||||||
211 | |||||||
212 | if (L.getObjCGCAttr() == R.getObjCGCAttr()) { | ||||||
213 | Q.setObjCGCAttr(L.getObjCGCAttr()); | ||||||
214 | L.removeObjCGCAttr(); | ||||||
215 | R.removeObjCGCAttr(); | ||||||
216 | } | ||||||
217 | |||||||
218 | if (L.getObjCLifetime() == R.getObjCLifetime()) { | ||||||
219 | Q.setObjCLifetime(L.getObjCLifetime()); | ||||||
220 | L.removeObjCLifetime(); | ||||||
221 | R.removeObjCLifetime(); | ||||||
222 | } | ||||||
223 | |||||||
224 | if (L.getAddressSpace() == R.getAddressSpace()) { | ||||||
225 | Q.setAddressSpace(L.getAddressSpace()); | ||||||
226 | L.removeAddressSpace(); | ||||||
227 | R.removeAddressSpace(); | ||||||
228 | } | ||||||
229 | return Q; | ||||||
230 | } | ||||||
231 | |||||||
232 | static Qualifiers fromFastMask(unsigned Mask) { | ||||||
233 | Qualifiers Qs; | ||||||
234 | Qs.addFastQualifiers(Mask); | ||||||
235 | return Qs; | ||||||
236 | } | ||||||
237 | |||||||
238 | static Qualifiers fromCVRMask(unsigned CVR) { | ||||||
239 | Qualifiers Qs; | ||||||
240 | Qs.addCVRQualifiers(CVR); | ||||||
241 | return Qs; | ||||||
242 | } | ||||||
243 | |||||||
244 | static Qualifiers fromCVRUMask(unsigned CVRU) { | ||||||
245 | Qualifiers Qs; | ||||||
246 | Qs.addCVRUQualifiers(CVRU); | ||||||
247 | return Qs; | ||||||
248 | } | ||||||
249 | |||||||
250 | // Deserialize qualifiers from an opaque representation. | ||||||
251 | static Qualifiers fromOpaqueValue(unsigned opaque) { | ||||||
252 | Qualifiers Qs; | ||||||
253 | Qs.Mask = opaque; | ||||||
254 | return Qs; | ||||||
255 | } | ||||||
256 | |||||||
257 | // Serialize these qualifiers into an opaque representation. | ||||||
258 | unsigned getAsOpaqueValue() const { | ||||||
259 | return Mask; | ||||||
260 | } | ||||||
261 | |||||||
262 | bool hasConst() const { return Mask & Const; } | ||||||
263 | bool hasOnlyConst() const { return Mask == Const; } | ||||||
264 | void removeConst() { Mask &= ~Const; } | ||||||
265 | void addConst() { Mask |= Const; } | ||||||
266 | |||||||
267 | bool hasVolatile() const { return Mask & Volatile; } | ||||||
268 | bool hasOnlyVolatile() const { return Mask == Volatile; } | ||||||
269 | void removeVolatile() { Mask &= ~Volatile; } | ||||||
270 | void addVolatile() { Mask |= Volatile; } | ||||||
271 | |||||||
272 | bool hasRestrict() const { return Mask & Restrict; } | ||||||
273 | bool hasOnlyRestrict() const { return Mask == Restrict; } | ||||||
274 | void removeRestrict() { Mask &= ~Restrict; } | ||||||
275 | void addRestrict() { Mask |= Restrict; } | ||||||
276 | |||||||
277 | bool hasCVRQualifiers() const { return getCVRQualifiers(); } | ||||||
278 | unsigned getCVRQualifiers() const { return Mask & CVRMask; } | ||||||
279 | unsigned getCVRUQualifiers() const { return Mask & (CVRMask | UMask); } | ||||||
280 | |||||||
281 | void setCVRQualifiers(unsigned mask) { | ||||||
282 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast <bool> (!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ) ? void (0) : __assert_fail ("!(mask & ~CVRMask) && \"bitmask contains non-CVR bits\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 282, __extension__ __PRETTY_FUNCTION__)); | ||||||
283 | Mask = (Mask & ~CVRMask) | mask; | ||||||
284 | } | ||||||
285 | void removeCVRQualifiers(unsigned mask) { | ||||||
286 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast <bool> (!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ) ? void (0) : __assert_fail ("!(mask & ~CVRMask) && \"bitmask contains non-CVR bits\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 286, __extension__ __PRETTY_FUNCTION__)); | ||||||
287 | Mask &= ~mask; | ||||||
288 | } | ||||||
289 | void removeCVRQualifiers() { | ||||||
290 | removeCVRQualifiers(CVRMask); | ||||||
291 | } | ||||||
292 | void addCVRQualifiers(unsigned mask) { | ||||||
293 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast <bool> (!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ) ? void (0) : __assert_fail ("!(mask & ~CVRMask) && \"bitmask contains non-CVR bits\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 293, __extension__ __PRETTY_FUNCTION__)); | ||||||
294 | Mask |= mask; | ||||||
295 | } | ||||||
296 | void addCVRUQualifiers(unsigned mask) { | ||||||
297 | assert(!(mask & ~CVRMask & ~UMask) && "bitmask contains non-CVRU bits")(static_cast <bool> (!(mask & ~CVRMask & ~UMask ) && "bitmask contains non-CVRU bits") ? void (0) : __assert_fail ("!(mask & ~CVRMask & ~UMask) && \"bitmask contains non-CVRU bits\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 297, __extension__ __PRETTY_FUNCTION__)); | ||||||
298 | Mask |= mask; | ||||||
299 | } | ||||||
300 | |||||||
301 | bool hasUnaligned() const { return Mask & UMask; } | ||||||
302 | void setUnaligned(bool flag) { | ||||||
303 | Mask = (Mask & ~UMask) | (flag ? UMask : 0); | ||||||
304 | } | ||||||
305 | void removeUnaligned() { Mask &= ~UMask; } | ||||||
306 | void addUnaligned() { Mask |= UMask; } | ||||||
307 | |||||||
308 | bool hasObjCGCAttr() const { return Mask & GCAttrMask; } | ||||||
309 | GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } | ||||||
310 | void setObjCGCAttr(GC type) { | ||||||
311 | Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift); | ||||||
312 | } | ||||||
313 | void removeObjCGCAttr() { setObjCGCAttr(GCNone); } | ||||||
314 | void addObjCGCAttr(GC type) { | ||||||
315 | assert(type)(static_cast <bool> (type) ? void (0) : __assert_fail ( "type", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 315, __extension__ __PRETTY_FUNCTION__)); | ||||||
316 | setObjCGCAttr(type); | ||||||
317 | } | ||||||
318 | Qualifiers withoutObjCGCAttr() const { | ||||||
319 | Qualifiers qs = *this; | ||||||
320 | qs.removeObjCGCAttr(); | ||||||
321 | return qs; | ||||||
322 | } | ||||||
323 | Qualifiers withoutObjCLifetime() const { | ||||||
324 | Qualifiers qs = *this; | ||||||
325 | qs.removeObjCLifetime(); | ||||||
326 | return qs; | ||||||
327 | } | ||||||
328 | Qualifiers withoutAddressSpace() const { | ||||||
329 | Qualifiers qs = *this; | ||||||
330 | qs.removeAddressSpace(); | ||||||
331 | return qs; | ||||||
332 | } | ||||||
333 | |||||||
334 | bool hasObjCLifetime() const { return Mask & LifetimeMask; } | ||||||
335 | ObjCLifetime getObjCLifetime() const { | ||||||
336 | return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift); | ||||||
337 | } | ||||||
338 | void setObjCLifetime(ObjCLifetime type) { | ||||||
339 | Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift); | ||||||
340 | } | ||||||
341 | void removeObjCLifetime() { setObjCLifetime(OCL_None); } | ||||||
342 | void addObjCLifetime(ObjCLifetime type) { | ||||||
343 | assert(type)(static_cast <bool> (type) ? void (0) : __assert_fail ( "type", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 343, __extension__ __PRETTY_FUNCTION__)); | ||||||
344 | assert(!hasObjCLifetime())(static_cast <bool> (!hasObjCLifetime()) ? void (0) : __assert_fail ("!hasObjCLifetime()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 344, __extension__ __PRETTY_FUNCTION__)); | ||||||
345 | Mask |= (type << LifetimeShift); | ||||||
346 | } | ||||||
347 | |||||||
348 | /// True if the lifetime is neither None or ExplicitNone. | ||||||
349 | bool hasNonTrivialObjCLifetime() const { | ||||||
350 | ObjCLifetime lifetime = getObjCLifetime(); | ||||||
351 | return (lifetime > OCL_ExplicitNone); | ||||||
352 | } | ||||||
353 | |||||||
354 | /// True if the lifetime is either strong or weak. | ||||||
355 | bool hasStrongOrWeakObjCLifetime() const { | ||||||
356 | ObjCLifetime lifetime = getObjCLifetime(); | ||||||
357 | return (lifetime == OCL_Strong || lifetime == OCL_Weak); | ||||||
358 | } | ||||||
359 | |||||||
360 | bool hasAddressSpace() const { return Mask & AddressSpaceMask; } | ||||||
361 | LangAS getAddressSpace() const { | ||||||
362 | return static_cast<LangAS>(Mask >> AddressSpaceShift); | ||||||
363 | } | ||||||
364 | bool hasTargetSpecificAddressSpace() const { | ||||||
365 | return isTargetAddressSpace(getAddressSpace()); | ||||||
366 | } | ||||||
367 | /// Get the address space attribute value to be printed by diagnostics. | ||||||
368 | unsigned getAddressSpaceAttributePrintValue() const { | ||||||
369 | auto Addr = getAddressSpace(); | ||||||
370 | // This function is not supposed to be used with language specific | ||||||
371 | // address spaces. If that happens, the diagnostic message should consider | ||||||
372 | // printing the QualType instead of the address space value. | ||||||
373 | assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace())(static_cast <bool> (Addr == LangAS::Default || hasTargetSpecificAddressSpace ()) ? void (0) : __assert_fail ("Addr == LangAS::Default || hasTargetSpecificAddressSpace()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 373, __extension__ __PRETTY_FUNCTION__)); | ||||||
374 | if (Addr != LangAS::Default) | ||||||
375 | return toTargetAddressSpace(Addr); | ||||||
376 | // TODO: The diagnostic messages where Addr may be 0 should be fixed | ||||||
377 | // since it cannot differentiate the situation where 0 denotes the default | ||||||
378 | // address space or user specified __attribute__((address_space(0))). | ||||||
379 | return 0; | ||||||
380 | } | ||||||
381 | void setAddressSpace(LangAS space) { | ||||||
382 | assert((unsigned)space <= MaxAddressSpace)(static_cast <bool> ((unsigned)space <= MaxAddressSpace ) ? void (0) : __assert_fail ("(unsigned)space <= MaxAddressSpace" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 382, __extension__ __PRETTY_FUNCTION__)); | ||||||
383 | Mask = (Mask & ~AddressSpaceMask) | ||||||
384 | | (((uint32_t) space) << AddressSpaceShift); | ||||||
385 | } | ||||||
386 | void removeAddressSpace() { setAddressSpace(LangAS::Default); } | ||||||
387 | void addAddressSpace(LangAS space) { | ||||||
388 | assert(space != LangAS::Default)(static_cast <bool> (space != LangAS::Default) ? void ( 0) : __assert_fail ("space != LangAS::Default", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 388, __extension__ __PRETTY_FUNCTION__)); | ||||||
389 | setAddressSpace(space); | ||||||
390 | } | ||||||
391 | |||||||
392 | // Fast qualifiers are those that can be allocated directly | ||||||
393 | // on a QualType object. | ||||||
394 | bool hasFastQualifiers() const { return getFastQualifiers(); } | ||||||
395 | unsigned getFastQualifiers() const { return Mask & FastMask; } | ||||||
396 | void setFastQualifiers(unsigned mask) { | ||||||
397 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast <bool> (!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits") ? void (0) : __assert_fail ("!(mask & ~FastMask) && \"bitmask contains non-fast qualifier bits\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 397, __extension__ __PRETTY_FUNCTION__)); | ||||||
398 | Mask = (Mask & ~FastMask) | mask; | ||||||
399 | } | ||||||
400 | void removeFastQualifiers(unsigned mask) { | ||||||
401 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast <bool> (!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits") ? void (0) : __assert_fail ("!(mask & ~FastMask) && \"bitmask contains non-fast qualifier bits\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 401, __extension__ __PRETTY_FUNCTION__)); | ||||||
402 | Mask &= ~mask; | ||||||
403 | } | ||||||
404 | void removeFastQualifiers() { | ||||||
405 | removeFastQualifiers(FastMask); | ||||||
406 | } | ||||||
407 | void addFastQualifiers(unsigned mask) { | ||||||
408 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast <bool> (!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits") ? void (0) : __assert_fail ("!(mask & ~FastMask) && \"bitmask contains non-fast qualifier bits\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 408, __extension__ __PRETTY_FUNCTION__)); | ||||||
409 | Mask |= mask; | ||||||
410 | } | ||||||
411 | |||||||
412 | /// Return true if the set contains any qualifiers which require an ExtQuals | ||||||
413 | /// node to be allocated. | ||||||
414 | bool hasNonFastQualifiers() const { return Mask & ~FastMask; } | ||||||
415 | Qualifiers getNonFastQualifiers() const { | ||||||
416 | Qualifiers Quals = *this; | ||||||
417 | Quals.setFastQualifiers(0); | ||||||
418 | return Quals; | ||||||
419 | } | ||||||
420 | |||||||
421 | /// Return true if the set contains any qualifiers. | ||||||
422 | bool hasQualifiers() const { return Mask; } | ||||||
423 | bool empty() const { return !Mask; } | ||||||
424 | |||||||
425 | /// Add the qualifiers from the given set to this set. | ||||||
426 | void addQualifiers(Qualifiers Q) { | ||||||
427 | // If the other set doesn't have any non-boolean qualifiers, just | ||||||
428 | // bit-or it in. | ||||||
429 | if (!(Q.Mask & ~CVRMask)) | ||||||
430 | Mask |= Q.Mask; | ||||||
431 | else { | ||||||
432 | Mask |= (Q.Mask & CVRMask); | ||||||
433 | if (Q.hasAddressSpace()) | ||||||
434 | addAddressSpace(Q.getAddressSpace()); | ||||||
435 | if (Q.hasObjCGCAttr()) | ||||||
436 | addObjCGCAttr(Q.getObjCGCAttr()); | ||||||
437 | if (Q.hasObjCLifetime()) | ||||||
438 | addObjCLifetime(Q.getObjCLifetime()); | ||||||
439 | } | ||||||
440 | } | ||||||
441 | |||||||
442 | /// Remove the qualifiers from the given set from this set. | ||||||
443 | void removeQualifiers(Qualifiers Q) { | ||||||
444 | // If the other set doesn't have any non-boolean qualifiers, just | ||||||
445 | // bit-and the inverse in. | ||||||
446 | if (!(Q.Mask & ~CVRMask)) | ||||||
447 | Mask &= ~Q.Mask; | ||||||
448 | else { | ||||||
449 | Mask &= ~(Q.Mask & CVRMask); | ||||||
450 | if (getObjCGCAttr() == Q.getObjCGCAttr()) | ||||||
451 | removeObjCGCAttr(); | ||||||
452 | if (getObjCLifetime() == Q.getObjCLifetime()) | ||||||
453 | removeObjCLifetime(); | ||||||
454 | if (getAddressSpace() == Q.getAddressSpace()) | ||||||
455 | removeAddressSpace(); | ||||||
456 | } | ||||||
457 | } | ||||||
458 | |||||||
459 | /// Add the qualifiers from the given set to this set, given that | ||||||
460 | /// they don't conflict. | ||||||
461 | void addConsistentQualifiers(Qualifiers qs) { | ||||||
462 | assert(getAddressSpace() == qs.getAddressSpace() ||(static_cast <bool> (getAddressSpace() == qs.getAddressSpace () || !hasAddressSpace() || !qs.hasAddressSpace()) ? void (0) : __assert_fail ("getAddressSpace() == qs.getAddressSpace() || !hasAddressSpace() || !qs.hasAddressSpace()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 463, __extension__ __PRETTY_FUNCTION__)) | ||||||
463 | !hasAddressSpace() || !qs.hasAddressSpace())(static_cast <bool> (getAddressSpace() == qs.getAddressSpace () || !hasAddressSpace() || !qs.hasAddressSpace()) ? void (0) : __assert_fail ("getAddressSpace() == qs.getAddressSpace() || !hasAddressSpace() || !qs.hasAddressSpace()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 463, __extension__ __PRETTY_FUNCTION__)); | ||||||
464 | assert(getObjCGCAttr() == qs.getObjCGCAttr() ||(static_cast <bool> (getObjCGCAttr() == qs.getObjCGCAttr () || !hasObjCGCAttr() || !qs.hasObjCGCAttr()) ? void (0) : __assert_fail ("getObjCGCAttr() == qs.getObjCGCAttr() || !hasObjCGCAttr() || !qs.hasObjCGCAttr()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 465, __extension__ __PRETTY_FUNCTION__)) | ||||||
465 | !hasObjCGCAttr() || !qs.hasObjCGCAttr())(static_cast <bool> (getObjCGCAttr() == qs.getObjCGCAttr () || !hasObjCGCAttr() || !qs.hasObjCGCAttr()) ? void (0) : __assert_fail ("getObjCGCAttr() == qs.getObjCGCAttr() || !hasObjCGCAttr() || !qs.hasObjCGCAttr()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 465, __extension__ __PRETTY_FUNCTION__)); | ||||||
466 | assert(getObjCLifetime() == qs.getObjCLifetime() ||(static_cast <bool> (getObjCLifetime() == qs.getObjCLifetime () || !hasObjCLifetime() || !qs.hasObjCLifetime()) ? void (0) : __assert_fail ("getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 467, __extension__ __PRETTY_FUNCTION__)) | ||||||
467 | !hasObjCLifetime() || !qs.hasObjCLifetime())(static_cast <bool> (getObjCLifetime() == qs.getObjCLifetime () || !hasObjCLifetime() || !qs.hasObjCLifetime()) ? void (0) : __assert_fail ("getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 467, __extension__ __PRETTY_FUNCTION__)); | ||||||
468 | Mask |= qs.Mask; | ||||||
469 | } | ||||||
470 | |||||||
471 | /// Returns true if address space A is equal to or a superset of B. | ||||||
472 | /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of | ||||||
473 | /// overlapping address spaces. | ||||||
474 | /// CL1.1 or CL1.2: | ||||||
475 | /// every address space is a superset of itself. | ||||||
476 | /// CL2.0 adds: | ||||||
477 | /// __generic is a superset of any address space except for __constant. | ||||||
478 | static bool isAddressSpaceSupersetOf(LangAS A, LangAS B) { | ||||||
479 | // Address spaces must match exactly. | ||||||
480 | return A == B || | ||||||
481 | // Otherwise in OpenCLC v2.0 s6.5.5: every address space except | ||||||
482 | // for __constant can be used as __generic. | ||||||
483 | (A == LangAS::opencl_generic && B != LangAS::opencl_constant) || | ||||||
484 | // We also define global_device and global_host address spaces, | ||||||
485 | // to distinguish global pointers allocated on host from pointers | ||||||
486 | // allocated on device, which are a subset of __global. | ||||||
487 | (A == LangAS::opencl_global && (B == LangAS::opencl_global_device || | ||||||
488 | B == LangAS::opencl_global_host)) || | ||||||
489 | (A == LangAS::sycl_global && (B == LangAS::sycl_global_device || | ||||||
490 | B == LangAS::sycl_global_host)) || | ||||||
491 | // Consider pointer size address spaces to be equivalent to default. | ||||||
492 | ((isPtrSizeAddressSpace(A) || A == LangAS::Default) && | ||||||
493 | (isPtrSizeAddressSpace(B) || B == LangAS::Default)) || | ||||||
494 | // Default is a superset of SYCL address spaces. | ||||||
495 | (A == LangAS::Default && | ||||||
496 | (B == LangAS::sycl_private || B == LangAS::sycl_local || | ||||||
497 | B == LangAS::sycl_global || B == LangAS::sycl_global_device || | ||||||
498 | B == LangAS::sycl_global_host)) || | ||||||
499 | // In HIP device compilation, any cuda address space is allowed | ||||||
500 | // to implicitly cast into the default address space. | ||||||
501 | (A == LangAS::Default && | ||||||
502 | (B == LangAS::cuda_constant || B == LangAS::cuda_device || | ||||||
503 | B == LangAS::cuda_shared)); | ||||||
504 | } | ||||||
505 | |||||||
506 | /// Returns true if the address space in these qualifiers is equal to or | ||||||
507 | /// a superset of the address space in the argument qualifiers. | ||||||
508 | bool isAddressSpaceSupersetOf(Qualifiers other) const { | ||||||
509 | return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace()); | ||||||
510 | } | ||||||
511 | |||||||
512 | /// Determines if these qualifiers compatibly include another set. | ||||||
513 | /// Generally this answers the question of whether an object with the other | ||||||
514 | /// qualifiers can be safely used as an object with these qualifiers. | ||||||
515 | bool compatiblyIncludes(Qualifiers other) const { | ||||||
516 | return isAddressSpaceSupersetOf(other) && | ||||||
517 | // ObjC GC qualifiers can match, be added, or be removed, but can't | ||||||
518 | // be changed. | ||||||
519 | (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || | ||||||
520 | !other.hasObjCGCAttr()) && | ||||||
521 | // ObjC lifetime qualifiers must match exactly. | ||||||
522 | getObjCLifetime() == other.getObjCLifetime() && | ||||||
523 | // CVR qualifiers may subset. | ||||||
524 | (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) && | ||||||
525 | // U qualifier may superset. | ||||||
526 | (!other.hasUnaligned() || hasUnaligned()); | ||||||
527 | } | ||||||
528 | |||||||
529 | /// Determines if these qualifiers compatibly include another set of | ||||||
530 | /// qualifiers from the narrow perspective of Objective-C ARC lifetime. | ||||||
531 | /// | ||||||
532 | /// One set of Objective-C lifetime qualifiers compatibly includes the other | ||||||
533 | /// if the lifetime qualifiers match, or if both are non-__weak and the | ||||||
534 | /// including set also contains the 'const' qualifier, or both are non-__weak | ||||||
535 | /// and one is None (which can only happen in non-ARC modes). | ||||||
536 | bool compatiblyIncludesObjCLifetime(Qualifiers other) const { | ||||||
537 | if (getObjCLifetime() == other.getObjCLifetime()) | ||||||
538 | return true; | ||||||
539 | |||||||
540 | if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) | ||||||
541 | return false; | ||||||
542 | |||||||
543 | if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None) | ||||||
544 | return true; | ||||||
545 | |||||||
546 | return hasConst(); | ||||||
547 | } | ||||||
548 | |||||||
549 | /// Determine whether this set of qualifiers is a strict superset of | ||||||
550 | /// another set of qualifiers, not considering qualifier compatibility. | ||||||
551 | bool isStrictSupersetOf(Qualifiers Other) const; | ||||||
552 | |||||||
553 | bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } | ||||||
554 | bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } | ||||||
555 | |||||||
556 | explicit operator bool() const { return hasQualifiers(); } | ||||||
557 | |||||||
558 | Qualifiers &operator+=(Qualifiers R) { | ||||||
559 | addQualifiers(R); | ||||||
560 | return *this; | ||||||
561 | } | ||||||
562 | |||||||
563 | // Union two qualifier sets. If an enumerated qualifier appears | ||||||
564 | // in both sets, use the one from the right. | ||||||
565 | friend Qualifiers operator+(Qualifiers L, Qualifiers R) { | ||||||
566 | L += R; | ||||||
567 | return L; | ||||||
568 | } | ||||||
569 | |||||||
570 | Qualifiers &operator-=(Qualifiers R) { | ||||||
571 | removeQualifiers(R); | ||||||
572 | return *this; | ||||||
573 | } | ||||||
574 | |||||||
575 | /// Compute the difference between two qualifier sets. | ||||||
576 | friend Qualifiers operator-(Qualifiers L, Qualifiers R) { | ||||||
577 | L -= R; | ||||||
578 | return L; | ||||||
579 | } | ||||||
580 | |||||||
581 | std::string getAsString() const; | ||||||
582 | std::string getAsString(const PrintingPolicy &Policy) const; | ||||||
583 | |||||||
584 | static std::string getAddrSpaceAsString(LangAS AS); | ||||||
585 | |||||||
586 | bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; | ||||||
587 | void print(raw_ostream &OS, const PrintingPolicy &Policy, | ||||||
588 | bool appendSpaceIfNonEmpty = false) const; | ||||||
589 | |||||||
590 | void Profile(llvm::FoldingSetNodeID &ID) const { | ||||||
591 | ID.AddInteger(Mask); | ||||||
592 | } | ||||||
593 | |||||||
594 | private: | ||||||
595 | // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| | ||||||
596 | // |C R V|U|GCAttr|Lifetime|AddressSpace| | ||||||
597 | uint32_t Mask = 0; | ||||||
598 | |||||||
599 | static const uint32_t UMask = 0x8; | ||||||
600 | static const uint32_t UShift = 3; | ||||||
601 | static const uint32_t GCAttrMask = 0x30; | ||||||
602 | static const uint32_t GCAttrShift = 4; | ||||||
603 | static const uint32_t LifetimeMask = 0x1C0; | ||||||
604 | static const uint32_t LifetimeShift = 6; | ||||||
605 | static const uint32_t AddressSpaceMask = | ||||||
606 | ~(CVRMask | UMask | GCAttrMask | LifetimeMask); | ||||||
607 | static const uint32_t AddressSpaceShift = 9; | ||||||
608 | }; | ||||||
609 | |||||||
610 | /// A std::pair-like structure for storing a qualified type split | ||||||
611 | /// into its local qualifiers and its locally-unqualified type. | ||||||
612 | struct SplitQualType { | ||||||
613 | /// The locally-unqualified type. | ||||||
614 | const Type *Ty = nullptr; | ||||||
615 | |||||||
616 | /// The local qualifiers. | ||||||
617 | Qualifiers Quals; | ||||||
618 | |||||||
619 | SplitQualType() = default; | ||||||
620 | SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {} | ||||||
621 | |||||||
622 | SplitQualType getSingleStepDesugaredType() const; // end of this file | ||||||
623 | |||||||
624 | // Make std::tie work. | ||||||
625 | std::pair<const Type *,Qualifiers> asPair() const { | ||||||
626 | return std::pair<const Type *, Qualifiers>(Ty, Quals); | ||||||
627 | } | ||||||
628 | |||||||
629 | friend bool operator==(SplitQualType a, SplitQualType b) { | ||||||
630 | return a.Ty == b.Ty && a.Quals == b.Quals; | ||||||
631 | } | ||||||
632 | friend bool operator!=(SplitQualType a, SplitQualType b) { | ||||||
633 | return a.Ty != b.Ty || a.Quals != b.Quals; | ||||||
634 | } | ||||||
635 | }; | ||||||
636 | |||||||
637 | /// The kind of type we are substituting Objective-C type arguments into. | ||||||
638 | /// | ||||||
639 | /// The kind of substitution affects the replacement of type parameters when | ||||||
640 | /// no concrete type information is provided, e.g., when dealing with an | ||||||
641 | /// unspecialized type. | ||||||
642 | enum class ObjCSubstitutionContext { | ||||||
643 | /// An ordinary type. | ||||||
644 | Ordinary, | ||||||
645 | |||||||
646 | /// The result type of a method or function. | ||||||
647 | Result, | ||||||
648 | |||||||
649 | /// The parameter type of a method or function. | ||||||
650 | Parameter, | ||||||
651 | |||||||
652 | /// The type of a property. | ||||||
653 | Property, | ||||||
654 | |||||||
655 | /// The superclass of a type. | ||||||
656 | Superclass, | ||||||
657 | }; | ||||||
658 | |||||||
659 | /// A (possibly-)qualified type. | ||||||
660 | /// | ||||||
661 | /// For efficiency, we don't store CV-qualified types as nodes on their | ||||||
662 | /// own: instead each reference to a type stores the qualifiers. This | ||||||
663 | /// greatly reduces the number of nodes we need to allocate for types (for | ||||||
664 | /// example we only need one for 'int', 'const int', 'volatile int', | ||||||
665 | /// 'const volatile int', etc). | ||||||
666 | /// | ||||||
667 | /// As an added efficiency bonus, instead of making this a pair, we | ||||||
668 | /// just store the two bits we care about in the low bits of the | ||||||
669 | /// pointer. To handle the packing/unpacking, we make QualType be a | ||||||
670 | /// simple wrapper class that acts like a smart pointer. A third bit | ||||||
671 | /// indicates whether there are extended qualifiers present, in which | ||||||
672 | /// case the pointer points to a special structure. | ||||||
673 | class QualType { | ||||||
674 | friend class QualifierCollector; | ||||||
675 | |||||||
676 | // Thankfully, these are efficiently composable. | ||||||
677 | llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>, | ||||||
678 | Qualifiers::FastWidth> Value; | ||||||
679 | |||||||
680 | const ExtQuals *getExtQualsUnsafe() const { | ||||||
681 | return Value.getPointer().get<const ExtQuals*>(); | ||||||
682 | } | ||||||
683 | |||||||
684 | const Type *getTypePtrUnsafe() const { | ||||||
685 | return Value.getPointer().get<const Type*>(); | ||||||
686 | } | ||||||
687 | |||||||
688 | const ExtQualsTypeCommonBase *getCommonPtr() const { | ||||||
689 | assert(!isNull() && "Cannot retrieve a NULL type pointer")(static_cast <bool> (!isNull() && "Cannot retrieve a NULL type pointer" ) ? void (0) : __assert_fail ("!isNull() && \"Cannot retrieve a NULL type pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 689, __extension__ __PRETTY_FUNCTION__)); | ||||||
690 | auto CommonPtrVal = reinterpret_cast<uintptr_t>(Value.getOpaqueValue()); | ||||||
691 | CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1); | ||||||
692 | return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal); | ||||||
693 | } | ||||||
694 | |||||||
695 | public: | ||||||
696 | QualType() = default; | ||||||
697 | QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {} | ||||||
698 | QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {} | ||||||
699 | |||||||
700 | unsigned getLocalFastQualifiers() const { return Value.getInt(); } | ||||||
701 | void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } | ||||||
702 | |||||||
703 | /// Retrieves a pointer to the underlying (unqualified) type. | ||||||
704 | /// | ||||||
705 | /// This function requires that the type not be NULL. If the type might be | ||||||
706 | /// NULL, use the (slightly less efficient) \c getTypePtrOrNull(). | ||||||
707 | const Type *getTypePtr() const; | ||||||
708 | |||||||
709 | const Type *getTypePtrOrNull() const; | ||||||
710 | |||||||
711 | /// Retrieves a pointer to the name of the base type. | ||||||
712 | const IdentifierInfo *getBaseTypeIdentifier() const; | ||||||
713 | |||||||
714 | /// Divides a QualType into its unqualified type and a set of local | ||||||
715 | /// qualifiers. | ||||||
716 | SplitQualType split() const; | ||||||
717 | |||||||
718 | void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } | ||||||
719 | |||||||
720 | static QualType getFromOpaquePtr(const void *Ptr) { | ||||||
721 | QualType T; | ||||||
722 | T.Value.setFromOpaqueValue(const_cast<void*>(Ptr)); | ||||||
723 | return T; | ||||||
724 | } | ||||||
725 | |||||||
726 | const Type &operator*() const { | ||||||
727 | return *getTypePtr(); | ||||||
728 | } | ||||||
729 | |||||||
730 | const Type *operator->() const { | ||||||
731 | return getTypePtr(); | ||||||
732 | } | ||||||
733 | |||||||
734 | bool isCanonical() const; | ||||||
735 | bool isCanonicalAsParam() const; | ||||||
736 | |||||||
737 | /// Return true if this QualType doesn't point to a type yet. | ||||||
738 | bool isNull() const { | ||||||
739 | return Value.getPointer().isNull(); | ||||||
740 | } | ||||||
741 | |||||||
742 | /// Determine whether this particular QualType instance has the | ||||||
743 | /// "const" qualifier set, without looking through typedefs that may have | ||||||
744 | /// added "const" at a different level. | ||||||
745 | bool isLocalConstQualified() const { | ||||||
746 | return (getLocalFastQualifiers() & Qualifiers::Const); | ||||||
747 | } | ||||||
748 | |||||||
749 | /// Determine whether this type is const-qualified. | ||||||
750 | bool isConstQualified() const; | ||||||
751 | |||||||
752 | /// Determine whether this particular QualType instance has the | ||||||
753 | /// "restrict" qualifier set, without looking through typedefs that may have | ||||||
754 | /// added "restrict" at a different level. | ||||||
755 | bool isLocalRestrictQualified() const { | ||||||
756 | return (getLocalFastQualifiers() & Qualifiers::Restrict); | ||||||
757 | } | ||||||
758 | |||||||
759 | /// Determine whether this type is restrict-qualified. | ||||||
760 | bool isRestrictQualified() const; | ||||||
761 | |||||||
762 | /// Determine whether this particular QualType instance has the | ||||||
763 | /// "volatile" qualifier set, without looking through typedefs that may have | ||||||
764 | /// added "volatile" at a different level. | ||||||
765 | bool isLocalVolatileQualified() const { | ||||||
766 | return (getLocalFastQualifiers() & Qualifiers::Volatile); | ||||||
767 | } | ||||||
768 | |||||||
769 | /// Determine whether this type is volatile-qualified. | ||||||
770 | bool isVolatileQualified() const; | ||||||
771 | |||||||
772 | /// Determine whether this particular QualType instance has any | ||||||
773 | /// qualifiers, without looking through any typedefs that might add | ||||||
774 | /// qualifiers at a different level. | ||||||
775 | bool hasLocalQualifiers() const { | ||||||
776 | return getLocalFastQualifiers() || hasLocalNonFastQualifiers(); | ||||||
777 | } | ||||||
778 | |||||||
779 | /// Determine whether this type has any qualifiers. | ||||||
780 | bool hasQualifiers() const; | ||||||
781 | |||||||
782 | /// Determine whether this particular QualType instance has any | ||||||
783 | /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType | ||||||
784 | /// instance. | ||||||
785 | bool hasLocalNonFastQualifiers() const { | ||||||
786 | return Value.getPointer().is<const ExtQuals*>(); | ||||||
787 | } | ||||||
788 | |||||||
789 | /// Retrieve the set of qualifiers local to this particular QualType | ||||||
790 | /// instance, not including any qualifiers acquired through typedefs or | ||||||
791 | /// other sugar. | ||||||
792 | Qualifiers getLocalQualifiers() const; | ||||||
793 | |||||||
794 | /// Retrieve the set of qualifiers applied to this type. | ||||||
795 | Qualifiers getQualifiers() const; | ||||||
796 | |||||||
797 | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers | ||||||
798 | /// local to this particular QualType instance, not including any qualifiers | ||||||
799 | /// acquired through typedefs or other sugar. | ||||||
800 | unsigned getLocalCVRQualifiers() const { | ||||||
801 | return getLocalFastQualifiers(); | ||||||
802 | } | ||||||
803 | |||||||
804 | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers | ||||||
805 | /// applied to this type. | ||||||
806 | unsigned getCVRQualifiers() const; | ||||||
807 | |||||||
808 | bool isConstant(const ASTContext& Ctx) const { | ||||||
809 | return QualType::isConstant(*this, Ctx); | ||||||
810 | } | ||||||
811 | |||||||
812 | /// Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). | ||||||
813 | bool isPODType(const ASTContext &Context) const; | ||||||
814 | |||||||
815 | /// Return true if this is a POD type according to the rules of the C++98 | ||||||
816 | /// standard, regardless of the current compilation's language. | ||||||
817 | bool isCXX98PODType(const ASTContext &Context) const; | ||||||
818 | |||||||
819 | /// Return true if this is a POD type according to the more relaxed rules | ||||||
820 | /// of the C++11 standard, regardless of the current compilation's language. | ||||||
821 | /// (C++0x [basic.types]p9). Note that, unlike | ||||||
822 | /// CXXRecordDecl::isCXX11StandardLayout, this takes DRs into account. | ||||||
823 | bool isCXX11PODType(const ASTContext &Context) const; | ||||||
824 | |||||||
825 | /// Return true if this is a trivial type per (C++0x [basic.types]p9) | ||||||
826 | bool isTrivialType(const ASTContext &Context) const; | ||||||
827 | |||||||
828 | /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) | ||||||
829 | bool isTriviallyCopyableType(const ASTContext &Context) const; | ||||||
830 | |||||||
831 | |||||||
832 | /// Returns true if it is a class and it might be dynamic. | ||||||
833 | bool mayBeDynamicClass() const; | ||||||
834 | |||||||
835 | /// Returns true if it is not a class or if the class might not be dynamic. | ||||||
836 | bool mayBeNotDynamicClass() const; | ||||||
837 | |||||||
838 | // Don't promise in the API that anything besides 'const' can be | ||||||
839 | // easily added. | ||||||
840 | |||||||
841 | /// Add the `const` type qualifier to this QualType. | ||||||
842 | void addConst() { | ||||||
843 | addFastQualifiers(Qualifiers::Const); | ||||||
844 | } | ||||||
845 | QualType withConst() const { | ||||||
846 | return withFastQualifiers(Qualifiers::Const); | ||||||
847 | } | ||||||
848 | |||||||
849 | /// Add the `volatile` type qualifier to this QualType. | ||||||
850 | void addVolatile() { | ||||||
851 | addFastQualifiers(Qualifiers::Volatile); | ||||||
852 | } | ||||||
853 | QualType withVolatile() const { | ||||||
854 | return withFastQualifiers(Qualifiers::Volatile); | ||||||
855 | } | ||||||
856 | |||||||
857 | /// Add the `restrict` qualifier to this QualType. | ||||||
858 | void addRestrict() { | ||||||
859 | addFastQualifiers(Qualifiers::Restrict); | ||||||
860 | } | ||||||
861 | QualType withRestrict() const { | ||||||
862 | return withFastQualifiers(Qualifiers::Restrict); | ||||||
863 | } | ||||||
864 | |||||||
865 | QualType withCVRQualifiers(unsigned CVR) const { | ||||||
866 | return withFastQualifiers(CVR); | ||||||
867 | } | ||||||
868 | |||||||
869 | void addFastQualifiers(unsigned TQs) { | ||||||
870 | assert(!(TQs & ~Qualifiers::FastMask)(static_cast <bool> (!(TQs & ~Qualifiers::FastMask) && "non-fast qualifier bits set in mask!") ? void (0 ) : __assert_fail ("!(TQs & ~Qualifiers::FastMask) && \"non-fast qualifier bits set in mask!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 871, __extension__ __PRETTY_FUNCTION__)) | ||||||
871 | && "non-fast qualifier bits set in mask!")(static_cast <bool> (!(TQs & ~Qualifiers::FastMask) && "non-fast qualifier bits set in mask!") ? void (0 ) : __assert_fail ("!(TQs & ~Qualifiers::FastMask) && \"non-fast qualifier bits set in mask!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 871, __extension__ __PRETTY_FUNCTION__)); | ||||||
872 | Value.setInt(Value.getInt() | TQs); | ||||||
873 | } | ||||||
874 | |||||||
875 | void removeLocalConst(); | ||||||
876 | void removeLocalVolatile(); | ||||||
877 | void removeLocalRestrict(); | ||||||
878 | void removeLocalCVRQualifiers(unsigned Mask); | ||||||
879 | |||||||
880 | void removeLocalFastQualifiers() { Value.setInt(0); } | ||||||
881 | void removeLocalFastQualifiers(unsigned Mask) { | ||||||
882 | assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers")(static_cast <bool> (!(Mask & ~Qualifiers::FastMask ) && "mask has non-fast qualifiers") ? void (0) : __assert_fail ("!(Mask & ~Qualifiers::FastMask) && \"mask has non-fast qualifiers\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 882, __extension__ __PRETTY_FUNCTION__)); | ||||||
883 | Value.setInt(Value.getInt() & ~Mask); | ||||||
884 | } | ||||||
885 | |||||||
886 | // Creates a type with the given qualifiers in addition to any | ||||||
887 | // qualifiers already on this type. | ||||||
888 | QualType withFastQualifiers(unsigned TQs) const { | ||||||
889 | QualType T = *this; | ||||||
890 | T.addFastQualifiers(TQs); | ||||||
891 | return T; | ||||||
892 | } | ||||||
893 | |||||||
894 | // Creates a type with exactly the given fast qualifiers, removing | ||||||
895 | // any existing fast qualifiers. | ||||||
896 | QualType withExactLocalFastQualifiers(unsigned TQs) const { | ||||||
897 | return withoutLocalFastQualifiers().withFastQualifiers(TQs); | ||||||
898 | } | ||||||
899 | |||||||
900 | // Removes fast qualifiers, but leaves any extended qualifiers in place. | ||||||
901 | QualType withoutLocalFastQualifiers() const { | ||||||
902 | QualType T = *this; | ||||||
903 | T.removeLocalFastQualifiers(); | ||||||
904 | return T; | ||||||
905 | } | ||||||
906 | |||||||
907 | QualType getCanonicalType() const; | ||||||
908 | |||||||
909 | /// Return this type with all of the instance-specific qualifiers | ||||||
910 | /// removed, but without removing any qualifiers that may have been applied | ||||||
911 | /// through typedefs. | ||||||
912 | QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); } | ||||||
913 | |||||||
914 | /// Retrieve the unqualified variant of the given type, | ||||||
915 | /// removing as little sugar as possible. | ||||||
916 | /// | ||||||
917 | /// This routine looks through various kinds of sugar to find the | ||||||
918 | /// least-desugared type that is unqualified. For example, given: | ||||||
919 | /// | ||||||
920 | /// \code | ||||||
921 | /// typedef int Integer; | ||||||
922 | /// typedef const Integer CInteger; | ||||||
923 | /// typedef CInteger DifferenceType; | ||||||
924 | /// \endcode | ||||||
925 | /// | ||||||
926 | /// Executing \c getUnqualifiedType() on the type \c DifferenceType will | ||||||
927 | /// desugar until we hit the type \c Integer, which has no qualifiers on it. | ||||||
928 | /// | ||||||
929 | /// The resulting type might still be qualified if it's sugar for an array | ||||||
930 | /// type. To strip qualifiers even from within a sugared array type, use | ||||||
931 | /// ASTContext::getUnqualifiedArrayType. | ||||||
932 | inline QualType getUnqualifiedType() const; | ||||||
933 | |||||||
934 | /// Retrieve the unqualified variant of the given type, removing as little | ||||||
935 | /// sugar as possible. | ||||||
936 | /// | ||||||
937 | /// Like getUnqualifiedType(), but also returns the set of | ||||||
938 | /// qualifiers that were built up. | ||||||
939 | /// | ||||||
940 | /// The resulting type might still be qualified if it's sugar for an array | ||||||
941 | /// type. To strip qualifiers even from within a sugared array type, use | ||||||
942 | /// ASTContext::getUnqualifiedArrayType. | ||||||
943 | inline SplitQualType getSplitUnqualifiedType() const; | ||||||
944 | |||||||
945 | /// Determine whether this type is more qualified than the other | ||||||
946 | /// given type, requiring exact equality for non-CVR qualifiers. | ||||||
947 | bool isMoreQualifiedThan(QualType Other) const; | ||||||
948 | |||||||
949 | /// Determine whether this type is at least as qualified as the other | ||||||
950 | /// given type, requiring exact equality for non-CVR qualifiers. | ||||||
951 | bool isAtLeastAsQualifiedAs(QualType Other) const; | ||||||
952 | |||||||
953 | QualType getNonReferenceType() const; | ||||||
954 | |||||||
955 | /// Determine the type of a (typically non-lvalue) expression with the | ||||||
956 | /// specified result type. | ||||||
957 | /// | ||||||
958 | /// This routine should be used for expressions for which the return type is | ||||||
959 | /// explicitly specified (e.g., in a cast or call) and isn't necessarily | ||||||
960 | /// an lvalue. It removes a top-level reference (since there are no | ||||||
961 | /// expressions of reference type) and deletes top-level cvr-qualifiers | ||||||
962 | /// from non-class types (in C++) or all types (in C). | ||||||
963 | QualType getNonLValueExprType(const ASTContext &Context) const; | ||||||
964 | |||||||
965 | /// Remove an outer pack expansion type (if any) from this type. Used as part | ||||||
966 | /// of converting the type of a declaration to the type of an expression that | ||||||
967 | /// references that expression. It's meaningless for an expression to have a | ||||||
968 | /// pack expansion type. | ||||||
969 | QualType getNonPackExpansionType() const; | ||||||
970 | |||||||
971 | /// Return the specified type with any "sugar" removed from | ||||||
972 | /// the type. This takes off typedefs, typeof's etc. If the outer level of | ||||||
973 | /// the type is already concrete, it returns it unmodified. This is similar | ||||||
974 | /// to getting the canonical type, but it doesn't remove *all* typedefs. For | ||||||
975 | /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is | ||||||
976 | /// concrete. | ||||||
977 | /// | ||||||
978 | /// Qualifiers are left in place. | ||||||
979 | QualType getDesugaredType(const ASTContext &Context) const { | ||||||
980 | return getDesugaredType(*this, Context); | ||||||
981 | } | ||||||
982 | |||||||
983 | SplitQualType getSplitDesugaredType() const { | ||||||
984 | return getSplitDesugaredType(*this); | ||||||
985 | } | ||||||
986 | |||||||
987 | /// Return the specified type with one level of "sugar" removed from | ||||||
988 | /// the type. | ||||||
989 | /// | ||||||
990 | /// This routine takes off the first typedef, typeof, etc. If the outer level | ||||||
991 | /// of the type is already concrete, it returns it unmodified. | ||||||
992 | QualType getSingleStepDesugaredType(const ASTContext &Context) const { | ||||||
993 | return getSingleStepDesugaredTypeImpl(*this, Context); | ||||||
994 | } | ||||||
995 | |||||||
996 | /// Returns the specified type after dropping any | ||||||
997 | /// outer-level parentheses. | ||||||
998 | QualType IgnoreParens() const { | ||||||
999 | if (isa<ParenType>(*this)) | ||||||
1000 | return QualType::IgnoreParens(*this); | ||||||
1001 | return *this; | ||||||
1002 | } | ||||||
1003 | |||||||
1004 | /// Indicate whether the specified types and qualifiers are identical. | ||||||
1005 | friend bool operator==(const QualType &LHS, const QualType &RHS) { | ||||||
1006 | return LHS.Value == RHS.Value; | ||||||
1007 | } | ||||||
1008 | friend bool operator!=(const QualType &LHS, const QualType &RHS) { | ||||||
1009 | return LHS.Value != RHS.Value; | ||||||
1010 | } | ||||||
1011 | friend bool operator<(const QualType &LHS, const QualType &RHS) { | ||||||
1012 | return LHS.Value < RHS.Value; | ||||||
1013 | } | ||||||
1014 | |||||||
1015 | static std::string getAsString(SplitQualType split, | ||||||
1016 | const PrintingPolicy &Policy) { | ||||||
1017 | return getAsString(split.Ty, split.Quals, Policy); | ||||||
1018 | } | ||||||
1019 | static std::string getAsString(const Type *ty, Qualifiers qs, | ||||||
1020 | const PrintingPolicy &Policy); | ||||||
1021 | |||||||
1022 | std::string getAsString() const; | ||||||
1023 | std::string getAsString(const PrintingPolicy &Policy) const; | ||||||
1024 | |||||||
1025 | void print(raw_ostream &OS, const PrintingPolicy &Policy, | ||||||
1026 | const Twine &PlaceHolder = Twine(), | ||||||
1027 | unsigned Indentation = 0) const; | ||||||
1028 | |||||||
1029 | static void print(SplitQualType split, raw_ostream &OS, | ||||||
1030 | const PrintingPolicy &policy, const Twine &PlaceHolder, | ||||||
1031 | unsigned Indentation = 0) { | ||||||
1032 | return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation); | ||||||
1033 | } | ||||||
1034 | |||||||
1035 | static void print(const Type *ty, Qualifiers qs, | ||||||
1036 | raw_ostream &OS, const PrintingPolicy &policy, | ||||||
1037 | const Twine &PlaceHolder, | ||||||
1038 | unsigned Indentation = 0); | ||||||
1039 | |||||||
1040 | void getAsStringInternal(std::string &Str, | ||||||
1041 | const PrintingPolicy &Policy) const; | ||||||
1042 | |||||||
1043 | static void getAsStringInternal(SplitQualType split, std::string &out, | ||||||
1044 | const PrintingPolicy &policy) { | ||||||
1045 | return getAsStringInternal(split.Ty, split.Quals, out, policy); | ||||||
1046 | } | ||||||
1047 | |||||||
1048 | static void getAsStringInternal(const Type *ty, Qualifiers qs, | ||||||
1049 | std::string &out, | ||||||
1050 | const PrintingPolicy &policy); | ||||||
1051 | |||||||
1052 | class StreamedQualTypeHelper { | ||||||
1053 | const QualType &T; | ||||||
1054 | const PrintingPolicy &Policy; | ||||||
1055 | const Twine &PlaceHolder; | ||||||
1056 | unsigned Indentation; | ||||||
1057 | |||||||
1058 | public: | ||||||
1059 | StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, | ||||||
1060 | const Twine &PlaceHolder, unsigned Indentation) | ||||||
1061 | : T(T), Policy(Policy), PlaceHolder(PlaceHolder), | ||||||
1062 | Indentation(Indentation) {} | ||||||
1063 | |||||||
1064 | friend raw_ostream &operator<<(raw_ostream &OS, | ||||||
1065 | const StreamedQualTypeHelper &SQT) { | ||||||
1066 | SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation); | ||||||
1067 | return OS; | ||||||
1068 | } | ||||||
1069 | }; | ||||||
1070 | |||||||
1071 | StreamedQualTypeHelper stream(const PrintingPolicy &Policy, | ||||||
1072 | const Twine &PlaceHolder = Twine(), | ||||||
1073 | unsigned Indentation = 0) const { | ||||||
1074 | return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation); | ||||||
1075 | } | ||||||
1076 | |||||||
1077 | void dump(const char *s) const; | ||||||
1078 | void dump() const; | ||||||
1079 | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; | ||||||
1080 | |||||||
1081 | void Profile(llvm::FoldingSetNodeID &ID) const { | ||||||
1082 | ID.AddPointer(getAsOpaquePtr()); | ||||||
1083 | } | ||||||
1084 | |||||||
1085 | /// Check if this type has any address space qualifier. | ||||||
1086 | inline bool hasAddressSpace() const; | ||||||
1087 | |||||||
1088 | /// Return the address space of this type. | ||||||
1089 | inline LangAS getAddressSpace() const; | ||||||
1090 | |||||||
1091 | /// Returns true if address space qualifiers overlap with T address space | ||||||
1092 | /// qualifiers. | ||||||
1093 | /// OpenCL C defines conversion rules for pointers to different address spaces | ||||||
1094 | /// and notion of overlapping address spaces. | ||||||
1095 | /// CL1.1 or CL1.2: | ||||||
1096 | /// address spaces overlap iff they are they same. | ||||||
1097 | /// OpenCL C v2.0 s6.5.5 adds: | ||||||
1098 | /// __generic overlaps with any address space except for __constant. | ||||||
1099 | bool isAddressSpaceOverlapping(QualType T) const { | ||||||
1100 | Qualifiers Q = getQualifiers(); | ||||||
1101 | Qualifiers TQ = T.getQualifiers(); | ||||||
1102 | // Address spaces overlap if at least one of them is a superset of another | ||||||
1103 | return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q); | ||||||
1104 | } | ||||||
1105 | |||||||
1106 | /// Returns gc attribute of this type. | ||||||
1107 | inline Qualifiers::GC getObjCGCAttr() const; | ||||||
1108 | |||||||
1109 | /// true when Type is objc's weak. | ||||||
1110 | bool isObjCGCWeak() const { | ||||||
1111 | return getObjCGCAttr() == Qualifiers::Weak; | ||||||
1112 | } | ||||||
1113 | |||||||
1114 | /// true when Type is objc's strong. | ||||||
1115 | bool isObjCGCStrong() const { | ||||||
1116 | return getObjCGCAttr() == Qualifiers::Strong; | ||||||
1117 | } | ||||||
1118 | |||||||
1119 | /// Returns lifetime attribute of this type. | ||||||
1120 | Qualifiers::ObjCLifetime getObjCLifetime() const { | ||||||
1121 | return getQualifiers().getObjCLifetime(); | ||||||
1122 | } | ||||||
1123 | |||||||
1124 | bool hasNonTrivialObjCLifetime() const { | ||||||
1125 | return getQualifiers().hasNonTrivialObjCLifetime(); | ||||||
1126 | } | ||||||
1127 | |||||||
1128 | bool hasStrongOrWeakObjCLifetime() const { | ||||||
1129 | return getQualifiers().hasStrongOrWeakObjCLifetime(); | ||||||
1130 | } | ||||||
1131 | |||||||
1132 | // true when Type is objc's weak and weak is enabled but ARC isn't. | ||||||
1133 | bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const; | ||||||
1134 | |||||||
1135 | enum PrimitiveDefaultInitializeKind { | ||||||
1136 | /// The type does not fall into any of the following categories. Note that | ||||||
1137 | /// this case is zero-valued so that values of this enum can be used as a | ||||||
1138 | /// boolean condition for non-triviality. | ||||||
1139 | PDIK_Trivial, | ||||||
1140 | |||||||
1141 | /// The type is an Objective-C retainable pointer type that is qualified | ||||||
1142 | /// with the ARC __strong qualifier. | ||||||
1143 | PDIK_ARCStrong, | ||||||
1144 | |||||||
1145 | /// The type is an Objective-C retainable pointer type that is qualified | ||||||
1146 | /// with the ARC __weak qualifier. | ||||||
1147 | PDIK_ARCWeak, | ||||||
1148 | |||||||
1149 | /// The type is a struct containing a field whose type is not PCK_Trivial. | ||||||
1150 | PDIK_Struct | ||||||
1151 | }; | ||||||
1152 | |||||||
1153 | /// Functions to query basic properties of non-trivial C struct types. | ||||||
1154 | |||||||
1155 | /// Check if this is a non-trivial type that would cause a C struct | ||||||
1156 | /// transitively containing this type to be non-trivial to default initialize | ||||||
1157 | /// and return the kind. | ||||||
1158 | PrimitiveDefaultInitializeKind | ||||||
1159 | isNonTrivialToPrimitiveDefaultInitialize() const; | ||||||
1160 | |||||||
1161 | enum PrimitiveCopyKind { | ||||||
1162 | /// The type does not fall into any of the following categories. Note that | ||||||
1163 | /// this case is zero-valued so that values of this enum can be used as a | ||||||
1164 | /// boolean condition for non-triviality. | ||||||
1165 | PCK_Trivial, | ||||||
1166 | |||||||
1167 | /// The type would be trivial except that it is volatile-qualified. Types | ||||||
1168 | /// that fall into one of the other non-trivial cases may additionally be | ||||||
1169 | /// volatile-qualified. | ||||||
1170 | PCK_VolatileTrivial, | ||||||
1171 | |||||||
1172 | /// The type is an Objective-C retainable pointer type that is qualified | ||||||
1173 | /// with the ARC __strong qualifier. | ||||||
1174 | PCK_ARCStrong, | ||||||
1175 | |||||||
1176 | /// The type is an Objective-C retainable pointer type that is qualified | ||||||
1177 | /// with the ARC __weak qualifier. | ||||||
1178 | PCK_ARCWeak, | ||||||
1179 | |||||||
1180 | /// The type is a struct containing a field whose type is neither | ||||||
1181 | /// PCK_Trivial nor PCK_VolatileTrivial. | ||||||
1182 | /// Note that a C++ struct type does not necessarily match this; C++ copying | ||||||
1183 | /// semantics are too complex to express here, in part because they depend | ||||||
1184 | /// on the exact constructor or assignment operator that is chosen by | ||||||
1185 | /// overload resolution to do the copy. | ||||||
1186 | PCK_Struct | ||||||
1187 | }; | ||||||
1188 | |||||||
1189 | /// Check if this is a non-trivial type that would cause a C struct | ||||||
1190 | /// transitively containing this type to be non-trivial to copy and return the | ||||||
1191 | /// kind. | ||||||
1192 | PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const; | ||||||
1193 | |||||||
1194 | /// Check if this is a non-trivial type that would cause a C struct | ||||||
1195 | /// transitively containing this type to be non-trivial to destructively | ||||||
1196 | /// move and return the kind. Destructive move in this context is a C++-style | ||||||
1197 | /// move in which the source object is placed in a valid but unspecified state | ||||||
1198 | /// after it is moved, as opposed to a truly destructive move in which the | ||||||
1199 | /// source object is placed in an uninitialized state. | ||||||
1200 | PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const; | ||||||
1201 | |||||||
1202 | enum DestructionKind { | ||||||
1203 | DK_none, | ||||||
1204 | DK_cxx_destructor, | ||||||
1205 | DK_objc_strong_lifetime, | ||||||
1206 | DK_objc_weak_lifetime, | ||||||
1207 | DK_nontrivial_c_struct | ||||||
1208 | }; | ||||||
1209 | |||||||
1210 | /// Returns a nonzero value if objects of this type require | ||||||
1211 | /// non-trivial work to clean up after. Non-zero because it's | ||||||
1212 | /// conceivable that qualifiers (objc_gc(weak)?) could make | ||||||
1213 | /// something require destruction. | ||||||
1214 | DestructionKind isDestructedType() const { | ||||||
1215 | return isDestructedTypeImpl(*this); | ||||||
1216 | } | ||||||
1217 | |||||||
1218 | /// Check if this is or contains a C union that is non-trivial to | ||||||
1219 | /// default-initialize, which is a union that has a member that is non-trivial | ||||||
1220 | /// to default-initialize. If this returns true, | ||||||
1221 | /// isNonTrivialToPrimitiveDefaultInitialize returns PDIK_Struct. | ||||||
1222 | bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const; | ||||||
1223 | |||||||
1224 | /// Check if this is or contains a C union that is non-trivial to destruct, | ||||||
1225 | /// which is a union that has a member that is non-trivial to destruct. If | ||||||
1226 | /// this returns true, isDestructedType returns DK_nontrivial_c_struct. | ||||||
1227 | bool hasNonTrivialToPrimitiveDestructCUnion() const; | ||||||
1228 | |||||||
1229 | /// Check if this is or contains a C union that is non-trivial to copy, which | ||||||
1230 | /// is a union that has a member that is non-trivial to copy. If this returns | ||||||
1231 | /// true, isNonTrivialToPrimitiveCopy returns PCK_Struct. | ||||||
1232 | bool hasNonTrivialToPrimitiveCopyCUnion() const; | ||||||
1233 | |||||||
1234 | /// Determine whether expressions of the given type are forbidden | ||||||
1235 | /// from being lvalues in C. | ||||||
1236 | /// | ||||||
1237 | /// The expression types that are forbidden to be lvalues are: | ||||||
1238 | /// - 'void', but not qualified void | ||||||
1239 | /// - function types | ||||||
1240 | /// | ||||||
1241 | /// The exact rule here is C99 6.3.2.1: | ||||||
1242 | /// An lvalue is an expression with an object type or an incomplete | ||||||
1243 | /// type other than void. | ||||||
1244 | bool isCForbiddenLValueType() const; | ||||||
1245 | |||||||
1246 | /// Substitute type arguments for the Objective-C type parameters used in the | ||||||
1247 | /// subject type. | ||||||
1248 | /// | ||||||
1249 | /// \param ctx ASTContext in which the type exists. | ||||||
1250 | /// | ||||||
1251 | /// \param typeArgs The type arguments that will be substituted for the | ||||||
1252 | /// Objective-C type parameters in the subject type, which are generally | ||||||
1253 | /// computed via \c Type::getObjCSubstitutions. If empty, the type | ||||||
1254 | /// parameters will be replaced with their bounds or id/Class, as appropriate | ||||||
1255 | /// for the context. | ||||||
1256 | /// | ||||||
1257 | /// \param context The context in which the subject type was written. | ||||||
1258 | /// | ||||||
1259 | /// \returns the resulting type. | ||||||
1260 | QualType substObjCTypeArgs(ASTContext &ctx, | ||||||
1261 | ArrayRef<QualType> typeArgs, | ||||||
1262 | ObjCSubstitutionContext context) const; | ||||||
1263 | |||||||
1264 | /// Substitute type arguments from an object type for the Objective-C type | ||||||
1265 | /// parameters used in the subject type. | ||||||
1266 | /// | ||||||
1267 | /// This operation combines the computation of type arguments for | ||||||
1268 | /// substitution (\c Type::getObjCSubstitutions) with the actual process of | ||||||
1269 | /// substitution (\c QualType::substObjCTypeArgs) for the convenience of | ||||||
1270 | /// callers that need to perform a single substitution in isolation. | ||||||
1271 | /// | ||||||
1272 | /// \param objectType The type of the object whose member type we're | ||||||
1273 | /// substituting into. For example, this might be the receiver of a message | ||||||
1274 | /// or the base of a property access. | ||||||
1275 | /// | ||||||
1276 | /// \param dc The declaration context from which the subject type was | ||||||
1277 | /// retrieved, which indicates (for example) which type parameters should | ||||||
1278 | /// be substituted. | ||||||
1279 | /// | ||||||
1280 | /// \param context The context in which the subject type was written. | ||||||
1281 | /// | ||||||
1282 | /// \returns the subject type after replacing all of the Objective-C type | ||||||
1283 | /// parameters with their corresponding arguments. | ||||||
1284 | QualType substObjCMemberType(QualType objectType, | ||||||
1285 | const DeclContext *dc, | ||||||
1286 | ObjCSubstitutionContext context) const; | ||||||
1287 | |||||||
1288 | /// Strip Objective-C "__kindof" types from the given type. | ||||||
1289 | QualType stripObjCKindOfType(const ASTContext &ctx) const; | ||||||
1290 | |||||||
1291 | /// Remove all qualifiers including _Atomic. | ||||||
1292 | QualType getAtomicUnqualifiedType() const; | ||||||
1293 | |||||||
1294 | private: | ||||||
1295 | // These methods are implemented in a separate translation unit; | ||||||
1296 | // "static"-ize them to avoid creating temporary QualTypes in the | ||||||
1297 | // caller. | ||||||
1298 | static bool isConstant(QualType T, const ASTContext& Ctx); | ||||||
1299 | static QualType getDesugaredType(QualType T, const ASTContext &Context); | ||||||
1300 | static SplitQualType getSplitDesugaredType(QualType T); | ||||||
1301 | static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); | ||||||
1302 | static QualType getSingleStepDesugaredTypeImpl(QualType type, | ||||||
1303 | const ASTContext &C); | ||||||
1304 | static QualType IgnoreParens(QualType T); | ||||||
1305 | static DestructionKind isDestructedTypeImpl(QualType type); | ||||||
1306 | |||||||
1307 | /// Check if \param RD is or contains a non-trivial C union. | ||||||
1308 | static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD); | ||||||
1309 | static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD); | ||||||
1310 | static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD); | ||||||
1311 | }; | ||||||
1312 | |||||||
1313 | } // namespace clang | ||||||
1314 | |||||||
1315 | namespace llvm { | ||||||
1316 | |||||||
1317 | /// Implement simplify_type for QualType, so that we can dyn_cast from QualType | ||||||
1318 | /// to a specific Type class. | ||||||
1319 | template<> struct simplify_type< ::clang::QualType> { | ||||||
1320 | using SimpleType = const ::clang::Type *; | ||||||
1321 | |||||||
1322 | static SimpleType getSimplifiedValue(::clang::QualType Val) { | ||||||
1323 | return Val.getTypePtr(); | ||||||
1324 | } | ||||||
1325 | }; | ||||||
1326 | |||||||
1327 | // Teach SmallPtrSet that QualType is "basically a pointer". | ||||||
1328 | template<> | ||||||
1329 | struct PointerLikeTypeTraits<clang::QualType> { | ||||||
1330 | static inline void *getAsVoidPointer(clang::QualType P) { | ||||||
1331 | return P.getAsOpaquePtr(); | ||||||
1332 | } | ||||||
1333 | |||||||
1334 | static inline clang::QualType getFromVoidPointer(void *P) { | ||||||
1335 | return clang::QualType::getFromOpaquePtr(P); | ||||||
1336 | } | ||||||
1337 | |||||||
1338 | // Various qualifiers go in low bits. | ||||||
1339 | static constexpr int NumLowBitsAvailable = 0; | ||||||
1340 | }; | ||||||
1341 | |||||||
1342 | } // namespace llvm | ||||||
1343 | |||||||
1344 | namespace clang { | ||||||
1345 | |||||||
1346 | /// Base class that is common to both the \c ExtQuals and \c Type | ||||||
1347 | /// classes, which allows \c QualType to access the common fields between the | ||||||
1348 | /// two. | ||||||
1349 | class ExtQualsTypeCommonBase { | ||||||
1350 | friend class ExtQuals; | ||||||
1351 | friend class QualType; | ||||||
1352 | friend class Type; | ||||||
1353 | |||||||
1354 | /// The "base" type of an extended qualifiers type (\c ExtQuals) or | ||||||
1355 | /// a self-referential pointer (for \c Type). | ||||||
1356 | /// | ||||||
1357 | /// This pointer allows an efficient mapping from a QualType to its | ||||||
1358 | /// underlying type pointer. | ||||||
1359 | const Type *const BaseType; | ||||||
1360 | |||||||
1361 | /// The canonical type of this type. A QualType. | ||||||
1362 | QualType CanonicalType; | ||||||
1363 | |||||||
1364 | ExtQualsTypeCommonBase(const Type *baseType, QualType canon) | ||||||
1365 | : BaseType(baseType), CanonicalType(canon) {} | ||||||
1366 | }; | ||||||
1367 | |||||||
1368 | /// We can encode up to four bits in the low bits of a | ||||||
1369 | /// type pointer, but there are many more type qualifiers that we want | ||||||
1370 | /// to be able to apply to an arbitrary type. Therefore we have this | ||||||
1371 | /// struct, intended to be heap-allocated and used by QualType to | ||||||
1372 | /// store qualifiers. | ||||||
1373 | /// | ||||||
1374 | /// The current design tags the 'const', 'restrict', and 'volatile' qualifiers | ||||||
1375 | /// in three low bits on the QualType pointer; a fourth bit records whether | ||||||
1376 | /// the pointer is an ExtQuals node. The extended qualifiers (address spaces, | ||||||
1377 | /// Objective-C GC attributes) are much more rare. | ||||||
1378 | class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode { | ||||||
1379 | // NOTE: changing the fast qualifiers should be straightforward as | ||||||
1380 | // long as you don't make 'const' non-fast. | ||||||
1381 | // 1. Qualifiers: | ||||||
1382 | // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ). | ||||||
1383 | // Fast qualifiers must occupy the low-order bits. | ||||||
1384 | // b) Update Qualifiers::FastWidth and FastMask. | ||||||
1385 | // 2. QualType: | ||||||
1386 | // a) Update is{Volatile,Restrict}Qualified(), defined inline. | ||||||
1387 | // b) Update remove{Volatile,Restrict}, defined near the end of | ||||||
1388 | // this header. | ||||||
1389 | // 3. ASTContext: | ||||||
1390 | // a) Update get{Volatile,Restrict}Type. | ||||||
1391 | |||||||
1392 | /// The immutable set of qualifiers applied by this node. Always contains | ||||||
1393 | /// extended qualifiers. | ||||||
1394 | Qualifiers Quals; | ||||||
1395 | |||||||
1396 | ExtQuals *this_() { return this; } | ||||||
1397 | |||||||
1398 | public: | ||||||
1399 | ExtQuals(const Type *baseType, QualType canon, Qualifiers quals) | ||||||
1400 | : ExtQualsTypeCommonBase(baseType, | ||||||
1401 | canon.isNull() ? QualType(this_(), 0) : canon), | ||||||
1402 | Quals(quals) { | ||||||
1403 | assert(Quals.hasNonFastQualifiers()(static_cast <bool> (Quals.hasNonFastQualifiers() && "ExtQuals created with no fast qualifiers") ? void (0) : __assert_fail ("Quals.hasNonFastQualifiers() && \"ExtQuals created with no fast qualifiers\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 1404, __extension__ __PRETTY_FUNCTION__)) | ||||||
1404 | && "ExtQuals created with no fast qualifiers")(static_cast <bool> (Quals.hasNonFastQualifiers() && "ExtQuals created with no fast qualifiers") ? void (0) : __assert_fail ("Quals.hasNonFastQualifiers() && \"ExtQuals created with no fast qualifiers\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 1404, __extension__ __PRETTY_FUNCTION__)); | ||||||
1405 | assert(!Quals.hasFastQualifiers()(static_cast <bool> (!Quals.hasFastQualifiers() && "ExtQuals created with fast qualifiers") ? void (0) : __assert_fail ("!Quals.hasFastQualifiers() && \"ExtQuals created with fast qualifiers\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 1406, __extension__ __PRETTY_FUNCTION__)) | ||||||
1406 | && "ExtQuals created with fast qualifiers")(static_cast <bool> (!Quals.hasFastQualifiers() && "ExtQuals created with fast qualifiers") ? void (0) : __assert_fail ("!Quals.hasFastQualifiers() && \"ExtQuals created with fast qualifiers\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 1406, __extension__ __PRETTY_FUNCTION__)); | ||||||
1407 | } | ||||||
1408 | |||||||
1409 | Qualifiers getQualifiers() const { return Quals; } | ||||||
1410 | |||||||
1411 | bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); } | ||||||
1412 | Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); } | ||||||
1413 | |||||||
1414 | bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); } | ||||||
1415 | Qualifiers::ObjCLifetime getObjCLifetime() const { | ||||||
1416 | return Quals.getObjCLifetime(); | ||||||
1417 | } | ||||||
1418 | |||||||
1419 | bool hasAddressSpace() const { return Quals.hasAddressSpace(); } | ||||||
1420 | LangAS getAddressSpace() const { return Quals.getAddressSpace(); } | ||||||
1421 | |||||||
1422 | const Type *getBaseType() const { return BaseType; } | ||||||
1423 | |||||||
1424 | public: | ||||||
1425 | void Profile(llvm::FoldingSetNodeID &ID) const { | ||||||
1426 | Profile(ID, getBaseType(), Quals); | ||||||
1427 | } | ||||||
1428 | |||||||
1429 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
1430 | const Type *BaseType, | ||||||
1431 | Qualifiers Quals) { | ||||||
1432 | assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!")(static_cast <bool> (!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!") ? void (0) : __assert_fail ("!Quals.hasFastQualifiers() && \"fast qualifiers in ExtQuals hash!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 1432, __extension__ __PRETTY_FUNCTION__)); | ||||||
1433 | ID.AddPointer(BaseType); | ||||||
1434 | Quals.Profile(ID); | ||||||
1435 | } | ||||||
1436 | }; | ||||||
1437 | |||||||
1438 | /// The kind of C++11 ref-qualifier associated with a function type. | ||||||
1439 | /// This determines whether a member function's "this" object can be an | ||||||
1440 | /// lvalue, rvalue, or neither. | ||||||
1441 | enum RefQualifierKind { | ||||||
1442 | /// No ref-qualifier was provided. | ||||||
1443 | RQ_None = 0, | ||||||
1444 | |||||||
1445 | /// An lvalue ref-qualifier was provided (\c &). | ||||||
1446 | RQ_LValue, | ||||||
1447 | |||||||
1448 | /// An rvalue ref-qualifier was provided (\c &&). | ||||||
1449 | RQ_RValue | ||||||
1450 | }; | ||||||
1451 | |||||||
1452 | /// Which keyword(s) were used to create an AutoType. | ||||||
1453 | enum class AutoTypeKeyword { | ||||||
1454 | /// auto | ||||||
1455 | Auto, | ||||||
1456 | |||||||
1457 | /// decltype(auto) | ||||||
1458 | DecltypeAuto, | ||||||
1459 | |||||||
1460 | /// __auto_type (GNU extension) | ||||||
1461 | GNUAutoType | ||||||
1462 | }; | ||||||
1463 | |||||||
1464 | /// The base class of the type hierarchy. | ||||||
1465 | /// | ||||||
1466 | /// A central concept with types is that each type always has a canonical | ||||||
1467 | /// type. A canonical type is the type with any typedef names stripped out | ||||||
1468 | /// of it or the types it references. For example, consider: | ||||||
1469 | /// | ||||||
1470 | /// typedef int foo; | ||||||
1471 | /// typedef foo* bar; | ||||||
1472 | /// 'int *' 'foo *' 'bar' | ||||||
1473 | /// | ||||||
1474 | /// There will be a Type object created for 'int'. Since int is canonical, its | ||||||
1475 | /// CanonicalType pointer points to itself. There is also a Type for 'foo' (a | ||||||
1476 | /// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next | ||||||
1477 | /// there is a PointerType that represents 'int*', which, like 'int', is | ||||||
1478 | /// canonical. Finally, there is a PointerType type for 'foo*' whose canonical | ||||||
1479 | /// type is 'int*', and there is a TypedefType for 'bar', whose canonical type | ||||||
1480 | /// is also 'int*'. | ||||||
1481 | /// | ||||||
1482 | /// Non-canonical types are useful for emitting diagnostics, without losing | ||||||
1483 | /// information about typedefs being used. Canonical types are useful for type | ||||||
1484 | /// comparisons (they allow by-pointer equality tests) and useful for reasoning | ||||||
1485 | /// about whether something has a particular form (e.g. is a function type), | ||||||
1486 | /// because they implicitly, recursively, strip all typedefs out of a type. | ||||||
1487 | /// | ||||||
1488 | /// Types, once created, are immutable. | ||||||
1489 | /// | ||||||
1490 | class alignas(8) Type : public ExtQualsTypeCommonBase { | ||||||
1491 | public: | ||||||
1492 | enum TypeClass { | ||||||
1493 | #define TYPE(Class, Base) Class, | ||||||
1494 | #define LAST_TYPE(Class) TypeLast = Class | ||||||
1495 | #define ABSTRACT_TYPE(Class, Base) | ||||||
1496 | #include "clang/AST/TypeNodes.inc" | ||||||
1497 | }; | ||||||
1498 | |||||||
1499 | private: | ||||||
1500 | /// Bitfields required by the Type class. | ||||||
1501 | class TypeBitfields { | ||||||
1502 | friend class Type; | ||||||
1503 | template <class T> friend class TypePropertyCache; | ||||||
1504 | |||||||
1505 | /// TypeClass bitfield - Enum that specifies what subclass this belongs to. | ||||||
1506 | unsigned TC : 8; | ||||||
1507 | |||||||
1508 | /// Store information on the type dependency. | ||||||
1509 | unsigned Dependence : llvm::BitWidth<TypeDependence>; | ||||||
1510 | |||||||
1511 | /// True if the cache (i.e. the bitfields here starting with | ||||||
1512 | /// 'Cache') is valid. | ||||||
1513 | mutable unsigned CacheValid : 1; | ||||||
1514 | |||||||
1515 | /// Linkage of this type. | ||||||
1516 | mutable unsigned CachedLinkage : 3; | ||||||
1517 | |||||||
1518 | /// Whether this type involves and local or unnamed types. | ||||||
1519 | mutable unsigned CachedLocalOrUnnamed : 1; | ||||||
1520 | |||||||
1521 | /// Whether this type comes from an AST file. | ||||||
1522 | mutable unsigned FromAST : 1; | ||||||
1523 | |||||||
1524 | bool isCacheValid() const { | ||||||
1525 | return CacheValid; | ||||||
1526 | } | ||||||
1527 | |||||||
1528 | Linkage getLinkage() const { | ||||||
1529 | assert(isCacheValid() && "getting linkage from invalid cache")(static_cast <bool> (isCacheValid() && "getting linkage from invalid cache" ) ? void (0) : __assert_fail ("isCacheValid() && \"getting linkage from invalid cache\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 1529, __extension__ __PRETTY_FUNCTION__)); | ||||||
1530 | return static_cast<Linkage>(CachedLinkage); | ||||||
1531 | } | ||||||
1532 | |||||||
1533 | bool hasLocalOrUnnamedType() const { | ||||||
1534 | assert(isCacheValid() && "getting linkage from invalid cache")(static_cast <bool> (isCacheValid() && "getting linkage from invalid cache" ) ? void (0) : __assert_fail ("isCacheValid() && \"getting linkage from invalid cache\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 1534, __extension__ __PRETTY_FUNCTION__)); | ||||||
1535 | return CachedLocalOrUnnamed; | ||||||
1536 | } | ||||||
1537 | }; | ||||||
1538 | enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 }; | ||||||
1539 | |||||||
1540 | protected: | ||||||
1541 | // These classes allow subclasses to somewhat cleanly pack bitfields | ||||||
1542 | // into Type. | ||||||
1543 | |||||||
1544 | class ArrayTypeBitfields { | ||||||
1545 | friend class ArrayType; | ||||||
1546 | |||||||
1547 | unsigned : NumTypeBits; | ||||||
1548 | |||||||
1549 | /// CVR qualifiers from declarations like | ||||||
1550 | /// 'int X[static restrict 4]'. For function parameters only. | ||||||
1551 | unsigned IndexTypeQuals : 3; | ||||||
1552 | |||||||
1553 | /// Storage class qualifiers from declarations like | ||||||
1554 | /// 'int X[static restrict 4]'. For function parameters only. | ||||||
1555 | /// Actually an ArrayType::ArraySizeModifier. | ||||||
1556 | unsigned SizeModifier : 3; | ||||||
1557 | }; | ||||||
1558 | |||||||
1559 | class ConstantArrayTypeBitfields { | ||||||
1560 | friend class ConstantArrayType; | ||||||
1561 | |||||||
1562 | unsigned : NumTypeBits + 3 + 3; | ||||||
1563 | |||||||
1564 | /// Whether we have a stored size expression. | ||||||
1565 | unsigned HasStoredSizeExpr : 1; | ||||||
1566 | }; | ||||||
1567 | |||||||
1568 | class BuiltinTypeBitfields { | ||||||
1569 | friend class BuiltinType; | ||||||
1570 | |||||||
1571 | unsigned : NumTypeBits; | ||||||
1572 | |||||||
1573 | /// The kind (BuiltinType::Kind) of builtin type this is. | ||||||
1574 | unsigned Kind : 8; | ||||||
1575 | }; | ||||||
1576 | |||||||
1577 | /// FunctionTypeBitfields store various bits belonging to FunctionProtoType. | ||||||
1578 | /// Only common bits are stored here. Additional uncommon bits are stored | ||||||
1579 | /// in a trailing object after FunctionProtoType. | ||||||
1580 | class FunctionTypeBitfields { | ||||||
1581 | friend class FunctionProtoType; | ||||||
1582 | friend class FunctionType; | ||||||
1583 | |||||||
1584 | unsigned : NumTypeBits; | ||||||
1585 | |||||||
1586 | /// Extra information which affects how the function is called, like | ||||||
1587 | /// regparm and the calling convention. | ||||||
1588 | unsigned ExtInfo : 13; | ||||||
1589 | |||||||
1590 | /// The ref-qualifier associated with a \c FunctionProtoType. | ||||||
1591 | /// | ||||||
1592 | /// This is a value of type \c RefQualifierKind. | ||||||
1593 | unsigned RefQualifier : 2; | ||||||
1594 | |||||||
1595 | /// Used only by FunctionProtoType, put here to pack with the | ||||||
1596 | /// other bitfields. | ||||||
1597 | /// The qualifiers are part of FunctionProtoType because... | ||||||
1598 | /// | ||||||
1599 | /// C++ 8.3.5p4: The return type, the parameter type list and the | ||||||
1600 | /// cv-qualifier-seq, [...], are part of the function type. | ||||||
1601 | unsigned FastTypeQuals : Qualifiers::FastWidth; | ||||||
1602 | /// Whether this function has extended Qualifiers. | ||||||
1603 | unsigned HasExtQuals : 1; | ||||||
1604 | |||||||
1605 | /// The number of parameters this function has, not counting '...'. | ||||||
1606 | /// According to [implimits] 8 bits should be enough here but this is | ||||||
1607 | /// somewhat easy to exceed with metaprogramming and so we would like to | ||||||
1608 | /// keep NumParams as wide as reasonably possible. | ||||||
1609 | unsigned NumParams : 16; | ||||||
1610 | |||||||
1611 | /// The type of exception specification this function has. | ||||||
1612 | unsigned ExceptionSpecType : 4; | ||||||
1613 | |||||||
1614 | /// Whether this function has extended parameter information. | ||||||
1615 | unsigned HasExtParameterInfos : 1; | ||||||
1616 | |||||||
1617 | /// Whether the function is variadic. | ||||||
1618 | unsigned Variadic : 1; | ||||||
1619 | |||||||
1620 | /// Whether this function has a trailing return type. | ||||||
1621 | unsigned HasTrailingReturn : 1; | ||||||
1622 | }; | ||||||
1623 | |||||||
1624 | class ObjCObjectTypeBitfields { | ||||||
1625 | friend class ObjCObjectType; | ||||||
1626 | |||||||
1627 | unsigned : NumTypeBits; | ||||||
1628 | |||||||
1629 | /// The number of type arguments stored directly on this object type. | ||||||
1630 | unsigned NumTypeArgs : 7; | ||||||
1631 | |||||||
1632 | /// The number of protocols stored directly on this object type. | ||||||
1633 | unsigned NumProtocols : 6; | ||||||
1634 | |||||||
1635 | /// Whether this is a "kindof" type. | ||||||
1636 | unsigned IsKindOf : 1; | ||||||
1637 | }; | ||||||
1638 | |||||||
1639 | class ReferenceTypeBitfields { | ||||||
1640 | friend class ReferenceType; | ||||||
1641 | |||||||
1642 | unsigned : NumTypeBits; | ||||||
1643 | |||||||
1644 | /// True if the type was originally spelled with an lvalue sigil. | ||||||
1645 | /// This is never true of rvalue references but can also be false | ||||||
1646 | /// on lvalue references because of C++0x [dcl.typedef]p9, | ||||||
1647 | /// as follows: | ||||||
1648 | /// | ||||||
1649 | /// typedef int &ref; // lvalue, spelled lvalue | ||||||
1650 | /// typedef int &&rvref; // rvalue | ||||||
1651 | /// ref &a; // lvalue, inner ref, spelled lvalue | ||||||
1652 | /// ref &&a; // lvalue, inner ref | ||||||
1653 | /// rvref &a; // lvalue, inner ref, spelled lvalue | ||||||
1654 | /// rvref &&a; // rvalue, inner ref | ||||||
1655 | unsigned SpelledAsLValue : 1; | ||||||
1656 | |||||||
1657 | /// True if the inner type is a reference type. This only happens | ||||||
1658 | /// in non-canonical forms. | ||||||
1659 | unsigned InnerRef : 1; | ||||||
1660 | }; | ||||||
1661 | |||||||
1662 | class TypeWithKeywordBitfields { | ||||||
1663 | friend class TypeWithKeyword; | ||||||
1664 | |||||||
1665 | unsigned : NumTypeBits; | ||||||
1666 | |||||||
1667 | /// An ElaboratedTypeKeyword. 8 bits for efficient access. | ||||||
1668 | unsigned Keyword : 8; | ||||||
1669 | }; | ||||||
1670 | |||||||
1671 | enum { NumTypeWithKeywordBits = 8 }; | ||||||
1672 | |||||||
1673 | class ElaboratedTypeBitfields { | ||||||
1674 | friend class ElaboratedType; | ||||||
1675 | |||||||
1676 | unsigned : NumTypeBits; | ||||||
1677 | unsigned : NumTypeWithKeywordBits; | ||||||
1678 | |||||||
1679 | /// Whether the ElaboratedType has a trailing OwnedTagDecl. | ||||||
1680 | unsigned HasOwnedTagDecl : 1; | ||||||
1681 | }; | ||||||
1682 | |||||||
1683 | class VectorTypeBitfields { | ||||||
1684 | friend class VectorType; | ||||||
1685 | friend class DependentVectorType; | ||||||
1686 | |||||||
1687 | unsigned : NumTypeBits; | ||||||
1688 | |||||||
1689 | /// The kind of vector, either a generic vector type or some | ||||||
1690 | /// target-specific vector type such as for AltiVec or Neon. | ||||||
1691 | unsigned VecKind : 3; | ||||||
1692 | /// The number of elements in the vector. | ||||||
1693 | uint32_t NumElements; | ||||||
1694 | }; | ||||||
1695 | |||||||
1696 | class AttributedTypeBitfields { | ||||||
1697 | friend class AttributedType; | ||||||
1698 | |||||||
1699 | unsigned : NumTypeBits; | ||||||
1700 | |||||||
1701 | /// An AttributedType::Kind | ||||||
1702 | unsigned AttrKind : 32 - NumTypeBits; | ||||||
1703 | }; | ||||||
1704 | |||||||
1705 | class AutoTypeBitfields { | ||||||
1706 | friend class AutoType; | ||||||
1707 | |||||||
1708 | unsigned : NumTypeBits; | ||||||
1709 | |||||||
1710 | /// Was this placeholder type spelled as 'auto', 'decltype(auto)', | ||||||
1711 | /// or '__auto_type'? AutoTypeKeyword value. | ||||||
1712 | unsigned Keyword : 2; | ||||||
1713 | |||||||
1714 | /// The number of template arguments in the type-constraints, which is | ||||||
1715 | /// expected to be able to hold at least 1024 according to [implimits]. | ||||||
1716 | /// However as this limit is somewhat easy to hit with template | ||||||
1717 | /// metaprogramming we'd prefer to keep it as large as possible. | ||||||
1718 | /// At the moment it has been left as a non-bitfield since this type | ||||||
1719 | /// safely fits in 64 bits as an unsigned, so there is no reason to | ||||||
1720 | /// introduce the performance impact of a bitfield. | ||||||
1721 | unsigned NumArgs; | ||||||
1722 | }; | ||||||
1723 | |||||||
1724 | class SubstTemplateTypeParmPackTypeBitfields { | ||||||
1725 | friend class SubstTemplateTypeParmPackType; | ||||||
1726 | |||||||
1727 | unsigned : NumTypeBits; | ||||||
1728 | |||||||
1729 | /// The number of template arguments in \c Arguments, which is | ||||||
1730 | /// expected to be able to hold at least 1024 according to [implimits]. | ||||||
1731 | /// However as this limit is somewhat easy to hit with template | ||||||
1732 | /// metaprogramming we'd prefer to keep it as large as possible. | ||||||
1733 | /// At the moment it has been left as a non-bitfield since this type | ||||||
1734 | /// safely fits in 64 bits as an unsigned, so there is no reason to | ||||||
1735 | /// introduce the performance impact of a bitfield. | ||||||
1736 | unsigned NumArgs; | ||||||
1737 | }; | ||||||
1738 | |||||||
1739 | class TemplateSpecializationTypeBitfields { | ||||||
1740 | friend class TemplateSpecializationType; | ||||||
1741 | |||||||
1742 | unsigned : NumTypeBits; | ||||||
1743 | |||||||
1744 | /// Whether this template specialization type is a substituted type alias. | ||||||
1745 | unsigned TypeAlias : 1; | ||||||
1746 | |||||||
1747 | /// The number of template arguments named in this class template | ||||||
1748 | /// specialization, which is expected to be able to hold at least 1024 | ||||||
1749 | /// according to [implimits]. However, as this limit is somewhat easy to | ||||||
1750 | /// hit with template metaprogramming we'd prefer to keep it as large | ||||||
1751 | /// as possible. At the moment it has been left as a non-bitfield since | ||||||
1752 | /// this type safely fits in 64 bits as an unsigned, so there is no reason | ||||||
1753 | /// to introduce the performance impact of a bitfield. | ||||||
1754 | unsigned NumArgs; | ||||||
1755 | }; | ||||||
1756 | |||||||
1757 | class DependentTemplateSpecializationTypeBitfields { | ||||||
1758 | friend class DependentTemplateSpecializationType; | ||||||
1759 | |||||||
1760 | unsigned : NumTypeBits; | ||||||
1761 | unsigned : NumTypeWithKeywordBits; | ||||||
1762 | |||||||
1763 | /// The number of template arguments named in this class template | ||||||
1764 | /// specialization, which is expected to be able to hold at least 1024 | ||||||
1765 | /// according to [implimits]. However, as this limit is somewhat easy to | ||||||
1766 | /// hit with template metaprogramming we'd prefer to keep it as large | ||||||
1767 | /// as possible. At the moment it has been left as a non-bitfield since | ||||||
1768 | /// this type safely fits in 64 bits as an unsigned, so there is no reason | ||||||
1769 | /// to introduce the performance impact of a bitfield. | ||||||
1770 | unsigned NumArgs; | ||||||
1771 | }; | ||||||
1772 | |||||||
1773 | class PackExpansionTypeBitfields { | ||||||
1774 | friend class PackExpansionType; | ||||||
1775 | |||||||
1776 | unsigned : NumTypeBits; | ||||||
1777 | |||||||
1778 | /// The number of expansions that this pack expansion will | ||||||
1779 | /// generate when substituted (+1), which is expected to be able to | ||||||
1780 | /// hold at least 1024 according to [implimits]. However, as this limit | ||||||
1781 | /// is somewhat easy to hit with template metaprogramming we'd prefer to | ||||||
1782 | /// keep it as large as possible. At the moment it has been left as a | ||||||
1783 | /// non-bitfield since this type safely fits in 64 bits as an unsigned, so | ||||||
1784 | /// there is no reason to introduce the performance impact of a bitfield. | ||||||
1785 | /// | ||||||
1786 | /// This field will only have a non-zero value when some of the parameter | ||||||
1787 | /// packs that occur within the pattern have been substituted but others | ||||||
1788 | /// have not. | ||||||
1789 | unsigned NumExpansions; | ||||||
1790 | }; | ||||||
1791 | |||||||
1792 | union { | ||||||
1793 | TypeBitfields TypeBits; | ||||||
1794 | ArrayTypeBitfields ArrayTypeBits; | ||||||
1795 | ConstantArrayTypeBitfields ConstantArrayTypeBits; | ||||||
1796 | AttributedTypeBitfields AttributedTypeBits; | ||||||
1797 | AutoTypeBitfields AutoTypeBits; | ||||||
1798 | BuiltinTypeBitfields BuiltinTypeBits; | ||||||
1799 | FunctionTypeBitfields FunctionTypeBits; | ||||||
1800 | ObjCObjectTypeBitfields ObjCObjectTypeBits; | ||||||
1801 | ReferenceTypeBitfields ReferenceTypeBits; | ||||||
1802 | TypeWithKeywordBitfields TypeWithKeywordBits; | ||||||
1803 | ElaboratedTypeBitfields ElaboratedTypeBits; | ||||||
1804 | VectorTypeBitfields VectorTypeBits; | ||||||
1805 | SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; | ||||||
1806 | TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; | ||||||
1807 | DependentTemplateSpecializationTypeBitfields | ||||||
1808 | DependentTemplateSpecializationTypeBits; | ||||||
1809 | PackExpansionTypeBitfields PackExpansionTypeBits; | ||||||
1810 | }; | ||||||
1811 | |||||||
1812 | private: | ||||||
1813 | template <class T> friend class TypePropertyCache; | ||||||
1814 | |||||||
1815 | /// Set whether this type comes from an AST file. | ||||||
1816 | void setFromAST(bool V = true) const { | ||||||
1817 | TypeBits.FromAST = V; | ||||||
1818 | } | ||||||
1819 | |||||||
1820 | protected: | ||||||
1821 | friend class ASTContext; | ||||||
1822 | |||||||
1823 | Type(TypeClass tc, QualType canon, TypeDependence Dependence) | ||||||
1824 | : ExtQualsTypeCommonBase(this, | ||||||
1825 | canon.isNull() ? QualType(this_(), 0) : canon) { | ||||||
1826 | static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase), | ||||||
1827 | "changing bitfields changed sizeof(Type)!"); | ||||||
1828 | static_assert(alignof(decltype(*this)) % sizeof(void *) == 0, | ||||||
1829 | "Insufficient alignment!"); | ||||||
1830 | TypeBits.TC = tc; | ||||||
1831 | TypeBits.Dependence = static_cast<unsigned>(Dependence); | ||||||
1832 | TypeBits.CacheValid = false; | ||||||
1833 | TypeBits.CachedLocalOrUnnamed = false; | ||||||
1834 | TypeBits.CachedLinkage = NoLinkage; | ||||||
1835 | TypeBits.FromAST = false; | ||||||
1836 | } | ||||||
1837 | |||||||
1838 | // silence VC++ warning C4355: 'this' : used in base member initializer list | ||||||
1839 | Type *this_() { return this; } | ||||||
1840 | |||||||
1841 | void setDependence(TypeDependence D) { | ||||||
1842 | TypeBits.Dependence = static_cast<unsigned>(D); | ||||||
1843 | } | ||||||
1844 | |||||||
1845 | void addDependence(TypeDependence D) { setDependence(getDependence() | D); } | ||||||
1846 | |||||||
1847 | public: | ||||||
1848 | friend class ASTReader; | ||||||
1849 | friend class ASTWriter; | ||||||
1850 | template <class T> friend class serialization::AbstractTypeReader; | ||||||
1851 | template <class T> friend class serialization::AbstractTypeWriter; | ||||||
1852 | |||||||
1853 | Type(const Type &) = delete; | ||||||
1854 | Type(Type &&) = delete; | ||||||
1855 | Type &operator=(const Type &) = delete; | ||||||
1856 | Type &operator=(Type &&) = delete; | ||||||
1857 | |||||||
1858 | TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } | ||||||
1859 | |||||||
1860 | /// Whether this type comes from an AST file. | ||||||
1861 | bool isFromAST() const { return TypeBits.FromAST; } | ||||||
1862 | |||||||
1863 | /// Whether this type is or contains an unexpanded parameter | ||||||
1864 | /// pack, used to support C++0x variadic templates. | ||||||
1865 | /// | ||||||
1866 | /// A type that contains a parameter pack shall be expanded by the | ||||||
1867 | /// ellipsis operator at some point. For example, the typedef in the | ||||||
1868 | /// following example contains an unexpanded parameter pack 'T': | ||||||
1869 | /// | ||||||
1870 | /// \code | ||||||
1871 | /// template<typename ...T> | ||||||
1872 | /// struct X { | ||||||
1873 | /// typedef T* pointer_types; // ill-formed; T is a parameter pack. | ||||||
1874 | /// }; | ||||||
1875 | /// \endcode | ||||||
1876 | /// | ||||||
1877 | /// Note that this routine does not specify which | ||||||
1878 | bool containsUnexpandedParameterPack() const { | ||||||
1879 | return getDependence() & TypeDependence::UnexpandedPack; | ||||||
1880 | } | ||||||
1881 | |||||||
1882 | /// Determines if this type would be canonical if it had no further | ||||||
1883 | /// qualification. | ||||||
1884 | bool isCanonicalUnqualified() const { | ||||||
1885 | return CanonicalType == QualType(this, 0); | ||||||
1886 | } | ||||||
1887 | |||||||
1888 | /// Pull a single level of sugar off of this locally-unqualified type. | ||||||
1889 | /// Users should generally prefer SplitQualType::getSingleStepDesugaredType() | ||||||
1890 | /// or QualType::getSingleStepDesugaredType(const ASTContext&). | ||||||
1891 | QualType getLocallyUnqualifiedSingleStepDesugaredType() const; | ||||||
1892 | |||||||
1893 | /// As an extension, we classify types as one of "sized" or "sizeless"; | ||||||
1894 | /// every type is one or the other. Standard types are all sized; | ||||||
1895 | /// sizeless types are purely an extension. | ||||||
1896 | /// | ||||||
1897 | /// Sizeless types contain data with no specified size, alignment, | ||||||
1898 | /// or layout. | ||||||
1899 | bool isSizelessType() const; | ||||||
1900 | bool isSizelessBuiltinType() const; | ||||||
1901 | |||||||
1902 | /// Determines if this is a sizeless type supported by the | ||||||
1903 | /// 'arm_sve_vector_bits' type attribute, which can be applied to a single | ||||||
1904 | /// SVE vector or predicate, excluding tuple types such as svint32x4_t. | ||||||
1905 | bool isVLSTBuiltinType() const; | ||||||
1906 | |||||||
1907 | /// Returns the representative type for the element of an SVE builtin type. | ||||||
1908 | /// This is used to represent fixed-length SVE vectors created with the | ||||||
1909 | /// 'arm_sve_vector_bits' type attribute as VectorType. | ||||||
1910 | QualType getSveEltType(const ASTContext &Ctx) const; | ||||||
1911 | |||||||
1912 | /// Types are partitioned into 3 broad categories (C99 6.2.5p1): | ||||||
1913 | /// object types, function types, and incomplete types. | ||||||
1914 | |||||||
1915 | /// Return true if this is an incomplete type. | ||||||
1916 | /// A type that can describe objects, but which lacks information needed to | ||||||
1917 | /// determine its size (e.g. void, or a fwd declared struct). Clients of this | ||||||
1918 | /// routine will need to determine if the size is actually required. | ||||||
1919 | /// | ||||||
1920 | /// Def If non-null, and the type refers to some kind of declaration | ||||||
1921 | /// that can be completed (such as a C struct, C++ class, or Objective-C | ||||||
1922 | /// class), will be set to the declaration. | ||||||
1923 | bool isIncompleteType(NamedDecl **Def = nullptr) const; | ||||||
1924 | |||||||
1925 | /// Return true if this is an incomplete or object | ||||||
1926 | /// type, in other words, not a function type. | ||||||
1927 | bool isIncompleteOrObjectType() const { | ||||||
1928 | return !isFunctionType(); | ||||||
1929 | } | ||||||
1930 | |||||||
1931 | /// Determine whether this type is an object type. | ||||||
1932 | bool isObjectType() const { | ||||||
1933 | // C++ [basic.types]p8: | ||||||
1934 | // An object type is a (possibly cv-qualified) type that is not a | ||||||
1935 | // function type, not a reference type, and not a void type. | ||||||
1936 | return !isReferenceType() && !isFunctionType() && !isVoidType(); | ||||||
1937 | } | ||||||
1938 | |||||||
1939 | /// Return true if this is a literal type | ||||||
1940 | /// (C++11 [basic.types]p10) | ||||||
1941 | bool isLiteralType(const ASTContext &Ctx) const; | ||||||
1942 | |||||||
1943 | /// Determine if this type is a structural type, per C++20 [temp.param]p7. | ||||||
1944 | bool isStructuralType() const; | ||||||
1945 | |||||||
1946 | /// Test if this type is a standard-layout type. | ||||||
1947 | /// (C++0x [basic.type]p9) | ||||||
1948 | bool isStandardLayoutType() const; | ||||||
1949 | |||||||
1950 | /// Helper methods to distinguish type categories. All type predicates | ||||||
1951 | /// operate on the canonical type, ignoring typedefs and qualifiers. | ||||||
1952 | |||||||
1953 | /// Returns true if the type is a builtin type. | ||||||
1954 | bool isBuiltinType() const; | ||||||
1955 | |||||||
1956 | /// Test for a particular builtin type. | ||||||
1957 | bool isSpecificBuiltinType(unsigned K) const; | ||||||
1958 | |||||||
1959 | /// Test for a type which does not represent an actual type-system type but | ||||||
1960 | /// is instead used as a placeholder for various convenient purposes within | ||||||
1961 | /// Clang. All such types are BuiltinTypes. | ||||||
1962 | bool isPlaceholderType() const; | ||||||
1963 | const BuiltinType *getAsPlaceholderType() const; | ||||||
1964 | |||||||
1965 | /// Test for a specific placeholder type. | ||||||
1966 | bool isSpecificPlaceholderType(unsigned K) const; | ||||||
1967 | |||||||
1968 | /// Test for a placeholder type other than Overload; see | ||||||
1969 | /// BuiltinType::isNonOverloadPlaceholderType. | ||||||
1970 | bool isNonOverloadPlaceholderType() const; | ||||||
1971 | |||||||
1972 | /// isIntegerType() does *not* include complex integers (a GCC extension). | ||||||
1973 | /// isComplexIntegerType() can be used to test for complex integers. | ||||||
1974 | bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) | ||||||
1975 | bool isEnumeralType() const; | ||||||
1976 | |||||||
1977 | /// Determine whether this type is a scoped enumeration type. | ||||||
1978 | bool isScopedEnumeralType() const; | ||||||
1979 | bool isBooleanType() const; | ||||||
1980 | bool isCharType() const; | ||||||
1981 | bool isWideCharType() const; | ||||||
1982 | bool isChar8Type() const; | ||||||
1983 | bool isChar16Type() const; | ||||||
1984 | bool isChar32Type() const; | ||||||
1985 | bool isAnyCharacterType() const; | ||||||
1986 | bool isIntegralType(const ASTContext &Ctx) const; | ||||||
1987 | |||||||
1988 | /// Determine whether this type is an integral or enumeration type. | ||||||
1989 | bool isIntegralOrEnumerationType() const; | ||||||
1990 | |||||||
1991 | /// Determine whether this type is an integral or unscoped enumeration type. | ||||||
1992 | bool isIntegralOrUnscopedEnumerationType() const; | ||||||
1993 | bool isUnscopedEnumerationType() const; | ||||||
1994 | |||||||
1995 | /// Floating point categories. | ||||||
1996 | bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) | ||||||
1997 | /// isComplexType() does *not* include complex integers (a GCC extension). | ||||||
1998 | /// isComplexIntegerType() can be used to test for complex integers. | ||||||
1999 | bool isComplexType() const; // C99 6.2.5p11 (complex) | ||||||
2000 | bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. | ||||||
2001 | bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) | ||||||
2002 | bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) | ||||||
2003 | bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 | ||||||
2004 | bool isBFloat16Type() const; | ||||||
2005 | bool isFloat128Type() const; | ||||||
2006 | bool isRealType() const; // C99 6.2.5p17 (real floating + integer) | ||||||
2007 | bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) | ||||||
2008 | bool isVoidType() const; // C99 6.2.5p19 | ||||||
2009 | bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) | ||||||
2010 | bool isAggregateType() const; | ||||||
2011 | bool isFundamentalType() const; | ||||||
2012 | bool isCompoundType() const; | ||||||
2013 | |||||||
2014 | // Type Predicates: Check to see if this type is structurally the specified | ||||||
2015 | // type, ignoring typedefs and qualifiers. | ||||||
2016 | bool isFunctionType() const; | ||||||
2017 | bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); } | ||||||
2018 | bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } | ||||||
2019 | bool isPointerType() const; | ||||||
2020 | bool isAnyPointerType() const; // Any C pointer or ObjC object pointer | ||||||
2021 | bool isBlockPointerType() const; | ||||||
2022 | bool isVoidPointerType() const; | ||||||
2023 | bool isReferenceType() const; | ||||||
2024 | bool isLValueReferenceType() const; | ||||||
2025 | bool isRValueReferenceType() const; | ||||||
2026 | bool isObjectPointerType() const; | ||||||
2027 | bool isFunctionPointerType() const; | ||||||
2028 | bool isFunctionReferenceType() const; | ||||||
2029 | bool isMemberPointerType() const; | ||||||
2030 | bool isMemberFunctionPointerType() const; | ||||||
2031 | bool isMemberDataPointerType() const; | ||||||
2032 | bool isArrayType() const; | ||||||
2033 | bool isConstantArrayType() const; | ||||||
2034 | bool isIncompleteArrayType() const; | ||||||
2035 | bool isVariableArrayType() const; | ||||||
2036 | bool isDependentSizedArrayType() const; | ||||||
2037 | bool isRecordType() const; | ||||||
2038 | bool isClassType() const; | ||||||
2039 | bool isStructureType() const; | ||||||
2040 | bool isObjCBoxableRecordType() const; | ||||||
2041 | bool isInterfaceType() const; | ||||||
2042 | bool isStructureOrClassType() const; | ||||||
2043 | bool isUnionType() const; | ||||||
2044 | bool isComplexIntegerType() const; // GCC _Complex integer type. | ||||||
2045 | bool isVectorType() const; // GCC vector type. | ||||||
2046 | bool isExtVectorType() const; // Extended vector type. | ||||||
2047 | bool isMatrixType() const; // Matrix type. | ||||||
2048 | bool isConstantMatrixType() const; // Constant matrix type. | ||||||
2049 | bool isDependentAddressSpaceType() const; // value-dependent address space qualifier | ||||||
2050 | bool isObjCObjectPointerType() const; // pointer to ObjC object | ||||||
2051 | bool isObjCRetainableType() const; // ObjC object or block pointer | ||||||
2052 | bool isObjCLifetimeType() const; // (array of)* retainable type | ||||||
2053 | bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type | ||||||
2054 | bool isObjCNSObjectType() const; // __attribute__((NSObject)) | ||||||
2055 | bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class)) | ||||||
2056 | // FIXME: change this to 'raw' interface type, so we can used 'interface' type | ||||||
2057 | // for the common case. | ||||||
2058 | bool isObjCObjectType() const; // NSString or typeof(*(id)0) | ||||||
2059 | bool isObjCQualifiedInterfaceType() const; // NSString<foo> | ||||||
2060 | bool isObjCQualifiedIdType() const; // id<foo> | ||||||
2061 | bool isObjCQualifiedClassType() const; // Class<foo> | ||||||
2062 | bool isObjCObjectOrInterfaceType() const; | ||||||
2063 | bool isObjCIdType() const; // id | ||||||
2064 | bool isDecltypeType() const; | ||||||
2065 | /// Was this type written with the special inert-in-ARC __unsafe_unretained | ||||||
2066 | /// qualifier? | ||||||
2067 | /// | ||||||
2068 | /// This approximates the answer to the following question: if this | ||||||
2069 | /// translation unit were compiled in ARC, would this type be qualified | ||||||
2070 | /// with __unsafe_unretained? | ||||||
2071 | bool isObjCInertUnsafeUnretainedType() const { | ||||||
2072 | return hasAttr(attr::ObjCInertUnsafeUnretained); | ||||||
2073 | } | ||||||
2074 | |||||||
2075 | /// Whether the type is Objective-C 'id' or a __kindof type of an | ||||||
2076 | /// object type, e.g., __kindof NSView * or __kindof id | ||||||
2077 | /// <NSCopying>. | ||||||
2078 | /// | ||||||
2079 | /// \param bound Will be set to the bound on non-id subtype types, | ||||||
2080 | /// which will be (possibly specialized) Objective-C class type, or | ||||||
2081 | /// null for 'id. | ||||||
2082 | bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, | ||||||
2083 | const ObjCObjectType *&bound) const; | ||||||
2084 | |||||||
2085 | bool isObjCClassType() const; // Class | ||||||
2086 | |||||||
2087 | /// Whether the type is Objective-C 'Class' or a __kindof type of an | ||||||
2088 | /// Class type, e.g., __kindof Class <NSCopying>. | ||||||
2089 | /// | ||||||
2090 | /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound | ||||||
2091 | /// here because Objective-C's type system cannot express "a class | ||||||
2092 | /// object for a subclass of NSFoo". | ||||||
2093 | bool isObjCClassOrClassKindOfType() const; | ||||||
2094 | |||||||
2095 | bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const; | ||||||
2096 | bool isObjCSelType() const; // Class | ||||||
2097 | bool isObjCBuiltinType() const; // 'id' or 'Class' | ||||||
2098 | bool isObjCARCBridgableType() const; | ||||||
2099 | bool isCARCBridgableType() const; | ||||||
2100 | bool isTemplateTypeParmType() const; // C++ template type parameter | ||||||
2101 | bool isNullPtrType() const; // C++11 std::nullptr_t | ||||||
2102 | bool isNothrowT() const; // C++ std::nothrow_t | ||||||
2103 | bool isAlignValT() const; // C++17 std::align_val_t | ||||||
2104 | bool isStdByteType() const; // C++17 std::byte | ||||||
2105 | bool isAtomicType() const; // C11 _Atomic() | ||||||
2106 | bool isUndeducedAutoType() const; // C++11 auto or | ||||||
2107 | // C++14 decltype(auto) | ||||||
2108 | bool isTypedefNameType() const; // typedef or alias template | ||||||
2109 | |||||||
2110 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | ||||||
2111 | bool is##Id##Type() const; | ||||||
2112 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||
2113 | |||||||
2114 | bool isImageType() const; // Any OpenCL image type | ||||||
2115 | |||||||
2116 | bool isSamplerT() const; // OpenCL sampler_t | ||||||
2117 | bool isEventT() const; // OpenCL event_t | ||||||
2118 | bool isClkEventT() const; // OpenCL clk_event_t | ||||||
2119 | bool isQueueT() const; // OpenCL queue_t | ||||||
2120 | bool isReserveIDT() const; // OpenCL reserve_id_t | ||||||
2121 | |||||||
2122 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ | ||||||
2123 | bool is##Id##Type() const; | ||||||
2124 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
2125 | // Type defined in cl_intel_device_side_avc_motion_estimation OpenCL extension | ||||||
2126 | bool isOCLIntelSubgroupAVCType() const; | ||||||
2127 | bool isOCLExtOpaqueType() const; // Any OpenCL extension type | ||||||
2128 | |||||||
2129 | bool isPipeType() const; // OpenCL pipe type | ||||||
2130 | bool isExtIntType() const; // Extended Int Type | ||||||
2131 | bool isOpenCLSpecificType() const; // Any OpenCL specific type | ||||||
2132 | |||||||
2133 | /// Determines if this type, which must satisfy | ||||||
2134 | /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather | ||||||
2135 | /// than implicitly __strong. | ||||||
2136 | bool isObjCARCImplicitlyUnretainedType() const; | ||||||
2137 | |||||||
2138 | /// Check if the type is the CUDA device builtin surface type. | ||||||
2139 | bool isCUDADeviceBuiltinSurfaceType() const; | ||||||
2140 | /// Check if the type is the CUDA device builtin texture type. | ||||||
2141 | bool isCUDADeviceBuiltinTextureType() const; | ||||||
2142 | |||||||
2143 | /// Return the implicit lifetime for this type, which must not be dependent. | ||||||
2144 | Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; | ||||||
2145 | |||||||
2146 | enum ScalarTypeKind { | ||||||
2147 | STK_CPointer, | ||||||
2148 | STK_BlockPointer, | ||||||
2149 | STK_ObjCObjectPointer, | ||||||
2150 | STK_MemberPointer, | ||||||
2151 | STK_Bool, | ||||||
2152 | STK_Integral, | ||||||
2153 | STK_Floating, | ||||||
2154 | STK_IntegralComplex, | ||||||
2155 | STK_FloatingComplex, | ||||||
2156 | STK_FixedPoint | ||||||
2157 | }; | ||||||
2158 | |||||||
2159 | /// Given that this is a scalar type, classify it. | ||||||
2160 | ScalarTypeKind getScalarTypeKind() const; | ||||||
2161 | |||||||
2162 | TypeDependence getDependence() const { | ||||||
2163 | return static_cast<TypeDependence>(TypeBits.Dependence); | ||||||
2164 | } | ||||||
2165 | |||||||
2166 | /// Whether this type is an error type. | ||||||
2167 | bool containsErrors() const { | ||||||
2168 | return getDependence() & TypeDependence::Error; | ||||||
2169 | } | ||||||
2170 | |||||||
2171 | /// Whether this type is a dependent type, meaning that its definition | ||||||
2172 | /// somehow depends on a template parameter (C++ [temp.dep.type]). | ||||||
2173 | bool isDependentType() const { | ||||||
2174 | return getDependence() & TypeDependence::Dependent; | ||||||
2175 | } | ||||||
2176 | |||||||
2177 | /// Determine whether this type is an instantiation-dependent type, | ||||||
2178 | /// meaning that the type involves a template parameter (even if the | ||||||
2179 | /// definition does not actually depend on the type substituted for that | ||||||
2180 | /// template parameter). | ||||||
2181 | bool isInstantiationDependentType() const { | ||||||
2182 | return getDependence() & TypeDependence::Instantiation; | ||||||
2183 | } | ||||||
2184 | |||||||
2185 | /// Determine whether this type is an undeduced type, meaning that | ||||||
2186 | /// it somehow involves a C++11 'auto' type or similar which has not yet been | ||||||
2187 | /// deduced. | ||||||
2188 | bool isUndeducedType() const; | ||||||
2189 | |||||||
2190 | /// Whether this type is a variably-modified type (C99 6.7.5). | ||||||
2191 | bool isVariablyModifiedType() const { | ||||||
2192 | return getDependence() & TypeDependence::VariablyModified; | ||||||
2193 | } | ||||||
2194 | |||||||
2195 | /// Whether this type involves a variable-length array type | ||||||
2196 | /// with a definite size. | ||||||
2197 | bool hasSizedVLAType() const; | ||||||
2198 | |||||||
2199 | /// Whether this type is or contains a local or unnamed type. | ||||||
2200 | bool hasUnnamedOrLocalType() const; | ||||||
2201 | |||||||
2202 | bool isOverloadableType() const; | ||||||
2203 | |||||||
2204 | /// Determine wither this type is a C++ elaborated-type-specifier. | ||||||
2205 | bool isElaboratedTypeSpecifier() const; | ||||||
2206 | |||||||
2207 | bool canDecayToPointerType() const; | ||||||
2208 | |||||||
2209 | /// Whether this type is represented natively as a pointer. This includes | ||||||
2210 | /// pointers, references, block pointers, and Objective-C interface, | ||||||
2211 | /// qualified id, and qualified interface types, as well as nullptr_t. | ||||||
2212 | bool hasPointerRepresentation() const; | ||||||
2213 | |||||||
2214 | /// Whether this type can represent an objective pointer type for the | ||||||
2215 | /// purpose of GC'ability | ||||||
2216 | bool hasObjCPointerRepresentation() const; | ||||||
2217 | |||||||
2218 | /// Determine whether this type has an integer representation | ||||||
2219 | /// of some sort, e.g., it is an integer type or a vector. | ||||||
2220 | bool hasIntegerRepresentation() const; | ||||||
2221 | |||||||
2222 | /// Determine whether this type has an signed integer representation | ||||||
2223 | /// of some sort, e.g., it is an signed integer type or a vector. | ||||||
2224 | bool hasSignedIntegerRepresentation() const; | ||||||
2225 | |||||||
2226 | /// Determine whether this type has an unsigned integer representation | ||||||
2227 | /// of some sort, e.g., it is an unsigned integer type or a vector. | ||||||
2228 | bool hasUnsignedIntegerRepresentation() const; | ||||||
2229 | |||||||
2230 | /// Determine whether this type has a floating-point representation | ||||||
2231 | /// of some sort, e.g., it is a floating-point type or a vector thereof. | ||||||
2232 | bool hasFloatingRepresentation() const; | ||||||
2233 | |||||||
2234 | // Type Checking Functions: Check to see if this type is structurally the | ||||||
2235 | // specified type, ignoring typedefs and qualifiers, and return a pointer to | ||||||
2236 | // the best type we can. | ||||||
2237 | const RecordType *getAsStructureType() const; | ||||||
2238 | /// NOTE: getAs*ArrayType are methods on ASTContext. | ||||||
2239 | const RecordType *getAsUnionType() const; | ||||||
2240 | const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. | ||||||
2241 | const ObjCObjectType *getAsObjCInterfaceType() const; | ||||||
2242 | |||||||
2243 | // The following is a convenience method that returns an ObjCObjectPointerType | ||||||
2244 | // for object declared using an interface. | ||||||
2245 | const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; | ||||||
2246 | const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; | ||||||
2247 | const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; | ||||||
2248 | const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; | ||||||
2249 | |||||||
2250 | /// Retrieves the CXXRecordDecl that this type refers to, either | ||||||
2251 | /// because the type is a RecordType or because it is the injected-class-name | ||||||
2252 | /// type of a class template or class template partial specialization. | ||||||
2253 | CXXRecordDecl *getAsCXXRecordDecl() const; | ||||||
2254 | |||||||
2255 | /// Retrieves the RecordDecl this type refers to. | ||||||
2256 | RecordDecl *getAsRecordDecl() const; | ||||||
2257 | |||||||
2258 | /// Retrieves the TagDecl that this type refers to, either | ||||||
2259 | /// because the type is a TagType or because it is the injected-class-name | ||||||
2260 | /// type of a class template or class template partial specialization. | ||||||
2261 | TagDecl *getAsTagDecl() const; | ||||||
2262 | |||||||
2263 | /// If this is a pointer or reference to a RecordType, return the | ||||||
2264 | /// CXXRecordDecl that the type refers to. | ||||||
2265 | /// | ||||||
2266 | /// If this is not a pointer or reference, or the type being pointed to does | ||||||
2267 | /// not refer to a CXXRecordDecl, returns NULL. | ||||||
2268 | const CXXRecordDecl *getPointeeCXXRecordDecl() const; | ||||||
2269 | |||||||
2270 | /// Get the DeducedType whose type will be deduced for a variable with | ||||||
2271 | /// an initializer of this type. This looks through declarators like pointer | ||||||
2272 | /// types, but not through decltype or typedefs. | ||||||
2273 | DeducedType *getContainedDeducedType() const; | ||||||
2274 | |||||||
2275 | /// Get the AutoType whose type will be deduced for a variable with | ||||||
2276 | /// an initializer of this type. This looks through declarators like pointer | ||||||
2277 | /// types, but not through decltype or typedefs. | ||||||
2278 | AutoType *getContainedAutoType() const { | ||||||
2279 | return dyn_cast_or_null<AutoType>(getContainedDeducedType()); | ||||||
2280 | } | ||||||
2281 | |||||||
2282 | /// Determine whether this type was written with a leading 'auto' | ||||||
2283 | /// corresponding to a trailing return type (possibly for a nested | ||||||
2284 | /// function type within a pointer to function type or similar). | ||||||
2285 | bool hasAutoForTrailingReturnType() const; | ||||||
2286 | |||||||
2287 | /// Member-template getAs<specific type>'. Look through sugar for | ||||||
2288 | /// an instance of \<specific type>. This scheme will eventually | ||||||
2289 | /// replace the specific getAsXXXX methods above. | ||||||
2290 | /// | ||||||
2291 | /// There are some specializations of this member template listed | ||||||
2292 | /// immediately following this class. | ||||||
2293 | template <typename T> const T *getAs() const; | ||||||
2294 | |||||||
2295 | /// Member-template getAsAdjusted<specific type>. Look through specific kinds | ||||||
2296 | /// of sugar (parens, attributes, etc) for an instance of \<specific type>. | ||||||
2297 | /// This is used when you need to walk over sugar nodes that represent some | ||||||
2298 | /// kind of type adjustment from a type that was written as a \<specific type> | ||||||
2299 | /// to another type that is still canonically a \<specific type>. | ||||||
2300 | template <typename T> const T *getAsAdjusted() const; | ||||||
2301 | |||||||
2302 | /// A variant of getAs<> for array types which silently discards | ||||||
2303 | /// qualifiers from the outermost type. | ||||||
2304 | const ArrayType *getAsArrayTypeUnsafe() const; | ||||||
2305 | |||||||
2306 | /// Member-template castAs<specific type>. Look through sugar for | ||||||
2307 | /// the underlying instance of \<specific type>. | ||||||
2308 | /// | ||||||
2309 | /// This method has the same relationship to getAs<T> as cast<T> has | ||||||
2310 | /// to dyn_cast<T>; which is to say, the underlying type *must* | ||||||
2311 | /// have the intended type, and this method will never return null. | ||||||
2312 | template <typename T> const T *castAs() const; | ||||||
2313 | |||||||
2314 | /// A variant of castAs<> for array type which silently discards | ||||||
2315 | /// qualifiers from the outermost type. | ||||||
2316 | const ArrayType *castAsArrayTypeUnsafe() const; | ||||||
2317 | |||||||
2318 | /// Determine whether this type had the specified attribute applied to it | ||||||
2319 | /// (looking through top-level type sugar). | ||||||
2320 | bool hasAttr(attr::Kind AK) const; | ||||||
2321 | |||||||
2322 | /// Get the base element type of this type, potentially discarding type | ||||||
2323 | /// qualifiers. This should never be used when type qualifiers | ||||||
2324 | /// are meaningful. | ||||||
2325 | const Type *getBaseElementTypeUnsafe() const; | ||||||
2326 | |||||||
2327 | /// If this is an array type, return the element type of the array, | ||||||
2328 | /// potentially with type qualifiers missing. | ||||||
2329 | /// This should never be used when type qualifiers are meaningful. | ||||||
2330 | const Type *getArrayElementTypeNoTypeQual() const; | ||||||
2331 | |||||||
2332 | /// If this is a pointer type, return the pointee type. | ||||||
2333 | /// If this is an array type, return the array element type. | ||||||
2334 | /// This should never be used when type qualifiers are meaningful. | ||||||
2335 | const Type *getPointeeOrArrayElementType() const; | ||||||
2336 | |||||||
2337 | /// If this is a pointer, ObjC object pointer, or block | ||||||
2338 | /// pointer, this returns the respective pointee. | ||||||
2339 | QualType getPointeeType() const; | ||||||
2340 | |||||||
2341 | /// Return the specified type with any "sugar" removed from the type, | ||||||
2342 | /// removing any typedefs, typeofs, etc., as well as any qualifiers. | ||||||
2343 | const Type *getUnqualifiedDesugaredType() const; | ||||||
2344 | |||||||
2345 | /// More type predicates useful for type checking/promotion | ||||||
2346 | bool isPromotableIntegerType() const; // C99 6.3.1.1p2 | ||||||
2347 | |||||||
2348 | /// Return true if this is an integer type that is | ||||||
2349 | /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], | ||||||
2350 | /// or an enum decl which has a signed representation. | ||||||
2351 | bool isSignedIntegerType() const; | ||||||
2352 | |||||||
2353 | /// Return true if this is an integer type that is | ||||||
2354 | /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], | ||||||
2355 | /// or an enum decl which has an unsigned representation. | ||||||
2356 | bool isUnsignedIntegerType() const; | ||||||
2357 | |||||||
2358 | /// Determines whether this is an integer type that is signed or an | ||||||
2359 | /// enumeration types whose underlying type is a signed integer type. | ||||||
2360 | bool isSignedIntegerOrEnumerationType() const; | ||||||
2361 | |||||||
2362 | /// Determines whether this is an integer type that is unsigned or an | ||||||
2363 | /// enumeration types whose underlying type is a unsigned integer type. | ||||||
2364 | bool isUnsignedIntegerOrEnumerationType() const; | ||||||
2365 | |||||||
2366 | /// Return true if this is a fixed point type according to | ||||||
2367 | /// ISO/IEC JTC1 SC22 WG14 N1169. | ||||||
2368 | bool isFixedPointType() const; | ||||||
2369 | |||||||
2370 | /// Return true if this is a fixed point or integer type. | ||||||
2371 | bool isFixedPointOrIntegerType() const; | ||||||
2372 | |||||||
2373 | /// Return true if this is a saturated fixed point type according to | ||||||
2374 | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. | ||||||
2375 | bool isSaturatedFixedPointType() const; | ||||||
2376 | |||||||
2377 | /// Return true if this is a saturated fixed point type according to | ||||||
2378 | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. | ||||||
2379 | bool isUnsaturatedFixedPointType() const; | ||||||
2380 | |||||||
2381 | /// Return true if this is a fixed point type that is signed according | ||||||
2382 | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. | ||||||
2383 | bool isSignedFixedPointType() const; | ||||||
2384 | |||||||
2385 | /// Return true if this is a fixed point type that is unsigned according | ||||||
2386 | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. | ||||||
2387 | bool isUnsignedFixedPointType() const; | ||||||
2388 | |||||||
2389 | /// Return true if this is not a variable sized type, | ||||||
2390 | /// according to the rules of C99 6.7.5p3. It is not legal to call this on | ||||||
2391 | /// incomplete types. | ||||||
2392 | bool isConstantSizeType() const; | ||||||
2393 | |||||||
2394 | /// Returns true if this type can be represented by some | ||||||
2395 | /// set of type specifiers. | ||||||
2396 | bool isSpecifierType() const; | ||||||
2397 | |||||||
2398 | /// Determine the linkage of this type. | ||||||
2399 | Linkage getLinkage() const; | ||||||
2400 | |||||||
2401 | /// Determine the visibility of this type. | ||||||
2402 | Visibility getVisibility() const { | ||||||
2403 | return getLinkageAndVisibility().getVisibility(); | ||||||
2404 | } | ||||||
2405 | |||||||
2406 | /// Return true if the visibility was explicitly set is the code. | ||||||
2407 | bool isVisibilityExplicit() const { | ||||||
2408 | return getLinkageAndVisibility().isVisibilityExplicit(); | ||||||
2409 | } | ||||||
2410 | |||||||
2411 | /// Determine the linkage and visibility of this type. | ||||||
2412 | LinkageInfo getLinkageAndVisibility() const; | ||||||
2413 | |||||||
2414 | /// True if the computed linkage is valid. Used for consistency | ||||||
2415 | /// checking. Should always return true. | ||||||
2416 | bool isLinkageValid() const; | ||||||
2417 | |||||||
2418 | /// Determine the nullability of the given type. | ||||||
2419 | /// | ||||||
2420 | /// Note that nullability is only captured as sugar within the type | ||||||
2421 | /// system, not as part of the canonical type, so nullability will | ||||||
2422 | /// be lost by canonicalization and desugaring. | ||||||
2423 | Optional<NullabilityKind> getNullability(const ASTContext &context) const; | ||||||
2424 | |||||||
2425 | /// Determine whether the given type can have a nullability | ||||||
2426 | /// specifier applied to it, i.e., if it is any kind of pointer type. | ||||||
2427 | /// | ||||||
2428 | /// \param ResultIfUnknown The value to return if we don't yet know whether | ||||||
2429 | /// this type can have nullability because it is dependent. | ||||||
2430 | bool canHaveNullability(bool ResultIfUnknown = true) const; | ||||||
2431 | |||||||
2432 | /// Retrieve the set of substitutions required when accessing a member | ||||||
2433 | /// of the Objective-C receiver type that is declared in the given context. | ||||||
2434 | /// | ||||||
2435 | /// \c *this is the type of the object we're operating on, e.g., the | ||||||
2436 | /// receiver for a message send or the base of a property access, and is | ||||||
2437 | /// expected to be of some object or object pointer type. | ||||||
2438 | /// | ||||||
2439 | /// \param dc The declaration context for which we are building up a | ||||||
2440 | /// substitution mapping, which should be an Objective-C class, extension, | ||||||
2441 | /// category, or method within. | ||||||
2442 | /// | ||||||
2443 | /// \returns an array of type arguments that can be substituted for | ||||||
2444 | /// the type parameters of the given declaration context in any type described | ||||||
2445 | /// within that context, or an empty optional to indicate that no | ||||||
2446 | /// substitution is required. | ||||||
2447 | Optional<ArrayRef<QualType>> | ||||||
2448 | getObjCSubstitutions(const DeclContext *dc) const; | ||||||
2449 | |||||||
2450 | /// Determines if this is an ObjC interface type that may accept type | ||||||
2451 | /// parameters. | ||||||
2452 | bool acceptsObjCTypeParams() const; | ||||||
2453 | |||||||
2454 | const char *getTypeClassName() const; | ||||||
2455 | |||||||
2456 | QualType getCanonicalTypeInternal() const { | ||||||
2457 | return CanonicalType; | ||||||
2458 | } | ||||||
2459 | |||||||
2460 | CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h | ||||||
2461 | void dump() const; | ||||||
2462 | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; | ||||||
2463 | }; | ||||||
2464 | |||||||
2465 | /// This will check for a TypedefType by removing any existing sugar | ||||||
2466 | /// until it reaches a TypedefType or a non-sugared type. | ||||||
2467 | template <> const TypedefType *Type::getAs() const; | ||||||
2468 | |||||||
2469 | /// This will check for a TemplateSpecializationType by removing any | ||||||
2470 | /// existing sugar until it reaches a TemplateSpecializationType or a | ||||||
2471 | /// non-sugared type. | ||||||
2472 | template <> const TemplateSpecializationType *Type::getAs() const; | ||||||
2473 | |||||||
2474 | /// This will check for an AttributedType by removing any existing sugar | ||||||
2475 | /// until it reaches an AttributedType or a non-sugared type. | ||||||
2476 | template <> const AttributedType *Type::getAs() const; | ||||||
2477 | |||||||
2478 | // We can do canonical leaf types faster, because we don't have to | ||||||
2479 | // worry about preserving child type decoration. | ||||||
2480 | #define TYPE(Class, Base) | ||||||
2481 | #define LEAF_TYPE(Class) \ | ||||||
2482 | template <> inline const Class##Type *Type::getAs() const { \ | ||||||
2483 | return dyn_cast<Class##Type>(CanonicalType); \ | ||||||
2484 | } \ | ||||||
2485 | template <> inline const Class##Type *Type::castAs() const { \ | ||||||
2486 | return cast<Class##Type>(CanonicalType); \ | ||||||
2487 | } | ||||||
2488 | #include "clang/AST/TypeNodes.inc" | ||||||
2489 | |||||||
2490 | /// This class is used for builtin types like 'int'. Builtin | ||||||
2491 | /// types are always canonical and have a literal name field. | ||||||
2492 | class BuiltinType : public Type { | ||||||
2493 | public: | ||||||
2494 | enum Kind { | ||||||
2495 | // OpenCL image types | ||||||
2496 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id, | ||||||
2497 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||
2498 | // OpenCL extension types | ||||||
2499 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id, | ||||||
2500 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
2501 | // SVE Types | ||||||
2502 | #define SVE_TYPE(Name, Id, SingletonId) Id, | ||||||
2503 | #include "clang/Basic/AArch64SVEACLETypes.def" | ||||||
2504 | // PPC MMA Types | ||||||
2505 | #define PPC_VECTOR_TYPE(Name, Id, Size) Id, | ||||||
2506 | #include "clang/Basic/PPCTypes.def" | ||||||
2507 | // RVV Types | ||||||
2508 | #define RVV_TYPE(Name, Id, SingletonId) Id, | ||||||
2509 | #include "clang/Basic/RISCVVTypes.def" | ||||||
2510 | // All other builtin types | ||||||
2511 | #define BUILTIN_TYPE(Id, SingletonId) Id, | ||||||
2512 | #define LAST_BUILTIN_TYPE(Id) LastKind = Id | ||||||
2513 | #include "clang/AST/BuiltinTypes.def" | ||||||
2514 | }; | ||||||
2515 | |||||||
2516 | private: | ||||||
2517 | friend class ASTContext; // ASTContext creates these. | ||||||
2518 | |||||||
2519 | BuiltinType(Kind K) | ||||||
2520 | : Type(Builtin, QualType(), | ||||||
2521 | K == Dependent ? TypeDependence::DependentInstantiation | ||||||
2522 | : TypeDependence::None) { | ||||||
2523 | BuiltinTypeBits.Kind = K; | ||||||
2524 | } | ||||||
2525 | |||||||
2526 | public: | ||||||
2527 | Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } | ||||||
2528 | StringRef getName(const PrintingPolicy &Policy) const; | ||||||
2529 | |||||||
2530 | const char *getNameAsCString(const PrintingPolicy &Policy) const { | ||||||
2531 | // The StringRef is null-terminated. | ||||||
2532 | StringRef str = getName(Policy); | ||||||
2533 | assert(!str.empty() && str.data()[str.size()] == '\0')(static_cast <bool> (!str.empty() && str.data() [str.size()] == '\0') ? void (0) : __assert_fail ("!str.empty() && str.data()[str.size()] == '\\0'" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 2533, __extension__ __PRETTY_FUNCTION__)); | ||||||
2534 | return str.data(); | ||||||
2535 | } | ||||||
2536 | |||||||
2537 | bool isSugared() const { return false; } | ||||||
2538 | QualType desugar() const { return QualType(this, 0); } | ||||||
2539 | |||||||
2540 | bool isInteger() const { | ||||||
2541 | return getKind() >= Bool && getKind() <= Int128; | ||||||
2542 | } | ||||||
2543 | |||||||
2544 | bool isSignedInteger() const { | ||||||
2545 | return getKind() >= Char_S && getKind() <= Int128; | ||||||
2546 | } | ||||||
2547 | |||||||
2548 | bool isUnsignedInteger() const { | ||||||
2549 | return getKind() >= Bool && getKind() <= UInt128; | ||||||
2550 | } | ||||||
2551 | |||||||
2552 | bool isFloatingPoint() const { | ||||||
2553 | return getKind() >= Half && getKind() <= Float128; | ||||||
2554 | } | ||||||
2555 | |||||||
2556 | /// Determines whether the given kind corresponds to a placeholder type. | ||||||
2557 | static bool isPlaceholderTypeKind(Kind K) { | ||||||
2558 | return K >= Overload; | ||||||
2559 | } | ||||||
2560 | |||||||
2561 | /// Determines whether this type is a placeholder type, i.e. a type | ||||||
2562 | /// which cannot appear in arbitrary positions in a fully-formed | ||||||
2563 | /// expression. | ||||||
2564 | bool isPlaceholderType() const { | ||||||
2565 | return isPlaceholderTypeKind(getKind()); | ||||||
2566 | } | ||||||
2567 | |||||||
2568 | /// Determines whether this type is a placeholder type other than | ||||||
2569 | /// Overload. Most placeholder types require only syntactic | ||||||
2570 | /// information about their context in order to be resolved (e.g. | ||||||
2571 | /// whether it is a call expression), which means they can (and | ||||||
2572 | /// should) be resolved in an earlier "phase" of analysis. | ||||||
2573 | /// Overload expressions sometimes pick up further information | ||||||
2574 | /// from their context, like whether the context expects a | ||||||
2575 | /// specific function-pointer type, and so frequently need | ||||||
2576 | /// special treatment. | ||||||
2577 | bool isNonOverloadPlaceholderType() const { | ||||||
2578 | return getKind() > Overload; | ||||||
2579 | } | ||||||
2580 | |||||||
2581 | static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } | ||||||
2582 | }; | ||||||
2583 | |||||||
2584 | /// Complex values, per C99 6.2.5p11. This supports the C99 complex | ||||||
2585 | /// types (_Complex float etc) as well as the GCC integer complex extensions. | ||||||
2586 | class ComplexType : public Type, public llvm::FoldingSetNode { | ||||||
2587 | friend class ASTContext; // ASTContext creates these. | ||||||
2588 | |||||||
2589 | QualType ElementType; | ||||||
2590 | |||||||
2591 | ComplexType(QualType Element, QualType CanonicalPtr) | ||||||
2592 | : Type(Complex, CanonicalPtr, Element->getDependence()), | ||||||
2593 | ElementType(Element) {} | ||||||
2594 | |||||||
2595 | public: | ||||||
2596 | QualType getElementType() const { return ElementType; } | ||||||
2597 | |||||||
2598 | bool isSugared() const { return false; } | ||||||
2599 | QualType desugar() const { return QualType(this, 0); } | ||||||
2600 | |||||||
2601 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2602 | Profile(ID, getElementType()); | ||||||
2603 | } | ||||||
2604 | |||||||
2605 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { | ||||||
2606 | ID.AddPointer(Element.getAsOpaquePtr()); | ||||||
2607 | } | ||||||
2608 | |||||||
2609 | static bool classof(const Type *T) { return T->getTypeClass() == Complex; } | ||||||
2610 | }; | ||||||
2611 | |||||||
2612 | /// Sugar for parentheses used when specifying types. | ||||||
2613 | class ParenType : public Type, public llvm::FoldingSetNode { | ||||||
2614 | friend class ASTContext; // ASTContext creates these. | ||||||
2615 | |||||||
2616 | QualType Inner; | ||||||
2617 | |||||||
2618 | ParenType(QualType InnerType, QualType CanonType) | ||||||
2619 | : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {} | ||||||
2620 | |||||||
2621 | public: | ||||||
2622 | QualType getInnerType() const { return Inner; } | ||||||
2623 | |||||||
2624 | bool isSugared() const { return true; } | ||||||
2625 | QualType desugar() const { return getInnerType(); } | ||||||
2626 | |||||||
2627 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2628 | Profile(ID, getInnerType()); | ||||||
2629 | } | ||||||
2630 | |||||||
2631 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { | ||||||
2632 | Inner.Profile(ID); | ||||||
2633 | } | ||||||
2634 | |||||||
2635 | static bool classof(const Type *T) { return T->getTypeClass() == Paren; } | ||||||
2636 | }; | ||||||
2637 | |||||||
2638 | /// PointerType - C99 6.7.5.1 - Pointer Declarators. | ||||||
2639 | class PointerType : public Type, public llvm::FoldingSetNode { | ||||||
2640 | friend class ASTContext; // ASTContext creates these. | ||||||
2641 | |||||||
2642 | QualType PointeeType; | ||||||
2643 | |||||||
2644 | PointerType(QualType Pointee, QualType CanonicalPtr) | ||||||
2645 | : Type(Pointer, CanonicalPtr, Pointee->getDependence()), | ||||||
2646 | PointeeType(Pointee) {} | ||||||
2647 | |||||||
2648 | public: | ||||||
2649 | QualType getPointeeType() const { return PointeeType; } | ||||||
2650 | |||||||
2651 | bool isSugared() const { return false; } | ||||||
2652 | QualType desugar() const { return QualType(this, 0); } | ||||||
2653 | |||||||
2654 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2655 | Profile(ID, getPointeeType()); | ||||||
2656 | } | ||||||
2657 | |||||||
2658 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { | ||||||
2659 | ID.AddPointer(Pointee.getAsOpaquePtr()); | ||||||
2660 | } | ||||||
2661 | |||||||
2662 | static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } | ||||||
2663 | }; | ||||||
2664 | |||||||
2665 | /// Represents a type which was implicitly adjusted by the semantic | ||||||
2666 | /// engine for arbitrary reasons. For example, array and function types can | ||||||
2667 | /// decay, and function types can have their calling conventions adjusted. | ||||||
2668 | class AdjustedType : public Type, public llvm::FoldingSetNode { | ||||||
2669 | QualType OriginalTy; | ||||||
2670 | QualType AdjustedTy; | ||||||
2671 | |||||||
2672 | protected: | ||||||
2673 | friend class ASTContext; // ASTContext creates these. | ||||||
2674 | |||||||
2675 | AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, | ||||||
2676 | QualType CanonicalPtr) | ||||||
2677 | : Type(TC, CanonicalPtr, OriginalTy->getDependence()), | ||||||
2678 | OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} | ||||||
2679 | |||||||
2680 | public: | ||||||
2681 | QualType getOriginalType() const { return OriginalTy; } | ||||||
2682 | QualType getAdjustedType() const { return AdjustedTy; } | ||||||
2683 | |||||||
2684 | bool isSugared() const { return true; } | ||||||
2685 | QualType desugar() const { return AdjustedTy; } | ||||||
2686 | |||||||
2687 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2688 | Profile(ID, OriginalTy, AdjustedTy); | ||||||
2689 | } | ||||||
2690 | |||||||
2691 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) { | ||||||
2692 | ID.AddPointer(Orig.getAsOpaquePtr()); | ||||||
2693 | ID.AddPointer(New.getAsOpaquePtr()); | ||||||
2694 | } | ||||||
2695 | |||||||
2696 | static bool classof(const Type *T) { | ||||||
2697 | return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed; | ||||||
2698 | } | ||||||
2699 | }; | ||||||
2700 | |||||||
2701 | /// Represents a pointer type decayed from an array or function type. | ||||||
2702 | class DecayedType : public AdjustedType { | ||||||
2703 | friend class ASTContext; // ASTContext creates these. | ||||||
2704 | |||||||
2705 | inline | ||||||
2706 | DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical); | ||||||
2707 | |||||||
2708 | public: | ||||||
2709 | QualType getDecayedType() const { return getAdjustedType(); } | ||||||
2710 | |||||||
2711 | inline QualType getPointeeType() const; | ||||||
2712 | |||||||
2713 | static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } | ||||||
2714 | }; | ||||||
2715 | |||||||
2716 | /// Pointer to a block type. | ||||||
2717 | /// This type is to represent types syntactically represented as | ||||||
2718 | /// "void (^)(int)", etc. Pointee is required to always be a function type. | ||||||
2719 | class BlockPointerType : public Type, public llvm::FoldingSetNode { | ||||||
2720 | friend class ASTContext; // ASTContext creates these. | ||||||
2721 | |||||||
2722 | // Block is some kind of pointer type | ||||||
2723 | QualType PointeeType; | ||||||
2724 | |||||||
2725 | BlockPointerType(QualType Pointee, QualType CanonicalCls) | ||||||
2726 | : Type(BlockPointer, CanonicalCls, Pointee->getDependence()), | ||||||
2727 | PointeeType(Pointee) {} | ||||||
2728 | |||||||
2729 | public: | ||||||
2730 | // Get the pointee type. Pointee is required to always be a function type. | ||||||
2731 | QualType getPointeeType() const { return PointeeType; } | ||||||
2732 | |||||||
2733 | bool isSugared() const { return false; } | ||||||
2734 | QualType desugar() const { return QualType(this, 0); } | ||||||
2735 | |||||||
2736 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2737 | Profile(ID, getPointeeType()); | ||||||
2738 | } | ||||||
2739 | |||||||
2740 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { | ||||||
2741 | ID.AddPointer(Pointee.getAsOpaquePtr()); | ||||||
2742 | } | ||||||
2743 | |||||||
2744 | static bool classof(const Type *T) { | ||||||
2745 | return T->getTypeClass() == BlockPointer; | ||||||
2746 | } | ||||||
2747 | }; | ||||||
2748 | |||||||
2749 | /// Base for LValueReferenceType and RValueReferenceType | ||||||
2750 | class ReferenceType : public Type, public llvm::FoldingSetNode { | ||||||
2751 | QualType PointeeType; | ||||||
2752 | |||||||
2753 | protected: | ||||||
2754 | ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, | ||||||
2755 | bool SpelledAsLValue) | ||||||
2756 | : Type(tc, CanonicalRef, Referencee->getDependence()), | ||||||
2757 | PointeeType(Referencee) { | ||||||
2758 | ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; | ||||||
2759 | ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); | ||||||
2760 | } | ||||||
2761 | |||||||
2762 | public: | ||||||
2763 | bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; } | ||||||
2764 | bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } | ||||||
2765 | |||||||
2766 | QualType getPointeeTypeAsWritten() const { return PointeeType; } | ||||||
2767 | |||||||
2768 | QualType getPointeeType() const { | ||||||
2769 | // FIXME: this might strip inner qualifiers; okay? | ||||||
2770 | const ReferenceType *T = this; | ||||||
2771 | while (T->isInnerRef()) | ||||||
2772 | T = T->PointeeType->castAs<ReferenceType>(); | ||||||
2773 | return T->PointeeType; | ||||||
2774 | } | ||||||
2775 | |||||||
2776 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2777 | Profile(ID, PointeeType, isSpelledAsLValue()); | ||||||
2778 | } | ||||||
2779 | |||||||
2780 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
2781 | QualType Referencee, | ||||||
2782 | bool SpelledAsLValue) { | ||||||
2783 | ID.AddPointer(Referencee.getAsOpaquePtr()); | ||||||
2784 | ID.AddBoolean(SpelledAsLValue); | ||||||
2785 | } | ||||||
2786 | |||||||
2787 | static bool classof(const Type *T) { | ||||||
2788 | return T->getTypeClass() == LValueReference || | ||||||
2789 | T->getTypeClass() == RValueReference; | ||||||
2790 | } | ||||||
2791 | }; | ||||||
2792 | |||||||
2793 | /// An lvalue reference type, per C++11 [dcl.ref]. | ||||||
2794 | class LValueReferenceType : public ReferenceType { | ||||||
2795 | friend class ASTContext; // ASTContext creates these | ||||||
2796 | |||||||
2797 | LValueReferenceType(QualType Referencee, QualType CanonicalRef, | ||||||
2798 | bool SpelledAsLValue) | ||||||
2799 | : ReferenceType(LValueReference, Referencee, CanonicalRef, | ||||||
2800 | SpelledAsLValue) {} | ||||||
2801 | |||||||
2802 | public: | ||||||
2803 | bool isSugared() const { return false; } | ||||||
2804 | QualType desugar() const { return QualType(this, 0); } | ||||||
2805 | |||||||
2806 | static bool classof(const Type *T) { | ||||||
2807 | return T->getTypeClass() == LValueReference; | ||||||
2808 | } | ||||||
2809 | }; | ||||||
2810 | |||||||
2811 | /// An rvalue reference type, per C++11 [dcl.ref]. | ||||||
2812 | class RValueReferenceType : public ReferenceType { | ||||||
2813 | friend class ASTContext; // ASTContext creates these | ||||||
2814 | |||||||
2815 | RValueReferenceType(QualType Referencee, QualType CanonicalRef) | ||||||
2816 | : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {} | ||||||
2817 | |||||||
2818 | public: | ||||||
2819 | bool isSugared() const { return false; } | ||||||
2820 | QualType desugar() const { return QualType(this, 0); } | ||||||
2821 | |||||||
2822 | static bool classof(const Type *T) { | ||||||
2823 | return T->getTypeClass() == RValueReference; | ||||||
2824 | } | ||||||
2825 | }; | ||||||
2826 | |||||||
2827 | /// A pointer to member type per C++ 8.3.3 - Pointers to members. | ||||||
2828 | /// | ||||||
2829 | /// This includes both pointers to data members and pointer to member functions. | ||||||
2830 | class MemberPointerType : public Type, public llvm::FoldingSetNode { | ||||||
2831 | friend class ASTContext; // ASTContext creates these. | ||||||
2832 | |||||||
2833 | QualType PointeeType; | ||||||
2834 | |||||||
2835 | /// The class of which the pointee is a member. Must ultimately be a | ||||||
2836 | /// RecordType, but could be a typedef or a template parameter too. | ||||||
2837 | const Type *Class; | ||||||
2838 | |||||||
2839 | MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) | ||||||
2840 | : Type(MemberPointer, CanonicalPtr, | ||||||
2841 | (Cls->getDependence() & ~TypeDependence::VariablyModified) | | ||||||
2842 | Pointee->getDependence()), | ||||||
2843 | PointeeType(Pointee), Class(Cls) {} | ||||||
2844 | |||||||
2845 | public: | ||||||
2846 | QualType getPointeeType() const { return PointeeType; } | ||||||
2847 | |||||||
2848 | /// Returns true if the member type (i.e. the pointee type) is a | ||||||
2849 | /// function type rather than a data-member type. | ||||||
2850 | bool isMemberFunctionPointer() const { | ||||||
2851 | return PointeeType->isFunctionProtoType(); | ||||||
2852 | } | ||||||
2853 | |||||||
2854 | /// Returns true if the member type (i.e. the pointee type) is a | ||||||
2855 | /// data type rather than a function type. | ||||||
2856 | bool isMemberDataPointer() const { | ||||||
2857 | return !PointeeType->isFunctionProtoType(); | ||||||
2858 | } | ||||||
2859 | |||||||
2860 | const Type *getClass() const { return Class; } | ||||||
2861 | CXXRecordDecl *getMostRecentCXXRecordDecl() const; | ||||||
2862 | |||||||
2863 | bool isSugared() const { return false; } | ||||||
2864 | QualType desugar() const { return QualType(this, 0); } | ||||||
2865 | |||||||
2866 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2867 | Profile(ID, getPointeeType(), getClass()); | ||||||
2868 | } | ||||||
2869 | |||||||
2870 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, | ||||||
2871 | const Type *Class) { | ||||||
2872 | ID.AddPointer(Pointee.getAsOpaquePtr()); | ||||||
2873 | ID.AddPointer(Class); | ||||||
2874 | } | ||||||
2875 | |||||||
2876 | static bool classof(const Type *T) { | ||||||
2877 | return T->getTypeClass() == MemberPointer; | ||||||
2878 | } | ||||||
2879 | }; | ||||||
2880 | |||||||
2881 | /// Represents an array type, per C99 6.7.5.2 - Array Declarators. | ||||||
2882 | class ArrayType : public Type, public llvm::FoldingSetNode { | ||||||
2883 | public: | ||||||
2884 | /// Capture whether this is a normal array (e.g. int X[4]) | ||||||
2885 | /// an array with a static size (e.g. int X[static 4]), or an array | ||||||
2886 | /// with a star size (e.g. int X[*]). | ||||||
2887 | /// 'static' is only allowed on function parameters. | ||||||
2888 | enum ArraySizeModifier { | ||||||
2889 | Normal, Static, Star | ||||||
2890 | }; | ||||||
2891 | |||||||
2892 | private: | ||||||
2893 | /// The element type of the array. | ||||||
2894 | QualType ElementType; | ||||||
2895 | |||||||
2896 | protected: | ||||||
2897 | friend class ASTContext; // ASTContext creates these. | ||||||
2898 | |||||||
2899 | ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm, | ||||||
2900 | unsigned tq, const Expr *sz = nullptr); | ||||||
2901 | |||||||
2902 | public: | ||||||
2903 | QualType getElementType() const { return ElementType; } | ||||||
2904 | |||||||
2905 | ArraySizeModifier getSizeModifier() const { | ||||||
2906 | return ArraySizeModifier(ArrayTypeBits.SizeModifier); | ||||||
2907 | } | ||||||
2908 | |||||||
2909 | Qualifiers getIndexTypeQualifiers() const { | ||||||
2910 | return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers()); | ||||||
2911 | } | ||||||
2912 | |||||||
2913 | unsigned getIndexTypeCVRQualifiers() const { | ||||||
2914 | return ArrayTypeBits.IndexTypeQuals; | ||||||
2915 | } | ||||||
2916 | |||||||
2917 | static bool classof(const Type *T) { | ||||||
2918 | return T->getTypeClass() == ConstantArray || | ||||||
2919 | T->getTypeClass() == VariableArray || | ||||||
2920 | T->getTypeClass() == IncompleteArray || | ||||||
2921 | T->getTypeClass() == DependentSizedArray; | ||||||
2922 | } | ||||||
2923 | }; | ||||||
2924 | |||||||
2925 | /// Represents the canonical version of C arrays with a specified constant size. | ||||||
2926 | /// For example, the canonical type for 'int A[4 + 4*100]' is a | ||||||
2927 | /// ConstantArrayType where the element type is 'int' and the size is 404. | ||||||
2928 | class ConstantArrayType final | ||||||
2929 | : public ArrayType, | ||||||
2930 | private llvm::TrailingObjects<ConstantArrayType, const Expr *> { | ||||||
2931 | friend class ASTContext; // ASTContext creates these. | ||||||
2932 | friend TrailingObjects; | ||||||
2933 | |||||||
2934 | llvm::APInt Size; // Allows us to unique the type. | ||||||
2935 | |||||||
2936 | ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, | ||||||
2937 | const Expr *sz, ArraySizeModifier sm, unsigned tq) | ||||||
2938 | : ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) { | ||||||
2939 | ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr; | ||||||
2940 | if (ConstantArrayTypeBits.HasStoredSizeExpr) { | ||||||
2941 | assert(!can.isNull() && "canonical constant array should not have size")(static_cast <bool> (!can.isNull() && "canonical constant array should not have size" ) ? void (0) : __assert_fail ("!can.isNull() && \"canonical constant array should not have size\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 2941, __extension__ __PRETTY_FUNCTION__)); | ||||||
2942 | *getTrailingObjects<const Expr*>() = sz; | ||||||
2943 | } | ||||||
2944 | } | ||||||
2945 | |||||||
2946 | unsigned numTrailingObjects(OverloadToken<const Expr*>) const { | ||||||
2947 | return ConstantArrayTypeBits.HasStoredSizeExpr; | ||||||
2948 | } | ||||||
2949 | |||||||
2950 | public: | ||||||
2951 | const llvm::APInt &getSize() const { return Size; } | ||||||
2952 | const Expr *getSizeExpr() const { | ||||||
2953 | return ConstantArrayTypeBits.HasStoredSizeExpr | ||||||
2954 | ? *getTrailingObjects<const Expr *>() | ||||||
2955 | : nullptr; | ||||||
2956 | } | ||||||
2957 | bool isSugared() const { return false; } | ||||||
2958 | QualType desugar() const { return QualType(this, 0); } | ||||||
2959 | |||||||
2960 | /// Determine the number of bits required to address a member of | ||||||
2961 | // an array with the given element type and number of elements. | ||||||
2962 | static unsigned getNumAddressingBits(const ASTContext &Context, | ||||||
2963 | QualType ElementType, | ||||||
2964 | const llvm::APInt &NumElements); | ||||||
2965 | |||||||
2966 | /// Determine the maximum number of active bits that an array's size | ||||||
2967 | /// can require, which limits the maximum size of the array. | ||||||
2968 | static unsigned getMaxSizeBits(const ASTContext &Context); | ||||||
2969 | |||||||
2970 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { | ||||||
2971 | Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(), | ||||||
2972 | getSizeModifier(), getIndexTypeCVRQualifiers()); | ||||||
2973 | } | ||||||
2974 | |||||||
2975 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx, | ||||||
2976 | QualType ET, const llvm::APInt &ArraySize, | ||||||
2977 | const Expr *SizeExpr, ArraySizeModifier SizeMod, | ||||||
2978 | unsigned TypeQuals); | ||||||
2979 | |||||||
2980 | static bool classof(const Type *T) { | ||||||
2981 | return T->getTypeClass() == ConstantArray; | ||||||
2982 | } | ||||||
2983 | }; | ||||||
2984 | |||||||
2985 | /// Represents a C array with an unspecified size. For example 'int A[]' has | ||||||
2986 | /// an IncompleteArrayType where the element type is 'int' and the size is | ||||||
2987 | /// unspecified. | ||||||
2988 | class IncompleteArrayType : public ArrayType { | ||||||
2989 | friend class ASTContext; // ASTContext creates these. | ||||||
2990 | |||||||
2991 | IncompleteArrayType(QualType et, QualType can, | ||||||
2992 | ArraySizeModifier sm, unsigned tq) | ||||||
2993 | : ArrayType(IncompleteArray, et, can, sm, tq) {} | ||||||
2994 | |||||||
2995 | public: | ||||||
2996 | friend class StmtIteratorBase; | ||||||
2997 | |||||||
2998 | bool isSugared() const { return false; } | ||||||
2999 | QualType desugar() const { return QualType(this, 0); } | ||||||
3000 | |||||||
3001 | static bool classof(const Type *T) { | ||||||
3002 | return T->getTypeClass() == IncompleteArray; | ||||||
3003 | } | ||||||
3004 | |||||||
3005 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3006 | Profile(ID, getElementType(), getSizeModifier(), | ||||||
3007 | getIndexTypeCVRQualifiers()); | ||||||
3008 | } | ||||||
3009 | |||||||
3010 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, | ||||||
3011 | ArraySizeModifier SizeMod, unsigned TypeQuals) { | ||||||
3012 | ID.AddPointer(ET.getAsOpaquePtr()); | ||||||
3013 | ID.AddInteger(SizeMod); | ||||||
3014 | ID.AddInteger(TypeQuals); | ||||||
3015 | } | ||||||
3016 | }; | ||||||
3017 | |||||||
3018 | /// Represents a C array with a specified size that is not an | ||||||
3019 | /// integer-constant-expression. For example, 'int s[x+foo()]'. | ||||||
3020 | /// Since the size expression is an arbitrary expression, we store it as such. | ||||||
3021 | /// | ||||||
3022 | /// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and | ||||||
3023 | /// should not be: two lexically equivalent variable array types could mean | ||||||
3024 | /// different things, for example, these variables do not have the same type | ||||||
3025 | /// dynamically: | ||||||
3026 | /// | ||||||
3027 | /// void foo(int x) { | ||||||
3028 | /// int Y[x]; | ||||||
3029 | /// ++x; | ||||||
3030 | /// int Z[x]; | ||||||
3031 | /// } | ||||||
3032 | class VariableArrayType : public ArrayType { | ||||||
3033 | friend class ASTContext; // ASTContext creates these. | ||||||
3034 | |||||||
3035 | /// An assignment-expression. VLA's are only permitted within | ||||||
3036 | /// a function block. | ||||||
3037 | Stmt *SizeExpr; | ||||||
3038 | |||||||
3039 | /// The range spanned by the left and right array brackets. | ||||||
3040 | SourceRange Brackets; | ||||||
3041 | |||||||
3042 | VariableArrayType(QualType et, QualType can, Expr *e, | ||||||
3043 | ArraySizeModifier sm, unsigned tq, | ||||||
3044 | SourceRange brackets) | ||||||
3045 | : ArrayType(VariableArray, et, can, sm, tq, e), | ||||||
3046 | SizeExpr((Stmt*) e), Brackets(brackets) {} | ||||||
3047 | |||||||
3048 | public: | ||||||
3049 | friend class StmtIteratorBase; | ||||||
3050 | |||||||
3051 | Expr *getSizeExpr() const { | ||||||
3052 | // We use C-style casts instead of cast<> here because we do not wish | ||||||
3053 | // to have a dependency of Type.h on Stmt.h/Expr.h. | ||||||
3054 | return (Expr*) SizeExpr; | ||||||
3055 | } | ||||||
3056 | |||||||
3057 | SourceRange getBracketsRange() const { return Brackets; } | ||||||
3058 | SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } | ||||||
3059 | SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } | ||||||
3060 | |||||||
3061 | bool isSugared() const { return false; } | ||||||
3062 | QualType desugar() const { return QualType(this, 0); } | ||||||
3063 | |||||||
3064 | static bool classof(const Type *T) { | ||||||
3065 | return T->getTypeClass() == VariableArray; | ||||||
3066 | } | ||||||
3067 | |||||||
3068 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3069 | llvm_unreachable("Cannot unique VariableArrayTypes.")::llvm::llvm_unreachable_internal("Cannot unique VariableArrayTypes." , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 3069); | ||||||
3070 | } | ||||||
3071 | }; | ||||||
3072 | |||||||
3073 | /// Represents an array type in C++ whose size is a value-dependent expression. | ||||||
3074 | /// | ||||||
3075 | /// For example: | ||||||
3076 | /// \code | ||||||
3077 | /// template<typename T, int Size> | ||||||
3078 | /// class array { | ||||||
3079 | /// T data[Size]; | ||||||
3080 | /// }; | ||||||
3081 | /// \endcode | ||||||
3082 | /// | ||||||
3083 | /// For these types, we won't actually know what the array bound is | ||||||
3084 | /// until template instantiation occurs, at which point this will | ||||||
3085 | /// become either a ConstantArrayType or a VariableArrayType. | ||||||
3086 | class DependentSizedArrayType : public ArrayType { | ||||||
3087 | friend class ASTContext; // ASTContext creates these. | ||||||
3088 | |||||||
3089 | const ASTContext &Context; | ||||||
3090 | |||||||
3091 | /// An assignment expression that will instantiate to the | ||||||
3092 | /// size of the array. | ||||||
3093 | /// | ||||||
3094 | /// The expression itself might be null, in which case the array | ||||||
3095 | /// type will have its size deduced from an initializer. | ||||||
3096 | Stmt *SizeExpr; | ||||||
3097 | |||||||
3098 | /// The range spanned by the left and right array brackets. | ||||||
3099 | SourceRange Brackets; | ||||||
3100 | |||||||
3101 | DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can, | ||||||
3102 | Expr *e, ArraySizeModifier sm, unsigned tq, | ||||||
3103 | SourceRange brackets); | ||||||
3104 | |||||||
3105 | public: | ||||||
3106 | friend class StmtIteratorBase; | ||||||
3107 | |||||||
3108 | Expr *getSizeExpr() const { | ||||||
3109 | // We use C-style casts instead of cast<> here because we do not wish | ||||||
3110 | // to have a dependency of Type.h on Stmt.h/Expr.h. | ||||||
3111 | return (Expr*) SizeExpr; | ||||||
3112 | } | ||||||
3113 | |||||||
3114 | SourceRange getBracketsRange() const { return Brackets; } | ||||||
3115 | SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } | ||||||
3116 | SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } | ||||||
3117 | |||||||
3118 | bool isSugared() const { return false; } | ||||||
3119 | QualType desugar() const { return QualType(this, 0); } | ||||||
3120 | |||||||
3121 | static bool classof(const Type *T) { | ||||||
3122 | return T->getTypeClass() == DependentSizedArray; | ||||||
3123 | } | ||||||
3124 | |||||||
3125 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3126 | Profile(ID, Context, getElementType(), | ||||||
3127 | getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr()); | ||||||
3128 | } | ||||||
3129 | |||||||
3130 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3131 | QualType ET, ArraySizeModifier SizeMod, | ||||||
3132 | unsigned TypeQuals, Expr *E); | ||||||
3133 | }; | ||||||
3134 | |||||||
3135 | /// Represents an extended address space qualifier where the input address space | ||||||
3136 | /// value is dependent. Non-dependent address spaces are not represented with a | ||||||
3137 | /// special Type subclass; they are stored on an ExtQuals node as part of a QualType. | ||||||
3138 | /// | ||||||
3139 | /// For example: | ||||||
3140 | /// \code | ||||||
3141 | /// template<typename T, int AddrSpace> | ||||||
3142 | /// class AddressSpace { | ||||||
3143 | /// typedef T __attribute__((address_space(AddrSpace))) type; | ||||||
3144 | /// } | ||||||
3145 | /// \endcode | ||||||
3146 | class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode { | ||||||
3147 | friend class ASTContext; | ||||||
3148 | |||||||
3149 | const ASTContext &Context; | ||||||
3150 | Expr *AddrSpaceExpr; | ||||||
3151 | QualType PointeeType; | ||||||
3152 | SourceLocation loc; | ||||||
3153 | |||||||
3154 | DependentAddressSpaceType(const ASTContext &Context, QualType PointeeType, | ||||||
3155 | QualType can, Expr *AddrSpaceExpr, | ||||||
3156 | SourceLocation loc); | ||||||
3157 | |||||||
3158 | public: | ||||||
3159 | Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; } | ||||||
3160 | QualType getPointeeType() const { return PointeeType; } | ||||||
3161 | SourceLocation getAttributeLoc() const { return loc; } | ||||||
3162 | |||||||
3163 | bool isSugared() const { return false; } | ||||||
3164 | QualType desugar() const { return QualType(this, 0); } | ||||||
3165 | |||||||
3166 | static bool classof(const Type *T) { | ||||||
3167 | return T->getTypeClass() == DependentAddressSpace; | ||||||
3168 | } | ||||||
3169 | |||||||
3170 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3171 | Profile(ID, Context, getPointeeType(), getAddrSpaceExpr()); | ||||||
3172 | } | ||||||
3173 | |||||||
3174 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3175 | QualType PointeeType, Expr *AddrSpaceExpr); | ||||||
3176 | }; | ||||||
3177 | |||||||
3178 | /// Represents an extended vector type where either the type or size is | ||||||
3179 | /// dependent. | ||||||
3180 | /// | ||||||
3181 | /// For example: | ||||||
3182 | /// \code | ||||||
3183 | /// template<typename T, int Size> | ||||||
3184 | /// class vector { | ||||||
3185 | /// typedef T __attribute__((ext_vector_type(Size))) type; | ||||||
3186 | /// } | ||||||
3187 | /// \endcode | ||||||
3188 | class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { | ||||||
3189 | friend class ASTContext; | ||||||
3190 | |||||||
3191 | const ASTContext &Context; | ||||||
3192 | Expr *SizeExpr; | ||||||
3193 | |||||||
3194 | /// The element type of the array. | ||||||
3195 | QualType ElementType; | ||||||
3196 | |||||||
3197 | SourceLocation loc; | ||||||
3198 | |||||||
3199 | DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType, | ||||||
3200 | QualType can, Expr *SizeExpr, SourceLocation loc); | ||||||
3201 | |||||||
3202 | public: | ||||||
3203 | Expr *getSizeExpr() const { return SizeExpr; } | ||||||
3204 | QualType getElementType() const { return ElementType; } | ||||||
3205 | SourceLocation getAttributeLoc() const { return loc; } | ||||||
3206 | |||||||
3207 | bool isSugared() const { return false; } | ||||||
3208 | QualType desugar() const { return QualType(this, 0); } | ||||||
3209 | |||||||
3210 | static bool classof(const Type *T) { | ||||||
3211 | return T->getTypeClass() == DependentSizedExtVector; | ||||||
3212 | } | ||||||
3213 | |||||||
3214 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3215 | Profile(ID, Context, getElementType(), getSizeExpr()); | ||||||
3216 | } | ||||||
3217 | |||||||
3218 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3219 | QualType ElementType, Expr *SizeExpr); | ||||||
3220 | }; | ||||||
3221 | |||||||
3222 | |||||||
3223 | /// Represents a GCC generic vector type. This type is created using | ||||||
3224 | /// __attribute__((vector_size(n)), where "n" specifies the vector size in | ||||||
3225 | /// bytes; or from an Altivec __vector or vector declaration. | ||||||
3226 | /// Since the constructor takes the number of vector elements, the | ||||||
3227 | /// client is responsible for converting the size into the number of elements. | ||||||
3228 | class VectorType : public Type, public llvm::FoldingSetNode { | ||||||
3229 | public: | ||||||
3230 | enum VectorKind { | ||||||
3231 | /// not a target-specific vector type | ||||||
3232 | GenericVector, | ||||||
3233 | |||||||
3234 | /// is AltiVec vector | ||||||
3235 | AltiVecVector, | ||||||
3236 | |||||||
3237 | /// is AltiVec 'vector Pixel' | ||||||
3238 | AltiVecPixel, | ||||||
3239 | |||||||
3240 | /// is AltiVec 'vector bool ...' | ||||||
3241 | AltiVecBool, | ||||||
3242 | |||||||
3243 | /// is ARM Neon vector | ||||||
3244 | NeonVector, | ||||||
3245 | |||||||
3246 | /// is ARM Neon polynomial vector | ||||||
3247 | NeonPolyVector, | ||||||
3248 | |||||||
3249 | /// is AArch64 SVE fixed-length data vector | ||||||
3250 | SveFixedLengthDataVector, | ||||||
3251 | |||||||
3252 | /// is AArch64 SVE fixed-length predicate vector | ||||||
3253 | SveFixedLengthPredicateVector | ||||||
3254 | }; | ||||||
3255 | |||||||
3256 | protected: | ||||||
3257 | friend class ASTContext; // ASTContext creates these. | ||||||
3258 | |||||||
3259 | /// The element type of the vector. | ||||||
3260 | QualType ElementType; | ||||||
3261 | |||||||
3262 | VectorType(QualType vecType, unsigned nElements, QualType canonType, | ||||||
3263 | VectorKind vecKind); | ||||||
3264 | |||||||
3265 | VectorType(TypeClass tc, QualType vecType, unsigned nElements, | ||||||
3266 | QualType canonType, VectorKind vecKind); | ||||||
3267 | |||||||
3268 | public: | ||||||
3269 | QualType getElementType() const { return ElementType; } | ||||||
3270 | unsigned getNumElements() const { return VectorTypeBits.NumElements; } | ||||||
3271 | |||||||
3272 | bool isSugared() const { return false; } | ||||||
3273 | QualType desugar() const { return QualType(this, 0); } | ||||||
3274 | |||||||
3275 | VectorKind getVectorKind() const { | ||||||
3276 | return VectorKind(VectorTypeBits.VecKind); | ||||||
3277 | } | ||||||
3278 | |||||||
3279 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3280 | Profile(ID, getElementType(), getNumElements(), | ||||||
3281 | getTypeClass(), getVectorKind()); | ||||||
3282 | } | ||||||
3283 | |||||||
3284 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, | ||||||
3285 | unsigned NumElements, TypeClass TypeClass, | ||||||
3286 | VectorKind VecKind) { | ||||||
3287 | ID.AddPointer(ElementType.getAsOpaquePtr()); | ||||||
3288 | ID.AddInteger(NumElements); | ||||||
3289 | ID.AddInteger(TypeClass); | ||||||
3290 | ID.AddInteger(VecKind); | ||||||
3291 | } | ||||||
3292 | |||||||
3293 | static bool classof(const Type *T) { | ||||||
3294 | return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; | ||||||
3295 | } | ||||||
3296 | }; | ||||||
3297 | |||||||
3298 | /// Represents a vector type where either the type or size is dependent. | ||||||
3299 | //// | ||||||
3300 | /// For example: | ||||||
3301 | /// \code | ||||||
3302 | /// template<typename T, int Size> | ||||||
3303 | /// class vector { | ||||||
3304 | /// typedef T __attribute__((vector_size(Size))) type; | ||||||
3305 | /// } | ||||||
3306 | /// \endcode | ||||||
3307 | class DependentVectorType : public Type, public llvm::FoldingSetNode { | ||||||
3308 | friend class ASTContext; | ||||||
3309 | |||||||
3310 | const ASTContext &Context; | ||||||
3311 | QualType ElementType; | ||||||
3312 | Expr *SizeExpr; | ||||||
3313 | SourceLocation Loc; | ||||||
3314 | |||||||
3315 | DependentVectorType(const ASTContext &Context, QualType ElementType, | ||||||
3316 | QualType CanonType, Expr *SizeExpr, | ||||||
3317 | SourceLocation Loc, VectorType::VectorKind vecKind); | ||||||
3318 | |||||||
3319 | public: | ||||||
3320 | Expr *getSizeExpr() const { return SizeExpr; } | ||||||
3321 | QualType getElementType() const { return ElementType; } | ||||||
3322 | SourceLocation getAttributeLoc() const { return Loc; } | ||||||
3323 | VectorType::VectorKind getVectorKind() const { | ||||||
3324 | return VectorType::VectorKind(VectorTypeBits.VecKind); | ||||||
3325 | } | ||||||
3326 | |||||||
3327 | bool isSugared() const { return false; } | ||||||
3328 | QualType desugar() const { return QualType(this, 0); } | ||||||
3329 | |||||||
3330 | static bool classof(const Type *T) { | ||||||
3331 | return T->getTypeClass() == DependentVector; | ||||||
3332 | } | ||||||
3333 | |||||||
3334 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3335 | Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind()); | ||||||
3336 | } | ||||||
3337 | |||||||
3338 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3339 | QualType ElementType, const Expr *SizeExpr, | ||||||
3340 | VectorType::VectorKind VecKind); | ||||||
3341 | }; | ||||||
3342 | |||||||
3343 | /// ExtVectorType - Extended vector type. This type is created using | ||||||
3344 | /// __attribute__((ext_vector_type(n)), where "n" is the number of elements. | ||||||
3345 | /// Unlike vector_size, ext_vector_type is only allowed on typedef's. This | ||||||
3346 | /// class enables syntactic extensions, like Vector Components for accessing | ||||||
3347 | /// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL | ||||||
3348 | /// Shading Language). | ||||||
3349 | class ExtVectorType : public VectorType { | ||||||
3350 | friend class ASTContext; // ASTContext creates these. | ||||||
3351 | |||||||
3352 | ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) | ||||||
3353 | : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} | ||||||
3354 | |||||||
3355 | public: | ||||||
3356 | static int getPointAccessorIdx(char c) { | ||||||
3357 | switch (c) { | ||||||
3358 | default: return -1; | ||||||
3359 | case 'x': case 'r': return 0; | ||||||
3360 | case 'y': case 'g': return 1; | ||||||
3361 | case 'z': case 'b': return 2; | ||||||
3362 | case 'w': case 'a': return 3; | ||||||
3363 | } | ||||||
3364 | } | ||||||
3365 | |||||||
3366 | static int getNumericAccessorIdx(char c) { | ||||||
3367 | switch (c) { | ||||||
3368 | default: return -1; | ||||||
3369 | case '0': return 0; | ||||||
3370 | case '1': return 1; | ||||||
3371 | case '2': return 2; | ||||||
3372 | case '3': return 3; | ||||||
3373 | case '4': return 4; | ||||||
3374 | case '5': return 5; | ||||||
3375 | case '6': return 6; | ||||||
3376 | case '7': return 7; | ||||||
3377 | case '8': return 8; | ||||||
3378 | case '9': return 9; | ||||||
3379 | case 'A': | ||||||
3380 | case 'a': return 10; | ||||||
3381 | case 'B': | ||||||
3382 | case 'b': return 11; | ||||||
3383 | case 'C': | ||||||
3384 | case 'c': return 12; | ||||||
3385 | case 'D': | ||||||
3386 | case 'd': return 13; | ||||||
3387 | case 'E': | ||||||
3388 | case 'e': return 14; | ||||||
3389 | case 'F': | ||||||
3390 | case 'f': return 15; | ||||||
3391 | } | ||||||
3392 | } | ||||||
3393 | |||||||
3394 | static int getAccessorIdx(char c, bool isNumericAccessor) { | ||||||
3395 | if (isNumericAccessor) | ||||||
3396 | return getNumericAccessorIdx(c); | ||||||
3397 | else | ||||||
3398 | return getPointAccessorIdx(c); | ||||||
3399 | } | ||||||
3400 | |||||||
3401 | bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const { | ||||||
3402 | if (int idx = getAccessorIdx(c, isNumericAccessor)+1) | ||||||
3403 | return unsigned(idx-1) < getNumElements(); | ||||||
3404 | return false; | ||||||
3405 | } | ||||||
3406 | |||||||
3407 | bool isSugared() const { return false; } | ||||||
3408 | QualType desugar() const { return QualType(this, 0); } | ||||||
3409 | |||||||
3410 | static bool classof(const Type *T) { | ||||||
3411 | return T->getTypeClass() == ExtVector; | ||||||
3412 | } | ||||||
3413 | }; | ||||||
3414 | |||||||
3415 | /// Represents a matrix type, as defined in the Matrix Types clang extensions. | ||||||
3416 | /// __attribute__((matrix_type(rows, columns))), where "rows" specifies | ||||||
3417 | /// number of rows and "columns" specifies the number of columns. | ||||||
3418 | class MatrixType : public Type, public llvm::FoldingSetNode { | ||||||
3419 | protected: | ||||||
3420 | friend class ASTContext; | ||||||
3421 | |||||||
3422 | /// The element type of the matrix. | ||||||
3423 | QualType ElementType; | ||||||
3424 | |||||||
3425 | MatrixType(QualType ElementTy, QualType CanonElementTy); | ||||||
3426 | |||||||
3427 | MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy, | ||||||
3428 | const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr); | ||||||
3429 | |||||||
3430 | public: | ||||||
3431 | /// Returns type of the elements being stored in the matrix | ||||||
3432 | QualType getElementType() const { return ElementType; } | ||||||
3433 | |||||||
3434 | /// Valid elements types are the following: | ||||||
3435 | /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types | ||||||
3436 | /// and _Bool | ||||||
3437 | /// * the standard floating types float or double | ||||||
3438 | /// * a half-precision floating point type, if one is supported on the target | ||||||
3439 | static bool isValidElementType(QualType T) { | ||||||
3440 | return T->isDependentType() || | ||||||
3441 | (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType()); | ||||||
3442 | } | ||||||
3443 | |||||||
3444 | bool isSugared() const { return false; } | ||||||
3445 | QualType desugar() const { return QualType(this, 0); } | ||||||
3446 | |||||||
3447 | static bool classof(const Type *T) { | ||||||
3448 | return T->getTypeClass() == ConstantMatrix || | ||||||
3449 | T->getTypeClass() == DependentSizedMatrix; | ||||||
3450 | } | ||||||
3451 | }; | ||||||
3452 | |||||||
3453 | /// Represents a concrete matrix type with constant number of rows and columns | ||||||
3454 | class ConstantMatrixType final : public MatrixType { | ||||||
3455 | protected: | ||||||
3456 | friend class ASTContext; | ||||||
3457 | |||||||
3458 | /// Number of rows and columns. | ||||||
3459 | unsigned NumRows; | ||||||
3460 | unsigned NumColumns; | ||||||
3461 | |||||||
3462 | static constexpr unsigned MaxElementsPerDimension = (1 << 20) - 1; | ||||||
3463 | |||||||
3464 | ConstantMatrixType(QualType MatrixElementType, unsigned NRows, | ||||||
3465 | unsigned NColumns, QualType CanonElementType); | ||||||
3466 | |||||||
3467 | ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows, | ||||||
3468 | unsigned NColumns, QualType CanonElementType); | ||||||
3469 | |||||||
3470 | public: | ||||||
3471 | /// Returns the number of rows in the matrix. | ||||||
3472 | unsigned getNumRows() const { return NumRows; } | ||||||
3473 | |||||||
3474 | /// Returns the number of columns in the matrix. | ||||||
3475 | unsigned getNumColumns() const { return NumColumns; } | ||||||
3476 | |||||||
3477 | /// Returns the number of elements required to embed the matrix into a vector. | ||||||
3478 | unsigned getNumElementsFlattened() const { | ||||||
3479 | return getNumRows() * getNumColumns(); | ||||||
3480 | } | ||||||
3481 | |||||||
3482 | /// Returns true if \p NumElements is a valid matrix dimension. | ||||||
3483 | static constexpr bool isDimensionValid(size_t NumElements) { | ||||||
3484 | return NumElements > 0 && NumElements <= MaxElementsPerDimension; | ||||||
3485 | } | ||||||
3486 | |||||||
3487 | /// Returns the maximum number of elements per dimension. | ||||||
3488 | static constexpr unsigned getMaxElementsPerDimension() { | ||||||
3489 | return MaxElementsPerDimension; | ||||||
3490 | } | ||||||
3491 | |||||||
3492 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3493 | Profile(ID, getElementType(), getNumRows(), getNumColumns(), | ||||||
3494 | getTypeClass()); | ||||||
3495 | } | ||||||
3496 | |||||||
3497 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, | ||||||
3498 | unsigned NumRows, unsigned NumColumns, | ||||||
3499 | TypeClass TypeClass) { | ||||||
3500 | ID.AddPointer(ElementType.getAsOpaquePtr()); | ||||||
3501 | ID.AddInteger(NumRows); | ||||||
3502 | ID.AddInteger(NumColumns); | ||||||
3503 | ID.AddInteger(TypeClass); | ||||||
3504 | } | ||||||
3505 | |||||||
3506 | static bool classof(const Type *T) { | ||||||
3507 | return T->getTypeClass() == ConstantMatrix; | ||||||
3508 | } | ||||||
3509 | }; | ||||||
3510 | |||||||
3511 | /// Represents a matrix type where the type and the number of rows and columns | ||||||
3512 | /// is dependent on a template. | ||||||
3513 | class DependentSizedMatrixType final : public MatrixType { | ||||||
3514 | friend class ASTContext; | ||||||
3515 | |||||||
3516 | const ASTContext &Context; | ||||||
3517 | Expr *RowExpr; | ||||||
3518 | Expr *ColumnExpr; | ||||||
3519 | |||||||
3520 | SourceLocation loc; | ||||||
3521 | |||||||
3522 | DependentSizedMatrixType(const ASTContext &Context, QualType ElementType, | ||||||
3523 | QualType CanonicalType, Expr *RowExpr, | ||||||
3524 | Expr *ColumnExpr, SourceLocation loc); | ||||||
3525 | |||||||
3526 | public: | ||||||
3527 | QualType getElementType() const { return ElementType; } | ||||||
3528 | Expr *getRowExpr() const { return RowExpr; } | ||||||
3529 | Expr *getColumnExpr() const { return ColumnExpr; } | ||||||
3530 | SourceLocation getAttributeLoc() const { return loc; } | ||||||
3531 | |||||||
3532 | bool isSugared() const { return false; } | ||||||
3533 | QualType desugar() const { return QualType(this, 0); } | ||||||
3534 | |||||||
3535 | static bool classof(const Type *T) { | ||||||
3536 | return T->getTypeClass() == DependentSizedMatrix; | ||||||
3537 | } | ||||||
3538 | |||||||
3539 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3540 | Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr()); | ||||||
3541 | } | ||||||
3542 | |||||||
3543 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3544 | QualType ElementType, Expr *RowExpr, Expr *ColumnExpr); | ||||||
3545 | }; | ||||||
3546 | |||||||
3547 | /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base | ||||||
3548 | /// class of FunctionNoProtoType and FunctionProtoType. | ||||||
3549 | class FunctionType : public Type { | ||||||
3550 | // The type returned by the function. | ||||||
3551 | QualType ResultType; | ||||||
3552 | |||||||
3553 | public: | ||||||
3554 | /// Interesting information about a specific parameter that can't simply | ||||||
3555 | /// be reflected in parameter's type. This is only used by FunctionProtoType | ||||||
3556 | /// but is in FunctionType to make this class available during the | ||||||
3557 | /// specification of the bases of FunctionProtoType. | ||||||
3558 | /// | ||||||
3559 | /// It makes sense to model language features this way when there's some | ||||||
3560 | /// sort of parameter-specific override (such as an attribute) that | ||||||
3561 | /// affects how the function is called. For example, the ARC ns_consumed | ||||||
3562 | /// attribute changes whether a parameter is passed at +0 (the default) | ||||||
3563 | /// or +1 (ns_consumed). This must be reflected in the function type, | ||||||
3564 | /// but isn't really a change to the parameter type. | ||||||
3565 | /// | ||||||
3566 | /// One serious disadvantage of modelling language features this way is | ||||||
3567 | /// that they generally do not work with language features that attempt | ||||||
3568 | /// to destructure types. For example, template argument deduction will | ||||||
3569 | /// not be able to match a parameter declared as | ||||||
3570 | /// T (*)(U) | ||||||
3571 | /// against an argument of type | ||||||
3572 | /// void (*)(__attribute__((ns_consumed)) id) | ||||||
3573 | /// because the substitution of T=void, U=id into the former will | ||||||
3574 | /// not produce the latter. | ||||||
3575 | class ExtParameterInfo { | ||||||
3576 | enum { | ||||||
3577 | ABIMask = 0x0F, | ||||||
3578 | IsConsumed = 0x10, | ||||||
3579 | HasPassObjSize = 0x20, | ||||||
3580 | IsNoEscape = 0x40, | ||||||
3581 | }; | ||||||
3582 | unsigned char Data = 0; | ||||||
3583 | |||||||
3584 | public: | ||||||
3585 | ExtParameterInfo() = default; | ||||||
3586 | |||||||
3587 | /// Return the ABI treatment of this parameter. | ||||||
3588 | ParameterABI getABI() const { return ParameterABI(Data & ABIMask); } | ||||||
3589 | ExtParameterInfo withABI(ParameterABI kind) const { | ||||||
3590 | ExtParameterInfo copy = *this; | ||||||
3591 | copy.Data = (copy.Data & ~ABIMask) | unsigned(kind); | ||||||
3592 | return copy; | ||||||
3593 | } | ||||||
3594 | |||||||
3595 | /// Is this parameter considered "consumed" by Objective-C ARC? | ||||||
3596 | /// Consumed parameters must have retainable object type. | ||||||
3597 | bool isConsumed() const { return (Data & IsConsumed); } | ||||||
3598 | ExtParameterInfo withIsConsumed(bool consumed) const { | ||||||
3599 | ExtParameterInfo copy = *this; | ||||||
3600 | if (consumed) | ||||||
3601 | copy.Data |= IsConsumed; | ||||||
3602 | else | ||||||
3603 | copy.Data &= ~IsConsumed; | ||||||
3604 | return copy; | ||||||
3605 | } | ||||||
3606 | |||||||
3607 | bool hasPassObjectSize() const { return Data & HasPassObjSize; } | ||||||
3608 | ExtParameterInfo withHasPassObjectSize() const { | ||||||
3609 | ExtParameterInfo Copy = *this; | ||||||
3610 | Copy.Data |= HasPassObjSize; | ||||||
3611 | return Copy; | ||||||
3612 | } | ||||||
3613 | |||||||
3614 | bool isNoEscape() const { return Data & IsNoEscape; } | ||||||
3615 | ExtParameterInfo withIsNoEscape(bool NoEscape) const { | ||||||
3616 | ExtParameterInfo Copy = *this; | ||||||
3617 | if (NoEscape) | ||||||
3618 | Copy.Data |= IsNoEscape; | ||||||
3619 | else | ||||||
3620 | Copy.Data &= ~IsNoEscape; | ||||||
3621 | return Copy; | ||||||
3622 | } | ||||||
3623 | |||||||
3624 | unsigned char getOpaqueValue() const { return Data; } | ||||||
3625 | static ExtParameterInfo getFromOpaqueValue(unsigned char data) { | ||||||
3626 | ExtParameterInfo result; | ||||||
3627 | result.Data = data; | ||||||
3628 | return result; | ||||||
3629 | } | ||||||
3630 | |||||||
3631 | friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) { | ||||||
3632 | return lhs.Data == rhs.Data; | ||||||
3633 | } | ||||||
3634 | |||||||
3635 | friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) { | ||||||
3636 | return lhs.Data != rhs.Data; | ||||||
3637 | } | ||||||
3638 | }; | ||||||
3639 | |||||||
3640 | /// A class which abstracts out some details necessary for | ||||||
3641 | /// making a call. | ||||||
3642 | /// | ||||||
3643 | /// It is not actually used directly for storing this information in | ||||||
3644 | /// a FunctionType, although FunctionType does currently use the | ||||||
3645 | /// same bit-pattern. | ||||||
3646 | /// | ||||||
3647 | // If you add a field (say Foo), other than the obvious places (both, | ||||||
3648 | // constructors, compile failures), what you need to update is | ||||||
3649 | // * Operator== | ||||||
3650 | // * getFoo | ||||||
3651 | // * withFoo | ||||||
3652 | // * functionType. Add Foo, getFoo. | ||||||
3653 | // * ASTContext::getFooType | ||||||
3654 | // * ASTContext::mergeFunctionTypes | ||||||
3655 | // * FunctionNoProtoType::Profile | ||||||
3656 | // * FunctionProtoType::Profile | ||||||
3657 | // * TypePrinter::PrintFunctionProto | ||||||
3658 | // * AST read and write | ||||||
3659 | // * Codegen | ||||||
3660 | class ExtInfo { | ||||||
3661 | friend class FunctionType; | ||||||
3662 | |||||||
3663 | // Feel free to rearrange or add bits, but if you go over 16, you'll need to | ||||||
3664 | // adjust the Bits field below, and if you add bits, you'll need to adjust | ||||||
3665 | // Type::FunctionTypeBitfields::ExtInfo as well. | ||||||
3666 | |||||||
3667 | // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall| | ||||||
3668 | // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | 12 | | ||||||
3669 | // | ||||||
3670 | // regparm is either 0 (no regparm attribute) or the regparm value+1. | ||||||
3671 | enum { CallConvMask = 0x1F }; | ||||||
3672 | enum { NoReturnMask = 0x20 }; | ||||||
3673 | enum { ProducesResultMask = 0x40 }; | ||||||
3674 | enum { NoCallerSavedRegsMask = 0x80 }; | ||||||
3675 | enum { | ||||||
3676 | RegParmMask = 0x700, | ||||||
3677 | RegParmOffset = 8 | ||||||
3678 | }; | ||||||
3679 | enum { NoCfCheckMask = 0x800 }; | ||||||
3680 | enum { CmseNSCallMask = 0x1000 }; | ||||||
3681 | uint16_t Bits = CC_C; | ||||||
3682 | |||||||
3683 | ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} | ||||||
3684 | |||||||
3685 | public: | ||||||
3686 | // Constructor with no defaults. Use this when you know that you | ||||||
3687 | // have all the elements (when reading an AST file for example). | ||||||
3688 | ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, | ||||||
3689 | bool producesResult, bool noCallerSavedRegs, bool NoCfCheck, | ||||||
3690 | bool cmseNSCall) { | ||||||
3691 | assert((!hasRegParm || regParm < 7) && "Invalid regparm value")(static_cast <bool> ((!hasRegParm || regParm < 7) && "Invalid regparm value") ? void (0) : __assert_fail ("(!hasRegParm || regParm < 7) && \"Invalid regparm value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 3691, __extension__ __PRETTY_FUNCTION__)); | ||||||
3692 | Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) | | ||||||
3693 | (producesResult ? ProducesResultMask : 0) | | ||||||
3694 | (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) | | ||||||
3695 | (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | | ||||||
3696 | (NoCfCheck ? NoCfCheckMask : 0) | | ||||||
3697 | (cmseNSCall ? CmseNSCallMask : 0); | ||||||
3698 | } | ||||||
3699 | |||||||
3700 | // Constructor with all defaults. Use when for example creating a | ||||||
3701 | // function known to use defaults. | ||||||
3702 | ExtInfo() = default; | ||||||
3703 | |||||||
3704 | // Constructor with just the calling convention, which is an important part | ||||||
3705 | // of the canonical type. | ||||||
3706 | ExtInfo(CallingConv CC) : Bits(CC) {} | ||||||
3707 | |||||||
3708 | bool getNoReturn() const { return Bits & NoReturnMask; } | ||||||
3709 | bool getProducesResult() const { return Bits & ProducesResultMask; } | ||||||
3710 | bool getCmseNSCall() const { return Bits & CmseNSCallMask; } | ||||||
3711 | bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; } | ||||||
3712 | bool getNoCfCheck() const { return Bits & NoCfCheckMask; } | ||||||
3713 | bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; } | ||||||
3714 | |||||||
3715 | unsigned getRegParm() const { | ||||||
3716 | unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset; | ||||||
3717 | if (RegParm > 0) | ||||||
3718 | --RegParm; | ||||||
3719 | return RegParm; | ||||||
3720 | } | ||||||
3721 | |||||||
3722 | CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } | ||||||
3723 | |||||||
3724 | bool operator==(ExtInfo Other) const { | ||||||
3725 | return Bits == Other.Bits; | ||||||
3726 | } | ||||||
3727 | bool operator!=(ExtInfo Other) const { | ||||||
3728 | return Bits != Other.Bits; | ||||||
3729 | } | ||||||
3730 | |||||||
3731 | // Note that we don't have setters. That is by design, use | ||||||
3732 | // the following with methods instead of mutating these objects. | ||||||
3733 | |||||||
3734 | ExtInfo withNoReturn(bool noReturn) const { | ||||||
3735 | if (noReturn) | ||||||
3736 | return ExtInfo(Bits | NoReturnMask); | ||||||
3737 | else | ||||||
3738 | return ExtInfo(Bits & ~NoReturnMask); | ||||||
3739 | } | ||||||
3740 | |||||||
3741 | ExtInfo withProducesResult(bool producesResult) const { | ||||||
3742 | if (producesResult) | ||||||
3743 | return ExtInfo(Bits | ProducesResultMask); | ||||||
3744 | else | ||||||
3745 | return ExtInfo(Bits & ~ProducesResultMask); | ||||||
3746 | } | ||||||
3747 | |||||||
3748 | ExtInfo withCmseNSCall(bool cmseNSCall) const { | ||||||
3749 | if (cmseNSCall) | ||||||
3750 | return ExtInfo(Bits | CmseNSCallMask); | ||||||
3751 | else | ||||||
3752 | return ExtInfo(Bits & ~CmseNSCallMask); | ||||||
3753 | } | ||||||
3754 | |||||||
3755 | ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const { | ||||||
3756 | if (noCallerSavedRegs) | ||||||
3757 | return ExtInfo(Bits | NoCallerSavedRegsMask); | ||||||
3758 | else | ||||||
3759 | return ExtInfo(Bits & ~NoCallerSavedRegsMask); | ||||||
3760 | } | ||||||
3761 | |||||||
3762 | ExtInfo withNoCfCheck(bool noCfCheck) const { | ||||||
3763 | if (noCfCheck) | ||||||
3764 | return ExtInfo(Bits | NoCfCheckMask); | ||||||
3765 | else | ||||||
3766 | return ExtInfo(Bits & ~NoCfCheckMask); | ||||||
3767 | } | ||||||
3768 | |||||||
3769 | ExtInfo withRegParm(unsigned RegParm) const { | ||||||
3770 | assert(RegParm < 7 && "Invalid regparm value")(static_cast <bool> (RegParm < 7 && "Invalid regparm value" ) ? void (0) : __assert_fail ("RegParm < 7 && \"Invalid regparm value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 3770, __extension__ __PRETTY_FUNCTION__)); | ||||||
3771 | return ExtInfo((Bits & ~RegParmMask) | | ||||||
3772 | ((RegParm + 1) << RegParmOffset)); | ||||||
3773 | } | ||||||
3774 | |||||||
3775 | ExtInfo withCallingConv(CallingConv cc) const { | ||||||
3776 | return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc); | ||||||
3777 | } | ||||||
3778 | |||||||
3779 | void Profile(llvm::FoldingSetNodeID &ID) const { | ||||||
3780 | ID.AddInteger(Bits); | ||||||
3781 | } | ||||||
3782 | }; | ||||||
3783 | |||||||
3784 | /// A simple holder for a QualType representing a type in an | ||||||
3785 | /// exception specification. Unfortunately needed by FunctionProtoType | ||||||
3786 | /// because TrailingObjects cannot handle repeated types. | ||||||
3787 | struct ExceptionType { QualType Type; }; | ||||||
3788 | |||||||
3789 | /// A simple holder for various uncommon bits which do not fit in | ||||||
3790 | /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the | ||||||
3791 | /// alignment of subsequent objects in TrailingObjects. You must update | ||||||
3792 | /// hasExtraBitfields in FunctionProtoType after adding extra data here. | ||||||
3793 | struct alignas(void *) FunctionTypeExtraBitfields { | ||||||
3794 | /// The number of types in the exception specification. | ||||||
3795 | /// A whole unsigned is not needed here and according to | ||||||
3796 | /// [implimits] 8 bits would be enough here. | ||||||
3797 | unsigned NumExceptionType; | ||||||
3798 | }; | ||||||
3799 | |||||||
3800 | protected: | ||||||
3801 | FunctionType(TypeClass tc, QualType res, QualType Canonical, | ||||||
3802 | TypeDependence Dependence, ExtInfo Info) | ||||||
3803 | : Type(tc, Canonical, Dependence), ResultType(res) { | ||||||
3804 | FunctionTypeBits.ExtInfo = Info.Bits; | ||||||
3805 | } | ||||||
3806 | |||||||
3807 | Qualifiers getFastTypeQuals() const { | ||||||
3808 | return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals); | ||||||
3809 | } | ||||||
3810 | |||||||
3811 | public: | ||||||
3812 | QualType getReturnType() const { return ResultType; } | ||||||
3813 | |||||||
3814 | bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } | ||||||
3815 | unsigned getRegParmType() const { return getExtInfo().getRegParm(); } | ||||||
3816 | |||||||
3817 | /// Determine whether this function type includes the GNU noreturn | ||||||
3818 | /// attribute. The C++11 [[noreturn]] attribute does not affect the function | ||||||
3819 | /// type. | ||||||
3820 | bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } | ||||||
3821 | |||||||
3822 | bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); } | ||||||
3823 | CallingConv getCallConv() const { return getExtInfo().getCC(); } | ||||||
3824 | ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } | ||||||
3825 | |||||||
3826 | static_assert((~Qualifiers::FastMask & Qualifiers::CVRMask) == 0, | ||||||
3827 | "Const, volatile and restrict are assumed to be a subset of " | ||||||
3828 | "the fast qualifiers."); | ||||||
3829 | |||||||
3830 | bool isConst() const { return getFastTypeQuals().hasConst(); } | ||||||
3831 | bool isVolatile() const { return getFastTypeQuals().hasVolatile(); } | ||||||
3832 | bool isRestrict() const { return getFastTypeQuals().hasRestrict(); } | ||||||
3833 | |||||||
3834 | /// Determine the type of an expression that calls a function of | ||||||
3835 | /// this type. | ||||||
3836 | QualType getCallResultType(const ASTContext &Context) const { | ||||||
3837 | return getReturnType().getNonLValueExprType(Context); | ||||||
3838 | } | ||||||
3839 | |||||||
3840 | static StringRef getNameForCallConv(CallingConv CC); | ||||||
3841 | |||||||
3842 | static bool classof(const Type *T) { | ||||||
3843 | return T->getTypeClass() == FunctionNoProto || | ||||||
3844 | T->getTypeClass() == FunctionProto; | ||||||
3845 | } | ||||||
3846 | }; | ||||||
3847 | |||||||
3848 | /// Represents a K&R-style 'int foo()' function, which has | ||||||
3849 | /// no information available about its arguments. | ||||||
3850 | class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { | ||||||
3851 | friend class ASTContext; // ASTContext creates these. | ||||||
3852 | |||||||
3853 | FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) | ||||||
3854 | : FunctionType(FunctionNoProto, Result, Canonical, | ||||||
3855 | Result->getDependence() & | ||||||
3856 | ~(TypeDependence::DependentInstantiation | | ||||||
3857 | TypeDependence::UnexpandedPack), | ||||||
3858 | Info) {} | ||||||
3859 | |||||||
3860 | public: | ||||||
3861 | // No additional state past what FunctionType provides. | ||||||
3862 | |||||||
3863 | bool isSugared() const { return false; } | ||||||
3864 | QualType desugar() const { return QualType(this, 0); } | ||||||
3865 | |||||||
3866 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3867 | Profile(ID, getReturnType(), getExtInfo()); | ||||||
3868 | } | ||||||
3869 | |||||||
3870 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, | ||||||
3871 | ExtInfo Info) { | ||||||
3872 | Info.Profile(ID); | ||||||
3873 | ID.AddPointer(ResultType.getAsOpaquePtr()); | ||||||
3874 | } | ||||||
3875 | |||||||
3876 | static bool classof(const Type *T) { | ||||||
3877 | return T->getTypeClass() == FunctionNoProto; | ||||||
3878 | } | ||||||
3879 | }; | ||||||
3880 | |||||||
3881 | /// Represents a prototype with parameter type info, e.g. | ||||||
3882 | /// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no | ||||||
3883 | /// parameters, not as having a single void parameter. Such a type can have | ||||||
3884 | /// an exception specification, but this specification is not part of the | ||||||
3885 | /// canonical type. FunctionProtoType has several trailing objects, some of | ||||||
3886 | /// which optional. For more information about the trailing objects see | ||||||
3887 | /// the first comment inside FunctionProtoType. | ||||||
3888 | class FunctionProtoType final | ||||||
3889 | : public FunctionType, | ||||||
3890 | public llvm::FoldingSetNode, | ||||||
3891 | private llvm::TrailingObjects< | ||||||
3892 | FunctionProtoType, QualType, SourceLocation, | ||||||
3893 | FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType, | ||||||
3894 | Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> { | ||||||
3895 | friend class ASTContext; // ASTContext creates these. | ||||||
3896 | friend TrailingObjects; | ||||||
3897 | |||||||
3898 | // FunctionProtoType is followed by several trailing objects, some of | ||||||
3899 | // which optional. They are in order: | ||||||
3900 | // | ||||||
3901 | // * An array of getNumParams() QualType holding the parameter types. | ||||||
3902 | // Always present. Note that for the vast majority of FunctionProtoType, | ||||||
3903 | // these will be the only trailing objects. | ||||||
3904 | // | ||||||
3905 | // * Optionally if the function is variadic, the SourceLocation of the | ||||||
3906 | // ellipsis. | ||||||
3907 | // | ||||||
3908 | // * Optionally if some extra data is stored in FunctionTypeExtraBitfields | ||||||
3909 | // (see FunctionTypeExtraBitfields and FunctionTypeBitfields): | ||||||
3910 | // a single FunctionTypeExtraBitfields. Present if and only if | ||||||
3911 | // hasExtraBitfields() is true. | ||||||
3912 | // | ||||||
3913 | // * Optionally exactly one of: | ||||||
3914 | // * an array of getNumExceptions() ExceptionType, | ||||||
3915 | // * a single Expr *, | ||||||
3916 | // * a pair of FunctionDecl *, | ||||||
3917 | // * a single FunctionDecl * | ||||||
3918 | // used to store information about the various types of exception | ||||||
3919 | // specification. See getExceptionSpecSize for the details. | ||||||
3920 | // | ||||||
3921 | // * Optionally an array of getNumParams() ExtParameterInfo holding | ||||||
3922 | // an ExtParameterInfo for each of the parameters. Present if and | ||||||
3923 | // only if hasExtParameterInfos() is true. | ||||||
3924 | // | ||||||
3925 | // * Optionally a Qualifiers object to represent extra qualifiers that can't | ||||||
3926 | // be represented by FunctionTypeBitfields.FastTypeQuals. Present if and only | ||||||
3927 | // if hasExtQualifiers() is true. | ||||||
3928 | // | ||||||
3929 | // The optional FunctionTypeExtraBitfields has to be before the data | ||||||
3930 | // related to the exception specification since it contains the number | ||||||
3931 | // of exception types. | ||||||
3932 | // | ||||||
3933 | // We put the ExtParameterInfos last. If all were equal, it would make | ||||||
3934 | // more sense to put these before the exception specification, because | ||||||
3935 | // it's much easier to skip past them compared to the elaborate switch | ||||||
3936 | // required to skip the exception specification. However, all is not | ||||||
3937 | // equal; ExtParameterInfos are used to model very uncommon features, | ||||||
3938 | // and it's better not to burden the more common paths. | ||||||
3939 | |||||||
3940 | public: | ||||||
3941 | /// Holds information about the various types of exception specification. | ||||||
3942 | /// ExceptionSpecInfo is not stored as such in FunctionProtoType but is | ||||||
3943 | /// used to group together the various bits of information about the | ||||||
3944 | /// exception specification. | ||||||
3945 | struct ExceptionSpecInfo { | ||||||
3946 | /// The kind of exception specification this is. | ||||||
3947 | ExceptionSpecificationType Type = EST_None; | ||||||
3948 | |||||||
3949 | /// Explicitly-specified list of exception types. | ||||||
3950 | ArrayRef<QualType> Exceptions; | ||||||
3951 | |||||||
3952 | /// Noexcept expression, if this is a computed noexcept specification. | ||||||
3953 | Expr *NoexceptExpr = nullptr; | ||||||
3954 | |||||||
3955 | /// The function whose exception specification this is, for | ||||||
3956 | /// EST_Unevaluated and EST_Uninstantiated. | ||||||
3957 | FunctionDecl *SourceDecl = nullptr; | ||||||
3958 | |||||||
3959 | /// The function template whose exception specification this is instantiated | ||||||
3960 | /// from, for EST_Uninstantiated. | ||||||
3961 | FunctionDecl *SourceTemplate = nullptr; | ||||||
3962 | |||||||
3963 | ExceptionSpecInfo() = default; | ||||||
3964 | |||||||
3965 | ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {} | ||||||
3966 | }; | ||||||
3967 | |||||||
3968 | /// Extra information about a function prototype. ExtProtoInfo is not | ||||||
3969 | /// stored as such in FunctionProtoType but is used to group together | ||||||
3970 | /// the various bits of extra information about a function prototype. | ||||||
3971 | struct ExtProtoInfo { | ||||||
3972 | FunctionType::ExtInfo ExtInfo; | ||||||
3973 | bool Variadic : 1; | ||||||
3974 | bool HasTrailingReturn : 1; | ||||||
3975 | Qualifiers TypeQuals; | ||||||
3976 | RefQualifierKind RefQualifier = RQ_None; | ||||||
3977 | ExceptionSpecInfo ExceptionSpec; | ||||||
3978 | const ExtParameterInfo *ExtParameterInfos = nullptr; | ||||||
3979 | SourceLocation EllipsisLoc; | ||||||
3980 | |||||||
3981 | ExtProtoInfo() : Variadic(false), HasTrailingReturn(false) {} | ||||||
3982 | |||||||
3983 | ExtProtoInfo(CallingConv CC) | ||||||
3984 | : ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {} | ||||||
3985 | |||||||
3986 | ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) { | ||||||
3987 | ExtProtoInfo Result(*this); | ||||||
3988 | Result.ExceptionSpec = ESI; | ||||||
3989 | return Result; | ||||||
3990 | } | ||||||
3991 | }; | ||||||
3992 | |||||||
3993 | private: | ||||||
3994 | unsigned numTrailingObjects(OverloadToken<QualType>) const { | ||||||
3995 | return getNumParams(); | ||||||
3996 | } | ||||||
3997 | |||||||
3998 | unsigned numTrailingObjects(OverloadToken<SourceLocation>) const { | ||||||
3999 | return isVariadic(); | ||||||
4000 | } | ||||||
4001 | |||||||
4002 | unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const { | ||||||
4003 | return hasExtraBitfields(); | ||||||
4004 | } | ||||||
4005 | |||||||
4006 | unsigned numTrailingObjects(OverloadToken<ExceptionType>) const { | ||||||
4007 | return getExceptionSpecSize().NumExceptionType; | ||||||
4008 | } | ||||||
4009 | |||||||
4010 | unsigned numTrailingObjects(OverloadToken<Expr *>) const { | ||||||
4011 | return getExceptionSpecSize().NumExprPtr; | ||||||
4012 | } | ||||||
4013 | |||||||
4014 | unsigned numTrailingObjects(OverloadToken<FunctionDecl *>) const { | ||||||
4015 | return getExceptionSpecSize().NumFunctionDeclPtr; | ||||||
4016 | } | ||||||
4017 | |||||||
4018 | unsigned numTrailingObjects(OverloadToken<ExtParameterInfo>) const { | ||||||
4019 | return hasExtParameterInfos() ? getNumParams() : 0; | ||||||
4020 | } | ||||||
4021 | |||||||
4022 | /// Determine whether there are any argument types that | ||||||
4023 | /// contain an unexpanded parameter pack. | ||||||
4024 | static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, | ||||||
4025 | unsigned numArgs) { | ||||||
4026 | for (unsigned Idx = 0; Idx < numArgs; ++Idx) | ||||||
4027 | if (ArgArray[Idx]->containsUnexpandedParameterPack()) | ||||||
4028 | return true; | ||||||
4029 | |||||||
4030 | return false; | ||||||
4031 | } | ||||||
4032 | |||||||
4033 | FunctionProtoType(QualType result, ArrayRef<QualType> params, | ||||||
4034 | QualType canonical, const ExtProtoInfo &epi); | ||||||
4035 | |||||||
4036 | /// This struct is returned by getExceptionSpecSize and is used to | ||||||
4037 | /// translate an ExceptionSpecificationType to the number and kind | ||||||
4038 | /// of trailing objects related to the exception specification. | ||||||
4039 | struct ExceptionSpecSizeHolder { | ||||||
4040 | unsigned NumExceptionType; | ||||||
4041 | unsigned NumExprPtr; | ||||||
4042 | unsigned NumFunctionDeclPtr; | ||||||
4043 | }; | ||||||
4044 | |||||||
4045 | /// Return the number and kind of trailing objects | ||||||
4046 | /// related to the exception specification. | ||||||
4047 | static ExceptionSpecSizeHolder | ||||||
4048 | getExceptionSpecSize(ExceptionSpecificationType EST, unsigned NumExceptions) { | ||||||
4049 | switch (EST) { | ||||||
4050 | case EST_None: | ||||||
4051 | case EST_DynamicNone: | ||||||
4052 | case EST_MSAny: | ||||||
4053 | case EST_BasicNoexcept: | ||||||
4054 | case EST_Unparsed: | ||||||
4055 | case EST_NoThrow: | ||||||
4056 | return {0, 0, 0}; | ||||||
4057 | |||||||
4058 | case EST_Dynamic: | ||||||
4059 | return {NumExceptions, 0, 0}; | ||||||
4060 | |||||||
4061 | case EST_DependentNoexcept: | ||||||
4062 | case EST_NoexceptFalse: | ||||||
4063 | case EST_NoexceptTrue: | ||||||
4064 | return {0, 1, 0}; | ||||||
4065 | |||||||
4066 | case EST_Uninstantiated: | ||||||
4067 | return {0, 0, 2}; | ||||||
4068 | |||||||
4069 | case EST_Unevaluated: | ||||||
4070 | return {0, 0, 1}; | ||||||
4071 | } | ||||||
4072 | llvm_unreachable("bad exception specification kind")::llvm::llvm_unreachable_internal("bad exception specification kind" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4072); | ||||||
4073 | } | ||||||
4074 | |||||||
4075 | /// Return the number and kind of trailing objects | ||||||
4076 | /// related to the exception specification. | ||||||
4077 | ExceptionSpecSizeHolder getExceptionSpecSize() const { | ||||||
4078 | return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions()); | ||||||
4079 | } | ||||||
4080 | |||||||
4081 | /// Whether the trailing FunctionTypeExtraBitfields is present. | ||||||
4082 | static bool hasExtraBitfields(ExceptionSpecificationType EST) { | ||||||
4083 | // If the exception spec type is EST_Dynamic then we have > 0 exception | ||||||
4084 | // types and the exact number is stored in FunctionTypeExtraBitfields. | ||||||
4085 | return EST == EST_Dynamic; | ||||||
4086 | } | ||||||
4087 | |||||||
4088 | /// Whether the trailing FunctionTypeExtraBitfields is present. | ||||||
4089 | bool hasExtraBitfields() const { | ||||||
4090 | return hasExtraBitfields(getExceptionSpecType()); | ||||||
4091 | } | ||||||
4092 | |||||||
4093 | bool hasExtQualifiers() const { | ||||||
4094 | return FunctionTypeBits.HasExtQuals; | ||||||
4095 | } | ||||||
4096 | |||||||
4097 | public: | ||||||
4098 | unsigned getNumParams() const { return FunctionTypeBits.NumParams; } | ||||||
4099 | |||||||
4100 | QualType getParamType(unsigned i) const { | ||||||
4101 | assert(i < getNumParams() && "invalid parameter index")(static_cast <bool> (i < getNumParams() && "invalid parameter index" ) ? void (0) : __assert_fail ("i < getNumParams() && \"invalid parameter index\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4101, __extension__ __PRETTY_FUNCTION__)); | ||||||
4102 | return param_type_begin()[i]; | ||||||
4103 | } | ||||||
4104 | |||||||
4105 | ArrayRef<QualType> getParamTypes() const { | ||||||
4106 | return llvm::makeArrayRef(param_type_begin(), param_type_end()); | ||||||
4107 | } | ||||||
4108 | |||||||
4109 | ExtProtoInfo getExtProtoInfo() const { | ||||||
4110 | ExtProtoInfo EPI; | ||||||
4111 | EPI.ExtInfo = getExtInfo(); | ||||||
4112 | EPI.Variadic = isVariadic(); | ||||||
4113 | EPI.EllipsisLoc = getEllipsisLoc(); | ||||||
4114 | EPI.HasTrailingReturn = hasTrailingReturn(); | ||||||
4115 | EPI.ExceptionSpec = getExceptionSpecInfo(); | ||||||
4116 | EPI.TypeQuals = getMethodQuals(); | ||||||
4117 | EPI.RefQualifier = getRefQualifier(); | ||||||
4118 | EPI.ExtParameterInfos = getExtParameterInfosOrNull(); | ||||||
4119 | return EPI; | ||||||
4120 | } | ||||||
4121 | |||||||
4122 | /// Get the kind of exception specification on this function. | ||||||
4123 | ExceptionSpecificationType getExceptionSpecType() const { | ||||||
4124 | return static_cast<ExceptionSpecificationType>( | ||||||
4125 | FunctionTypeBits.ExceptionSpecType); | ||||||
4126 | } | ||||||
4127 | |||||||
4128 | /// Return whether this function has any kind of exception spec. | ||||||
4129 | bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; } | ||||||
4130 | |||||||
4131 | /// Return whether this function has a dynamic (throw) exception spec. | ||||||
4132 | bool hasDynamicExceptionSpec() const { | ||||||
4133 | return isDynamicExceptionSpec(getExceptionSpecType()); | ||||||
4134 | } | ||||||
4135 | |||||||
4136 | /// Return whether this function has a noexcept exception spec. | ||||||
4137 | bool hasNoexceptExceptionSpec() const { | ||||||
4138 | return isNoexceptExceptionSpec(getExceptionSpecType()); | ||||||
4139 | } | ||||||
4140 | |||||||
4141 | /// Return whether this function has a dependent exception spec. | ||||||
4142 | bool hasDependentExceptionSpec() const; | ||||||
4143 | |||||||
4144 | /// Return whether this function has an instantiation-dependent exception | ||||||
4145 | /// spec. | ||||||
4146 | bool hasInstantiationDependentExceptionSpec() const; | ||||||
4147 | |||||||
4148 | /// Return all the available information about this type's exception spec. | ||||||
4149 | ExceptionSpecInfo getExceptionSpecInfo() const { | ||||||
4150 | ExceptionSpecInfo Result; | ||||||
4151 | Result.Type = getExceptionSpecType(); | ||||||
4152 | if (Result.Type == EST_Dynamic) { | ||||||
4153 | Result.Exceptions = exceptions(); | ||||||
4154 | } else if (isComputedNoexcept(Result.Type)) { | ||||||
4155 | Result.NoexceptExpr = getNoexceptExpr(); | ||||||
4156 | } else if (Result.Type == EST_Uninstantiated) { | ||||||
4157 | Result.SourceDecl = getExceptionSpecDecl(); | ||||||
4158 | Result.SourceTemplate = getExceptionSpecTemplate(); | ||||||
4159 | } else if (Result.Type == EST_Unevaluated) { | ||||||
4160 | Result.SourceDecl = getExceptionSpecDecl(); | ||||||
4161 | } | ||||||
4162 | return Result; | ||||||
4163 | } | ||||||
4164 | |||||||
4165 | /// Return the number of types in the exception specification. | ||||||
4166 | unsigned getNumExceptions() const { | ||||||
4167 | return getExceptionSpecType() == EST_Dynamic | ||||||
4168 | ? getTrailingObjects<FunctionTypeExtraBitfields>() | ||||||
4169 | ->NumExceptionType | ||||||
4170 | : 0; | ||||||
4171 | } | ||||||
4172 | |||||||
4173 | /// Return the ith exception type, where 0 <= i < getNumExceptions(). | ||||||
4174 | QualType getExceptionType(unsigned i) const { | ||||||
4175 | assert(i < getNumExceptions() && "Invalid exception number!")(static_cast <bool> (i < getNumExceptions() && "Invalid exception number!") ? void (0) : __assert_fail ("i < getNumExceptions() && \"Invalid exception number!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4175, __extension__ __PRETTY_FUNCTION__)); | ||||||
4176 | return exception_begin()[i]; | ||||||
4177 | } | ||||||
4178 | |||||||
4179 | /// Return the expression inside noexcept(expression), or a null pointer | ||||||
4180 | /// if there is none (because the exception spec is not of this form). | ||||||
4181 | Expr *getNoexceptExpr() const { | ||||||
4182 | if (!isComputedNoexcept(getExceptionSpecType())) | ||||||
4183 | return nullptr; | ||||||
4184 | return *getTrailingObjects<Expr *>(); | ||||||
4185 | } | ||||||
4186 | |||||||
4187 | /// If this function type has an exception specification which hasn't | ||||||
4188 | /// been determined yet (either because it has not been evaluated or because | ||||||
4189 | /// it has not been instantiated), this is the function whose exception | ||||||
4190 | /// specification is represented by this type. | ||||||
4191 | FunctionDecl *getExceptionSpecDecl() const { | ||||||
4192 | if (getExceptionSpecType() != EST_Uninstantiated && | ||||||
4193 | getExceptionSpecType() != EST_Unevaluated) | ||||||
4194 | return nullptr; | ||||||
4195 | return getTrailingObjects<FunctionDecl *>()[0]; | ||||||
4196 | } | ||||||
4197 | |||||||
4198 | /// If this function type has an uninstantiated exception | ||||||
4199 | /// specification, this is the function whose exception specification | ||||||
4200 | /// should be instantiated to find the exception specification for | ||||||
4201 | /// this type. | ||||||
4202 | FunctionDecl *getExceptionSpecTemplate() const { | ||||||
4203 | if (getExceptionSpecType() != EST_Uninstantiated) | ||||||
4204 | return nullptr; | ||||||
4205 | return getTrailingObjects<FunctionDecl *>()[1]; | ||||||
4206 | } | ||||||
4207 | |||||||
4208 | /// Determine whether this function type has a non-throwing exception | ||||||
4209 | /// specification. | ||||||
4210 | CanThrowResult canThrow() const; | ||||||
4211 | |||||||
4212 | /// Determine whether this function type has a non-throwing exception | ||||||
4213 | /// specification. If this depends on template arguments, returns | ||||||
4214 | /// \c ResultIfDependent. | ||||||
4215 | bool isNothrow(bool ResultIfDependent = false) const { | ||||||
4216 | return ResultIfDependent ? canThrow() != CT_Can : canThrow() == CT_Cannot; | ||||||
4217 | } | ||||||
4218 | |||||||
4219 | /// Whether this function prototype is variadic. | ||||||
4220 | bool isVariadic() const { return FunctionTypeBits.Variadic; } | ||||||
4221 | |||||||
4222 | SourceLocation getEllipsisLoc() const { | ||||||
4223 | return isVariadic() ? *getTrailingObjects<SourceLocation>() | ||||||
4224 | : SourceLocation(); | ||||||
4225 | } | ||||||
4226 | |||||||
4227 | /// Determines whether this function prototype contains a | ||||||
4228 | /// parameter pack at the end. | ||||||
4229 | /// | ||||||
4230 | /// A function template whose last parameter is a parameter pack can be | ||||||
4231 | /// called with an arbitrary number of arguments, much like a variadic | ||||||
4232 | /// function. | ||||||
4233 | bool isTemplateVariadic() const; | ||||||
4234 | |||||||
4235 | /// Whether this function prototype has a trailing return type. | ||||||
4236 | bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; } | ||||||
4237 | |||||||
4238 | Qualifiers getMethodQuals() const { | ||||||
4239 | if (hasExtQualifiers()) | ||||||
4240 | return *getTrailingObjects<Qualifiers>(); | ||||||
4241 | else | ||||||
4242 | return getFastTypeQuals(); | ||||||
4243 | } | ||||||
4244 | |||||||
4245 | /// Retrieve the ref-qualifier associated with this function type. | ||||||
4246 | RefQualifierKind getRefQualifier() const { | ||||||
4247 | return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier); | ||||||
4248 | } | ||||||
4249 | |||||||
4250 | using param_type_iterator = const QualType *; | ||||||
4251 | using param_type_range = llvm::iterator_range<param_type_iterator>; | ||||||
4252 | |||||||
4253 | param_type_range param_types() const { | ||||||
4254 | return param_type_range(param_type_begin(), param_type_end()); | ||||||
4255 | } | ||||||
4256 | |||||||
4257 | param_type_iterator param_type_begin() const { | ||||||
4258 | return getTrailingObjects<QualType>(); | ||||||
4259 | } | ||||||
4260 | |||||||
4261 | param_type_iterator param_type_end() const { | ||||||
4262 | return param_type_begin() + getNumParams(); | ||||||
4263 | } | ||||||
4264 | |||||||
4265 | using exception_iterator = const QualType *; | ||||||
4266 | |||||||
4267 | ArrayRef<QualType> exceptions() const { | ||||||
4268 | return llvm::makeArrayRef(exception_begin(), exception_end()); | ||||||
4269 | } | ||||||
4270 | |||||||
4271 | exception_iterator exception_begin() const { | ||||||
4272 | return reinterpret_cast<exception_iterator>( | ||||||
4273 | getTrailingObjects<ExceptionType>()); | ||||||
4274 | } | ||||||
4275 | |||||||
4276 | exception_iterator exception_end() const { | ||||||
4277 | return exception_begin() + getNumExceptions(); | ||||||
4278 | } | ||||||
4279 | |||||||
4280 | /// Is there any interesting extra information for any of the parameters | ||||||
4281 | /// of this function type? | ||||||
4282 | bool hasExtParameterInfos() const { | ||||||
4283 | return FunctionTypeBits.HasExtParameterInfos; | ||||||
4284 | } | ||||||
4285 | |||||||
4286 | ArrayRef<ExtParameterInfo> getExtParameterInfos() const { | ||||||
4287 | assert(hasExtParameterInfos())(static_cast <bool> (hasExtParameterInfos()) ? void (0) : __assert_fail ("hasExtParameterInfos()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4287, __extension__ __PRETTY_FUNCTION__)); | ||||||
4288 | return ArrayRef<ExtParameterInfo>(getTrailingObjects<ExtParameterInfo>(), | ||||||
4289 | getNumParams()); | ||||||
4290 | } | ||||||
4291 | |||||||
4292 | /// Return a pointer to the beginning of the array of extra parameter | ||||||
4293 | /// information, if present, or else null if none of the parameters | ||||||
4294 | /// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos. | ||||||
4295 | const ExtParameterInfo *getExtParameterInfosOrNull() const { | ||||||
4296 | if (!hasExtParameterInfos()) | ||||||
4297 | return nullptr; | ||||||
4298 | return getTrailingObjects<ExtParameterInfo>(); | ||||||
4299 | } | ||||||
4300 | |||||||
4301 | ExtParameterInfo getExtParameterInfo(unsigned I) const { | ||||||
4302 | assert(I < getNumParams() && "parameter index out of range")(static_cast <bool> (I < getNumParams() && "parameter index out of range" ) ? void (0) : __assert_fail ("I < getNumParams() && \"parameter index out of range\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4302, __extension__ __PRETTY_FUNCTION__)); | ||||||
4303 | if (hasExtParameterInfos()) | ||||||
4304 | return getTrailingObjects<ExtParameterInfo>()[I]; | ||||||
4305 | return ExtParameterInfo(); | ||||||
4306 | } | ||||||
4307 | |||||||
4308 | ParameterABI getParameterABI(unsigned I) const { | ||||||
4309 | assert(I < getNumParams() && "parameter index out of range")(static_cast <bool> (I < getNumParams() && "parameter index out of range" ) ? void (0) : __assert_fail ("I < getNumParams() && \"parameter index out of range\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4309, __extension__ __PRETTY_FUNCTION__)); | ||||||
4310 | if (hasExtParameterInfos()) | ||||||
4311 | return getTrailingObjects<ExtParameterInfo>()[I].getABI(); | ||||||
4312 | return ParameterABI::Ordinary; | ||||||
4313 | } | ||||||
4314 | |||||||
4315 | bool isParamConsumed(unsigned I) const { | ||||||
4316 | assert(I < getNumParams() && "parameter index out of range")(static_cast <bool> (I < getNumParams() && "parameter index out of range" ) ? void (0) : __assert_fail ("I < getNumParams() && \"parameter index out of range\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4316, __extension__ __PRETTY_FUNCTION__)); | ||||||
4317 | if (hasExtParameterInfos()) | ||||||
4318 | return getTrailingObjects<ExtParameterInfo>()[I].isConsumed(); | ||||||
4319 | return false; | ||||||
4320 | } | ||||||
4321 | |||||||
4322 | bool isSugared() const { return false; } | ||||||
4323 | QualType desugar() const { return QualType(this, 0); } | ||||||
4324 | |||||||
4325 | void printExceptionSpecification(raw_ostream &OS, | ||||||
4326 | const PrintingPolicy &Policy) const; | ||||||
4327 | |||||||
4328 | static bool classof(const Type *T) { | ||||||
4329 | return T->getTypeClass() == FunctionProto; | ||||||
4330 | } | ||||||
4331 | |||||||
4332 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); | ||||||
4333 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, | ||||||
4334 | param_type_iterator ArgTys, unsigned NumArgs, | ||||||
4335 | const ExtProtoInfo &EPI, const ASTContext &Context, | ||||||
4336 | bool Canonical); | ||||||
4337 | }; | ||||||
4338 | |||||||
4339 | /// Represents the dependent type named by a dependently-scoped | ||||||
4340 | /// typename using declaration, e.g. | ||||||
4341 | /// using typename Base<T>::foo; | ||||||
4342 | /// | ||||||
4343 | /// Template instantiation turns these into the underlying type. | ||||||
4344 | class UnresolvedUsingType : public Type { | ||||||
4345 | friend class ASTContext; // ASTContext creates these. | ||||||
4346 | |||||||
4347 | UnresolvedUsingTypenameDecl *Decl; | ||||||
4348 | |||||||
4349 | UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) | ||||||
4350 | : Type(UnresolvedUsing, QualType(), | ||||||
4351 | TypeDependence::DependentInstantiation), | ||||||
4352 | Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {} | ||||||
4353 | |||||||
4354 | public: | ||||||
4355 | UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } | ||||||
4356 | |||||||
4357 | bool isSugared() const { return false; } | ||||||
4358 | QualType desugar() const { return QualType(this, 0); } | ||||||
4359 | |||||||
4360 | static bool classof(const Type *T) { | ||||||
4361 | return T->getTypeClass() == UnresolvedUsing; | ||||||
4362 | } | ||||||
4363 | |||||||
4364 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4365 | return Profile(ID, Decl); | ||||||
4366 | } | ||||||
4367 | |||||||
4368 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
4369 | UnresolvedUsingTypenameDecl *D) { | ||||||
4370 | ID.AddPointer(D); | ||||||
4371 | } | ||||||
4372 | }; | ||||||
4373 | |||||||
4374 | class TypedefType : public Type { | ||||||
4375 | TypedefNameDecl *Decl; | ||||||
4376 | |||||||
4377 | private: | ||||||
4378 | friend class ASTContext; // ASTContext creates these. | ||||||
4379 | |||||||
4380 | TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying, | ||||||
4381 | QualType can); | ||||||
4382 | |||||||
4383 | public: | ||||||
4384 | TypedefNameDecl *getDecl() const { return Decl; } | ||||||
4385 | |||||||
4386 | bool isSugared() const { return true; } | ||||||
4387 | QualType desugar() const; | ||||||
4388 | |||||||
4389 | static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } | ||||||
4390 | }; | ||||||
4391 | |||||||
4392 | /// Sugar type that represents a type that was qualified by a qualifier written | ||||||
4393 | /// as a macro invocation. | ||||||
4394 | class MacroQualifiedType : public Type { | ||||||
4395 | friend class ASTContext; // ASTContext creates these. | ||||||
4396 | |||||||
4397 | QualType UnderlyingTy; | ||||||
4398 | const IdentifierInfo *MacroII; | ||||||
4399 | |||||||
4400 | MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, | ||||||
4401 | const IdentifierInfo *MacroII) | ||||||
4402 | : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()), | ||||||
4403 | UnderlyingTy(UnderlyingTy), MacroII(MacroII) { | ||||||
4404 | assert(isa<AttributedType>(UnderlyingTy) &&(static_cast <bool> (isa<AttributedType>(UnderlyingTy ) && "Expected a macro qualified type to only wrap attributed types." ) ? void (0) : __assert_fail ("isa<AttributedType>(UnderlyingTy) && \"Expected a macro qualified type to only wrap attributed types.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4405, __extension__ __PRETTY_FUNCTION__)) | ||||||
4405 | "Expected a macro qualified type to only wrap attributed types.")(static_cast <bool> (isa<AttributedType>(UnderlyingTy ) && "Expected a macro qualified type to only wrap attributed types." ) ? void (0) : __assert_fail ("isa<AttributedType>(UnderlyingTy) && \"Expected a macro qualified type to only wrap attributed types.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4405, __extension__ __PRETTY_FUNCTION__)); | ||||||
4406 | } | ||||||
4407 | |||||||
4408 | public: | ||||||
4409 | const IdentifierInfo *getMacroIdentifier() const { return MacroII; } | ||||||
4410 | QualType getUnderlyingType() const { return UnderlyingTy; } | ||||||
4411 | |||||||
4412 | /// Return this attributed type's modified type with no qualifiers attached to | ||||||
4413 | /// it. | ||||||
4414 | QualType getModifiedType() const; | ||||||
4415 | |||||||
4416 | bool isSugared() const { return true; } | ||||||
4417 | QualType desugar() const; | ||||||
4418 | |||||||
4419 | static bool classof(const Type *T) { | ||||||
4420 | return T->getTypeClass() == MacroQualified; | ||||||
4421 | } | ||||||
4422 | }; | ||||||
4423 | |||||||
4424 | /// Represents a `typeof` (or __typeof__) expression (a GCC extension). | ||||||
4425 | class TypeOfExprType : public Type { | ||||||
4426 | Expr *TOExpr; | ||||||
4427 | |||||||
4428 | protected: | ||||||
4429 | friend class ASTContext; // ASTContext creates these. | ||||||
4430 | |||||||
4431 | TypeOfExprType(Expr *E, QualType can = QualType()); | ||||||
4432 | |||||||
4433 | public: | ||||||
4434 | Expr *getUnderlyingExpr() const { return TOExpr; } | ||||||
4435 | |||||||
4436 | /// Remove a single level of sugar. | ||||||
4437 | QualType desugar() const; | ||||||
4438 | |||||||
4439 | /// Returns whether this type directly provides sugar. | ||||||
4440 | bool isSugared() const; | ||||||
4441 | |||||||
4442 | static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } | ||||||
4443 | }; | ||||||
4444 | |||||||
4445 | /// Internal representation of canonical, dependent | ||||||
4446 | /// `typeof(expr)` types. | ||||||
4447 | /// | ||||||
4448 | /// This class is used internally by the ASTContext to manage | ||||||
4449 | /// canonical, dependent types, only. Clients will only see instances | ||||||
4450 | /// of this class via TypeOfExprType nodes. | ||||||
4451 | class DependentTypeOfExprType | ||||||
4452 | : public TypeOfExprType, public llvm::FoldingSetNode { | ||||||
4453 | const ASTContext &Context; | ||||||
4454 | |||||||
4455 | public: | ||||||
4456 | DependentTypeOfExprType(const ASTContext &Context, Expr *E) | ||||||
4457 | : TypeOfExprType(E), Context(Context) {} | ||||||
4458 | |||||||
4459 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4460 | Profile(ID, Context, getUnderlyingExpr()); | ||||||
4461 | } | ||||||
4462 | |||||||
4463 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
4464 | Expr *E); | ||||||
4465 | }; | ||||||
4466 | |||||||
4467 | /// Represents `typeof(type)`, a GCC extension. | ||||||
4468 | class TypeOfType : public Type { | ||||||
4469 | friend class ASTContext; // ASTContext creates these. | ||||||
4470 | |||||||
4471 | QualType TOType; | ||||||
4472 | |||||||
4473 | TypeOfType(QualType T, QualType can) | ||||||
4474 | : Type(TypeOf, can, T->getDependence()), TOType(T) { | ||||||
4475 | assert(!isa<TypedefType>(can) && "Invalid canonical type")(static_cast <bool> (!isa<TypedefType>(can) && "Invalid canonical type") ? void (0) : __assert_fail ("!isa<TypedefType>(can) && \"Invalid canonical type\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4475, __extension__ __PRETTY_FUNCTION__)); | ||||||
4476 | } | ||||||
4477 | |||||||
4478 | public: | ||||||
4479 | QualType getUnderlyingType() const { return TOType; } | ||||||
4480 | |||||||
4481 | /// Remove a single level of sugar. | ||||||
4482 | QualType desugar() const { return getUnderlyingType(); } | ||||||
4483 | |||||||
4484 | /// Returns whether this type directly provides sugar. | ||||||
4485 | bool isSugared() const { return true; } | ||||||
4486 | |||||||
4487 | static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } | ||||||
4488 | }; | ||||||
4489 | |||||||
4490 | /// Represents the type `decltype(expr)` (C++11). | ||||||
4491 | class DecltypeType : public Type { | ||||||
4492 | Expr *E; | ||||||
4493 | QualType UnderlyingType; | ||||||
4494 | |||||||
4495 | protected: | ||||||
4496 | friend class ASTContext; // ASTContext creates these. | ||||||
4497 | |||||||
4498 | DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType()); | ||||||
4499 | |||||||
4500 | public: | ||||||
4501 | Expr *getUnderlyingExpr() const { return E; } | ||||||
4502 | QualType getUnderlyingType() const { return UnderlyingType; } | ||||||
4503 | |||||||
4504 | /// Remove a single level of sugar. | ||||||
4505 | QualType desugar() const; | ||||||
4506 | |||||||
4507 | /// Returns whether this type directly provides sugar. | ||||||
4508 | bool isSugared() const; | ||||||
4509 | |||||||
4510 | static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } | ||||||
4511 | }; | ||||||
4512 | |||||||
4513 | /// Internal representation of canonical, dependent | ||||||
4514 | /// decltype(expr) types. | ||||||
4515 | /// | ||||||
4516 | /// This class is used internally by the ASTContext to manage | ||||||
4517 | /// canonical, dependent types, only. Clients will only see instances | ||||||
4518 | /// of this class via DecltypeType nodes. | ||||||
4519 | class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { | ||||||
4520 | const ASTContext &Context; | ||||||
4521 | |||||||
4522 | public: | ||||||
4523 | DependentDecltypeType(const ASTContext &Context, Expr *E); | ||||||
4524 | |||||||
4525 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4526 | Profile(ID, Context, getUnderlyingExpr()); | ||||||
4527 | } | ||||||
4528 | |||||||
4529 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
4530 | Expr *E); | ||||||
4531 | }; | ||||||
4532 | |||||||
4533 | /// A unary type transform, which is a type constructed from another. | ||||||
4534 | class UnaryTransformType : public Type { | ||||||
4535 | public: | ||||||
4536 | enum UTTKind { | ||||||
4537 | EnumUnderlyingType | ||||||
4538 | }; | ||||||
4539 | |||||||
4540 | private: | ||||||
4541 | /// The untransformed type. | ||||||
4542 | QualType BaseType; | ||||||
4543 | |||||||
4544 | /// The transformed type if not dependent, otherwise the same as BaseType. | ||||||
4545 | QualType UnderlyingType; | ||||||
4546 | |||||||
4547 | UTTKind UKind; | ||||||
4548 | |||||||
4549 | protected: | ||||||
4550 | friend class ASTContext; | ||||||
4551 | |||||||
4552 | UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, | ||||||
4553 | QualType CanonicalTy); | ||||||
4554 | |||||||
4555 | public: | ||||||
4556 | bool isSugared() const { return !isDependentType(); } | ||||||
4557 | QualType desugar() const { return UnderlyingType; } | ||||||
4558 | |||||||
4559 | QualType getUnderlyingType() const { return UnderlyingType; } | ||||||
4560 | QualType getBaseType() const { return BaseType; } | ||||||
4561 | |||||||
4562 | UTTKind getUTTKind() const { return UKind; } | ||||||
4563 | |||||||
4564 | static bool classof(const Type *T) { | ||||||
4565 | return T->getTypeClass() == UnaryTransform; | ||||||
4566 | } | ||||||
4567 | }; | ||||||
4568 | |||||||
4569 | /// Internal representation of canonical, dependent | ||||||
4570 | /// __underlying_type(type) types. | ||||||
4571 | /// | ||||||
4572 | /// This class is used internally by the ASTContext to manage | ||||||
4573 | /// canonical, dependent types, only. Clients will only see instances | ||||||
4574 | /// of this class via UnaryTransformType nodes. | ||||||
4575 | class DependentUnaryTransformType : public UnaryTransformType, | ||||||
4576 | public llvm::FoldingSetNode { | ||||||
4577 | public: | ||||||
4578 | DependentUnaryTransformType(const ASTContext &C, QualType BaseType, | ||||||
4579 | UTTKind UKind); | ||||||
4580 | |||||||
4581 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4582 | Profile(ID, getBaseType(), getUTTKind()); | ||||||
4583 | } | ||||||
4584 | |||||||
4585 | static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType, | ||||||
4586 | UTTKind UKind) { | ||||||
4587 | ID.AddPointer(BaseType.getAsOpaquePtr()); | ||||||
4588 | ID.AddInteger((unsigned)UKind); | ||||||
4589 | } | ||||||
4590 | }; | ||||||
4591 | |||||||
4592 | class TagType : public Type { | ||||||
4593 | friend class ASTReader; | ||||||
4594 | template <class T> friend class serialization::AbstractTypeReader; | ||||||
4595 | |||||||
4596 | /// Stores the TagDecl associated with this type. The decl may point to any | ||||||
4597 | /// TagDecl that declares the entity. | ||||||
4598 | TagDecl *decl; | ||||||
4599 | |||||||
4600 | protected: | ||||||
4601 | TagType(TypeClass TC, const TagDecl *D, QualType can); | ||||||
4602 | |||||||
4603 | public: | ||||||
4604 | TagDecl *getDecl() const; | ||||||
4605 | |||||||
4606 | /// Determines whether this type is in the process of being defined. | ||||||
4607 | bool isBeingDefined() const; | ||||||
4608 | |||||||
4609 | static bool classof(const Type *T) { | ||||||
4610 | return T->getTypeClass() == Enum || T->getTypeClass() == Record; | ||||||
4611 | } | ||||||
4612 | }; | ||||||
4613 | |||||||
4614 | /// A helper class that allows the use of isa/cast/dyncast | ||||||
4615 | /// to detect TagType objects of structs/unions/classes. | ||||||
4616 | class RecordType : public TagType { | ||||||
4617 | protected: | ||||||
4618 | friend class ASTContext; // ASTContext creates these. | ||||||
4619 | |||||||
4620 | explicit RecordType(const RecordDecl *D) | ||||||
4621 | : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) {} | ||||||
4622 | explicit RecordType(TypeClass TC, RecordDecl *D) | ||||||
4623 | : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) {} | ||||||
4624 | |||||||
4625 | public: | ||||||
4626 | RecordDecl *getDecl() const { | ||||||
4627 | return reinterpret_cast<RecordDecl*>(TagType::getDecl()); | ||||||
4628 | } | ||||||
4629 | |||||||
4630 | /// Recursively check all fields in the record for const-ness. If any field | ||||||
4631 | /// is declared const, return true. Otherwise, return false. | ||||||
4632 | bool hasConstFields() const; | ||||||
4633 | |||||||
4634 | bool isSugared() const { return false; } | ||||||
4635 | QualType desugar() const { return QualType(this, 0); } | ||||||
4636 | |||||||
4637 | static bool classof(const Type *T) { return T->getTypeClass() == Record; } | ||||||
4638 | }; | ||||||
4639 | |||||||
4640 | /// A helper class that allows the use of isa/cast/dyncast | ||||||
4641 | /// to detect TagType objects of enums. | ||||||
4642 | class EnumType : public TagType { | ||||||
4643 | friend class ASTContext; // ASTContext creates these. | ||||||
4644 | |||||||
4645 | explicit EnumType(const EnumDecl *D) | ||||||
4646 | : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) {} | ||||||
4647 | |||||||
4648 | public: | ||||||
4649 | EnumDecl *getDecl() const { | ||||||
4650 | return reinterpret_cast<EnumDecl*>(TagType::getDecl()); | ||||||
4651 | } | ||||||
4652 | |||||||
4653 | bool isSugared() const { return false; } | ||||||
4654 | QualType desugar() const { return QualType(this, 0); } | ||||||
4655 | |||||||
4656 | static bool classof(const Type *T) { return T->getTypeClass() == Enum; } | ||||||
4657 | }; | ||||||
4658 | |||||||
4659 | /// An attributed type is a type to which a type attribute has been applied. | ||||||
4660 | /// | ||||||
4661 | /// The "modified type" is the fully-sugared type to which the attributed | ||||||
4662 | /// type was applied; generally it is not canonically equivalent to the | ||||||
4663 | /// attributed type. The "equivalent type" is the minimally-desugared type | ||||||
4664 | /// which the type is canonically equivalent to. | ||||||
4665 | /// | ||||||
4666 | /// For example, in the following attributed type: | ||||||
4667 | /// int32_t __attribute__((vector_size(16))) | ||||||
4668 | /// - the modified type is the TypedefType for int32_t | ||||||
4669 | /// - the equivalent type is VectorType(16, int32_t) | ||||||
4670 | /// - the canonical type is VectorType(16, int) | ||||||
4671 | class AttributedType : public Type, public llvm::FoldingSetNode { | ||||||
4672 | public: | ||||||
4673 | using Kind = attr::Kind; | ||||||
4674 | |||||||
4675 | private: | ||||||
4676 | friend class ASTContext; // ASTContext creates these | ||||||
4677 | |||||||
4678 | QualType ModifiedType; | ||||||
4679 | QualType EquivalentType; | ||||||
4680 | |||||||
4681 | AttributedType(QualType canon, attr::Kind attrKind, QualType modified, | ||||||
4682 | QualType equivalent) | ||||||
4683 | : Type(Attributed, canon, equivalent->getDependence()), | ||||||
4684 | ModifiedType(modified), EquivalentType(equivalent) { | ||||||
4685 | AttributedTypeBits.AttrKind = attrKind; | ||||||
4686 | } | ||||||
4687 | |||||||
4688 | public: | ||||||
4689 | Kind getAttrKind() const { | ||||||
4690 | return static_cast<Kind>(AttributedTypeBits.AttrKind); | ||||||
4691 | } | ||||||
4692 | |||||||
4693 | QualType getModifiedType() const { return ModifiedType; } | ||||||
4694 | QualType getEquivalentType() const { return EquivalentType; } | ||||||
4695 | |||||||
4696 | bool isSugared() const { return true; } | ||||||
4697 | QualType desugar() const { return getEquivalentType(); } | ||||||
4698 | |||||||
4699 | /// Does this attribute behave like a type qualifier? | ||||||
4700 | /// | ||||||
4701 | /// A type qualifier adjusts a type to provide specialized rules for | ||||||
4702 | /// a specific object, like the standard const and volatile qualifiers. | ||||||
4703 | /// This includes attributes controlling things like nullability, | ||||||
4704 | /// address spaces, and ARC ownership. The value of the object is still | ||||||
4705 | /// largely described by the modified type. | ||||||
4706 | /// | ||||||
4707 | /// In contrast, many type attributes "rewrite" their modified type to | ||||||
4708 | /// produce a fundamentally different type, not necessarily related in any | ||||||
4709 | /// formalizable way to the original type. For example, calling convention | ||||||
4710 | /// and vector attributes are not simple type qualifiers. | ||||||
4711 | /// | ||||||
4712 | /// Type qualifiers are often, but not always, reflected in the canonical | ||||||
4713 | /// type. | ||||||
4714 | bool isQualifier() const; | ||||||
4715 | |||||||
4716 | bool isMSTypeSpec() const; | ||||||
4717 | |||||||
4718 | bool isCallingConv() const; | ||||||
4719 | |||||||
4720 | llvm::Optional<NullabilityKind> getImmediateNullability() const; | ||||||
4721 | |||||||
4722 | /// Retrieve the attribute kind corresponding to the given | ||||||
4723 | /// nullability kind. | ||||||
4724 | static Kind getNullabilityAttrKind(NullabilityKind kind) { | ||||||
4725 | switch (kind) { | ||||||
4726 | case NullabilityKind::NonNull: | ||||||
4727 | return attr::TypeNonNull; | ||||||
4728 | |||||||
4729 | case NullabilityKind::Nullable: | ||||||
4730 | return attr::TypeNullable; | ||||||
4731 | |||||||
4732 | case NullabilityKind::NullableResult: | ||||||
4733 | return attr::TypeNullableResult; | ||||||
4734 | |||||||
4735 | case NullabilityKind::Unspecified: | ||||||
4736 | return attr::TypeNullUnspecified; | ||||||
4737 | } | ||||||
4738 | llvm_unreachable("Unknown nullability kind.")::llvm::llvm_unreachable_internal("Unknown nullability kind." , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 4738); | ||||||
4739 | } | ||||||
4740 | |||||||
4741 | /// Strip off the top-level nullability annotation on the given | ||||||
4742 | /// type, if it's there. | ||||||
4743 | /// | ||||||
4744 | /// \param T The type to strip. If the type is exactly an | ||||||
4745 | /// AttributedType specifying nullability (without looking through | ||||||
4746 | /// type sugar), the nullability is returned and this type changed | ||||||
4747 | /// to the underlying modified type. | ||||||
4748 | /// | ||||||
4749 | /// \returns the top-level nullability, if present. | ||||||
4750 | static Optional<NullabilityKind> stripOuterNullability(QualType &T); | ||||||
4751 | |||||||
4752 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4753 | Profile(ID, getAttrKind(), ModifiedType, EquivalentType); | ||||||
4754 | } | ||||||
4755 | |||||||
4756 | static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind, | ||||||
4757 | QualType modified, QualType equivalent) { | ||||||
4758 | ID.AddInteger(attrKind); | ||||||
4759 | ID.AddPointer(modified.getAsOpaquePtr()); | ||||||
4760 | ID.AddPointer(equivalent.getAsOpaquePtr()); | ||||||
4761 | } | ||||||
4762 | |||||||
4763 | static bool classof(const Type *T) { | ||||||
4764 | return T->getTypeClass() == Attributed; | ||||||
4765 | } | ||||||
4766 | }; | ||||||
4767 | |||||||
4768 | class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { | ||||||
4769 | friend class ASTContext; // ASTContext creates these | ||||||
4770 | |||||||
4771 | // Helper data collector for canonical types. | ||||||
4772 | struct CanonicalTTPTInfo { | ||||||
4773 | unsigned Depth : 15; | ||||||
4774 | unsigned ParameterPack : 1; | ||||||
4775 | unsigned Index : 16; | ||||||
4776 | }; | ||||||
4777 | |||||||
4778 | union { | ||||||
4779 | // Info for the canonical type. | ||||||
4780 | CanonicalTTPTInfo CanTTPTInfo; | ||||||
4781 | |||||||
4782 | // Info for the non-canonical type. | ||||||
4783 | TemplateTypeParmDecl *TTPDecl; | ||||||
4784 | }; | ||||||
4785 | |||||||
4786 | /// Build a non-canonical type. | ||||||
4787 | TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) | ||||||
4788 | : Type(TemplateTypeParm, Canon, | ||||||
4789 | TypeDependence::DependentInstantiation | | ||||||
4790 | (Canon->getDependence() & TypeDependence::UnexpandedPack)), | ||||||
4791 | TTPDecl(TTPDecl) {} | ||||||
4792 | |||||||
4793 | /// Build the canonical type. | ||||||
4794 | TemplateTypeParmType(unsigned D, unsigned I, bool PP) | ||||||
4795 | : Type(TemplateTypeParm, QualType(this, 0), | ||||||
4796 | TypeDependence::DependentInstantiation | | ||||||
4797 | (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)) { | ||||||
4798 | CanTTPTInfo.Depth = D; | ||||||
4799 | CanTTPTInfo.Index = I; | ||||||
4800 | CanTTPTInfo.ParameterPack = PP; | ||||||
4801 | } | ||||||
4802 | |||||||
4803 | const CanonicalTTPTInfo& getCanTTPTInfo() const { | ||||||
4804 | QualType Can = getCanonicalTypeInternal(); | ||||||
4805 | return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo; | ||||||
4806 | } | ||||||
4807 | |||||||
4808 | public: | ||||||
4809 | unsigned getDepth() const { return getCanTTPTInfo().Depth; } | ||||||
4810 | unsigned getIndex() const { return getCanTTPTInfo().Index; } | ||||||
4811 | bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; } | ||||||
4812 | |||||||
4813 | TemplateTypeParmDecl *getDecl() const { | ||||||
4814 | return isCanonicalUnqualified() ? nullptr : TTPDecl; | ||||||
4815 | } | ||||||
4816 | |||||||
4817 | IdentifierInfo *getIdentifier() const; | ||||||
4818 | |||||||
4819 | bool isSugared() const { return false; } | ||||||
4820 | QualType desugar() const { return QualType(this, 0); } | ||||||
4821 | |||||||
4822 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4823 | Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl()); | ||||||
4824 | } | ||||||
4825 | |||||||
4826 | static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, | ||||||
4827 | unsigned Index, bool ParameterPack, | ||||||
4828 | TemplateTypeParmDecl *TTPDecl) { | ||||||
4829 | ID.AddInteger(Depth); | ||||||
4830 | ID.AddInteger(Index); | ||||||
4831 | ID.AddBoolean(ParameterPack); | ||||||
4832 | ID.AddPointer(TTPDecl); | ||||||
4833 | } | ||||||
4834 | |||||||
4835 | static bool classof(const Type *T) { | ||||||
4836 | return T->getTypeClass() == TemplateTypeParm; | ||||||
4837 | } | ||||||
4838 | }; | ||||||
4839 | |||||||
4840 | /// Represents the result of substituting a type for a template | ||||||
4841 | /// type parameter. | ||||||
4842 | /// | ||||||
4843 | /// Within an instantiated template, all template type parameters have | ||||||
4844 | /// been replaced with these. They are used solely to record that a | ||||||
4845 | /// type was originally written as a template type parameter; | ||||||
4846 | /// therefore they are never canonical. | ||||||
4847 | class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { | ||||||
4848 | friend class ASTContext; | ||||||
4849 | |||||||
4850 | // The original type parameter. | ||||||
4851 | const TemplateTypeParmType *Replaced; | ||||||
4852 | |||||||
4853 | SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) | ||||||
4854 | : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()), | ||||||
4855 | Replaced(Param) {} | ||||||
4856 | |||||||
4857 | public: | ||||||
4858 | /// Gets the template parameter that was substituted for. | ||||||
4859 | const TemplateTypeParmType *getReplacedParameter() const { | ||||||
4860 | return Replaced; | ||||||
4861 | } | ||||||
4862 | |||||||
4863 | /// Gets the type that was substituted for the template | ||||||
4864 | /// parameter. | ||||||
4865 | QualType getReplacementType() const { | ||||||
4866 | return getCanonicalTypeInternal(); | ||||||
4867 | } | ||||||
4868 | |||||||
4869 | bool isSugared() const { return true; } | ||||||
4870 | QualType desugar() const { return getReplacementType(); } | ||||||
4871 | |||||||
4872 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4873 | Profile(ID, getReplacedParameter(), getReplacementType()); | ||||||
4874 | } | ||||||
4875 | |||||||
4876 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
4877 | const TemplateTypeParmType *Replaced, | ||||||
4878 | QualType Replacement) { | ||||||
4879 | ID.AddPointer(Replaced); | ||||||
4880 | ID.AddPointer(Replacement.getAsOpaquePtr()); | ||||||
4881 | } | ||||||
4882 | |||||||
4883 | static bool classof(const Type *T) { | ||||||
4884 | return T->getTypeClass() == SubstTemplateTypeParm; | ||||||
4885 | } | ||||||
4886 | }; | ||||||
4887 | |||||||
4888 | /// Represents the result of substituting a set of types for a template | ||||||
4889 | /// type parameter pack. | ||||||
4890 | /// | ||||||
4891 | /// When a pack expansion in the source code contains multiple parameter packs | ||||||
4892 | /// and those parameter packs correspond to different levels of template | ||||||
4893 | /// parameter lists, this type node is used to represent a template type | ||||||
4894 | /// parameter pack from an outer level, which has already had its argument pack | ||||||
4895 | /// substituted but that still lives within a pack expansion that itself | ||||||
4896 | /// could not be instantiated. When actually performing a substitution into | ||||||
4897 | /// that pack expansion (e.g., when all template parameters have corresponding | ||||||
4898 | /// arguments), this type will be replaced with the \c SubstTemplateTypeParmType | ||||||
4899 | /// at the current pack substitution index. | ||||||
4900 | class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { | ||||||
4901 | friend class ASTContext; | ||||||
4902 | |||||||
4903 | /// The original type parameter. | ||||||
4904 | const TemplateTypeParmType *Replaced; | ||||||
4905 | |||||||
4906 | /// A pointer to the set of template arguments that this | ||||||
4907 | /// parameter pack is instantiated with. | ||||||
4908 | const TemplateArgument *Arguments; | ||||||
4909 | |||||||
4910 | SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, | ||||||
4911 | QualType Canon, | ||||||
4912 | const TemplateArgument &ArgPack); | ||||||
4913 | |||||||
4914 | public: | ||||||
4915 | IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); } | ||||||
4916 | |||||||
4917 | /// Gets the template parameter that was substituted for. | ||||||
4918 | const TemplateTypeParmType *getReplacedParameter() const { | ||||||
4919 | return Replaced; | ||||||
4920 | } | ||||||
4921 | |||||||
4922 | unsigned getNumArgs() const { | ||||||
4923 | return SubstTemplateTypeParmPackTypeBits.NumArgs; | ||||||
4924 | } | ||||||
4925 | |||||||
4926 | bool isSugared() const { return false; } | ||||||
4927 | QualType desugar() const { return QualType(this, 0); } | ||||||
4928 | |||||||
4929 | TemplateArgument getArgumentPack() const; | ||||||
4930 | |||||||
4931 | void Profile(llvm::FoldingSetNodeID &ID); | ||||||
4932 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
4933 | const TemplateTypeParmType *Replaced, | ||||||
4934 | const TemplateArgument &ArgPack); | ||||||
4935 | |||||||
4936 | static bool classof(const Type *T) { | ||||||
4937 | return T->getTypeClass() == SubstTemplateTypeParmPack; | ||||||
4938 | } | ||||||
4939 | }; | ||||||
4940 | |||||||
4941 | /// Common base class for placeholders for types that get replaced by | ||||||
4942 | /// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced | ||||||
4943 | /// class template types, and constrained type names. | ||||||
4944 | /// | ||||||
4945 | /// These types are usually a placeholder for a deduced type. However, before | ||||||
4946 | /// the initializer is attached, or (usually) if the initializer is | ||||||
4947 | /// type-dependent, there is no deduced type and the type is canonical. In | ||||||
4948 | /// the latter case, it is also a dependent type. | ||||||
4949 | class DeducedType : public Type { | ||||||
4950 | protected: | ||||||
4951 | DeducedType(TypeClass TC, QualType DeducedAsType, | ||||||
4952 | TypeDependence ExtraDependence) | ||||||
4953 | : Type(TC, | ||||||
4954 | // FIXME: Retain the sugared deduced type? | ||||||
4955 | DeducedAsType.isNull() ? QualType(this, 0) | ||||||
4956 | : DeducedAsType.getCanonicalType(), | ||||||
4957 | ExtraDependence | (DeducedAsType.isNull() | ||||||
4958 | ? TypeDependence::None | ||||||
4959 | : DeducedAsType->getDependence() & | ||||||
4960 | ~TypeDependence::VariablyModified)) {} | ||||||
4961 | |||||||
4962 | public: | ||||||
4963 | bool isSugared() const { return !isCanonicalUnqualified(); } | ||||||
4964 | QualType desugar() const { return getCanonicalTypeInternal(); } | ||||||
4965 | |||||||
4966 | /// Get the type deduced for this placeholder type, or null if it's | ||||||
4967 | /// either not been deduced or was deduced to a dependent type. | ||||||
4968 | QualType getDeducedType() const { | ||||||
4969 | return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType(); | ||||||
4970 | } | ||||||
4971 | bool isDeduced() const { | ||||||
4972 | return !isCanonicalUnqualified() || isDependentType(); | ||||||
4973 | } | ||||||
4974 | |||||||
4975 | static bool classof(const Type *T) { | ||||||
4976 | return T->getTypeClass() == Auto || | ||||||
4977 | T->getTypeClass() == DeducedTemplateSpecialization; | ||||||
4978 | } | ||||||
4979 | }; | ||||||
4980 | |||||||
4981 | /// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained | ||||||
4982 | /// by a type-constraint. | ||||||
4983 | class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode { | ||||||
4984 | friend class ASTContext; // ASTContext creates these | ||||||
4985 | |||||||
4986 | ConceptDecl *TypeConstraintConcept; | ||||||
4987 | |||||||
4988 | AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, | ||||||
4989 | TypeDependence ExtraDependence, ConceptDecl *CD, | ||||||
4990 | ArrayRef<TemplateArgument> TypeConstraintArgs); | ||||||
4991 | |||||||
4992 | const TemplateArgument *getArgBuffer() const { | ||||||
4993 | return reinterpret_cast<const TemplateArgument*>(this+1); | ||||||
4994 | } | ||||||
4995 | |||||||
4996 | TemplateArgument *getArgBuffer() { | ||||||
4997 | return reinterpret_cast<TemplateArgument*>(this+1); | ||||||
4998 | } | ||||||
4999 | |||||||
5000 | public: | ||||||
5001 | /// Retrieve the template arguments. | ||||||
5002 | const TemplateArgument *getArgs() const { | ||||||
5003 | return getArgBuffer(); | ||||||
5004 | } | ||||||
5005 | |||||||
5006 | /// Retrieve the number of template arguments. | ||||||
5007 | unsigned getNumArgs() const { | ||||||
5008 | return AutoTypeBits.NumArgs; | ||||||
5009 | } | ||||||
5010 | |||||||
5011 | const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h | ||||||
5012 | |||||||
5013 | ArrayRef<TemplateArgument> getTypeConstraintArguments() const { | ||||||
5014 | return {getArgs(), getNumArgs()}; | ||||||
5015 | } | ||||||
5016 | |||||||
5017 | ConceptDecl *getTypeConstraintConcept() const { | ||||||
5018 | return TypeConstraintConcept; | ||||||
5019 | } | ||||||
5020 | |||||||
5021 | bool isConstrained() const { | ||||||
5022 | return TypeConstraintConcept != nullptr; | ||||||
5023 | } | ||||||
5024 | |||||||
5025 | bool isDecltypeAuto() const { | ||||||
5026 | return getKeyword() == AutoTypeKeyword::DecltypeAuto; | ||||||
5027 | } | ||||||
5028 | |||||||
5029 | AutoTypeKeyword getKeyword() const { | ||||||
5030 | return (AutoTypeKeyword)AutoTypeBits.Keyword; | ||||||
5031 | } | ||||||
5032 | |||||||
5033 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { | ||||||
5034 | Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(), | ||||||
5035 | getTypeConstraintConcept(), getTypeConstraintArguments()); | ||||||
5036 | } | ||||||
5037 | |||||||
5038 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
5039 | QualType Deduced, AutoTypeKeyword Keyword, | ||||||
5040 | bool IsDependent, ConceptDecl *CD, | ||||||
5041 | ArrayRef<TemplateArgument> Arguments); | ||||||
5042 | |||||||
5043 | static bool classof(const Type *T) { | ||||||
5044 | return T->getTypeClass() == Auto; | ||||||
5045 | } | ||||||
5046 | }; | ||||||
5047 | |||||||
5048 | /// Represents a C++17 deduced template specialization type. | ||||||
5049 | class DeducedTemplateSpecializationType : public DeducedType, | ||||||
5050 | public llvm::FoldingSetNode { | ||||||
5051 | friend class ASTContext; // ASTContext creates these | ||||||
5052 | |||||||
5053 | /// The name of the template whose arguments will be deduced. | ||||||
5054 | TemplateName Template; | ||||||
5055 | |||||||
5056 | DeducedTemplateSpecializationType(TemplateName Template, | ||||||
5057 | QualType DeducedAsType, | ||||||
5058 | bool IsDeducedAsDependent) | ||||||
5059 | : DeducedType(DeducedTemplateSpecialization, DeducedAsType, | ||||||
5060 | toTypeDependence(Template.getDependence()) | | ||||||
5061 | (IsDeducedAsDependent | ||||||
5062 | ? TypeDependence::DependentInstantiation | ||||||
5063 | : TypeDependence::None)), | ||||||
5064 | Template(Template) {} | ||||||
5065 | |||||||
5066 | public: | ||||||
5067 | /// Retrieve the name of the template that we are deducing. | ||||||
5068 | TemplateName getTemplateName() const { return Template;} | ||||||
5069 | |||||||
5070 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
5071 | Profile(ID, getTemplateName(), getDeducedType(), isDependentType()); | ||||||
5072 | } | ||||||
5073 | |||||||
5074 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template, | ||||||
5075 | QualType Deduced, bool IsDependent) { | ||||||
5076 | Template.Profile(ID); | ||||||
5077 | ID.AddPointer(Deduced.getAsOpaquePtr()); | ||||||
5078 | ID.AddBoolean(IsDependent); | ||||||
5079 | } | ||||||
5080 | |||||||
5081 | static bool classof(const Type *T) { | ||||||
5082 | return T->getTypeClass() == DeducedTemplateSpecialization; | ||||||
5083 | } | ||||||
5084 | }; | ||||||
5085 | |||||||
5086 | /// Represents a type template specialization; the template | ||||||
5087 | /// must be a class template, a type alias template, or a template | ||||||
5088 | /// template parameter. A template which cannot be resolved to one of | ||||||
5089 | /// these, e.g. because it is written with a dependent scope | ||||||
5090 | /// specifier, is instead represented as a | ||||||
5091 | /// @c DependentTemplateSpecializationType. | ||||||
5092 | /// | ||||||
5093 | /// A non-dependent template specialization type is always "sugar", | ||||||
5094 | /// typically for a \c RecordType. For example, a class template | ||||||
5095 | /// specialization type of \c vector<int> will refer to a tag type for | ||||||
5096 | /// the instantiation \c std::vector<int, std::allocator<int>> | ||||||
5097 | /// | ||||||
5098 | /// Template specializations are dependent if either the template or | ||||||
5099 | /// any of the template arguments are dependent, in which case the | ||||||
5100 | /// type may also be canonical. | ||||||
5101 | /// | ||||||
5102 | /// Instances of this type are allocated with a trailing array of | ||||||
5103 | /// TemplateArguments, followed by a QualType representing the | ||||||
5104 | /// non-canonical aliased type when the template is a type alias | ||||||
5105 | /// template. | ||||||
5106 | class alignas(8) TemplateSpecializationType | ||||||
5107 | : public Type, | ||||||
5108 | public llvm::FoldingSetNode { | ||||||
5109 | friend class ASTContext; // ASTContext creates these | ||||||
5110 | |||||||
5111 | /// The name of the template being specialized. This is | ||||||
5112 | /// either a TemplateName::Template (in which case it is a | ||||||
5113 | /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a | ||||||
5114 | /// TypeAliasTemplateDecl*), a | ||||||
5115 | /// TemplateName::SubstTemplateTemplateParmPack, or a | ||||||
5116 | /// TemplateName::SubstTemplateTemplateParm (in which case the | ||||||
5117 | /// replacement must, recursively, be one of these). | ||||||
5118 | TemplateName Template; | ||||||
5119 | |||||||
5120 | TemplateSpecializationType(TemplateName T, | ||||||
5121 | ArrayRef<TemplateArgument> Args, | ||||||
5122 | QualType Canon, | ||||||
5123 | QualType Aliased); | ||||||
5124 | |||||||
5125 | public: | ||||||
5126 | /// Determine whether any of the given template arguments are dependent. | ||||||
5127 | /// | ||||||
5128 | /// The converted arguments should be supplied when known; whether an | ||||||
5129 | /// argument is dependent can depend on the conversions performed on it | ||||||
5130 | /// (for example, a 'const int' passed as a template argument might be | ||||||
5131 | /// dependent if the parameter is a reference but non-dependent if the | ||||||
5132 | /// parameter is an int). | ||||||
5133 | /// | ||||||
5134 | /// Note that the \p Args parameter is unused: this is intentional, to remind | ||||||
5135 | /// the caller that they need to pass in the converted arguments, not the | ||||||
5136 | /// specified arguments. | ||||||
5137 | static bool | ||||||
5138 | anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args, | ||||||
5139 | ArrayRef<TemplateArgument> Converted); | ||||||
5140 | static bool | ||||||
5141 | anyDependentTemplateArguments(const TemplateArgumentListInfo &, | ||||||
5142 | ArrayRef<TemplateArgument> Converted); | ||||||
5143 | static bool anyInstantiationDependentTemplateArguments( | ||||||
5144 | ArrayRef<TemplateArgumentLoc> Args); | ||||||
5145 | |||||||
5146 | /// True if this template specialization type matches a current | ||||||
5147 | /// instantiation in the context in which it is found. | ||||||
5148 | bool isCurrentInstantiation() const { | ||||||
5149 | return isa<InjectedClassNameType>(getCanonicalTypeInternal()); | ||||||
5150 | } | ||||||
5151 | |||||||
5152 | /// Determine if this template specialization type is for a type alias | ||||||
5153 | /// template that has been substituted. | ||||||
5154 | /// | ||||||
5155 | /// Nearly every template specialization type whose template is an alias | ||||||
5156 | /// template will be substituted. However, this is not the case when | ||||||
5157 | /// the specialization contains a pack expansion but the template alias | ||||||
5158 | /// does not have a corresponding parameter pack, e.g., | ||||||
5159 | /// | ||||||
5160 | /// \code | ||||||
5161 | /// template<typename T, typename U, typename V> struct S; | ||||||
5162 | /// template<typename T, typename U> using A = S<T, int, U>; | ||||||
5163 | /// template<typename... Ts> struct X { | ||||||
5164 | /// typedef A<Ts...> type; // not a type alias | ||||||
5165 | /// }; | ||||||
5166 | /// \endcode | ||||||
5167 | bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; } | ||||||
5168 | |||||||
5169 | /// Get the aliased type, if this is a specialization of a type alias | ||||||
5170 | /// template. | ||||||
5171 | QualType getAliasedType() const { | ||||||
5172 | assert(isTypeAlias() && "not a type alias template specialization")(static_cast <bool> (isTypeAlias() && "not a type alias template specialization" ) ? void (0) : __assert_fail ("isTypeAlias() && \"not a type alias template specialization\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5172, __extension__ __PRETTY_FUNCTION__)); | ||||||
5173 | return *reinterpret_cast<const QualType*>(end()); | ||||||
5174 | } | ||||||
5175 | |||||||
5176 | using iterator = const TemplateArgument *; | ||||||
5177 | |||||||
5178 | iterator begin() const { return getArgs(); } | ||||||
5179 | iterator end() const; // defined inline in TemplateBase.h | ||||||
5180 | |||||||
5181 | /// Retrieve the name of the template that we are specializing. | ||||||
5182 | TemplateName getTemplateName() const { return Template; } | ||||||
5183 | |||||||
5184 | /// Retrieve the template arguments. | ||||||
5185 | const TemplateArgument *getArgs() const { | ||||||
5186 | return reinterpret_cast<const TemplateArgument *>(this + 1); | ||||||
5187 | } | ||||||
5188 | |||||||
5189 | /// Retrieve the number of template arguments. | ||||||
5190 | unsigned getNumArgs() const { | ||||||
5191 | return TemplateSpecializationTypeBits.NumArgs; | ||||||
5192 | } | ||||||
5193 | |||||||
5194 | /// Retrieve a specific template argument as a type. | ||||||
5195 | /// \pre \c isArgType(Arg) | ||||||
5196 | const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h | ||||||
5197 | |||||||
5198 | ArrayRef<TemplateArgument> template_arguments() const { | ||||||
5199 | return {getArgs(), getNumArgs()}; | ||||||
5200 | } | ||||||
5201 | |||||||
5202 | bool isSugared() const { | ||||||
5203 | return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); | ||||||
5204 | } | ||||||
5205 | |||||||
5206 | QualType desugar() const { | ||||||
5207 | return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal(); | ||||||
5208 | } | ||||||
5209 | |||||||
5210 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { | ||||||
5211 | Profile(ID, Template, template_arguments(), Ctx); | ||||||
5212 | if (isTypeAlias()) | ||||||
5213 | getAliasedType().Profile(ID); | ||||||
5214 | } | ||||||
5215 | |||||||
5216 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, | ||||||
5217 | ArrayRef<TemplateArgument> Args, | ||||||
5218 | const ASTContext &Context); | ||||||
5219 | |||||||
5220 | static bool classof(const Type *T) { | ||||||
5221 | return T->getTypeClass() == TemplateSpecialization; | ||||||
5222 | } | ||||||
5223 | }; | ||||||
5224 | |||||||
5225 | /// Print a template argument list, including the '<' and '>' | ||||||
5226 | /// enclosing the template arguments. | ||||||
5227 | void printTemplateArgumentList(raw_ostream &OS, | ||||||
5228 | ArrayRef<TemplateArgument> Args, | ||||||
5229 | const PrintingPolicy &Policy, | ||||||
5230 | const TemplateParameterList *TPL = nullptr); | ||||||
5231 | |||||||
5232 | void printTemplateArgumentList(raw_ostream &OS, | ||||||
5233 | ArrayRef<TemplateArgumentLoc> Args, | ||||||
5234 | const PrintingPolicy &Policy, | ||||||
5235 | const TemplateParameterList *TPL = nullptr); | ||||||
5236 | |||||||
5237 | void printTemplateArgumentList(raw_ostream &OS, | ||||||
5238 | const TemplateArgumentListInfo &Args, | ||||||
5239 | const PrintingPolicy &Policy, | ||||||
5240 | const TemplateParameterList *TPL = nullptr); | ||||||
5241 | |||||||
5242 | /// The injected class name of a C++ class template or class | ||||||
5243 | /// template partial specialization. Used to record that a type was | ||||||
5244 | /// spelled with a bare identifier rather than as a template-id; the | ||||||
5245 | /// equivalent for non-templated classes is just RecordType. | ||||||
5246 | /// | ||||||
5247 | /// Injected class name types are always dependent. Template | ||||||
5248 | /// instantiation turns these into RecordTypes. | ||||||
5249 | /// | ||||||
5250 | /// Injected class name types are always canonical. This works | ||||||
5251 | /// because it is impossible to compare an injected class name type | ||||||
5252 | /// with the corresponding non-injected template type, for the same | ||||||
5253 | /// reason that it is impossible to directly compare template | ||||||
5254 | /// parameters from different dependent contexts: injected class name | ||||||
5255 | /// types can only occur within the scope of a particular templated | ||||||
5256 | /// declaration, and within that scope every template specialization | ||||||
5257 | /// will canonicalize to the injected class name (when appropriate | ||||||
5258 | /// according to the rules of the language). | ||||||
5259 | class InjectedClassNameType : public Type { | ||||||
5260 | friend class ASTContext; // ASTContext creates these. | ||||||
5261 | friend class ASTNodeImporter; | ||||||
5262 | friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not | ||||||
5263 | // currently suitable for AST reading, too much | ||||||
5264 | // interdependencies. | ||||||
5265 | template <class T> friend class serialization::AbstractTypeReader; | ||||||
5266 | |||||||
5267 | CXXRecordDecl *Decl; | ||||||
5268 | |||||||
5269 | /// The template specialization which this type represents. | ||||||
5270 | /// For example, in | ||||||
5271 | /// template <class T> class A { ... }; | ||||||
5272 | /// this is A<T>, whereas in | ||||||
5273 | /// template <class X, class Y> class A<B<X,Y> > { ... }; | ||||||
5274 | /// this is A<B<X,Y> >. | ||||||
5275 | /// | ||||||
5276 | /// It is always unqualified, always a template specialization type, | ||||||
5277 | /// and always dependent. | ||||||
5278 | QualType InjectedType; | ||||||
5279 | |||||||
5280 | InjectedClassNameType(CXXRecordDecl *D, QualType TST) | ||||||
5281 | : Type(InjectedClassName, QualType(), | ||||||
5282 | TypeDependence::DependentInstantiation), | ||||||
5283 | Decl(D), InjectedType(TST) { | ||||||
5284 | assert(isa<TemplateSpecializationType>(TST))(static_cast <bool> (isa<TemplateSpecializationType> (TST)) ? void (0) : __assert_fail ("isa<TemplateSpecializationType>(TST)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5284, __extension__ __PRETTY_FUNCTION__)); | ||||||
5285 | assert(!TST.hasQualifiers())(static_cast <bool> (!TST.hasQualifiers()) ? void (0) : __assert_fail ("!TST.hasQualifiers()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5285, __extension__ __PRETTY_FUNCTION__)); | ||||||
5286 | assert(TST->isDependentType())(static_cast <bool> (TST->isDependentType()) ? void ( 0) : __assert_fail ("TST->isDependentType()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5286, __extension__ __PRETTY_FUNCTION__)); | ||||||
5287 | } | ||||||
5288 | |||||||
5289 | public: | ||||||
5290 | QualType getInjectedSpecializationType() const { return InjectedType; } | ||||||
5291 | |||||||
5292 | const TemplateSpecializationType *getInjectedTST() const { | ||||||
5293 | return cast<TemplateSpecializationType>(InjectedType.getTypePtr()); | ||||||
5294 | } | ||||||
5295 | |||||||
5296 | TemplateName getTemplateName() const { | ||||||
5297 | return getInjectedTST()->getTemplateName(); | ||||||
5298 | } | ||||||
5299 | |||||||
5300 | CXXRecordDecl *getDecl() const; | ||||||
5301 | |||||||
5302 | bool isSugared() const { return false; } | ||||||
5303 | QualType desugar() const { return QualType(this, 0); } | ||||||
5304 | |||||||
5305 | static bool classof(const Type *T) { | ||||||
5306 | return T->getTypeClass() == InjectedClassName; | ||||||
5307 | } | ||||||
5308 | }; | ||||||
5309 | |||||||
5310 | /// The kind of a tag type. | ||||||
5311 | enum TagTypeKind { | ||||||
5312 | /// The "struct" keyword. | ||||||
5313 | TTK_Struct, | ||||||
5314 | |||||||
5315 | /// The "__interface" keyword. | ||||||
5316 | TTK_Interface, | ||||||
5317 | |||||||
5318 | /// The "union" keyword. | ||||||
5319 | TTK_Union, | ||||||
5320 | |||||||
5321 | /// The "class" keyword. | ||||||
5322 | TTK_Class, | ||||||
5323 | |||||||
5324 | /// The "enum" keyword. | ||||||
5325 | TTK_Enum | ||||||
5326 | }; | ||||||
5327 | |||||||
5328 | /// The elaboration keyword that precedes a qualified type name or | ||||||
5329 | /// introduces an elaborated-type-specifier. | ||||||
5330 | enum ElaboratedTypeKeyword { | ||||||
5331 | /// The "struct" keyword introduces the elaborated-type-specifier. | ||||||
5332 | ETK_Struct, | ||||||
5333 | |||||||
5334 | /// The "__interface" keyword introduces the elaborated-type-specifier. | ||||||
5335 | ETK_Interface, | ||||||
5336 | |||||||
5337 | /// The "union" keyword introduces the elaborated-type-specifier. | ||||||
5338 | ETK_Union, | ||||||
5339 | |||||||
5340 | /// The "class" keyword introduces the elaborated-type-specifier. | ||||||
5341 | ETK_Class, | ||||||
5342 | |||||||
5343 | /// The "enum" keyword introduces the elaborated-type-specifier. | ||||||
5344 | ETK_Enum, | ||||||
5345 | |||||||
5346 | /// The "typename" keyword precedes the qualified type name, e.g., | ||||||
5347 | /// \c typename T::type. | ||||||
5348 | ETK_Typename, | ||||||
5349 | |||||||
5350 | /// No keyword precedes the qualified type name. | ||||||
5351 | ETK_None | ||||||
5352 | }; | ||||||
5353 | |||||||
5354 | /// A helper class for Type nodes having an ElaboratedTypeKeyword. | ||||||
5355 | /// The keyword in stored in the free bits of the base class. | ||||||
5356 | /// Also provides a few static helpers for converting and printing | ||||||
5357 | /// elaborated type keyword and tag type kind enumerations. | ||||||
5358 | class TypeWithKeyword : public Type { | ||||||
5359 | protected: | ||||||
5360 | TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, | ||||||
5361 | QualType Canonical, TypeDependence Dependence) | ||||||
5362 | : Type(tc, Canonical, Dependence) { | ||||||
5363 | TypeWithKeywordBits.Keyword = Keyword; | ||||||
5364 | } | ||||||
5365 | |||||||
5366 | public: | ||||||
5367 | ElaboratedTypeKeyword getKeyword() const { | ||||||
5368 | return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword); | ||||||
5369 | } | ||||||
5370 | |||||||
5371 | /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword. | ||||||
5372 | static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec); | ||||||
5373 | |||||||
5374 | /// Converts a type specifier (DeclSpec::TST) into a tag type kind. | ||||||
5375 | /// It is an error to provide a type specifier which *isn't* a tag kind here. | ||||||
5376 | static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec); | ||||||
5377 | |||||||
5378 | /// Converts a TagTypeKind into an elaborated type keyword. | ||||||
5379 | static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag); | ||||||
5380 | |||||||
5381 | /// Converts an elaborated type keyword into a TagTypeKind. | ||||||
5382 | /// It is an error to provide an elaborated type keyword | ||||||
5383 | /// which *isn't* a tag kind here. | ||||||
5384 | static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword); | ||||||
5385 | |||||||
5386 | static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword); | ||||||
5387 | |||||||
5388 | static StringRef getKeywordName(ElaboratedTypeKeyword Keyword); | ||||||
5389 | |||||||
5390 | static StringRef getTagTypeKindName(TagTypeKind Kind) { | ||||||
5391 | return getKeywordName(getKeywordForTagTypeKind(Kind)); | ||||||
5392 | } | ||||||
5393 | |||||||
5394 | class CannotCastToThisType {}; | ||||||
5395 | static CannotCastToThisType classof(const Type *); | ||||||
5396 | }; | ||||||
5397 | |||||||
5398 | /// Represents a type that was referred to using an elaborated type | ||||||
5399 | /// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, | ||||||
5400 | /// or both. | ||||||
5401 | /// | ||||||
5402 | /// This type is used to keep track of a type name as written in the | ||||||
5403 | /// source code, including tag keywords and any nested-name-specifiers. | ||||||
5404 | /// The type itself is always "sugar", used to express what was written | ||||||
5405 | /// in the source code but containing no additional semantic information. | ||||||
5406 | class ElaboratedType final | ||||||
5407 | : public TypeWithKeyword, | ||||||
5408 | public llvm::FoldingSetNode, | ||||||
5409 | private llvm::TrailingObjects<ElaboratedType, TagDecl *> { | ||||||
5410 | friend class ASTContext; // ASTContext creates these | ||||||
5411 | friend TrailingObjects; | ||||||
5412 | |||||||
5413 | /// The nested name specifier containing the qualifier. | ||||||
5414 | NestedNameSpecifier *NNS; | ||||||
5415 | |||||||
5416 | /// The type that this qualified name refers to. | ||||||
5417 | QualType NamedType; | ||||||
5418 | |||||||
5419 | /// The (re)declaration of this tag type owned by this occurrence is stored | ||||||
5420 | /// as a trailing object if there is one. Use getOwnedTagDecl to obtain | ||||||
5421 | /// it, or obtain a null pointer if there is none. | ||||||
5422 | |||||||
5423 | ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, | ||||||
5424 | QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl) | ||||||
5425 | : TypeWithKeyword(Keyword, Elaborated, CanonType, | ||||||
5426 | // Any semantic dependence on the qualifier will have | ||||||
5427 | // been incorporated into NamedType. We still need to | ||||||
5428 | // track syntactic (instantiation / error / pack) | ||||||
5429 | // dependence on the qualifier. | ||||||
5430 | NamedType->getDependence() | | ||||||
5431 | (NNS ? toSyntacticDependence( | ||||||
5432 | toTypeDependence(NNS->getDependence())) | ||||||
5433 | : TypeDependence::None)), | ||||||
5434 | NNS(NNS), NamedType(NamedType) { | ||||||
5435 | ElaboratedTypeBits.HasOwnedTagDecl = false; | ||||||
5436 | if (OwnedTagDecl) { | ||||||
5437 | ElaboratedTypeBits.HasOwnedTagDecl = true; | ||||||
5438 | *getTrailingObjects<TagDecl *>() = OwnedTagDecl; | ||||||
5439 | } | ||||||
5440 | assert(!(Keyword == ETK_None && NNS == nullptr) &&(static_cast <bool> (!(Keyword == ETK_None && NNS == nullptr) && "ElaboratedType cannot have elaborated type keyword " "and name qualifier both null.") ? void (0) : __assert_fail ( "!(Keyword == ETK_None && NNS == nullptr) && \"ElaboratedType cannot have elaborated type keyword \" \"and name qualifier both null.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5442, __extension__ __PRETTY_FUNCTION__)) | ||||||
5441 | "ElaboratedType cannot have elaborated type keyword "(static_cast <bool> (!(Keyword == ETK_None && NNS == nullptr) && "ElaboratedType cannot have elaborated type keyword " "and name qualifier both null.") ? void (0) : __assert_fail ( "!(Keyword == ETK_None && NNS == nullptr) && \"ElaboratedType cannot have elaborated type keyword \" \"and name qualifier both null.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5442, __extension__ __PRETTY_FUNCTION__)) | ||||||
5442 | "and name qualifier both null.")(static_cast <bool> (!(Keyword == ETK_None && NNS == nullptr) && "ElaboratedType cannot have elaborated type keyword " "and name qualifier both null.") ? void (0) : __assert_fail ( "!(Keyword == ETK_None && NNS == nullptr) && \"ElaboratedType cannot have elaborated type keyword \" \"and name qualifier both null.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5442, __extension__ __PRETTY_FUNCTION__)); | ||||||
5443 | } | ||||||
5444 | |||||||
5445 | public: | ||||||
5446 | /// Retrieve the qualification on this type. | ||||||
5447 | NestedNameSpecifier *getQualifier() const { return NNS; } | ||||||
5448 | |||||||
5449 | /// Retrieve the type named by the qualified-id. | ||||||
5450 | QualType getNamedType() const { return NamedType; } | ||||||
5451 | |||||||
5452 | /// Remove a single level of sugar. | ||||||
5453 | QualType desugar() const { return getNamedType(); } | ||||||
5454 | |||||||
5455 | /// Returns whether this type directly provides sugar. | ||||||
5456 | bool isSugared() const { return true; } | ||||||
5457 | |||||||
5458 | /// Return the (re)declaration of this type owned by this occurrence of this | ||||||
5459 | /// type, or nullptr if there is none. | ||||||
5460 | TagDecl *getOwnedTagDecl() const { | ||||||
5461 | return ElaboratedTypeBits.HasOwnedTagDecl ? *getTrailingObjects<TagDecl *>() | ||||||
5462 | : nullptr; | ||||||
5463 | } | ||||||
5464 | |||||||
5465 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
5466 | Profile(ID, getKeyword(), NNS, NamedType, getOwnedTagDecl()); | ||||||
5467 | } | ||||||
5468 | |||||||
5469 | static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, | ||||||
5470 | NestedNameSpecifier *NNS, QualType NamedType, | ||||||
5471 | TagDecl *OwnedTagDecl) { | ||||||
5472 | ID.AddInteger(Keyword); | ||||||
5473 | ID.AddPointer(NNS); | ||||||
5474 | NamedType.Profile(ID); | ||||||
5475 | ID.AddPointer(OwnedTagDecl); | ||||||
5476 | } | ||||||
5477 | |||||||
5478 | static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; } | ||||||
5479 | }; | ||||||
5480 | |||||||
5481 | /// Represents a qualified type name for which the type name is | ||||||
5482 | /// dependent. | ||||||
5483 | /// | ||||||
5484 | /// DependentNameType represents a class of dependent types that involve a | ||||||
5485 | /// possibly dependent nested-name-specifier (e.g., "T::") followed by a | ||||||
5486 | /// name of a type. The DependentNameType may start with a "typename" (for a | ||||||
5487 | /// typename-specifier), "class", "struct", "union", or "enum" (for a | ||||||
5488 | /// dependent elaborated-type-specifier), or nothing (in contexts where we | ||||||
5489 | /// know that we must be referring to a type, e.g., in a base class specifier). | ||||||
5490 | /// Typically the nested-name-specifier is dependent, but in MSVC compatibility | ||||||
5491 | /// mode, this type is used with non-dependent names to delay name lookup until | ||||||
5492 | /// instantiation. | ||||||
5493 | class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { | ||||||
5494 | friend class ASTContext; // ASTContext creates these | ||||||
5495 | |||||||
5496 | /// The nested name specifier containing the qualifier. | ||||||
5497 | NestedNameSpecifier *NNS; | ||||||
5498 | |||||||
5499 | /// The type that this typename specifier refers to. | ||||||
5500 | const IdentifierInfo *Name; | ||||||
5501 | |||||||
5502 | DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, | ||||||
5503 | const IdentifierInfo *Name, QualType CanonType) | ||||||
5504 | : TypeWithKeyword(Keyword, DependentName, CanonType, | ||||||
5505 | TypeDependence::DependentInstantiation | | ||||||
5506 | toTypeDependence(NNS->getDependence())), | ||||||
5507 | NNS(NNS), Name(Name) {} | ||||||
5508 | |||||||
5509 | public: | ||||||
5510 | /// Retrieve the qualification on this type. | ||||||
5511 | NestedNameSpecifier *getQualifier() const { return NNS; } | ||||||
5512 | |||||||
5513 | /// Retrieve the type named by the typename specifier as an identifier. | ||||||
5514 | /// | ||||||
5515 | /// This routine will return a non-NULL identifier pointer when the | ||||||
5516 | /// form of the original typename was terminated by an identifier, | ||||||
5517 | /// e.g., "typename T::type". | ||||||
5518 | const IdentifierInfo *getIdentifier() const { | ||||||
5519 | return Name; | ||||||
5520 | } | ||||||
5521 | |||||||
5522 | bool isSugared() const { return false; } | ||||||
5523 | QualType desugar() const { return QualType(this, 0); } | ||||||
5524 | |||||||
5525 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
5526 | Profile(ID, getKeyword(), NNS, Name); | ||||||
5527 | } | ||||||
5528 | |||||||
5529 | static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, | ||||||
5530 | NestedNameSpecifier *NNS, const IdentifierInfo *Name) { | ||||||
5531 | ID.AddInteger(Keyword); | ||||||
5532 | ID.AddPointer(NNS); | ||||||
5533 | ID.AddPointer(Name); | ||||||
5534 | } | ||||||
5535 | |||||||
5536 | static bool classof(const Type *T) { | ||||||
5537 | return T->getTypeClass() == DependentName; | ||||||
5538 | } | ||||||
5539 | }; | ||||||
5540 | |||||||
5541 | /// Represents a template specialization type whose template cannot be | ||||||
5542 | /// resolved, e.g. | ||||||
5543 | /// A<T>::template B<T> | ||||||
5544 | class alignas(8) DependentTemplateSpecializationType | ||||||
5545 | : public TypeWithKeyword, | ||||||
5546 | public llvm::FoldingSetNode { | ||||||
5547 | friend class ASTContext; // ASTContext creates these | ||||||
5548 | |||||||
5549 | /// The nested name specifier containing the qualifier. | ||||||
5550 | NestedNameSpecifier *NNS; | ||||||
5551 | |||||||
5552 | /// The identifier of the template. | ||||||
5553 | const IdentifierInfo *Name; | ||||||
5554 | |||||||
5555 | DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, | ||||||
5556 | NestedNameSpecifier *NNS, | ||||||
5557 | const IdentifierInfo *Name, | ||||||
5558 | ArrayRef<TemplateArgument> Args, | ||||||
5559 | QualType Canon); | ||||||
5560 | |||||||
5561 | const TemplateArgument *getArgBuffer() const { | ||||||
5562 | return reinterpret_cast<const TemplateArgument*>(this+1); | ||||||
5563 | } | ||||||
5564 | |||||||
5565 | TemplateArgument *getArgBuffer() { | ||||||
5566 | return reinterpret_cast<TemplateArgument*>(this+1); | ||||||
5567 | } | ||||||
5568 | |||||||
5569 | public: | ||||||
5570 | NestedNameSpecifier *getQualifier() const { return NNS; } | ||||||
5571 | const IdentifierInfo *getIdentifier() const { return Name; } | ||||||
5572 | |||||||
5573 | /// Retrieve the template arguments. | ||||||
5574 | const TemplateArgument *getArgs() const { | ||||||
5575 | return getArgBuffer(); | ||||||
5576 | } | ||||||
5577 | |||||||
5578 | /// Retrieve the number of template arguments. | ||||||
5579 | unsigned getNumArgs() const { | ||||||
5580 | return DependentTemplateSpecializationTypeBits.NumArgs; | ||||||
5581 | } | ||||||
5582 | |||||||
5583 | const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h | ||||||
5584 | |||||||
5585 | ArrayRef<TemplateArgument> template_arguments() const { | ||||||
5586 | return {getArgs(), getNumArgs()}; | ||||||
5587 | } | ||||||
5588 | |||||||
5589 | using iterator = const TemplateArgument *; | ||||||
5590 | |||||||
5591 | iterator begin() const { return getArgs(); } | ||||||
5592 | iterator end() const; // inline in TemplateBase.h | ||||||
5593 | |||||||
5594 | bool isSugared() const { return false; } | ||||||
5595 | QualType desugar() const { return QualType(this, 0); } | ||||||
5596 | |||||||
5597 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { | ||||||
5598 | Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()}); | ||||||
5599 | } | ||||||
5600 | |||||||
5601 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
5602 | const ASTContext &Context, | ||||||
5603 | ElaboratedTypeKeyword Keyword, | ||||||
5604 | NestedNameSpecifier *Qualifier, | ||||||
5605 | const IdentifierInfo *Name, | ||||||
5606 | ArrayRef<TemplateArgument> Args); | ||||||
5607 | |||||||
5608 | static bool classof(const Type *T) { | ||||||
5609 | return T->getTypeClass() == DependentTemplateSpecialization; | ||||||
5610 | } | ||||||
5611 | }; | ||||||
5612 | |||||||
5613 | /// Represents a pack expansion of types. | ||||||
5614 | /// | ||||||
5615 | /// Pack expansions are part of C++11 variadic templates. A pack | ||||||
5616 | /// expansion contains a pattern, which itself contains one or more | ||||||
5617 | /// "unexpanded" parameter packs. When instantiated, a pack expansion | ||||||
5618 | /// produces a series of types, each instantiated from the pattern of | ||||||
5619 | /// the expansion, where the Ith instantiation of the pattern uses the | ||||||
5620 | /// Ith arguments bound to each of the unexpanded parameter packs. The | ||||||
5621 | /// pack expansion is considered to "expand" these unexpanded | ||||||
5622 | /// parameter packs. | ||||||
5623 | /// | ||||||
5624 | /// \code | ||||||
5625 | /// template<typename ...Types> struct tuple; | ||||||
5626 | /// | ||||||
5627 | /// template<typename ...Types> | ||||||
5628 | /// struct tuple_of_references { | ||||||
5629 | /// typedef tuple<Types&...> type; | ||||||
5630 | /// }; | ||||||
5631 | /// \endcode | ||||||
5632 | /// | ||||||
5633 | /// Here, the pack expansion \c Types&... is represented via a | ||||||
5634 | /// PackExpansionType whose pattern is Types&. | ||||||
5635 | class PackExpansionType : public Type, public llvm::FoldingSetNode { | ||||||
5636 | friend class ASTContext; // ASTContext creates these | ||||||
5637 | |||||||
5638 | /// The pattern of the pack expansion. | ||||||
5639 | QualType Pattern; | ||||||
5640 | |||||||
5641 | PackExpansionType(QualType Pattern, QualType Canon, | ||||||
5642 | Optional<unsigned> NumExpansions) | ||||||
5643 | : Type(PackExpansion, Canon, | ||||||
5644 | (Pattern->getDependence() | TypeDependence::Dependent | | ||||||
5645 | TypeDependence::Instantiation) & | ||||||
5646 | ~TypeDependence::UnexpandedPack), | ||||||
5647 | Pattern(Pattern) { | ||||||
5648 | PackExpansionTypeBits.NumExpansions = | ||||||
5649 | NumExpansions ? *NumExpansions + 1 : 0; | ||||||
5650 | } | ||||||
5651 | |||||||
5652 | public: | ||||||
5653 | /// Retrieve the pattern of this pack expansion, which is the | ||||||
5654 | /// type that will be repeatedly instantiated when instantiating the | ||||||
5655 | /// pack expansion itself. | ||||||
5656 | QualType getPattern() const { return Pattern; } | ||||||
5657 | |||||||
5658 | /// Retrieve the number of expansions that this pack expansion will | ||||||
5659 | /// generate, if known. | ||||||
5660 | Optional<unsigned> getNumExpansions() const { | ||||||
5661 | if (PackExpansionTypeBits.NumExpansions) | ||||||
5662 | return PackExpansionTypeBits.NumExpansions - 1; | ||||||
5663 | return None; | ||||||
5664 | } | ||||||
5665 | |||||||
5666 | bool isSugared() const { return false; } | ||||||
5667 | QualType desugar() const { return QualType(this, 0); } | ||||||
5668 | |||||||
5669 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
5670 | Profile(ID, getPattern(), getNumExpansions()); | ||||||
5671 | } | ||||||
5672 | |||||||
5673 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern, | ||||||
5674 | Optional<unsigned> NumExpansions) { | ||||||
5675 | ID.AddPointer(Pattern.getAsOpaquePtr()); | ||||||
5676 | ID.AddBoolean(NumExpansions.hasValue()); | ||||||
5677 | if (NumExpansions) | ||||||
5678 | ID.AddInteger(*NumExpansions); | ||||||
5679 | } | ||||||
5680 | |||||||
5681 | static bool classof(const Type *T) { | ||||||
5682 | return T->getTypeClass() == PackExpansion; | ||||||
5683 | } | ||||||
5684 | }; | ||||||
5685 | |||||||
5686 | /// This class wraps the list of protocol qualifiers. For types that can | ||||||
5687 | /// take ObjC protocol qualifers, they can subclass this class. | ||||||
5688 | template <class T> | ||||||
5689 | class ObjCProtocolQualifiers { | ||||||
5690 | protected: | ||||||
5691 | ObjCProtocolQualifiers() = default; | ||||||
5692 | |||||||
5693 | ObjCProtocolDecl * const *getProtocolStorage() const { | ||||||
5694 | return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage(); | ||||||
5695 | } | ||||||
5696 | |||||||
5697 | ObjCProtocolDecl **getProtocolStorage() { | ||||||
5698 | return static_cast<T*>(this)->getProtocolStorageImpl(); | ||||||
5699 | } | ||||||
5700 | |||||||
5701 | void setNumProtocols(unsigned N) { | ||||||
5702 | static_cast<T*>(this)->setNumProtocolsImpl(N); | ||||||
5703 | } | ||||||
5704 | |||||||
5705 | void initialize(ArrayRef<ObjCProtocolDecl *> protocols) { | ||||||
5706 | setNumProtocols(protocols.size()); | ||||||
5707 | assert(getNumProtocols() == protocols.size() &&(static_cast <bool> (getNumProtocols() == protocols.size () && "bitfield overflow in protocol count") ? void ( 0) : __assert_fail ("getNumProtocols() == protocols.size() && \"bitfield overflow in protocol count\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5708, __extension__ __PRETTY_FUNCTION__)) | ||||||
5708 | "bitfield overflow in protocol count")(static_cast <bool> (getNumProtocols() == protocols.size () && "bitfield overflow in protocol count") ? void ( 0) : __assert_fail ("getNumProtocols() == protocols.size() && \"bitfield overflow in protocol count\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5708, __extension__ __PRETTY_FUNCTION__)); | ||||||
5709 | if (!protocols.empty()) | ||||||
5710 | memcpy(getProtocolStorage(), protocols.data(), | ||||||
5711 | protocols.size() * sizeof(ObjCProtocolDecl*)); | ||||||
5712 | } | ||||||
5713 | |||||||
5714 | public: | ||||||
5715 | using qual_iterator = ObjCProtocolDecl * const *; | ||||||
5716 | using qual_range = llvm::iterator_range<qual_iterator>; | ||||||
5717 | |||||||
5718 | qual_range quals() const { return qual_range(qual_begin(), qual_end()); } | ||||||
5719 | qual_iterator qual_begin() const { return getProtocolStorage(); } | ||||||
5720 | qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); } | ||||||
5721 | |||||||
5722 | bool qual_empty() const { return getNumProtocols() == 0; } | ||||||
5723 | |||||||
5724 | /// Return the number of qualifying protocols in this type, or 0 if | ||||||
5725 | /// there are none. | ||||||
5726 | unsigned getNumProtocols() const { | ||||||
5727 | return static_cast<const T*>(this)->getNumProtocolsImpl(); | ||||||
5728 | } | ||||||
5729 | |||||||
5730 | /// Fetch a protocol by index. | ||||||
5731 | ObjCProtocolDecl *getProtocol(unsigned I) const { | ||||||
5732 | assert(I < getNumProtocols() && "Out-of-range protocol access")(static_cast <bool> (I < getNumProtocols() && "Out-of-range protocol access") ? void (0) : __assert_fail ( "I < getNumProtocols() && \"Out-of-range protocol access\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5732, __extension__ __PRETTY_FUNCTION__)); | ||||||
5733 | return qual_begin()[I]; | ||||||
5734 | } | ||||||
5735 | |||||||
5736 | /// Retrieve all of the protocol qualifiers. | ||||||
5737 | ArrayRef<ObjCProtocolDecl *> getProtocols() const { | ||||||
5738 | return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols()); | ||||||
5739 | } | ||||||
5740 | }; | ||||||
5741 | |||||||
5742 | /// Represents a type parameter type in Objective C. It can take | ||||||
5743 | /// a list of protocols. | ||||||
5744 | class ObjCTypeParamType : public Type, | ||||||
5745 | public ObjCProtocolQualifiers<ObjCTypeParamType>, | ||||||
5746 | public llvm::FoldingSetNode { | ||||||
5747 | friend class ASTContext; | ||||||
5748 | friend class ObjCProtocolQualifiers<ObjCTypeParamType>; | ||||||
5749 | |||||||
5750 | /// The number of protocols stored on this type. | ||||||
5751 | unsigned NumProtocols : 6; | ||||||
5752 | |||||||
5753 | ObjCTypeParamDecl *OTPDecl; | ||||||
5754 | |||||||
5755 | /// The protocols are stored after the ObjCTypeParamType node. In the | ||||||
5756 | /// canonical type, the list of protocols are sorted alphabetically | ||||||
5757 | /// and uniqued. | ||||||
5758 | ObjCProtocolDecl **getProtocolStorageImpl(); | ||||||
5759 | |||||||
5760 | /// Return the number of qualifying protocols in this interface type, | ||||||
5761 | /// or 0 if there are none. | ||||||
5762 | unsigned getNumProtocolsImpl() const { | ||||||
5763 | return NumProtocols; | ||||||
5764 | } | ||||||
5765 | |||||||
5766 | void setNumProtocolsImpl(unsigned N) { | ||||||
5767 | NumProtocols = N; | ||||||
5768 | } | ||||||
5769 | |||||||
5770 | ObjCTypeParamType(const ObjCTypeParamDecl *D, | ||||||
5771 | QualType can, | ||||||
5772 | ArrayRef<ObjCProtocolDecl *> protocols); | ||||||
5773 | |||||||
5774 | public: | ||||||
5775 | bool isSugared() const { return true; } | ||||||
5776 | QualType desugar() const { return getCanonicalTypeInternal(); } | ||||||
5777 | |||||||
5778 | static bool classof(const Type *T) { | ||||||
5779 | return T->getTypeClass() == ObjCTypeParam; | ||||||
5780 | } | ||||||
5781 | |||||||
5782 | void Profile(llvm::FoldingSetNodeID &ID); | ||||||
5783 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
5784 | const ObjCTypeParamDecl *OTPDecl, | ||||||
5785 | QualType CanonicalType, | ||||||
5786 | ArrayRef<ObjCProtocolDecl *> protocols); | ||||||
5787 | |||||||
5788 | ObjCTypeParamDecl *getDecl() const { return OTPDecl; } | ||||||
5789 | }; | ||||||
5790 | |||||||
5791 | /// Represents a class type in Objective C. | ||||||
5792 | /// | ||||||
5793 | /// Every Objective C type is a combination of a base type, a set of | ||||||
5794 | /// type arguments (optional, for parameterized classes) and a list of | ||||||
5795 | /// protocols. | ||||||
5796 | /// | ||||||
5797 | /// Given the following declarations: | ||||||
5798 | /// \code | ||||||
5799 | /// \@class C<T>; | ||||||
5800 | /// \@protocol P; | ||||||
5801 | /// \endcode | ||||||
5802 | /// | ||||||
5803 | /// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType | ||||||
5804 | /// with base C and no protocols. | ||||||
5805 | /// | ||||||
5806 | /// 'C<P>' is an unspecialized ObjCObjectType with base C and protocol list [P]. | ||||||
5807 | /// 'C<C*>' is a specialized ObjCObjectType with type arguments 'C*' and no | ||||||
5808 | /// protocol list. | ||||||
5809 | /// 'C<C*><P>' is a specialized ObjCObjectType with base C, type arguments 'C*', | ||||||
5810 | /// and protocol list [P]. | ||||||
5811 | /// | ||||||
5812 | /// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose | ||||||
5813 | /// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType | ||||||
5814 | /// and no protocols. | ||||||
5815 | /// | ||||||
5816 | /// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType | ||||||
5817 | /// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually | ||||||
5818 | /// this should get its own sugar class to better represent the source. | ||||||
5819 | class ObjCObjectType : public Type, | ||||||
5820 | public ObjCProtocolQualifiers<ObjCObjectType> { | ||||||
5821 | friend class ObjCProtocolQualifiers<ObjCObjectType>; | ||||||
5822 | |||||||
5823 | // ObjCObjectType.NumTypeArgs - the number of type arguments stored | ||||||
5824 | // after the ObjCObjectPointerType node. | ||||||
5825 | // ObjCObjectType.NumProtocols - the number of protocols stored | ||||||
5826 | // after the type arguments of ObjCObjectPointerType node. | ||||||
5827 | // | ||||||
5828 | // These protocols are those written directly on the type. If | ||||||
5829 | // protocol qualifiers ever become additive, the iterators will need | ||||||
5830 | // to get kindof complicated. | ||||||
5831 | // | ||||||
5832 | // In the canonical object type, these are sorted alphabetically | ||||||
5833 | // and uniqued. | ||||||
5834 | |||||||
5835 | /// Either a BuiltinType or an InterfaceType or sugar for either. | ||||||
5836 | QualType BaseType; | ||||||
5837 | |||||||
5838 | /// Cached superclass type. | ||||||
5839 | mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool> | ||||||
5840 | CachedSuperClassType; | ||||||
5841 | |||||||
5842 | QualType *getTypeArgStorage(); | ||||||
5843 | const QualType *getTypeArgStorage() const { | ||||||
5844 | return const_cast<ObjCObjectType *>(this)->getTypeArgStorage(); | ||||||
5845 | } | ||||||
5846 | |||||||
5847 | ObjCProtocolDecl **getProtocolStorageImpl(); | ||||||
5848 | /// Return the number of qualifying protocols in this interface type, | ||||||
5849 | /// or 0 if there are none. | ||||||
5850 | unsigned getNumProtocolsImpl() const { | ||||||
5851 | return ObjCObjectTypeBits.NumProtocols; | ||||||
5852 | } | ||||||
5853 | void setNumProtocolsImpl(unsigned N) { | ||||||
5854 | ObjCObjectTypeBits.NumProtocols = N; | ||||||
5855 | } | ||||||
5856 | |||||||
5857 | protected: | ||||||
5858 | enum Nonce_ObjCInterface { Nonce_ObjCInterface }; | ||||||
5859 | |||||||
5860 | ObjCObjectType(QualType Canonical, QualType Base, | ||||||
5861 | ArrayRef<QualType> typeArgs, | ||||||
5862 | ArrayRef<ObjCProtocolDecl *> protocols, | ||||||
5863 | bool isKindOf); | ||||||
5864 | |||||||
5865 | ObjCObjectType(enum Nonce_ObjCInterface) | ||||||
5866 | : Type(ObjCInterface, QualType(), TypeDependence::None), | ||||||
5867 | BaseType(QualType(this_(), 0)) { | ||||||
5868 | ObjCObjectTypeBits.NumProtocols = 0; | ||||||
5869 | ObjCObjectTypeBits.NumTypeArgs = 0; | ||||||
5870 | ObjCObjectTypeBits.IsKindOf = 0; | ||||||
5871 | } | ||||||
5872 | |||||||
5873 | void computeSuperClassTypeSlow() const; | ||||||
5874 | |||||||
5875 | public: | ||||||
5876 | /// Gets the base type of this object type. This is always (possibly | ||||||
5877 | /// sugar for) one of: | ||||||
5878 | /// - the 'id' builtin type (as opposed to the 'id' type visible to the | ||||||
5879 | /// user, which is a typedef for an ObjCObjectPointerType) | ||||||
5880 | /// - the 'Class' builtin type (same caveat) | ||||||
5881 | /// - an ObjCObjectType (currently always an ObjCInterfaceType) | ||||||
5882 | QualType getBaseType() const { return BaseType; } | ||||||
5883 | |||||||
5884 | bool isObjCId() const { | ||||||
5885 | return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId); | ||||||
5886 | } | ||||||
5887 | |||||||
5888 | bool isObjCClass() const { | ||||||
5889 | return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass); | ||||||
5890 | } | ||||||
5891 | |||||||
5892 | bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } | ||||||
5893 | bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } | ||||||
5894 | bool isObjCUnqualifiedIdOrClass() const { | ||||||
5895 | if (!qual_empty()) return false; | ||||||
5896 | if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>()) | ||||||
5897 | return T->getKind() == BuiltinType::ObjCId || | ||||||
5898 | T->getKind() == BuiltinType::ObjCClass; | ||||||
5899 | return false; | ||||||
5900 | } | ||||||
5901 | bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); } | ||||||
5902 | bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); } | ||||||
5903 | |||||||
5904 | /// Gets the interface declaration for this object type, if the base type | ||||||
5905 | /// really is an interface. | ||||||
5906 | ObjCInterfaceDecl *getInterface() const; | ||||||
5907 | |||||||
5908 | /// Determine whether this object type is "specialized", meaning | ||||||
5909 | /// that it has type arguments. | ||||||
5910 | bool isSpecialized() const; | ||||||
5911 | |||||||
5912 | /// Determine whether this object type was written with type arguments. | ||||||
5913 | bool isSpecializedAsWritten() const { | ||||||
5914 | return ObjCObjectTypeBits.NumTypeArgs > 0; | ||||||
5915 | } | ||||||
5916 | |||||||
5917 | /// Determine whether this object type is "unspecialized", meaning | ||||||
5918 | /// that it has no type arguments. | ||||||
5919 | bool isUnspecialized() const { return !isSpecialized(); } | ||||||
5920 | |||||||
5921 | /// Determine whether this object type is "unspecialized" as | ||||||
5922 | /// written, meaning that it has no type arguments. | ||||||
5923 | bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } | ||||||
5924 | |||||||
5925 | /// Retrieve the type arguments of this object type (semantically). | ||||||
5926 | ArrayRef<QualType> getTypeArgs() const; | ||||||
5927 | |||||||
5928 | /// Retrieve the type arguments of this object type as they were | ||||||
5929 | /// written. | ||||||
5930 | ArrayRef<QualType> getTypeArgsAsWritten() const { | ||||||
5931 | return llvm::makeArrayRef(getTypeArgStorage(), | ||||||
5932 | ObjCObjectTypeBits.NumTypeArgs); | ||||||
5933 | } | ||||||
5934 | |||||||
5935 | /// Whether this is a "__kindof" type as written. | ||||||
5936 | bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; } | ||||||
5937 | |||||||
5938 | /// Whether this ia a "__kindof" type (semantically). | ||||||
5939 | bool isKindOfType() const; | ||||||
5940 | |||||||
5941 | /// Retrieve the type of the superclass of this object type. | ||||||
5942 | /// | ||||||
5943 | /// This operation substitutes any type arguments into the | ||||||
5944 | /// superclass of the current class type, potentially producing a | ||||||
5945 | /// specialization of the superclass type. Produces a null type if | ||||||
5946 | /// there is no superclass. | ||||||
5947 | QualType getSuperClassType() const { | ||||||
5948 | if (!CachedSuperClassType.getInt()) | ||||||
5949 | computeSuperClassTypeSlow(); | ||||||
5950 | |||||||
5951 | assert(CachedSuperClassType.getInt() && "Superclass not set?")(static_cast <bool> (CachedSuperClassType.getInt() && "Superclass not set?") ? void (0) : __assert_fail ("CachedSuperClassType.getInt() && \"Superclass not set?\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 5951, __extension__ __PRETTY_FUNCTION__)); | ||||||
5952 | return QualType(CachedSuperClassType.getPointer(), 0); | ||||||
5953 | } | ||||||
5954 | |||||||
5955 | /// Strip off the Objective-C "kindof" type and (with it) any | ||||||
5956 | /// protocol qualifiers. | ||||||
5957 | QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const; | ||||||
5958 | |||||||
5959 | bool isSugared() const { return false; } | ||||||
5960 | QualType desugar() const { return QualType(this, 0); } | ||||||
5961 | |||||||
5962 | static bool classof(const Type *T) { | ||||||
5963 | return T->getTypeClass() == ObjCObject || | ||||||
5964 | T->getTypeClass() == ObjCInterface; | ||||||
5965 | } | ||||||
5966 | }; | ||||||
5967 | |||||||
5968 | /// A class providing a concrete implementation | ||||||
5969 | /// of ObjCObjectType, so as to not increase the footprint of | ||||||
5970 | /// ObjCInterfaceType. Code outside of ASTContext and the core type | ||||||
5971 | /// system should not reference this type. | ||||||
5972 | class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { | ||||||
5973 | friend class ASTContext; | ||||||
5974 | |||||||
5975 | // If anyone adds fields here, ObjCObjectType::getProtocolStorage() | ||||||
5976 | // will need to be modified. | ||||||
5977 | |||||||
5978 | ObjCObjectTypeImpl(QualType Canonical, QualType Base, | ||||||
5979 | ArrayRef<QualType> typeArgs, | ||||||
5980 | ArrayRef<ObjCProtocolDecl *> protocols, | ||||||
5981 | bool isKindOf) | ||||||
5982 | : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {} | ||||||
5983 | |||||||
5984 | public: | ||||||
5985 | void Profile(llvm::FoldingSetNodeID &ID); | ||||||
5986 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
5987 | QualType Base, | ||||||
5988 | ArrayRef<QualType> typeArgs, | ||||||
5989 | ArrayRef<ObjCProtocolDecl *> protocols, | ||||||
5990 | bool isKindOf); | ||||||
5991 | }; | ||||||
5992 | |||||||
5993 | inline QualType *ObjCObjectType::getTypeArgStorage() { | ||||||
5994 | return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1); | ||||||
5995 | } | ||||||
5996 | |||||||
5997 | inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() { | ||||||
5998 | return reinterpret_cast<ObjCProtocolDecl**>( | ||||||
5999 | getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs); | ||||||
6000 | } | ||||||
6001 | |||||||
6002 | inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() { | ||||||
6003 | return reinterpret_cast<ObjCProtocolDecl**>( | ||||||
6004 | static_cast<ObjCTypeParamType*>(this)+1); | ||||||
6005 | } | ||||||
6006 | |||||||
6007 | /// Interfaces are the core concept in Objective-C for object oriented design. | ||||||
6008 | /// They basically correspond to C++ classes. There are two kinds of interface | ||||||
6009 | /// types: normal interfaces like `NSString`, and qualified interfaces, which | ||||||
6010 | /// are qualified with a protocol list like `NSString<NSCopyable, NSAmazing>`. | ||||||
6011 | /// | ||||||
6012 | /// ObjCInterfaceType guarantees the following properties when considered | ||||||
6013 | /// as a subtype of its superclass, ObjCObjectType: | ||||||
6014 | /// - There are no protocol qualifiers. To reinforce this, code which | ||||||
6015 | /// tries to invoke the protocol methods via an ObjCInterfaceType will | ||||||
6016 | /// fail to compile. | ||||||
6017 | /// - It is its own base type. That is, if T is an ObjCInterfaceType*, | ||||||
6018 | /// T->getBaseType() == QualType(T, 0). | ||||||
6019 | class ObjCInterfaceType : public ObjCObjectType { | ||||||
6020 | friend class ASTContext; // ASTContext creates these. | ||||||
6021 | friend class ASTReader; | ||||||
6022 | friend class ObjCInterfaceDecl; | ||||||
6023 | template <class T> friend class serialization::AbstractTypeReader; | ||||||
6024 | |||||||
6025 | mutable ObjCInterfaceDecl *Decl; | ||||||
6026 | |||||||
6027 | ObjCInterfaceType(const ObjCInterfaceDecl *D) | ||||||
6028 | : ObjCObjectType(Nonce_ObjCInterface), | ||||||
6029 | Decl(const_cast<ObjCInterfaceDecl*>(D)) {} | ||||||
6030 | |||||||
6031 | public: | ||||||
6032 | /// Get the declaration of this interface. | ||||||
6033 | ObjCInterfaceDecl *getDecl() const { return Decl; } | ||||||
6034 | |||||||
6035 | bool isSugared() const { return false; } | ||||||
6036 | QualType desugar() const { return QualType(this, 0); } | ||||||
6037 | |||||||
6038 | static bool classof(const Type *T) { | ||||||
6039 | return T->getTypeClass() == ObjCInterface; | ||||||
6040 | } | ||||||
6041 | |||||||
6042 | // Nonsense to "hide" certain members of ObjCObjectType within this | ||||||
6043 | // class. People asking for protocols on an ObjCInterfaceType are | ||||||
6044 | // not going to get what they want: ObjCInterfaceTypes are | ||||||
6045 | // guaranteed to have no protocols. | ||||||
6046 | enum { | ||||||
6047 | qual_iterator, | ||||||
6048 | qual_begin, | ||||||
6049 | qual_end, | ||||||
6050 | getNumProtocols, | ||||||
6051 | getProtocol | ||||||
6052 | }; | ||||||
6053 | }; | ||||||
6054 | |||||||
6055 | inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { | ||||||
6056 | QualType baseType = getBaseType(); | ||||||
6057 | while (const auto *ObjT = baseType->getAs<ObjCObjectType>()) { | ||||||
6058 | if (const auto *T = dyn_cast<ObjCInterfaceType>(ObjT)) | ||||||
6059 | return T->getDecl(); | ||||||
6060 | |||||||
6061 | baseType = ObjT->getBaseType(); | ||||||
6062 | } | ||||||
6063 | |||||||
6064 | return nullptr; | ||||||
6065 | } | ||||||
6066 | |||||||
6067 | /// Represents a pointer to an Objective C object. | ||||||
6068 | /// | ||||||
6069 | /// These are constructed from pointer declarators when the pointee type is | ||||||
6070 | /// an ObjCObjectType (or sugar for one). In addition, the 'id' and 'Class' | ||||||
6071 | /// types are typedefs for these, and the protocol-qualified types 'id<P>' | ||||||
6072 | /// and 'Class<P>' are translated into these. | ||||||
6073 | /// | ||||||
6074 | /// Pointers to pointers to Objective C objects are still PointerTypes; | ||||||
6075 | /// only the first level of pointer gets it own type implementation. | ||||||
6076 | class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { | ||||||
6077 | friend class ASTContext; // ASTContext creates these. | ||||||
6078 | |||||||
6079 | QualType PointeeType; | ||||||
6080 | |||||||
6081 | ObjCObjectPointerType(QualType Canonical, QualType Pointee) | ||||||
6082 | : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()), | ||||||
6083 | PointeeType(Pointee) {} | ||||||
6084 | |||||||
6085 | public: | ||||||
6086 | /// Gets the type pointed to by this ObjC pointer. | ||||||
6087 | /// The result will always be an ObjCObjectType or sugar thereof. | ||||||
6088 | QualType getPointeeType() const { return PointeeType; } | ||||||
6089 | |||||||
6090 | /// Gets the type pointed to by this ObjC pointer. Always returns non-null. | ||||||
6091 | /// | ||||||
6092 | /// This method is equivalent to getPointeeType() except that | ||||||
6093 | /// it discards any typedefs (or other sugar) between this | ||||||
6094 | /// type and the "outermost" object type. So for: | ||||||
6095 | /// \code | ||||||
6096 | /// \@class A; \@protocol P; \@protocol Q; | ||||||
6097 | /// typedef A<P> AP; | ||||||
6098 | /// typedef A A1; | ||||||
6099 | /// typedef A1<P> A1P; | ||||||
6100 | /// typedef A1P<Q> A1PQ; | ||||||
6101 | /// \endcode | ||||||
6102 | /// For 'A*', getObjectType() will return 'A'. | ||||||
6103 | /// For 'A<P>*', getObjectType() will return 'A<P>'. | ||||||
6104 | /// For 'AP*', getObjectType() will return 'A<P>'. | ||||||
6105 | /// For 'A1*', getObjectType() will return 'A'. | ||||||
6106 | /// For 'A1<P>*', getObjectType() will return 'A1<P>'. | ||||||
6107 | /// For 'A1P*', getObjectType() will return 'A1<P>'. | ||||||
6108 | /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because | ||||||
6109 | /// adding protocols to a protocol-qualified base discards the | ||||||
6110 | /// old qualifiers (for now). But if it didn't, getObjectType() | ||||||
6111 | /// would return 'A1P<Q>' (and we'd have to make iterating over | ||||||
6112 | /// qualifiers more complicated). | ||||||
6113 | const ObjCObjectType *getObjectType() const { | ||||||
6114 | return PointeeType->castAs<ObjCObjectType>(); | ||||||
6115 | } | ||||||
6116 | |||||||
6117 | /// If this pointer points to an Objective C | ||||||
6118 | /// \@interface type, gets the type for that interface. Any protocol | ||||||
6119 | /// qualifiers on the interface are ignored. | ||||||
6120 | /// | ||||||
6121 | /// \return null if the base type for this pointer is 'id' or 'Class' | ||||||
6122 | const ObjCInterfaceType *getInterfaceType() const; | ||||||
6123 | |||||||
6124 | /// If this pointer points to an Objective \@interface | ||||||
6125 | /// type, gets the declaration for that interface. | ||||||
6126 | /// | ||||||
6127 | /// \return null if the base type for this pointer is 'id' or 'Class' | ||||||
6128 | ObjCInterfaceDecl *getInterfaceDecl() const { | ||||||
6129 | return getObjectType()->getInterface(); | ||||||
6130 | } | ||||||
6131 | |||||||
6132 | /// True if this is equivalent to the 'id' type, i.e. if | ||||||
6133 | /// its object type is the primitive 'id' type with no protocols. | ||||||
6134 | bool isObjCIdType() const { | ||||||
6135 | return getObjectType()->isObjCUnqualifiedId(); | ||||||
6136 | } | ||||||
6137 | |||||||
6138 | /// True if this is equivalent to the 'Class' type, | ||||||
6139 | /// i.e. if its object tive is the primitive 'Class' type with no protocols. | ||||||
6140 | bool isObjCClassType() const { | ||||||
6141 | return getObjectType()->isObjCUnqualifiedClass(); | ||||||
6142 | } | ||||||
6143 | |||||||
6144 | /// True if this is equivalent to the 'id' or 'Class' type, | ||||||
6145 | bool isObjCIdOrClassType() const { | ||||||
6146 | return getObjectType()->isObjCUnqualifiedIdOrClass(); | ||||||
6147 | } | ||||||
6148 | |||||||
6149 | /// True if this is equivalent to 'id<P>' for some non-empty set of | ||||||
6150 | /// protocols. | ||||||
6151 | bool isObjCQualifiedIdType() const { | ||||||
6152 | return getObjectType()->isObjCQualifiedId(); | ||||||
6153 | } | ||||||
6154 | |||||||
6155 | /// True if this is equivalent to 'Class<P>' for some non-empty set of | ||||||
6156 | /// protocols. | ||||||
6157 | bool isObjCQualifiedClassType() const { | ||||||
6158 | return getObjectType()->isObjCQualifiedClass(); | ||||||
6159 | } | ||||||
6160 | |||||||
6161 | /// Whether this is a "__kindof" type. | ||||||
6162 | bool isKindOfType() const { return getObjectType()->isKindOfType(); } | ||||||
6163 | |||||||
6164 | /// Whether this type is specialized, meaning that it has type arguments. | ||||||
6165 | bool isSpecialized() const { return getObjectType()->isSpecialized(); } | ||||||
6166 | |||||||
6167 | /// Whether this type is specialized, meaning that it has type arguments. | ||||||
6168 | bool isSpecializedAsWritten() const { | ||||||
6169 | return getObjectType()->isSpecializedAsWritten(); | ||||||
6170 | } | ||||||
6171 | |||||||
6172 | /// Whether this type is unspecialized, meaning that is has no type arguments. | ||||||
6173 | bool isUnspecialized() const { return getObjectType()->isUnspecialized(); } | ||||||
6174 | |||||||
6175 | /// Determine whether this object type is "unspecialized" as | ||||||
6176 | /// written, meaning that it has no type arguments. | ||||||
6177 | bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } | ||||||
6178 | |||||||
6179 | /// Retrieve the type arguments for this type. | ||||||
6180 | ArrayRef<QualType> getTypeArgs() const { | ||||||
6181 | return getObjectType()->getTypeArgs(); | ||||||
6182 | } | ||||||
6183 | |||||||
6184 | /// Retrieve the type arguments for this type. | ||||||
6185 | ArrayRef<QualType> getTypeArgsAsWritten() const { | ||||||
6186 | return getObjectType()->getTypeArgsAsWritten(); | ||||||
6187 | } | ||||||
6188 | |||||||
6189 | /// An iterator over the qualifiers on the object type. Provided | ||||||
6190 | /// for convenience. This will always iterate over the full set of | ||||||
6191 | /// protocols on a type, not just those provided directly. | ||||||
6192 | using qual_iterator = ObjCObjectType::qual_iterator; | ||||||
6193 | using qual_range = llvm::iterator_range<qual_iterator>; | ||||||
6194 | |||||||
6195 | qual_range quals() const { return qual_range(qual_begin(), qual_end()); } | ||||||
6196 | |||||||
6197 | qual_iterator qual_begin() const { | ||||||
6198 | return getObjectType()->qual_begin(); | ||||||
6199 | } | ||||||
6200 | |||||||
6201 | qual_iterator qual_end() const { | ||||||
6202 | return getObjectType()->qual_end(); | ||||||
6203 | } | ||||||
6204 | |||||||
6205 | bool qual_empty() const { return getObjectType()->qual_empty(); } | ||||||
6206 | |||||||
6207 | /// Return the number of qualifying protocols on the object type. | ||||||
6208 | unsigned getNumProtocols() const { | ||||||
6209 | return getObjectType()->getNumProtocols(); | ||||||
6210 | } | ||||||
6211 | |||||||
6212 | /// Retrieve a qualifying protocol by index on the object type. | ||||||
6213 | ObjCProtocolDecl *getProtocol(unsigned I) const { | ||||||
6214 | return getObjectType()->getProtocol(I); | ||||||
6215 | } | ||||||
6216 | |||||||
6217 | bool isSugared() const { return false; } | ||||||
6218 | QualType desugar() const { return QualType(this, 0); } | ||||||
6219 | |||||||
6220 | /// Retrieve the type of the superclass of this object pointer type. | ||||||
6221 | /// | ||||||
6222 | /// This operation substitutes any type arguments into the | ||||||
6223 | /// superclass of the current class type, potentially producing a | ||||||
6224 | /// pointer to a specialization of the superclass type. Produces a | ||||||
6225 | /// null type if there is no superclass. | ||||||
6226 | QualType getSuperClassType() const; | ||||||
6227 | |||||||
6228 | /// Strip off the Objective-C "kindof" type and (with it) any | ||||||
6229 | /// protocol qualifiers. | ||||||
6230 | const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals( | ||||||
6231 | const ASTContext &ctx) const; | ||||||
6232 | |||||||
6233 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6234 | Profile(ID, getPointeeType()); | ||||||
6235 | } | ||||||
6236 | |||||||
6237 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { | ||||||
6238 | ID.AddPointer(T.getAsOpaquePtr()); | ||||||
6239 | } | ||||||
6240 | |||||||
6241 | static bool classof(const Type *T) { | ||||||
6242 | return T->getTypeClass() == ObjCObjectPointer; | ||||||
6243 | } | ||||||
6244 | }; | ||||||
6245 | |||||||
6246 | class AtomicType : public Type, public llvm::FoldingSetNode { | ||||||
6247 | friend class ASTContext; // ASTContext creates these. | ||||||
6248 | |||||||
6249 | QualType ValueType; | ||||||
6250 | |||||||
6251 | AtomicType(QualType ValTy, QualType Canonical) | ||||||
6252 | : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {} | ||||||
6253 | |||||||
6254 | public: | ||||||
6255 | /// Gets the type contained by this atomic type, i.e. | ||||||
6256 | /// the type returned by performing an atomic load of this atomic type. | ||||||
6257 | QualType getValueType() const { return ValueType; } | ||||||
6258 | |||||||
6259 | bool isSugared() const { return false; } | ||||||
6260 | QualType desugar() const { return QualType(this, 0); } | ||||||
6261 | |||||||
6262 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6263 | Profile(ID, getValueType()); | ||||||
6264 | } | ||||||
6265 | |||||||
6266 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { | ||||||
6267 | ID.AddPointer(T.getAsOpaquePtr()); | ||||||
6268 | } | ||||||
6269 | |||||||
6270 | static bool classof(const Type *T) { | ||||||
6271 | return T->getTypeClass() == Atomic; | ||||||
6272 | } | ||||||
6273 | }; | ||||||
6274 | |||||||
6275 | /// PipeType - OpenCL20. | ||||||
6276 | class PipeType : public Type, public llvm::FoldingSetNode { | ||||||
6277 | friend class ASTContext; // ASTContext creates these. | ||||||
6278 | |||||||
6279 | QualType ElementType; | ||||||
6280 | bool isRead; | ||||||
6281 | |||||||
6282 | PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) | ||||||
6283 | : Type(Pipe, CanonicalPtr, elemType->getDependence()), | ||||||
6284 | ElementType(elemType), isRead(isRead) {} | ||||||
6285 | |||||||
6286 | public: | ||||||
6287 | QualType getElementType() const { return ElementType; } | ||||||
6288 | |||||||
6289 | bool isSugared() const { return false; } | ||||||
6290 | |||||||
6291 | QualType desugar() const { return QualType(this, 0); } | ||||||
6292 | |||||||
6293 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6294 | Profile(ID, getElementType(), isReadOnly()); | ||||||
6295 | } | ||||||
6296 | |||||||
6297 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T, bool isRead) { | ||||||
6298 | ID.AddPointer(T.getAsOpaquePtr()); | ||||||
6299 | ID.AddBoolean(isRead); | ||||||
6300 | } | ||||||
6301 | |||||||
6302 | static bool classof(const Type *T) { | ||||||
6303 | return T->getTypeClass() == Pipe; | ||||||
6304 | } | ||||||
6305 | |||||||
6306 | bool isReadOnly() const { return isRead; } | ||||||
6307 | }; | ||||||
6308 | |||||||
6309 | /// A fixed int type of a specified bitwidth. | ||||||
6310 | class ExtIntType final : public Type, public llvm::FoldingSetNode { | ||||||
6311 | friend class ASTContext; | ||||||
6312 | unsigned IsUnsigned : 1; | ||||||
6313 | unsigned NumBits : 24; | ||||||
6314 | |||||||
6315 | protected: | ||||||
6316 | ExtIntType(bool isUnsigned, unsigned NumBits); | ||||||
6317 | |||||||
6318 | public: | ||||||
6319 | bool isUnsigned() const { return IsUnsigned; } | ||||||
6320 | bool isSigned() const { return !IsUnsigned; } | ||||||
6321 | unsigned getNumBits() const { return NumBits; } | ||||||
6322 | |||||||
6323 | bool isSugared() const { return false; } | ||||||
6324 | QualType desugar() const { return QualType(this, 0); } | ||||||
6325 | |||||||
6326 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6327 | Profile(ID, isUnsigned(), getNumBits()); | ||||||
6328 | } | ||||||
6329 | |||||||
6330 | static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned, | ||||||
6331 | unsigned NumBits) { | ||||||
6332 | ID.AddBoolean(IsUnsigned); | ||||||
6333 | ID.AddInteger(NumBits); | ||||||
6334 | } | ||||||
6335 | |||||||
6336 | static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; } | ||||||
6337 | }; | ||||||
6338 | |||||||
6339 | class DependentExtIntType final : public Type, public llvm::FoldingSetNode { | ||||||
6340 | friend class ASTContext; | ||||||
6341 | const ASTContext &Context; | ||||||
6342 | llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned; | ||||||
6343 | |||||||
6344 | protected: | ||||||
6345 | DependentExtIntType(const ASTContext &Context, bool IsUnsigned, | ||||||
6346 | Expr *NumBits); | ||||||
6347 | |||||||
6348 | public: | ||||||
6349 | bool isUnsigned() const; | ||||||
6350 | bool isSigned() const { return !isUnsigned(); } | ||||||
6351 | Expr *getNumBitsExpr() const; | ||||||
6352 | |||||||
6353 | bool isSugared() const { return false; } | ||||||
6354 | QualType desugar() const { return QualType(this, 0); } | ||||||
6355 | |||||||
6356 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6357 | Profile(ID, Context, isUnsigned(), getNumBitsExpr()); | ||||||
6358 | } | ||||||
6359 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
6360 | bool IsUnsigned, Expr *NumBitsExpr); | ||||||
6361 | |||||||
6362 | static bool classof(const Type *T) { | ||||||
6363 | return T->getTypeClass() == DependentExtInt; | ||||||
6364 | } | ||||||
6365 | }; | ||||||
6366 | |||||||
6367 | /// A qualifier set is used to build a set of qualifiers. | ||||||
6368 | class QualifierCollector : public Qualifiers { | ||||||
6369 | public: | ||||||
6370 | QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {} | ||||||
6371 | |||||||
6372 | /// Collect any qualifiers on the given type and return an | ||||||
6373 | /// unqualified type. The qualifiers are assumed to be consistent | ||||||
6374 | /// with those already in the type. | ||||||
6375 | const Type *strip(QualType type) { | ||||||
6376 | addFastQualifiers(type.getLocalFastQualifiers()); | ||||||
6377 | if (!type.hasLocalNonFastQualifiers()) | ||||||
6378 | return type.getTypePtrUnsafe(); | ||||||
6379 | |||||||
6380 | const ExtQuals *extQuals = type.getExtQualsUnsafe(); | ||||||
6381 | addConsistentQualifiers(extQuals->getQualifiers()); | ||||||
6382 | return extQuals->getBaseType(); | ||||||
6383 | } | ||||||
6384 | |||||||
6385 | /// Apply the collected qualifiers to the given type. | ||||||
6386 | QualType apply(const ASTContext &Context, QualType QT) const; | ||||||
6387 | |||||||
6388 | /// Apply the collected qualifiers to the given type. | ||||||
6389 | QualType apply(const ASTContext &Context, const Type* T) const; | ||||||
6390 | }; | ||||||
6391 | |||||||
6392 | /// A container of type source information. | ||||||
6393 | /// | ||||||
6394 | /// A client can read the relevant info using TypeLoc wrappers, e.g: | ||||||
6395 | /// @code | ||||||
6396 | /// TypeLoc TL = TypeSourceInfo->getTypeLoc(); | ||||||
6397 | /// TL.getBeginLoc().print(OS, SrcMgr); | ||||||
6398 | /// @endcode | ||||||
6399 | class alignas(8) TypeSourceInfo { | ||||||
6400 | // Contains a memory block after the class, used for type source information, | ||||||
6401 | // allocated by ASTContext. | ||||||
6402 | friend class ASTContext; | ||||||
6403 | |||||||
6404 | QualType Ty; | ||||||
6405 | |||||||
6406 | TypeSourceInfo(QualType ty) : Ty(ty) {} | ||||||
6407 | |||||||
6408 | public: | ||||||
6409 | /// Return the type wrapped by this type source info. | ||||||
6410 | QualType getType() const { return Ty; } | ||||||
6411 | |||||||
6412 | /// Return the TypeLoc wrapper for the type source info. | ||||||
6413 | TypeLoc getTypeLoc() const; // implemented in TypeLoc.h | ||||||
6414 | |||||||
6415 | /// Override the type stored in this TypeSourceInfo. Use with caution! | ||||||
6416 | void overrideType(QualType T) { Ty = T; } | ||||||
6417 | }; | ||||||
6418 | |||||||
6419 | // Inline function definitions. | ||||||
6420 | |||||||
6421 | inline SplitQualType SplitQualType::getSingleStepDesugaredType() const { | ||||||
6422 | SplitQualType desugar = | ||||||
6423 | Ty->getLocallyUnqualifiedSingleStepDesugaredType().split(); | ||||||
6424 | desugar.Quals.addConsistentQualifiers(Quals); | ||||||
6425 | return desugar; | ||||||
6426 | } | ||||||
6427 | |||||||
6428 | inline const Type *QualType::getTypePtr() const { | ||||||
6429 | return getCommonPtr()->BaseType; | ||||||
6430 | } | ||||||
6431 | |||||||
6432 | inline const Type *QualType::getTypePtrOrNull() const { | ||||||
6433 | return (isNull() ? nullptr : getCommonPtr()->BaseType); | ||||||
6434 | } | ||||||
6435 | |||||||
6436 | inline SplitQualType QualType::split() const { | ||||||
6437 | if (!hasLocalNonFastQualifiers()) | ||||||
6438 | return SplitQualType(getTypePtrUnsafe(), | ||||||
6439 | Qualifiers::fromFastMask(getLocalFastQualifiers())); | ||||||
6440 | |||||||
6441 | const ExtQuals *eq = getExtQualsUnsafe(); | ||||||
6442 | Qualifiers qs = eq->getQualifiers(); | ||||||
6443 | qs.addFastQualifiers(getLocalFastQualifiers()); | ||||||
6444 | return SplitQualType(eq->getBaseType(), qs); | ||||||
6445 | } | ||||||
6446 | |||||||
6447 | inline Qualifiers QualType::getLocalQualifiers() const { | ||||||
6448 | Qualifiers Quals; | ||||||
6449 | if (hasLocalNonFastQualifiers()) | ||||||
6450 | Quals = getExtQualsUnsafe()->getQualifiers(); | ||||||
6451 | Quals.addFastQualifiers(getLocalFastQualifiers()); | ||||||
6452 | return Quals; | ||||||
6453 | } | ||||||
6454 | |||||||
6455 | inline Qualifiers QualType::getQualifiers() const { | ||||||
6456 | Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers(); | ||||||
6457 | quals.addFastQualifiers(getLocalFastQualifiers()); | ||||||
6458 | return quals; | ||||||
6459 | } | ||||||
6460 | |||||||
6461 | inline unsigned QualType::getCVRQualifiers() const { | ||||||
6462 | unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers(); | ||||||
6463 | cvr |= getLocalCVRQualifiers(); | ||||||
6464 | return cvr; | ||||||
6465 | } | ||||||
6466 | |||||||
6467 | inline QualType QualType::getCanonicalType() const { | ||||||
6468 | QualType canon = getCommonPtr()->CanonicalType; | ||||||
6469 | return canon.withFastQualifiers(getLocalFastQualifiers()); | ||||||
6470 | } | ||||||
6471 | |||||||
6472 | inline bool QualType::isCanonical() const { | ||||||
6473 | return getTypePtr()->isCanonicalUnqualified(); | ||||||
6474 | } | ||||||
6475 | |||||||
6476 | inline bool QualType::isCanonicalAsParam() const { | ||||||
6477 | if (!isCanonical()) return false; | ||||||
6478 | if (hasLocalQualifiers()) return false; | ||||||
6479 | |||||||
6480 | const Type *T = getTypePtr(); | ||||||
6481 | if (T->isVariablyModifiedType() && T->hasSizedVLAType()) | ||||||
6482 | return false; | ||||||
6483 | |||||||
6484 | return !isa<FunctionType>(T) && !isa<ArrayType>(T); | ||||||
6485 | } | ||||||
6486 | |||||||
6487 | inline bool QualType::isConstQualified() const { | ||||||
6488 | return isLocalConstQualified() || | ||||||
6489 | getCommonPtr()->CanonicalType.isLocalConstQualified(); | ||||||
6490 | } | ||||||
6491 | |||||||
6492 | inline bool QualType::isRestrictQualified() const { | ||||||
6493 | return isLocalRestrictQualified() || | ||||||
6494 | getCommonPtr()->CanonicalType.isLocalRestrictQualified(); | ||||||
6495 | } | ||||||
6496 | |||||||
6497 | |||||||
6498 | inline bool QualType::isVolatileQualified() const { | ||||||
6499 | return isLocalVolatileQualified() || | ||||||
6500 | getCommonPtr()->CanonicalType.isLocalVolatileQualified(); | ||||||
6501 | } | ||||||
6502 | |||||||
6503 | inline bool QualType::hasQualifiers() const { | ||||||
6504 | return hasLocalQualifiers() || | ||||||
6505 | getCommonPtr()->CanonicalType.hasLocalQualifiers(); | ||||||
6506 | } | ||||||
6507 | |||||||
6508 | inline QualType QualType::getUnqualifiedType() const { | ||||||
6509 | if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) | ||||||
6510 | return QualType(getTypePtr(), 0); | ||||||
6511 | |||||||
6512 | return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0); | ||||||
6513 | } | ||||||
6514 | |||||||
6515 | inline SplitQualType QualType::getSplitUnqualifiedType() const { | ||||||
6516 | if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) | ||||||
6517 | return split(); | ||||||
6518 | |||||||
6519 | return getSplitUnqualifiedTypeImpl(*this); | ||||||
6520 | } | ||||||
6521 | |||||||
6522 | inline void QualType::removeLocalConst() { | ||||||
6523 | removeLocalFastQualifiers(Qualifiers::Const); | ||||||
6524 | } | ||||||
6525 | |||||||
6526 | inline void QualType::removeLocalRestrict() { | ||||||
6527 | removeLocalFastQualifiers(Qualifiers::Restrict); | ||||||
6528 | } | ||||||
6529 | |||||||
6530 | inline void QualType::removeLocalVolatile() { | ||||||
6531 | removeLocalFastQualifiers(Qualifiers::Volatile); | ||||||
6532 | } | ||||||
6533 | |||||||
6534 | inline void QualType::removeLocalCVRQualifiers(unsigned Mask) { | ||||||
6535 | assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits")(static_cast <bool> (!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits") ? void (0) : __assert_fail ("!(Mask & ~Qualifiers::CVRMask) && \"mask has non-CVR bits\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 6535, __extension__ __PRETTY_FUNCTION__)); | ||||||
6536 | static_assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask, | ||||||
6537 | "Fast bits differ from CVR bits!"); | ||||||
6538 | |||||||
6539 | // Fast path: we don't need to touch the slow qualifiers. | ||||||
6540 | removeLocalFastQualifiers(Mask); | ||||||
6541 | } | ||||||
6542 | |||||||
6543 | /// Check if this type has any address space qualifier. | ||||||
6544 | inline bool QualType::hasAddressSpace() const { | ||||||
6545 | return getQualifiers().hasAddressSpace(); | ||||||
6546 | } | ||||||
6547 | |||||||
6548 | /// Return the address space of this type. | ||||||
6549 | inline LangAS QualType::getAddressSpace() const { | ||||||
6550 | return getQualifiers().getAddressSpace(); | ||||||
6551 | } | ||||||
6552 | |||||||
6553 | /// Return the gc attribute of this type. | ||||||
6554 | inline Qualifiers::GC QualType::getObjCGCAttr() const { | ||||||
6555 | return getQualifiers().getObjCGCAttr(); | ||||||
6556 | } | ||||||
6557 | |||||||
6558 | inline bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion() const { | ||||||
6559 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) | ||||||
6560 | return hasNonTrivialToPrimitiveDefaultInitializeCUnion(RD); | ||||||
6561 | return false; | ||||||
6562 | } | ||||||
6563 | |||||||
6564 | inline bool QualType::hasNonTrivialToPrimitiveDestructCUnion() const { | ||||||
6565 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) | ||||||
6566 | return hasNonTrivialToPrimitiveDestructCUnion(RD); | ||||||
6567 | return false; | ||||||
6568 | } | ||||||
6569 | |||||||
6570 | inline bool QualType::hasNonTrivialToPrimitiveCopyCUnion() const { | ||||||
6571 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) | ||||||
6572 | return hasNonTrivialToPrimitiveCopyCUnion(RD); | ||||||
6573 | return false; | ||||||
6574 | } | ||||||
6575 | |||||||
6576 | inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { | ||||||
6577 | if (const auto *PT = t.getAs<PointerType>()) { | ||||||
6578 | if (const auto *FT = PT->getPointeeType()->getAs<FunctionType>()) | ||||||
6579 | return FT->getExtInfo(); | ||||||
6580 | } else if (const auto *FT = t.getAs<FunctionType>()) | ||||||
6581 | return FT->getExtInfo(); | ||||||
6582 | |||||||
6583 | return FunctionType::ExtInfo(); | ||||||
6584 | } | ||||||
6585 | |||||||
6586 | inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { | ||||||
6587 | return getFunctionExtInfo(*t); | ||||||
6588 | } | ||||||
6589 | |||||||
6590 | /// Determine whether this type is more | ||||||
6591 | /// qualified than the Other type. For example, "const volatile int" | ||||||
6592 | /// is more qualified than "const int", "volatile int", and | ||||||
6593 | /// "int". However, it is not more qualified than "const volatile | ||||||
6594 | /// int". | ||||||
6595 | inline bool QualType::isMoreQualifiedThan(QualType other) const { | ||||||
6596 | Qualifiers MyQuals = getQualifiers(); | ||||||
6597 | Qualifiers OtherQuals = other.getQualifiers(); | ||||||
6598 | return (MyQuals != OtherQuals && MyQuals.compatiblyIncludes(OtherQuals)); | ||||||
6599 | } | ||||||
6600 | |||||||
6601 | /// Determine whether this type is at last | ||||||
6602 | /// as qualified as the Other type. For example, "const volatile | ||||||
6603 | /// int" is at least as qualified as "const int", "volatile int", | ||||||
6604 | /// "int", and "const volatile int". | ||||||
6605 | inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const { | ||||||
6606 | Qualifiers OtherQuals = other.getQualifiers(); | ||||||
6607 | |||||||
6608 | // Ignore __unaligned qualifier if this type is a void. | ||||||
6609 | if (getUnqualifiedType()->isVoidType()) | ||||||
6610 | OtherQuals.removeUnaligned(); | ||||||
6611 | |||||||
6612 | return getQualifiers().compatiblyIncludes(OtherQuals); | ||||||
6613 | } | ||||||
6614 | |||||||
6615 | /// If Type is a reference type (e.g., const | ||||||
6616 | /// int&), returns the type that the reference refers to ("const | ||||||
6617 | /// int"). Otherwise, returns the type itself. This routine is used | ||||||
6618 | /// throughout Sema to implement C++ 5p6: | ||||||
6619 | /// | ||||||
6620 | /// If an expression initially has the type "reference to T" (8.3.2, | ||||||
6621 | /// 8.5.3), the type is adjusted to "T" prior to any further | ||||||
6622 | /// analysis, the expression designates the object or function | ||||||
6623 | /// denoted by the reference, and the expression is an lvalue. | ||||||
6624 | inline QualType QualType::getNonReferenceType() const { | ||||||
6625 | if (const auto *RefType = (*this)->getAs<ReferenceType>()) | ||||||
6626 | return RefType->getPointeeType(); | ||||||
6627 | else | ||||||
6628 | return *this; | ||||||
6629 | } | ||||||
6630 | |||||||
6631 | inline bool QualType::isCForbiddenLValueType() const { | ||||||
6632 | return ((getTypePtr()->isVoidType() && !hasQualifiers()) || | ||||||
6633 | getTypePtr()->isFunctionType()); | ||||||
6634 | } | ||||||
6635 | |||||||
6636 | /// Tests whether the type is categorized as a fundamental type. | ||||||
6637 | /// | ||||||
6638 | /// \returns True for types specified in C++0x [basic.fundamental]. | ||||||
6639 | inline bool Type::isFundamentalType() const { | ||||||
6640 | return isVoidType() || | ||||||
6641 | isNullPtrType() || | ||||||
6642 | // FIXME: It's really annoying that we don't have an | ||||||
6643 | // 'isArithmeticType()' which agrees with the standard definition. | ||||||
6644 | (isArithmeticType() && !isEnumeralType()); | ||||||
6645 | } | ||||||
6646 | |||||||
6647 | /// Tests whether the type is categorized as a compound type. | ||||||
6648 | /// | ||||||
6649 | /// \returns True for types specified in C++0x [basic.compound]. | ||||||
6650 | inline bool Type::isCompoundType() const { | ||||||
6651 | // C++0x [basic.compound]p1: | ||||||
6652 | // Compound types can be constructed in the following ways: | ||||||
6653 | // -- arrays of objects of a given type [...]; | ||||||
6654 | return isArrayType() || | ||||||
6655 | // -- functions, which have parameters of given types [...]; | ||||||
6656 | isFunctionType() || | ||||||
6657 | // -- pointers to void or objects or functions [...]; | ||||||
6658 | isPointerType() || | ||||||
6659 | // -- references to objects or functions of a given type. [...] | ||||||
6660 | isReferenceType() || | ||||||
6661 | // -- classes containing a sequence of objects of various types, [...]; | ||||||
6662 | isRecordType() || | ||||||
6663 | // -- unions, which are classes capable of containing objects of different | ||||||
6664 | // types at different times; | ||||||
6665 | isUnionType() || | ||||||
6666 | // -- enumerations, which comprise a set of named constant values. [...]; | ||||||
6667 | isEnumeralType() || | ||||||
6668 | // -- pointers to non-static class members, [...]. | ||||||
6669 | isMemberPointerType(); | ||||||
6670 | } | ||||||
6671 | |||||||
6672 | inline bool Type::isFunctionType() const { | ||||||
6673 | return isa<FunctionType>(CanonicalType); | ||||||
6674 | } | ||||||
6675 | |||||||
6676 | inline bool Type::isPointerType() const { | ||||||
6677 | return isa<PointerType>(CanonicalType); | ||||||
6678 | } | ||||||
6679 | |||||||
6680 | inline bool Type::isAnyPointerType() const { | ||||||
6681 | return isPointerType() || isObjCObjectPointerType(); | ||||||
6682 | } | ||||||
6683 | |||||||
6684 | inline bool Type::isBlockPointerType() const { | ||||||
6685 | return isa<BlockPointerType>(CanonicalType); | ||||||
6686 | } | ||||||
6687 | |||||||
6688 | inline bool Type::isReferenceType() const { | ||||||
6689 | return isa<ReferenceType>(CanonicalType); | ||||||
6690 | } | ||||||
6691 | |||||||
6692 | inline bool Type::isLValueReferenceType() const { | ||||||
6693 | return isa<LValueReferenceType>(CanonicalType); | ||||||
6694 | } | ||||||
6695 | |||||||
6696 | inline bool Type::isRValueReferenceType() const { | ||||||
6697 | return isa<RValueReferenceType>(CanonicalType); | ||||||
6698 | } | ||||||
6699 | |||||||
6700 | inline bool Type::isObjectPointerType() const { | ||||||
6701 | // Note: an "object pointer type" is not the same thing as a pointer to an | ||||||
6702 | // object type; rather, it is a pointer to an object type or a pointer to cv | ||||||
6703 | // void. | ||||||
6704 | if (const auto *T = getAs<PointerType>()) | ||||||
6705 | return !T->getPointeeType()->isFunctionType(); | ||||||
6706 | else | ||||||
6707 | return false; | ||||||
6708 | } | ||||||
6709 | |||||||
6710 | inline bool Type::isFunctionPointerType() const { | ||||||
6711 | if (const auto *T = getAs<PointerType>()) | ||||||
6712 | return T->getPointeeType()->isFunctionType(); | ||||||
6713 | else | ||||||
6714 | return false; | ||||||
6715 | } | ||||||
6716 | |||||||
6717 | inline bool Type::isFunctionReferenceType() const { | ||||||
6718 | if (const auto *T = getAs<ReferenceType>()) | ||||||
6719 | return T->getPointeeType()->isFunctionType(); | ||||||
6720 | else | ||||||
6721 | return false; | ||||||
6722 | } | ||||||
6723 | |||||||
6724 | inline bool Type::isMemberPointerType() const { | ||||||
6725 | return isa<MemberPointerType>(CanonicalType); | ||||||
6726 | } | ||||||
6727 | |||||||
6728 | inline bool Type::isMemberFunctionPointerType() const { | ||||||
6729 | if (const auto *T = getAs<MemberPointerType>()) | ||||||
6730 | return T->isMemberFunctionPointer(); | ||||||
6731 | else | ||||||
6732 | return false; | ||||||
6733 | } | ||||||
6734 | |||||||
6735 | inline bool Type::isMemberDataPointerType() const { | ||||||
6736 | if (const auto *T = getAs<MemberPointerType>()) | ||||||
6737 | return T->isMemberDataPointer(); | ||||||
6738 | else | ||||||
6739 | return false; | ||||||
6740 | } | ||||||
6741 | |||||||
6742 | inline bool Type::isArrayType() const { | ||||||
6743 | return isa<ArrayType>(CanonicalType); | ||||||
6744 | } | ||||||
6745 | |||||||
6746 | inline bool Type::isConstantArrayType() const { | ||||||
6747 | return isa<ConstantArrayType>(CanonicalType); | ||||||
6748 | } | ||||||
6749 | |||||||
6750 | inline bool Type::isIncompleteArrayType() const { | ||||||
6751 | return isa<IncompleteArrayType>(CanonicalType); | ||||||
6752 | } | ||||||
6753 | |||||||
6754 | inline bool Type::isVariableArrayType() const { | ||||||
6755 | return isa<VariableArrayType>(CanonicalType); | ||||||
6756 | } | ||||||
6757 | |||||||
6758 | inline bool Type::isDependentSizedArrayType() const { | ||||||
6759 | return isa<DependentSizedArrayType>(CanonicalType); | ||||||
6760 | } | ||||||
6761 | |||||||
6762 | inline bool Type::isBuiltinType() const { | ||||||
6763 | return isa<BuiltinType>(CanonicalType); | ||||||
6764 | } | ||||||
6765 | |||||||
6766 | inline bool Type::isRecordType() const { | ||||||
6767 | return isa<RecordType>(CanonicalType); | ||||||
6768 | } | ||||||
6769 | |||||||
6770 | inline bool Type::isEnumeralType() const { | ||||||
6771 | return isa<EnumType>(CanonicalType); | ||||||
6772 | } | ||||||
6773 | |||||||
6774 | inline bool Type::isAnyComplexType() const { | ||||||
6775 | return isa<ComplexType>(CanonicalType); | ||||||
6776 | } | ||||||
6777 | |||||||
6778 | inline bool Type::isVectorType() const { | ||||||
6779 | return isa<VectorType>(CanonicalType); | ||||||
6780 | } | ||||||
6781 | |||||||
6782 | inline bool Type::isExtVectorType() const { | ||||||
6783 | return isa<ExtVectorType>(CanonicalType); | ||||||
6784 | } | ||||||
6785 | |||||||
6786 | inline bool Type::isMatrixType() const { | ||||||
6787 | return isa<MatrixType>(CanonicalType); | ||||||
6788 | } | ||||||
6789 | |||||||
6790 | inline bool Type::isConstantMatrixType() const { | ||||||
6791 | return isa<ConstantMatrixType>(CanonicalType); | ||||||
6792 | } | ||||||
6793 | |||||||
6794 | inline bool Type::isDependentAddressSpaceType() const { | ||||||
6795 | return isa<DependentAddressSpaceType>(CanonicalType); | ||||||
6796 | } | ||||||
6797 | |||||||
6798 | inline bool Type::isObjCObjectPointerType() const { | ||||||
6799 | return isa<ObjCObjectPointerType>(CanonicalType); | ||||||
6800 | } | ||||||
6801 | |||||||
6802 | inline bool Type::isObjCObjectType() const { | ||||||
6803 | return isa<ObjCObjectType>(CanonicalType); | ||||||
6804 | } | ||||||
6805 | |||||||
6806 | inline bool Type::isObjCObjectOrInterfaceType() const { | ||||||
6807 | return isa<ObjCInterfaceType>(CanonicalType) || | ||||||
6808 | isa<ObjCObjectType>(CanonicalType); | ||||||
6809 | } | ||||||
6810 | |||||||
6811 | inline bool Type::isAtomicType() const { | ||||||
6812 | return isa<AtomicType>(CanonicalType); | ||||||
6813 | } | ||||||
6814 | |||||||
6815 | inline bool Type::isUndeducedAutoType() const { | ||||||
6816 | return isa<AutoType>(CanonicalType); | ||||||
6817 | } | ||||||
6818 | |||||||
6819 | inline bool Type::isObjCQualifiedIdType() const { | ||||||
6820 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) | ||||||
6821 | return OPT->isObjCQualifiedIdType(); | ||||||
6822 | return false; | ||||||
6823 | } | ||||||
6824 | |||||||
6825 | inline bool Type::isObjCQualifiedClassType() const { | ||||||
6826 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) | ||||||
6827 | return OPT->isObjCQualifiedClassType(); | ||||||
6828 | return false; | ||||||
6829 | } | ||||||
6830 | |||||||
6831 | inline bool Type::isObjCIdType() const { | ||||||
6832 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) | ||||||
6833 | return OPT->isObjCIdType(); | ||||||
6834 | return false; | ||||||
6835 | } | ||||||
6836 | |||||||
6837 | inline bool Type::isObjCClassType() const { | ||||||
6838 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) | ||||||
6839 | return OPT->isObjCClassType(); | ||||||
6840 | return false; | ||||||
6841 | } | ||||||
6842 | |||||||
6843 | inline bool Type::isObjCSelType() const { | ||||||
6844 | if (const auto *OPT = getAs<PointerType>()) | ||||||
6845 | return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel); | ||||||
6846 | return false; | ||||||
6847 | } | ||||||
6848 | |||||||
6849 | inline bool Type::isObjCBuiltinType() const { | ||||||
6850 | return isObjCIdType() || isObjCClassType() || isObjCSelType(); | ||||||
6851 | } | ||||||
6852 | |||||||
6853 | inline bool Type::isDecltypeType() const { | ||||||
6854 | return isa<DecltypeType>(this); | ||||||
6855 | } | ||||||
6856 | |||||||
6857 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | ||||||
6858 | inline bool Type::is##Id##Type() const { \ | ||||||
6859 | return isSpecificBuiltinType(BuiltinType::Id); \ | ||||||
6860 | } | ||||||
6861 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||
6862 | |||||||
6863 | inline bool Type::isSamplerT() const { | ||||||
6864 | return isSpecificBuiltinType(BuiltinType::OCLSampler); | ||||||
6865 | } | ||||||
6866 | |||||||
6867 | inline bool Type::isEventT() const { | ||||||
6868 | return isSpecificBuiltinType(BuiltinType::OCLEvent); | ||||||
6869 | } | ||||||
6870 | |||||||
6871 | inline bool Type::isClkEventT() const { | ||||||
6872 | return isSpecificBuiltinType(BuiltinType::OCLClkEvent); | ||||||
6873 | } | ||||||
6874 | |||||||
6875 | inline bool Type::isQueueT() const { | ||||||
6876 | return isSpecificBuiltinType(BuiltinType::OCLQueue); | ||||||
6877 | } | ||||||
6878 | |||||||
6879 | inline bool Type::isReserveIDT() const { | ||||||
6880 | return isSpecificBuiltinType(BuiltinType::OCLReserveID); | ||||||
6881 | } | ||||||
6882 | |||||||
6883 | inline bool Type::isImageType() const { | ||||||
6884 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() || | ||||||
6885 | return | ||||||
6886 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||
6887 | false; // end boolean or operation | ||||||
6888 | } | ||||||
6889 | |||||||
6890 | inline bool Type::isPipeType() const { | ||||||
6891 | return isa<PipeType>(CanonicalType); | ||||||
6892 | } | ||||||
6893 | |||||||
6894 | inline bool Type::isExtIntType() const { | ||||||
6895 | return isa<ExtIntType>(CanonicalType); | ||||||
6896 | } | ||||||
6897 | |||||||
6898 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ | ||||||
6899 | inline bool Type::is##Id##Type() const { \ | ||||||
6900 | return isSpecificBuiltinType(BuiltinType::Id); \ | ||||||
6901 | } | ||||||
6902 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
6903 | |||||||
6904 | inline bool Type::isOCLIntelSubgroupAVCType() const { | ||||||
6905 | #define INTEL_SUBGROUP_AVC_TYPE(ExtType, Id) \ | ||||||
6906 | isOCLIntelSubgroupAVC##Id##Type() || | ||||||
6907 | return | ||||||
6908 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
6909 | false; // end of boolean or operation | ||||||
6910 | } | ||||||
6911 | |||||||
6912 | inline bool Type::isOCLExtOpaqueType() const { | ||||||
6913 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) is##Id##Type() || | ||||||
6914 | return | ||||||
6915 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
6916 | false; // end of boolean or operation | ||||||
6917 | } | ||||||
6918 | |||||||
6919 | inline bool Type::isOpenCLSpecificType() const { | ||||||
6920 | return isSamplerT() || isEventT() || isImageType() || isClkEventT() || | ||||||
6921 | isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType(); | ||||||
6922 | } | ||||||
6923 | |||||||
6924 | inline bool Type::isTemplateTypeParmType() const { | ||||||
6925 | return isa<TemplateTypeParmType>(CanonicalType); | ||||||
6926 | } | ||||||
6927 | |||||||
6928 | inline bool Type::isSpecificBuiltinType(unsigned K) const { | ||||||
6929 | if (const BuiltinType *BT = getAs<BuiltinType>()) { | ||||||
6930 | return BT->getKind() == static_cast<BuiltinType::Kind>(K); | ||||||
6931 | } | ||||||
6932 | return false; | ||||||
6933 | } | ||||||
6934 | |||||||
6935 | inline bool Type::isPlaceholderType() const { | ||||||
6936 | if (const auto *BT = dyn_cast<BuiltinType>(this)) | ||||||
6937 | return BT->isPlaceholderType(); | ||||||
6938 | return false; | ||||||
6939 | } | ||||||
6940 | |||||||
6941 | inline const BuiltinType *Type::getAsPlaceholderType() const { | ||||||
6942 | if (const auto *BT = dyn_cast<BuiltinType>(this)) | ||||||
6943 | if (BT->isPlaceholderType()) | ||||||
6944 | return BT; | ||||||
6945 | return nullptr; | ||||||
6946 | } | ||||||
6947 | |||||||
6948 | inline bool Type::isSpecificPlaceholderType(unsigned K) const { | ||||||
6949 | assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K))(static_cast <bool> (BuiltinType::isPlaceholderTypeKind ((BuiltinType::Kind) K)) ? void (0) : __assert_fail ("BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 6949, __extension__ __PRETTY_FUNCTION__)); | ||||||
6950 | return isSpecificBuiltinType(K); | ||||||
6951 | } | ||||||
6952 | |||||||
6953 | inline bool Type::isNonOverloadPlaceholderType() const { | ||||||
6954 | if (const auto *BT = dyn_cast<BuiltinType>(this)) | ||||||
6955 | return BT->isNonOverloadPlaceholderType(); | ||||||
6956 | return false; | ||||||
6957 | } | ||||||
6958 | |||||||
6959 | inline bool Type::isVoidType() const { | ||||||
6960 | return isSpecificBuiltinType(BuiltinType::Void); | ||||||
6961 | } | ||||||
6962 | |||||||
6963 | inline bool Type::isHalfType() const { | ||||||
6964 | // FIXME: Should we allow complex __fp16? Probably not. | ||||||
6965 | return isSpecificBuiltinType(BuiltinType::Half); | ||||||
6966 | } | ||||||
6967 | |||||||
6968 | inline bool Type::isFloat16Type() const { | ||||||
6969 | return isSpecificBuiltinType(BuiltinType::Float16); | ||||||
6970 | } | ||||||
6971 | |||||||
6972 | inline bool Type::isBFloat16Type() const { | ||||||
6973 | return isSpecificBuiltinType(BuiltinType::BFloat16); | ||||||
6974 | } | ||||||
6975 | |||||||
6976 | inline bool Type::isFloat128Type() const { | ||||||
6977 | return isSpecificBuiltinType(BuiltinType::Float128); | ||||||
6978 | } | ||||||
6979 | |||||||
6980 | inline bool Type::isNullPtrType() const { | ||||||
6981 | return isSpecificBuiltinType(BuiltinType::NullPtr); | ||||||
6982 | } | ||||||
6983 | |||||||
6984 | bool IsEnumDeclComplete(EnumDecl *); | ||||||
6985 | bool IsEnumDeclScoped(EnumDecl *); | ||||||
6986 | |||||||
6987 | inline bool Type::isIntegerType() const { | ||||||
6988 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) | ||||||
6989 | return BT->getKind() >= BuiltinType::Bool && | ||||||
6990 | BT->getKind() <= BuiltinType::Int128; | ||||||
6991 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) { | ||||||
6992 | // Incomplete enum types are not treated as integer types. | ||||||
6993 | // FIXME: In C++, enum types are never integer types. | ||||||
6994 | return IsEnumDeclComplete(ET->getDecl()) && | ||||||
6995 | !IsEnumDeclScoped(ET->getDecl()); | ||||||
6996 | } | ||||||
6997 | return isExtIntType(); | ||||||
6998 | } | ||||||
6999 | |||||||
7000 | inline bool Type::isFixedPointType() const { | ||||||
7001 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { | ||||||
7002 | return BT->getKind() >= BuiltinType::ShortAccum && | ||||||
7003 | BT->getKind() <= BuiltinType::SatULongFract; | ||||||
7004 | } | ||||||
7005 | return false; | ||||||
7006 | } | ||||||
7007 | |||||||
7008 | inline bool Type::isFixedPointOrIntegerType() const { | ||||||
7009 | return isFixedPointType() || isIntegerType(); | ||||||
7010 | } | ||||||
7011 | |||||||
7012 | inline bool Type::isSaturatedFixedPointType() const { | ||||||
7013 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { | ||||||
7014 | return BT->getKind() >= BuiltinType::SatShortAccum && | ||||||
7015 | BT->getKind() <= BuiltinType::SatULongFract; | ||||||
7016 | } | ||||||
7017 | return false; | ||||||
7018 | } | ||||||
7019 | |||||||
7020 | inline bool Type::isUnsaturatedFixedPointType() const { | ||||||
7021 | return isFixedPointType() && !isSaturatedFixedPointType(); | ||||||
7022 | } | ||||||
7023 | |||||||
7024 | inline bool Type::isSignedFixedPointType() const { | ||||||
7025 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { | ||||||
7026 | return ((BT->getKind() >= BuiltinType::ShortAccum && | ||||||
7027 | BT->getKind() <= BuiltinType::LongAccum) || | ||||||
7028 | (BT->getKind() >= BuiltinType::ShortFract && | ||||||
7029 | BT->getKind() <= BuiltinType::LongFract) || | ||||||
7030 | (BT->getKind() >= BuiltinType::SatShortAccum && | ||||||
7031 | BT->getKind() <= BuiltinType::SatLongAccum) || | ||||||
7032 | (BT->getKind() >= BuiltinType::SatShortFract && | ||||||
7033 | BT->getKind() <= BuiltinType::SatLongFract)); | ||||||
7034 | } | ||||||
7035 | return false; | ||||||
7036 | } | ||||||
7037 | |||||||
7038 | inline bool Type::isUnsignedFixedPointType() const { | ||||||
7039 | return isFixedPointType() && !isSignedFixedPointType(); | ||||||
7040 | } | ||||||
7041 | |||||||
7042 | inline bool Type::isScalarType() const { | ||||||
7043 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) | ||||||
7044 | return BT->getKind() > BuiltinType::Void && | ||||||
7045 | BT->getKind() <= BuiltinType::NullPtr; | ||||||
7046 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) | ||||||
7047 | // Enums are scalar types, but only if they are defined. Incomplete enums | ||||||
7048 | // are not treated as scalar types. | ||||||
7049 | return IsEnumDeclComplete(ET->getDecl()); | ||||||
7050 | return isa<PointerType>(CanonicalType) || | ||||||
7051 | isa<BlockPointerType>(CanonicalType) || | ||||||
7052 | isa<MemberPointerType>(CanonicalType) || | ||||||
7053 | isa<ComplexType>(CanonicalType) || | ||||||
7054 | isa<ObjCObjectPointerType>(CanonicalType) || | ||||||
7055 | isExtIntType(); | ||||||
7056 | } | ||||||
7057 | |||||||
7058 | inline bool Type::isIntegralOrEnumerationType() const { | ||||||
7059 | if (const auto *BT
| ||||||
7060 | return BT->getKind() >= BuiltinType::Bool && | ||||||
7061 | BT->getKind() <= BuiltinType::Int128; | ||||||
7062 | |||||||
7063 | // Check for a complete enum type; incomplete enum types are not properly an | ||||||
7064 | // enumeration type in the sense required here. | ||||||
7065 | if (const auto *ET
| ||||||
7066 | return IsEnumDeclComplete(ET->getDecl()); | ||||||
7067 | |||||||
7068 | return isExtIntType(); | ||||||
7069 | } | ||||||
7070 | |||||||
7071 | inline bool Type::isBooleanType() const { | ||||||
7072 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) | ||||||
7073 | return BT->getKind() == BuiltinType::Bool; | ||||||
7074 | return false; | ||||||
7075 | } | ||||||
7076 | |||||||
7077 | inline bool Type::isUndeducedType() const { | ||||||
7078 | auto *DT = getContainedDeducedType(); | ||||||
7079 | return DT && !DT->isDeduced(); | ||||||
7080 | } | ||||||
7081 | |||||||
7082 | /// Determines whether this is a type for which one can define | ||||||
7083 | /// an overloaded operator. | ||||||
7084 | inline bool Type::isOverloadableType() const { | ||||||
7085 | return isDependentType() || isRecordType() || isEnumeralType(); | ||||||
7086 | } | ||||||
7087 | |||||||
7088 | /// Determines whether this type is written as a typedef-name. | ||||||
7089 | inline bool Type::isTypedefNameType() const { | ||||||
7090 | if (getAs<TypedefType>()) | ||||||
7091 | return true; | ||||||
7092 | if (auto *TST = getAs<TemplateSpecializationType>()) | ||||||
7093 | return TST->isTypeAlias(); | ||||||
7094 | return false; | ||||||
7095 | } | ||||||
7096 | |||||||
7097 | /// Determines whether this type can decay to a pointer type. | ||||||
7098 | inline bool Type::canDecayToPointerType() const { | ||||||
7099 | return isFunctionType() || isArrayType(); | ||||||
7100 | } | ||||||
7101 | |||||||
7102 | inline bool Type::hasPointerRepresentation() const { | ||||||
7103 | return (isPointerType() || isReferenceType() || isBlockPointerType() || | ||||||
7104 | isObjCObjectPointerType() || isNullPtrType()); | ||||||
7105 | } | ||||||
7106 | |||||||
7107 | inline bool Type::hasObjCPointerRepresentation() const { | ||||||
7108 | return isObjCObjectPointerType(); | ||||||
7109 | } | ||||||
7110 | |||||||
7111 | inline const Type *Type::getBaseElementTypeUnsafe() const { | ||||||
7112 | const Type *type = this; | ||||||
7113 | while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe()) | ||||||
7114 | type = arrayType->getElementType().getTypePtr(); | ||||||
7115 | return type; | ||||||
7116 | } | ||||||
7117 | |||||||
7118 | inline const Type *Type::getPointeeOrArrayElementType() const { | ||||||
7119 | const Type *type = this; | ||||||
7120 | if (type->isAnyPointerType()) | ||||||
7121 | return type->getPointeeType().getTypePtr(); | ||||||
7122 | else if (type->isArrayType()) | ||||||
7123 | return type->getBaseElementTypeUnsafe(); | ||||||
7124 | return type; | ||||||
7125 | } | ||||||
7126 | /// Insertion operator for partial diagnostics. This allows sending adress | ||||||
7127 | /// spaces into a diagnostic with <<. | ||||||
7128 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, | ||||||
7129 | LangAS AS) { | ||||||
7130 | PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS), | ||||||
7131 | DiagnosticsEngine::ArgumentKind::ak_addrspace); | ||||||
7132 | return PD; | ||||||
7133 | } | ||||||
7134 | |||||||
7135 | /// Insertion operator for partial diagnostics. This allows sending Qualifiers | ||||||
7136 | /// into a diagnostic with <<. | ||||||
7137 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, | ||||||
7138 | Qualifiers Q) { | ||||||
7139 | PD.AddTaggedVal(Q.getAsOpaqueValue(), | ||||||
7140 | DiagnosticsEngine::ArgumentKind::ak_qual); | ||||||
7141 | return PD; | ||||||
7142 | } | ||||||
7143 | |||||||
7144 | /// Insertion operator for partial diagnostics. This allows sending QualType's | ||||||
7145 | /// into a diagnostic with <<. | ||||||
7146 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, | ||||||
7147 | QualType T) { | ||||||
7148 | PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), | ||||||
7149 | DiagnosticsEngine::ak_qualtype); | ||||||
7150 | return PD; | ||||||
7151 | } | ||||||
7152 | |||||||
7153 | // Helper class template that is used by Type::getAs to ensure that one does | ||||||
7154 | // not try to look through a qualified type to get to an array type. | ||||||
7155 | template <typename T> | ||||||
7156 | using TypeIsArrayType = | ||||||
7157 | std::integral_constant<bool, std::is_same<T, ArrayType>::value || | ||||||
7158 | std::is_base_of<ArrayType, T>::value>; | ||||||
7159 | |||||||
7160 | // Member-template getAs<specific type>'. | ||||||
7161 | template <typename T> const T *Type::getAs() const { | ||||||
7162 | static_assert(!TypeIsArrayType<T>::value, | ||||||
7163 | "ArrayType cannot be used with getAs!"); | ||||||
7164 | |||||||
7165 | // If this is directly a T type, return it. | ||||||
7166 | if (const auto *Ty = dyn_cast<T>(this)) | ||||||
7167 | return Ty; | ||||||
7168 | |||||||
7169 | // If the canonical form of this type isn't the right kind, reject it. | ||||||
7170 | if (!isa<T>(CanonicalType)) | ||||||
7171 | return nullptr; | ||||||
7172 | |||||||
7173 | // If this is a typedef for the type, strip the typedef off without | ||||||
7174 | // losing all typedef information. | ||||||
7175 | return cast<T>(getUnqualifiedDesugaredType()); | ||||||
7176 | } | ||||||
7177 | |||||||
7178 | template <typename T> const T *Type::getAsAdjusted() const { | ||||||
7179 | static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!"); | ||||||
7180 | |||||||
7181 | // If this is directly a T type, return it. | ||||||
7182 | if (const auto *Ty = dyn_cast<T>(this)) | ||||||
7183 | return Ty; | ||||||
7184 | |||||||
7185 | // If the canonical form of this type isn't the right kind, reject it. | ||||||
7186 | if (!isa<T>(CanonicalType)) | ||||||
7187 | return nullptr; | ||||||
7188 | |||||||
7189 | // Strip off type adjustments that do not modify the underlying nature of the | ||||||
7190 | // type. | ||||||
7191 | const Type *Ty = this; | ||||||
7192 | while (Ty) { | ||||||
7193 | if (const auto *A = dyn_cast<AttributedType>(Ty)) | ||||||
7194 | Ty = A->getModifiedType().getTypePtr(); | ||||||
7195 | else if (const auto *E = dyn_cast<ElaboratedType>(Ty)) | ||||||
7196 | Ty = E->desugar().getTypePtr(); | ||||||
7197 | else if (const auto *P = dyn_cast<ParenType>(Ty)) | ||||||
7198 | Ty = P->desugar().getTypePtr(); | ||||||
7199 | else if (const auto *A = dyn_cast<AdjustedType>(Ty)) | ||||||
7200 | Ty = A->desugar().getTypePtr(); | ||||||
7201 | else if (const auto *M = dyn_cast<MacroQualifiedType>(Ty)) | ||||||
7202 | Ty = M->desugar().getTypePtr(); | ||||||
7203 | else | ||||||
7204 | break; | ||||||
7205 | } | ||||||
7206 | |||||||
7207 | // Just because the canonical type is correct does not mean we can use cast<>, | ||||||
7208 | // since we may not have stripped off all the sugar down to the base type. | ||||||
7209 | return dyn_cast<T>(Ty); | ||||||
7210 | } | ||||||
7211 | |||||||
7212 | inline const ArrayType *Type::getAsArrayTypeUnsafe() const { | ||||||
7213 | // If this is directly an array type, return it. | ||||||
7214 | if (const auto *arr = dyn_cast<ArrayType>(this)) | ||||||
7215 | return arr; | ||||||
7216 | |||||||
7217 | // If the canonical form of this type isn't the right kind, reject it. | ||||||
7218 | if (!isa<ArrayType>(CanonicalType)) | ||||||
7219 | return nullptr; | ||||||
7220 | |||||||
7221 | // If this is a typedef for the type, strip the typedef off without | ||||||
7222 | // losing all typedef information. | ||||||
7223 | return cast<ArrayType>(getUnqualifiedDesugaredType()); | ||||||
7224 | } | ||||||
7225 | |||||||
7226 | template <typename T> const T *Type::castAs() const { | ||||||
7227 | static_assert(!TypeIsArrayType<T>::value, | ||||||
7228 | "ArrayType cannot be used with castAs!"); | ||||||
7229 | |||||||
7230 | if (const auto *ty = dyn_cast<T>(this)) return ty; | ||||||
7231 | assert(isa<T>(CanonicalType))(static_cast <bool> (isa<T>(CanonicalType)) ? void (0) : __assert_fail ("isa<T>(CanonicalType)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 7231, __extension__ __PRETTY_FUNCTION__)); | ||||||
7232 | return cast<T>(getUnqualifiedDesugaredType()); | ||||||
7233 | } | ||||||
7234 | |||||||
7235 | inline const ArrayType *Type::castAsArrayTypeUnsafe() const { | ||||||
7236 | assert(isa<ArrayType>(CanonicalType))(static_cast <bool> (isa<ArrayType>(CanonicalType )) ? void (0) : __assert_fail ("isa<ArrayType>(CanonicalType)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 7236, __extension__ __PRETTY_FUNCTION__)); | ||||||
7237 | if (const auto *arr = dyn_cast<ArrayType>(this)) return arr; | ||||||
7238 | return cast<ArrayType>(getUnqualifiedDesugaredType()); | ||||||
7239 | } | ||||||
7240 | |||||||
7241 | DecayedType::DecayedType(QualType OriginalType, QualType DecayedPtr, | ||||||
7242 | QualType CanonicalPtr) | ||||||
7243 | : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) { | ||||||
7244 | #ifndef NDEBUG | ||||||
7245 | QualType Adjusted = getAdjustedType(); | ||||||
7246 | (void)AttributedType::stripOuterNullability(Adjusted); | ||||||
7247 | assert(isa<PointerType>(Adjusted))(static_cast <bool> (isa<PointerType>(Adjusted)) ? void (0) : __assert_fail ("isa<PointerType>(Adjusted)" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/Type.h" , 7247, __extension__ __PRETTY_FUNCTION__)); | ||||||
7248 | #endif | ||||||
7249 | } | ||||||
7250 | |||||||
7251 | QualType DecayedType::getPointeeType() const { | ||||||
7252 | QualType Decayed = getDecayedType(); | ||||||
7253 | (void)AttributedType::stripOuterNullability(Decayed); | ||||||
7254 | return cast<PointerType>(Decayed)->getPointeeType(); | ||||||
7255 | } | ||||||
7256 | |||||||
7257 | // Get the decimal string representation of a fixed point type, represented | ||||||
7258 | // as a scaled integer. | ||||||
7259 | // TODO: At some point, we should change the arguments to instead just accept an | ||||||
7260 | // APFixedPoint instead of APSInt and scale. | ||||||
7261 | void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val, | ||||||
7262 | unsigned Scale); | ||||||
7263 | |||||||
7264 | } // namespace clang | ||||||
7265 | |||||||
7266 | #endif // LLVM_CLANG_AST_TYPE_H |
1 | //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- 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 | // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), |
10 | // and dyn_cast_or_null<X>() templates. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_SUPPORT_CASTING_H |
15 | #define LLVM_SUPPORT_CASTING_H |
16 | |
17 | #include "llvm/Support/Compiler.h" |
18 | #include "llvm/Support/type_traits.h" |
19 | #include <cassert> |
20 | #include <memory> |
21 | #include <type_traits> |
22 | |
23 | namespace llvm { |
24 | |
25 | //===----------------------------------------------------------------------===// |
26 | // isa<x> Support Templates |
27 | //===----------------------------------------------------------------------===// |
28 | |
29 | // Define a template that can be specialized by smart pointers to reflect the |
30 | // fact that they are automatically dereferenced, and are not involved with the |
31 | // template selection process... the default implementation is a noop. |
32 | // |
33 | template<typename From> struct simplify_type { |
34 | using SimpleType = From; // The real type this represents... |
35 | |
36 | // An accessor to get the real value... |
37 | static SimpleType &getSimplifiedValue(From &Val) { return Val; } |
38 | }; |
39 | |
40 | template<typename From> struct simplify_type<const From> { |
41 | using NonConstSimpleType = typename simplify_type<From>::SimpleType; |
42 | using SimpleType = |
43 | typename add_const_past_pointer<NonConstSimpleType>::type; |
44 | using RetType = |
45 | typename add_lvalue_reference_if_not_pointer<SimpleType>::type; |
46 | |
47 | static RetType getSimplifiedValue(const From& Val) { |
48 | return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); |
49 | } |
50 | }; |
51 | |
52 | // The core of the implementation of isa<X> is here; To and From should be |
53 | // the names of classes. This template can be specialized to customize the |
54 | // implementation of isa<> without rewriting it from scratch. |
55 | template <typename To, typename From, typename Enabler = void> |
56 | struct isa_impl { |
57 | static inline bool doit(const From &Val) { |
58 | return To::classof(&Val); |
59 | } |
60 | }; |
61 | |
62 | /// Always allow upcasts, and perform no dynamic check for them. |
63 | template <typename To, typename From> |
64 | struct isa_impl<To, From, std::enable_if_t<std::is_base_of<To, From>::value>> { |
65 | static inline bool doit(const From &) { return true; } |
66 | }; |
67 | |
68 | template <typename To, typename From> struct isa_impl_cl { |
69 | static inline bool doit(const From &Val) { |
70 | return isa_impl<To, From>::doit(Val); |
71 | } |
72 | }; |
73 | |
74 | template <typename To, typename From> struct isa_impl_cl<To, const From> { |
75 | static inline bool doit(const From &Val) { |
76 | return isa_impl<To, From>::doit(Val); |
77 | } |
78 | }; |
79 | |
80 | template <typename To, typename From> |
81 | struct isa_impl_cl<To, const std::unique_ptr<From>> { |
82 | static inline bool doit(const std::unique_ptr<From> &Val) { |
83 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 83, __extension__ __PRETTY_FUNCTION__)); |
84 | return isa_impl_cl<To, From>::doit(*Val); |
85 | } |
86 | }; |
87 | |
88 | template <typename To, typename From> struct isa_impl_cl<To, From*> { |
89 | static inline bool doit(const From *Val) { |
90 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 90, __extension__ __PRETTY_FUNCTION__)); |
91 | return isa_impl<To, From>::doit(*Val); |
92 | } |
93 | }; |
94 | |
95 | template <typename To, typename From> struct isa_impl_cl<To, From*const> { |
96 | static inline bool doit(const From *Val) { |
97 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 97, __extension__ __PRETTY_FUNCTION__)); |
98 | return isa_impl<To, From>::doit(*Val); |
99 | } |
100 | }; |
101 | |
102 | template <typename To, typename From> struct isa_impl_cl<To, const From*> { |
103 | static inline bool doit(const From *Val) { |
104 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 104, __extension__ __PRETTY_FUNCTION__)); |
105 | return isa_impl<To, From>::doit(*Val); |
106 | } |
107 | }; |
108 | |
109 | template <typename To, typename From> struct isa_impl_cl<To, const From*const> { |
110 | static inline bool doit(const From *Val) { |
111 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 111, __extension__ __PRETTY_FUNCTION__)); |
112 | return isa_impl<To, From>::doit(*Val); |
113 | } |
114 | }; |
115 | |
116 | template<typename To, typename From, typename SimpleFrom> |
117 | struct isa_impl_wrap { |
118 | // When From != SimplifiedType, we can simplify the type some more by using |
119 | // the simplify_type template. |
120 | static bool doit(const From &Val) { |
121 | return isa_impl_wrap<To, SimpleFrom, |
122 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
123 | simplify_type<const From>::getSimplifiedValue(Val)); |
124 | } |
125 | }; |
126 | |
127 | template<typename To, typename FromTy> |
128 | struct isa_impl_wrap<To, FromTy, FromTy> { |
129 | // When From == SimpleType, we are as simple as we are going to get. |
130 | static bool doit(const FromTy &Val) { |
131 | return isa_impl_cl<To,FromTy>::doit(Val); |
132 | } |
133 | }; |
134 | |
135 | // isa<X> - Return true if the parameter to the template is an instance of one |
136 | // of the template type arguments. Used like this: |
137 | // |
138 | // if (isa<Type>(myVal)) { ... } |
139 | // if (isa<Type0, Type1, Type2>(myVal)) { ... } |
140 | // |
141 | template <class X, class Y> LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
142 | return isa_impl_wrap<X, const Y, |
143 | typename simplify_type<const Y>::SimpleType>::doit(Val); |
144 | } |
145 | |
146 | template <typename First, typename Second, typename... Rest, typename Y> |
147 | LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
148 | return isa<First>(Val) || isa<Second, Rest...>(Val); |
149 | } |
150 | |
151 | // isa_and_nonnull<X> - Functionally identical to isa, except that a null value |
152 | // is accepted. |
153 | // |
154 | template <typename... X, class Y> |
155 | LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa_and_nonnull(const Y &Val) { |
156 | if (!Val) |
157 | return false; |
158 | return isa<X...>(Val); |
159 | } |
160 | |
161 | //===----------------------------------------------------------------------===// |
162 | // cast<x> Support Templates |
163 | //===----------------------------------------------------------------------===// |
164 | |
165 | template<class To, class From> struct cast_retty; |
166 | |
167 | // Calculate what type the 'cast' function should return, based on a requested |
168 | // type of To and a source type of From. |
169 | template<class To, class From> struct cast_retty_impl { |
170 | using ret_type = To &; // Normal case, return Ty& |
171 | }; |
172 | template<class To, class From> struct cast_retty_impl<To, const From> { |
173 | using ret_type = const To &; // Normal case, return Ty& |
174 | }; |
175 | |
176 | template<class To, class From> struct cast_retty_impl<To, From*> { |
177 | using ret_type = To *; // Pointer arg case, return Ty* |
178 | }; |
179 | |
180 | template<class To, class From> struct cast_retty_impl<To, const From*> { |
181 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
182 | }; |
183 | |
184 | template<class To, class From> struct cast_retty_impl<To, const From*const> { |
185 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
186 | }; |
187 | |
188 | template <class To, class From> |
189 | struct cast_retty_impl<To, std::unique_ptr<From>> { |
190 | private: |
191 | using PointerType = typename cast_retty_impl<To, From *>::ret_type; |
192 | using ResultType = std::remove_pointer_t<PointerType>; |
193 | |
194 | public: |
195 | using ret_type = std::unique_ptr<ResultType>; |
196 | }; |
197 | |
198 | template<class To, class From, class SimpleFrom> |
199 | struct cast_retty_wrap { |
200 | // When the simplified type and the from type are not the same, use the type |
201 | // simplifier to reduce the type, then reuse cast_retty_impl to get the |
202 | // resultant type. |
203 | using ret_type = typename cast_retty<To, SimpleFrom>::ret_type; |
204 | }; |
205 | |
206 | template<class To, class FromTy> |
207 | struct cast_retty_wrap<To, FromTy, FromTy> { |
208 | // When the simplified type is equal to the from type, use it directly. |
209 | using ret_type = typename cast_retty_impl<To,FromTy>::ret_type; |
210 | }; |
211 | |
212 | template<class To, class From> |
213 | struct cast_retty { |
214 | using ret_type = typename cast_retty_wrap< |
215 | To, From, typename simplify_type<From>::SimpleType>::ret_type; |
216 | }; |
217 | |
218 | // Ensure the non-simple values are converted using the simplify_type template |
219 | // that may be specialized by smart pointers... |
220 | // |
221 | template<class To, class From, class SimpleFrom> struct cast_convert_val { |
222 | // This is not a simple type, use the template to simplify it... |
223 | static typename cast_retty<To, From>::ret_type doit(From &Val) { |
224 | return cast_convert_val<To, SimpleFrom, |
225 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
226 | simplify_type<From>::getSimplifiedValue(Val)); |
227 | } |
228 | }; |
229 | |
230 | template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { |
231 | // This _is_ a simple type, just cast it. |
232 | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { |
233 | typename cast_retty<To, FromTy>::ret_type Res2 |
234 | = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); |
235 | return Res2; |
236 | } |
237 | }; |
238 | |
239 | template <class X> struct is_simple_type { |
240 | static const bool value = |
241 | std::is_same<X, typename simplify_type<X>::SimpleType>::value; |
242 | }; |
243 | |
244 | // cast<X> - Return the argument parameter cast to the specified type. This |
245 | // casting operator asserts that the type is correct, so it does not return null |
246 | // on failure. It does not allow a null argument (use cast_or_null for that). |
247 | // It is typically used like this: |
248 | // |
249 | // cast<Instruction>(myVal)->getParent() |
250 | // |
251 | template <class X, class Y> |
252 | inline std::enable_if_t<!is_simple_type<Y>::value, |
253 | typename cast_retty<X, const Y>::ret_type> |
254 | cast(const Y &Val) { |
255 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 255, __extension__ __PRETTY_FUNCTION__)); |
256 | return cast_convert_val< |
257 | X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); |
258 | } |
259 | |
260 | template <class X, class Y> |
261 | inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { |
262 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 262, __extension__ __PRETTY_FUNCTION__)); |
263 | return cast_convert_val<X, Y, |
264 | typename simplify_type<Y>::SimpleType>::doit(Val); |
265 | } |
266 | |
267 | template <class X, class Y> |
268 | inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { |
269 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 269, __extension__ __PRETTY_FUNCTION__)); |
270 | return cast_convert_val<X, Y*, |
271 | typename simplify_type<Y*>::SimpleType>::doit(Val); |
272 | } |
273 | |
274 | template <class X, class Y> |
275 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
276 | cast(std::unique_ptr<Y> &&Val) { |
277 | assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!") ? void (0 ) : __assert_fail ("isa<X>(Val.get()) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 277, __extension__ __PRETTY_FUNCTION__)); |
278 | using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type; |
279 | return ret_type( |
280 | cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit( |
281 | Val.release())); |
282 | } |
283 | |
284 | // cast_or_null<X> - Functionally identical to cast, except that a null value is |
285 | // accepted. |
286 | // |
287 | template <class X, class Y> |
288 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
289 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
290 | cast_or_null(const Y &Val) { |
291 | if (!Val) |
292 | return nullptr; |
293 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 293, __extension__ __PRETTY_FUNCTION__)); |
294 | return cast<X>(Val); |
295 | } |
296 | |
297 | template <class X, class Y> |
298 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t<!is_simple_type<Y>::value, |
299 | typename cast_retty<X, Y>::ret_type> |
300 | cast_or_null(Y &Val) { |
301 | if (!Val) |
302 | return nullptr; |
303 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 303, __extension__ __PRETTY_FUNCTION__)); |
304 | return cast<X>(Val); |
305 | } |
306 | |
307 | template <class X, class Y> |
308 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
309 | cast_or_null(Y *Val) { |
310 | if (!Val) return nullptr; |
311 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 311, __extension__ __PRETTY_FUNCTION__)); |
312 | return cast<X>(Val); |
313 | } |
314 | |
315 | template <class X, class Y> |
316 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
317 | cast_or_null(std::unique_ptr<Y> &&Val) { |
318 | if (!Val) |
319 | return nullptr; |
320 | return cast<X>(std::move(Val)); |
321 | } |
322 | |
323 | // dyn_cast<X> - Return the argument parameter cast to the specified type. This |
324 | // casting operator returns null if the argument is of the wrong type, so it can |
325 | // be used to test for a type as well as cast if successful. This should be |
326 | // used in the context of an if statement like this: |
327 | // |
328 | // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } |
329 | // |
330 | |
331 | template <class X, class Y> |
332 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
333 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
334 | dyn_cast(const Y &Val) { |
335 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
336 | } |
337 | |
338 | template <class X, class Y> |
339 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { |
340 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
341 | } |
342 | |
343 | template <class X, class Y> |
344 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { |
345 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
346 | } |
347 | |
348 | // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null |
349 | // value is accepted. |
350 | // |
351 | template <class X, class Y> |
352 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
353 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
354 | dyn_cast_or_null(const Y &Val) { |
355 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
356 | } |
357 | |
358 | template <class X, class Y> |
359 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t<!is_simple_type<Y>::value, |
360 | typename cast_retty<X, Y>::ret_type> |
361 | dyn_cast_or_null(Y &Val) { |
362 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
363 | } |
364 | |
365 | template <class X, class Y> |
366 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
367 | dyn_cast_or_null(Y *Val) { |
368 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
369 | } |
370 | |
371 | // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, |
372 | // taking ownership of the input pointer iff isa<X>(Val) is true. If the |
373 | // cast is successful, From refers to nullptr on exit and the casted value |
374 | // is returned. If the cast is unsuccessful, the function returns nullptr |
375 | // and From is unchanged. |
376 | template <class X, class Y> |
377 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &Val) |
378 | -> decltype(cast<X>(Val)) { |
379 | if (!isa<X>(Val)) |
380 | return nullptr; |
381 | return cast<X>(std::move(Val)); |
382 | } |
383 | |
384 | template <class X, class Y> |
385 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) { |
386 | return unique_dyn_cast<X, Y>(Val); |
387 | } |
388 | |
389 | // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that |
390 | // a null value is accepted. |
391 | template <class X, class Y> |
392 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) |
393 | -> decltype(cast<X>(Val)) { |
394 | if (!Val) |
395 | return nullptr; |
396 | return unique_dyn_cast<X, Y>(Val); |
397 | } |
398 | |
399 | template <class X, class Y> |
400 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) { |
401 | return unique_dyn_cast_or_null<X, Y>(Val); |
402 | } |
403 | |
404 | } // end namespace llvm |
405 | |
406 | #endif // LLVM_SUPPORT_CASTING_H |