File: | build/source/clang/lib/Sema/SemaTemplateVariadic.cpp |
Warning: | line 705, column 11 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/ | ||||||||
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 | // This file implements semantic analysis for C++0x variadic templates. | ||||||||
9 | //===----------------------------------------------------------------------===/ | ||||||||
10 | |||||||||
11 | #include "clang/Sema/Sema.h" | ||||||||
12 | #include "TypeLocBuilder.h" | ||||||||
13 | #include "clang/AST/Expr.h" | ||||||||
14 | #include "clang/AST/RecursiveASTVisitor.h" | ||||||||
15 | #include "clang/AST/TypeLoc.h" | ||||||||
16 | #include "clang/Sema/Lookup.h" | ||||||||
17 | #include "clang/Sema/ParsedTemplate.h" | ||||||||
18 | #include "clang/Sema/ScopeInfo.h" | ||||||||
19 | #include "clang/Sema/SemaInternal.h" | ||||||||
20 | #include "clang/Sema/Template.h" | ||||||||
21 | |||||||||
22 | using namespace clang; | ||||||||
23 | |||||||||
24 | //---------------------------------------------------------------------------- | ||||||||
25 | // Visitor that collects unexpanded parameter packs | ||||||||
26 | //---------------------------------------------------------------------------- | ||||||||
27 | |||||||||
28 | namespace { | ||||||||
29 | /// A class that collects unexpanded parameter packs. | ||||||||
30 | class CollectUnexpandedParameterPacksVisitor : | ||||||||
31 | public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor> | ||||||||
32 | { | ||||||||
33 | typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor> | ||||||||
34 | inherited; | ||||||||
35 | |||||||||
36 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded; | ||||||||
37 | |||||||||
38 | bool InLambda = false; | ||||||||
39 | unsigned DepthLimit = (unsigned)-1; | ||||||||
40 | |||||||||
41 | void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) { | ||||||||
42 | if (auto *VD = dyn_cast<VarDecl>(ND)) { | ||||||||
43 | // For now, the only problematic case is a generic lambda's templated | ||||||||
44 | // call operator, so we don't need to look for all the other ways we | ||||||||
45 | // could have reached a dependent parameter pack. | ||||||||
46 | auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext()); | ||||||||
47 | auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr; | ||||||||
48 | if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit) | ||||||||
49 | return; | ||||||||
50 | } else if (getDepthAndIndex(ND).first >= DepthLimit) | ||||||||
51 | return; | ||||||||
52 | |||||||||
53 | Unexpanded.push_back({ND, Loc}); | ||||||||
54 | } | ||||||||
55 | void addUnexpanded(const TemplateTypeParmType *T, | ||||||||
56 | SourceLocation Loc = SourceLocation()) { | ||||||||
57 | if (T->getDepth() < DepthLimit) | ||||||||
58 | Unexpanded.push_back({T, Loc}); | ||||||||
59 | } | ||||||||
60 | |||||||||
61 | public: | ||||||||
62 | explicit CollectUnexpandedParameterPacksVisitor( | ||||||||
63 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) | ||||||||
64 | : Unexpanded(Unexpanded) {} | ||||||||
65 | |||||||||
66 | bool shouldWalkTypesOfTypeLocs() const { return false; } | ||||||||
67 | |||||||||
68 | //------------------------------------------------------------------------ | ||||||||
69 | // Recording occurrences of (unexpanded) parameter packs. | ||||||||
70 | //------------------------------------------------------------------------ | ||||||||
71 | |||||||||
72 | /// Record occurrences of template type parameter packs. | ||||||||
73 | bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { | ||||||||
74 | if (TL.getTypePtr()->isParameterPack()) | ||||||||
75 | addUnexpanded(TL.getTypePtr(), TL.getNameLoc()); | ||||||||
76 | return true; | ||||||||
77 | } | ||||||||
78 | |||||||||
79 | /// Record occurrences of template type parameter packs | ||||||||
80 | /// when we don't have proper source-location information for | ||||||||
81 | /// them. | ||||||||
82 | /// | ||||||||
83 | /// Ideally, this routine would never be used. | ||||||||
84 | bool VisitTemplateTypeParmType(TemplateTypeParmType *T) { | ||||||||
85 | if (T->isParameterPack()) | ||||||||
86 | addUnexpanded(T); | ||||||||
87 | |||||||||
88 | return true; | ||||||||
89 | } | ||||||||
90 | |||||||||
91 | bool | ||||||||
92 | VisitSubstTemplateTypeParmPackTypeLoc(SubstTemplateTypeParmPackTypeLoc TL) { | ||||||||
93 | Unexpanded.push_back({TL.getTypePtr(), TL.getNameLoc()}); | ||||||||
94 | return true; | ||||||||
95 | } | ||||||||
96 | |||||||||
97 | bool VisitSubstTemplateTypeParmPackType(SubstTemplateTypeParmPackType *T) { | ||||||||
98 | Unexpanded.push_back({T, SourceLocation()}); | ||||||||
99 | return true; | ||||||||
100 | } | ||||||||
101 | |||||||||
102 | bool | ||||||||
103 | VisitSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr *E) { | ||||||||
104 | Unexpanded.push_back({E, E->getParameterPackLocation()}); | ||||||||
105 | return true; | ||||||||
106 | } | ||||||||
107 | |||||||||
108 | /// Record occurrences of function and non-type template | ||||||||
109 | /// parameter packs in an expression. | ||||||||
110 | bool VisitDeclRefExpr(DeclRefExpr *E) { | ||||||||
111 | if (E->getDecl()->isParameterPack()) | ||||||||
112 | addUnexpanded(E->getDecl(), E->getLocation()); | ||||||||
113 | |||||||||
114 | return true; | ||||||||
115 | } | ||||||||
116 | |||||||||
117 | /// Record occurrences of template template parameter packs. | ||||||||
118 | bool TraverseTemplateName(TemplateName Template) { | ||||||||
119 | if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>( | ||||||||
120 | Template.getAsTemplateDecl())) { | ||||||||
121 | if (TTP->isParameterPack()) | ||||||||
122 | addUnexpanded(TTP); | ||||||||
123 | } | ||||||||
124 | |||||||||
125 | return inherited::TraverseTemplateName(Template); | ||||||||
126 | } | ||||||||
127 | |||||||||
128 | /// Suppress traversal into Objective-C container literal | ||||||||
129 | /// elements that are pack expansions. | ||||||||
130 | bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { | ||||||||
131 | if (!E->containsUnexpandedParameterPack()) | ||||||||
132 | return true; | ||||||||
133 | |||||||||
134 | for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { | ||||||||
135 | ObjCDictionaryElement Element = E->getKeyValueElement(I); | ||||||||
136 | if (Element.isPackExpansion()) | ||||||||
137 | continue; | ||||||||
138 | |||||||||
139 | TraverseStmt(Element.Key); | ||||||||
140 | TraverseStmt(Element.Value); | ||||||||
141 | } | ||||||||
142 | return true; | ||||||||
143 | } | ||||||||
144 | //------------------------------------------------------------------------ | ||||||||
145 | // Pruning the search for unexpanded parameter packs. | ||||||||
146 | //------------------------------------------------------------------------ | ||||||||
147 | |||||||||
148 | /// Suppress traversal into statements and expressions that | ||||||||
149 | /// do not contain unexpanded parameter packs. | ||||||||
150 | bool TraverseStmt(Stmt *S) { | ||||||||
151 | Expr *E = dyn_cast_or_null<Expr>(S); | ||||||||
152 | if ((E && E->containsUnexpandedParameterPack()) || InLambda) | ||||||||
153 | return inherited::TraverseStmt(S); | ||||||||
154 | |||||||||
155 | return true; | ||||||||
156 | } | ||||||||
157 | |||||||||
158 | /// Suppress traversal into types that do not contain | ||||||||
159 | /// unexpanded parameter packs. | ||||||||
160 | bool TraverseType(QualType T) { | ||||||||
161 | if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda) | ||||||||
162 | return inherited::TraverseType(T); | ||||||||
163 | |||||||||
164 | return true; | ||||||||
165 | } | ||||||||
166 | |||||||||
167 | /// Suppress traversal into types with location information | ||||||||
168 | /// that do not contain unexpanded parameter packs. | ||||||||
169 | bool TraverseTypeLoc(TypeLoc TL) { | ||||||||
170 | if ((!TL.getType().isNull() && | ||||||||
171 | TL.getType()->containsUnexpandedParameterPack()) || | ||||||||
172 | InLambda) | ||||||||
173 | return inherited::TraverseTypeLoc(TL); | ||||||||
174 | |||||||||
175 | return true; | ||||||||
176 | } | ||||||||
177 | |||||||||
178 | /// Suppress traversal of parameter packs. | ||||||||
179 | bool TraverseDecl(Decl *D) { | ||||||||
180 | // A function parameter pack is a pack expansion, so cannot contain | ||||||||
181 | // an unexpanded parameter pack. Likewise for a template parameter | ||||||||
182 | // pack that contains any references to other packs. | ||||||||
183 | if (D && D->isParameterPack()) | ||||||||
184 | return true; | ||||||||
185 | |||||||||
186 | return inherited::TraverseDecl(D); | ||||||||
187 | } | ||||||||
188 | |||||||||
189 | /// Suppress traversal of pack-expanded attributes. | ||||||||
190 | bool TraverseAttr(Attr *A) { | ||||||||
191 | if (A->isPackExpansion()) | ||||||||
192 | return true; | ||||||||
193 | |||||||||
194 | return inherited::TraverseAttr(A); | ||||||||
195 | } | ||||||||
196 | |||||||||
197 | /// Suppress traversal of pack expansion expressions and types. | ||||||||
198 | ///@{ | ||||||||
199 | bool TraversePackExpansionType(PackExpansionType *T) { return true; } | ||||||||
200 | bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; } | ||||||||
201 | bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; } | ||||||||
202 | bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; } | ||||||||
203 | |||||||||
204 | ///@} | ||||||||
205 | |||||||||
206 | /// Suppress traversal of using-declaration pack expansion. | ||||||||
207 | bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { | ||||||||
208 | if (D->isPackExpansion()) | ||||||||
209 | return true; | ||||||||
210 | |||||||||
211 | return inherited::TraverseUnresolvedUsingValueDecl(D); | ||||||||
212 | } | ||||||||
213 | |||||||||
214 | /// Suppress traversal of using-declaration pack expansion. | ||||||||
215 | bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { | ||||||||
216 | if (D->isPackExpansion()) | ||||||||
217 | return true; | ||||||||
218 | |||||||||
219 | return inherited::TraverseUnresolvedUsingTypenameDecl(D); | ||||||||
220 | } | ||||||||
221 | |||||||||
222 | /// Suppress traversal of template argument pack expansions. | ||||||||
223 | bool TraverseTemplateArgument(const TemplateArgument &Arg) { | ||||||||
224 | if (Arg.isPackExpansion()) | ||||||||
225 | return true; | ||||||||
226 | |||||||||
227 | return inherited::TraverseTemplateArgument(Arg); | ||||||||
228 | } | ||||||||
229 | |||||||||
230 | /// Suppress traversal of template argument pack expansions. | ||||||||
231 | bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { | ||||||||
232 | if (ArgLoc.getArgument().isPackExpansion()) | ||||||||
233 | return true; | ||||||||
234 | |||||||||
235 | return inherited::TraverseTemplateArgumentLoc(ArgLoc); | ||||||||
236 | } | ||||||||
237 | |||||||||
238 | /// Suppress traversal of base specifier pack expansions. | ||||||||
239 | bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { | ||||||||
240 | if (Base.isPackExpansion()) | ||||||||
241 | return true; | ||||||||
242 | |||||||||
243 | return inherited::TraverseCXXBaseSpecifier(Base); | ||||||||
244 | } | ||||||||
245 | |||||||||
246 | /// Suppress traversal of mem-initializer pack expansions. | ||||||||
247 | bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { | ||||||||
248 | if (Init->isPackExpansion()) | ||||||||
249 | return true; | ||||||||
250 | |||||||||
251 | return inherited::TraverseConstructorInitializer(Init); | ||||||||
252 | } | ||||||||
253 | |||||||||
254 | /// Note whether we're traversing a lambda containing an unexpanded | ||||||||
255 | /// parameter pack. In this case, the unexpanded pack can occur anywhere, | ||||||||
256 | /// including all the places where we normally wouldn't look. Within a | ||||||||
257 | /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit | ||||||||
258 | /// outside an expression. | ||||||||
259 | bool TraverseLambdaExpr(LambdaExpr *Lambda) { | ||||||||
260 | // The ContainsUnexpandedParameterPack bit on a lambda is always correct, | ||||||||
261 | // even if it's contained within another lambda. | ||||||||
262 | if (!Lambda->containsUnexpandedParameterPack()) | ||||||||
263 | return true; | ||||||||
264 | |||||||||
265 | bool WasInLambda = InLambda; | ||||||||
266 | unsigned OldDepthLimit = DepthLimit; | ||||||||
267 | |||||||||
268 | InLambda = true; | ||||||||
269 | if (auto *TPL = Lambda->getTemplateParameterList()) | ||||||||
270 | DepthLimit = TPL->getDepth(); | ||||||||
271 | |||||||||
272 | inherited::TraverseLambdaExpr(Lambda); | ||||||||
273 | |||||||||
274 | InLambda = WasInLambda; | ||||||||
275 | DepthLimit = OldDepthLimit; | ||||||||
276 | return true; | ||||||||
277 | } | ||||||||
278 | |||||||||
279 | /// Suppress traversal within pack expansions in lambda captures. | ||||||||
280 | bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C, | ||||||||
281 | Expr *Init) { | ||||||||
282 | if (C->isPackExpansion()) | ||||||||
283 | return true; | ||||||||
284 | |||||||||
285 | return inherited::TraverseLambdaCapture(Lambda, C, Init); | ||||||||
286 | } | ||||||||
287 | }; | ||||||||
288 | } | ||||||||
289 | |||||||||
290 | /// Determine whether it's possible for an unexpanded parameter pack to | ||||||||
291 | /// be valid in this location. This only happens when we're in a declaration | ||||||||
292 | /// that is nested within an expression that could be expanded, such as a | ||||||||
293 | /// lambda-expression within a function call. | ||||||||
294 | /// | ||||||||
295 | /// This is conservatively correct, but may claim that some unexpanded packs are | ||||||||
296 | /// permitted when they are not. | ||||||||
297 | bool Sema::isUnexpandedParameterPackPermitted() { | ||||||||
298 | for (auto *SI : FunctionScopes) | ||||||||
299 | if (isa<sema::LambdaScopeInfo>(SI)) | ||||||||
300 | return true; | ||||||||
301 | return false; | ||||||||
302 | } | ||||||||
303 | |||||||||
304 | /// Diagnose all of the unexpanded parameter packs in the given | ||||||||
305 | /// vector. | ||||||||
306 | bool | ||||||||
307 | Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, | ||||||||
308 | UnexpandedParameterPackContext UPPC, | ||||||||
309 | ArrayRef<UnexpandedParameterPack> Unexpanded) { | ||||||||
310 | if (Unexpanded.empty()) | ||||||||
311 | return false; | ||||||||
312 | |||||||||
313 | // If we are within a lambda expression and referencing a pack that is not | ||||||||
314 | // declared within the lambda itself, that lambda contains an unexpanded | ||||||||
315 | // parameter pack, and we are done. | ||||||||
316 | // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it | ||||||||
317 | // later. | ||||||||
318 | SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences; | ||||||||
319 | if (auto *LSI = getEnclosingLambda()) { | ||||||||
320 | for (auto &Pack : Unexpanded) { | ||||||||
321 | auto DeclaresThisPack = [&](NamedDecl *LocalPack) { | ||||||||
322 | if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) { | ||||||||
323 | auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack); | ||||||||
324 | return TTPD && TTPD->getTypeForDecl() == TTPT; | ||||||||
325 | } | ||||||||
326 | return declaresSameEntity(Pack.first.get<const NamedDecl *>(), | ||||||||
327 | LocalPack); | ||||||||
328 | }; | ||||||||
329 | if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack)) | ||||||||
330 | LambdaParamPackReferences.push_back(Pack); | ||||||||
331 | } | ||||||||
332 | |||||||||
333 | if (LambdaParamPackReferences.empty()) { | ||||||||
334 | // Construct in lambda only references packs declared outside the lambda. | ||||||||
335 | // That's OK for now, but the lambda itself is considered to contain an | ||||||||
336 | // unexpanded pack in this case, which will require expansion outside the | ||||||||
337 | // lambda. | ||||||||
338 | |||||||||
339 | // We do not permit pack expansion that would duplicate a statement | ||||||||
340 | // expression, not even within a lambda. | ||||||||
341 | // FIXME: We could probably support this for statement expressions that | ||||||||
342 | // do not contain labels. | ||||||||
343 | // FIXME: This is insufficient to detect this problem; consider | ||||||||
344 | // f( ({ bad: 0; }) + pack ... ); | ||||||||
345 | bool EnclosingStmtExpr = false; | ||||||||
346 | for (unsigned N = FunctionScopes.size(); N; --N) { | ||||||||
347 | sema::FunctionScopeInfo *Func = FunctionScopes[N-1]; | ||||||||
348 | if (llvm::any_of( | ||||||||
349 | Func->CompoundScopes, | ||||||||
350 | [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) { | ||||||||
351 | EnclosingStmtExpr = true; | ||||||||
352 | break; | ||||||||
353 | } | ||||||||
354 | // Coumpound-statements outside the lambda are OK for now; we'll check | ||||||||
355 | // for those when we finish handling the lambda. | ||||||||
356 | if (Func == LSI) | ||||||||
357 | break; | ||||||||
358 | } | ||||||||
359 | |||||||||
360 | if (!EnclosingStmtExpr) { | ||||||||
361 | LSI->ContainsUnexpandedParameterPack = true; | ||||||||
362 | return false; | ||||||||
363 | } | ||||||||
364 | } else { | ||||||||
365 | Unexpanded = LambdaParamPackReferences; | ||||||||
366 | } | ||||||||
367 | } | ||||||||
368 | |||||||||
369 | SmallVector<SourceLocation, 4> Locations; | ||||||||
370 | SmallVector<IdentifierInfo *, 4> Names; | ||||||||
371 | llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown; | ||||||||
372 | |||||||||
373 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { | ||||||||
374 | IdentifierInfo *Name = nullptr; | ||||||||
375 | if (const TemplateTypeParmType *TTP | ||||||||
376 | = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) | ||||||||
377 | Name = TTP->getIdentifier(); | ||||||||
378 | else | ||||||||
379 | Name = Unexpanded[I].first.get<const NamedDecl *>()->getIdentifier(); | ||||||||
380 | |||||||||
381 | if (Name && NamesKnown.insert(Name).second) | ||||||||
382 | Names.push_back(Name); | ||||||||
383 | |||||||||
384 | if (Unexpanded[I].second.isValid()) | ||||||||
385 | Locations.push_back(Unexpanded[I].second); | ||||||||
386 | } | ||||||||
387 | |||||||||
388 | auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack) | ||||||||
389 | << (int)UPPC << (int)Names.size(); | ||||||||
390 | for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I) | ||||||||
391 | DB << Names[I]; | ||||||||
392 | |||||||||
393 | for (unsigned I = 0, N = Locations.size(); I != N; ++I) | ||||||||
394 | DB << SourceRange(Locations[I]); | ||||||||
395 | return true; | ||||||||
396 | } | ||||||||
397 | |||||||||
398 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, | ||||||||
399 | TypeSourceInfo *T, | ||||||||
400 | UnexpandedParameterPackContext UPPC) { | ||||||||
401 | // C++0x [temp.variadic]p5: | ||||||||
402 | // An appearance of a name of a parameter pack that is not expanded is | ||||||||
403 | // ill-formed. | ||||||||
404 | if (!T->getType()->containsUnexpandedParameterPack()) | ||||||||
405 | return false; | ||||||||
406 | |||||||||
407 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||
408 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc( | ||||||||
409 | T->getTypeLoc()); | ||||||||
410 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 410, __extension__ __PRETTY_FUNCTION__)); | ||||||||
411 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); | ||||||||
412 | } | ||||||||
413 | |||||||||
414 | bool Sema::DiagnoseUnexpandedParameterPack(Expr *E, | ||||||||
415 | UnexpandedParameterPackContext UPPC) { | ||||||||
416 | // C++0x [temp.variadic]p5: | ||||||||
417 | // An appearance of a name of a parameter pack that is not expanded is | ||||||||
418 | // ill-formed. | ||||||||
419 | if (!E->containsUnexpandedParameterPack()) | ||||||||
420 | return false; | ||||||||
421 | |||||||||
422 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||
423 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E); | ||||||||
424 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 424, __extension__ __PRETTY_FUNCTION__)); | ||||||||
425 | return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded); | ||||||||
426 | } | ||||||||
427 | |||||||||
428 | bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) { | ||||||||
429 | if (!RE->containsUnexpandedParameterPack()) | ||||||||
430 | return false; | ||||||||
431 | |||||||||
432 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||
433 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE); | ||||||||
434 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 434, __extension__ __PRETTY_FUNCTION__)); | ||||||||
435 | |||||||||
436 | // We only care about unexpanded references to the RequiresExpr's own | ||||||||
437 | // parameter packs. | ||||||||
438 | auto Parms = RE->getLocalParameters(); | ||||||||
439 | llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end()); | ||||||||
440 | SmallVector<UnexpandedParameterPack, 2> UnexpandedParms; | ||||||||
441 | for (auto Parm : Unexpanded) | ||||||||
442 | if (ParmSet.contains(Parm.first.dyn_cast<const NamedDecl *>())) | ||||||||
443 | UnexpandedParms.push_back(Parm); | ||||||||
444 | if (UnexpandedParms.empty()) | ||||||||
445 | return false; | ||||||||
446 | |||||||||
447 | return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement, | ||||||||
448 | UnexpandedParms); | ||||||||
449 | } | ||||||||
450 | |||||||||
451 | bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, | ||||||||
452 | UnexpandedParameterPackContext UPPC) { | ||||||||
453 | // C++0x [temp.variadic]p5: | ||||||||
454 | // An appearance of a name of a parameter pack that is not expanded is | ||||||||
455 | // ill-formed. | ||||||||
456 | if (!SS.getScopeRep() || | ||||||||
457 | !SS.getScopeRep()->containsUnexpandedParameterPack()) | ||||||||
458 | return false; | ||||||||
459 | |||||||||
460 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||
461 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||
462 | .TraverseNestedNameSpecifier(SS.getScopeRep()); | ||||||||
463 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 463, __extension__ __PRETTY_FUNCTION__)); | ||||||||
464 | return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(), | ||||||||
465 | UPPC, Unexpanded); | ||||||||
466 | } | ||||||||
467 | |||||||||
468 | bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, | ||||||||
469 | UnexpandedParameterPackContext UPPC) { | ||||||||
470 | // C++0x [temp.variadic]p5: | ||||||||
471 | // An appearance of a name of a parameter pack that is not expanded is | ||||||||
472 | // ill-formed. | ||||||||
473 | switch (NameInfo.getName().getNameKind()) { | ||||||||
474 | case DeclarationName::Identifier: | ||||||||
475 | case DeclarationName::ObjCZeroArgSelector: | ||||||||
476 | case DeclarationName::ObjCOneArgSelector: | ||||||||
477 | case DeclarationName::ObjCMultiArgSelector: | ||||||||
478 | case DeclarationName::CXXOperatorName: | ||||||||
479 | case DeclarationName::CXXLiteralOperatorName: | ||||||||
480 | case DeclarationName::CXXUsingDirective: | ||||||||
481 | case DeclarationName::CXXDeductionGuideName: | ||||||||
482 | return false; | ||||||||
483 | |||||||||
484 | case DeclarationName::CXXConstructorName: | ||||||||
485 | case DeclarationName::CXXDestructorName: | ||||||||
486 | case DeclarationName::CXXConversionFunctionName: | ||||||||
487 | // FIXME: We shouldn't need this null check! | ||||||||
488 | if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) | ||||||||
489 | return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC); | ||||||||
490 | |||||||||
491 | if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack()) | ||||||||
492 | return false; | ||||||||
493 | |||||||||
494 | break; | ||||||||
495 | } | ||||||||
496 | |||||||||
497 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||
498 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||
499 | .TraverseType(NameInfo.getName().getCXXNameType()); | ||||||||
500 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 500, __extension__ __PRETTY_FUNCTION__)); | ||||||||
501 | return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded); | ||||||||
502 | } | ||||||||
503 | |||||||||
504 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, | ||||||||
505 | TemplateName Template, | ||||||||
506 | UnexpandedParameterPackContext UPPC) { | ||||||||
507 | |||||||||
508 | if (Template.isNull() || !Template.containsUnexpandedParameterPack()) | ||||||||
509 | return false; | ||||||||
510 | |||||||||
511 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||
512 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||
513 | .TraverseTemplateName(Template); | ||||||||
514 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 514, __extension__ __PRETTY_FUNCTION__)); | ||||||||
515 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); | ||||||||
516 | } | ||||||||
517 | |||||||||
518 | bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, | ||||||||
519 | UnexpandedParameterPackContext UPPC) { | ||||||||
520 | if (Arg.getArgument().isNull() || | ||||||||
521 | !Arg.getArgument().containsUnexpandedParameterPack()) | ||||||||
522 | return false; | ||||||||
523 | |||||||||
524 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||
525 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||
526 | .TraverseTemplateArgumentLoc(Arg); | ||||||||
527 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 527, __extension__ __PRETTY_FUNCTION__)); | ||||||||
528 | return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded); | ||||||||
529 | } | ||||||||
530 | |||||||||
531 | void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg, | ||||||||
532 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||
533 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||
534 | .TraverseTemplateArgument(Arg); | ||||||||
535 | } | ||||||||
536 | |||||||||
537 | void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, | ||||||||
538 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||
539 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||
540 | .TraverseTemplateArgumentLoc(Arg); | ||||||||
541 | } | ||||||||
542 | |||||||||
543 | void Sema::collectUnexpandedParameterPacks(QualType T, | ||||||||
544 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||
545 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T); | ||||||||
546 | } | ||||||||
547 | |||||||||
548 | void Sema::collectUnexpandedParameterPacks(TypeLoc TL, | ||||||||
549 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||
550 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL); | ||||||||
551 | } | ||||||||
552 | |||||||||
553 | void Sema::collectUnexpandedParameterPacks( | ||||||||
554 | NestedNameSpecifierLoc NNS, | ||||||||
555 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||
556 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||
557 | .TraverseNestedNameSpecifierLoc(NNS); | ||||||||
558 | } | ||||||||
559 | |||||||||
560 | void Sema::collectUnexpandedParameterPacks( | ||||||||
561 | const DeclarationNameInfo &NameInfo, | ||||||||
562 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||
563 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||
564 | .TraverseDeclarationNameInfo(NameInfo); | ||||||||
565 | } | ||||||||
566 | |||||||||
567 | |||||||||
568 | ParsedTemplateArgument | ||||||||
569 | Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg, | ||||||||
570 | SourceLocation EllipsisLoc) { | ||||||||
571 | if (Arg.isInvalid()) | ||||||||
572 | return Arg; | ||||||||
573 | |||||||||
574 | switch (Arg.getKind()) { | ||||||||
575 | case ParsedTemplateArgument::Type: { | ||||||||
576 | TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc); | ||||||||
577 | if (Result.isInvalid()) | ||||||||
578 | return ParsedTemplateArgument(); | ||||||||
579 | |||||||||
580 | return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(), | ||||||||
581 | Arg.getLocation()); | ||||||||
582 | } | ||||||||
583 | |||||||||
584 | case ParsedTemplateArgument::NonType: { | ||||||||
585 | ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc); | ||||||||
586 | if (Result.isInvalid()) | ||||||||
587 | return ParsedTemplateArgument(); | ||||||||
588 | |||||||||
589 | return ParsedTemplateArgument(Arg.getKind(), Result.get(), | ||||||||
590 | Arg.getLocation()); | ||||||||
591 | } | ||||||||
592 | |||||||||
593 | case ParsedTemplateArgument::Template: | ||||||||
594 | if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) { | ||||||||
595 | SourceRange R(Arg.getLocation()); | ||||||||
596 | if (Arg.getScopeSpec().isValid()) | ||||||||
597 | R.setBegin(Arg.getScopeSpec().getBeginLoc()); | ||||||||
598 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | ||||||||
599 | << R; | ||||||||
600 | return ParsedTemplateArgument(); | ||||||||
601 | } | ||||||||
602 | |||||||||
603 | return Arg.getTemplatePackExpansion(EllipsisLoc); | ||||||||
604 | } | ||||||||
605 | llvm_unreachable("Unhandled template argument kind?")::llvm::llvm_unreachable_internal("Unhandled template argument kind?" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 605); | ||||||||
606 | } | ||||||||
607 | |||||||||
608 | TypeResult Sema::ActOnPackExpansion(ParsedType Type, | ||||||||
609 | SourceLocation EllipsisLoc) { | ||||||||
610 | TypeSourceInfo *TSInfo; | ||||||||
611 | GetTypeFromParser(Type, &TSInfo); | ||||||||
612 | if (!TSInfo) | ||||||||
613 | return true; | ||||||||
614 | |||||||||
615 | TypeSourceInfo *TSResult = | ||||||||
616 | CheckPackExpansion(TSInfo, EllipsisLoc, std::nullopt); | ||||||||
617 | if (!TSResult) | ||||||||
618 | return true; | ||||||||
619 | |||||||||
620 | return CreateParsedType(TSResult->getType(), TSResult); | ||||||||
621 | } | ||||||||
622 | |||||||||
623 | TypeSourceInfo * | ||||||||
624 | Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, | ||||||||
625 | Optional<unsigned> NumExpansions) { | ||||||||
626 | // Create the pack expansion type and source-location information. | ||||||||
627 | QualType Result = CheckPackExpansion(Pattern->getType(), | ||||||||
628 | Pattern->getTypeLoc().getSourceRange(), | ||||||||
629 | EllipsisLoc, NumExpansions); | ||||||||
630 | if (Result.isNull()) | ||||||||
631 | return nullptr; | ||||||||
632 | |||||||||
633 | TypeLocBuilder TLB; | ||||||||
634 | TLB.pushFullCopy(Pattern->getTypeLoc()); | ||||||||
635 | PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result); | ||||||||
636 | TL.setEllipsisLoc(EllipsisLoc); | ||||||||
637 | |||||||||
638 | return TLB.getTypeSourceInfo(Context, Result); | ||||||||
639 | } | ||||||||
640 | |||||||||
641 | QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, | ||||||||
642 | SourceLocation EllipsisLoc, | ||||||||
643 | Optional<unsigned> NumExpansions) { | ||||||||
644 | // C++11 [temp.variadic]p5: | ||||||||
645 | // The pattern of a pack expansion shall name one or more | ||||||||
646 | // parameter packs that are not expanded by a nested pack | ||||||||
647 | // expansion. | ||||||||
648 | // | ||||||||
649 | // A pattern containing a deduced type can't occur "naturally" but arises in | ||||||||
650 | // the desugaring of an init-capture pack. | ||||||||
651 | if (!Pattern->containsUnexpandedParameterPack() && | ||||||||
652 | !Pattern->getContainedDeducedType()) { | ||||||||
653 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | ||||||||
654 | << PatternRange; | ||||||||
655 | return QualType(); | ||||||||
656 | } | ||||||||
657 | |||||||||
658 | return Context.getPackExpansionType(Pattern, NumExpansions, | ||||||||
659 | /*ExpectPackInType=*/false); | ||||||||
660 | } | ||||||||
661 | |||||||||
662 | ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { | ||||||||
663 | return CheckPackExpansion(Pattern, EllipsisLoc, std::nullopt); | ||||||||
664 | } | ||||||||
665 | |||||||||
666 | ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, | ||||||||
667 | Optional<unsigned> NumExpansions) { | ||||||||
668 | if (!Pattern) | ||||||||
669 | return ExprError(); | ||||||||
670 | |||||||||
671 | // C++0x [temp.variadic]p5: | ||||||||
672 | // The pattern of a pack expansion shall name one or more | ||||||||
673 | // parameter packs that are not expanded by a nested pack | ||||||||
674 | // expansion. | ||||||||
675 | if (!Pattern->containsUnexpandedParameterPack()) { | ||||||||
676 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | ||||||||
677 | << Pattern->getSourceRange(); | ||||||||
678 | CorrectDelayedTyposInExpr(Pattern); | ||||||||
679 | return ExprError(); | ||||||||
680 | } | ||||||||
681 | |||||||||
682 | // Create the pack expansion expression and source-location information. | ||||||||
683 | return new (Context) | ||||||||
684 | PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions); | ||||||||
685 | } | ||||||||
686 | |||||||||
687 | bool Sema::CheckParameterPacksForExpansion( | ||||||||
688 | SourceLocation EllipsisLoc, SourceRange PatternRange, | ||||||||
689 | ArrayRef<UnexpandedParameterPack> Unexpanded, | ||||||||
690 | const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, | ||||||||
691 | bool &RetainExpansion, Optional<unsigned> &NumExpansions) { | ||||||||
692 | ShouldExpand = true; | ||||||||
693 | RetainExpansion = false; | ||||||||
694 | std::pair<const IdentifierInfo *, SourceLocation> FirstPack; | ||||||||
695 | Optional<std::pair<unsigned, SourceLocation>> PartialExpansion; | ||||||||
696 | Optional<unsigned> CurNumExpansions; | ||||||||
697 | |||||||||
698 | for (auto [P, Loc] : Unexpanded) { | ||||||||
| |||||||||
699 | // Compute the depth and index for this parameter pack. | ||||||||
700 | Optional<std::pair<unsigned, unsigned>> Pos; | ||||||||
701 | unsigned NewPackSize; | ||||||||
702 | const auto *ND = P.dyn_cast<const NamedDecl *>(); | ||||||||
703 | if (ND
| ||||||||
704 | const auto *DAP = | ||||||||
705 | CurrentInstantiationScope->findInstantiationOf(ND) | ||||||||
| |||||||||
706 | ->dyn_cast<LocalInstantiationScope::DeclArgumentPack *>(); | ||||||||
707 | if (!DAP) { | ||||||||
708 | // We can't expand this function parameter pack, so we can't expand | ||||||||
709 | // the pack expansion. | ||||||||
710 | ShouldExpand = false; | ||||||||
711 | continue; | ||||||||
712 | } | ||||||||
713 | NewPackSize = DAP->size(); | ||||||||
714 | } else if (ND
| ||||||||
715 | Pos = getDepthAndIndex(ND); | ||||||||
716 | } else if (const auto *TTP = P.dyn_cast<const TemplateTypeParmType *>()) { | ||||||||
717 | Pos = {TTP->getDepth(), TTP->getIndex()}; | ||||||||
718 | ND = TTP->getDecl(); | ||||||||
719 | // FIXME: We either should have some fallback for canonical TTP, or | ||||||||
720 | // never have canonical TTP here. | ||||||||
721 | } else if (const auto *STP = | ||||||||
722 | P.dyn_cast<const SubstTemplateTypeParmPackType *>()) { | ||||||||
723 | NewPackSize = STP->getNumArgs(); | ||||||||
724 | ND = STP->getReplacedParameter(); | ||||||||
725 | } else { | ||||||||
726 | const auto *SEP = P.get<const SubstNonTypeTemplateParmPackExpr *>(); | ||||||||
727 | NewPackSize = SEP->getArgumentPack().pack_size(); | ||||||||
728 | ND = SEP->getParameterPack(); | ||||||||
729 | } | ||||||||
730 | |||||||||
731 | if (Pos) { | ||||||||
732 | // If we don't have a template argument at this depth/index, then we | ||||||||
733 | // cannot expand the pack expansion. Make a note of this, but we still | ||||||||
734 | // want to check any parameter packs we *do* have arguments for. | ||||||||
735 | if (Pos->first >= TemplateArgs.getNumLevels() || | ||||||||
736 | !TemplateArgs.hasTemplateArgument(Pos->first, Pos->second)) { | ||||||||
737 | ShouldExpand = false; | ||||||||
738 | continue; | ||||||||
739 | } | ||||||||
740 | // Determine the size of the argument pack. | ||||||||
741 | NewPackSize = TemplateArgs(Pos->first, Pos->second).pack_size(); | ||||||||
742 | // C++0x [temp.arg.explicit]p9: | ||||||||
743 | // Template argument deduction can extend the sequence of template | ||||||||
744 | // arguments corresponding to a template parameter pack, even when the | ||||||||
745 | // sequence contains explicitly specified template arguments. | ||||||||
746 | if (CurrentInstantiationScope) | ||||||||
747 | if (const NamedDecl *PartialPack = | ||||||||
748 | CurrentInstantiationScope->getPartiallySubstitutedPack(); | ||||||||
749 | PartialPack && getDepthAndIndex(PartialPack) == *Pos) { | ||||||||
750 | RetainExpansion = true; | ||||||||
751 | // We don't actually know the new pack size yet. | ||||||||
752 | PartialExpansion = {NewPackSize, Loc}; | ||||||||
753 | continue; | ||||||||
754 | } | ||||||||
755 | } | ||||||||
756 | |||||||||
757 | // FIXME: Workaround for Canonical TTP. | ||||||||
758 | const IdentifierInfo *Name = ND
| ||||||||
759 | if (!CurNumExpansions) { | ||||||||
760 | // The is the first pack we've seen for which we have an argument. | ||||||||
761 | // Record it. | ||||||||
762 | CurNumExpansions = NewPackSize; | ||||||||
763 | FirstPack = {Name, Loc}; | ||||||||
764 | } else if (NewPackSize != *CurNumExpansions) { | ||||||||
765 | // C++0x [temp.variadic]p5: | ||||||||
766 | // All of the parameter packs expanded by a pack expansion shall have | ||||||||
767 | // the same number of arguments specified. | ||||||||
768 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) | ||||||||
769 | << FirstPack.first << Name << *CurNumExpansions << NewPackSize | ||||||||
770 | << SourceRange(FirstPack.second) << SourceRange(Loc); | ||||||||
771 | return true; | ||||||||
772 | } | ||||||||
773 | } | ||||||||
774 | |||||||||
775 | if (NumExpansions && CurNumExpansions && | ||||||||
776 | *NumExpansions != *CurNumExpansions) { | ||||||||
777 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) | ||||||||
778 | << FirstPack.first << *CurNumExpansions << *NumExpansions | ||||||||
779 | << SourceRange(FirstPack.second); | ||||||||
780 | return true; | ||||||||
781 | } | ||||||||
782 | |||||||||
783 | // If we're performing a partial expansion but we also have a full expansion, | ||||||||
784 | // expand to the number of common arguments. For example, given: | ||||||||
785 | // | ||||||||
786 | // template<typename ...T> struct A { | ||||||||
787 | // template<typename ...U> void f(pair<T, U>...); | ||||||||
788 | // }; | ||||||||
789 | // | ||||||||
790 | // ... a call to 'A<int, int>().f<int>' should expand the pack once and | ||||||||
791 | // retain an expansion. | ||||||||
792 | if (PartialExpansion) { | ||||||||
793 | if (CurNumExpansions && *CurNumExpansions < PartialExpansion->first) { | ||||||||
794 | NamedDecl *PartialPack = | ||||||||
795 | CurrentInstantiationScope->getPartiallySubstitutedPack(); | ||||||||
796 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial) | ||||||||
797 | << PartialPack << PartialExpansion->first << *CurNumExpansions | ||||||||
798 | << SourceRange(PartialExpansion->second); | ||||||||
799 | return true; | ||||||||
800 | } | ||||||||
801 | NumExpansions = PartialExpansion->first; | ||||||||
802 | } else { | ||||||||
803 | NumExpansions = CurNumExpansions; | ||||||||
804 | } | ||||||||
805 | |||||||||
806 | return false; | ||||||||
807 | } | ||||||||
808 | |||||||||
809 | Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T, | ||||||||
810 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||
811 | QualType Pattern = cast<PackExpansionType>(T)->getPattern(); | ||||||||
812 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||
813 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern); | ||||||||
814 | |||||||||
815 | Optional<unsigned> Result; | ||||||||
816 | auto setResultSz = [&Result](unsigned Size) { | ||||||||
817 | assert((!Result || *Result == Size) && "inconsistent pack sizes")(static_cast <bool> ((!Result || *Result == Size) && "inconsistent pack sizes") ? void (0) : __assert_fail ("(!Result || *Result == Size) && \"inconsistent pack sizes\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 817, __extension__ __PRETTY_FUNCTION__)); | ||||||||
818 | Result = Size; | ||||||||
819 | }; | ||||||||
820 | auto setResultPos = [&](const std::pair<unsigned, unsigned> &Pos) -> bool { | ||||||||
821 | unsigned Depth = Pos.first, Index = Pos.second; | ||||||||
822 | if (Depth >= TemplateArgs.getNumLevels() || | ||||||||
823 | !TemplateArgs.hasTemplateArgument(Depth, Index)) | ||||||||
824 | // The pattern refers to an unknown template argument. We're not ready to | ||||||||
825 | // expand this pack yet. | ||||||||
826 | return true; | ||||||||
827 | // Determine the size of the argument pack. | ||||||||
828 | setResultSz(TemplateArgs(Depth, Index).pack_size()); | ||||||||
829 | return false; | ||||||||
830 | }; | ||||||||
831 | |||||||||
832 | for (auto [I, _] : Unexpanded) { | ||||||||
833 | if (const auto *TTP = I.dyn_cast<const TemplateTypeParmType *>()) { | ||||||||
834 | if (setResultPos({TTP->getDepth(), TTP->getIndex()})) | ||||||||
835 | return std::nullopt; | ||||||||
836 | } else if (const auto *STP = | ||||||||
837 | I.dyn_cast<const SubstTemplateTypeParmPackType *>()) { | ||||||||
838 | setResultSz(STP->getNumArgs()); | ||||||||
839 | } else if (const auto *SEP = | ||||||||
840 | I.dyn_cast<const SubstNonTypeTemplateParmPackExpr *>()) { | ||||||||
841 | setResultSz(SEP->getArgumentPack().pack_size()); | ||||||||
842 | } else { | ||||||||
843 | const auto *ND = I.get<const NamedDecl *>(); | ||||||||
844 | // Function parameter pack or init-capture pack. | ||||||||
845 | if (isa<VarDecl>(ND)) { | ||||||||
846 | const auto *DAP = | ||||||||
847 | CurrentInstantiationScope->findInstantiationOf(ND) | ||||||||
848 | ->dyn_cast<LocalInstantiationScope::DeclArgumentPack *>(); | ||||||||
849 | if (!DAP) | ||||||||
850 | // The pattern refers to an unexpanded pack. We're not ready to expand | ||||||||
851 | // this pack yet. | ||||||||
852 | return std::nullopt; | ||||||||
853 | setResultSz(DAP->size()); | ||||||||
854 | } else if (setResultPos(getDepthAndIndex(ND))) { | ||||||||
855 | return std::nullopt; | ||||||||
856 | } | ||||||||
857 | } | ||||||||
858 | } | ||||||||
859 | |||||||||
860 | return Result; | ||||||||
861 | } | ||||||||
862 | |||||||||
863 | bool Sema::containsUnexpandedParameterPacks(Declarator &D) { | ||||||||
864 | const DeclSpec &DS = D.getDeclSpec(); | ||||||||
865 | switch (DS.getTypeSpecType()) { | ||||||||
866 | case TST_typename: | ||||||||
867 | case TST_typeof_unqualType: | ||||||||
868 | case TST_typeofType: | ||||||||
869 | #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: | ||||||||
870 | #include "clang/Basic/TransformTypeTraits.def" | ||||||||
871 | case TST_atomic: { | ||||||||
872 | QualType T = DS.getRepAsType().get(); | ||||||||
873 | if (!T.isNull() && T->containsUnexpandedParameterPack()) | ||||||||
874 | return true; | ||||||||
875 | break; | ||||||||
876 | } | ||||||||
877 | |||||||||
878 | case TST_typeof_unqualExpr: | ||||||||
879 | case TST_typeofExpr: | ||||||||
880 | case TST_decltype: | ||||||||
881 | case TST_bitint: | ||||||||
882 | if (DS.getRepAsExpr() && | ||||||||
883 | DS.getRepAsExpr()->containsUnexpandedParameterPack()) | ||||||||
884 | return true; | ||||||||
885 | break; | ||||||||
886 | |||||||||
887 | case TST_unspecified: | ||||||||
888 | case TST_void: | ||||||||
889 | case TST_char: | ||||||||
890 | case TST_wchar: | ||||||||
891 | case TST_char8: | ||||||||
892 | case TST_char16: | ||||||||
893 | case TST_char32: | ||||||||
894 | case TST_int: | ||||||||
895 | case TST_int128: | ||||||||
896 | case TST_half: | ||||||||
897 | case TST_float: | ||||||||
898 | case TST_double: | ||||||||
899 | case TST_Accum: | ||||||||
900 | case TST_Fract: | ||||||||
901 | case TST_Float16: | ||||||||
902 | case TST_float128: | ||||||||
903 | case TST_ibm128: | ||||||||
904 | case TST_bool: | ||||||||
905 | case TST_decimal32: | ||||||||
906 | case TST_decimal64: | ||||||||
907 | case TST_decimal128: | ||||||||
908 | case TST_enum: | ||||||||
909 | case TST_union: | ||||||||
910 | case TST_struct: | ||||||||
911 | case TST_interface: | ||||||||
912 | case TST_class: | ||||||||
913 | case TST_auto: | ||||||||
914 | case TST_auto_type: | ||||||||
915 | case TST_decltype_auto: | ||||||||
916 | case TST_BFloat16: | ||||||||
917 | #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: | ||||||||
918 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||||
919 | case TST_unknown_anytype: | ||||||||
920 | case TST_error: | ||||||||
921 | break; | ||||||||
922 | } | ||||||||
923 | |||||||||
924 | for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) { | ||||||||
925 | const DeclaratorChunk &Chunk = D.getTypeObject(I); | ||||||||
926 | switch (Chunk.Kind) { | ||||||||
927 | case DeclaratorChunk::Pointer: | ||||||||
928 | case DeclaratorChunk::Reference: | ||||||||
929 | case DeclaratorChunk::Paren: | ||||||||
930 | case DeclaratorChunk::Pipe: | ||||||||
931 | case DeclaratorChunk::BlockPointer: | ||||||||
932 | // These declarator chunks cannot contain any parameter packs. | ||||||||
933 | break; | ||||||||
934 | |||||||||
935 | case DeclaratorChunk::Array: | ||||||||
936 | if (Chunk.Arr.NumElts && | ||||||||
937 | Chunk.Arr.NumElts->containsUnexpandedParameterPack()) | ||||||||
938 | return true; | ||||||||
939 | break; | ||||||||
940 | case DeclaratorChunk::Function: | ||||||||
941 | for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) { | ||||||||
942 | ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param); | ||||||||
943 | QualType ParamTy = Param->getType(); | ||||||||
944 | assert(!ParamTy.isNull() && "Couldn't parse type?")(static_cast <bool> (!ParamTy.isNull() && "Couldn't parse type?" ) ? void (0) : __assert_fail ("!ParamTy.isNull() && \"Couldn't parse type?\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 944, __extension__ __PRETTY_FUNCTION__)); | ||||||||
945 | if (ParamTy->containsUnexpandedParameterPack()) return true; | ||||||||
946 | } | ||||||||
947 | |||||||||
948 | if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) { | ||||||||
949 | for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) { | ||||||||
950 | if (Chunk.Fun.Exceptions[i] | ||||||||
951 | .Ty.get() | ||||||||
952 | ->containsUnexpandedParameterPack()) | ||||||||
953 | return true; | ||||||||
954 | } | ||||||||
955 | } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) && | ||||||||
956 | Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack()) | ||||||||
957 | return true; | ||||||||
958 | |||||||||
959 | if (Chunk.Fun.hasTrailingReturnType()) { | ||||||||
960 | QualType T = Chunk.Fun.getTrailingReturnType().get(); | ||||||||
961 | if (!T.isNull() && T->containsUnexpandedParameterPack()) | ||||||||
962 | return true; | ||||||||
963 | } | ||||||||
964 | break; | ||||||||
965 | |||||||||
966 | case DeclaratorChunk::MemberPointer: | ||||||||
967 | if (Chunk.Mem.Scope().getScopeRep() && | ||||||||
968 | Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack()) | ||||||||
969 | return true; | ||||||||
970 | break; | ||||||||
971 | } | ||||||||
972 | } | ||||||||
973 | |||||||||
974 | if (Expr *TRC = D.getTrailingRequiresClause()) | ||||||||
975 | if (TRC->containsUnexpandedParameterPack()) | ||||||||
976 | return true; | ||||||||
977 | |||||||||
978 | return false; | ||||||||
979 | } | ||||||||
980 | |||||||||
981 | namespace { | ||||||||
982 | |||||||||
983 | // Callback to only accept typo corrections that refer to parameter packs. | ||||||||
984 | class ParameterPackValidatorCCC final : public CorrectionCandidateCallback { | ||||||||
985 | public: | ||||||||
986 | bool ValidateCandidate(const TypoCorrection &candidate) override { | ||||||||
987 | NamedDecl *ND = candidate.getCorrectionDecl(); | ||||||||
988 | return ND && ND->isParameterPack(); | ||||||||
989 | } | ||||||||
990 | |||||||||
991 | std::unique_ptr<CorrectionCandidateCallback> clone() override { | ||||||||
992 | return std::make_unique<ParameterPackValidatorCCC>(*this); | ||||||||
993 | } | ||||||||
994 | }; | ||||||||
995 | |||||||||
996 | } | ||||||||
997 | |||||||||
998 | /// Called when an expression computing the size of a parameter pack | ||||||||
999 | /// is parsed. | ||||||||
1000 | /// | ||||||||
1001 | /// \code | ||||||||
1002 | /// template<typename ...Types> struct count { | ||||||||
1003 | /// static const unsigned value = sizeof...(Types); | ||||||||
1004 | /// }; | ||||||||
1005 | /// \endcode | ||||||||
1006 | /// | ||||||||
1007 | // | ||||||||
1008 | /// \param OpLoc The location of the "sizeof" keyword. | ||||||||
1009 | /// \param Name The name of the parameter pack whose size will be determined. | ||||||||
1010 | /// \param NameLoc The source location of the name of the parameter pack. | ||||||||
1011 | /// \param RParenLoc The location of the closing parentheses. | ||||||||
1012 | ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, | ||||||||
1013 | SourceLocation OpLoc, | ||||||||
1014 | IdentifierInfo &Name, | ||||||||
1015 | SourceLocation NameLoc, | ||||||||
1016 | SourceLocation RParenLoc) { | ||||||||
1017 | // C++0x [expr.sizeof]p5: | ||||||||
1018 | // The identifier in a sizeof... expression shall name a parameter pack. | ||||||||
1019 | LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName); | ||||||||
1020 | LookupName(R, S); | ||||||||
1021 | |||||||||
1022 | NamedDecl *ParameterPack = nullptr; | ||||||||
1023 | switch (R.getResultKind()) { | ||||||||
1024 | case LookupResult::Found: | ||||||||
1025 | ParameterPack = R.getFoundDecl(); | ||||||||
1026 | break; | ||||||||
1027 | |||||||||
1028 | case LookupResult::NotFound: | ||||||||
1029 | case LookupResult::NotFoundInCurrentInstantiation: { | ||||||||
1030 | ParameterPackValidatorCCC CCC{}; | ||||||||
1031 | if (TypoCorrection Corrected = | ||||||||
1032 | CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr, | ||||||||
1033 | CCC, CTK_ErrorRecovery)) { | ||||||||
1034 | diagnoseTypo(Corrected, | ||||||||
1035 | PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name, | ||||||||
1036 | PDiag(diag::note_parameter_pack_here)); | ||||||||
1037 | ParameterPack = Corrected.getCorrectionDecl(); | ||||||||
1038 | } | ||||||||
1039 | break; | ||||||||
1040 | } | ||||||||
1041 | case LookupResult::FoundOverloaded: | ||||||||
1042 | case LookupResult::FoundUnresolvedValue: | ||||||||
1043 | break; | ||||||||
1044 | |||||||||
1045 | case LookupResult::Ambiguous: | ||||||||
1046 | DiagnoseAmbiguousLookup(R); | ||||||||
1047 | return ExprError(); | ||||||||
1048 | } | ||||||||
1049 | |||||||||
1050 | if (!ParameterPack || !ParameterPack->isParameterPack()) { | ||||||||
1051 | Diag(NameLoc, diag::err_sizeof_pack_no_pack_name) | ||||||||
1052 | << &Name; | ||||||||
1053 | return ExprError(); | ||||||||
1054 | } | ||||||||
1055 | |||||||||
1056 | MarkAnyDeclReferenced(OpLoc, ParameterPack, true); | ||||||||
1057 | |||||||||
1058 | return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc, | ||||||||
1059 | RParenLoc); | ||||||||
1060 | } | ||||||||
1061 | |||||||||
1062 | TemplateArgumentLoc | ||||||||
1063 | Sema::getTemplateArgumentPackExpansionPattern( | ||||||||
1064 | TemplateArgumentLoc OrigLoc, | ||||||||
1065 | SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const { | ||||||||
1066 | const TemplateArgument &Argument = OrigLoc.getArgument(); | ||||||||
1067 | assert(Argument.isPackExpansion())(static_cast <bool> (Argument.isPackExpansion()) ? void (0) : __assert_fail ("Argument.isPackExpansion()", "clang/lib/Sema/SemaTemplateVariadic.cpp" , 1067, __extension__ __PRETTY_FUNCTION__)); | ||||||||
1068 | switch (Argument.getKind()) { | ||||||||
1069 | case TemplateArgument::Type: { | ||||||||
1070 | // FIXME: We shouldn't ever have to worry about missing | ||||||||
1071 | // type-source info! | ||||||||
1072 | TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo(); | ||||||||
1073 | if (!ExpansionTSInfo) | ||||||||
1074 | ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(), | ||||||||
1075 | Ellipsis); | ||||||||
1076 | PackExpansionTypeLoc Expansion = | ||||||||
1077 | ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>(); | ||||||||
1078 | Ellipsis = Expansion.getEllipsisLoc(); | ||||||||
1079 | |||||||||
1080 | TypeLoc Pattern = Expansion.getPatternLoc(); | ||||||||
1081 | NumExpansions = Expansion.getTypePtr()->getNumExpansions(); | ||||||||
1082 | |||||||||
1083 | // We need to copy the TypeLoc because TemplateArgumentLocs store a | ||||||||
1084 | // TypeSourceInfo. | ||||||||
1085 | // FIXME: Find some way to avoid the copy? | ||||||||
1086 | TypeLocBuilder TLB; | ||||||||
1087 | TLB.pushFullCopy(Pattern); | ||||||||
1088 | TypeSourceInfo *PatternTSInfo = | ||||||||
1089 | TLB.getTypeSourceInfo(Context, Pattern.getType()); | ||||||||
1090 | return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), | ||||||||
1091 | PatternTSInfo); | ||||||||
1092 | } | ||||||||
1093 | |||||||||
1094 | case TemplateArgument::Expression: { | ||||||||
1095 | PackExpansionExpr *Expansion | ||||||||
1096 | = cast<PackExpansionExpr>(Argument.getAsExpr()); | ||||||||
1097 | Expr *Pattern = Expansion->getPattern(); | ||||||||
1098 | Ellipsis = Expansion->getEllipsisLoc(); | ||||||||
1099 | NumExpansions = Expansion->getNumExpansions(); | ||||||||
1100 | return TemplateArgumentLoc(Pattern, Pattern); | ||||||||
1101 | } | ||||||||
1102 | |||||||||
1103 | case TemplateArgument::TemplateExpansion: | ||||||||
1104 | Ellipsis = OrigLoc.getTemplateEllipsisLoc(); | ||||||||
1105 | NumExpansions = Argument.getNumTemplateExpansions(); | ||||||||
1106 | return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(), | ||||||||
1107 | OrigLoc.getTemplateQualifierLoc(), | ||||||||
1108 | OrigLoc.getTemplateNameLoc()); | ||||||||
1109 | |||||||||
1110 | case TemplateArgument::Declaration: | ||||||||
1111 | case TemplateArgument::NullPtr: | ||||||||
1112 | case TemplateArgument::Template: | ||||||||
1113 | case TemplateArgument::Integral: | ||||||||
1114 | case TemplateArgument::Pack: | ||||||||
1115 | case TemplateArgument::Null: | ||||||||
1116 | return TemplateArgumentLoc(); | ||||||||
1117 | } | ||||||||
1118 | |||||||||
1119 | llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 1119); | ||||||||
1120 | } | ||||||||
1121 | |||||||||
1122 | Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) { | ||||||||
1123 | assert(Arg.containsUnexpandedParameterPack())(static_cast <bool> (Arg.containsUnexpandedParameterPack ()) ? void (0) : __assert_fail ("Arg.containsUnexpandedParameterPack()" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 1123, __extension__ __PRETTY_FUNCTION__)); | ||||||||
1124 | |||||||||
1125 | // If this is a substituted pack, grab that pack. If not, we don't know | ||||||||
1126 | // the size yet. | ||||||||
1127 | // FIXME: We could find a size in more cases by looking for a substituted | ||||||||
1128 | // pack anywhere within this argument, but that's not necessary in the common | ||||||||
1129 | // case for 'sizeof...(A)' handling. | ||||||||
1130 | TemplateArgument Pack; | ||||||||
1131 | switch (Arg.getKind()) { | ||||||||
1132 | case TemplateArgument::Type: | ||||||||
1133 | if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>()) | ||||||||
1134 | Pack = Subst->getArgumentPack(); | ||||||||
1135 | else | ||||||||
1136 | return std::nullopt; | ||||||||
1137 | break; | ||||||||
1138 | |||||||||
1139 | case TemplateArgument::Expression: | ||||||||
1140 | if (auto *Subst = | ||||||||
1141 | dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr())) | ||||||||
1142 | Pack = Subst->getArgumentPack(); | ||||||||
1143 | else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) { | ||||||||
1144 | for (VarDecl *PD : *Subst) | ||||||||
1145 | if (PD->isParameterPack()) | ||||||||
1146 | return std::nullopt; | ||||||||
1147 | return Subst->getNumExpansions(); | ||||||||
1148 | } else | ||||||||
1149 | return std::nullopt; | ||||||||
1150 | break; | ||||||||
1151 | |||||||||
1152 | case TemplateArgument::Template: | ||||||||
1153 | if (SubstTemplateTemplateParmPackStorage *Subst = | ||||||||
1154 | Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) | ||||||||
1155 | Pack = Subst->getArgumentPack(); | ||||||||
1156 | else | ||||||||
1157 | return std::nullopt; | ||||||||
1158 | break; | ||||||||
1159 | |||||||||
1160 | case TemplateArgument::Declaration: | ||||||||
1161 | case TemplateArgument::NullPtr: | ||||||||
1162 | case TemplateArgument::TemplateExpansion: | ||||||||
1163 | case TemplateArgument::Integral: | ||||||||
1164 | case TemplateArgument::Pack: | ||||||||
1165 | case TemplateArgument::Null: | ||||||||
1166 | return std::nullopt; | ||||||||
1167 | } | ||||||||
1168 | |||||||||
1169 | // Check that no argument in the pack is itself a pack expansion. | ||||||||
1170 | for (TemplateArgument Elem : Pack.pack_elements()) { | ||||||||
1171 | // There's no point recursing in this case; we would have already | ||||||||
1172 | // expanded this pack expansion into the enclosing pack if we could. | ||||||||
1173 | if (Elem.isPackExpansion()) | ||||||||
1174 | return std::nullopt; | ||||||||
1175 | } | ||||||||
1176 | return Pack.pack_size(); | ||||||||
1177 | } | ||||||||
1178 | |||||||||
1179 | static void CheckFoldOperand(Sema &S, Expr *E) { | ||||||||
1180 | if (!E) | ||||||||
1181 | return; | ||||||||
1182 | |||||||||
1183 | E = E->IgnoreImpCasts(); | ||||||||
1184 | auto *OCE = dyn_cast<CXXOperatorCallExpr>(E); | ||||||||
1185 | if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) || | ||||||||
1186 | isa<AbstractConditionalOperator>(E)) { | ||||||||
1187 | S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand) | ||||||||
1188 | << E->getSourceRange() | ||||||||
1189 | << FixItHint::CreateInsertion(E->getBeginLoc(), "(") | ||||||||
1190 | << FixItHint::CreateInsertion(E->getEndLoc(), ")"); | ||||||||
1191 | } | ||||||||
1192 | } | ||||||||
1193 | |||||||||
1194 | ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, | ||||||||
1195 | tok::TokenKind Operator, | ||||||||
1196 | SourceLocation EllipsisLoc, Expr *RHS, | ||||||||
1197 | SourceLocation RParenLoc) { | ||||||||
1198 | // LHS and RHS must be cast-expressions. We allow an arbitrary expression | ||||||||
1199 | // in the parser and reduce down to just cast-expressions here. | ||||||||
1200 | CheckFoldOperand(*this, LHS); | ||||||||
1201 | CheckFoldOperand(*this, RHS); | ||||||||
1202 | |||||||||
1203 | auto DiscardOperands = [&] { | ||||||||
1204 | CorrectDelayedTyposInExpr(LHS); | ||||||||
1205 | CorrectDelayedTyposInExpr(RHS); | ||||||||
1206 | }; | ||||||||
1207 | |||||||||
1208 | // [expr.prim.fold]p3: | ||||||||
1209 | // In a binary fold, op1 and op2 shall be the same fold-operator, and | ||||||||
1210 | // either e1 shall contain an unexpanded parameter pack or e2 shall contain | ||||||||
1211 | // an unexpanded parameter pack, but not both. | ||||||||
1212 | if (LHS && RHS && | ||||||||
1213 | LHS->containsUnexpandedParameterPack() == | ||||||||
1214 | RHS->containsUnexpandedParameterPack()) { | ||||||||
1215 | DiscardOperands(); | ||||||||
1216 | return Diag(EllipsisLoc, | ||||||||
1217 | LHS->containsUnexpandedParameterPack() | ||||||||
1218 | ? diag::err_fold_expression_packs_both_sides | ||||||||
1219 | : diag::err_pack_expansion_without_parameter_packs) | ||||||||
1220 | << LHS->getSourceRange() << RHS->getSourceRange(); | ||||||||
1221 | } | ||||||||
1222 | |||||||||
1223 | // [expr.prim.fold]p2: | ||||||||
1224 | // In a unary fold, the cast-expression shall contain an unexpanded | ||||||||
1225 | // parameter pack. | ||||||||
1226 | if (!LHS || !RHS) { | ||||||||
1227 | Expr *Pack = LHS ? LHS : RHS; | ||||||||
1228 | assert(Pack && "fold expression with neither LHS nor RHS")(static_cast <bool> (Pack && "fold expression with neither LHS nor RHS" ) ? void (0) : __assert_fail ("Pack && \"fold expression with neither LHS nor RHS\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 1228, __extension__ __PRETTY_FUNCTION__)); | ||||||||
1229 | DiscardOperands(); | ||||||||
1230 | if (!Pack->containsUnexpandedParameterPack()) | ||||||||
1231 | return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | ||||||||
1232 | << Pack->getSourceRange(); | ||||||||
1233 | } | ||||||||
1234 | |||||||||
1235 | BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator); | ||||||||
1236 | |||||||||
1237 | // Perform first-phase name lookup now. | ||||||||
1238 | UnresolvedLookupExpr *ULE = nullptr; | ||||||||
1239 | { | ||||||||
1240 | UnresolvedSet<16> Functions; | ||||||||
1241 | LookupBinOp(S, EllipsisLoc, Opc, Functions); | ||||||||
1242 | if (!Functions.empty()) { | ||||||||
1243 | DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName( | ||||||||
1244 | BinaryOperator::getOverloadedOperator(Opc)); | ||||||||
1245 | ExprResult Callee = CreateUnresolvedLookupExpr( | ||||||||
1246 | /*NamingClass*/ nullptr, NestedNameSpecifierLoc(), | ||||||||
1247 | DeclarationNameInfo(OpName, EllipsisLoc), Functions); | ||||||||
1248 | if (Callee.isInvalid()) | ||||||||
1249 | return ExprError(); | ||||||||
1250 | ULE = cast<UnresolvedLookupExpr>(Callee.get()); | ||||||||
1251 | } | ||||||||
1252 | } | ||||||||
1253 | |||||||||
1254 | return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc, | ||||||||
1255 | std::nullopt); | ||||||||
1256 | } | ||||||||
1257 | |||||||||
1258 | ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, | ||||||||
1259 | SourceLocation LParenLoc, Expr *LHS, | ||||||||
1260 | BinaryOperatorKind Operator, | ||||||||
1261 | SourceLocation EllipsisLoc, Expr *RHS, | ||||||||
1262 | SourceLocation RParenLoc, | ||||||||
1263 | Optional<unsigned> NumExpansions) { | ||||||||
1264 | return new (Context) | ||||||||
1265 | CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator, | ||||||||
1266 | EllipsisLoc, RHS, RParenLoc, NumExpansions); | ||||||||
1267 | } | ||||||||
1268 | |||||||||
1269 | ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, | ||||||||
1270 | BinaryOperatorKind Operator) { | ||||||||
1271 | // [temp.variadic]p9: | ||||||||
1272 | // If N is zero for a unary fold-expression, the value of the expression is | ||||||||
1273 | // && -> true | ||||||||
1274 | // || -> false | ||||||||
1275 | // , -> void() | ||||||||
1276 | // if the operator is not listed [above], the instantiation is ill-formed. | ||||||||
1277 | // | ||||||||
1278 | // Note that we need to use something like int() here, not merely 0, to | ||||||||
1279 | // prevent the result from being a null pointer constant. | ||||||||
1280 | QualType ScalarType; | ||||||||
1281 | switch (Operator) { | ||||||||
1282 | case BO_LOr: | ||||||||
1283 | return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false); | ||||||||
1284 | case BO_LAnd: | ||||||||
1285 | return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true); | ||||||||
1286 | case BO_Comma: | ||||||||
1287 | ScalarType = Context.VoidTy; | ||||||||
1288 | break; | ||||||||
1289 | |||||||||
1290 | default: | ||||||||
1291 | return Diag(EllipsisLoc, diag::err_fold_expression_empty) | ||||||||
1292 | << BinaryOperator::getOpcodeStr(Operator); | ||||||||
1293 | } | ||||||||
1294 | |||||||||
1295 | return new (Context) CXXScalarValueInitExpr( | ||||||||
1296 | ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc), | ||||||||
1297 | EllipsisLoc); | ||||||||
1298 | } |
1 | //===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- 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 | /// This file defines the PointerUnion class, which is a discriminated union of |
11 | /// pointer types. |
12 | /// |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_ADT_POINTERUNION_H |
16 | #define LLVM_ADT_POINTERUNION_H |
17 | |
18 | #include "llvm/ADT/DenseMapInfo.h" |
19 | #include "llvm/ADT/PointerIntPair.h" |
20 | #include "llvm/ADT/STLExtras.h" |
21 | #include "llvm/Support/Casting.h" |
22 | #include "llvm/Support/PointerLikeTypeTraits.h" |
23 | #include <algorithm> |
24 | #include <cassert> |
25 | #include <cstddef> |
26 | #include <cstdint> |
27 | |
28 | namespace llvm { |
29 | |
30 | namespace pointer_union_detail { |
31 | /// Determine the number of bits required to store integers with values < n. |
32 | /// This is ceil(log2(n)). |
33 | constexpr int bitsRequired(unsigned n) { |
34 | return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0; |
35 | } |
36 | |
37 | template <typename... Ts> constexpr int lowBitsAvailable() { |
38 | return std::min<int>({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...}); |
39 | } |
40 | |
41 | /// Find the first type in a list of types. |
42 | template <typename T, typename...> struct GetFirstType { |
43 | using type = T; |
44 | }; |
45 | |
46 | /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion |
47 | /// for the template arguments. |
48 | template <typename ...PTs> class PointerUnionUIntTraits { |
49 | public: |
50 | static inline void *getAsVoidPointer(void *P) { return P; } |
51 | static inline void *getFromVoidPointer(void *P) { return P; } |
52 | static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>(); |
53 | }; |
54 | |
55 | template <typename Derived, typename ValTy, int I, typename ...Types> |
56 | class PointerUnionMembers; |
57 | |
58 | template <typename Derived, typename ValTy, int I> |
59 | class PointerUnionMembers<Derived, ValTy, I> { |
60 | protected: |
61 | ValTy Val; |
62 | PointerUnionMembers() = default; |
63 | PointerUnionMembers(ValTy Val) : Val(Val) {} |
64 | |
65 | friend struct PointerLikeTypeTraits<Derived>; |
66 | }; |
67 | |
68 | template <typename Derived, typename ValTy, int I, typename Type, |
69 | typename ...Types> |
70 | class PointerUnionMembers<Derived, ValTy, I, Type, Types...> |
71 | : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> { |
72 | using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>; |
73 | public: |
74 | using Base::Base; |
75 | PointerUnionMembers() = default; |
76 | PointerUnionMembers(Type V) |
77 | : Base(ValTy(const_cast<void *>( |
78 | PointerLikeTypeTraits<Type>::getAsVoidPointer(V)), |
79 | I)) {} |
80 | |
81 | using Base::operator=; |
82 | Derived &operator=(Type V) { |
83 | this->Val = ValTy( |
84 | const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)), |
85 | I); |
86 | return static_cast<Derived &>(*this); |
87 | }; |
88 | }; |
89 | } |
90 | |
91 | // This is a forward declaration of CastInfoPointerUnionImpl |
92 | // Refer to its definition below for further details |
93 | template <typename... PTs> struct CastInfoPointerUnionImpl; |
94 | /// A discriminated union of two or more pointer types, with the discriminator |
95 | /// in the low bit of the pointer. |
96 | /// |
97 | /// This implementation is extremely efficient in space due to leveraging the |
98 | /// low bits of the pointer, while exposing a natural and type-safe API. |
99 | /// |
100 | /// Common use patterns would be something like this: |
101 | /// PointerUnion<int*, float*> P; |
102 | /// P = (int*)0; |
103 | /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0" |
104 | /// X = P.get<int*>(); // ok. |
105 | /// Y = P.get<float*>(); // runtime assertion failure. |
106 | /// Z = P.get<double*>(); // compile time failure. |
107 | /// P = (float*)0; |
108 | /// Y = P.get<float*>(); // ok. |
109 | /// X = P.get<int*>(); // runtime assertion failure. |
110 | /// PointerUnion<int*, int*> Q; // compile time failure. |
111 | template <typename... PTs> |
112 | class PointerUnion |
113 | : public pointer_union_detail::PointerUnionMembers< |
114 | PointerUnion<PTs...>, |
115 | PointerIntPair< |
116 | void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int, |
117 | pointer_union_detail::PointerUnionUIntTraits<PTs...>>, |
118 | 0, PTs...> { |
119 | static_assert(TypesAreDistinct<PTs...>::value, |
120 | "PointerUnion alternative types cannot be repeated"); |
121 | // The first type is special because we want to directly cast a pointer to a |
122 | // default-initialized union to a pointer to the first type. But we don't |
123 | // want PointerUnion to be a 'template <typename First, typename ...Rest>' |
124 | // because it's much more convenient to have a name for the whole pack. So |
125 | // split off the first type here. |
126 | using First = TypeAtIndex<0, PTs...>; |
127 | using Base = typename PointerUnion::PointerUnionMembers; |
128 | |
129 | /// This is needed to give the CastInfo implementation below access |
130 | /// to protected members. |
131 | /// Refer to its definition for further details. |
132 | friend struct CastInfoPointerUnionImpl<PTs...>; |
133 | |
134 | public: |
135 | PointerUnion() = default; |
136 | |
137 | PointerUnion(std::nullptr_t) : PointerUnion() {} |
138 | using Base::Base; |
139 | |
140 | /// Test if the pointer held in the union is null, regardless of |
141 | /// which type it is. |
142 | bool isNull() const { return !this->Val.getPointer(); } |
143 | |
144 | explicit operator bool() const { return !isNull(); } |
145 | |
146 | // FIXME: Replace the uses of is(), get() and dyn_cast() with |
147 | // isa<T>, cast<T> and the llvm::dyn_cast<T> |
148 | |
149 | /// Test if the Union currently holds the type matching T. |
150 | template <typename T> inline bool is() const { return isa<T>(*this); } |
151 | |
152 | /// Returns the value of the specified pointer type. |
153 | /// |
154 | /// If the specified pointer type is incorrect, assert. |
155 | template <typename T> inline T get() const { |
156 | assert(isa<T>(*this) && "Invalid accessor called")(static_cast <bool> (isa<T>(*this) && "Invalid accessor called" ) ? void (0) : __assert_fail ("isa<T>(*this) && \"Invalid accessor called\"" , "llvm/include/llvm/ADT/PointerUnion.h", 156, __extension__ __PRETTY_FUNCTION__ )); |
157 | return cast<T>(*this); |
158 | } |
159 | |
160 | /// Returns the current pointer if it is of the specified pointer type, |
161 | /// otherwise returns null. |
162 | template <typename T> inline T dyn_cast() const { |
163 | return llvm::dyn_cast_if_present<T>(*this); |
164 | } |
165 | |
166 | /// If the union is set to the first pointer type get an address pointing to |
167 | /// it. |
168 | First const *getAddrOfPtr1() const { |
169 | return const_cast<PointerUnion *>(this)->getAddrOfPtr1(); |
170 | } |
171 | |
172 | /// If the union is set to the first pointer type get an address pointing to |
173 | /// it. |
174 | First *getAddrOfPtr1() { |
175 | assert(is<First>() && "Val is not the first pointer")(static_cast <bool> (is<First>() && "Val is not the first pointer" ) ? void (0) : __assert_fail ("is<First>() && \"Val is not the first pointer\"" , "llvm/include/llvm/ADT/PointerUnion.h", 175, __extension__ __PRETTY_FUNCTION__ )); |
176 | assert((static_cast <bool> (PointerLikeTypeTraits<First> ::getAsVoidPointer(get<First>()) == this->Val.getPointer () && "Can't get the address because PointerLikeTypeTraits changes the ptr" ) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\"" , "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__ )) |
177 | PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) ==(static_cast <bool> (PointerLikeTypeTraits<First> ::getAsVoidPointer(get<First>()) == this->Val.getPointer () && "Can't get the address because PointerLikeTypeTraits changes the ptr" ) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\"" , "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__ )) |
178 | this->Val.getPointer() &&(static_cast <bool> (PointerLikeTypeTraits<First> ::getAsVoidPointer(get<First>()) == this->Val.getPointer () && "Can't get the address because PointerLikeTypeTraits changes the ptr" ) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\"" , "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__ )) |
179 | "Can't get the address because PointerLikeTypeTraits changes the ptr")(static_cast <bool> (PointerLikeTypeTraits<First> ::getAsVoidPointer(get<First>()) == this->Val.getPointer () && "Can't get the address because PointerLikeTypeTraits changes the ptr" ) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\"" , "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__ )); |
180 | return const_cast<First *>( |
181 | reinterpret_cast<const First *>(this->Val.getAddrOfPointer())); |
182 | } |
183 | |
184 | /// Assignment from nullptr which just clears the union. |
185 | const PointerUnion &operator=(std::nullptr_t) { |
186 | this->Val.initWithPointer(nullptr); |
187 | return *this; |
188 | } |
189 | |
190 | /// Assignment from elements of the union. |
191 | using Base::operator=; |
192 | |
193 | void *getOpaqueValue() const { return this->Val.getOpaqueValue(); } |
194 | static inline PointerUnion getFromOpaqueValue(void *VP) { |
195 | PointerUnion V; |
196 | V.Val = decltype(V.Val)::getFromOpaqueValue(VP); |
197 | return V; |
198 | } |
199 | }; |
200 | |
201 | template <typename ...PTs> |
202 | bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
203 | return lhs.getOpaqueValue() == rhs.getOpaqueValue(); |
204 | } |
205 | |
206 | template <typename ...PTs> |
207 | bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
208 | return lhs.getOpaqueValue() != rhs.getOpaqueValue(); |
209 | } |
210 | |
211 | template <typename ...PTs> |
212 | bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
213 | return lhs.getOpaqueValue() < rhs.getOpaqueValue(); |
214 | } |
215 | |
216 | /// We can't (at least, at this moment with C++14) declare CastInfo |
217 | /// as a friend of PointerUnion like this: |
218 | /// ``` |
219 | /// template<typename To> |
220 | /// friend struct CastInfo<To, PointerUnion<PTs...>>; |
221 | /// ``` |
222 | /// The compiler complains 'Partial specialization cannot be declared as a |
223 | /// friend'. |
224 | /// So we define this struct to be a bridge between CastInfo and |
225 | /// PointerUnion. |
226 | template <typename... PTs> struct CastInfoPointerUnionImpl { |
227 | using From = PointerUnion<PTs...>; |
228 | |
229 | template <typename To> static inline bool isPossible(From &F) { |
230 | return F.Val.getInt() == FirstIndexOfType<To, PTs...>::value; |
231 | } |
232 | |
233 | template <typename To> static To doCast(From &F) { |
234 | assert(isPossible<To>(F) && "cast to an incompatible type !")(static_cast <bool> (isPossible<To>(F) && "cast to an incompatible type !") ? void (0) : __assert_fail ("isPossible<To>(F) && \"cast to an incompatible type !\"" , "llvm/include/llvm/ADT/PointerUnion.h", 234, __extension__ __PRETTY_FUNCTION__ )); |
235 | return PointerLikeTypeTraits<To>::getFromVoidPointer(F.Val.getPointer()); |
236 | } |
237 | }; |
238 | |
239 | // Specialization of CastInfo for PointerUnion |
240 | template <typename To, typename... PTs> |
241 | struct CastInfo<To, PointerUnion<PTs...>> |
242 | : public DefaultDoCastIfPossible<To, PointerUnion<PTs...>, |
243 | CastInfo<To, PointerUnion<PTs...>>> { |
244 | using From = PointerUnion<PTs...>; |
245 | using Impl = CastInfoPointerUnionImpl<PTs...>; |
246 | |
247 | static inline bool isPossible(From &f) { |
248 | return Impl::template isPossible<To>(f); |
249 | } |
250 | |
251 | static To doCast(From &f) { return Impl::template doCast<To>(f); } |
252 | |
253 | static inline To castFailed() { return To(); } |
254 | }; |
255 | |
256 | template <typename To, typename... PTs> |
257 | struct CastInfo<To, const PointerUnion<PTs...>> |
258 | : public ConstStrippingForwardingCast<To, const PointerUnion<PTs...>, |
259 | CastInfo<To, PointerUnion<PTs...>>> { |
260 | }; |
261 | |
262 | // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has |
263 | // # low bits available = min(PT1bits,PT2bits)-1. |
264 | template <typename ...PTs> |
265 | struct PointerLikeTypeTraits<PointerUnion<PTs...>> { |
266 | static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) { |
267 | return P.getOpaqueValue(); |
268 | } |
269 | |
270 | static inline PointerUnion<PTs...> getFromVoidPointer(void *P) { |
271 | return PointerUnion<PTs...>::getFromOpaqueValue(P); |
272 | } |
273 | |
274 | // The number of bits available are the min of the pointer types minus the |
275 | // bits needed for the discriminator. |
276 | static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype( |
277 | PointerUnion<PTs...>::Val)>::NumLowBitsAvailable; |
278 | }; |
279 | |
280 | // Teach DenseMap how to use PointerUnions as keys. |
281 | template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> { |
282 | using Union = PointerUnion<PTs...>; |
283 | using FirstInfo = |
284 | DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>; |
285 | |
286 | static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); } |
287 | |
288 | static inline Union getTombstoneKey() { |
289 | return Union(FirstInfo::getTombstoneKey()); |
290 | } |
291 | |
292 | static unsigned getHashValue(const Union &UnionVal) { |
293 | intptr_t key = (intptr_t)UnionVal.getOpaqueValue(); |
294 | return DenseMapInfo<intptr_t>::getHashValue(key); |
295 | } |
296 | |
297 | static bool isEqual(const Union &LHS, const Union &RHS) { |
298 | return LHS == RHS; |
299 | } |
300 | }; |
301 | |
302 | } // end namespace llvm |
303 | |
304 | #endif // LLVM_ADT_POINTERUNION_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>(), |
10 | // cast_if_present<X>(), and dyn_cast_if_present<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 <optional> |
22 | #include <type_traits> |
23 | |
24 | namespace llvm { |
25 | |
26 | //===----------------------------------------------------------------------===// |
27 | // simplify_type |
28 | //===----------------------------------------------------------------------===// |
29 | |
30 | /// Define a template that can be specialized by smart pointers to reflect the |
31 | /// fact that they are automatically dereferenced, and are not involved with the |
32 | /// template selection process... the default implementation is a noop. |
33 | // TODO: rename this and/or replace it with other cast traits. |
34 | template <typename From> struct simplify_type { |
35 | using SimpleType = From; // The real type this represents... |
36 | |
37 | // An accessor to get the real value... |
38 | static SimpleType &getSimplifiedValue(From &Val) { return Val; } |
39 | }; |
40 | |
41 | template <typename From> struct simplify_type<const From> { |
42 | using NonConstSimpleType = typename simplify_type<From>::SimpleType; |
43 | using SimpleType = 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 | // TODO: add this namespace once everyone is switched to using the new |
53 | // interface. |
54 | // namespace detail { |
55 | |
56 | //===----------------------------------------------------------------------===// |
57 | // isa_impl |
58 | //===----------------------------------------------------------------------===// |
59 | |
60 | // The core of the implementation of isa<X> is here; To and From should be |
61 | // the names of classes. This template can be specialized to customize the |
62 | // implementation of isa<> without rewriting it from scratch. |
63 | template <typename To, typename From, typename Enabler = void> struct isa_impl { |
64 | static inline bool doit(const From &Val) { return To::classof(&Val); } |
65 | }; |
66 | |
67 | // Always allow upcasts, and perform no dynamic check for them. |
68 | template <typename To, typename From> |
69 | struct isa_impl<To, From, std::enable_if_t<std::is_base_of<To, From>::value>> { |
70 | static inline bool doit(const From &) { return true; } |
71 | }; |
72 | |
73 | template <typename To, typename From> struct isa_impl_cl { |
74 | static inline bool doit(const From &Val) { |
75 | return isa_impl<To, From>::doit(Val); |
76 | } |
77 | }; |
78 | |
79 | template <typename To, typename From> struct isa_impl_cl<To, const From> { |
80 | static inline bool doit(const From &Val) { |
81 | return isa_impl<To, From>::doit(Val); |
82 | } |
83 | }; |
84 | |
85 | template <typename To, typename From> |
86 | struct isa_impl_cl<To, const std::unique_ptr<From>> { |
87 | static inline bool doit(const std::unique_ptr<From> &Val) { |
88 | 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\"" , "llvm/include/llvm/Support/Casting.h", 88, __extension__ __PRETTY_FUNCTION__ )); |
89 | return isa_impl_cl<To, From>::doit(*Val); |
90 | } |
91 | }; |
92 | |
93 | template <typename To, typename From> struct isa_impl_cl<To, From *> { |
94 | static inline bool doit(const From *Val) { |
95 | 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\"" , "llvm/include/llvm/Support/Casting.h", 95, __extension__ __PRETTY_FUNCTION__ )); |
96 | return isa_impl<To, From>::doit(*Val); |
97 | } |
98 | }; |
99 | |
100 | template <typename To, typename From> struct isa_impl_cl<To, From *const> { |
101 | static inline bool doit(const From *Val) { |
102 | 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\"" , "llvm/include/llvm/Support/Casting.h", 102, __extension__ __PRETTY_FUNCTION__ )); |
103 | return isa_impl<To, From>::doit(*Val); |
104 | } |
105 | }; |
106 | |
107 | template <typename To, typename From> struct isa_impl_cl<To, const From *> { |
108 | static inline bool doit(const From *Val) { |
109 | 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\"" , "llvm/include/llvm/Support/Casting.h", 109, __extension__ __PRETTY_FUNCTION__ )); |
110 | return isa_impl<To, From>::doit(*Val); |
111 | } |
112 | }; |
113 | |
114 | template <typename To, typename From> |
115 | struct isa_impl_cl<To, const From *const> { |
116 | static inline bool doit(const From *Val) { |
117 | 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\"" , "llvm/include/llvm/Support/Casting.h", 117, __extension__ __PRETTY_FUNCTION__ )); |
118 | return isa_impl<To, From>::doit(*Val); |
119 | } |
120 | }; |
121 | |
122 | template <typename To, typename From, typename SimpleFrom> |
123 | struct isa_impl_wrap { |
124 | // When From != SimplifiedType, we can simplify the type some more by using |
125 | // the simplify_type template. |
126 | static bool doit(const From &Val) { |
127 | return isa_impl_wrap<To, SimpleFrom, |
128 | typename simplify_type<SimpleFrom>::SimpleType>:: |
129 | doit(simplify_type<const From>::getSimplifiedValue(Val)); |
130 | } |
131 | }; |
132 | |
133 | template <typename To, typename FromTy> |
134 | struct isa_impl_wrap<To, FromTy, FromTy> { |
135 | // When From == SimpleType, we are as simple as we are going to get. |
136 | static bool doit(const FromTy &Val) { |
137 | return isa_impl_cl<To, FromTy>::doit(Val); |
138 | } |
139 | }; |
140 | |
141 | //===----------------------------------------------------------------------===// |
142 | // cast_retty + cast_retty_impl |
143 | //===----------------------------------------------------------------------===// |
144 | |
145 | template <class To, class From> struct cast_retty; |
146 | |
147 | // Calculate what type the 'cast' function should return, based on a requested |
148 | // type of To and a source type of From. |
149 | template <class To, class From> struct cast_retty_impl { |
150 | using ret_type = To &; // Normal case, return Ty& |
151 | }; |
152 | template <class To, class From> struct cast_retty_impl<To, const From> { |
153 | using ret_type = const To &; // Normal case, return Ty& |
154 | }; |
155 | |
156 | template <class To, class From> struct cast_retty_impl<To, From *> { |
157 | using ret_type = To *; // Pointer arg case, return Ty* |
158 | }; |
159 | |
160 | template <class To, class From> struct cast_retty_impl<To, const From *> { |
161 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
162 | }; |
163 | |
164 | template <class To, class From> struct cast_retty_impl<To, const From *const> { |
165 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
166 | }; |
167 | |
168 | template <class To, class From> |
169 | struct cast_retty_impl<To, std::unique_ptr<From>> { |
170 | private: |
171 | using PointerType = typename cast_retty_impl<To, From *>::ret_type; |
172 | using ResultType = std::remove_pointer_t<PointerType>; |
173 | |
174 | public: |
175 | using ret_type = std::unique_ptr<ResultType>; |
176 | }; |
177 | |
178 | template <class To, class From, class SimpleFrom> struct cast_retty_wrap { |
179 | // When the simplified type and the from type are not the same, use the type |
180 | // simplifier to reduce the type, then reuse cast_retty_impl to get the |
181 | // resultant type. |
182 | using ret_type = typename cast_retty<To, SimpleFrom>::ret_type; |
183 | }; |
184 | |
185 | template <class To, class FromTy> struct cast_retty_wrap<To, FromTy, FromTy> { |
186 | // When the simplified type is equal to the from type, use it directly. |
187 | using ret_type = typename cast_retty_impl<To, FromTy>::ret_type; |
188 | }; |
189 | |
190 | template <class To, class From> struct cast_retty { |
191 | using ret_type = typename cast_retty_wrap< |
192 | To, From, typename simplify_type<From>::SimpleType>::ret_type; |
193 | }; |
194 | |
195 | //===----------------------------------------------------------------------===// |
196 | // cast_convert_val |
197 | //===----------------------------------------------------------------------===// |
198 | |
199 | // Ensure the non-simple values are converted using the simplify_type template |
200 | // that may be specialized by smart pointers... |
201 | // |
202 | template <class To, class From, class SimpleFrom> struct cast_convert_val { |
203 | // This is not a simple type, use the template to simplify it... |
204 | static typename cast_retty<To, From>::ret_type doit(const From &Val) { |
205 | return cast_convert_val<To, SimpleFrom, |
206 | typename simplify_type<SimpleFrom>::SimpleType>:: |
207 | doit(simplify_type<From>::getSimplifiedValue(const_cast<From &>(Val))); |
208 | } |
209 | }; |
210 | |
211 | template <class To, class FromTy> struct cast_convert_val<To, FromTy, FromTy> { |
212 | // If it's a reference, switch to a pointer to do the cast and then deref it. |
213 | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { |
214 | return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type> |
215 | *)&const_cast<FromTy &>(Val); |
216 | } |
217 | }; |
218 | |
219 | template <class To, class FromTy> |
220 | struct cast_convert_val<To, FromTy *, FromTy *> { |
221 | // If it's a pointer, we can use c-style casting directly. |
222 | static typename cast_retty<To, FromTy *>::ret_type doit(const FromTy *Val) { |
223 | return (typename cast_retty<To, FromTy *>::ret_type) const_cast<FromTy *>( |
224 | Val); |
225 | } |
226 | }; |
227 | |
228 | //===----------------------------------------------------------------------===// |
229 | // is_simple_type |
230 | //===----------------------------------------------------------------------===// |
231 | |
232 | template <class X> struct is_simple_type { |
233 | static const bool value = |
234 | std::is_same<X, typename simplify_type<X>::SimpleType>::value; |
235 | }; |
236 | |
237 | // } // namespace detail |
238 | |
239 | //===----------------------------------------------------------------------===// |
240 | // CastIsPossible |
241 | //===----------------------------------------------------------------------===// |
242 | |
243 | /// This struct provides a way to check if a given cast is possible. It provides |
244 | /// a static function called isPossible that is used to check if a cast can be |
245 | /// performed. It should be overridden like this: |
246 | /// |
247 | /// template<> struct CastIsPossible<foo, bar> { |
248 | /// static inline bool isPossible(const bar &b) { |
249 | /// return bar.isFoo(); |
250 | /// } |
251 | /// }; |
252 | template <typename To, typename From, typename Enable = void> |
253 | struct CastIsPossible { |
254 | static inline bool isPossible(const From &f) { |
255 | return isa_impl_wrap< |
256 | To, const From, |
257 | typename simplify_type<const From>::SimpleType>::doit(f); |
258 | } |
259 | }; |
260 | |
261 | // Needed for optional unwrapping. This could be implemented with isa_impl, but |
262 | // we want to implement things in the new method and move old implementations |
263 | // over. In fact, some of the isa_impl templates should be moved over to |
264 | // CastIsPossible. |
265 | template <typename To, typename From> |
266 | struct CastIsPossible<To, std::optional<From>> { |
267 | static inline bool isPossible(const std::optional<From> &f) { |
268 | assert(f && "CastIsPossible::isPossible called on a nullopt!")(static_cast <bool> (f && "CastIsPossible::isPossible called on a nullopt!" ) ? void (0) : __assert_fail ("f && \"CastIsPossible::isPossible called on a nullopt!\"" , "llvm/include/llvm/Support/Casting.h", 268, __extension__ __PRETTY_FUNCTION__ )); |
269 | return isa_impl_wrap< |
270 | To, const From, |
271 | typename simplify_type<const From>::SimpleType>::doit(*f); |
272 | } |
273 | }; |
274 | |
275 | /// Upcasting (from derived to base) and casting from a type to itself should |
276 | /// always be possible. |
277 | template <typename To, typename From> |
278 | struct CastIsPossible<To, From, |
279 | std::enable_if_t<std::is_base_of<To, From>::value>> { |
280 | static inline bool isPossible(const From &f) { return true; } |
281 | }; |
282 | |
283 | //===----------------------------------------------------------------------===// |
284 | // Cast traits |
285 | //===----------------------------------------------------------------------===// |
286 | |
287 | /// All of these cast traits are meant to be implementations for useful casts |
288 | /// that users may want to use that are outside the standard behavior. An |
289 | /// example of how to use a special cast called `CastTrait` is: |
290 | /// |
291 | /// template<> struct CastInfo<foo, bar> : public CastTrait<foo, bar> {}; |
292 | /// |
293 | /// Essentially, if your use case falls directly into one of the use cases |
294 | /// supported by a given cast trait, simply inherit your special CastInfo |
295 | /// directly from one of these to avoid having to reimplement the boilerplate |
296 | /// `isPossible/castFailed/doCast/doCastIfPossible`. A cast trait can also |
297 | /// provide a subset of those functions. |
298 | |
299 | /// This cast trait just provides castFailed for the specified `To` type to make |
300 | /// CastInfo specializations more declarative. In order to use this, the target |
301 | /// result type must be `To` and `To` must be constructible from `nullptr`. |
302 | template <typename To> struct NullableValueCastFailed { |
303 | static To castFailed() { return To(nullptr); } |
304 | }; |
305 | |
306 | /// This cast trait just provides the default implementation of doCastIfPossible |
307 | /// to make CastInfo specializations more declarative. The `Derived` template |
308 | /// parameter *must* be provided for forwarding castFailed and doCast. |
309 | template <typename To, typename From, typename Derived> |
310 | struct DefaultDoCastIfPossible { |
311 | static To doCastIfPossible(From f) { |
312 | if (!Derived::isPossible(f)) |
313 | return Derived::castFailed(); |
314 | return Derived::doCast(f); |
315 | } |
316 | }; |
317 | |
318 | namespace detail { |
319 | /// A helper to derive the type to use with `Self` for cast traits, when the |
320 | /// provided CRTP derived type is allowed to be void. |
321 | template <typename OptionalDerived, typename Default> |
322 | using SelfType = std::conditional_t<std::is_same<OptionalDerived, void>::value, |
323 | Default, OptionalDerived>; |
324 | } // namespace detail |
325 | |
326 | /// This cast trait provides casting for the specific case of casting to a |
327 | /// value-typed object from a pointer-typed object. Note that `To` must be |
328 | /// nullable/constructible from a pointer to `From` to use this cast. |
329 | template <typename To, typename From, typename Derived = void> |
330 | struct ValueFromPointerCast |
331 | : public CastIsPossible<To, From *>, |
332 | public NullableValueCastFailed<To>, |
333 | public DefaultDoCastIfPossible< |
334 | To, From *, |
335 | detail::SelfType<Derived, ValueFromPointerCast<To, From>>> { |
336 | static inline To doCast(From *f) { return To(f); } |
337 | }; |
338 | |
339 | /// This cast trait provides std::unique_ptr casting. It has the semantics of |
340 | /// moving the contents of the input unique_ptr into the output unique_ptr |
341 | /// during the cast. It's also a good example of how to implement a move-only |
342 | /// cast. |
343 | template <typename To, typename From, typename Derived = void> |
344 | struct UniquePtrCast : public CastIsPossible<To, From *> { |
345 | using Self = detail::SelfType<Derived, UniquePtrCast<To, From>>; |
346 | using CastResultType = std::unique_ptr< |
347 | std::remove_reference_t<typename cast_retty<To, From>::ret_type>>; |
348 | |
349 | static inline CastResultType doCast(std::unique_ptr<From> &&f) { |
350 | return CastResultType((typename CastResultType::element_type *)f.release()); |
351 | } |
352 | |
353 | static inline CastResultType castFailed() { return CastResultType(nullptr); } |
354 | |
355 | static inline CastResultType doCastIfPossible(std::unique_ptr<From> &&f) { |
356 | if (!Self::isPossible(f)) |
357 | return castFailed(); |
358 | return doCast(f); |
359 | } |
360 | }; |
361 | |
362 | /// This cast trait provides std::optional<T> casting. This means that if you |
363 | /// have a value type, you can cast it to another value type and have dyn_cast |
364 | /// return an std::optional<T>. |
365 | template <typename To, typename From, typename Derived = void> |
366 | struct OptionalValueCast |
367 | : public CastIsPossible<To, From>, |
368 | public DefaultDoCastIfPossible< |
369 | std::optional<To>, From, |
370 | detail::SelfType<Derived, OptionalValueCast<To, From>>> { |
371 | static inline std::optional<To> castFailed() { return std::optional<To>{}; } |
372 | |
373 | static inline std::optional<To> doCast(const From &f) { return To(f); } |
374 | }; |
375 | |
376 | /// Provides a cast trait that strips `const` from types to make it easier to |
377 | /// implement a const-version of a non-const cast. It just removes boilerplate |
378 | /// and reduces the amount of code you as the user need to implement. You can |
379 | /// use it like this: |
380 | /// |
381 | /// template<> struct CastInfo<foo, bar> { |
382 | /// ...verbose implementation... |
383 | /// }; |
384 | /// |
385 | /// template<> struct CastInfo<foo, const bar> : public |
386 | /// ConstStrippingForwardingCast<foo, const bar, CastInfo<foo, bar>> {}; |
387 | /// |
388 | template <typename To, typename From, typename ForwardTo> |
389 | struct ConstStrippingForwardingCast { |
390 | // Remove the pointer if it exists, then we can get rid of consts/volatiles. |
391 | using DecayedFrom = std::remove_cv_t<std::remove_pointer_t<From>>; |
392 | // Now if it's a pointer, add it back. Otherwise, we want a ref. |
393 | using NonConstFrom = std::conditional_t<std::is_pointer<From>::value, |
394 | DecayedFrom *, DecayedFrom &>; |
395 | |
396 | static inline bool isPossible(const From &f) { |
397 | return ForwardTo::isPossible(const_cast<NonConstFrom>(f)); |
398 | } |
399 | |
400 | static inline decltype(auto) castFailed() { return ForwardTo::castFailed(); } |
401 | |
402 | static inline decltype(auto) doCast(const From &f) { |
403 | return ForwardTo::doCast(const_cast<NonConstFrom>(f)); |
404 | } |
405 | |
406 | static inline decltype(auto) doCastIfPossible(const From &f) { |
407 | return ForwardTo::doCastIfPossible(const_cast<NonConstFrom>(f)); |
408 | } |
409 | }; |
410 | |
411 | /// Provides a cast trait that uses a defined pointer to pointer cast as a base |
412 | /// for reference-to-reference casts. Note that it does not provide castFailed |
413 | /// and doCastIfPossible because a pointer-to-pointer cast would likely just |
414 | /// return `nullptr` which could cause nullptr dereference. You can use it like |
415 | /// this: |
416 | /// |
417 | /// template <> struct CastInfo<foo, bar *> { ... verbose implementation... }; |
418 | /// |
419 | /// template <> |
420 | /// struct CastInfo<foo, bar> |
421 | /// : public ForwardToPointerCast<foo, bar, CastInfo<foo, bar *>> {}; |
422 | /// |
423 | template <typename To, typename From, typename ForwardTo> |
424 | struct ForwardToPointerCast { |
425 | static inline bool isPossible(const From &f) { |
426 | return ForwardTo::isPossible(&f); |
427 | } |
428 | |
429 | static inline decltype(auto) doCast(const From &f) { |
430 | return *ForwardTo::doCast(&f); |
431 | } |
432 | }; |
433 | |
434 | //===----------------------------------------------------------------------===// |
435 | // CastInfo |
436 | //===----------------------------------------------------------------------===// |
437 | |
438 | /// This struct provides a method for customizing the way a cast is performed. |
439 | /// It inherits from CastIsPossible, to support the case of declaring many |
440 | /// CastIsPossible specializations without having to specialize the full |
441 | /// CastInfo. |
442 | /// |
443 | /// In order to specialize different behaviors, specify different functions in |
444 | /// your CastInfo specialization. |
445 | /// For isa<> customization, provide: |
446 | /// |
447 | /// `static bool isPossible(const From &f)` |
448 | /// |
449 | /// For cast<> customization, provide: |
450 | /// |
451 | /// `static To doCast(const From &f)` |
452 | /// |
453 | /// For dyn_cast<> and the *_if_present<> variants' customization, provide: |
454 | /// |
455 | /// `static To castFailed()` and `static To doCastIfPossible(const From &f)` |
456 | /// |
457 | /// Your specialization might look something like this: |
458 | /// |
459 | /// template<> struct CastInfo<foo, bar> : public CastIsPossible<foo, bar> { |
460 | /// static inline foo doCast(const bar &b) { |
461 | /// return foo(const_cast<bar &>(b)); |
462 | /// } |
463 | /// static inline foo castFailed() { return foo(); } |
464 | /// static inline foo doCastIfPossible(const bar &b) { |
465 | /// if (!CastInfo<foo, bar>::isPossible(b)) |
466 | /// return castFailed(); |
467 | /// return doCast(b); |
468 | /// } |
469 | /// }; |
470 | |
471 | // The default implementations of CastInfo don't use cast traits for now because |
472 | // we need to specify types all over the place due to the current expected |
473 | // casting behavior and the way cast_retty works. New use cases can and should |
474 | // take advantage of the cast traits whenever possible! |
475 | |
476 | template <typename To, typename From, typename Enable = void> |
477 | struct CastInfo : public CastIsPossible<To, From> { |
478 | using Self = CastInfo<To, From, Enable>; |
479 | |
480 | using CastReturnType = typename cast_retty<To, From>::ret_type; |
481 | |
482 | static inline CastReturnType doCast(const From &f) { |
483 | return cast_convert_val< |
484 | To, From, |
485 | typename simplify_type<From>::SimpleType>::doit(const_cast<From &>(f)); |
486 | } |
487 | |
488 | // This assumes that you can construct the cast return type from `nullptr`. |
489 | // This is largely to support legacy use cases - if you don't want this |
490 | // behavior you should specialize CastInfo for your use case. |
491 | static inline CastReturnType castFailed() { return CastReturnType(nullptr); } |
492 | |
493 | static inline CastReturnType doCastIfPossible(const From &f) { |
494 | if (!Self::isPossible(f)) |
495 | return castFailed(); |
496 | return doCast(f); |
497 | } |
498 | }; |
499 | |
500 | /// This struct provides an overload for CastInfo where From has simplify_type |
501 | /// defined. This simply forwards to the appropriate CastInfo with the |
502 | /// simplified type/value, so you don't have to implement both. |
503 | template <typename To, typename From> |
504 | struct CastInfo<To, From, std::enable_if_t<!is_simple_type<From>::value>> { |
505 | using Self = CastInfo<To, From>; |
506 | using SimpleFrom = typename simplify_type<From>::SimpleType; |
507 | using SimplifiedSelf = CastInfo<To, SimpleFrom>; |
508 | |
509 | static inline bool isPossible(From &f) { |
510 | return SimplifiedSelf::isPossible( |
511 | simplify_type<From>::getSimplifiedValue(f)); |
512 | } |
513 | |
514 | static inline decltype(auto) doCast(From &f) { |
515 | return SimplifiedSelf::doCast(simplify_type<From>::getSimplifiedValue(f)); |
516 | } |
517 | |
518 | static inline decltype(auto) castFailed() { |
519 | return SimplifiedSelf::castFailed(); |
520 | } |
521 | |
522 | static inline decltype(auto) doCastIfPossible(From &f) { |
523 | return SimplifiedSelf::doCastIfPossible( |
524 | simplify_type<From>::getSimplifiedValue(f)); |
525 | } |
526 | }; |
527 | |
528 | //===----------------------------------------------------------------------===// |
529 | // Pre-specialized CastInfo |
530 | //===----------------------------------------------------------------------===// |
531 | |
532 | /// Provide a CastInfo specialized for std::unique_ptr. |
533 | template <typename To, typename From> |
534 | struct CastInfo<To, std::unique_ptr<From>> : public UniquePtrCast<To, From> {}; |
535 | |
536 | /// Provide a CastInfo specialized for std::optional<From>. It's assumed that if |
537 | /// the input is std::optional<From> that the output can be std::optional<To>. |
538 | /// If that's not the case, specialize CastInfo for your use case. |
539 | template <typename To, typename From> |
540 | struct CastInfo<To, std::optional<From>> : public OptionalValueCast<To, From> { |
541 | }; |
542 | |
543 | /// isa<X> - Return true if the parameter to the template is an instance of one |
544 | /// of the template type arguments. Used like this: |
545 | /// |
546 | /// if (isa<Type>(myVal)) { ... } |
547 | /// if (isa<Type0, Type1, Type2>(myVal)) { ... } |
548 | template <typename To, typename From> |
549 | [[nodiscard]] inline bool isa(const From &Val) { |
550 | return CastInfo<To, const From>::isPossible(Val); |
551 | } |
552 | |
553 | template <typename First, typename Second, typename... Rest, typename From> |
554 | [[nodiscard]] inline bool isa(const From &Val) { |
555 | return isa<First>(Val) || isa<Second, Rest...>(Val); |
556 | } |
557 | |
558 | /// cast<X> - Return the argument parameter cast to the specified type. This |
559 | /// casting operator asserts that the type is correct, so it does not return |
560 | /// null on failure. It does not allow a null argument (use cast_if_present for |
561 | /// that). It is typically used like this: |
562 | /// |
563 | /// cast<Instruction>(myVal)->getParent() |
564 | |
565 | template <typename To, typename From> |
566 | [[nodiscard]] inline decltype(auto) cast(const From &Val) { |
567 | assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 567, __extension__ __PRETTY_FUNCTION__ )); |
568 | return CastInfo<To, const From>::doCast(Val); |
569 | } |
570 | |
571 | template <typename To, typename From> |
572 | [[nodiscard]] inline decltype(auto) cast(From &Val) { |
573 | assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 573, __extension__ __PRETTY_FUNCTION__ )); |
574 | return CastInfo<To, From>::doCast(Val); |
575 | } |
576 | |
577 | template <typename To, typename From> |
578 | [[nodiscard]] inline decltype(auto) cast(From *Val) { |
579 | assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 579, __extension__ __PRETTY_FUNCTION__ )); |
580 | return CastInfo<To, From *>::doCast(Val); |
581 | } |
582 | |
583 | template <typename To, typename From> |
584 | [[nodiscard]] inline decltype(auto) cast(std::unique_ptr<From> &&Val) { |
585 | assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 585, __extension__ __PRETTY_FUNCTION__ )); |
586 | return CastInfo<To, std::unique_ptr<From>>::doCast(std::move(Val)); |
587 | } |
588 | |
589 | //===----------------------------------------------------------------------===// |
590 | // ValueIsPresent |
591 | //===----------------------------------------------------------------------===// |
592 | |
593 | template <typename T> |
594 | constexpr bool IsNullable = |
595 | std::is_pointer_v<T> || std::is_constructible_v<T, std::nullptr_t>; |
596 | |
597 | /// ValueIsPresent provides a way to check if a value is, well, present. For |
598 | /// pointers, this is the equivalent of checking against nullptr, for Optionals |
599 | /// this is the equivalent of checking hasValue(). It also provides a method for |
600 | /// unwrapping a value (think calling .value() on an optional). |
601 | |
602 | // Generic values can't *not* be present. |
603 | template <typename T, typename Enable = void> struct ValueIsPresent { |
604 | using UnwrappedType = T; |
605 | static inline bool isPresent(const T &t) { return true; } |
606 | static inline decltype(auto) unwrapValue(T &t) { return t; } |
607 | }; |
608 | |
609 | // Optional provides its own way to check if something is present. |
610 | template <typename T> struct ValueIsPresent<std::optional<T>> { |
611 | using UnwrappedType = T; |
612 | static inline bool isPresent(const std::optional<T> &t) { |
613 | return t.has_value(); |
614 | } |
615 | static inline decltype(auto) unwrapValue(std::optional<T> &t) { return *t; } |
616 | }; |
617 | |
618 | // If something is "nullable" then we just compare it to nullptr to see if it |
619 | // exists. |
620 | template <typename T> |
621 | struct ValueIsPresent<T, std::enable_if_t<IsNullable<T>>> { |
622 | using UnwrappedType = T; |
623 | static inline bool isPresent(const T &t) { return t != T(nullptr); } |
624 | static inline decltype(auto) unwrapValue(T &t) { return t; } |
625 | }; |
626 | |
627 | namespace detail { |
628 | // Convenience function we can use to check if a value is present. Because of |
629 | // simplify_type, we have to call it on the simplified type for now. |
630 | template <typename T> inline bool isPresent(const T &t) { |
631 | return ValueIsPresent<typename simplify_type<T>::SimpleType>::isPresent( |
632 | simplify_type<T>::getSimplifiedValue(const_cast<T &>(t))); |
633 | } |
634 | |
635 | // Convenience function we can use to unwrap a value. |
636 | template <typename T> inline decltype(auto) unwrapValue(T &t) { |
637 | return ValueIsPresent<T>::unwrapValue(t); |
638 | } |
639 | } // namespace detail |
640 | |
641 | /// dyn_cast<X> - Return the argument parameter cast to the specified type. This |
642 | /// casting operator returns null if the argument is of the wrong type, so it |
643 | /// can be used to test for a type as well as cast if successful. The value |
644 | /// passed in must be present, if not, use dyn_cast_if_present. This should be |
645 | /// used in the context of an if statement like this: |
646 | /// |
647 | /// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } |
648 | |
649 | template <typename To, typename From> |
650 | [[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) { |
651 | assert(detail::isPresent(Val) && "dyn_cast on a non-existent value")(static_cast <bool> (detail::isPresent(Val) && "dyn_cast on a non-existent value" ) ? void (0) : __assert_fail ("detail::isPresent(Val) && \"dyn_cast on a non-existent value\"" , "llvm/include/llvm/Support/Casting.h", 651, __extension__ __PRETTY_FUNCTION__ )); |
652 | return CastInfo<To, const From>::doCastIfPossible(Val); |
653 | } |
654 | |
655 | template <typename To, typename From> |
656 | [[nodiscard]] inline decltype(auto) dyn_cast(From &Val) { |
657 | assert(detail::isPresent(Val) && "dyn_cast on a non-existent value")(static_cast <bool> (detail::isPresent(Val) && "dyn_cast on a non-existent value" ) ? void (0) : __assert_fail ("detail::isPresent(Val) && \"dyn_cast on a non-existent value\"" , "llvm/include/llvm/Support/Casting.h", 657, __extension__ __PRETTY_FUNCTION__ )); |
658 | return CastInfo<To, From>::doCastIfPossible(Val); |
659 | } |
660 | |
661 | template <typename To, typename From> |
662 | [[nodiscard]] inline decltype(auto) dyn_cast(From *Val) { |
663 | assert(detail::isPresent(Val) && "dyn_cast on a non-existent value")(static_cast <bool> (detail::isPresent(Val) && "dyn_cast on a non-existent value" ) ? void (0) : __assert_fail ("detail::isPresent(Val) && \"dyn_cast on a non-existent value\"" , "llvm/include/llvm/Support/Casting.h", 663, __extension__ __PRETTY_FUNCTION__ )); |
664 | return CastInfo<To, From *>::doCastIfPossible(Val); |
665 | } |
666 | |
667 | template <typename To, typename From> |
668 | [[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr<From> &&Val) { |
669 | assert(detail::isPresent(Val) && "dyn_cast on a non-existent value")(static_cast <bool> (detail::isPresent(Val) && "dyn_cast on a non-existent value" ) ? void (0) : __assert_fail ("detail::isPresent(Val) && \"dyn_cast on a non-existent value\"" , "llvm/include/llvm/Support/Casting.h", 669, __extension__ __PRETTY_FUNCTION__ )); |
670 | return CastInfo<To, std::unique_ptr<From>>::doCastIfPossible( |
671 | std::forward<std::unique_ptr<From> &&>(Val)); |
672 | } |
673 | |
674 | /// isa_and_present<X> - Functionally identical to isa, except that a null value |
675 | /// is accepted. |
676 | template <typename... X, class Y> |
677 | [[nodiscard]] inline bool isa_and_present(const Y &Val) { |
678 | if (!detail::isPresent(Val)) |
679 | return false; |
680 | return isa<X...>(Val); |
681 | } |
682 | |
683 | template <typename... X, class Y> |
684 | [[nodiscard]] inline bool isa_and_nonnull(const Y &Val) { |
685 | return isa_and_present<X...>(Val); |
686 | } |
687 | |
688 | /// cast_if_present<X> - Functionally identical to cast, except that a null |
689 | /// value is accepted. |
690 | template <class X, class Y> |
691 | [[nodiscard]] inline auto cast_if_present(const Y &Val) { |
692 | if (!detail::isPresent(Val)) |
693 | return CastInfo<X, const Y>::castFailed(); |
694 | assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 694, __extension__ __PRETTY_FUNCTION__ )); |
695 | return cast<X>(detail::unwrapValue(Val)); |
696 | } |
697 | |
698 | template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y &Val) { |
699 | if (!detail::isPresent(Val)) |
700 | return CastInfo<X, Y>::castFailed(); |
701 | assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 701, __extension__ __PRETTY_FUNCTION__ )); |
702 | return cast<X>(detail::unwrapValue(Val)); |
703 | } |
704 | |
705 | template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y *Val) { |
706 | if (!detail::isPresent(Val)) |
707 | return CastInfo<X, Y *>::castFailed(); |
708 | assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 708, __extension__ __PRETTY_FUNCTION__ )); |
709 | return cast<X>(detail::unwrapValue(Val)); |
710 | } |
711 | |
712 | template <class X, class Y> |
713 | [[nodiscard]] inline auto cast_if_present(std::unique_ptr<Y> &&Val) { |
714 | if (!detail::isPresent(Val)) |
715 | return UniquePtrCast<X, Y>::castFailed(); |
716 | return UniquePtrCast<X, Y>::doCast(std::move(Val)); |
717 | } |
718 | |
719 | // Provide a forwarding from cast_or_null to cast_if_present for current |
720 | // users. This is deprecated and will be removed in a future patch, use |
721 | // cast_if_present instead. |
722 | template <class X, class Y> auto cast_or_null(const Y &Val) { |
723 | return cast_if_present<X>(Val); |
724 | } |
725 | |
726 | template <class X, class Y> auto cast_or_null(Y &Val) { |
727 | return cast_if_present<X>(Val); |
728 | } |
729 | |
730 | template <class X, class Y> auto cast_or_null(Y *Val) { |
731 | return cast_if_present<X>(Val); |
732 | } |
733 | |
734 | template <class X, class Y> auto cast_or_null(std::unique_ptr<Y> &&Val) { |
735 | return cast_if_present<X>(std::move(Val)); |
736 | } |
737 | |
738 | /// dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a |
739 | /// null (or none in the case of optionals) value is accepted. |
740 | template <class X, class Y> auto dyn_cast_if_present(const Y &Val) { |
741 | if (!detail::isPresent(Val)) |
742 | return CastInfo<X, const Y>::castFailed(); |
743 | return CastInfo<X, const Y>::doCastIfPossible(detail::unwrapValue(Val)); |
744 | } |
745 | |
746 | template <class X, class Y> auto dyn_cast_if_present(Y &Val) { |
747 | if (!detail::isPresent(Val)) |
748 | return CastInfo<X, Y>::castFailed(); |
749 | return CastInfo<X, Y>::doCastIfPossible(detail::unwrapValue(Val)); |
750 | } |
751 | |
752 | template <class X, class Y> auto dyn_cast_if_present(Y *Val) { |
753 | if (!detail::isPresent(Val)) |
754 | return CastInfo<X, Y *>::castFailed(); |
755 | return CastInfo<X, Y *>::doCastIfPossible(detail::unwrapValue(Val)); |
756 | } |
757 | |
758 | // Forwards to dyn_cast_if_present to avoid breaking current users. This is |
759 | // deprecated and will be removed in a future patch, use |
760 | // cast_if_present instead. |
761 | template <class X, class Y> auto dyn_cast_or_null(const Y &Val) { |
762 | return dyn_cast_if_present<X>(Val); |
763 | } |
764 | |
765 | template <class X, class Y> auto dyn_cast_or_null(Y &Val) { |
766 | return dyn_cast_if_present<X>(Val); |
767 | } |
768 | |
769 | template <class X, class Y> auto dyn_cast_or_null(Y *Val) { |
770 | return dyn_cast_if_present<X>(Val); |
771 | } |
772 | |
773 | /// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, |
774 | /// taking ownership of the input pointer iff isa<X>(Val) is true. If the |
775 | /// cast is successful, From refers to nullptr on exit and the casted value |
776 | /// is returned. If the cast is unsuccessful, the function returns nullptr |
777 | /// and From is unchanged. |
778 | template <class X, class Y> |
779 | [[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType |
780 | unique_dyn_cast(std::unique_ptr<Y> &Val) { |
781 | if (!isa<X>(Val)) |
782 | return nullptr; |
783 | return cast<X>(std::move(Val)); |
784 | } |
785 | |
786 | template <class X, class Y> |
787 | [[nodiscard]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) { |
788 | return unique_dyn_cast<X, Y>(Val); |
789 | } |
790 | |
791 | // unique_dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, |
792 | // except that a null value is accepted. |
793 | template <class X, class Y> |
794 | [[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType |
795 | unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) { |
796 | if (!Val) |
797 | return nullptr; |
798 | return unique_dyn_cast<X, Y>(Val); |
799 | } |
800 | |
801 | template <class X, class Y> |
802 | [[nodiscard]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) { |
803 | return unique_dyn_cast_or_null<X, Y>(Val); |
804 | } |
805 | |
806 | } // end namespace llvm |
807 | |
808 | #endif // LLVM_SUPPORT_CASTING_H |
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/Optional.h" |
38 | #include "llvm/ADT/PointerIntPair.h" |
39 | #include "llvm/ADT/PointerUnion.h" |
40 | #include "llvm/ADT/StringRef.h" |
41 | #include "llvm/ADT/Twine.h" |
42 | #include "llvm/ADT/iterator_range.h" |
43 | #include "llvm/Support/Casting.h" |
44 | #include "llvm/Support/Compiler.h" |
45 | #include "llvm/Support/ErrorHandling.h" |
46 | #include "llvm/Support/PointerLikeTypeTraits.h" |
47 | #include "llvm/Support/TrailingObjects.h" |
48 | #include "llvm/Support/type_traits.h" |
49 | #include <cassert> |
50 | #include <cstddef> |
51 | #include <cstdint> |
52 | #include <cstring> |
53 | #include <string> |
54 | #include <type_traits> |
55 | #include <utility> |
56 | |
57 | namespace clang { |
58 | |
59 | class BTFTypeTagAttr; |
60 | class ExtQuals; |
61 | class QualType; |
62 | class ConceptDecl; |
63 | class TagDecl; |
64 | class TemplateParameterList; |
65 | class Type; |
66 | |
67 | enum { |
68 | TypeAlignmentInBits = 4, |
69 | TypeAlignment = 1 << TypeAlignmentInBits |
70 | }; |
71 | |
72 | namespace serialization { |
73 | template <class T> class AbstractTypeReader; |
74 | template <class T> class AbstractTypeWriter; |
75 | } |
76 | |
77 | } // namespace clang |
78 | |
79 | namespace llvm { |
80 | |
81 | template <typename T> |
82 | struct PointerLikeTypeTraits; |
83 | template<> |
84 | struct PointerLikeTypeTraits< ::clang::Type*> { |
85 | 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 | class UsingShadowDecl; |
133 | |
134 | using CanQualType = CanQual<Type>; |
135 | |
136 | // Provide forward declarations for all of the *Type classes. |
137 | #define TYPE(Class, Base) class Class##Type; |
138 | #include "clang/AST/TypeNodes.inc" |
139 | |
140 | /// The collection of all-type qualifiers we support. |
141 | /// Clang supports five independent qualifiers: |
142 | /// * C99: const, volatile, and restrict |
143 | /// * MS: __unaligned |
144 | /// * Embedded C (TR18037): address spaces |
145 | /// * Objective C: the GC attributes (none, weak, or strong) |
146 | class Qualifiers { |
147 | public: |
148 | enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. |
149 | Const = 0x1, |
150 | Restrict = 0x2, |
151 | Volatile = 0x4, |
152 | CVRMask = Const | Volatile | Restrict |
153 | }; |
154 | |
155 | enum GC { |
156 | GCNone = 0, |
157 | Weak, |
158 | Strong |
159 | }; |
160 | |
161 | enum ObjCLifetime { |
162 | /// There is no lifetime qualification on this type. |
163 | OCL_None, |
164 | |
165 | /// This object can be modified without requiring retains or |
166 | /// releases. |
167 | OCL_ExplicitNone, |
168 | |
169 | /// Assigning into this object requires the old value to be |
170 | /// released and the new value to be retained. The timing of the |
171 | /// release of the old value is inexact: it may be moved to |
172 | /// immediately after the last known point where the value is |
173 | /// live. |
174 | OCL_Strong, |
175 | |
176 | /// Reading or writing from this object requires a barrier call. |
177 | OCL_Weak, |
178 | |
179 | /// Assigning into this object requires a lifetime extension. |
180 | OCL_Autoreleasing |
181 | }; |
182 | |
183 | enum { |
184 | /// The maximum supported address space number. |
185 | /// 23 bits should be enough for anyone. |
186 | MaxAddressSpace = 0x7fffffu, |
187 | |
188 | /// The width of the "fast" qualifier mask. |
189 | FastWidth = 3, |
190 | |
191 | /// The fast qualifier mask. |
192 | FastMask = (1 << FastWidth) - 1 |
193 | }; |
194 | |
195 | /// Returns the common set of qualifiers while removing them from |
196 | /// the given sets. |
197 | static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { |
198 | // If both are only CVR-qualified, bit operations are sufficient. |
199 | if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { |
200 | Qualifiers Q; |
201 | Q.Mask = L.Mask & R.Mask; |
202 | L.Mask &= ~Q.Mask; |
203 | R.Mask &= ~Q.Mask; |
204 | return Q; |
205 | } |
206 | |
207 | Qualifiers Q; |
208 | unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); |
209 | Q.addCVRQualifiers(CommonCRV); |
210 | L.removeCVRQualifiers(CommonCRV); |
211 | R.removeCVRQualifiers(CommonCRV); |
212 | |
213 | if (L.getObjCGCAttr() == R.getObjCGCAttr()) { |
214 | Q.setObjCGCAttr(L.getObjCGCAttr()); |
215 | L.removeObjCGCAttr(); |
216 | R.removeObjCGCAttr(); |
217 | } |
218 | |
219 | if (L.getObjCLifetime() == R.getObjCLifetime()) { |
220 | Q.setObjCLifetime(L.getObjCLifetime()); |
221 | L.removeObjCLifetime(); |
222 | R.removeObjCLifetime(); |
223 | } |
224 | |
225 | if (L.getAddressSpace() == R.getAddressSpace()) { |
226 | Q.setAddressSpace(L.getAddressSpace()); |
227 | L.removeAddressSpace(); |
228 | R.removeAddressSpace(); |
229 | } |
230 | return Q; |
231 | } |
232 | |
233 | static Qualifiers fromFastMask(unsigned Mask) { |
234 | Qualifiers Qs; |
235 | Qs.addFastQualifiers(Mask); |
236 | return Qs; |
237 | } |
238 | |
239 | static Qualifiers fromCVRMask(unsigned CVR) { |
240 | Qualifiers Qs; |
241 | Qs.addCVRQualifiers(CVR); |
242 | return Qs; |
243 | } |
244 | |
245 | static Qualifiers fromCVRUMask(unsigned CVRU) { |
246 | Qualifiers Qs; |
247 | Qs.addCVRUQualifiers(CVRU); |
248 | return Qs; |
249 | } |
250 | |
251 | // Deserialize qualifiers from an opaque representation. |
252 | static Qualifiers fromOpaqueValue(unsigned opaque) { |
253 | Qualifiers Qs; |
254 | Qs.Mask = opaque; |
255 | return Qs; |
256 | } |
257 | |
258 | // Serialize these qualifiers into an opaque representation. |
259 | unsigned getAsOpaqueValue() const { |
260 | return Mask; |
261 | } |
262 | |
263 | bool hasConst() const { return Mask & Const; } |
264 | bool hasOnlyConst() const { return Mask == Const; } |
265 | void removeConst() { Mask &= ~Const; } |
266 | void addConst() { Mask |= Const; } |
267 | Qualifiers withConst() const { |
268 | Qualifiers Qs = *this; |
269 | Qs.addConst(); |
270 | return Qs; |
271 | } |
272 | |
273 | bool hasVolatile() const { return Mask & Volatile; } |
274 | bool hasOnlyVolatile() const { return Mask == Volatile; } |
275 | void removeVolatile() { Mask &= ~Volatile; } |
276 | void addVolatile() { Mask |= Volatile; } |
277 | Qualifiers withVolatile() const { |
278 | Qualifiers Qs = *this; |
279 | Qs.addVolatile(); |
280 | return Qs; |
281 | } |
282 | |
283 | bool hasRestrict() const { return Mask & Restrict; } |
284 | bool hasOnlyRestrict() const { return Mask == Restrict; } |
285 | void removeRestrict() { Mask &= ~Restrict; } |
286 | void addRestrict() { Mask |= Restrict; } |
287 | Qualifiers withRestrict() const { |
288 | Qualifiers Qs = *this; |
289 | Qs.addRestrict(); |
290 | return Qs; |
291 | } |
292 | |
293 | bool hasCVRQualifiers() const { return getCVRQualifiers(); } |
294 | unsigned getCVRQualifiers() const { return Mask & CVRMask; } |
295 | unsigned getCVRUQualifiers() const { return Mask & (CVRMask | UMask); } |
296 | |
297 | void setCVRQualifiers(unsigned mask) { |
298 | 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\"" , "clang/include/clang/AST/Type.h", 298, __extension__ __PRETTY_FUNCTION__ )); |
299 | Mask = (Mask & ~CVRMask) | mask; |
300 | } |
301 | void removeCVRQualifiers(unsigned mask) { |
302 | 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\"" , "clang/include/clang/AST/Type.h", 302, __extension__ __PRETTY_FUNCTION__ )); |
303 | Mask &= ~mask; |
304 | } |
305 | void removeCVRQualifiers() { |
306 | removeCVRQualifiers(CVRMask); |
307 | } |
308 | void addCVRQualifiers(unsigned mask) { |
309 | 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\"" , "clang/include/clang/AST/Type.h", 309, __extension__ __PRETTY_FUNCTION__ )); |
310 | Mask |= mask; |
311 | } |
312 | void addCVRUQualifiers(unsigned mask) { |
313 | 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\"" , "clang/include/clang/AST/Type.h", 313, __extension__ __PRETTY_FUNCTION__ )); |
314 | Mask |= mask; |
315 | } |
316 | |
317 | bool hasUnaligned() const { return Mask & UMask; } |
318 | void setUnaligned(bool flag) { |
319 | Mask = (Mask & ~UMask) | (flag ? UMask : 0); |
320 | } |
321 | void removeUnaligned() { Mask &= ~UMask; } |
322 | void addUnaligned() { Mask |= UMask; } |
323 | |
324 | bool hasObjCGCAttr() const { return Mask & GCAttrMask; } |
325 | GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } |
326 | void setObjCGCAttr(GC type) { |
327 | Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift); |
328 | } |
329 | void removeObjCGCAttr() { setObjCGCAttr(GCNone); } |
330 | void addObjCGCAttr(GC type) { |
331 | assert(type)(static_cast <bool> (type) ? void (0) : __assert_fail ( "type", "clang/include/clang/AST/Type.h", 331, __extension__ __PRETTY_FUNCTION__ )); |
332 | setObjCGCAttr(type); |
333 | } |
334 | Qualifiers withoutObjCGCAttr() const { |
335 | Qualifiers qs = *this; |
336 | qs.removeObjCGCAttr(); |
337 | return qs; |
338 | } |
339 | Qualifiers withoutObjCLifetime() const { |
340 | Qualifiers qs = *this; |
341 | qs.removeObjCLifetime(); |
342 | return qs; |
343 | } |
344 | Qualifiers withoutAddressSpace() const { |
345 | Qualifiers qs = *this; |
346 | qs.removeAddressSpace(); |
347 | return qs; |
348 | } |
349 | |
350 | bool hasObjCLifetime() const { return Mask & LifetimeMask; } |
351 | ObjCLifetime getObjCLifetime() const { |
352 | return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift); |
353 | } |
354 | void setObjCLifetime(ObjCLifetime type) { |
355 | Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift); |
356 | } |
357 | void removeObjCLifetime() { setObjCLifetime(OCL_None); } |
358 | void addObjCLifetime(ObjCLifetime type) { |
359 | assert(type)(static_cast <bool> (type) ? void (0) : __assert_fail ( "type", "clang/include/clang/AST/Type.h", 359, __extension__ __PRETTY_FUNCTION__ )); |
360 | assert(!hasObjCLifetime())(static_cast <bool> (!hasObjCLifetime()) ? void (0) : __assert_fail ("!hasObjCLifetime()", "clang/include/clang/AST/Type.h", 360 , __extension__ __PRETTY_FUNCTION__)); |
361 | Mask |= (type << LifetimeShift); |
362 | } |
363 | |
364 | /// True if the lifetime is neither None or ExplicitNone. |
365 | bool hasNonTrivialObjCLifetime() const { |
366 | ObjCLifetime lifetime = getObjCLifetime(); |
367 | return (lifetime > OCL_ExplicitNone); |
368 | } |
369 | |
370 | /// True if the lifetime is either strong or weak. |
371 | bool hasStrongOrWeakObjCLifetime() const { |
372 | ObjCLifetime lifetime = getObjCLifetime(); |
373 | return (lifetime == OCL_Strong || lifetime == OCL_Weak); |
374 | } |
375 | |
376 | bool hasAddressSpace() const { return Mask & AddressSpaceMask; } |
377 | LangAS getAddressSpace() const { |
378 | return static_cast<LangAS>(Mask >> AddressSpaceShift); |
379 | } |
380 | bool hasTargetSpecificAddressSpace() const { |
381 | return isTargetAddressSpace(getAddressSpace()); |
382 | } |
383 | /// Get the address space attribute value to be printed by diagnostics. |
384 | unsigned getAddressSpaceAttributePrintValue() const { |
385 | auto Addr = getAddressSpace(); |
386 | // This function is not supposed to be used with language specific |
387 | // address spaces. If that happens, the diagnostic message should consider |
388 | // printing the QualType instead of the address space value. |
389 | assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace())(static_cast <bool> (Addr == LangAS::Default || hasTargetSpecificAddressSpace ()) ? void (0) : __assert_fail ("Addr == LangAS::Default || hasTargetSpecificAddressSpace()" , "clang/include/clang/AST/Type.h", 389, __extension__ __PRETTY_FUNCTION__ )); |
390 | if (Addr != LangAS::Default) |
391 | return toTargetAddressSpace(Addr); |
392 | // TODO: The diagnostic messages where Addr may be 0 should be fixed |
393 | // since it cannot differentiate the situation where 0 denotes the default |
394 | // address space or user specified __attribute__((address_space(0))). |
395 | return 0; |
396 | } |
397 | void setAddressSpace(LangAS space) { |
398 | assert((unsigned)space <= MaxAddressSpace)(static_cast <bool> ((unsigned)space <= MaxAddressSpace ) ? void (0) : __assert_fail ("(unsigned)space <= MaxAddressSpace" , "clang/include/clang/AST/Type.h", 398, __extension__ __PRETTY_FUNCTION__ )); |
399 | Mask = (Mask & ~AddressSpaceMask) |
400 | | (((uint32_t) space) << AddressSpaceShift); |
401 | } |
402 | void removeAddressSpace() { setAddressSpace(LangAS::Default); } |
403 | void addAddressSpace(LangAS space) { |
404 | assert(space != LangAS::Default)(static_cast <bool> (space != LangAS::Default) ? void ( 0) : __assert_fail ("space != LangAS::Default", "clang/include/clang/AST/Type.h" , 404, __extension__ __PRETTY_FUNCTION__)); |
405 | setAddressSpace(space); |
406 | } |
407 | |
408 | // Fast qualifiers are those that can be allocated directly |
409 | // on a QualType object. |
410 | bool hasFastQualifiers() const { return getFastQualifiers(); } |
411 | unsigned getFastQualifiers() const { return Mask & FastMask; } |
412 | void setFastQualifiers(unsigned mask) { |
413 | 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\"" , "clang/include/clang/AST/Type.h", 413, __extension__ __PRETTY_FUNCTION__ )); |
414 | Mask = (Mask & ~FastMask) | mask; |
415 | } |
416 | void removeFastQualifiers(unsigned mask) { |
417 | 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\"" , "clang/include/clang/AST/Type.h", 417, __extension__ __PRETTY_FUNCTION__ )); |
418 | Mask &= ~mask; |
419 | } |
420 | void removeFastQualifiers() { |
421 | removeFastQualifiers(FastMask); |
422 | } |
423 | void addFastQualifiers(unsigned mask) { |
424 | 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\"" , "clang/include/clang/AST/Type.h", 424, __extension__ __PRETTY_FUNCTION__ )); |
425 | Mask |= mask; |
426 | } |
427 | |
428 | /// Return true if the set contains any qualifiers which require an ExtQuals |
429 | /// node to be allocated. |
430 | bool hasNonFastQualifiers() const { return Mask & ~FastMask; } |
431 | Qualifiers getNonFastQualifiers() const { |
432 | Qualifiers Quals = *this; |
433 | Quals.setFastQualifiers(0); |
434 | return Quals; |
435 | } |
436 | |
437 | /// Return true if the set contains any qualifiers. |
438 | bool hasQualifiers() const { return Mask; } |
439 | bool empty() const { return !Mask; } |
440 | |
441 | /// Add the qualifiers from the given set to this set. |
442 | void addQualifiers(Qualifiers Q) { |
443 | // If the other set doesn't have any non-boolean qualifiers, just |
444 | // bit-or it in. |
445 | if (!(Q.Mask & ~CVRMask)) |
446 | Mask |= Q.Mask; |
447 | else { |
448 | Mask |= (Q.Mask & CVRMask); |
449 | if (Q.hasAddressSpace()) |
450 | addAddressSpace(Q.getAddressSpace()); |
451 | if (Q.hasObjCGCAttr()) |
452 | addObjCGCAttr(Q.getObjCGCAttr()); |
453 | if (Q.hasObjCLifetime()) |
454 | addObjCLifetime(Q.getObjCLifetime()); |
455 | } |
456 | } |
457 | |
458 | /// Remove the qualifiers from the given set from this set. |
459 | void removeQualifiers(Qualifiers Q) { |
460 | // If the other set doesn't have any non-boolean qualifiers, just |
461 | // bit-and the inverse in. |
462 | if (!(Q.Mask & ~CVRMask)) |
463 | Mask &= ~Q.Mask; |
464 | else { |
465 | Mask &= ~(Q.Mask & CVRMask); |
466 | if (getObjCGCAttr() == Q.getObjCGCAttr()) |
467 | removeObjCGCAttr(); |
468 | if (getObjCLifetime() == Q.getObjCLifetime()) |
469 | removeObjCLifetime(); |
470 | if (getAddressSpace() == Q.getAddressSpace()) |
471 | removeAddressSpace(); |
472 | } |
473 | } |
474 | |
475 | /// Add the qualifiers from the given set to this set, given that |
476 | /// they don't conflict. |
477 | void addConsistentQualifiers(Qualifiers qs) { |
478 | assert(getAddressSpace() == qs.getAddressSpace() ||(static_cast <bool> (getAddressSpace() == qs.getAddressSpace () || !hasAddressSpace() || !qs.hasAddressSpace()) ? void (0) : __assert_fail ("getAddressSpace() == qs.getAddressSpace() || !hasAddressSpace() || !qs.hasAddressSpace()" , "clang/include/clang/AST/Type.h", 479, __extension__ __PRETTY_FUNCTION__ )) |
479 | !hasAddressSpace() || !qs.hasAddressSpace())(static_cast <bool> (getAddressSpace() == qs.getAddressSpace () || !hasAddressSpace() || !qs.hasAddressSpace()) ? void (0) : __assert_fail ("getAddressSpace() == qs.getAddressSpace() || !hasAddressSpace() || !qs.hasAddressSpace()" , "clang/include/clang/AST/Type.h", 479, __extension__ __PRETTY_FUNCTION__ )); |
480 | assert(getObjCGCAttr() == qs.getObjCGCAttr() ||(static_cast <bool> (getObjCGCAttr() == qs.getObjCGCAttr () || !hasObjCGCAttr() || !qs.hasObjCGCAttr()) ? void (0) : __assert_fail ("getObjCGCAttr() == qs.getObjCGCAttr() || !hasObjCGCAttr() || !qs.hasObjCGCAttr()" , "clang/include/clang/AST/Type.h", 481, __extension__ __PRETTY_FUNCTION__ )) |
481 | !hasObjCGCAttr() || !qs.hasObjCGCAttr())(static_cast <bool> (getObjCGCAttr() == qs.getObjCGCAttr () || !hasObjCGCAttr() || !qs.hasObjCGCAttr()) ? void (0) : __assert_fail ("getObjCGCAttr() == qs.getObjCGCAttr() || !hasObjCGCAttr() || !qs.hasObjCGCAttr()" , "clang/include/clang/AST/Type.h", 481, __extension__ __PRETTY_FUNCTION__ )); |
482 | assert(getObjCLifetime() == qs.getObjCLifetime() ||(static_cast <bool> (getObjCLifetime() == qs.getObjCLifetime () || !hasObjCLifetime() || !qs.hasObjCLifetime()) ? void (0) : __assert_fail ("getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()" , "clang/include/clang/AST/Type.h", 483, __extension__ __PRETTY_FUNCTION__ )) |
483 | !hasObjCLifetime() || !qs.hasObjCLifetime())(static_cast <bool> (getObjCLifetime() == qs.getObjCLifetime () || !hasObjCLifetime() || !qs.hasObjCLifetime()) ? void (0) : __assert_fail ("getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()" , "clang/include/clang/AST/Type.h", 483, __extension__ __PRETTY_FUNCTION__ )); |
484 | Mask |= qs.Mask; |
485 | } |
486 | |
487 | /// Returns true if address space A is equal to or a superset of B. |
488 | /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of |
489 | /// overlapping address spaces. |
490 | /// CL1.1 or CL1.2: |
491 | /// every address space is a superset of itself. |
492 | /// CL2.0 adds: |
493 | /// __generic is a superset of any address space except for __constant. |
494 | static bool isAddressSpaceSupersetOf(LangAS A, LangAS B) { |
495 | // Address spaces must match exactly. |
496 | return A == B || |
497 | // Otherwise in OpenCLC v2.0 s6.5.5: every address space except |
498 | // for __constant can be used as __generic. |
499 | (A == LangAS::opencl_generic && B != LangAS::opencl_constant) || |
500 | // We also define global_device and global_host address spaces, |
501 | // to distinguish global pointers allocated on host from pointers |
502 | // allocated on device, which are a subset of __global. |
503 | (A == LangAS::opencl_global && (B == LangAS::opencl_global_device || |
504 | B == LangAS::opencl_global_host)) || |
505 | (A == LangAS::sycl_global && (B == LangAS::sycl_global_device || |
506 | B == LangAS::sycl_global_host)) || |
507 | // Consider pointer size address spaces to be equivalent to default. |
508 | ((isPtrSizeAddressSpace(A) || A == LangAS::Default) && |
509 | (isPtrSizeAddressSpace(B) || B == LangAS::Default)) || |
510 | // Default is a superset of SYCL address spaces. |
511 | (A == LangAS::Default && |
512 | (B == LangAS::sycl_private || B == LangAS::sycl_local || |
513 | B == LangAS::sycl_global || B == LangAS::sycl_global_device || |
514 | B == LangAS::sycl_global_host)) || |
515 | // In HIP device compilation, any cuda address space is allowed |
516 | // to implicitly cast into the default address space. |
517 | (A == LangAS::Default && |
518 | (B == LangAS::cuda_constant || B == LangAS::cuda_device || |
519 | B == LangAS::cuda_shared)); |
520 | } |
521 | |
522 | /// Returns true if the address space in these qualifiers is equal to or |
523 | /// a superset of the address space in the argument qualifiers. |
524 | bool isAddressSpaceSupersetOf(Qualifiers other) const { |
525 | return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace()); |
526 | } |
527 | |
528 | /// Determines if these qualifiers compatibly include another set. |
529 | /// Generally this answers the question of whether an object with the other |
530 | /// qualifiers can be safely used as an object with these qualifiers. |
531 | bool compatiblyIncludes(Qualifiers other) const { |
532 | return isAddressSpaceSupersetOf(other) && |
533 | // ObjC GC qualifiers can match, be added, or be removed, but can't |
534 | // be changed. |
535 | (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || |
536 | !other.hasObjCGCAttr()) && |
537 | // ObjC lifetime qualifiers must match exactly. |
538 | getObjCLifetime() == other.getObjCLifetime() && |
539 | // CVR qualifiers may subset. |
540 | (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) && |
541 | // U qualifier may superset. |
542 | (!other.hasUnaligned() || hasUnaligned()); |
543 | } |
544 | |
545 | /// Determines if these qualifiers compatibly include another set of |
546 | /// qualifiers from the narrow perspective of Objective-C ARC lifetime. |
547 | /// |
548 | /// One set of Objective-C lifetime qualifiers compatibly includes the other |
549 | /// if the lifetime qualifiers match, or if both are non-__weak and the |
550 | /// including set also contains the 'const' qualifier, or both are non-__weak |
551 | /// and one is None (which can only happen in non-ARC modes). |
552 | bool compatiblyIncludesObjCLifetime(Qualifiers other) const { |
553 | if (getObjCLifetime() == other.getObjCLifetime()) |
554 | return true; |
555 | |
556 | if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) |
557 | return false; |
558 | |
559 | if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None) |
560 | return true; |
561 | |
562 | return hasConst(); |
563 | } |
564 | |
565 | /// Determine whether this set of qualifiers is a strict superset of |
566 | /// another set of qualifiers, not considering qualifier compatibility. |
567 | bool isStrictSupersetOf(Qualifiers Other) const; |
568 | |
569 | bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } |
570 | bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } |
571 | |
572 | explicit operator bool() const { return hasQualifiers(); } |
573 | |
574 | Qualifiers &operator+=(Qualifiers R) { |
575 | addQualifiers(R); |
576 | return *this; |
577 | } |
578 | |
579 | // Union two qualifier sets. If an enumerated qualifier appears |
580 | // in both sets, use the one from the right. |
581 | friend Qualifiers operator+(Qualifiers L, Qualifiers R) { |
582 | L += R; |
583 | return L; |
584 | } |
585 | |
586 | Qualifiers &operator-=(Qualifiers R) { |
587 | removeQualifiers(R); |
588 | return *this; |
589 | } |
590 | |
591 | /// Compute the difference between two qualifier sets. |
592 | friend Qualifiers operator-(Qualifiers L, Qualifiers R) { |
593 | L -= R; |
594 | return L; |
595 | } |
596 | |
597 | std::string getAsString() const; |
598 | std::string getAsString(const PrintingPolicy &Policy) const; |
599 | |
600 | static std::string getAddrSpaceAsString(LangAS AS); |
601 | |
602 | bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; |
603 | void print(raw_ostream &OS, const PrintingPolicy &Policy, |
604 | bool appendSpaceIfNonEmpty = false) const; |
605 | |
606 | void Profile(llvm::FoldingSetNodeID &ID) const { |
607 | ID.AddInteger(Mask); |
608 | } |
609 | |
610 | private: |
611 | // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| |
612 | // |C R V|U|GCAttr|Lifetime|AddressSpace| |
613 | uint32_t Mask = 0; |
614 | |
615 | static const uint32_t UMask = 0x8; |
616 | static const uint32_t UShift = 3; |
617 | static const uint32_t GCAttrMask = 0x30; |
618 | static const uint32_t GCAttrShift = 4; |
619 | static const uint32_t LifetimeMask = 0x1C0; |
620 | static const uint32_t LifetimeShift = 6; |
621 | static const uint32_t AddressSpaceMask = |
622 | ~(CVRMask | UMask | GCAttrMask | LifetimeMask); |
623 | static const uint32_t AddressSpaceShift = 9; |
624 | }; |
625 | |
626 | class QualifiersAndAtomic { |
627 | Qualifiers Quals; |
628 | bool HasAtomic; |
629 | |
630 | public: |
631 | QualifiersAndAtomic() : HasAtomic(false) {} |
632 | QualifiersAndAtomic(Qualifiers Quals, bool HasAtomic) |
633 | : Quals(Quals), HasAtomic(HasAtomic) {} |
634 | |
635 | operator Qualifiers() const { return Quals; } |
636 | |
637 | bool hasVolatile() const { return Quals.hasVolatile(); } |
638 | bool hasConst() const { return Quals.hasConst(); } |
639 | bool hasRestrict() const { return Quals.hasRestrict(); } |
640 | bool hasAtomic() const { return HasAtomic; } |
641 | |
642 | void addVolatile() { Quals.addVolatile(); } |
643 | void addConst() { Quals.addConst(); } |
644 | void addRestrict() { Quals.addRestrict(); } |
645 | void addAtomic() { HasAtomic = true; } |
646 | |
647 | void removeVolatile() { Quals.removeVolatile(); } |
648 | void removeConst() { Quals.removeConst(); } |
649 | void removeRestrict() { Quals.removeRestrict(); } |
650 | void removeAtomic() { HasAtomic = false; } |
651 | |
652 | QualifiersAndAtomic withVolatile() { |
653 | return {Quals.withVolatile(), HasAtomic}; |
654 | } |
655 | QualifiersAndAtomic withConst() { return {Quals.withConst(), HasAtomic}; } |
656 | QualifiersAndAtomic withRestrict() { |
657 | return {Quals.withRestrict(), HasAtomic}; |
658 | } |
659 | QualifiersAndAtomic withAtomic() { return {Quals, true}; } |
660 | |
661 | QualifiersAndAtomic &operator+=(Qualifiers RHS) { |
662 | Quals += RHS; |
663 | return *this; |
664 | } |
665 | }; |
666 | |
667 | /// A std::pair-like structure for storing a qualified type split |
668 | /// into its local qualifiers and its locally-unqualified type. |
669 | struct SplitQualType { |
670 | /// The locally-unqualified type. |
671 | const Type *Ty = nullptr; |
672 | |
673 | /// The local qualifiers. |
674 | Qualifiers Quals; |
675 | |
676 | SplitQualType() = default; |
677 | SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {} |
678 | |
679 | SplitQualType getSingleStepDesugaredType() const; // end of this file |
680 | |
681 | // Make std::tie work. |
682 | std::pair<const Type *,Qualifiers> asPair() const { |
683 | return std::pair<const Type *, Qualifiers>(Ty, Quals); |
684 | } |
685 | |
686 | friend bool operator==(SplitQualType a, SplitQualType b) { |
687 | return a.Ty == b.Ty && a.Quals == b.Quals; |
688 | } |
689 | friend bool operator!=(SplitQualType a, SplitQualType b) { |
690 | return a.Ty != b.Ty || a.Quals != b.Quals; |
691 | } |
692 | }; |
693 | |
694 | /// The kind of type we are substituting Objective-C type arguments into. |
695 | /// |
696 | /// The kind of substitution affects the replacement of type parameters when |
697 | /// no concrete type information is provided, e.g., when dealing with an |
698 | /// unspecialized type. |
699 | enum class ObjCSubstitutionContext { |
700 | /// An ordinary type. |
701 | Ordinary, |
702 | |
703 | /// The result type of a method or function. |
704 | Result, |
705 | |
706 | /// The parameter type of a method or function. |
707 | Parameter, |
708 | |
709 | /// The type of a property. |
710 | Property, |
711 | |
712 | /// The superclass of a type. |
713 | Superclass, |
714 | }; |
715 | |
716 | /// The kind of 'typeof' expression we're after. |
717 | enum class TypeOfKind : uint8_t { |
718 | Qualified, |
719 | Unqualified, |
720 | }; |
721 | |
722 | /// A (possibly-)qualified type. |
723 | /// |
724 | /// For efficiency, we don't store CV-qualified types as nodes on their |
725 | /// own: instead each reference to a type stores the qualifiers. This |
726 | /// greatly reduces the number of nodes we need to allocate for types (for |
727 | /// example we only need one for 'int', 'const int', 'volatile int', |
728 | /// 'const volatile int', etc). |
729 | /// |
730 | /// As an added efficiency bonus, instead of making this a pair, we |
731 | /// just store the two bits we care about in the low bits of the |
732 | /// pointer. To handle the packing/unpacking, we make QualType be a |
733 | /// simple wrapper class that acts like a smart pointer. A third bit |
734 | /// indicates whether there are extended qualifiers present, in which |
735 | /// case the pointer points to a special structure. |
736 | class QualType { |
737 | friend class QualifierCollector; |
738 | |
739 | // Thankfully, these are efficiently composable. |
740 | llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>, |
741 | Qualifiers::FastWidth> Value; |
742 | |
743 | const ExtQuals *getExtQualsUnsafe() const { |
744 | return Value.getPointer().get<const ExtQuals*>(); |
745 | } |
746 | |
747 | const Type *getTypePtrUnsafe() const { |
748 | return Value.getPointer().get<const Type*>(); |
749 | } |
750 | |
751 | const ExtQualsTypeCommonBase *getCommonPtr() const { |
752 | 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\"" , "clang/include/clang/AST/Type.h", 752, __extension__ __PRETTY_FUNCTION__ )); |
753 | auto CommonPtrVal = reinterpret_cast<uintptr_t>(Value.getOpaqueValue()); |
754 | CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1); |
755 | return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal); |
756 | } |
757 | |
758 | public: |
759 | QualType() = default; |
760 | QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {} |
761 | QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {} |
762 | |
763 | unsigned getLocalFastQualifiers() const { return Value.getInt(); } |
764 | void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } |
765 | |
766 | /// Retrieves a pointer to the underlying (unqualified) type. |
767 | /// |
768 | /// This function requires that the type not be NULL. If the type might be |
769 | /// NULL, use the (slightly less efficient) \c getTypePtrOrNull(). |
770 | const Type *getTypePtr() const; |
771 | |
772 | const Type *getTypePtrOrNull() const; |
773 | |
774 | /// Retrieves a pointer to the name of the base type. |
775 | const IdentifierInfo *getBaseTypeIdentifier() const; |
776 | |
777 | /// Divides a QualType into its unqualified type and a set of local |
778 | /// qualifiers. |
779 | SplitQualType split() const; |
780 | |
781 | void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } |
782 | |
783 | static QualType getFromOpaquePtr(const void *Ptr) { |
784 | QualType T; |
785 | T.Value.setFromOpaqueValue(const_cast<void*>(Ptr)); |
786 | return T; |
787 | } |
788 | |
789 | const Type &operator*() const { |
790 | return *getTypePtr(); |
791 | } |
792 | |
793 | const Type *operator->() const { |
794 | return getTypePtr(); |
795 | } |
796 | |
797 | bool isCanonical() const; |
798 | bool isCanonicalAsParam() const; |
799 | |
800 | /// Return true if this QualType doesn't point to a type yet. |
801 | bool isNull() const { |
802 | return Value.getPointer().isNull(); |
803 | } |
804 | |
805 | // Determines if a type can form `T&`. |
806 | bool isReferenceable() const; |
807 | |
808 | /// Determine whether this particular QualType instance has the |
809 | /// "const" qualifier set, without looking through typedefs that may have |
810 | /// added "const" at a different level. |
811 | bool isLocalConstQualified() const { |
812 | return (getLocalFastQualifiers() & Qualifiers::Const); |
813 | } |
814 | |
815 | /// Determine whether this type is const-qualified. |
816 | bool isConstQualified() const; |
817 | |
818 | /// Determine whether this particular QualType instance has the |
819 | /// "restrict" qualifier set, without looking through typedefs that may have |
820 | /// added "restrict" at a different level. |
821 | bool isLocalRestrictQualified() const { |
822 | return (getLocalFastQualifiers() & Qualifiers::Restrict); |
823 | } |
824 | |
825 | /// Determine whether this type is restrict-qualified. |
826 | bool isRestrictQualified() const; |
827 | |
828 | /// Determine whether this particular QualType instance has the |
829 | /// "volatile" qualifier set, without looking through typedefs that may have |
830 | /// added "volatile" at a different level. |
831 | bool isLocalVolatileQualified() const { |
832 | return (getLocalFastQualifiers() & Qualifiers::Volatile); |
833 | } |
834 | |
835 | /// Determine whether this type is volatile-qualified. |
836 | bool isVolatileQualified() const; |
837 | |
838 | /// Determine whether this particular QualType instance has any |
839 | /// qualifiers, without looking through any typedefs that might add |
840 | /// qualifiers at a different level. |
841 | bool hasLocalQualifiers() const { |
842 | return getLocalFastQualifiers() || hasLocalNonFastQualifiers(); |
843 | } |
844 | |
845 | /// Determine whether this type has any qualifiers. |
846 | bool hasQualifiers() const; |
847 | |
848 | /// Determine whether this particular QualType instance has any |
849 | /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType |
850 | /// instance. |
851 | bool hasLocalNonFastQualifiers() const { |
852 | return Value.getPointer().is<const ExtQuals*>(); |
853 | } |
854 | |
855 | /// Retrieve the set of qualifiers local to this particular QualType |
856 | /// instance, not including any qualifiers acquired through typedefs or |
857 | /// other sugar. |
858 | Qualifiers getLocalQualifiers() const; |
859 | |
860 | /// Retrieve the set of qualifiers applied to this type. |
861 | Qualifiers getQualifiers() const; |
862 | |
863 | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers |
864 | /// local to this particular QualType instance, not including any qualifiers |
865 | /// acquired through typedefs or other sugar. |
866 | unsigned getLocalCVRQualifiers() const { |
867 | return getLocalFastQualifiers(); |
868 | } |
869 | |
870 | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers |
871 | /// applied to this type. |
872 | unsigned getCVRQualifiers() const; |
873 | |
874 | bool isConstant(const ASTContext& Ctx) const { |
875 | return QualType::isConstant(*this, Ctx); |
876 | } |
877 | |
878 | /// Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). |
879 | bool isPODType(const ASTContext &Context) const; |
880 | |
881 | /// Return true if this is a POD type according to the rules of the C++98 |
882 | /// standard, regardless of the current compilation's language. |
883 | bool isCXX98PODType(const ASTContext &Context) const; |
884 | |
885 | /// Return true if this is a POD type according to the more relaxed rules |
886 | /// of the C++11 standard, regardless of the current compilation's language. |
887 | /// (C++0x [basic.types]p9). Note that, unlike |
888 | /// CXXRecordDecl::isCXX11StandardLayout, this takes DRs into account. |
889 | bool isCXX11PODType(const ASTContext &Context) const; |
890 | |
891 | /// Return true if this is a trivial type per (C++0x [basic.types]p9) |
892 | bool isTrivialType(const ASTContext &Context) const; |
893 | |
894 | /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) |
895 | bool isTriviallyCopyableType(const ASTContext &Context) const; |
896 | |
897 | /// Return true if this is a trivially relocatable type. |
898 | bool isTriviallyRelocatableType(const ASTContext &Context) const; |
899 | |
900 | /// Returns true if it is a class and it might be dynamic. |
901 | bool mayBeDynamicClass() const; |
902 | |
903 | /// Returns true if it is not a class or if the class might not be dynamic. |
904 | bool mayBeNotDynamicClass() const; |
905 | |
906 | // Don't promise in the API that anything besides 'const' can be |
907 | // easily added. |
908 | |
909 | /// Add the `const` type qualifier to this QualType. |
910 | void addConst() { |
911 | addFastQualifiers(Qualifiers::Const); |
912 | } |
913 | QualType withConst() const { |
914 | return withFastQualifiers(Qualifiers::Const); |
915 | } |
916 | |
917 | /// Add the `volatile` type qualifier to this QualType. |
918 | void addVolatile() { |
919 | addFastQualifiers(Qualifiers::Volatile); |
920 | } |
921 | QualType withVolatile() const { |
922 | return withFastQualifiers(Qualifiers::Volatile); |
923 | } |
924 | |
925 | /// Add the `restrict` qualifier to this QualType. |
926 | void addRestrict() { |
927 | addFastQualifiers(Qualifiers::Restrict); |
928 | } |
929 | QualType withRestrict() const { |
930 | return withFastQualifiers(Qualifiers::Restrict); |
931 | } |
932 | |
933 | QualType withCVRQualifiers(unsigned CVR) const { |
934 | return withFastQualifiers(CVR); |
935 | } |
936 | |
937 | void addFastQualifiers(unsigned TQs) { |
938 | 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!\"" , "clang/include/clang/AST/Type.h", 939, __extension__ __PRETTY_FUNCTION__ )) |
939 | && "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!\"" , "clang/include/clang/AST/Type.h", 939, __extension__ __PRETTY_FUNCTION__ )); |
940 | Value.setInt(Value.getInt() | TQs); |
941 | } |
942 | |
943 | void removeLocalConst(); |
944 | void removeLocalVolatile(); |
945 | void removeLocalRestrict(); |
946 | void removeLocalCVRQualifiers(unsigned Mask); |
947 | |
948 | void removeLocalFastQualifiers() { Value.setInt(0); } |
949 | void removeLocalFastQualifiers(unsigned Mask) { |
950 | 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\"" , "clang/include/clang/AST/Type.h", 950, __extension__ __PRETTY_FUNCTION__ )); |
951 | Value.setInt(Value.getInt() & ~Mask); |
952 | } |
953 | |
954 | // Creates a type with the given qualifiers in addition to any |
955 | // qualifiers already on this type. |
956 | QualType withFastQualifiers(unsigned TQs) const { |
957 | QualType T = *this; |
958 | T.addFastQualifiers(TQs); |
959 | return T; |
960 | } |
961 | |
962 | // Creates a type with exactly the given fast qualifiers, removing |
963 | // any existing fast qualifiers. |
964 | QualType withExactLocalFastQualifiers(unsigned TQs) const { |
965 | return withoutLocalFastQualifiers().withFastQualifiers(TQs); |
966 | } |
967 | |
968 | // Removes fast qualifiers, but leaves any extended qualifiers in place. |
969 | QualType withoutLocalFastQualifiers() const { |
970 | QualType T = *this; |
971 | T.removeLocalFastQualifiers(); |
972 | return T; |
973 | } |
974 | |
975 | QualType getCanonicalType() const; |
976 | |
977 | /// Return this type with all of the instance-specific qualifiers |
978 | /// removed, but without removing any qualifiers that may have been applied |
979 | /// through typedefs. |
980 | QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); } |
981 | |
982 | /// Retrieve the unqualified variant of the given type, |
983 | /// removing as little sugar as possible. |
984 | /// |
985 | /// This routine looks through various kinds of sugar to find the |
986 | /// least-desugared type that is unqualified. For example, given: |
987 | /// |
988 | /// \code |
989 | /// typedef int Integer; |
990 | /// typedef const Integer CInteger; |
991 | /// typedef CInteger DifferenceType; |
992 | /// \endcode |
993 | /// |
994 | /// Executing \c getUnqualifiedType() on the type \c DifferenceType will |
995 | /// desugar until we hit the type \c Integer, which has no qualifiers on it. |
996 | /// |
997 | /// The resulting type might still be qualified if it's sugar for an array |
998 | /// type. To strip qualifiers even from within a sugared array type, use |
999 | /// ASTContext::getUnqualifiedArrayType. |
1000 | /// |
1001 | /// Note: In C, the _Atomic qualifier is special (see C2x 6.2.5p29 for |
1002 | /// details), and it is not stripped by this function. Use |
1003 | /// getAtomicUnqualifiedType() to strip qualifiers including _Atomic. |
1004 | inline QualType getUnqualifiedType() const; |
1005 | |
1006 | /// Retrieve the unqualified variant of the given type, removing as little |
1007 | /// sugar as possible. |
1008 | /// |
1009 | /// Like getUnqualifiedType(), but also returns the set of |
1010 | /// qualifiers that were built up. |
1011 | /// |
1012 | /// The resulting type might still be qualified if it's sugar for an array |
1013 | /// type. To strip qualifiers even from within a sugared array type, use |
1014 | /// ASTContext::getUnqualifiedArrayType. |
1015 | inline SplitQualType getSplitUnqualifiedType() const; |
1016 | |
1017 | /// Determine whether this type is more qualified than the other |
1018 | /// given type, requiring exact equality for non-CVR qualifiers. |
1019 | bool isMoreQualifiedThan(QualType Other) const; |
1020 | |
1021 | /// Determine whether this type is at least as qualified as the other |
1022 | /// given type, requiring exact equality for non-CVR qualifiers. |
1023 | bool isAtLeastAsQualifiedAs(QualType Other) const; |
1024 | |
1025 | QualType getNonReferenceType() const; |
1026 | |
1027 | /// Determine the type of a (typically non-lvalue) expression with the |
1028 | /// specified result type. |
1029 | /// |
1030 | /// This routine should be used for expressions for which the return type is |
1031 | /// explicitly specified (e.g., in a cast or call) and isn't necessarily |
1032 | /// an lvalue. It removes a top-level reference (since there are no |
1033 | /// expressions of reference type) and deletes top-level cvr-qualifiers |
1034 | /// from non-class types (in C++) or all types (in C). |
1035 | QualType getNonLValueExprType(const ASTContext &Context) const; |
1036 | |
1037 | /// Remove an outer pack expansion type (if any) from this type. Used as part |
1038 | /// of converting the type of a declaration to the type of an expression that |
1039 | /// references that expression. It's meaningless for an expression to have a |
1040 | /// pack expansion type. |
1041 | QualType getNonPackExpansionType() const; |
1042 | |
1043 | /// Return the specified type with any "sugar" removed from |
1044 | /// the type. This takes off typedefs, typeof's etc. If the outer level of |
1045 | /// the type is already concrete, it returns it unmodified. This is similar |
1046 | /// to getting the canonical type, but it doesn't remove *all* typedefs. For |
1047 | /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is |
1048 | /// concrete. |
1049 | /// |
1050 | /// Qualifiers are left in place. |
1051 | QualType getDesugaredType(const ASTContext &Context) const { |
1052 | return getDesugaredType(*this, Context); |
1053 | } |
1054 | |
1055 | SplitQualType getSplitDesugaredType() const { |
1056 | return getSplitDesugaredType(*this); |
1057 | } |
1058 | |
1059 | /// Return the specified type with one level of "sugar" removed from |
1060 | /// the type. |
1061 | /// |
1062 | /// This routine takes off the first typedef, typeof, etc. If the outer level |
1063 | /// of the type is already concrete, it returns it unmodified. |
1064 | QualType getSingleStepDesugaredType(const ASTContext &Context) const { |
1065 | return getSingleStepDesugaredTypeImpl(*this, Context); |
1066 | } |
1067 | |
1068 | /// Returns the specified type after dropping any |
1069 | /// outer-level parentheses. |
1070 | QualType IgnoreParens() const { |
1071 | if (isa<ParenType>(*this)) |
1072 | return QualType::IgnoreParens(*this); |
1073 | return *this; |
1074 | } |
1075 | |
1076 | /// Indicate whether the specified types and qualifiers are identical. |
1077 | friend bool operator==(const QualType &LHS, const QualType &RHS) { |
1078 | return LHS.Value == RHS.Value; |
1079 | } |
1080 | friend bool operator!=(const QualType &LHS, const QualType &RHS) { |
1081 | return LHS.Value != RHS.Value; |
1082 | } |
1083 | friend bool operator<(const QualType &LHS, const QualType &RHS) { |
1084 | return LHS.Value < RHS.Value; |
1085 | } |
1086 | |
1087 | static std::string getAsString(SplitQualType split, |
1088 | const PrintingPolicy &Policy) { |
1089 | return getAsString(split.Ty, split.Quals, Policy); |
1090 | } |
1091 | static std::string getAsString(const Type *ty, Qualifiers qs, |
1092 | const PrintingPolicy &Policy); |
1093 | |
1094 | std::string getAsString() const; |
1095 | std::string getAsString(const PrintingPolicy &Policy) const; |
1096 | |
1097 | void print(raw_ostream &OS, const PrintingPolicy &Policy, |
1098 | const Twine &PlaceHolder = Twine(), |
1099 | unsigned Indentation = 0) const; |
1100 | |
1101 | static void print(SplitQualType split, raw_ostream &OS, |
1102 | const PrintingPolicy &policy, const Twine &PlaceHolder, |
1103 | unsigned Indentation = 0) { |
1104 | return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation); |
1105 | } |
1106 | |
1107 | static void print(const Type *ty, Qualifiers qs, |
1108 | raw_ostream &OS, const PrintingPolicy &policy, |
1109 | const Twine &PlaceHolder, |
1110 | unsigned Indentation = 0); |
1111 | |
1112 | void getAsStringInternal(std::string &Str, |
1113 | const PrintingPolicy &Policy) const; |
1114 | |
1115 | static void getAsStringInternal(SplitQualType split, std::string &out, |
1116 | const PrintingPolicy &policy) { |
1117 | return getAsStringInternal(split.Ty, split.Quals, out, policy); |
1118 | } |
1119 | |
1120 | static void getAsStringInternal(const Type *ty, Qualifiers qs, |
1121 | std::string &out, |
1122 | const PrintingPolicy &policy); |
1123 | |
1124 | class StreamedQualTypeHelper { |
1125 | const QualType &T; |
1126 | const PrintingPolicy &Policy; |
1127 | const Twine &PlaceHolder; |
1128 | unsigned Indentation; |
1129 | |
1130 | public: |
1131 | StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, |
1132 | const Twine &PlaceHolder, unsigned Indentation) |
1133 | : T(T), Policy(Policy), PlaceHolder(PlaceHolder), |
1134 | Indentation(Indentation) {} |
1135 | |
1136 | friend raw_ostream &operator<<(raw_ostream &OS, |
1137 | const StreamedQualTypeHelper &SQT) { |
1138 | SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation); |
1139 | return OS; |
1140 | } |
1141 | }; |
1142 | |
1143 | StreamedQualTypeHelper stream(const PrintingPolicy &Policy, |
1144 | const Twine &PlaceHolder = Twine(), |
1145 | unsigned Indentation = 0) const { |
1146 | return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation); |
1147 | } |
1148 | |
1149 | void dump(const char *s) const; |
1150 | void dump() const; |
1151 | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; |
1152 | |
1153 | void Profile(llvm::FoldingSetNodeID &ID) const { |
1154 | ID.AddPointer(getAsOpaquePtr()); |
1155 | } |
1156 | |
1157 | /// Check if this type has any address space qualifier. |
1158 | inline bool hasAddressSpace() const; |
1159 | |
1160 | /// Return the address space of this type. |
1161 | inline LangAS getAddressSpace() const; |
1162 | |
1163 | /// Returns true if address space qualifiers overlap with T address space |
1164 | /// qualifiers. |
1165 | /// OpenCL C defines conversion rules for pointers to different address spaces |
1166 | /// and notion of overlapping address spaces. |
1167 | /// CL1.1 or CL1.2: |
1168 | /// address spaces overlap iff they are they same. |
1169 | /// OpenCL C v2.0 s6.5.5 adds: |
1170 | /// __generic overlaps with any address space except for __constant. |
1171 | bool isAddressSpaceOverlapping(QualType T) const { |
1172 | Qualifiers Q = getQualifiers(); |
1173 | Qualifiers TQ = T.getQualifiers(); |
1174 | // Address spaces overlap if at least one of them is a superset of another |
1175 | return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q); |
1176 | } |
1177 | |
1178 | /// Returns gc attribute of this type. |
1179 | inline Qualifiers::GC getObjCGCAttr() const; |
1180 | |
1181 | /// true when Type is objc's weak. |
1182 | bool isObjCGCWeak() const { |
1183 | return getObjCGCAttr() == Qualifiers::Weak; |
1184 | } |
1185 | |
1186 | /// true when Type is objc's strong. |
1187 | bool isObjCGCStrong() const { |
1188 | return getObjCGCAttr() == Qualifiers::Strong; |
1189 | } |
1190 | |
1191 | /// Returns lifetime attribute of this type. |
1192 | Qualifiers::ObjCLifetime getObjCLifetime() const { |
1193 | return getQualifiers().getObjCLifetime(); |
1194 | } |
1195 | |
1196 | bool hasNonTrivialObjCLifetime() const { |
1197 | return getQualifiers().hasNonTrivialObjCLifetime(); |
1198 | } |
1199 | |
1200 | bool hasStrongOrWeakObjCLifetime() const { |
1201 | return getQualifiers().hasStrongOrWeakObjCLifetime(); |
1202 | } |
1203 | |
1204 | // true when Type is objc's weak and weak is enabled but ARC isn't. |
1205 | bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const; |
1206 | |
1207 | enum PrimitiveDefaultInitializeKind { |
1208 | /// The type does not fall into any of the following categories. Note that |
1209 | /// this case is zero-valued so that values of this enum can be used as a |
1210 | /// boolean condition for non-triviality. |
1211 | PDIK_Trivial, |
1212 | |
1213 | /// The type is an Objective-C retainable pointer type that is qualified |
1214 | /// with the ARC __strong qualifier. |
1215 | PDIK_ARCStrong, |
1216 | |
1217 | /// The type is an Objective-C retainable pointer type that is qualified |
1218 | /// with the ARC __weak qualifier. |
1219 | PDIK_ARCWeak, |
1220 | |
1221 | /// The type is a struct containing a field whose type is not PCK_Trivial. |
1222 | PDIK_Struct |
1223 | }; |
1224 | |
1225 | /// Functions to query basic properties of non-trivial C struct types. |
1226 | |
1227 | /// Check if this is a non-trivial type that would cause a C struct |
1228 | /// transitively containing this type to be non-trivial to default initialize |
1229 | /// and return the kind. |
1230 | PrimitiveDefaultInitializeKind |
1231 | isNonTrivialToPrimitiveDefaultInitialize() const; |
1232 | |
1233 | enum PrimitiveCopyKind { |
1234 | /// The type does not fall into any of the following categories. Note that |
1235 | /// this case is zero-valued so that values of this enum can be used as a |
1236 | /// boolean condition for non-triviality. |
1237 | PCK_Trivial, |
1238 | |
1239 | /// The type would be trivial except that it is volatile-qualified. Types |
1240 | /// that fall into one of the other non-trivial cases may additionally be |
1241 | /// volatile-qualified. |
1242 | PCK_VolatileTrivial, |
1243 | |
1244 | /// The type is an Objective-C retainable pointer type that is qualified |
1245 | /// with the ARC __strong qualifier. |
1246 | PCK_ARCStrong, |
1247 | |
1248 | /// The type is an Objective-C retainable pointer type that is qualified |
1249 | /// with the ARC __weak qualifier. |
1250 | PCK_ARCWeak, |
1251 | |
1252 | /// The type is a struct containing a field whose type is neither |
1253 | /// PCK_Trivial nor PCK_VolatileTrivial. |
1254 | /// Note that a C++ struct type does not necessarily match this; C++ copying |
1255 | /// semantics are too complex to express here, in part because they depend |
1256 | /// on the exact constructor or assignment operator that is chosen by |
1257 | /// overload resolution to do the copy. |
1258 | PCK_Struct |
1259 | }; |
1260 | |
1261 | /// Check if this is a non-trivial type that would cause a C struct |
1262 | /// transitively containing this type to be non-trivial to copy and return the |
1263 | /// kind. |
1264 | PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const; |
1265 | |
1266 | /// Check if this is a non-trivial type that would cause a C struct |
1267 | /// transitively containing this type to be non-trivial to destructively |
1268 | /// move and return the kind. Destructive move in this context is a C++-style |
1269 | /// move in which the source object is placed in a valid but unspecified state |
1270 | /// after it is moved, as opposed to a truly destructive move in which the |
1271 | /// source object is placed in an uninitialized state. |
1272 | PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const; |
1273 | |
1274 | enum DestructionKind { |
1275 | DK_none, |
1276 | DK_cxx_destructor, |
1277 | DK_objc_strong_lifetime, |
1278 | DK_objc_weak_lifetime, |
1279 | DK_nontrivial_c_struct |
1280 | }; |
1281 | |
1282 | /// Returns a nonzero value if objects of this type require |
1283 | /// non-trivial work to clean up after. Non-zero because it's |
1284 | /// conceivable that qualifiers (objc_gc(weak)?) could make |
1285 | /// something require destruction. |
1286 | DestructionKind isDestructedType() const { |
1287 | return isDestructedTypeImpl(*this); |
1288 | } |
1289 | |
1290 | /// Check if this is or contains a C union that is non-trivial to |
1291 | /// default-initialize, which is a union that has a member that is non-trivial |
1292 | /// to default-initialize. If this returns true, |
1293 | /// isNonTrivialToPrimitiveDefaultInitialize returns PDIK_Struct. |
1294 | bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const; |
1295 | |
1296 | /// Check if this is or contains a C union that is non-trivial to destruct, |
1297 | /// which is a union that has a member that is non-trivial to destruct. If |
1298 | /// this returns true, isDestructedType returns DK_nontrivial_c_struct. |
1299 | bool hasNonTrivialToPrimitiveDestructCUnion() const; |
1300 | |
1301 | /// Check if this is or contains a C union that is non-trivial to copy, which |
1302 | /// is a union that has a member that is non-trivial to copy. If this returns |
1303 | /// true, isNonTrivialToPrimitiveCopy returns PCK_Struct. |
1304 | bool hasNonTrivialToPrimitiveCopyCUnion() const; |
1305 | |
1306 | /// Determine whether expressions of the given type are forbidden |
1307 | /// from being lvalues in C. |
1308 | /// |
1309 | /// The expression types that are forbidden to be lvalues are: |
1310 | /// - 'void', but not qualified void |
1311 | /// - function types |
1312 | /// |
1313 | /// The exact rule here is C99 6.3.2.1: |
1314 | /// An lvalue is an expression with an object type or an incomplete |
1315 | /// type other than void. |
1316 | bool isCForbiddenLValueType() const; |
1317 | |
1318 | /// Substitute type arguments for the Objective-C type parameters used in the |
1319 | /// subject type. |
1320 | /// |
1321 | /// \param ctx ASTContext in which the type exists. |
1322 | /// |
1323 | /// \param typeArgs The type arguments that will be substituted for the |
1324 | /// Objective-C type parameters in the subject type, which are generally |
1325 | /// computed via \c Type::getObjCSubstitutions. If empty, the type |
1326 | /// parameters will be replaced with their bounds or id/Class, as appropriate |
1327 | /// for the context. |
1328 | /// |
1329 | /// \param context The context in which the subject type was written. |
1330 | /// |
1331 | /// \returns the resulting type. |
1332 | QualType substObjCTypeArgs(ASTContext &ctx, |
1333 | ArrayRef<QualType> typeArgs, |
1334 | ObjCSubstitutionContext context) const; |
1335 | |
1336 | /// Substitute type arguments from an object type for the Objective-C type |
1337 | /// parameters used in the subject type. |
1338 | /// |
1339 | /// This operation combines the computation of type arguments for |
1340 | /// substitution (\c Type::getObjCSubstitutions) with the actual process of |
1341 | /// substitution (\c QualType::substObjCTypeArgs) for the convenience of |
1342 | /// callers that need to perform a single substitution in isolation. |
1343 | /// |
1344 | /// \param objectType The type of the object whose member type we're |
1345 | /// substituting into. For example, this might be the receiver of a message |
1346 | /// or the base of a property access. |
1347 | /// |
1348 | /// \param dc The declaration context from which the subject type was |
1349 | /// retrieved, which indicates (for example) which type parameters should |
1350 | /// be substituted. |
1351 | /// |
1352 | /// \param context The context in which the subject type was written. |
1353 | /// |
1354 | /// \returns the subject type after replacing all of the Objective-C type |
1355 | /// parameters with their corresponding arguments. |
1356 | QualType substObjCMemberType(QualType objectType, |
1357 | const DeclContext *dc, |
1358 | ObjCSubstitutionContext context) const; |
1359 | |
1360 | /// Strip Objective-C "__kindof" types from the given type. |
1361 | QualType stripObjCKindOfType(const ASTContext &ctx) const; |
1362 | |
1363 | /// Remove all qualifiers including _Atomic. |
1364 | QualType getAtomicUnqualifiedType() const; |
1365 | |
1366 | private: |
1367 | // These methods are implemented in a separate translation unit; |
1368 | // "static"-ize them to avoid creating temporary QualTypes in the |
1369 | // caller. |
1370 | static bool isConstant(QualType T, const ASTContext& Ctx); |
1371 | static QualType getDesugaredType(QualType T, const ASTContext &Context); |
1372 | static SplitQualType getSplitDesugaredType(QualType T); |
1373 | static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); |
1374 | static QualType getSingleStepDesugaredTypeImpl(QualType type, |
1375 | const ASTContext &C); |
1376 | static QualType IgnoreParens(QualType T); |
1377 | static DestructionKind isDestructedTypeImpl(QualType type); |
1378 | |
1379 | /// Check if \param RD is or contains a non-trivial C union. |
1380 | static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD); |
1381 | static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD); |
1382 | static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD); |
1383 | }; |
1384 | |
1385 | raw_ostream &operator<<(raw_ostream &OS, QualType QT); |
1386 | |
1387 | } // namespace clang |
1388 | |
1389 | namespace llvm { |
1390 | |
1391 | /// Implement simplify_type for QualType, so that we can dyn_cast from QualType |
1392 | /// to a specific Type class. |
1393 | template<> struct simplify_type< ::clang::QualType> { |
1394 | using SimpleType = const ::clang::Type *; |
1395 | |
1396 | static SimpleType getSimplifiedValue(::clang::QualType Val) { |
1397 | return Val.getTypePtr(); |
1398 | } |
1399 | }; |
1400 | |
1401 | // Teach SmallPtrSet that QualType is "basically a pointer". |
1402 | template<> |
1403 | struct PointerLikeTypeTraits<clang::QualType> { |
1404 | static inline void *getAsVoidPointer(clang::QualType P) { |
1405 | return P.getAsOpaquePtr(); |
1406 | } |
1407 | |
1408 | static inline clang::QualType getFromVoidPointer(void *P) { |
1409 | return clang::QualType::getFromOpaquePtr(P); |
1410 | } |
1411 | |
1412 | // Various qualifiers go in low bits. |
1413 | static constexpr int NumLowBitsAvailable = 0; |
1414 | }; |
1415 | |
1416 | } // namespace llvm |
1417 | |
1418 | namespace clang { |
1419 | |
1420 | /// Base class that is common to both the \c ExtQuals and \c Type |
1421 | /// classes, which allows \c QualType to access the common fields between the |
1422 | /// two. |
1423 | class ExtQualsTypeCommonBase { |
1424 | friend class ExtQuals; |
1425 | friend class QualType; |
1426 | friend class Type; |
1427 | |
1428 | /// The "base" type of an extended qualifiers type (\c ExtQuals) or |
1429 | /// a self-referential pointer (for \c Type). |
1430 | /// |
1431 | /// This pointer allows an efficient mapping from a QualType to its |
1432 | /// underlying type pointer. |
1433 | const Type *const BaseType; |
1434 | |
1435 | /// The canonical type of this type. A QualType. |
1436 | QualType CanonicalType; |
1437 | |
1438 | ExtQualsTypeCommonBase(const Type *baseType, QualType canon) |
1439 | : BaseType(baseType), CanonicalType(canon) {} |
1440 | }; |
1441 | |
1442 | /// We can encode up to four bits in the low bits of a |
1443 | /// type pointer, but there are many more type qualifiers that we want |
1444 | /// to be able to apply to an arbitrary type. Therefore we have this |
1445 | /// struct, intended to be heap-allocated and used by QualType to |
1446 | /// store qualifiers. |
1447 | /// |
1448 | /// The current design tags the 'const', 'restrict', and 'volatile' qualifiers |
1449 | /// in three low bits on the QualType pointer; a fourth bit records whether |
1450 | /// the pointer is an ExtQuals node. The extended qualifiers (address spaces, |
1451 | /// Objective-C GC attributes) are much more rare. |
1452 | class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode { |
1453 | // NOTE: changing the fast qualifiers should be straightforward as |
1454 | // long as you don't make 'const' non-fast. |
1455 | // 1. Qualifiers: |
1456 | // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ). |
1457 | // Fast qualifiers must occupy the low-order bits. |
1458 | // b) Update Qualifiers::FastWidth and FastMask. |
1459 | // 2. QualType: |
1460 | // a) Update is{Volatile,Restrict}Qualified(), defined inline. |
1461 | // b) Update remove{Volatile,Restrict}, defined near the end of |
1462 | // this header. |
1463 | // 3. ASTContext: |
1464 | // a) Update get{Volatile,Restrict}Type. |
1465 | |
1466 | /// The immutable set of qualifiers applied by this node. Always contains |
1467 | /// extended qualifiers. |
1468 | Qualifiers Quals; |
1469 | |
1470 | ExtQuals *this_() { return this; } |
1471 | |
1472 | public: |
1473 | ExtQuals(const Type *baseType, QualType canon, Qualifiers quals) |
1474 | : ExtQualsTypeCommonBase(baseType, |
1475 | canon.isNull() ? QualType(this_(), 0) : canon), |
1476 | Quals(quals) { |
1477 | 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\"" , "clang/include/clang/AST/Type.h", 1478, __extension__ __PRETTY_FUNCTION__ )) |
1478 | && "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\"" , "clang/include/clang/AST/Type.h", 1478, __extension__ __PRETTY_FUNCTION__ )); |
1479 | assert(!Quals.hasFastQualifiers()(static_cast <bool> (!Quals.hasFastQualifiers() && "ExtQuals created with fast qualifiers") ? void (0) : __assert_fail ("!Quals.hasFastQualifiers() && \"ExtQuals created with fast qualifiers\"" , "clang/include/clang/AST/Type.h", 1480, __extension__ __PRETTY_FUNCTION__ )) |
1480 | && "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\"" , "clang/include/clang/AST/Type.h", 1480, __extension__ __PRETTY_FUNCTION__ )); |
1481 | } |
1482 | |
1483 | Qualifiers getQualifiers() const { return Quals; } |
1484 | |
1485 | bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); } |
1486 | Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); } |
1487 | |
1488 | bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); } |
1489 | Qualifiers::ObjCLifetime getObjCLifetime() const { |
1490 | return Quals.getObjCLifetime(); |
1491 | } |
1492 | |
1493 | bool hasAddressSpace() const { return Quals.hasAddressSpace(); } |
1494 | LangAS getAddressSpace() const { return Quals.getAddressSpace(); } |
1495 | |
1496 | const Type *getBaseType() const { return BaseType; } |
1497 | |
1498 | public: |
1499 | void Profile(llvm::FoldingSetNodeID &ID) const { |
1500 | Profile(ID, getBaseType(), Quals); |
1501 | } |
1502 | |
1503 | static void Profile(llvm::FoldingSetNodeID &ID, |
1504 | const Type *BaseType, |
1505 | Qualifiers Quals) { |
1506 | 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!\"" , "clang/include/clang/AST/Type.h", 1506, __extension__ __PRETTY_FUNCTION__ )); |
1507 | ID.AddPointer(BaseType); |
1508 | Quals.Profile(ID); |
1509 | } |
1510 | }; |
1511 | |
1512 | /// The kind of C++11 ref-qualifier associated with a function type. |
1513 | /// This determines whether a member function's "this" object can be an |
1514 | /// lvalue, rvalue, or neither. |
1515 | enum RefQualifierKind { |
1516 | /// No ref-qualifier was provided. |
1517 | RQ_None = 0, |
1518 | |
1519 | /// An lvalue ref-qualifier was provided (\c &). |
1520 | RQ_LValue, |
1521 | |
1522 | /// An rvalue ref-qualifier was provided (\c &&). |
1523 | RQ_RValue |
1524 | }; |
1525 | |
1526 | /// Which keyword(s) were used to create an AutoType. |
1527 | enum class AutoTypeKeyword { |
1528 | /// auto |
1529 | Auto, |
1530 | |
1531 | /// decltype(auto) |
1532 | DecltypeAuto, |
1533 | |
1534 | /// __auto_type (GNU extension) |
1535 | GNUAutoType |
1536 | }; |
1537 | |
1538 | /// The base class of the type hierarchy. |
1539 | /// |
1540 | /// A central concept with types is that each type always has a canonical |
1541 | /// type. A canonical type is the type with any typedef names stripped out |
1542 | /// of it or the types it references. For example, consider: |
1543 | /// |
1544 | /// typedef int foo; |
1545 | /// typedef foo* bar; |
1546 | /// 'int *' 'foo *' 'bar' |
1547 | /// |
1548 | /// There will be a Type object created for 'int'. Since int is canonical, its |
1549 | /// CanonicalType pointer points to itself. There is also a Type for 'foo' (a |
1550 | /// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next |
1551 | /// there is a PointerType that represents 'int*', which, like 'int', is |
1552 | /// canonical. Finally, there is a PointerType type for 'foo*' whose canonical |
1553 | /// type is 'int*', and there is a TypedefType for 'bar', whose canonical type |
1554 | /// is also 'int*'. |
1555 | /// |
1556 | /// Non-canonical types are useful for emitting diagnostics, without losing |
1557 | /// information about typedefs being used. Canonical types are useful for type |
1558 | /// comparisons (they allow by-pointer equality tests) and useful for reasoning |
1559 | /// about whether something has a particular form (e.g. is a function type), |
1560 | /// because they implicitly, recursively, strip all typedefs out of a type. |
1561 | /// |
1562 | /// Types, once created, are immutable. |
1563 | /// |
1564 | class alignas(8) Type : public ExtQualsTypeCommonBase { |
1565 | public: |
1566 | enum TypeClass { |
1567 | #define TYPE(Class, Base) Class, |
1568 | #define LAST_TYPE(Class) TypeLast = Class |
1569 | #define ABSTRACT_TYPE(Class, Base) |
1570 | #include "clang/AST/TypeNodes.inc" |
1571 | }; |
1572 | |
1573 | private: |
1574 | /// Bitfields required by the Type class. |
1575 | class TypeBitfields { |
1576 | friend class Type; |
1577 | template <class T> friend class TypePropertyCache; |
1578 | |
1579 | /// TypeClass bitfield - Enum that specifies what subclass this belongs to. |
1580 | unsigned TC : 8; |
1581 | |
1582 | /// Store information on the type dependency. |
1583 | unsigned Dependence : llvm::BitWidth<TypeDependence>; |
1584 | |
1585 | /// True if the cache (i.e. the bitfields here starting with |
1586 | /// 'Cache') is valid. |
1587 | mutable unsigned CacheValid : 1; |
1588 | |
1589 | /// Linkage of this type. |
1590 | mutable unsigned CachedLinkage : 3; |
1591 | |
1592 | /// Whether this type involves and local or unnamed types. |
1593 | mutable unsigned CachedLocalOrUnnamed : 1; |
1594 | |
1595 | /// Whether this type comes from an AST file. |
1596 | mutable unsigned FromAST : 1; |
1597 | |
1598 | bool isCacheValid() const { |
1599 | return CacheValid; |
1600 | } |
1601 | |
1602 | Linkage getLinkage() const { |
1603 | 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\"" , "clang/include/clang/AST/Type.h", 1603, __extension__ __PRETTY_FUNCTION__ )); |
1604 | return static_cast<Linkage>(CachedLinkage); |
1605 | } |
1606 | |
1607 | bool hasLocalOrUnnamedType() const { |
1608 | 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\"" , "clang/include/clang/AST/Type.h", 1608, __extension__ __PRETTY_FUNCTION__ )); |
1609 | return CachedLocalOrUnnamed; |
1610 | } |
1611 | }; |
1612 | enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 }; |
1613 | |
1614 | protected: |
1615 | // These classes allow subclasses to somewhat cleanly pack bitfields |
1616 | // into Type. |
1617 | |
1618 | class ArrayTypeBitfields { |
1619 | friend class ArrayType; |
1620 | |
1621 | unsigned : NumTypeBits; |
1622 | |
1623 | /// CVR qualifiers from declarations like |
1624 | /// 'int X[static restrict 4]'. For function parameters only. |
1625 | unsigned IndexTypeQuals : 3; |
1626 | |
1627 | /// Storage class qualifiers from declarations like |
1628 | /// 'int X[static restrict 4]'. For function parameters only. |
1629 | /// Actually an ArrayType::ArraySizeModifier. |
1630 | unsigned SizeModifier : 3; |
1631 | }; |
1632 | |
1633 | class ConstantArrayTypeBitfields { |
1634 | friend class ConstantArrayType; |
1635 | |
1636 | unsigned : NumTypeBits + 3 + 3; |
1637 | |
1638 | /// Whether we have a stored size expression. |
1639 | unsigned HasStoredSizeExpr : 1; |
1640 | }; |
1641 | |
1642 | class BuiltinTypeBitfields { |
1643 | friend class BuiltinType; |
1644 | |
1645 | unsigned : NumTypeBits; |
1646 | |
1647 | /// The kind (BuiltinType::Kind) of builtin type this is. |
1648 | unsigned Kind : 8; |
1649 | }; |
1650 | |
1651 | /// FunctionTypeBitfields store various bits belonging to FunctionProtoType. |
1652 | /// Only common bits are stored here. Additional uncommon bits are stored |
1653 | /// in a trailing object after FunctionProtoType. |
1654 | class FunctionTypeBitfields { |
1655 | friend class FunctionProtoType; |
1656 | friend class FunctionType; |
1657 | |
1658 | unsigned : NumTypeBits; |
1659 | |
1660 | /// Extra information which affects how the function is called, like |
1661 | /// regparm and the calling convention. |
1662 | unsigned ExtInfo : 13; |
1663 | |
1664 | /// The ref-qualifier associated with a \c FunctionProtoType. |
1665 | /// |
1666 | /// This is a value of type \c RefQualifierKind. |
1667 | unsigned RefQualifier : 2; |
1668 | |
1669 | /// Used only by FunctionProtoType, put here to pack with the |
1670 | /// other bitfields. |
1671 | /// The qualifiers are part of FunctionProtoType because... |
1672 | /// |
1673 | /// C++ 8.3.5p4: The return type, the parameter type list and the |
1674 | /// cv-qualifier-seq, [...], are part of the function type. |
1675 | unsigned FastTypeQuals : Qualifiers::FastWidth; |
1676 | /// Whether this function has extended Qualifiers. |
1677 | unsigned HasExtQuals : 1; |
1678 | |
1679 | /// The number of parameters this function has, not counting '...'. |
1680 | /// According to [implimits] 8 bits should be enough here but this is |
1681 | /// somewhat easy to exceed with metaprogramming and so we would like to |
1682 | /// keep NumParams as wide as reasonably possible. |
1683 | unsigned NumParams : 16; |
1684 | |
1685 | /// The type of exception specification this function has. |
1686 | unsigned ExceptionSpecType : 4; |
1687 | |
1688 | /// Whether this function has extended parameter information. |
1689 | unsigned HasExtParameterInfos : 1; |
1690 | |
1691 | /// Whether this function has extra bitfields for the prototype. |
1692 | unsigned HasExtraBitfields : 1; |
1693 | |
1694 | /// Whether the function is variadic. |
1695 | unsigned Variadic : 1; |
1696 | |
1697 | /// Whether this function has a trailing return type. |
1698 | unsigned HasTrailingReturn : 1; |
1699 | }; |
1700 | |
1701 | class ObjCObjectTypeBitfields { |
1702 | friend class ObjCObjectType; |
1703 | |
1704 | unsigned : NumTypeBits; |
1705 | |
1706 | /// The number of type arguments stored directly on this object type. |
1707 | unsigned NumTypeArgs : 7; |
1708 | |
1709 | /// The number of protocols stored directly on this object type. |
1710 | unsigned NumProtocols : 6; |
1711 | |
1712 | /// Whether this is a "kindof" type. |
1713 | unsigned IsKindOf : 1; |
1714 | }; |
1715 | |
1716 | class ReferenceTypeBitfields { |
1717 | friend class ReferenceType; |
1718 | |
1719 | unsigned : NumTypeBits; |
1720 | |
1721 | /// True if the type was originally spelled with an lvalue sigil. |
1722 | /// This is never true of rvalue references but can also be false |
1723 | /// on lvalue references because of C++0x [dcl.typedef]p9, |
1724 | /// as follows: |
1725 | /// |
1726 | /// typedef int &ref; // lvalue, spelled lvalue |
1727 | /// typedef int &&rvref; // rvalue |
1728 | /// ref &a; // lvalue, inner ref, spelled lvalue |
1729 | /// ref &&a; // lvalue, inner ref |
1730 | /// rvref &a; // lvalue, inner ref, spelled lvalue |
1731 | /// rvref &&a; // rvalue, inner ref |
1732 | unsigned SpelledAsLValue : 1; |
1733 | |
1734 | /// True if the inner type is a reference type. This only happens |
1735 | /// in non-canonical forms. |
1736 | unsigned InnerRef : 1; |
1737 | }; |
1738 | |
1739 | class TypeWithKeywordBitfields { |
1740 | friend class TypeWithKeyword; |
1741 | |
1742 | unsigned : NumTypeBits; |
1743 | |
1744 | /// An ElaboratedTypeKeyword. 8 bits for efficient access. |
1745 | unsigned Keyword : 8; |
1746 | }; |
1747 | |
1748 | enum { NumTypeWithKeywordBits = 8 }; |
1749 | |
1750 | class ElaboratedTypeBitfields { |
1751 | friend class ElaboratedType; |
1752 | |
1753 | unsigned : NumTypeBits; |
1754 | unsigned : NumTypeWithKeywordBits; |
1755 | |
1756 | /// Whether the ElaboratedType has a trailing OwnedTagDecl. |
1757 | unsigned HasOwnedTagDecl : 1; |
1758 | }; |
1759 | |
1760 | class VectorTypeBitfields { |
1761 | friend class VectorType; |
1762 | friend class DependentVectorType; |
1763 | |
1764 | unsigned : NumTypeBits; |
1765 | |
1766 | /// The kind of vector, either a generic vector type or some |
1767 | /// target-specific vector type such as for AltiVec or Neon. |
1768 | unsigned VecKind : 3; |
1769 | /// The number of elements in the vector. |
1770 | uint32_t NumElements; |
1771 | }; |
1772 | |
1773 | class AttributedTypeBitfields { |
1774 | friend class AttributedType; |
1775 | |
1776 | unsigned : NumTypeBits; |
1777 | |
1778 | /// An AttributedType::Kind |
1779 | unsigned AttrKind : 32 - NumTypeBits; |
1780 | }; |
1781 | |
1782 | class AutoTypeBitfields { |
1783 | friend class AutoType; |
1784 | |
1785 | unsigned : NumTypeBits; |
1786 | |
1787 | /// Was this placeholder type spelled as 'auto', 'decltype(auto)', |
1788 | /// or '__auto_type'? AutoTypeKeyword value. |
1789 | unsigned Keyword : 2; |
1790 | |
1791 | /// The number of template arguments in the type-constraints, which is |
1792 | /// expected to be able to hold at least 1024 according to [implimits]. |
1793 | /// However as this limit is somewhat easy to hit with template |
1794 | /// metaprogramming we'd prefer to keep it as large as possible. |
1795 | /// At the moment it has been left as a non-bitfield since this type |
1796 | /// safely fits in 64 bits as an unsigned, so there is no reason to |
1797 | /// introduce the performance impact of a bitfield. |
1798 | unsigned NumArgs; |
1799 | }; |
1800 | |
1801 | class TypeOfBitfields { |
1802 | friend class TypeOfType; |
1803 | friend class TypeOfExprType; |
1804 | |
1805 | unsigned : NumTypeBits; |
1806 | unsigned IsUnqual : 1; // If true: typeof_unqual, else: typeof |
1807 | }; |
1808 | |
1809 | class UsingBitfields { |
1810 | friend class UsingType; |
1811 | |
1812 | unsigned : NumTypeBits; |
1813 | |
1814 | /// True if the underlying type is different from the declared one. |
1815 | unsigned hasTypeDifferentFromDecl : 1; |
1816 | }; |
1817 | |
1818 | class TypedefBitfields { |
1819 | friend class TypedefType; |
1820 | |
1821 | unsigned : NumTypeBits; |
1822 | |
1823 | /// True if the underlying type is different from the declared one. |
1824 | unsigned hasTypeDifferentFromDecl : 1; |
1825 | }; |
1826 | |
1827 | class SubstTemplateTypeParmTypeBitfields { |
1828 | friend class SubstTemplateTypeParmType; |
1829 | |
1830 | unsigned : NumTypeBits; |
1831 | |
1832 | unsigned HasNonCanonicalUnderlyingType : 1; |
1833 | |
1834 | // The index of the template parameter this substitution represents. |
1835 | unsigned Index : 15; |
1836 | |
1837 | /// Represents the index within a pack if this represents a substitution |
1838 | /// from a pack expansion. This index starts at the end of the pack and |
1839 | /// increments towards the beginning. |
1840 | /// Positive non-zero number represents the index + 1. |
1841 | /// Zero means this is not substituted from an expansion. |
1842 | unsigned PackIndex : 16; |
1843 | }; |
1844 | |
1845 | class SubstTemplateTypeParmPackTypeBitfields { |
1846 | friend class SubstTemplateTypeParmPackType; |
1847 | |
1848 | unsigned : NumTypeBits; |
1849 | |
1850 | // The index of the template parameter this substitution represents. |
1851 | unsigned Index : 16; |
1852 | |
1853 | /// The number of template arguments in \c Arguments, which is |
1854 | /// expected to be able to hold at least 1024 according to [implimits]. |
1855 | /// However as this limit is somewhat easy to hit with template |
1856 | /// metaprogramming we'd prefer to keep it as large as possible. |
1857 | unsigned NumArgs : 16; |
1858 | }; |
1859 | |
1860 | class TemplateSpecializationTypeBitfields { |
1861 | friend class TemplateSpecializationType; |
1862 | |
1863 | unsigned : NumTypeBits; |
1864 | |
1865 | /// Whether this template specialization type is a substituted type alias. |
1866 | unsigned TypeAlias : 1; |
1867 | |
1868 | /// The number of template arguments named in this class template |
1869 | /// specialization, which is expected to be able to hold at least 1024 |
1870 | /// according to [implimits]. However, as this limit is somewhat easy to |
1871 | /// hit with template metaprogramming we'd prefer to keep it as large |
1872 | /// as possible. At the moment it has been left as a non-bitfield since |
1873 | /// this type safely fits in 64 bits as an unsigned, so there is no reason |
1874 | /// to introduce the performance impact of a bitfield. |
1875 | unsigned NumArgs; |
1876 | }; |
1877 | |
1878 | class DependentTemplateSpecializationTypeBitfields { |
1879 | friend class DependentTemplateSpecializationType; |
1880 | |
1881 | unsigned : NumTypeBits; |
1882 | unsigned : NumTypeWithKeywordBits; |
1883 | |
1884 | /// The number of template arguments named in this class template |
1885 | /// specialization, which is expected to be able to hold at least 1024 |
1886 | /// according to [implimits]. However, as this limit is somewhat easy to |
1887 | /// hit with template metaprogramming we'd prefer to keep it as large |
1888 | /// as possible. At the moment it has been left as a non-bitfield since |
1889 | /// this type safely fits in 64 bits as an unsigned, so there is no reason |
1890 | /// to introduce the performance impact of a bitfield. |
1891 | unsigned NumArgs; |
1892 | }; |
1893 | |
1894 | class PackExpansionTypeBitfields { |
1895 | friend class PackExpansionType; |
1896 | |
1897 | unsigned : NumTypeBits; |
1898 | |
1899 | /// The number of expansions that this pack expansion will |
1900 | /// generate when substituted (+1), which is expected to be able to |
1901 | /// hold at least 1024 according to [implimits]. However, as this limit |
1902 | /// is somewhat easy to hit with template metaprogramming we'd prefer to |
1903 | /// keep it as large as possible. At the moment it has been left as a |
1904 | /// non-bitfield since this type safely fits in 64 bits as an unsigned, so |
1905 | /// there is no reason to introduce the performance impact of a bitfield. |
1906 | /// |
1907 | /// This field will only have a non-zero value when some of the parameter |
1908 | /// packs that occur within the pattern have been substituted but others |
1909 | /// have not. |
1910 | unsigned NumExpansions; |
1911 | }; |
1912 | |
1913 | union { |
1914 | TypeBitfields TypeBits; |
1915 | ArrayTypeBitfields ArrayTypeBits; |
1916 | ConstantArrayTypeBitfields ConstantArrayTypeBits; |
1917 | AttributedTypeBitfields AttributedTypeBits; |
1918 | AutoTypeBitfields AutoTypeBits; |
1919 | TypeOfBitfields TypeOfBits; |
1920 | TypedefBitfields TypedefBits; |
1921 | UsingBitfields UsingBits; |
1922 | BuiltinTypeBitfields BuiltinTypeBits; |
1923 | FunctionTypeBitfields FunctionTypeBits; |
1924 | ObjCObjectTypeBitfields ObjCObjectTypeBits; |
1925 | ReferenceTypeBitfields ReferenceTypeBits; |
1926 | TypeWithKeywordBitfields TypeWithKeywordBits; |
1927 | ElaboratedTypeBitfields ElaboratedTypeBits; |
1928 | VectorTypeBitfields VectorTypeBits; |
1929 | SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits; |
1930 | SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; |
1931 | TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; |
1932 | DependentTemplateSpecializationTypeBitfields |
1933 | DependentTemplateSpecializationTypeBits; |
1934 | PackExpansionTypeBitfields PackExpansionTypeBits; |
1935 | }; |
1936 | |
1937 | private: |
1938 | template <class T> friend class TypePropertyCache; |
1939 | |
1940 | /// Set whether this type comes from an AST file. |
1941 | void setFromAST(bool V = true) const { |
1942 | TypeBits.FromAST = V; |
1943 | } |
1944 | |
1945 | protected: |
1946 | friend class ASTContext; |
1947 | |
1948 | Type(TypeClass tc, QualType canon, TypeDependence Dependence) |
1949 | : ExtQualsTypeCommonBase(this, |
1950 | canon.isNull() ? QualType(this_(), 0) : canon) { |
1951 | static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase), |
1952 | "changing bitfields changed sizeof(Type)!"); |
1953 | static_assert(alignof(decltype(*this)) % sizeof(void *) == 0, |
1954 | "Insufficient alignment!"); |
1955 | TypeBits.TC = tc; |
1956 | TypeBits.Dependence = static_cast<unsigned>(Dependence); |
1957 | TypeBits.CacheValid = false; |
1958 | TypeBits.CachedLocalOrUnnamed = false; |
1959 | TypeBits.CachedLinkage = NoLinkage; |
1960 | TypeBits.FromAST = false; |
1961 | } |
1962 | |
1963 | // silence VC++ warning C4355: 'this' : used in base member initializer list |
1964 | Type *this_() { return this; } |
1965 | |
1966 | void setDependence(TypeDependence D) { |
1967 | TypeBits.Dependence = static_cast<unsigned>(D); |
1968 | } |
1969 | |
1970 | void addDependence(TypeDependence D) { setDependence(getDependence() | D); } |
1971 | |
1972 | public: |
1973 | friend class ASTReader; |
1974 | friend class ASTWriter; |
1975 | template <class T> friend class serialization::AbstractTypeReader; |
1976 | template <class T> friend class serialization::AbstractTypeWriter; |
1977 | |
1978 | Type(const Type &) = delete; |
1979 | Type(Type &&) = delete; |
1980 | Type &operator=(const Type &) = delete; |
1981 | Type &operator=(Type &&) = delete; |
1982 | |
1983 | TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } |
1984 | |
1985 | /// Whether this type comes from an AST file. |
1986 | bool isFromAST() const { return TypeBits.FromAST; } |
1987 | |
1988 | /// Whether this type is or contains an unexpanded parameter |
1989 | /// pack, used to support C++0x variadic templates. |
1990 | /// |
1991 | /// A type that contains a parameter pack shall be expanded by the |
1992 | /// ellipsis operator at some point. For example, the typedef in the |
1993 | /// following example contains an unexpanded parameter pack 'T': |
1994 | /// |
1995 | /// \code |
1996 | /// template<typename ...T> |
1997 | /// struct X { |
1998 | /// typedef T* pointer_types; // ill-formed; T is a parameter pack. |
1999 | /// }; |
2000 | /// \endcode |
2001 | /// |
2002 | /// Note that this routine does not specify which |
2003 | bool containsUnexpandedParameterPack() const { |
2004 | return getDependence() & TypeDependence::UnexpandedPack; |
2005 | } |
2006 | |
2007 | /// Determines if this type would be canonical if it had no further |
2008 | /// qualification. |
2009 | bool isCanonicalUnqualified() const { |
2010 | return CanonicalType == QualType(this, 0); |
2011 | } |
2012 | |
2013 | /// Pull a single level of sugar off of this locally-unqualified type. |
2014 | /// Users should generally prefer SplitQualType::getSingleStepDesugaredType() |
2015 | /// or QualType::getSingleStepDesugaredType(const ASTContext&). |
2016 | QualType getLocallyUnqualifiedSingleStepDesugaredType() const; |
2017 | |
2018 | /// As an extension, we classify types as one of "sized" or "sizeless"; |
2019 | /// every type is one or the other. Standard types are all sized; |
2020 | /// sizeless types are purely an extension. |
2021 | /// |
2022 | /// Sizeless types contain data with no specified size, alignment, |
2023 | /// or layout. |
2024 | bool isSizelessType() const; |
2025 | bool isSizelessBuiltinType() const; |
2026 | |
2027 | /// Determines if this is a sizeless type supported by the |
2028 | /// 'arm_sve_vector_bits' type attribute, which can be applied to a single |
2029 | /// SVE vector or predicate, excluding tuple types such as svint32x4_t. |
2030 | bool isVLSTBuiltinType() const; |
2031 | |
2032 | /// Returns the representative type for the element of an SVE builtin type. |
2033 | /// This is used to represent fixed-length SVE vectors created with the |
2034 | /// 'arm_sve_vector_bits' type attribute as VectorType. |
2035 | QualType getSveEltType(const ASTContext &Ctx) const; |
2036 | |
2037 | /// Types are partitioned into 3 broad categories (C99 6.2.5p1): |
2038 | /// object types, function types, and incomplete types. |
2039 | |
2040 | /// Return true if this is an incomplete type. |
2041 | /// A type that can describe objects, but which lacks information needed to |
2042 | /// determine its size (e.g. void, or a fwd declared struct). Clients of this |
2043 | /// routine will need to determine if the size is actually required. |
2044 | /// |
2045 | /// Def If non-null, and the type refers to some kind of declaration |
2046 | /// that can be completed (such as a C struct, C++ class, or Objective-C |
2047 | /// class), will be set to the declaration. |
2048 | bool isIncompleteType(NamedDecl **Def = nullptr) const; |
2049 | |
2050 | /// Return true if this is an incomplete or object |
2051 | /// type, in other words, not a function type. |
2052 | bool isIncompleteOrObjectType() const { |
2053 | return !isFunctionType(); |
2054 | } |
2055 | |
2056 | /// Determine whether this type is an object type. |
2057 | bool isObjectType() const { |
2058 | // C++ [basic.types]p8: |
2059 | // An object type is a (possibly cv-qualified) type that is not a |
2060 | // function type, not a reference type, and not a void type. |
2061 | return !isReferenceType() && !isFunctionType() && !isVoidType(); |
2062 | } |
2063 | |
2064 | /// Return true if this is a literal type |
2065 | /// (C++11 [basic.types]p10) |
2066 | bool isLiteralType(const ASTContext &Ctx) const; |
2067 | |
2068 | /// Determine if this type is a structural type, per C++20 [temp.param]p7. |
2069 | bool isStructuralType() const; |
2070 | |
2071 | /// Test if this type is a standard-layout type. |
2072 | /// (C++0x [basic.type]p9) |
2073 | bool isStandardLayoutType() const; |
2074 | |
2075 | /// Helper methods to distinguish type categories. All type predicates |
2076 | /// operate on the canonical type, ignoring typedefs and qualifiers. |
2077 | |
2078 | /// Returns true if the type is a builtin type. |
2079 | bool isBuiltinType() const; |
2080 | |
2081 | /// Test for a particular builtin type. |
2082 | bool isSpecificBuiltinType(unsigned K) const; |
2083 | |
2084 | /// Test for a type which does not represent an actual type-system type but |
2085 | /// is instead used as a placeholder for various convenient purposes within |
2086 | /// Clang. All such types are BuiltinTypes. |
2087 | bool isPlaceholderType() const; |
2088 | const BuiltinType *getAsPlaceholderType() const; |
2089 | |
2090 | /// Test for a specific placeholder type. |
2091 | bool isSpecificPlaceholderType(unsigned K) const; |
2092 | |
2093 | /// Test for a placeholder type other than Overload; see |
2094 | /// BuiltinType::isNonOverloadPlaceholderType. |
2095 | bool isNonOverloadPlaceholderType() const; |
2096 | |
2097 | /// isIntegerType() does *not* include complex integers (a GCC extension). |
2098 | /// isComplexIntegerType() can be used to test for complex integers. |
2099 | bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) |
2100 | bool isEnumeralType() const; |
2101 | |
2102 | /// Determine whether this type is a scoped enumeration type. |
2103 | bool isScopedEnumeralType() const; |
2104 | bool isBooleanType() const; |
2105 | bool isCharType() const; |
2106 | bool isWideCharType() const; |
2107 | bool isChar8Type() const; |
2108 | bool isChar16Type() const; |
2109 | bool isChar32Type() const; |
2110 | bool isAnyCharacterType() const; |
2111 | bool isIntegralType(const ASTContext &Ctx) const; |
2112 | |
2113 | /// Determine whether this type is an integral or enumeration type. |
2114 | bool isIntegralOrEnumerationType() const; |
2115 | |
2116 | /// Determine whether this type is an integral or unscoped enumeration type. |
2117 | bool isIntegralOrUnscopedEnumerationType() const; |
2118 | bool isUnscopedEnumerationType() const; |
2119 | |
2120 | /// Floating point categories. |
2121 | bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) |
2122 | /// isComplexType() does *not* include complex integers (a GCC extension). |
2123 | /// isComplexIntegerType() can be used to test for complex integers. |
2124 | bool isComplexType() const; // C99 6.2.5p11 (complex) |
2125 | bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. |
2126 | bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) |
2127 | bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) |
2128 | bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 |
2129 | bool isBFloat16Type() const; |
2130 | bool isFloat128Type() const; |
2131 | bool isIbm128Type() const; |
2132 | bool isRealType() const; // C99 6.2.5p17 (real floating + integer) |
2133 | bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) |
2134 | bool isVoidType() const; // C99 6.2.5p19 |
2135 | bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) |
2136 | bool isAggregateType() const; |
2137 | bool isFundamentalType() const; |
2138 | bool isCompoundType() const; |
2139 | |
2140 | // Type Predicates: Check to see if this type is structurally the specified |
2141 | // type, ignoring typedefs and qualifiers. |
2142 | bool isFunctionType() const; |
2143 | bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); } |
2144 | bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } |
2145 | bool isPointerType() const; |
2146 | bool isAnyPointerType() const; // Any C pointer or ObjC object pointer |
2147 | bool isBlockPointerType() const; |
2148 | bool isVoidPointerType() const; |
2149 | bool isReferenceType() const; |
2150 | bool isLValueReferenceType() const; |
2151 | bool isRValueReferenceType() const; |
2152 | bool isObjectPointerType() const; |
2153 | bool isFunctionPointerType() const; |
2154 | bool isFunctionReferenceType() const; |
2155 | bool isMemberPointerType() const; |
2156 | bool isMemberFunctionPointerType() const; |
2157 | bool isMemberDataPointerType() const; |
2158 | bool isArrayType() const; |
2159 | bool isConstantArrayType() const; |
2160 | bool isIncompleteArrayType() const; |
2161 | bool isVariableArrayType() const; |
2162 | bool isDependentSizedArrayType() const; |
2163 | bool isRecordType() const; |
2164 | bool isClassType() const; |
2165 | bool isStructureType() const; |
2166 | bool isObjCBoxableRecordType() const; |
2167 | bool isInterfaceType() const; |
2168 | bool isStructureOrClassType() const; |
2169 | bool isUnionType() const; |
2170 | bool isComplexIntegerType() const; // GCC _Complex integer type. |
2171 | bool isVectorType() const; // GCC vector type. |
2172 | bool isExtVectorType() const; // Extended vector type. |
2173 | bool isExtVectorBoolType() const; // Extended vector type with bool element. |
2174 | bool isMatrixType() const; // Matrix type. |
2175 | bool isConstantMatrixType() const; // Constant matrix type. |
2176 | bool isDependentAddressSpaceType() const; // value-dependent address space qualifier |
2177 | bool isObjCObjectPointerType() const; // pointer to ObjC object |
2178 | bool isObjCRetainableType() const; // ObjC object or block pointer |
2179 | bool isObjCLifetimeType() const; // (array of)* retainable type |
2180 | bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type |
2181 | bool isObjCNSObjectType() const; // __attribute__((NSObject)) |
2182 | bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class)) |
2183 | // FIXME: change this to 'raw' interface type, so we can used 'interface' type |
2184 | // for the common case. |
2185 | bool isObjCObjectType() const; // NSString or typeof(*(id)0) |
2186 | bool isObjCQualifiedInterfaceType() const; // NSString<foo> |
2187 | bool isObjCQualifiedIdType() const; // id<foo> |
2188 | bool isObjCQualifiedClassType() const; // Class<foo> |
2189 | bool isObjCObjectOrInterfaceType() const; |
2190 | bool isObjCIdType() const; // id |
2191 | bool isDecltypeType() const; |
2192 | /// Was this type written with the special inert-in-ARC __unsafe_unretained |
2193 | /// qualifier? |
2194 | /// |
2195 | /// This approximates the answer to the following question: if this |
2196 | /// translation unit were compiled in ARC, would this type be qualified |
2197 | /// with __unsafe_unretained? |
2198 | bool isObjCInertUnsafeUnretainedType() const { |
2199 | return hasAttr(attr::ObjCInertUnsafeUnretained); |
2200 | } |
2201 | |
2202 | /// Whether the type is Objective-C 'id' or a __kindof type of an |
2203 | /// object type, e.g., __kindof NSView * or __kindof id |
2204 | /// <NSCopying>. |
2205 | /// |
2206 | /// \param bound Will be set to the bound on non-id subtype types, |
2207 | /// which will be (possibly specialized) Objective-C class type, or |
2208 | /// null for 'id. |
2209 | bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, |
2210 | const ObjCObjectType *&bound) const; |
2211 | |
2212 | bool isObjCClassType() const; // Class |
2213 | |
2214 | /// Whether the type is Objective-C 'Class' or a __kindof type of an |
2215 | /// Class type, e.g., __kindof Class <NSCopying>. |
2216 | /// |
2217 | /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound |
2218 | /// here because Objective-C's type system cannot express "a class |
2219 | /// object for a subclass of NSFoo". |
2220 | bool isObjCClassOrClassKindOfType() const; |
2221 | |
2222 | bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const; |
2223 | bool isObjCSelType() const; // Class |
2224 | bool isObjCBuiltinType() const; // 'id' or 'Class' |
2225 | bool isObjCARCBridgableType() const; |
2226 | bool isCARCBridgableType() const; |
2227 | bool isTemplateTypeParmType() const; // C++ template type parameter |
2228 | bool isNullPtrType() const; // C++11 std::nullptr_t or |
2229 | // C2x nullptr_t |
2230 | bool isNothrowT() const; // C++ std::nothrow_t |
2231 | bool isAlignValT() const; // C++17 std::align_val_t |
2232 | bool isStdByteType() const; // C++17 std::byte |
2233 | bool isAtomicType() const; // C11 _Atomic() |
2234 | bool isUndeducedAutoType() const; // C++11 auto or |
2235 | // C++14 decltype(auto) |
2236 | bool isTypedefNameType() const; // typedef or alias template |
2237 | |
2238 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ |
2239 | bool is##Id##Type() const; |
2240 | #include "clang/Basic/OpenCLImageTypes.def" |
2241 | |
2242 | bool isImageType() const; // Any OpenCL image type |
2243 | |
2244 | bool isSamplerT() const; // OpenCL sampler_t |
2245 | bool isEventT() const; // OpenCL event_t |
2246 | bool isClkEventT() const; // OpenCL clk_event_t |
2247 | bool isQueueT() const; // OpenCL queue_t |
2248 | bool isReserveIDT() const; // OpenCL reserve_id_t |
2249 | |
2250 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
2251 | bool is##Id##Type() const; |
2252 | #include "clang/Basic/OpenCLExtensionTypes.def" |
2253 | // Type defined in cl_intel_device_side_avc_motion_estimation OpenCL extension |
2254 | bool isOCLIntelSubgroupAVCType() const; |
2255 | bool isOCLExtOpaqueType() const; // Any OpenCL extension type |
2256 | |
2257 | bool isPipeType() const; // OpenCL pipe type |
2258 | bool isBitIntType() const; // Bit-precise integer type |
2259 | bool isOpenCLSpecificType() const; // Any OpenCL specific type |
2260 | |
2261 | /// Determines if this type, which must satisfy |
2262 | /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather |
2263 | /// than implicitly __strong. |
2264 | bool isObjCARCImplicitlyUnretainedType() const; |
2265 | |
2266 | /// Check if the type is the CUDA device builtin surface type. |
2267 | bool isCUDADeviceBuiltinSurfaceType() const; |
2268 | /// Check if the type is the CUDA device builtin texture type. |
2269 | bool isCUDADeviceBuiltinTextureType() const; |
2270 | |
2271 | bool isRVVType() const; |
2272 | |
2273 | /// Return the implicit lifetime for this type, which must not be dependent. |
2274 | Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; |
2275 | |
2276 | enum ScalarTypeKind { |
2277 | STK_CPointer, |
2278 | STK_BlockPointer, |
2279 | STK_ObjCObjectPointer, |
2280 | STK_MemberPointer, |
2281 | STK_Bool, |
2282 | STK_Integral, |
2283 | STK_Floating, |
2284 | STK_IntegralComplex, |
2285 | STK_FloatingComplex, |
2286 | STK_FixedPoint |
2287 | }; |
2288 | |
2289 | /// Given that this is a scalar type, classify it. |
2290 | ScalarTypeKind getScalarTypeKind() const; |
2291 | |
2292 | TypeDependence getDependence() const { |
2293 | return static_cast<TypeDependence>(TypeBits.Dependence); |
2294 | } |
2295 | |
2296 | /// Whether this type is an error type. |
2297 | bool containsErrors() const { |
2298 | return getDependence() & TypeDependence::Error; |
2299 | } |
2300 | |
2301 | /// Whether this type is a dependent type, meaning that its definition |
2302 | /// somehow depends on a template parameter (C++ [temp.dep.type]). |
2303 | bool isDependentType() const { |
2304 | return getDependence() & TypeDependence::Dependent; |
2305 | } |
2306 | |
2307 | /// Determine whether this type is an instantiation-dependent type, |
2308 | /// meaning that the type involves a template parameter (even if the |
2309 | /// definition does not actually depend on the type substituted for that |
2310 | /// template parameter). |
2311 | bool isInstantiationDependentType() const { |
2312 | return getDependence() & TypeDependence::Instantiation; |
2313 | } |
2314 | |
2315 | /// Determine whether this type is an undeduced type, meaning that |
2316 | /// it somehow involves a C++11 'auto' type or similar which has not yet been |
2317 | /// deduced. |
2318 | bool isUndeducedType() const; |
2319 | |
2320 | /// Whether this type is a variably-modified type (C99 6.7.5). |
2321 | bool isVariablyModifiedType() const { |
2322 | return getDependence() & TypeDependence::VariablyModified; |
2323 | } |
2324 | |
2325 | /// Whether this type involves a variable-length array type |
2326 | /// with a definite size. |
2327 | bool hasSizedVLAType() const; |
2328 | |
2329 | /// Whether this type is or contains a local or unnamed type. |
2330 | bool hasUnnamedOrLocalType() const; |
2331 | |
2332 | bool isOverloadableType() const; |
2333 | |
2334 | /// Determine wither this type is a C++ elaborated-type-specifier. |
2335 | bool isElaboratedTypeSpecifier() const; |
2336 | |
2337 | bool canDecayToPointerType() const; |
2338 | |
2339 | /// Whether this type is represented natively as a pointer. This includes |
2340 | /// pointers, references, block pointers, and Objective-C interface, |
2341 | /// qualified id, and qualified interface types, as well as nullptr_t. |
2342 | bool hasPointerRepresentation() const; |
2343 | |
2344 | /// Whether this type can represent an objective pointer type for the |
2345 | /// purpose of GC'ability |
2346 | bool hasObjCPointerRepresentation() const; |
2347 | |
2348 | /// Determine whether this type has an integer representation |
2349 | /// of some sort, e.g., it is an integer type or a vector. |
2350 | bool hasIntegerRepresentation() const; |
2351 | |
2352 | /// Determine whether this type has an signed integer representation |
2353 | /// of some sort, e.g., it is an signed integer type or a vector. |
2354 | bool hasSignedIntegerRepresentation() const; |
2355 | |
2356 | /// Determine whether this type has an unsigned integer representation |
2357 | /// of some sort, e.g., it is an unsigned integer type or a vector. |
2358 | bool hasUnsignedIntegerRepresentation() const; |
2359 | |
2360 | /// Determine whether this type has a floating-point representation |
2361 | /// of some sort, e.g., it is a floating-point type or a vector thereof. |
2362 | bool hasFloatingRepresentation() const; |
2363 | |
2364 | // Type Checking Functions: Check to see if this type is structurally the |
2365 | // specified type, ignoring typedefs and qualifiers, and return a pointer to |
2366 | // the best type we can. |
2367 | const RecordType *getAsStructureType() const; |
2368 | /// NOTE: getAs*ArrayType are methods on ASTContext. |
2369 | const RecordType *getAsUnionType() const; |
2370 | const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. |
2371 | const ObjCObjectType *getAsObjCInterfaceType() const; |
2372 | |
2373 | // The following is a convenience method that returns an ObjCObjectPointerType |
2374 | // for object declared using an interface. |
2375 | const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; |
2376 | const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; |
2377 | const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; |
2378 | const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; |
2379 | |
2380 | /// Retrieves the CXXRecordDecl that this type refers to, either |
2381 | /// because the type is a RecordType or because it is the injected-class-name |
2382 | /// type of a class template or class template partial specialization. |
2383 | CXXRecordDecl *getAsCXXRecordDecl() const; |
2384 | |
2385 | /// Retrieves the RecordDecl this type refers to. |
2386 | RecordDecl *getAsRecordDecl() const; |
2387 | |
2388 | /// Retrieves the TagDecl that this type refers to, either |
2389 | /// because the type is a TagType or because it is the injected-class-name |
2390 | /// type of a class template or class template partial specialization. |
2391 | TagDecl *getAsTagDecl() const; |
2392 | |
2393 | /// If this is a pointer or reference to a RecordType, return the |
2394 | /// CXXRecordDecl that the type refers to. |
2395 | /// |
2396 | /// If this is not a pointer or reference, or the type being pointed to does |
2397 | /// not refer to a CXXRecordDecl, returns NULL. |
2398 | const CXXRecordDecl *getPointeeCXXRecordDecl() const; |
2399 | |
2400 | /// Get the DeducedType whose type will be deduced for a variable with |
2401 | /// an initializer of this type. This looks through declarators like pointer |
2402 | /// types, but not through decltype or typedefs. |
2403 | DeducedType *getContainedDeducedType() const; |
2404 | |
2405 | /// Get the AutoType whose type will be deduced for a variable with |
2406 | /// an initializer of this type. This looks through declarators like pointer |
2407 | /// types, but not through decltype or typedefs. |
2408 | AutoType *getContainedAutoType() const { |
2409 | return dyn_cast_or_null<AutoType>(getContainedDeducedType()); |
2410 | } |
2411 | |
2412 | /// Determine whether this type was written with a leading 'auto' |
2413 | /// corresponding to a trailing return type (possibly for a nested |
2414 | /// function type within a pointer to function type or similar). |
2415 | bool hasAutoForTrailingReturnType() const; |
2416 | |
2417 | /// Member-template getAs<specific type>'. Look through sugar for |
2418 | /// an instance of \<specific type>. This scheme will eventually |
2419 | /// replace the specific getAsXXXX methods above. |
2420 | /// |
2421 | /// There are some specializations of this member template listed |
2422 | /// immediately following this class. |
2423 | template <typename T> const T *getAs() const; |
2424 | |
2425 | /// Member-template getAsAdjusted<specific type>. Look through specific kinds |
2426 | /// of sugar (parens, attributes, etc) for an instance of \<specific type>. |
2427 | /// This is used when you need to walk over sugar nodes that represent some |
2428 | /// kind of type adjustment from a type that was written as a \<specific type> |
2429 | /// to another type that is still canonically a \<specific type>. |
2430 | template <typename T> const T *getAsAdjusted() const; |
2431 | |
2432 | /// A variant of getAs<> for array types which silently discards |
2433 | /// qualifiers from the outermost type. |
2434 | const ArrayType *getAsArrayTypeUnsafe() const; |
2435 | |
2436 | /// Member-template castAs<specific type>. Look through sugar for |
2437 | /// the underlying instance of \<specific type>. |
2438 | /// |
2439 | /// This method has the same relationship to getAs<T> as cast<T> has |
2440 | /// to dyn_cast<T>; which is to say, the underlying type *must* |
2441 | /// have the intended type, and this method will never return null. |
2442 | template <typename T> const T *castAs() const; |
2443 | |
2444 | /// A variant of castAs<> for array type which silently discards |
2445 | /// qualifiers from the outermost type. |
2446 | const ArrayType *castAsArrayTypeUnsafe() const; |
2447 | |
2448 | /// Determine whether this type had the specified attribute applied to it |
2449 | /// (looking through top-level type sugar). |
2450 | bool hasAttr(attr::Kind AK) const; |
2451 | |
2452 | /// Get the base element type of this type, potentially discarding type |
2453 | /// qualifiers. This should never be used when type qualifiers |
2454 | /// are meaningful. |
2455 | const Type *getBaseElementTypeUnsafe() const; |
2456 | |
2457 | /// If this is an array type, return the element type of the array, |
2458 | /// potentially with type qualifiers missing. |
2459 | /// This should never be used when type qualifiers are meaningful. |
2460 | const Type *getArrayElementTypeNoTypeQual() const; |
2461 | |
2462 | /// If this is a pointer type, return the pointee type. |
2463 | /// If this is an array type, return the array element type. |
2464 | /// This should never be used when type qualifiers are meaningful. |
2465 | const Type *getPointeeOrArrayElementType() const; |
2466 | |
2467 | /// If this is a pointer, ObjC object pointer, or block |
2468 | /// pointer, this returns the respective pointee. |
2469 | QualType getPointeeType() const; |
2470 | |
2471 | /// Return the specified type with any "sugar" removed from the type, |
2472 | /// removing any typedefs, typeofs, etc., as well as any qualifiers. |
2473 | const Type *getUnqualifiedDesugaredType() const; |
2474 | |
2475 | /// Return true if this is an integer type that is |
2476 | /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], |
2477 | /// or an enum decl which has a signed representation. |
2478 | bool isSignedIntegerType() const; |
2479 | |
2480 | /// Return true if this is an integer type that is |
2481 | /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], |
2482 | /// or an enum decl which has an unsigned representation. |
2483 | bool isUnsignedIntegerType() const; |
2484 | |
2485 | /// Determines whether this is an integer type that is signed or an |
2486 | /// enumeration types whose underlying type is a signed integer type. |
2487 | bool isSignedIntegerOrEnumerationType() const; |
2488 | |
2489 | /// Determines whether this is an integer type that is unsigned or an |
2490 | /// enumeration types whose underlying type is a unsigned integer type. |
2491 | bool isUnsignedIntegerOrEnumerationType() const; |
2492 | |
2493 | /// Return true if this is a fixed point type according to |
2494 | /// ISO/IEC JTC1 SC22 WG14 N1169. |
2495 | bool isFixedPointType() const; |
2496 | |
2497 | /// Return true if this is a fixed point or integer type. |
2498 | bool isFixedPointOrIntegerType() const; |
2499 | |
2500 | /// Return true if this is a saturated fixed point type according to |
2501 | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. |
2502 | bool isSaturatedFixedPointType() const; |
2503 | |
2504 | /// Return true if this is a saturated fixed point type according to |
2505 | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. |
2506 | bool isUnsaturatedFixedPointType() const; |
2507 | |
2508 | /// Return true if this is a fixed point type that is signed according |
2509 | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. |
2510 | bool isSignedFixedPointType() const; |
2511 | |
2512 | /// Return true if this is a fixed point type that is unsigned according |
2513 | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. |
2514 | bool isUnsignedFixedPointType() const; |
2515 | |
2516 | /// Return true if this is not a variable sized type, |
2517 | /// according to the rules of C99 6.7.5p3. It is not legal to call this on |
2518 | /// incomplete types. |
2519 | bool isConstantSizeType() const; |
2520 | |
2521 | /// Returns true if this type can be represented by some |
2522 | /// set of type specifiers. |
2523 | bool isSpecifierType() const; |
2524 | |
2525 | /// Determine the linkage of this type. |
2526 | Linkage getLinkage() const; |
2527 | |
2528 | /// Determine the visibility of this type. |
2529 | Visibility getVisibility() const { |
2530 | return getLinkageAndVisibility().getVisibility(); |
2531 | } |
2532 | |
2533 | /// Return true if the visibility was explicitly set is the code. |
2534 | bool isVisibilityExplicit() const { |
2535 | return getLinkageAndVisibility().isVisibilityExplicit(); |
2536 | } |
2537 | |
2538 | /// Determine the linkage and visibility of this type. |
2539 | LinkageInfo getLinkageAndVisibility() const; |
2540 | |
2541 | /// True if the computed linkage is valid. Used for consistency |
2542 | /// checking. Should always return true. |
2543 | bool isLinkageValid() const; |
2544 | |
2545 | /// Determine the nullability of the given type. |
2546 | /// |
2547 | /// Note that nullability is only captured as sugar within the type |
2548 | /// system, not as part of the canonical type, so nullability will |
2549 | /// be lost by canonicalization and desugaring. |
2550 | Optional<NullabilityKind> getNullability() const; |
2551 | // TODO: Remove overload. |
2552 | Optional<NullabilityKind> getNullability(const ASTContext &) const; |
2553 | |
2554 | /// Determine whether the given type can have a nullability |
2555 | /// specifier applied to it, i.e., if it is any kind of pointer type. |
2556 | /// |
2557 | /// \param ResultIfUnknown The value to return if we don't yet know whether |
2558 | /// this type can have nullability because it is dependent. |
2559 | bool canHaveNullability(bool ResultIfUnknown = true) const; |
2560 | |
2561 | /// Retrieve the set of substitutions required when accessing a member |
2562 | /// of the Objective-C receiver type that is declared in the given context. |
2563 | /// |
2564 | /// \c *this is the type of the object we're operating on, e.g., the |
2565 | /// receiver for a message send or the base of a property access, and is |
2566 | /// expected to be of some object or object pointer type. |
2567 | /// |
2568 | /// \param dc The declaration context for which we are building up a |
2569 | /// substitution mapping, which should be an Objective-C class, extension, |
2570 | /// category, or method within. |
2571 | /// |
2572 | /// \returns an array of type arguments that can be substituted for |
2573 | /// the type parameters of the given declaration context in any type described |
2574 | /// within that context, or an empty optional to indicate that no |
2575 | /// substitution is required. |
2576 | Optional<ArrayRef<QualType>> |
2577 | getObjCSubstitutions(const DeclContext *dc) const; |
2578 | |
2579 | /// Determines if this is an ObjC interface type that may accept type |
2580 | /// parameters. |
2581 | bool acceptsObjCTypeParams() const; |
2582 | |
2583 | const char *getTypeClassName() const; |
2584 | |
2585 | QualType getCanonicalTypeInternal() const { |
2586 | return CanonicalType; |
2587 | } |
2588 | |
2589 | CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h |
2590 | void dump() const; |
2591 | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; |
2592 | }; |
2593 | |
2594 | /// This will check for a TypedefType by removing any existing sugar |
2595 | /// until it reaches a TypedefType or a non-sugared type. |
2596 | template <> const TypedefType *Type::getAs() const; |
2597 | template <> const UsingType *Type::getAs() const; |
2598 | |
2599 | /// This will check for a TemplateSpecializationType by removing any |
2600 | /// existing sugar until it reaches a TemplateSpecializationType or a |
2601 | /// non-sugared type. |
2602 | template <> const TemplateSpecializationType *Type::getAs() const; |
2603 | |
2604 | /// This will check for an AttributedType by removing any existing sugar |
2605 | /// until it reaches an AttributedType or a non-sugared type. |
2606 | template <> const AttributedType *Type::getAs() const; |
2607 | |
2608 | // We can do canonical leaf types faster, because we don't have to |
2609 | // worry about preserving child type decoration. |
2610 | #define TYPE(Class, Base) |
2611 | #define LEAF_TYPE(Class) \ |
2612 | template <> inline const Class##Type *Type::getAs() const { \ |
2613 | return dyn_cast<Class##Type>(CanonicalType); \ |
2614 | } \ |
2615 | template <> inline const Class##Type *Type::castAs() const { \ |
2616 | return cast<Class##Type>(CanonicalType); \ |
2617 | } |
2618 | #include "clang/AST/TypeNodes.inc" |
2619 | |
2620 | /// This class is used for builtin types like 'int'. Builtin |
2621 | /// types are always canonical and have a literal name field. |
2622 | class BuiltinType : public Type { |
2623 | public: |
2624 | enum Kind { |
2625 | // OpenCL image types |
2626 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id, |
2627 | #include "clang/Basic/OpenCLImageTypes.def" |
2628 | // OpenCL extension types |
2629 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id, |
2630 | #include "clang/Basic/OpenCLExtensionTypes.def" |
2631 | // SVE Types |
2632 | #define SVE_TYPE(Name, Id, SingletonId) Id, |
2633 | #include "clang/Basic/AArch64SVEACLETypes.def" |
2634 | // PPC MMA Types |
2635 | #define PPC_VECTOR_TYPE(Name, Id, Size) Id, |
2636 | #include "clang/Basic/PPCTypes.def" |
2637 | // RVV Types |
2638 | #define RVV_TYPE(Name, Id, SingletonId) Id, |
2639 | #include "clang/Basic/RISCVVTypes.def" |
2640 | // All other builtin types |
2641 | #define BUILTIN_TYPE(Id, SingletonId) Id, |
2642 | #define LAST_BUILTIN_TYPE(Id) LastKind = Id |
2643 | #include "clang/AST/BuiltinTypes.def" |
2644 | }; |
2645 | |
2646 | private: |
2647 | friend class ASTContext; // ASTContext creates these. |
2648 | |
2649 | BuiltinType(Kind K) |
2650 | : Type(Builtin, QualType(), |
2651 | K == Dependent ? TypeDependence::DependentInstantiation |
2652 | : TypeDependence::None) { |
2653 | BuiltinTypeBits.Kind = K; |
2654 | } |
2655 | |
2656 | public: |
2657 | Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } |
2658 | StringRef getName(const PrintingPolicy &Policy) const; |
2659 | |
2660 | const char *getNameAsCString(const PrintingPolicy &Policy) const { |
2661 | // The StringRef is null-terminated. |
2662 | StringRef str = getName(Policy); |
2663 | 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'" , "clang/include/clang/AST/Type.h", 2663, __extension__ __PRETTY_FUNCTION__ )); |
2664 | return str.data(); |
2665 | } |
2666 | |
2667 | bool isSugared() const { return false; } |
2668 | QualType desugar() const { return QualType(this, 0); } |
2669 | |
2670 | bool isInteger() const { |
2671 | return getKind() >= Bool && getKind() <= Int128; |
2672 | } |
2673 | |
2674 | bool isSignedInteger() const { |
2675 | return getKind() >= Char_S && getKind() <= Int128; |
2676 | } |
2677 | |
2678 | bool isUnsignedInteger() const { |
2679 | return getKind() >= Bool && getKind() <= UInt128; |
2680 | } |
2681 | |
2682 | bool isFloatingPoint() const { |
2683 | return getKind() >= Half && getKind() <= Ibm128; |
2684 | } |
2685 | |
2686 | bool isSVEBool() const { return getKind() == Kind::SveBool; } |
2687 | |
2688 | /// Determines whether the given kind corresponds to a placeholder type. |
2689 | static bool isPlaceholderTypeKind(Kind K) { |
2690 | return K >= Overload; |
2691 | } |
2692 | |
2693 | /// Determines whether this type is a placeholder type, i.e. a type |
2694 | /// which cannot appear in arbitrary positions in a fully-formed |
2695 | /// expression. |
2696 | bool isPlaceholderType() const { |
2697 | return isPlaceholderTypeKind(getKind()); |
2698 | } |
2699 | |
2700 | /// Determines whether this type is a placeholder type other than |
2701 | /// Overload. Most placeholder types require only syntactic |
2702 | /// information about their context in order to be resolved (e.g. |
2703 | /// whether it is a call expression), which means they can (and |
2704 | /// should) be resolved in an earlier "phase" of analysis. |
2705 | /// Overload expressions sometimes pick up further information |
2706 | /// from their context, like whether the context expects a |
2707 | /// specific function-pointer type, and so frequently need |
2708 | /// special treatment. |
2709 | bool isNonOverloadPlaceholderType() const { |
2710 | return getKind() > Overload; |
2711 | } |
2712 | |
2713 | static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } |
2714 | }; |
2715 | |
2716 | /// Complex values, per C99 6.2.5p11. This supports the C99 complex |
2717 | /// types (_Complex float etc) as well as the GCC integer complex extensions. |
2718 | class ComplexType : public Type, public llvm::FoldingSetNode { |
2719 | friend class ASTContext; // ASTContext creates these. |
2720 | |
2721 | QualType ElementType; |
2722 | |
2723 | ComplexType(QualType Element, QualType CanonicalPtr) |
2724 | : Type(Complex, CanonicalPtr, Element->getDependence()), |
2725 | ElementType(Element) {} |
2726 | |
2727 | public: |
2728 | QualType getElementType() const { return ElementType; } |
2729 | |
2730 | bool isSugared() const { return false; } |
2731 | QualType desugar() const { return QualType(this, 0); } |
2732 | |
2733 | void Profile(llvm::FoldingSetNodeID &ID) { |
2734 | Profile(ID, getElementType()); |
2735 | } |
2736 | |
2737 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { |
2738 | ID.AddPointer(Element.getAsOpaquePtr()); |
2739 | } |
2740 | |
2741 | static bool classof(const Type *T) { return T->getTypeClass() == Complex; } |
2742 | }; |
2743 | |
2744 | /// Sugar for parentheses used when specifying types. |
2745 | class ParenType : public Type, public llvm::FoldingSetNode { |
2746 | friend class ASTContext; // ASTContext creates these. |
2747 | |
2748 | QualType Inner; |
2749 | |
2750 | ParenType(QualType InnerType, QualType CanonType) |
2751 | : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {} |
2752 | |
2753 | public: |
2754 | QualType getInnerType() const { return Inner; } |
2755 | |
2756 | bool isSugared() const { return true; } |
2757 | QualType desugar() const { return getInnerType(); } |
2758 | |
2759 | void Profile(llvm::FoldingSetNodeID &ID) { |
2760 | Profile(ID, getInnerType()); |
2761 | } |
2762 | |
2763 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { |
2764 | Inner.Profile(ID); |
2765 | } |
2766 | |
2767 | static bool classof(const Type *T) { return T->getTypeClass() == Paren; } |
2768 | }; |
2769 | |
2770 | /// PointerType - C99 6.7.5.1 - Pointer Declarators. |
2771 | class PointerType : public Type, public llvm::FoldingSetNode { |
2772 | friend class ASTContext; // ASTContext creates these. |
2773 | |
2774 | QualType PointeeType; |
2775 | |
2776 | PointerType(QualType Pointee, QualType CanonicalPtr) |
2777 | : Type(Pointer, CanonicalPtr, Pointee->getDependence()), |
2778 | PointeeType(Pointee) {} |
2779 | |
2780 | public: |
2781 | QualType getPointeeType() const { return PointeeType; } |
2782 | |
2783 | bool isSugared() const { return false; } |
2784 | QualType desugar() const { return QualType(this, 0); } |
2785 | |
2786 | void Profile(llvm::FoldingSetNodeID &ID) { |
2787 | Profile(ID, getPointeeType()); |
2788 | } |
2789 | |
2790 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { |
2791 | ID.AddPointer(Pointee.getAsOpaquePtr()); |
2792 | } |
2793 | |
2794 | static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } |
2795 | }; |
2796 | |
2797 | /// Represents a type which was implicitly adjusted by the semantic |
2798 | /// engine for arbitrary reasons. For example, array and function types can |
2799 | /// decay, and function types can have their calling conventions adjusted. |
2800 | class AdjustedType : public Type, public llvm::FoldingSetNode { |
2801 | QualType OriginalTy; |
2802 | QualType AdjustedTy; |
2803 | |
2804 | protected: |
2805 | friend class ASTContext; // ASTContext creates these. |
2806 | |
2807 | AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, |
2808 | QualType CanonicalPtr) |
2809 | : Type(TC, CanonicalPtr, OriginalTy->getDependence()), |
2810 | OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} |
2811 | |
2812 | public: |
2813 | QualType getOriginalType() const { return OriginalTy; } |
2814 | QualType getAdjustedType() const { return AdjustedTy; } |
2815 | |
2816 | bool isSugared() const { return true; } |
2817 | QualType desugar() const { return AdjustedTy; } |
2818 | |
2819 | void Profile(llvm::FoldingSetNodeID &ID) { |
2820 | Profile(ID, OriginalTy, AdjustedTy); |
2821 | } |
2822 | |
2823 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) { |
2824 | ID.AddPointer(Orig.getAsOpaquePtr()); |
2825 | ID.AddPointer(New.getAsOpaquePtr()); |
2826 | } |
2827 | |
2828 | static bool classof(const Type *T) { |
2829 | return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed; |
2830 | } |
2831 | }; |
2832 | |
2833 | /// Represents a pointer type decayed from an array or function type. |
2834 | class DecayedType : public AdjustedType { |
2835 | friend class ASTContext; // ASTContext creates these. |
2836 | |
2837 | inline |
2838 | DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical); |
2839 | |
2840 | public: |
2841 | QualType getDecayedType() const { return getAdjustedType(); } |
2842 | |
2843 | inline QualType getPointeeType() const; |
2844 | |
2845 | static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } |
2846 | }; |
2847 | |
2848 | /// Pointer to a block type. |
2849 | /// This type is to represent types syntactically represented as |
2850 | /// "void (^)(int)", etc. Pointee is required to always be a function type. |
2851 | class BlockPointerType : public Type, public llvm::FoldingSetNode { |
2852 | friend class ASTContext; // ASTContext creates these. |
2853 | |
2854 | // Block is some kind of pointer type |
2855 | QualType PointeeType; |
2856 | |
2857 | BlockPointerType(QualType Pointee, QualType CanonicalCls) |
2858 | : Type(BlockPointer, CanonicalCls, Pointee->getDependence()), |
2859 | PointeeType(Pointee) {} |
2860 | |
2861 | public: |
2862 | // Get the pointee type. Pointee is required to always be a function type. |
2863 | QualType getPointeeType() const { return PointeeType; } |
2864 | |
2865 | bool isSugared() const { return false; } |
2866 | QualType desugar() const { return QualType(this, 0); } |
2867 | |
2868 | void Profile(llvm::FoldingSetNodeID &ID) { |
2869 | Profile(ID, getPointeeType()); |
2870 | } |
2871 | |
2872 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { |
2873 | ID.AddPointer(Pointee.getAsOpaquePtr()); |
2874 | } |
2875 | |
2876 | static bool classof(const Type *T) { |
2877 | return T->getTypeClass() == BlockPointer; |
2878 | } |
2879 | }; |
2880 | |
2881 | /// Base for LValueReferenceType and RValueReferenceType |
2882 | class ReferenceType : public Type, public llvm::FoldingSetNode { |
2883 | QualType PointeeType; |
2884 | |
2885 | protected: |
2886 | ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, |
2887 | bool SpelledAsLValue) |
2888 | : Type(tc, CanonicalRef, Referencee->getDependence()), |
2889 | PointeeType(Referencee) { |
2890 | ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; |
2891 | ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); |
2892 | } |
2893 | |
2894 | public: |
2895 | bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; } |
2896 | bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } |
2897 | |
2898 | QualType getPointeeTypeAsWritten() const { return PointeeType; } |
2899 | |
2900 | QualType getPointeeType() const { |
2901 | // FIXME: this might strip inner qualifiers; okay? |
2902 | const ReferenceType *T = this; |
2903 | while (T->isInnerRef()) |
2904 | T = T->PointeeType->castAs<ReferenceType>(); |
2905 | return T->PointeeType; |
2906 | } |
2907 | |
2908 | void Profile(llvm::FoldingSetNodeID &ID) { |
2909 | Profile(ID, PointeeType, isSpelledAsLValue()); |
2910 | } |
2911 | |
2912 | static void Profile(llvm::FoldingSetNodeID &ID, |
2913 | QualType Referencee, |
2914 | bool SpelledAsLValue) { |
2915 | ID.AddPointer(Referencee.getAsOpaquePtr()); |
2916 | ID.AddBoolean(SpelledAsLValue); |
2917 | } |
2918 | |
2919 | static bool classof(const Type *T) { |
2920 | return T->getTypeClass() == LValueReference || |
2921 | T->getTypeClass() == RValueReference; |
2922 | } |
2923 | }; |
2924 | |
2925 | /// An lvalue reference type, per C++11 [dcl.ref]. |
2926 | class LValueReferenceType : public ReferenceType { |
2927 | friend class ASTContext; // ASTContext creates these |
2928 | |
2929 | LValueReferenceType(QualType Referencee, QualType CanonicalRef, |
2930 | bool SpelledAsLValue) |
2931 | : ReferenceType(LValueReference, Referencee, CanonicalRef, |
2932 | SpelledAsLValue) {} |
2933 | |
2934 | public: |
2935 | bool isSugared() const { return false; } |
2936 | QualType desugar() const { return QualType(this, 0); } |
2937 | |
2938 | static bool classof(const Type *T) { |
2939 | return T->getTypeClass() == LValueReference; |
2940 | } |
2941 | }; |
2942 | |
2943 | /// An rvalue reference type, per C++11 [dcl.ref]. |
2944 | class RValueReferenceType : public ReferenceType { |
2945 | friend class ASTContext; // ASTContext creates these |
2946 | |
2947 | RValueReferenceType(QualType Referencee, QualType CanonicalRef) |
2948 | : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {} |
2949 | |
2950 | public: |
2951 | bool isSugared() const { return false; } |
2952 | QualType desugar() const { return QualType(this, 0); } |
2953 | |
2954 | static bool classof(const Type *T) { |
2955 | return T->getTypeClass() == RValueReference; |
2956 | } |
2957 | }; |
2958 | |
2959 | /// A pointer to member type per C++ 8.3.3 - Pointers to members. |
2960 | /// |
2961 | /// This includes both pointers to data members and pointer to member functions. |
2962 | class MemberPointerType : public Type, public llvm::FoldingSetNode { |
2963 | friend class ASTContext; // ASTContext creates these. |
2964 | |
2965 | QualType PointeeType; |
2966 | |
2967 | /// The class of which the pointee is a member. Must ultimately be a |
2968 | /// RecordType, but could be a typedef or a template parameter too. |
2969 | const Type *Class; |
2970 | |
2971 | MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) |
2972 | : Type(MemberPointer, CanonicalPtr, |
2973 | (Cls->getDependence() & ~TypeDependence::VariablyModified) | |
2974 | Pointee->getDependence()), |
2975 | PointeeType(Pointee), Class(Cls) {} |
2976 | |
2977 | public: |
2978 | QualType getPointeeType() const { return PointeeType; } |
2979 | |
2980 | /// Returns true if the member type (i.e. the pointee type) is a |
2981 | /// function type rather than a data-member type. |
2982 | bool isMemberFunctionPointer() const { |
2983 | return PointeeType->isFunctionProtoType(); |
2984 | } |
2985 | |
2986 | /// Returns true if the member type (i.e. the pointee type) is a |
2987 | /// data type rather than a function type. |
2988 | bool isMemberDataPointer() const { |
2989 | return !PointeeType->isFunctionProtoType(); |
2990 | } |
2991 | |
2992 | const Type *getClass() const { return Class; } |
2993 | CXXRecordDecl *getMostRecentCXXRecordDecl() const; |
2994 | |
2995 | bool isSugared() const { return false; } |
2996 | QualType desugar() const { return QualType(this, 0); } |
2997 | |
2998 | void Profile(llvm::FoldingSetNodeID &ID) { |
2999 | Profile(ID, getPointeeType(), getClass()); |
3000 | } |
3001 | |
3002 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, |
3003 | const Type *Class) { |
3004 | ID.AddPointer(Pointee.getAsOpaquePtr()); |
3005 | ID.AddPointer(Class); |
3006 | } |
3007 | |
3008 | static bool classof(const Type *T) { |
3009 | return T->getTypeClass() == MemberPointer; |
3010 | } |
3011 | }; |
3012 | |
3013 | /// Represents an array type, per C99 6.7.5.2 - Array Declarators. |
3014 |