1 | //===- ExprCXX.h - Classes for representing expressions ---------*- 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 | /// Defines the clang::Expr interface and subclasses for C++ expressions. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CLANG_AST_EXPRCXX_H |
15 | #define LLVM_CLANG_AST_EXPRCXX_H |
16 | |
17 | #include "clang/AST/ASTConcept.h" |
18 | #include "clang/AST/ComputeDependence.h" |
19 | #include "clang/AST/Decl.h" |
20 | #include "clang/AST/DeclBase.h" |
21 | #include "clang/AST/DeclCXX.h" |
22 | #include "clang/AST/DeclTemplate.h" |
23 | #include "clang/AST/DeclarationName.h" |
24 | #include "clang/AST/DependenceFlags.h" |
25 | #include "clang/AST/Expr.h" |
26 | #include "clang/AST/NestedNameSpecifier.h" |
27 | #include "clang/AST/OperationKinds.h" |
28 | #include "clang/AST/Stmt.h" |
29 | #include "clang/AST/StmtCXX.h" |
30 | #include "clang/AST/TemplateBase.h" |
31 | #include "clang/AST/Type.h" |
32 | #include "clang/AST/UnresolvedSet.h" |
33 | #include "clang/Basic/ExceptionSpecificationType.h" |
34 | #include "clang/Basic/ExpressionTraits.h" |
35 | #include "clang/Basic/LLVM.h" |
36 | #include "clang/Basic/Lambda.h" |
37 | #include "clang/Basic/LangOptions.h" |
38 | #include "clang/Basic/OperatorKinds.h" |
39 | #include "clang/Basic/SourceLocation.h" |
40 | #include "clang/Basic/Specifiers.h" |
41 | #include "clang/Basic/TypeTraits.h" |
42 | #include "llvm/ADT/ArrayRef.h" |
43 | #include "llvm/ADT/PointerUnion.h" |
44 | #include "llvm/ADT/StringRef.h" |
45 | #include "llvm/ADT/iterator_range.h" |
46 | #include "llvm/Support/Casting.h" |
47 | #include "llvm/Support/Compiler.h" |
48 | #include "llvm/Support/TrailingObjects.h" |
49 | #include <cassert> |
50 | #include <cstddef> |
51 | #include <cstdint> |
52 | #include <memory> |
53 | #include <optional> |
54 | |
55 | namespace clang { |
56 | |
57 | class ASTContext; |
58 | class DeclAccessPair; |
59 | class IdentifierInfo; |
60 | class LambdaCapture; |
61 | class NonTypeTemplateParmDecl; |
62 | class TemplateParameterList; |
63 | |
64 | //===--------------------------------------------------------------------===// |
65 | // C++ Expressions. |
66 | //===--------------------------------------------------------------------===// |
67 | |
68 | /// A call to an overloaded operator written using operator |
69 | /// syntax. |
70 | /// |
71 | /// Represents a call to an overloaded operator written using operator |
72 | /// syntax, e.g., "x + y" or "*p". While semantically equivalent to a |
73 | /// normal call, this AST node provides better information about the |
74 | /// syntactic representation of the call. |
75 | /// |
76 | /// In a C++ template, this expression node kind will be used whenever |
77 | /// any of the arguments are type-dependent. In this case, the |
78 | /// function itself will be a (possibly empty) set of functions and |
79 | /// function templates that were found by name lookup at template |
80 | /// definition time. |
81 | class CXXOperatorCallExpr final : public CallExpr { |
82 | friend class ASTStmtReader; |
83 | friend class ASTStmtWriter; |
84 | |
85 | SourceRange Range; |
86 | |
87 | // CXXOperatorCallExpr has some trailing objects belonging |
88 | // to CallExpr. See CallExpr for the details. |
89 | |
90 | SourceRange getSourceRangeImpl() const LLVM_READONLY; |
91 | |
92 | CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn, |
93 | ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK, |
94 | SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, |
95 | ADLCallKind UsesADL); |
96 | |
97 | CXXOperatorCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty); |
98 | |
99 | public: |
100 | static CXXOperatorCallExpr * |
101 | Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, |
102 | ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK, |
103 | SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, |
104 | ADLCallKind UsesADL = NotADL); |
105 | |
106 | static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx, |
107 | unsigned NumArgs, bool HasFPFeatures, |
108 | EmptyShell Empty); |
109 | |
110 | /// Returns the kind of overloaded operator that this expression refers to. |
111 | OverloadedOperatorKind getOperator() const { |
112 | return static_cast<OverloadedOperatorKind>( |
113 | CXXOperatorCallExprBits.OperatorKind); |
114 | } |
115 | |
116 | static bool isAssignmentOp(OverloadedOperatorKind Opc) { |
117 | return Opc == OO_Equal || Opc == OO_StarEqual || Opc == OO_SlashEqual || |
118 | Opc == OO_PercentEqual || Opc == OO_PlusEqual || |
119 | Opc == OO_MinusEqual || Opc == OO_LessLessEqual || |
120 | Opc == OO_GreaterGreaterEqual || Opc == OO_AmpEqual || |
121 | Opc == OO_CaretEqual || Opc == OO_PipeEqual; |
122 | } |
123 | bool isAssignmentOp() const { return isAssignmentOp(Opc: getOperator()); } |
124 | |
125 | static bool isComparisonOp(OverloadedOperatorKind Opc) { |
126 | switch (Opc) { |
127 | case OO_EqualEqual: |
128 | case OO_ExclaimEqual: |
129 | case OO_Greater: |
130 | case OO_GreaterEqual: |
131 | case OO_Less: |
132 | case OO_LessEqual: |
133 | case OO_Spaceship: |
134 | return true; |
135 | default: |
136 | return false; |
137 | } |
138 | } |
139 | bool isComparisonOp() const { return isComparisonOp(Opc: getOperator()); } |
140 | |
141 | /// Is this written as an infix binary operator? |
142 | bool isInfixBinaryOp() const; |
143 | |
144 | /// Returns the location of the operator symbol in the expression. |
145 | /// |
146 | /// When \c getOperator()==OO_Call, this is the location of the right |
147 | /// parentheses; when \c getOperator()==OO_Subscript, this is the location |
148 | /// of the right bracket. |
149 | SourceLocation getOperatorLoc() const { return getRParenLoc(); } |
150 | |
151 | SourceLocation getExprLoc() const LLVM_READONLY { |
152 | OverloadedOperatorKind Operator = getOperator(); |
153 | return (Operator < OO_Plus || Operator >= OO_Arrow || |
154 | Operator == OO_PlusPlus || Operator == OO_MinusMinus) |
155 | ? getBeginLoc() |
156 | : getOperatorLoc(); |
157 | } |
158 | |
159 | SourceLocation getBeginLoc() const { return Range.getBegin(); } |
160 | SourceLocation getEndLoc() const { return Range.getEnd(); } |
161 | SourceRange getSourceRange() const { return Range; } |
162 | |
163 | static bool classof(const Stmt *T) { |
164 | return T->getStmtClass() == CXXOperatorCallExprClass; |
165 | } |
166 | }; |
167 | |
168 | /// Represents a call to a member function that |
169 | /// may be written either with member call syntax (e.g., "obj.func()" |
170 | /// or "objptr->func()") or with normal function-call syntax |
171 | /// ("func()") within a member function that ends up calling a member |
172 | /// function. The callee in either case is a MemberExpr that contains |
173 | /// both the object argument and the member function, while the |
174 | /// arguments are the arguments within the parentheses (not including |
175 | /// the object argument). |
176 | class CXXMemberCallExpr final : public CallExpr { |
177 | // CXXMemberCallExpr has some trailing objects belonging |
178 | // to CallExpr. See CallExpr for the details. |
179 | |
180 | CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty, |
181 | ExprValueKind VK, SourceLocation RP, |
182 | FPOptionsOverride FPOptions, unsigned MinNumArgs); |
183 | |
184 | CXXMemberCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty); |
185 | |
186 | public: |
187 | static CXXMemberCallExpr *Create(const ASTContext &Ctx, Expr *Fn, |
188 | ArrayRef<Expr *> Args, QualType Ty, |
189 | ExprValueKind VK, SourceLocation RP, |
190 | FPOptionsOverride FPFeatures, |
191 | unsigned MinNumArgs = 0); |
192 | |
193 | static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs, |
194 | bool HasFPFeatures, EmptyShell Empty); |
195 | |
196 | /// Retrieve the implicit object argument for the member call. |
197 | /// |
198 | /// For example, in "x.f(5)", this returns the sub-expression "x". |
199 | Expr *getImplicitObjectArgument() const; |
200 | |
201 | /// Retrieve the type of the object argument. |
202 | /// |
203 | /// Note that this always returns a non-pointer type. |
204 | QualType getObjectType() const; |
205 | |
206 | /// Retrieve the declaration of the called method. |
207 | CXXMethodDecl *getMethodDecl() const; |
208 | |
209 | /// Retrieve the CXXRecordDecl for the underlying type of |
210 | /// the implicit object argument. |
211 | /// |
212 | /// Note that this is may not be the same declaration as that of the class |
213 | /// context of the CXXMethodDecl which this function is calling. |
214 | /// FIXME: Returns 0 for member pointer call exprs. |
215 | CXXRecordDecl *getRecordDecl() const; |
216 | |
217 | SourceLocation getExprLoc() const LLVM_READONLY { |
218 | SourceLocation CLoc = getCallee()->getExprLoc(); |
219 | if (CLoc.isValid()) |
220 | return CLoc; |
221 | |
222 | return getBeginLoc(); |
223 | } |
224 | |
225 | static bool classof(const Stmt *T) { |
226 | return T->getStmtClass() == CXXMemberCallExprClass; |
227 | } |
228 | }; |
229 | |
230 | /// Represents a call to a CUDA kernel function. |
231 | class CUDAKernelCallExpr final : public CallExpr { |
232 | friend class ASTStmtReader; |
233 | |
234 | enum { CONFIG, END_PREARG }; |
235 | |
236 | // CUDAKernelCallExpr has some trailing objects belonging |
237 | // to CallExpr. See CallExpr for the details. |
238 | |
239 | CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef<Expr *> Args, |
240 | QualType Ty, ExprValueKind VK, SourceLocation RP, |
241 | FPOptionsOverride FPFeatures, unsigned MinNumArgs); |
242 | |
243 | CUDAKernelCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty); |
244 | |
245 | public: |
246 | static CUDAKernelCallExpr *Create(const ASTContext &Ctx, Expr *Fn, |
247 | CallExpr *Config, ArrayRef<Expr *> Args, |
248 | QualType Ty, ExprValueKind VK, |
249 | SourceLocation RP, |
250 | FPOptionsOverride FPFeatures, |
251 | unsigned MinNumArgs = 0); |
252 | |
253 | static CUDAKernelCallExpr *CreateEmpty(const ASTContext &Ctx, |
254 | unsigned NumArgs, bool HasFPFeatures, |
255 | EmptyShell Empty); |
256 | |
257 | const CallExpr *getConfig() const { |
258 | return cast_or_null<CallExpr>(getPreArg(CONFIG)); |
259 | } |
260 | CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); } |
261 | |
262 | static bool classof(const Stmt *T) { |
263 | return T->getStmtClass() == CUDAKernelCallExprClass; |
264 | } |
265 | }; |
266 | |
267 | /// A rewritten comparison expression that was originally written using |
268 | /// operator syntax. |
269 | /// |
270 | /// In C++20, the following rewrites are performed: |
271 | /// - <tt>a == b</tt> -> <tt>b == a</tt> |
272 | /// - <tt>a != b</tt> -> <tt>!(a == b)</tt> |
273 | /// - <tt>a != b</tt> -> <tt>!(b == a)</tt> |
274 | /// - For \c \@ in \c <, \c <=, \c >, \c >=, \c <=>: |
275 | /// - <tt>a @ b</tt> -> <tt>(a <=> b) @ 0</tt> |
276 | /// - <tt>a @ b</tt> -> <tt>0 @ (b <=> a)</tt> |
277 | /// |
278 | /// This expression provides access to both the original syntax and the |
279 | /// rewritten expression. |
280 | /// |
281 | /// Note that the rewritten calls to \c ==, \c <=>, and \c \@ are typically |
282 | /// \c CXXOperatorCallExprs, but could theoretically be \c BinaryOperators. |
283 | class CXXRewrittenBinaryOperator : public Expr { |
284 | friend class ASTStmtReader; |
285 | |
286 | /// The rewritten semantic form. |
287 | Stmt *SemanticForm; |
288 | |
289 | public: |
290 | CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed) |
291 | : Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(), |
292 | SemanticForm->getValueKind(), SemanticForm->getObjectKind()), |
293 | SemanticForm(SemanticForm) { |
294 | CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed; |
295 | setDependence(computeDependence(E: this)); |
296 | } |
297 | CXXRewrittenBinaryOperator(EmptyShell Empty) |
298 | : Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {} |
299 | |
300 | /// Get an equivalent semantic form for this expression. |
301 | Expr *getSemanticForm() { return cast<Expr>(Val: SemanticForm); } |
302 | const Expr *getSemanticForm() const { return cast<Expr>(Val: SemanticForm); } |
303 | |
304 | struct DecomposedForm { |
305 | /// The original opcode, prior to rewriting. |
306 | BinaryOperatorKind Opcode; |
307 | /// The original left-hand side. |
308 | const Expr *LHS; |
309 | /// The original right-hand side. |
310 | const Expr *RHS; |
311 | /// The inner \c == or \c <=> operator expression. |
312 | const Expr *InnerBinOp; |
313 | }; |
314 | |
315 | /// Decompose this operator into its syntactic form. |
316 | DecomposedForm getDecomposedForm() const LLVM_READONLY; |
317 | |
318 | /// Determine whether this expression was rewritten in reverse form. |
319 | bool isReversed() const { return CXXRewrittenBinaryOperatorBits.IsReversed; } |
320 | |
321 | BinaryOperatorKind getOperator() const { return getDecomposedForm().Opcode; } |
322 | BinaryOperatorKind getOpcode() const { return getOperator(); } |
323 | static StringRef getOpcodeStr(BinaryOperatorKind Op) { |
324 | return BinaryOperator::getOpcodeStr(Op); |
325 | } |
326 | StringRef getOpcodeStr() const { |
327 | return BinaryOperator::getOpcodeStr(Op: getOpcode()); |
328 | } |
329 | bool isComparisonOp() const { return true; } |
330 | bool isAssignmentOp() const { return false; } |
331 | |
332 | const Expr *getLHS() const { return getDecomposedForm().LHS; } |
333 | const Expr *getRHS() const { return getDecomposedForm().RHS; } |
334 | |
335 | SourceLocation getOperatorLoc() const LLVM_READONLY { |
336 | return getDecomposedForm().InnerBinOp->getExprLoc(); |
337 | } |
338 | SourceLocation getExprLoc() const LLVM_READONLY { return getOperatorLoc(); } |
339 | |
340 | /// Compute the begin and end locations from the decomposed form. |
341 | /// The locations of the semantic form are not reliable if this is |
342 | /// a reversed expression. |
343 | //@{ |
344 | SourceLocation getBeginLoc() const LLVM_READONLY { |
345 | return getDecomposedForm().LHS->getBeginLoc(); |
346 | } |
347 | SourceLocation getEndLoc() const LLVM_READONLY { |
348 | return getDecomposedForm().RHS->getEndLoc(); |
349 | } |
350 | SourceRange getSourceRange() const LLVM_READONLY { |
351 | DecomposedForm DF = getDecomposedForm(); |
352 | return SourceRange(DF.LHS->getBeginLoc(), DF.RHS->getEndLoc()); |
353 | } |
354 | //@} |
355 | |
356 | child_range children() { |
357 | return child_range(&SemanticForm, &SemanticForm + 1); |
358 | } |
359 | |
360 | static bool classof(const Stmt *T) { |
361 | return T->getStmtClass() == CXXRewrittenBinaryOperatorClass; |
362 | } |
363 | }; |
364 | |
365 | /// Abstract class common to all of the C++ "named"/"keyword" casts. |
366 | /// |
367 | /// This abstract class is inherited by all of the classes |
368 | /// representing "named" casts: CXXStaticCastExpr for \c static_cast, |
369 | /// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for |
370 | /// reinterpret_cast, CXXConstCastExpr for \c const_cast and |
371 | /// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL). |
372 | class CXXNamedCastExpr : public ExplicitCastExpr { |
373 | private: |
374 | // the location of the casting op |
375 | SourceLocation Loc; |
376 | |
377 | // the location of the right parenthesis |
378 | SourceLocation RParenLoc; |
379 | |
380 | // range for '<' '>' |
381 | SourceRange AngleBrackets; |
382 | |
383 | protected: |
384 | friend class ASTStmtReader; |
385 | |
386 | CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, CastKind kind, |
387 | Expr *op, unsigned PathSize, bool HasFPFeatures, |
388 | TypeSourceInfo *writtenTy, SourceLocation l, |
389 | SourceLocation RParenLoc, SourceRange AngleBrackets) |
390 | : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, HasFPFeatures, |
391 | writtenTy), |
392 | Loc(l), RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {} |
393 | |
394 | explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize, |
395 | bool HasFPFeatures) |
396 | : ExplicitCastExpr(SC, Shell, PathSize, HasFPFeatures) {} |
397 | |
398 | public: |
399 | const char *getCastName() const; |
400 | |
401 | /// Retrieve the location of the cast operator keyword, e.g., |
402 | /// \c static_cast. |
403 | SourceLocation getOperatorLoc() const { return Loc; } |
404 | |
405 | /// Retrieve the location of the closing parenthesis. |
406 | SourceLocation getRParenLoc() const { return RParenLoc; } |
407 | |
408 | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
409 | SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } |
410 | SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; } |
411 | |
412 | static bool classof(const Stmt *T) { |
413 | switch (T->getStmtClass()) { |
414 | case CXXStaticCastExprClass: |
415 | case CXXDynamicCastExprClass: |
416 | case CXXReinterpretCastExprClass: |
417 | case CXXConstCastExprClass: |
418 | case CXXAddrspaceCastExprClass: |
419 | return true; |
420 | default: |
421 | return false; |
422 | } |
423 | } |
424 | }; |
425 | |
426 | /// A C++ \c static_cast expression (C++ [expr.static.cast]). |
427 | /// |
428 | /// This expression node represents a C++ static cast, e.g., |
429 | /// \c static_cast<int>(1.0). |
430 | class CXXStaticCastExpr final |
431 | : public CXXNamedCastExpr, |
432 | private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *, |
433 | FPOptionsOverride> { |
434 | CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, |
435 | unsigned pathSize, TypeSourceInfo *writtenTy, |
436 | FPOptionsOverride FPO, SourceLocation l, |
437 | SourceLocation RParenLoc, SourceRange AngleBrackets) |
438 | : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize, |
439 | FPO.requiresTrailingStorage(), writtenTy, l, RParenLoc, |
440 | AngleBrackets) { |
441 | if (hasStoredFPFeatures()) |
442 | *getTrailingFPFeatures() = FPO; |
443 | } |
444 | |
445 | explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize, |
446 | bool HasFPFeatures) |
447 | : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize, |
448 | HasFPFeatures) {} |
449 | |
450 | unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const { |
451 | return path_size(); |
452 | } |
453 | |
454 | public: |
455 | friend class CastExpr; |
456 | friend TrailingObjects; |
457 | |
458 | static CXXStaticCastExpr * |
459 | Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, |
460 | Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, |
461 | FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc, |
462 | SourceRange AngleBrackets); |
463 | static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context, |
464 | unsigned PathSize, bool hasFPFeatures); |
465 | |
466 | static bool classof(const Stmt *T) { |
467 | return T->getStmtClass() == CXXStaticCastExprClass; |
468 | } |
469 | }; |
470 | |
471 | /// A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]). |
472 | /// |
473 | /// This expression node represents a dynamic cast, e.g., |
474 | /// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time |
475 | /// check to determine how to perform the type conversion. |
476 | class CXXDynamicCastExpr final |
477 | : public CXXNamedCastExpr, |
478 | private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> { |
479 | CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op, |
480 | unsigned pathSize, TypeSourceInfo *writtenTy, |
481 | SourceLocation l, SourceLocation RParenLoc, |
482 | SourceRange AngleBrackets) |
483 | : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize, |
484 | /*HasFPFeatures*/ false, writtenTy, l, RParenLoc, |
485 | AngleBrackets) {} |
486 | |
487 | explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize) |
488 | : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize, |
489 | /*HasFPFeatures*/ false) {} |
490 | |
491 | public: |
492 | friend class CastExpr; |
493 | friend TrailingObjects; |
494 | |
495 | static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T, |
496 | ExprValueKind VK, CastKind Kind, Expr *Op, |
497 | const CXXCastPath *Path, |
498 | TypeSourceInfo *Written, SourceLocation L, |
499 | SourceLocation RParenLoc, |
500 | SourceRange AngleBrackets); |
501 | |
502 | static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context, |
503 | unsigned pathSize); |
504 | |
505 | bool isAlwaysNull() const; |
506 | |
507 | static bool classof(const Stmt *T) { |
508 | return T->getStmtClass() == CXXDynamicCastExprClass; |
509 | } |
510 | }; |
511 | |
512 | /// A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]). |
513 | /// |
514 | /// This expression node represents a reinterpret cast, e.g., |
515 | /// @c reinterpret_cast<int>(VoidPtr). |
516 | /// |
517 | /// A reinterpret_cast provides a differently-typed view of a value but |
518 | /// (in Clang, as in most C++ implementations) performs no actual work at |
519 | /// run time. |
520 | class CXXReinterpretCastExpr final |
521 | : public CXXNamedCastExpr, |
522 | private llvm::TrailingObjects<CXXReinterpretCastExpr, |
523 | CXXBaseSpecifier *> { |
524 | CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, |
525 | unsigned pathSize, TypeSourceInfo *writtenTy, |
526 | SourceLocation l, SourceLocation RParenLoc, |
527 | SourceRange AngleBrackets) |
528 | : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op, |
529 | pathSize, /*HasFPFeatures*/ false, writtenTy, l, |
530 | RParenLoc, AngleBrackets) {} |
531 | |
532 | CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize) |
533 | : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize, |
534 | /*HasFPFeatures*/ false) {} |
535 | |
536 | public: |
537 | friend class CastExpr; |
538 | friend TrailingObjects; |
539 | |
540 | static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T, |
541 | ExprValueKind VK, CastKind Kind, |
542 | Expr *Op, const CXXCastPath *Path, |
543 | TypeSourceInfo *WrittenTy, SourceLocation L, |
544 | SourceLocation RParenLoc, |
545 | SourceRange AngleBrackets); |
546 | static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context, |
547 | unsigned pathSize); |
548 | |
549 | static bool classof(const Stmt *T) { |
550 | return T->getStmtClass() == CXXReinterpretCastExprClass; |
551 | } |
552 | }; |
553 | |
554 | /// A C++ \c const_cast expression (C++ [expr.const.cast]). |
555 | /// |
556 | /// This expression node represents a const cast, e.g., |
557 | /// \c const_cast<char*>(PtrToConstChar). |
558 | /// |
559 | /// A const_cast can remove type qualifiers but does not change the underlying |
560 | /// value. |
561 | class CXXConstCastExpr final |
562 | : public CXXNamedCastExpr, |
563 | private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> { |
564 | CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, |
565 | TypeSourceInfo *writtenTy, SourceLocation l, |
566 | SourceLocation RParenLoc, SourceRange AngleBrackets) |
567 | : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, 0, |
568 | /*HasFPFeatures*/ false, writtenTy, l, RParenLoc, |
569 | AngleBrackets) {} |
570 | |
571 | explicit CXXConstCastExpr(EmptyShell Empty) |
572 | : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0, |
573 | /*HasFPFeatures*/ false) {} |
574 | |
575 | public: |
576 | friend class CastExpr; |
577 | friend TrailingObjects; |
578 | |
579 | static CXXConstCastExpr *Create(const ASTContext &Context, QualType T, |
580 | ExprValueKind VK, Expr *Op, |
581 | TypeSourceInfo *WrittenTy, SourceLocation L, |
582 | SourceLocation RParenLoc, |
583 | SourceRange AngleBrackets); |
584 | static CXXConstCastExpr *CreateEmpty(const ASTContext &Context); |
585 | |
586 | static bool classof(const Stmt *T) { |
587 | return T->getStmtClass() == CXXConstCastExprClass; |
588 | } |
589 | }; |
590 | |
591 | /// A C++ addrspace_cast expression (currently only enabled for OpenCL). |
592 | /// |
593 | /// This expression node represents a cast between pointers to objects in |
594 | /// different address spaces e.g., |
595 | /// \c addrspace_cast<global int*>(PtrToGenericInt). |
596 | /// |
597 | /// A addrspace_cast can cast address space type qualifiers but does not change |
598 | /// the underlying value. |
599 | class CXXAddrspaceCastExpr final |
600 | : public CXXNamedCastExpr, |
601 | private llvm::TrailingObjects<CXXAddrspaceCastExpr, CXXBaseSpecifier *> { |
602 | CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op, |
603 | TypeSourceInfo *writtenTy, SourceLocation l, |
604 | SourceLocation RParenLoc, SourceRange AngleBrackets) |
605 | : CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0, |
606 | /*HasFPFeatures*/ false, writtenTy, l, RParenLoc, |
607 | AngleBrackets) {} |
608 | |
609 | explicit CXXAddrspaceCastExpr(EmptyShell Empty) |
610 | : CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0, |
611 | /*HasFPFeatures*/ false) {} |
612 | |
613 | public: |
614 | friend class CastExpr; |
615 | friend TrailingObjects; |
616 | |
617 | static CXXAddrspaceCastExpr * |
618 | Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, |
619 | Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, |
620 | SourceLocation RParenLoc, SourceRange AngleBrackets); |
621 | static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context); |
622 | |
623 | static bool classof(const Stmt *T) { |
624 | return T->getStmtClass() == CXXAddrspaceCastExprClass; |
625 | } |
626 | }; |
627 | |
628 | /// A call to a literal operator (C++11 [over.literal]) |
629 | /// written as a user-defined literal (C++11 [lit.ext]). |
630 | /// |
631 | /// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this |
632 | /// is semantically equivalent to a normal call, this AST node provides better |
633 | /// information about the syntactic representation of the literal. |
634 | /// |
635 | /// Since literal operators are never found by ADL and can only be declared at |
636 | /// namespace scope, a user-defined literal is never dependent. |
637 | class UserDefinedLiteral final : public CallExpr { |
638 | friend class ASTStmtReader; |
639 | friend class ASTStmtWriter; |
640 | |
641 | /// The location of a ud-suffix within the literal. |
642 | SourceLocation UDSuffixLoc; |
643 | |
644 | // UserDefinedLiteral has some trailing objects belonging |
645 | // to CallExpr. See CallExpr for the details. |
646 | |
647 | UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty, |
648 | ExprValueKind VK, SourceLocation LitEndLoc, |
649 | SourceLocation SuffixLoc, FPOptionsOverride FPFeatures); |
650 | |
651 | UserDefinedLiteral(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty); |
652 | |
653 | public: |
654 | static UserDefinedLiteral *Create(const ASTContext &Ctx, Expr *Fn, |
655 | ArrayRef<Expr *> Args, QualType Ty, |
656 | ExprValueKind VK, SourceLocation LitEndLoc, |
657 | SourceLocation SuffixLoc, |
658 | FPOptionsOverride FPFeatures); |
659 | |
660 | static UserDefinedLiteral *CreateEmpty(const ASTContext &Ctx, |
661 | unsigned NumArgs, bool HasFPOptions, |
662 | EmptyShell Empty); |
663 | |
664 | /// The kind of literal operator which is invoked. |
665 | enum LiteralOperatorKind { |
666 | /// Raw form: operator "" X (const char *) |
667 | LOK_Raw, |
668 | |
669 | /// Raw form: operator "" X<cs...> () |
670 | LOK_Template, |
671 | |
672 | /// operator "" X (unsigned long long) |
673 | LOK_Integer, |
674 | |
675 | /// operator "" X (long double) |
676 | LOK_Floating, |
677 | |
678 | /// operator "" X (const CharT *, size_t) |
679 | LOK_String, |
680 | |
681 | /// operator "" X (CharT) |
682 | LOK_Character |
683 | }; |
684 | |
685 | /// Returns the kind of literal operator invocation |
686 | /// which this expression represents. |
687 | LiteralOperatorKind getLiteralOperatorKind() const; |
688 | |
689 | /// If this is not a raw user-defined literal, get the |
690 | /// underlying cooked literal (representing the literal with the suffix |
691 | /// removed). |
692 | Expr *getCookedLiteral(); |
693 | const Expr *getCookedLiteral() const { |
694 | return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral(); |
695 | } |
696 | |
697 | SourceLocation getBeginLoc() const { |
698 | if (getLiteralOperatorKind() == LOK_Template) |
699 | return getRParenLoc(); |
700 | return getArg(0)->getBeginLoc(); |
701 | } |
702 | |
703 | SourceLocation getEndLoc() const { return getRParenLoc(); } |
704 | |
705 | /// Returns the location of a ud-suffix in the expression. |
706 | /// |
707 | /// For a string literal, there may be multiple identical suffixes. This |
708 | /// returns the first. |
709 | SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; } |
710 | |
711 | /// Returns the ud-suffix specified for this literal. |
712 | const IdentifierInfo *getUDSuffix() const; |
713 | |
714 | static bool classof(const Stmt *S) { |
715 | return S->getStmtClass() == UserDefinedLiteralClass; |
716 | } |
717 | }; |
718 | |
719 | /// A boolean literal, per ([C++ lex.bool] Boolean literals). |
720 | class CXXBoolLiteralExpr : public Expr { |
721 | public: |
722 | CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc) |
723 | : Expr(CXXBoolLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) { |
724 | CXXBoolLiteralExprBits.Value = Val; |
725 | CXXBoolLiteralExprBits.Loc = Loc; |
726 | setDependence(ExprDependence::None); |
727 | } |
728 | |
729 | explicit CXXBoolLiteralExpr(EmptyShell Empty) |
730 | : Expr(CXXBoolLiteralExprClass, Empty) {} |
731 | |
732 | static CXXBoolLiteralExpr *Create(const ASTContext &C, bool Val, QualType Ty, |
733 | SourceLocation Loc) { |
734 | return new (C) CXXBoolLiteralExpr(Val, Ty, Loc); |
735 | } |
736 | |
737 | bool getValue() const { return CXXBoolLiteralExprBits.Value; } |
738 | void setValue(bool V) { CXXBoolLiteralExprBits.Value = V; } |
739 | |
740 | SourceLocation getBeginLoc() const { return getLocation(); } |
741 | SourceLocation getEndLoc() const { return getLocation(); } |
742 | |
743 | SourceLocation getLocation() const { return CXXBoolLiteralExprBits.Loc; } |
744 | void setLocation(SourceLocation L) { CXXBoolLiteralExprBits.Loc = L; } |
745 | |
746 | static bool classof(const Stmt *T) { |
747 | return T->getStmtClass() == CXXBoolLiteralExprClass; |
748 | } |
749 | |
750 | // Iterators |
751 | child_range children() { |
752 | return child_range(child_iterator(), child_iterator()); |
753 | } |
754 | |
755 | const_child_range children() const { |
756 | return const_child_range(const_child_iterator(), const_child_iterator()); |
757 | } |
758 | }; |
759 | |
760 | /// The null pointer literal (C++11 [lex.nullptr]) |
761 | /// |
762 | /// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr. |
763 | /// This also implements the null pointer literal in C23 (C23 6.4.1) which is |
764 | /// intended to have the same semantics as the feature in C++. |
765 | class CXXNullPtrLiteralExpr : public Expr { |
766 | public: |
767 | CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc) |
768 | : Expr(CXXNullPtrLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) { |
769 | CXXNullPtrLiteralExprBits.Loc = Loc; |
770 | setDependence(ExprDependence::None); |
771 | } |
772 | |
773 | explicit CXXNullPtrLiteralExpr(EmptyShell Empty) |
774 | : Expr(CXXNullPtrLiteralExprClass, Empty) {} |
775 | |
776 | SourceLocation getBeginLoc() const { return getLocation(); } |
777 | SourceLocation getEndLoc() const { return getLocation(); } |
778 | |
779 | SourceLocation getLocation() const { return CXXNullPtrLiteralExprBits.Loc; } |
780 | void setLocation(SourceLocation L) { CXXNullPtrLiteralExprBits.Loc = L; } |
781 | |
782 | static bool classof(const Stmt *T) { |
783 | return T->getStmtClass() == CXXNullPtrLiteralExprClass; |
784 | } |
785 | |
786 | child_range children() { |
787 | return child_range(child_iterator(), child_iterator()); |
788 | } |
789 | |
790 | const_child_range children() const { |
791 | return const_child_range(const_child_iterator(), const_child_iterator()); |
792 | } |
793 | }; |
794 | |
795 | /// Implicit construction of a std::initializer_list<T> object from an |
796 | /// array temporary within list-initialization (C++11 [dcl.init.list]p5). |
797 | class CXXStdInitializerListExpr : public Expr { |
798 | Stmt *SubExpr = nullptr; |
799 | |
800 | CXXStdInitializerListExpr(EmptyShell Empty) |
801 | : Expr(CXXStdInitializerListExprClass, Empty) {} |
802 | |
803 | public: |
804 | friend class ASTReader; |
805 | friend class ASTStmtReader; |
806 | |
807 | CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr) |
808 | : Expr(CXXStdInitializerListExprClass, Ty, VK_PRValue, OK_Ordinary), |
809 | SubExpr(SubExpr) { |
810 | setDependence(computeDependence(E: this)); |
811 | } |
812 | |
813 | Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); } |
814 | const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); } |
815 | |
816 | SourceLocation getBeginLoc() const LLVM_READONLY { |
817 | return SubExpr->getBeginLoc(); |
818 | } |
819 | |
820 | SourceLocation getEndLoc() const LLVM_READONLY { |
821 | return SubExpr->getEndLoc(); |
822 | } |
823 | |
824 | /// Retrieve the source range of the expression. |
825 | SourceRange getSourceRange() const LLVM_READONLY { |
826 | return SubExpr->getSourceRange(); |
827 | } |
828 | |
829 | static bool classof(const Stmt *S) { |
830 | return S->getStmtClass() == CXXStdInitializerListExprClass; |
831 | } |
832 | |
833 | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } |
834 | |
835 | const_child_range children() const { |
836 | return const_child_range(&SubExpr, &SubExpr + 1); |
837 | } |
838 | }; |
839 | |
840 | /// A C++ \c typeid expression (C++ [expr.typeid]), which gets |
841 | /// the \c type_info that corresponds to the supplied type, or the (possibly |
842 | /// dynamic) type of the supplied expression. |
843 | /// |
844 | /// This represents code like \c typeid(int) or \c typeid(*objPtr) |
845 | class CXXTypeidExpr : public Expr { |
846 | friend class ASTStmtReader; |
847 | |
848 | private: |
849 | llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; |
850 | SourceRange Range; |
851 | |
852 | public: |
853 | CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) |
854 | : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), |
855 | Range(R) { |
856 | setDependence(computeDependence(E: this)); |
857 | } |
858 | |
859 | CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R) |
860 | : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), |
861 | Range(R) { |
862 | setDependence(computeDependence(E: this)); |
863 | } |
864 | |
865 | CXXTypeidExpr(EmptyShell Empty, bool isExpr) |
866 | : Expr(CXXTypeidExprClass, Empty) { |
867 | if (isExpr) |
868 | Operand = (Expr*)nullptr; |
869 | else |
870 | Operand = (TypeSourceInfo*)nullptr; |
871 | } |
872 | |
873 | /// Determine whether this typeid has a type operand which is potentially |
874 | /// evaluated, per C++11 [expr.typeid]p3. |
875 | bool isPotentiallyEvaluated() const; |
876 | |
877 | /// Best-effort check if the expression operand refers to a most derived |
878 | /// object. This is not a strong guarantee. |
879 | bool isMostDerived(ASTContext &Context) const; |
880 | |
881 | bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); } |
882 | |
883 | /// Retrieves the type operand of this typeid() expression after |
884 | /// various required adjustments (removing reference types, cv-qualifiers). |
885 | QualType getTypeOperand(ASTContext &Context) const; |
886 | |
887 | /// Retrieve source information for the type operand. |
888 | TypeSourceInfo *getTypeOperandSourceInfo() const { |
889 | assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)" ); |
890 | return Operand.get<TypeSourceInfo *>(); |
891 | } |
892 | Expr *getExprOperand() const { |
893 | assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)" ); |
894 | return static_cast<Expr*>(Operand.get<Stmt *>()); |
895 | } |
896 | |
897 | SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } |
898 | SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } |
899 | SourceRange getSourceRange() const LLVM_READONLY { return Range; } |
900 | void setSourceRange(SourceRange R) { Range = R; } |
901 | |
902 | static bool classof(const Stmt *T) { |
903 | return T->getStmtClass() == CXXTypeidExprClass; |
904 | } |
905 | |
906 | // Iterators |
907 | child_range children() { |
908 | if (isTypeOperand()) |
909 | return child_range(child_iterator(), child_iterator()); |
910 | auto **begin = reinterpret_cast<Stmt **>(&Operand); |
911 | return child_range(begin, begin + 1); |
912 | } |
913 | |
914 | const_child_range children() const { |
915 | if (isTypeOperand()) |
916 | return const_child_range(const_child_iterator(), const_child_iterator()); |
917 | |
918 | auto **begin = |
919 | reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand); |
920 | return const_child_range(begin, begin + 1); |
921 | } |
922 | }; |
923 | |
924 | /// A member reference to an MSPropertyDecl. |
925 | /// |
926 | /// This expression always has pseudo-object type, and therefore it is |
927 | /// typically not encountered in a fully-typechecked expression except |
928 | /// within the syntactic form of a PseudoObjectExpr. |
929 | class MSPropertyRefExpr : public Expr { |
930 | Expr *BaseExpr; |
931 | MSPropertyDecl *TheDecl; |
932 | SourceLocation MemberLoc; |
933 | bool IsArrow; |
934 | NestedNameSpecifierLoc QualifierLoc; |
935 | |
936 | public: |
937 | friend class ASTStmtReader; |
938 | |
939 | MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow, |
940 | QualType ty, ExprValueKind VK, |
941 | NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc) |
942 | : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary), BaseExpr(baseExpr), |
943 | TheDecl(decl), MemberLoc(nameLoc), IsArrow(isArrow), |
944 | QualifierLoc(qualifierLoc) { |
945 | setDependence(computeDependence(E: this)); |
946 | } |
947 | |
948 | MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {} |
949 | |
950 | SourceRange getSourceRange() const LLVM_READONLY { |
951 | return SourceRange(getBeginLoc(), getEndLoc()); |
952 | } |
953 | |
954 | bool isImplicitAccess() const { |
955 | return getBaseExpr() && getBaseExpr()->isImplicitCXXThis(); |
956 | } |
957 | |
958 | SourceLocation getBeginLoc() const { |
959 | if (!isImplicitAccess()) |
960 | return BaseExpr->getBeginLoc(); |
961 | else if (QualifierLoc) |
962 | return QualifierLoc.getBeginLoc(); |
963 | else |
964 | return MemberLoc; |
965 | } |
966 | |
967 | SourceLocation getEndLoc() const { return getMemberLoc(); } |
968 | |
969 | child_range children() { |
970 | return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1); |
971 | } |
972 | |
973 | const_child_range children() const { |
974 | auto Children = const_cast<MSPropertyRefExpr *>(this)->children(); |
975 | return const_child_range(Children.begin(), Children.end()); |
976 | } |
977 | |
978 | static bool classof(const Stmt *T) { |
979 | return T->getStmtClass() == MSPropertyRefExprClass; |
980 | } |
981 | |
982 | Expr *getBaseExpr() const { return BaseExpr; } |
983 | MSPropertyDecl *getPropertyDecl() const { return TheDecl; } |
984 | bool isArrow() const { return IsArrow; } |
985 | SourceLocation getMemberLoc() const { return MemberLoc; } |
986 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
987 | }; |
988 | |
989 | /// MS property subscript expression. |
990 | /// MSVC supports 'property' attribute and allows to apply it to the |
991 | /// declaration of an empty array in a class or structure definition. |
992 | /// For example: |
993 | /// \code |
994 | /// __declspec(property(get=GetX, put=PutX)) int x[]; |
995 | /// \endcode |
996 | /// The above statement indicates that x[] can be used with one or more array |
997 | /// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and |
998 | /// p->x[a][b] = i will be turned into p->PutX(a, b, i). |
999 | /// This is a syntactic pseudo-object expression. |
1000 | class MSPropertySubscriptExpr : public Expr { |
1001 | friend class ASTStmtReader; |
1002 | |
1003 | enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 }; |
1004 | |
1005 | Stmt *SubExprs[NUM_SUBEXPRS]; |
1006 | SourceLocation RBracketLoc; |
1007 | |
1008 | void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; } |
1009 | void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; } |
1010 | |
1011 | public: |
1012 | MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK, |
1013 | ExprObjectKind OK, SourceLocation RBracketLoc) |
1014 | : Expr(MSPropertySubscriptExprClass, Ty, VK, OK), |
1015 | RBracketLoc(RBracketLoc) { |
1016 | SubExprs[BASE_EXPR] = Base; |
1017 | SubExprs[IDX_EXPR] = Idx; |
1018 | setDependence(computeDependence(E: this)); |
1019 | } |
1020 | |
1021 | /// Create an empty array subscript expression. |
1022 | explicit MSPropertySubscriptExpr(EmptyShell Shell) |
1023 | : Expr(MSPropertySubscriptExprClass, Shell) {} |
1024 | |
1025 | Expr *getBase() { return cast<Expr>(Val: SubExprs[BASE_EXPR]); } |
1026 | const Expr *getBase() const { return cast<Expr>(Val: SubExprs[BASE_EXPR]); } |
1027 | |
1028 | Expr *getIdx() { return cast<Expr>(Val: SubExprs[IDX_EXPR]); } |
1029 | const Expr *getIdx() const { return cast<Expr>(Val: SubExprs[IDX_EXPR]); } |
1030 | |
1031 | SourceLocation getBeginLoc() const LLVM_READONLY { |
1032 | return getBase()->getBeginLoc(); |
1033 | } |
1034 | |
1035 | SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } |
1036 | |
1037 | SourceLocation getRBracketLoc() const { return RBracketLoc; } |
1038 | void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } |
1039 | |
1040 | SourceLocation getExprLoc() const LLVM_READONLY { |
1041 | return getBase()->getExprLoc(); |
1042 | } |
1043 | |
1044 | static bool classof(const Stmt *T) { |
1045 | return T->getStmtClass() == MSPropertySubscriptExprClass; |
1046 | } |
1047 | |
1048 | // Iterators |
1049 | child_range children() { |
1050 | return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); |
1051 | } |
1052 | |
1053 | const_child_range children() const { |
1054 | return const_child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); |
1055 | } |
1056 | }; |
1057 | |
1058 | /// A Microsoft C++ @c __uuidof expression, which gets |
1059 | /// the _GUID that corresponds to the supplied type or expression. |
1060 | /// |
1061 | /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr) |
1062 | class CXXUuidofExpr : public Expr { |
1063 | friend class ASTStmtReader; |
1064 | |
1065 | private: |
1066 | llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; |
1067 | MSGuidDecl *Guid; |
1068 | SourceRange Range; |
1069 | |
1070 | public: |
1071 | CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, MSGuidDecl *Guid, |
1072 | SourceRange R) |
1073 | : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), |
1074 | Guid(Guid), Range(R) { |
1075 | setDependence(computeDependence(E: this)); |
1076 | } |
1077 | |
1078 | CXXUuidofExpr(QualType Ty, Expr *Operand, MSGuidDecl *Guid, SourceRange R) |
1079 | : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), |
1080 | Guid(Guid), Range(R) { |
1081 | setDependence(computeDependence(E: this)); |
1082 | } |
1083 | |
1084 | CXXUuidofExpr(EmptyShell Empty, bool isExpr) |
1085 | : Expr(CXXUuidofExprClass, Empty) { |
1086 | if (isExpr) |
1087 | Operand = (Expr*)nullptr; |
1088 | else |
1089 | Operand = (TypeSourceInfo*)nullptr; |
1090 | } |
1091 | |
1092 | bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); } |
1093 | |
1094 | /// Retrieves the type operand of this __uuidof() expression after |
1095 | /// various required adjustments (removing reference types, cv-qualifiers). |
1096 | QualType getTypeOperand(ASTContext &Context) const; |
1097 | |
1098 | /// Retrieve source information for the type operand. |
1099 | TypeSourceInfo *getTypeOperandSourceInfo() const { |
1100 | assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)" ); |
1101 | return Operand.get<TypeSourceInfo *>(); |
1102 | } |
1103 | Expr *getExprOperand() const { |
1104 | assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)" ); |
1105 | return static_cast<Expr*>(Operand.get<Stmt *>()); |
1106 | } |
1107 | |
1108 | MSGuidDecl *getGuidDecl() const { return Guid; } |
1109 | |
1110 | SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } |
1111 | SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } |
1112 | SourceRange getSourceRange() const LLVM_READONLY { return Range; } |
1113 | void setSourceRange(SourceRange R) { Range = R; } |
1114 | |
1115 | static bool classof(const Stmt *T) { |
1116 | return T->getStmtClass() == CXXUuidofExprClass; |
1117 | } |
1118 | |
1119 | // Iterators |
1120 | child_range children() { |
1121 | if (isTypeOperand()) |
1122 | return child_range(child_iterator(), child_iterator()); |
1123 | auto **begin = reinterpret_cast<Stmt **>(&Operand); |
1124 | return child_range(begin, begin + 1); |
1125 | } |
1126 | |
1127 | const_child_range children() const { |
1128 | if (isTypeOperand()) |
1129 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1130 | auto **begin = |
1131 | reinterpret_cast<Stmt **>(&const_cast<CXXUuidofExpr *>(this)->Operand); |
1132 | return const_child_range(begin, begin + 1); |
1133 | } |
1134 | }; |
1135 | |
1136 | /// Represents the \c this expression in C++. |
1137 | /// |
1138 | /// This is a pointer to the object on which the current member function is |
1139 | /// executing (C++ [expr.prim]p3). Example: |
1140 | /// |
1141 | /// \code |
1142 | /// class Foo { |
1143 | /// public: |
1144 | /// void bar(); |
1145 | /// void test() { this->bar(); } |
1146 | /// }; |
1147 | /// \endcode |
1148 | class CXXThisExpr : public Expr { |
1149 | CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK) |
1150 | : Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) { |
1151 | CXXThisExprBits.IsImplicit = IsImplicit; |
1152 | CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; |
1153 | CXXThisExprBits.Loc = L; |
1154 | setDependence(computeDependence(E: this)); |
1155 | } |
1156 | |
1157 | CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} |
1158 | |
1159 | public: |
1160 | static CXXThisExpr *Create(const ASTContext &Ctx, SourceLocation L, |
1161 | QualType Ty, bool IsImplicit); |
1162 | |
1163 | static CXXThisExpr *CreateEmpty(const ASTContext &Ctx); |
1164 | |
1165 | SourceLocation getLocation() const { return CXXThisExprBits.Loc; } |
1166 | void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; } |
1167 | |
1168 | SourceLocation getBeginLoc() const { return getLocation(); } |
1169 | SourceLocation getEndLoc() const { return getLocation(); } |
1170 | |
1171 | bool isImplicit() const { return CXXThisExprBits.IsImplicit; } |
1172 | void setImplicit(bool I) { CXXThisExprBits.IsImplicit = I; } |
1173 | |
1174 | bool isCapturedByCopyInLambdaWithExplicitObjectParameter() const { |
1175 | return CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter; |
1176 | } |
1177 | |
1178 | void setCapturedByCopyInLambdaWithExplicitObjectParameter(bool Set) { |
1179 | CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = Set; |
1180 | setDependence(computeDependence(E: this)); |
1181 | } |
1182 | |
1183 | static bool classof(const Stmt *T) { |
1184 | return T->getStmtClass() == CXXThisExprClass; |
1185 | } |
1186 | |
1187 | // Iterators |
1188 | child_range children() { |
1189 | return child_range(child_iterator(), child_iterator()); |
1190 | } |
1191 | |
1192 | const_child_range children() const { |
1193 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1194 | } |
1195 | }; |
1196 | |
1197 | /// A C++ throw-expression (C++ [except.throw]). |
1198 | /// |
1199 | /// This handles 'throw' (for re-throwing the current exception) and |
1200 | /// 'throw' assignment-expression. When assignment-expression isn't |
1201 | /// present, Op will be null. |
1202 | class CXXThrowExpr : public Expr { |
1203 | friend class ASTStmtReader; |
1204 | |
1205 | /// The optional expression in the throw statement. |
1206 | Stmt *Operand; |
1207 | |
1208 | public: |
1209 | // \p Ty is the void type which is used as the result type of the |
1210 | // expression. The \p Loc is the location of the throw keyword. |
1211 | // \p Operand is the expression in the throw statement, and can be |
1212 | // null if not present. |
1213 | CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc, |
1214 | bool IsThrownVariableInScope) |
1215 | : Expr(CXXThrowExprClass, Ty, VK_PRValue, OK_Ordinary), Operand(Operand) { |
1216 | CXXThrowExprBits.ThrowLoc = Loc; |
1217 | CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope; |
1218 | setDependence(computeDependence(E: this)); |
1219 | } |
1220 | CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} |
1221 | |
1222 | const Expr *getSubExpr() const { return cast_or_null<Expr>(Val: Operand); } |
1223 | Expr *getSubExpr() { return cast_or_null<Expr>(Val: Operand); } |
1224 | |
1225 | SourceLocation getThrowLoc() const { return CXXThrowExprBits.ThrowLoc; } |
1226 | |
1227 | /// Determines whether the variable thrown by this expression (if any!) |
1228 | /// is within the innermost try block. |
1229 | /// |
1230 | /// This information is required to determine whether the NRVO can apply to |
1231 | /// this variable. |
1232 | bool isThrownVariableInScope() const { |
1233 | return CXXThrowExprBits.IsThrownVariableInScope; |
1234 | } |
1235 | |
1236 | SourceLocation getBeginLoc() const { return getThrowLoc(); } |
1237 | SourceLocation getEndLoc() const LLVM_READONLY { |
1238 | if (!getSubExpr()) |
1239 | return getThrowLoc(); |
1240 | return getSubExpr()->getEndLoc(); |
1241 | } |
1242 | |
1243 | static bool classof(const Stmt *T) { |
1244 | return T->getStmtClass() == CXXThrowExprClass; |
1245 | } |
1246 | |
1247 | // Iterators |
1248 | child_range children() { |
1249 | return child_range(&Operand, Operand ? &Operand + 1 : &Operand); |
1250 | } |
1251 | |
1252 | const_child_range children() const { |
1253 | return const_child_range(&Operand, Operand ? &Operand + 1 : &Operand); |
1254 | } |
1255 | }; |
1256 | |
1257 | /// A default argument (C++ [dcl.fct.default]). |
1258 | /// |
1259 | /// This wraps up a function call argument that was created from the |
1260 | /// corresponding parameter's default argument, when the call did not |
1261 | /// explicitly supply arguments for all of the parameters. |
1262 | class CXXDefaultArgExpr final |
1263 | : public Expr, |
1264 | private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> { |
1265 | friend class ASTStmtReader; |
1266 | friend class ASTReader; |
1267 | friend TrailingObjects; |
1268 | |
1269 | /// The parameter whose default is being used. |
1270 | ParmVarDecl *Param; |
1271 | |
1272 | /// The context where the default argument expression was used. |
1273 | DeclContext *UsedContext; |
1274 | |
1275 | CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param, |
1276 | Expr *RewrittenExpr, DeclContext *UsedContext) |
1277 | : Expr(SC, |
1278 | Param->hasUnparsedDefaultArg() |
1279 | ? Param->getType().getNonReferenceType() |
1280 | : Param->getDefaultArg()->getType(), |
1281 | Param->getDefaultArg()->getValueKind(), |
1282 | Param->getDefaultArg()->getObjectKind()), |
1283 | Param(Param), UsedContext(UsedContext) { |
1284 | CXXDefaultArgExprBits.Loc = Loc; |
1285 | CXXDefaultArgExprBits.HasRewrittenInit = RewrittenExpr != nullptr; |
1286 | if (RewrittenExpr) |
1287 | *getTrailingObjects<Expr *>() = RewrittenExpr; |
1288 | setDependence(computeDependence(E: this)); |
1289 | } |
1290 | |
1291 | CXXDefaultArgExpr(EmptyShell Empty, bool HasRewrittenInit) |
1292 | : Expr(CXXDefaultArgExprClass, Empty) { |
1293 | CXXDefaultArgExprBits.HasRewrittenInit = HasRewrittenInit; |
1294 | } |
1295 | |
1296 | public: |
1297 | static CXXDefaultArgExpr *CreateEmpty(const ASTContext &C, |
1298 | bool HasRewrittenInit); |
1299 | |
1300 | // \p Param is the parameter whose default argument is used by this |
1301 | // expression. |
1302 | static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, |
1303 | ParmVarDecl *Param, Expr *RewrittenExpr, |
1304 | DeclContext *UsedContext); |
1305 | // Retrieve the parameter that the argument was created from. |
1306 | const ParmVarDecl *getParam() const { return Param; } |
1307 | ParmVarDecl *getParam() { return Param; } |
1308 | |
1309 | bool hasRewrittenInit() const { |
1310 | return CXXDefaultArgExprBits.HasRewrittenInit; |
1311 | } |
1312 | |
1313 | // Retrieve the argument to the function call. |
1314 | Expr *getExpr(); |
1315 | const Expr *getExpr() const { |
1316 | return const_cast<CXXDefaultArgExpr *>(this)->getExpr(); |
1317 | } |
1318 | |
1319 | Expr *getRewrittenExpr() { |
1320 | return hasRewrittenInit() ? *getTrailingObjects<Expr *>() : nullptr; |
1321 | } |
1322 | |
1323 | const Expr *getRewrittenExpr() const { |
1324 | return const_cast<CXXDefaultArgExpr *>(this)->getRewrittenExpr(); |
1325 | } |
1326 | |
1327 | // Retrieve the rewritten init expression (for an init expression containing |
1328 | // immediate calls) with the top level FullExpr and ConstantExpr stripped off. |
1329 | Expr *getAdjustedRewrittenExpr(); |
1330 | const Expr *getAdjustedRewrittenExpr() const { |
1331 | return const_cast<CXXDefaultArgExpr *>(this)->getAdjustedRewrittenExpr(); |
1332 | } |
1333 | |
1334 | const DeclContext *getUsedContext() const { return UsedContext; } |
1335 | DeclContext *getUsedContext() { return UsedContext; } |
1336 | |
1337 | /// Retrieve the location where this default argument was actually used. |
1338 | SourceLocation getUsedLocation() const { return CXXDefaultArgExprBits.Loc; } |
1339 | |
1340 | /// Default argument expressions have no representation in the |
1341 | /// source, so they have an empty source range. |
1342 | SourceLocation getBeginLoc() const { return SourceLocation(); } |
1343 | SourceLocation getEndLoc() const { return SourceLocation(); } |
1344 | |
1345 | SourceLocation getExprLoc() const { return getUsedLocation(); } |
1346 | |
1347 | static bool classof(const Stmt *T) { |
1348 | return T->getStmtClass() == CXXDefaultArgExprClass; |
1349 | } |
1350 | |
1351 | // Iterators |
1352 | child_range children() { |
1353 | return child_range(child_iterator(), child_iterator()); |
1354 | } |
1355 | |
1356 | const_child_range children() const { |
1357 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1358 | } |
1359 | }; |
1360 | |
1361 | /// A use of a default initializer in a constructor or in aggregate |
1362 | /// initialization. |
1363 | /// |
1364 | /// This wraps a use of a C++ default initializer (technically, |
1365 | /// a brace-or-equal-initializer for a non-static data member) when it |
1366 | /// is implicitly used in a mem-initializer-list in a constructor |
1367 | /// (C++11 [class.base.init]p8) or in aggregate initialization |
1368 | /// (C++1y [dcl.init.aggr]p7). |
1369 | class CXXDefaultInitExpr final |
1370 | : public Expr, |
1371 | private llvm::TrailingObjects<CXXDefaultInitExpr, Expr *> { |
1372 | |
1373 | friend class ASTStmtReader; |
1374 | friend class ASTReader; |
1375 | friend TrailingObjects; |
1376 | /// The field whose default is being used. |
1377 | FieldDecl *Field; |
1378 | |
1379 | /// The context where the default initializer expression was used. |
1380 | DeclContext *UsedContext; |
1381 | |
1382 | CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc, |
1383 | FieldDecl *Field, QualType Ty, DeclContext *UsedContext, |
1384 | Expr *RewrittenInitExpr); |
1385 | |
1386 | CXXDefaultInitExpr(EmptyShell Empty, bool HasRewrittenInit) |
1387 | : Expr(CXXDefaultInitExprClass, Empty) { |
1388 | CXXDefaultInitExprBits.HasRewrittenInit = HasRewrittenInit; |
1389 | } |
1390 | |
1391 | public: |
1392 | static CXXDefaultInitExpr *CreateEmpty(const ASTContext &C, |
1393 | bool HasRewrittenInit); |
1394 | /// \p Field is the non-static data member whose default initializer is used |
1395 | /// by this expression. |
1396 | static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc, |
1397 | FieldDecl *Field, DeclContext *UsedContext, |
1398 | Expr *RewrittenInitExpr); |
1399 | |
1400 | bool hasRewrittenInit() const { |
1401 | return CXXDefaultInitExprBits.HasRewrittenInit; |
1402 | } |
1403 | |
1404 | /// Get the field whose initializer will be used. |
1405 | FieldDecl *getField() { return Field; } |
1406 | const FieldDecl *getField() const { return Field; } |
1407 | |
1408 | /// Get the initialization expression that will be used. |
1409 | Expr *getExpr(); |
1410 | const Expr *getExpr() const { |
1411 | return const_cast<CXXDefaultInitExpr *>(this)->getExpr(); |
1412 | } |
1413 | |
1414 | /// Retrieve the initializing expression with evaluated immediate calls, if |
1415 | /// any. |
1416 | const Expr *getRewrittenExpr() const { |
1417 | assert(hasRewrittenInit() && "expected a rewritten init expression" ); |
1418 | return *getTrailingObjects<Expr *>(); |
1419 | } |
1420 | |
1421 | /// Retrieve the initializing expression with evaluated immediate calls, if |
1422 | /// any. |
1423 | Expr *getRewrittenExpr() { |
1424 | assert(hasRewrittenInit() && "expected a rewritten init expression" ); |
1425 | return *getTrailingObjects<Expr *>(); |
1426 | } |
1427 | |
1428 | const DeclContext *getUsedContext() const { return UsedContext; } |
1429 | DeclContext *getUsedContext() { return UsedContext; } |
1430 | |
1431 | /// Retrieve the location where this default initializer expression was |
1432 | /// actually used. |
1433 | SourceLocation getUsedLocation() const { return getBeginLoc(); } |
1434 | |
1435 | SourceLocation getBeginLoc() const { return CXXDefaultInitExprBits.Loc; } |
1436 | SourceLocation getEndLoc() const { return CXXDefaultInitExprBits.Loc; } |
1437 | |
1438 | static bool classof(const Stmt *T) { |
1439 | return T->getStmtClass() == CXXDefaultInitExprClass; |
1440 | } |
1441 | |
1442 | // Iterators |
1443 | child_range children() { |
1444 | return child_range(child_iterator(), child_iterator()); |
1445 | } |
1446 | |
1447 | const_child_range children() const { |
1448 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1449 | } |
1450 | }; |
1451 | |
1452 | /// Represents a C++ temporary. |
1453 | class CXXTemporary { |
1454 | /// The destructor that needs to be called. |
1455 | const CXXDestructorDecl *Destructor; |
1456 | |
1457 | explicit CXXTemporary(const CXXDestructorDecl *destructor) |
1458 | : Destructor(destructor) {} |
1459 | |
1460 | public: |
1461 | static CXXTemporary *Create(const ASTContext &C, |
1462 | const CXXDestructorDecl *Destructor); |
1463 | |
1464 | const CXXDestructorDecl *getDestructor() const { return Destructor; } |
1465 | |
1466 | void setDestructor(const CXXDestructorDecl *Dtor) { |
1467 | Destructor = Dtor; |
1468 | } |
1469 | }; |
1470 | |
1471 | /// Represents binding an expression to a temporary. |
1472 | /// |
1473 | /// This ensures the destructor is called for the temporary. It should only be |
1474 | /// needed for non-POD, non-trivially destructable class types. For example: |
1475 | /// |
1476 | /// \code |
1477 | /// struct S { |
1478 | /// S() { } // User defined constructor makes S non-POD. |
1479 | /// ~S() { } // User defined destructor makes it non-trivial. |
1480 | /// }; |
1481 | /// void test() { |
1482 | /// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr. |
1483 | /// } |
1484 | /// \endcode |
1485 | class CXXBindTemporaryExpr : public Expr { |
1486 | CXXTemporary *Temp = nullptr; |
1487 | Stmt *SubExpr = nullptr; |
1488 | |
1489 | CXXBindTemporaryExpr(CXXTemporary *temp, Expr *SubExpr) |
1490 | : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_PRValue, |
1491 | OK_Ordinary), |
1492 | Temp(temp), SubExpr(SubExpr) { |
1493 | setDependence(computeDependence(E: this)); |
1494 | } |
1495 | |
1496 | public: |
1497 | CXXBindTemporaryExpr(EmptyShell Empty) |
1498 | : Expr(CXXBindTemporaryExprClass, Empty) {} |
1499 | |
1500 | static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp, |
1501 | Expr* SubExpr); |
1502 | |
1503 | CXXTemporary *getTemporary() { return Temp; } |
1504 | const CXXTemporary *getTemporary() const { return Temp; } |
1505 | void setTemporary(CXXTemporary *T) { Temp = T; } |
1506 | |
1507 | const Expr *getSubExpr() const { return cast<Expr>(Val: SubExpr); } |
1508 | Expr *getSubExpr() { return cast<Expr>(Val: SubExpr); } |
1509 | void setSubExpr(Expr *E) { SubExpr = E; } |
1510 | |
1511 | SourceLocation getBeginLoc() const LLVM_READONLY { |
1512 | return SubExpr->getBeginLoc(); |
1513 | } |
1514 | |
1515 | SourceLocation getEndLoc() const LLVM_READONLY { |
1516 | return SubExpr->getEndLoc(); |
1517 | } |
1518 | |
1519 | // Implement isa/cast/dyncast/etc. |
1520 | static bool classof(const Stmt *T) { |
1521 | return T->getStmtClass() == CXXBindTemporaryExprClass; |
1522 | } |
1523 | |
1524 | // Iterators |
1525 | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } |
1526 | |
1527 | const_child_range children() const { |
1528 | return const_child_range(&SubExpr, &SubExpr + 1); |
1529 | } |
1530 | }; |
1531 | |
1532 | enum class CXXConstructionKind { |
1533 | Complete, |
1534 | NonVirtualBase, |
1535 | VirtualBase, |
1536 | Delegating |
1537 | }; |
1538 | |
1539 | /// Represents a call to a C++ constructor. |
1540 | class CXXConstructExpr : public Expr { |
1541 | friend class ASTStmtReader; |
1542 | |
1543 | /// A pointer to the constructor which will be ultimately called. |
1544 | CXXConstructorDecl *Constructor; |
1545 | |
1546 | SourceRange ParenOrBraceRange; |
1547 | |
1548 | /// The number of arguments. |
1549 | unsigned NumArgs; |
1550 | |
1551 | // We would like to stash the arguments of the constructor call after |
1552 | // CXXConstructExpr. However CXXConstructExpr is used as a base class of |
1553 | // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects |
1554 | // impossible. |
1555 | // |
1556 | // Instead we manually stash the trailing object after the full object |
1557 | // containing CXXConstructExpr (that is either CXXConstructExpr or |
1558 | // CXXTemporaryObjectExpr). |
1559 | // |
1560 | // The trailing objects are: |
1561 | // |
1562 | // * An array of getNumArgs() "Stmt *" for the arguments of the |
1563 | // constructor call. |
1564 | |
1565 | /// Return a pointer to the start of the trailing arguments. |
1566 | /// Defined just after CXXTemporaryObjectExpr. |
1567 | inline Stmt **getTrailingArgs(); |
1568 | const Stmt *const *getTrailingArgs() const { |
1569 | return const_cast<CXXConstructExpr *>(this)->getTrailingArgs(); |
1570 | } |
1571 | |
1572 | protected: |
1573 | /// Build a C++ construction expression. |
1574 | CXXConstructExpr(StmtClass SC, QualType Ty, SourceLocation Loc, |
1575 | CXXConstructorDecl *Ctor, bool Elidable, |
1576 | ArrayRef<Expr *> Args, bool HadMultipleCandidates, |
1577 | bool ListInitialization, bool StdInitListInitialization, |
1578 | bool ZeroInitialization, CXXConstructionKind ConstructKind, |
1579 | SourceRange ParenOrBraceRange); |
1580 | |
1581 | /// Build an empty C++ construction expression. |
1582 | CXXConstructExpr(StmtClass SC, EmptyShell Empty, unsigned NumArgs); |
1583 | |
1584 | /// Return the size in bytes of the trailing objects. Used by |
1585 | /// CXXTemporaryObjectExpr to allocate the right amount of storage. |
1586 | static unsigned sizeOfTrailingObjects(unsigned NumArgs) { |
1587 | return NumArgs * sizeof(Stmt *); |
1588 | } |
1589 | |
1590 | public: |
1591 | /// Create a C++ construction expression. |
1592 | static CXXConstructExpr * |
1593 | Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, |
1594 | CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args, |
1595 | bool HadMultipleCandidates, bool ListInitialization, |
1596 | bool StdInitListInitialization, bool ZeroInitialization, |
1597 | CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange); |
1598 | |
1599 | /// Create an empty C++ construction expression. |
1600 | static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs); |
1601 | |
1602 | /// Get the constructor that this expression will (ultimately) call. |
1603 | CXXConstructorDecl *getConstructor() const { return Constructor; } |
1604 | |
1605 | SourceLocation getLocation() const { return CXXConstructExprBits.Loc; } |
1606 | void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; } |
1607 | |
1608 | /// Whether this construction is elidable. |
1609 | bool isElidable() const { return CXXConstructExprBits.Elidable; } |
1610 | void setElidable(bool E) { CXXConstructExprBits.Elidable = E; } |
1611 | |
1612 | /// Whether the referred constructor was resolved from |
1613 | /// an overloaded set having size greater than 1. |
1614 | bool hadMultipleCandidates() const { |
1615 | return CXXConstructExprBits.HadMultipleCandidates; |
1616 | } |
1617 | void setHadMultipleCandidates(bool V) { |
1618 | CXXConstructExprBits.HadMultipleCandidates = V; |
1619 | } |
1620 | |
1621 | /// Whether this constructor call was written as list-initialization. |
1622 | bool isListInitialization() const { |
1623 | return CXXConstructExprBits.ListInitialization; |
1624 | } |
1625 | void setListInitialization(bool V) { |
1626 | CXXConstructExprBits.ListInitialization = V; |
1627 | } |
1628 | |
1629 | /// Whether this constructor call was written as list-initialization, |
1630 | /// but was interpreted as forming a std::initializer_list<T> from the list |
1631 | /// and passing that as a single constructor argument. |
1632 | /// See C++11 [over.match.list]p1 bullet 1. |
1633 | bool isStdInitListInitialization() const { |
1634 | return CXXConstructExprBits.StdInitListInitialization; |
1635 | } |
1636 | void setStdInitListInitialization(bool V) { |
1637 | CXXConstructExprBits.StdInitListInitialization = V; |
1638 | } |
1639 | |
1640 | /// Whether this construction first requires |
1641 | /// zero-initialization before the initializer is called. |
1642 | bool requiresZeroInitialization() const { |
1643 | return CXXConstructExprBits.ZeroInitialization; |
1644 | } |
1645 | void setRequiresZeroInitialization(bool ZeroInit) { |
1646 | CXXConstructExprBits.ZeroInitialization = ZeroInit; |
1647 | } |
1648 | |
1649 | /// Determine whether this constructor is actually constructing |
1650 | /// a base class (rather than a complete object). |
1651 | CXXConstructionKind getConstructionKind() const { |
1652 | return static_cast<CXXConstructionKind>( |
1653 | CXXConstructExprBits.ConstructionKind); |
1654 | } |
1655 | void setConstructionKind(CXXConstructionKind CK) { |
1656 | CXXConstructExprBits.ConstructionKind = llvm::to_underlying(E: CK); |
1657 | } |
1658 | |
1659 | using arg_iterator = ExprIterator; |
1660 | using const_arg_iterator = ConstExprIterator; |
1661 | using arg_range = llvm::iterator_range<arg_iterator>; |
1662 | using const_arg_range = llvm::iterator_range<const_arg_iterator>; |
1663 | |
1664 | arg_range arguments() { return arg_range(arg_begin(), arg_end()); } |
1665 | const_arg_range arguments() const { |
1666 | return const_arg_range(arg_begin(), arg_end()); |
1667 | } |
1668 | |
1669 | arg_iterator arg_begin() { return getTrailingArgs(); } |
1670 | arg_iterator arg_end() { return arg_begin() + getNumArgs(); } |
1671 | const_arg_iterator arg_begin() const { return getTrailingArgs(); } |
1672 | const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); } |
1673 | |
1674 | Expr **getArgs() { return reinterpret_cast<Expr **>(getTrailingArgs()); } |
1675 | const Expr *const *getArgs() const { |
1676 | return reinterpret_cast<const Expr *const *>(getTrailingArgs()); |
1677 | } |
1678 | |
1679 | /// Return the number of arguments to the constructor call. |
1680 | unsigned getNumArgs() const { return NumArgs; } |
1681 | |
1682 | /// Return the specified argument. |
1683 | Expr *getArg(unsigned Arg) { |
1684 | assert(Arg < getNumArgs() && "Arg access out of range!" ); |
1685 | return getArgs()[Arg]; |
1686 | } |
1687 | const Expr *getArg(unsigned Arg) const { |
1688 | assert(Arg < getNumArgs() && "Arg access out of range!" ); |
1689 | return getArgs()[Arg]; |
1690 | } |
1691 | |
1692 | /// Set the specified argument. |
1693 | void setArg(unsigned Arg, Expr *ArgExpr) { |
1694 | assert(Arg < getNumArgs() && "Arg access out of range!" ); |
1695 | getArgs()[Arg] = ArgExpr; |
1696 | } |
1697 | |
1698 | bool isImmediateEscalating() const { |
1699 | return CXXConstructExprBits.IsImmediateEscalating; |
1700 | } |
1701 | |
1702 | void setIsImmediateEscalating(bool Set) { |
1703 | CXXConstructExprBits.IsImmediateEscalating = Set; |
1704 | } |
1705 | |
1706 | SourceLocation getBeginLoc() const LLVM_READONLY; |
1707 | SourceLocation getEndLoc() const LLVM_READONLY; |
1708 | SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; } |
1709 | void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; } |
1710 | |
1711 | static bool classof(const Stmt *T) { |
1712 | return T->getStmtClass() == CXXConstructExprClass || |
1713 | T->getStmtClass() == CXXTemporaryObjectExprClass; |
1714 | } |
1715 | |
1716 | // Iterators |
1717 | child_range children() { |
1718 | return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs()); |
1719 | } |
1720 | |
1721 | const_child_range children() const { |
1722 | auto Children = const_cast<CXXConstructExpr *>(this)->children(); |
1723 | return const_child_range(Children.begin(), Children.end()); |
1724 | } |
1725 | }; |
1726 | |
1727 | /// Represents a call to an inherited base class constructor from an |
1728 | /// inheriting constructor. This call implicitly forwards the arguments from |
1729 | /// the enclosing context (an inheriting constructor) to the specified inherited |
1730 | /// base class constructor. |
1731 | class CXXInheritedCtorInitExpr : public Expr { |
1732 | private: |
1733 | CXXConstructorDecl *Constructor = nullptr; |
1734 | |
1735 | /// The location of the using declaration. |
1736 | SourceLocation Loc; |
1737 | |
1738 | /// Whether this is the construction of a virtual base. |
1739 | LLVM_PREFERRED_TYPE(bool) |
1740 | unsigned ConstructsVirtualBase : 1; |
1741 | |
1742 | /// Whether the constructor is inherited from a virtual base class of the |
1743 | /// class that we construct. |
1744 | LLVM_PREFERRED_TYPE(bool) |
1745 | unsigned InheritedFromVirtualBase : 1; |
1746 | |
1747 | public: |
1748 | friend class ASTStmtReader; |
1749 | |
1750 | /// Construct a C++ inheriting construction expression. |
1751 | CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T, |
1752 | CXXConstructorDecl *Ctor, bool ConstructsVirtualBase, |
1753 | bool InheritedFromVirtualBase) |
1754 | : Expr(CXXInheritedCtorInitExprClass, T, VK_PRValue, OK_Ordinary), |
1755 | Constructor(Ctor), Loc(Loc), |
1756 | ConstructsVirtualBase(ConstructsVirtualBase), |
1757 | InheritedFromVirtualBase(InheritedFromVirtualBase) { |
1758 | assert(!T->isDependentType()); |
1759 | setDependence(ExprDependence::None); |
1760 | } |
1761 | |
1762 | /// Construct an empty C++ inheriting construction expression. |
1763 | explicit CXXInheritedCtorInitExpr(EmptyShell Empty) |
1764 | : Expr(CXXInheritedCtorInitExprClass, Empty), |
1765 | ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {} |
1766 | |
1767 | /// Get the constructor that this expression will call. |
1768 | CXXConstructorDecl *getConstructor() const { return Constructor; } |
1769 | |
1770 | /// Determine whether this constructor is actually constructing |
1771 | /// a base class (rather than a complete object). |
1772 | bool constructsVBase() const { return ConstructsVirtualBase; } |
1773 | CXXConstructionKind getConstructionKind() const { |
1774 | return ConstructsVirtualBase ? CXXConstructionKind::VirtualBase |
1775 | : CXXConstructionKind::NonVirtualBase; |
1776 | } |
1777 | |
1778 | /// Determine whether the inherited constructor is inherited from a |
1779 | /// virtual base of the object we construct. If so, we are not responsible |
1780 | /// for calling the inherited constructor (the complete object constructor |
1781 | /// does that), and so we don't need to pass any arguments. |
1782 | bool inheritedFromVBase() const { return InheritedFromVirtualBase; } |
1783 | |
1784 | SourceLocation getLocation() const LLVM_READONLY { return Loc; } |
1785 | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
1786 | SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } |
1787 | |
1788 | static bool classof(const Stmt *T) { |
1789 | return T->getStmtClass() == CXXInheritedCtorInitExprClass; |
1790 | } |
1791 | |
1792 | child_range children() { |
1793 | return child_range(child_iterator(), child_iterator()); |
1794 | } |
1795 | |
1796 | const_child_range children() const { |
1797 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1798 | } |
1799 | }; |
1800 | |
1801 | /// Represents an explicit C++ type conversion that uses "functional" |
1802 | /// notation (C++ [expr.type.conv]). |
1803 | /// |
1804 | /// Example: |
1805 | /// \code |
1806 | /// x = int(0.5); |
1807 | /// \endcode |
1808 | class CXXFunctionalCastExpr final |
1809 | : public ExplicitCastExpr, |
1810 | private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *, |
1811 | FPOptionsOverride> { |
1812 | SourceLocation LParenLoc; |
1813 | SourceLocation RParenLoc; |
1814 | |
1815 | CXXFunctionalCastExpr(QualType ty, ExprValueKind VK, |
1816 | TypeSourceInfo *writtenTy, CastKind kind, |
1817 | Expr *castExpr, unsigned pathSize, |
1818 | FPOptionsOverride FPO, SourceLocation lParenLoc, |
1819 | SourceLocation rParenLoc) |
1820 | : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, castExpr, |
1821 | pathSize, FPO.requiresTrailingStorage(), writtenTy), |
1822 | LParenLoc(lParenLoc), RParenLoc(rParenLoc) { |
1823 | if (hasStoredFPFeatures()) |
1824 | *getTrailingFPFeatures() = FPO; |
1825 | } |
1826 | |
1827 | explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize, |
1828 | bool HasFPFeatures) |
1829 | : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize, |
1830 | HasFPFeatures) {} |
1831 | |
1832 | unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const { |
1833 | return path_size(); |
1834 | } |
1835 | |
1836 | public: |
1837 | friend class CastExpr; |
1838 | friend TrailingObjects; |
1839 | |
1840 | static CXXFunctionalCastExpr * |
1841 | Create(const ASTContext &Context, QualType T, ExprValueKind VK, |
1842 | TypeSourceInfo *Written, CastKind Kind, Expr *Op, |
1843 | const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc, |
1844 | SourceLocation RPLoc); |
1845 | static CXXFunctionalCastExpr * |
1846 | CreateEmpty(const ASTContext &Context, unsigned PathSize, bool HasFPFeatures); |
1847 | |
1848 | SourceLocation getLParenLoc() const { return LParenLoc; } |
1849 | void setLParenLoc(SourceLocation L) { LParenLoc = L; } |
1850 | SourceLocation getRParenLoc() const { return RParenLoc; } |
1851 | void setRParenLoc(SourceLocation L) { RParenLoc = L; } |
1852 | |
1853 | /// Determine whether this expression models list-initialization. |
1854 | bool isListInitialization() const { return LParenLoc.isInvalid(); } |
1855 | |
1856 | SourceLocation getBeginLoc() const LLVM_READONLY; |
1857 | SourceLocation getEndLoc() const LLVM_READONLY; |
1858 | |
1859 | static bool classof(const Stmt *T) { |
1860 | return T->getStmtClass() == CXXFunctionalCastExprClass; |
1861 | } |
1862 | }; |
1863 | |
1864 | /// Represents a C++ functional cast expression that builds a |
1865 | /// temporary object. |
1866 | /// |
1867 | /// This expression type represents a C++ "functional" cast |
1868 | /// (C++[expr.type.conv]) with N != 1 arguments that invokes a |
1869 | /// constructor to build a temporary object. With N == 1 arguments the |
1870 | /// functional cast expression will be represented by CXXFunctionalCastExpr. |
1871 | /// Example: |
1872 | /// \code |
1873 | /// struct X { X(int, float); } |
1874 | /// |
1875 | /// X create_X() { |
1876 | /// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr |
1877 | /// }; |
1878 | /// \endcode |
1879 | class CXXTemporaryObjectExpr final : public CXXConstructExpr { |
1880 | friend class ASTStmtReader; |
1881 | |
1882 | // CXXTemporaryObjectExpr has some trailing objects belonging |
1883 | // to CXXConstructExpr. See the comment inside CXXConstructExpr |
1884 | // for more details. |
1885 | |
1886 | TypeSourceInfo *TSI; |
1887 | |
1888 | CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty, |
1889 | TypeSourceInfo *TSI, ArrayRef<Expr *> Args, |
1890 | SourceRange ParenOrBraceRange, |
1891 | bool HadMultipleCandidates, bool ListInitialization, |
1892 | bool StdInitListInitialization, |
1893 | bool ZeroInitialization); |
1894 | |
1895 | CXXTemporaryObjectExpr(EmptyShell Empty, unsigned NumArgs); |
1896 | |
1897 | public: |
1898 | static CXXTemporaryObjectExpr * |
1899 | Create(const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty, |
1900 | TypeSourceInfo *TSI, ArrayRef<Expr *> Args, |
1901 | SourceRange ParenOrBraceRange, bool HadMultipleCandidates, |
1902 | bool ListInitialization, bool StdInitListInitialization, |
1903 | bool ZeroInitialization); |
1904 | |
1905 | static CXXTemporaryObjectExpr *CreateEmpty(const ASTContext &Ctx, |
1906 | unsigned NumArgs); |
1907 | |
1908 | TypeSourceInfo *getTypeSourceInfo() const { return TSI; } |
1909 | |
1910 | SourceLocation getBeginLoc() const LLVM_READONLY; |
1911 | SourceLocation getEndLoc() const LLVM_READONLY; |
1912 | |
1913 | static bool classof(const Stmt *T) { |
1914 | return T->getStmtClass() == CXXTemporaryObjectExprClass; |
1915 | } |
1916 | }; |
1917 | |
1918 | Stmt **CXXConstructExpr::getTrailingArgs() { |
1919 | if (auto *E = dyn_cast<CXXTemporaryObjectExpr>(Val: this)) |
1920 | return reinterpret_cast<Stmt **>(E + 1); |
1921 | assert((getStmtClass() == CXXConstructExprClass) && |
1922 | "Unexpected class deriving from CXXConstructExpr!" ); |
1923 | return reinterpret_cast<Stmt **>(this + 1); |
1924 | } |
1925 | |
1926 | /// A C++ lambda expression, which produces a function object |
1927 | /// (of unspecified type) that can be invoked later. |
1928 | /// |
1929 | /// Example: |
1930 | /// \code |
1931 | /// void low_pass_filter(std::vector<double> &values, double cutoff) { |
1932 | /// values.erase(std::remove_if(values.begin(), values.end(), |
1933 | /// [=](double value) { return value > cutoff; }); |
1934 | /// } |
1935 | /// \endcode |
1936 | /// |
1937 | /// C++11 lambda expressions can capture local variables, either by copying |
1938 | /// the values of those local variables at the time the function |
1939 | /// object is constructed (not when it is called!) or by holding a |
1940 | /// reference to the local variable. These captures can occur either |
1941 | /// implicitly or can be written explicitly between the square |
1942 | /// brackets ([...]) that start the lambda expression. |
1943 | /// |
1944 | /// C++1y introduces a new form of "capture" called an init-capture that |
1945 | /// includes an initializing expression (rather than capturing a variable), |
1946 | /// and which can never occur implicitly. |
1947 | class LambdaExpr final : public Expr, |
1948 | private llvm::TrailingObjects<LambdaExpr, Stmt *> { |
1949 | // LambdaExpr has some data stored in LambdaExprBits. |
1950 | |
1951 | /// The source range that covers the lambda introducer ([...]). |
1952 | SourceRange IntroducerRange; |
1953 | |
1954 | /// The source location of this lambda's capture-default ('=' or '&'). |
1955 | SourceLocation CaptureDefaultLoc; |
1956 | |
1957 | /// The location of the closing brace ('}') that completes |
1958 | /// the lambda. |
1959 | /// |
1960 | /// The location of the brace is also available by looking up the |
1961 | /// function call operator in the lambda class. However, it is |
1962 | /// stored here to improve the performance of getSourceRange(), and |
1963 | /// to avoid having to deserialize the function call operator from a |
1964 | /// module file just to determine the source range. |
1965 | SourceLocation ClosingBrace; |
1966 | |
1967 | /// Construct a lambda expression. |
1968 | LambdaExpr(QualType T, SourceRange IntroducerRange, |
1969 | LambdaCaptureDefault CaptureDefault, |
1970 | SourceLocation CaptureDefaultLoc, bool ExplicitParams, |
1971 | bool ExplicitResultType, ArrayRef<Expr *> CaptureInits, |
1972 | SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack); |
1973 | |
1974 | /// Construct an empty lambda expression. |
1975 | LambdaExpr(EmptyShell Empty, unsigned NumCaptures); |
1976 | |
1977 | Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); } |
1978 | Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); } |
1979 | |
1980 | void initBodyIfNeeded() const; |
1981 | |
1982 | public: |
1983 | friend class ASTStmtReader; |
1984 | friend class ASTStmtWriter; |
1985 | friend TrailingObjects; |
1986 | |
1987 | /// Construct a new lambda expression. |
1988 | static LambdaExpr * |
1989 | Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange, |
1990 | LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc, |
1991 | bool ExplicitParams, bool ExplicitResultType, |
1992 | ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace, |
1993 | bool ContainsUnexpandedParameterPack); |
1994 | |
1995 | /// Construct a new lambda expression that will be deserialized from |
1996 | /// an external source. |
1997 | static LambdaExpr *CreateDeserialized(const ASTContext &C, |
1998 | unsigned NumCaptures); |
1999 | |
2000 | /// Determine the default capture kind for this lambda. |
2001 | LambdaCaptureDefault getCaptureDefault() const { |
2002 | return static_cast<LambdaCaptureDefault>(LambdaExprBits.CaptureDefault); |
2003 | } |
2004 | |
2005 | /// Retrieve the location of this lambda's capture-default, if any. |
2006 | SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; } |
2007 | |
2008 | /// Determine whether one of this lambda's captures is an init-capture. |
2009 | bool isInitCapture(const LambdaCapture *Capture) const; |
2010 | |
2011 | /// An iterator that walks over the captures of the lambda, |
2012 | /// both implicit and explicit. |
2013 | using capture_iterator = const LambdaCapture *; |
2014 | |
2015 | /// An iterator over a range of lambda captures. |
2016 | using capture_range = llvm::iterator_range<capture_iterator>; |
2017 | |
2018 | /// Retrieve this lambda's captures. |
2019 | capture_range captures() const; |
2020 | |
2021 | /// Retrieve an iterator pointing to the first lambda capture. |
2022 | capture_iterator capture_begin() const; |
2023 | |
2024 | /// Retrieve an iterator pointing past the end of the |
2025 | /// sequence of lambda captures. |
2026 | capture_iterator capture_end() const; |
2027 | |
2028 | /// Determine the number of captures in this lambda. |
2029 | unsigned capture_size() const { return LambdaExprBits.NumCaptures; } |
2030 | |
2031 | /// Retrieve this lambda's explicit captures. |
2032 | capture_range explicit_captures() const; |
2033 | |
2034 | /// Retrieve an iterator pointing to the first explicit |
2035 | /// lambda capture. |
2036 | capture_iterator explicit_capture_begin() const; |
2037 | |
2038 | /// Retrieve an iterator pointing past the end of the sequence of |
2039 | /// explicit lambda captures. |
2040 | capture_iterator explicit_capture_end() const; |
2041 | |
2042 | /// Retrieve this lambda's implicit captures. |
2043 | capture_range implicit_captures() const; |
2044 | |
2045 | /// Retrieve an iterator pointing to the first implicit |
2046 | /// lambda capture. |
2047 | capture_iterator implicit_capture_begin() const; |
2048 | |
2049 | /// Retrieve an iterator pointing past the end of the sequence of |
2050 | /// implicit lambda captures. |
2051 | capture_iterator implicit_capture_end() const; |
2052 | |
2053 | /// Iterator that walks over the capture initialization |
2054 | /// arguments. |
2055 | using capture_init_iterator = Expr **; |
2056 | |
2057 | /// Const iterator that walks over the capture initialization |
2058 | /// arguments. |
2059 | /// FIXME: This interface is prone to being used incorrectly. |
2060 | using const_capture_init_iterator = Expr *const *; |
2061 | |
2062 | /// Retrieve the initialization expressions for this lambda's captures. |
2063 | llvm::iterator_range<capture_init_iterator> capture_inits() { |
2064 | return llvm::make_range(x: capture_init_begin(), y: capture_init_end()); |
2065 | } |
2066 | |
2067 | /// Retrieve the initialization expressions for this lambda's captures. |
2068 | llvm::iterator_range<const_capture_init_iterator> capture_inits() const { |
2069 | return llvm::make_range(x: capture_init_begin(), y: capture_init_end()); |
2070 | } |
2071 | |
2072 | /// Retrieve the first initialization argument for this |
2073 | /// lambda expression (which initializes the first capture field). |
2074 | capture_init_iterator capture_init_begin() { |
2075 | return reinterpret_cast<Expr **>(getStoredStmts()); |
2076 | } |
2077 | |
2078 | /// Retrieve the first initialization argument for this |
2079 | /// lambda expression (which initializes the first capture field). |
2080 | const_capture_init_iterator capture_init_begin() const { |
2081 | return reinterpret_cast<Expr *const *>(getStoredStmts()); |
2082 | } |
2083 | |
2084 | /// Retrieve the iterator pointing one past the last |
2085 | /// initialization argument for this lambda expression. |
2086 | capture_init_iterator capture_init_end() { |
2087 | return capture_init_begin() + capture_size(); |
2088 | } |
2089 | |
2090 | /// Retrieve the iterator pointing one past the last |
2091 | /// initialization argument for this lambda expression. |
2092 | const_capture_init_iterator capture_init_end() const { |
2093 | return capture_init_begin() + capture_size(); |
2094 | } |
2095 | |
2096 | /// Retrieve the source range covering the lambda introducer, |
2097 | /// which contains the explicit capture list surrounded by square |
2098 | /// brackets ([...]). |
2099 | SourceRange getIntroducerRange() const { return IntroducerRange; } |
2100 | |
2101 | /// Retrieve the class that corresponds to the lambda. |
2102 | /// |
2103 | /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the |
2104 | /// captures in its fields and provides the various operations permitted |
2105 | /// on a lambda (copying, calling). |
2106 | CXXRecordDecl *getLambdaClass() const; |
2107 | |
2108 | /// Retrieve the function call operator associated with this |
2109 | /// lambda expression. |
2110 | CXXMethodDecl *getCallOperator() const; |
2111 | |
2112 | /// Retrieve the function template call operator associated with this |
2113 | /// lambda expression. |
2114 | FunctionTemplateDecl *getDependentCallOperator() const; |
2115 | |
2116 | /// If this is a generic lambda expression, retrieve the template |
2117 | /// parameter list associated with it, or else return null. |
2118 | TemplateParameterList *getTemplateParameterList() const; |
2119 | |
2120 | /// Get the template parameters were explicitly specified (as opposed to being |
2121 | /// invented by use of an auto parameter). |
2122 | ArrayRef<NamedDecl *> getExplicitTemplateParameters() const; |
2123 | |
2124 | /// Get the trailing requires clause, if any. |
2125 | Expr *getTrailingRequiresClause() const; |
2126 | |
2127 | /// Whether this is a generic lambda. |
2128 | bool isGenericLambda() const { return getTemplateParameterList(); } |
2129 | |
2130 | /// Retrieve the body of the lambda. This will be most of the time |
2131 | /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping |
2132 | /// a \p CompoundStmt. Note that unlike functions, lambda-expressions |
2133 | /// cannot have a function-try-block. |
2134 | Stmt *getBody() const; |
2135 | |
2136 | /// Retrieve the \p CompoundStmt representing the body of the lambda. |
2137 | /// This is a convenience function for callers who do not need |
2138 | /// to handle node(s) which may wrap a \p CompoundStmt. |
2139 | const CompoundStmt *getCompoundStmtBody() const; |
2140 | CompoundStmt *getCompoundStmtBody() { |
2141 | const auto *ConstThis = this; |
2142 | return const_cast<CompoundStmt *>(ConstThis->getCompoundStmtBody()); |
2143 | } |
2144 | |
2145 | /// Determine whether the lambda is mutable, meaning that any |
2146 | /// captures values can be modified. |
2147 | bool isMutable() const; |
2148 | |
2149 | /// Determine whether this lambda has an explicit parameter |
2150 | /// list vs. an implicit (empty) parameter list. |
2151 | bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; } |
2152 | |
2153 | /// Whether this lambda had its result type explicitly specified. |
2154 | bool hasExplicitResultType() const { |
2155 | return LambdaExprBits.ExplicitResultType; |
2156 | } |
2157 | |
2158 | static bool classof(const Stmt *T) { |
2159 | return T->getStmtClass() == LambdaExprClass; |
2160 | } |
2161 | |
2162 | SourceLocation getBeginLoc() const LLVM_READONLY { |
2163 | return IntroducerRange.getBegin(); |
2164 | } |
2165 | |
2166 | SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; } |
2167 | |
2168 | /// Includes the captures and the body of the lambda. |
2169 | child_range children(); |
2170 | const_child_range children() const; |
2171 | }; |
2172 | |
2173 | /// An expression "T()" which creates a value-initialized rvalue of type |
2174 | /// T, which is a non-class type. See (C++98 [5.2.3p2]). |
2175 | class CXXScalarValueInitExpr : public Expr { |
2176 | friend class ASTStmtReader; |
2177 | |
2178 | TypeSourceInfo *TypeInfo; |
2179 | |
2180 | public: |
2181 | /// Create an explicitly-written scalar-value initialization |
2182 | /// expression. |
2183 | CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo, |
2184 | SourceLocation RParenLoc) |
2185 | : Expr(CXXScalarValueInitExprClass, Type, VK_PRValue, OK_Ordinary), |
2186 | TypeInfo(TypeInfo) { |
2187 | CXXScalarValueInitExprBits.RParenLoc = RParenLoc; |
2188 | setDependence(computeDependence(E: this)); |
2189 | } |
2190 | |
2191 | explicit CXXScalarValueInitExpr(EmptyShell Shell) |
2192 | : Expr(CXXScalarValueInitExprClass, Shell) {} |
2193 | |
2194 | TypeSourceInfo *getTypeSourceInfo() const { |
2195 | return TypeInfo; |
2196 | } |
2197 | |
2198 | SourceLocation getRParenLoc() const { |
2199 | return CXXScalarValueInitExprBits.RParenLoc; |
2200 | } |
2201 | |
2202 | SourceLocation getBeginLoc() const LLVM_READONLY; |
2203 | SourceLocation getEndLoc() const { return getRParenLoc(); } |
2204 | |
2205 | static bool classof(const Stmt *T) { |
2206 | return T->getStmtClass() == CXXScalarValueInitExprClass; |
2207 | } |
2208 | |
2209 | // Iterators |
2210 | child_range children() { |
2211 | return child_range(child_iterator(), child_iterator()); |
2212 | } |
2213 | |
2214 | const_child_range children() const { |
2215 | return const_child_range(const_child_iterator(), const_child_iterator()); |
2216 | } |
2217 | }; |
2218 | |
2219 | enum class CXXNewInitializationStyle { |
2220 | /// New-expression has no initializer as written. |
2221 | None, |
2222 | |
2223 | /// New-expression has a C++98 paren-delimited initializer. |
2224 | Parens, |
2225 | |
2226 | /// New-expression has a C++11 list-initializer. |
2227 | Braces |
2228 | }; |
2229 | |
2230 | /// Represents a new-expression for memory allocation and constructor |
2231 | /// calls, e.g: "new CXXNewExpr(foo)". |
2232 | class CXXNewExpr final |
2233 | : public Expr, |
2234 | private llvm::TrailingObjects<CXXNewExpr, Stmt *, SourceRange> { |
2235 | friend class ASTStmtReader; |
2236 | friend class ASTStmtWriter; |
2237 | friend TrailingObjects; |
2238 | |
2239 | /// Points to the allocation function used. |
2240 | FunctionDecl *OperatorNew; |
2241 | |
2242 | /// Points to the deallocation function used in case of error. May be null. |
2243 | FunctionDecl *OperatorDelete; |
2244 | |
2245 | /// The allocated type-source information, as written in the source. |
2246 | TypeSourceInfo *AllocatedTypeInfo; |
2247 | |
2248 | /// Range of the entire new expression. |
2249 | SourceRange Range; |
2250 | |
2251 | /// Source-range of a paren-delimited initializer. |
2252 | SourceRange DirectInitRange; |
2253 | |
2254 | // CXXNewExpr is followed by several optional trailing objects. |
2255 | // They are in order: |
2256 | // |
2257 | // * An optional "Stmt *" for the array size expression. |
2258 | // Present if and ony if isArray(). |
2259 | // |
2260 | // * An optional "Stmt *" for the init expression. |
2261 | // Present if and only if hasInitializer(). |
2262 | // |
2263 | // * An array of getNumPlacementArgs() "Stmt *" for the placement new |
2264 | // arguments, if any. |
2265 | // |
2266 | // * An optional SourceRange for the range covering the parenthesized type-id |
2267 | // if the allocated type was expressed as a parenthesized type-id. |
2268 | // Present if and only if isParenTypeId(). |
2269 | unsigned arraySizeOffset() const { return 0; } |
2270 | unsigned initExprOffset() const { return arraySizeOffset() + isArray(); } |
2271 | unsigned placementNewArgsOffset() const { |
2272 | return initExprOffset() + hasInitializer(); |
2273 | } |
2274 | |
2275 | unsigned numTrailingObjects(OverloadToken<Stmt *>) const { |
2276 | return isArray() + hasInitializer() + getNumPlacementArgs(); |
2277 | } |
2278 | |
2279 | unsigned numTrailingObjects(OverloadToken<SourceRange>) const { |
2280 | return isParenTypeId(); |
2281 | } |
2282 | |
2283 | /// Build a c++ new expression. |
2284 | CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew, |
2285 | FunctionDecl *OperatorDelete, bool ShouldPassAlignment, |
2286 | bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs, |
2287 | SourceRange TypeIdParens, std::optional<Expr *> ArraySize, |
2288 | CXXNewInitializationStyle InitializationStyle, Expr *Initializer, |
2289 | QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, |
2290 | SourceRange DirectInitRange); |
2291 | |
2292 | /// Build an empty c++ new expression. |
2293 | CXXNewExpr(EmptyShell Empty, bool IsArray, unsigned NumPlacementArgs, |
2294 | bool IsParenTypeId); |
2295 | |
2296 | public: |
2297 | /// Create a c++ new expression. |
2298 | static CXXNewExpr * |
2299 | Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew, |
2300 | FunctionDecl *OperatorDelete, bool ShouldPassAlignment, |
2301 | bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs, |
2302 | SourceRange TypeIdParens, std::optional<Expr *> ArraySize, |
2303 | CXXNewInitializationStyle InitializationStyle, Expr *Initializer, |
2304 | QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, |
2305 | SourceRange DirectInitRange); |
2306 | |
2307 | /// Create an empty c++ new expression. |
2308 | static CXXNewExpr *CreateEmpty(const ASTContext &Ctx, bool IsArray, |
2309 | bool HasInit, unsigned NumPlacementArgs, |
2310 | bool IsParenTypeId); |
2311 | |
2312 | QualType getAllocatedType() const { |
2313 | return getType()->castAs<PointerType>()->getPointeeType(); |
2314 | } |
2315 | |
2316 | TypeSourceInfo *getAllocatedTypeSourceInfo() const { |
2317 | return AllocatedTypeInfo; |
2318 | } |
2319 | |
2320 | /// True if the allocation result needs to be null-checked. |
2321 | /// |
2322 | /// C++11 [expr.new]p13: |
2323 | /// If the allocation function returns null, initialization shall |
2324 | /// not be done, the deallocation function shall not be called, |
2325 | /// and the value of the new-expression shall be null. |
2326 | /// |
2327 | /// C++ DR1748: |
2328 | /// If the allocation function is a reserved placement allocation |
2329 | /// function that returns null, the behavior is undefined. |
2330 | /// |
2331 | /// An allocation function is not allowed to return null unless it |
2332 | /// has a non-throwing exception-specification. The '03 rule is |
2333 | /// identical except that the definition of a non-throwing |
2334 | /// exception specification is just "is it throw()?". |
2335 | bool shouldNullCheckAllocation() const; |
2336 | |
2337 | FunctionDecl *getOperatorNew() const { return OperatorNew; } |
2338 | void setOperatorNew(FunctionDecl *D) { OperatorNew = D; } |
2339 | FunctionDecl *getOperatorDelete() const { return OperatorDelete; } |
2340 | void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; } |
2341 | |
2342 | bool isArray() const { return CXXNewExprBits.IsArray; } |
2343 | |
2344 | /// This might return std::nullopt even if isArray() returns true, |
2345 | /// since there might not be an array size expression. |
2346 | /// If the result is not std::nullopt, it will never wrap a nullptr. |
2347 | std::optional<Expr *> getArraySize() { |
2348 | if (!isArray()) |
2349 | return std::nullopt; |
2350 | |
2351 | if (auto *Result = |
2352 | cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()])) |
2353 | return Result; |
2354 | |
2355 | return std::nullopt; |
2356 | } |
2357 | |
2358 | /// This might return std::nullopt even if isArray() returns true, |
2359 | /// since there might not be an array size expression. |
2360 | /// If the result is not std::nullopt, it will never wrap a nullptr. |
2361 | std::optional<const Expr *> getArraySize() const { |
2362 | if (!isArray()) |
2363 | return std::nullopt; |
2364 | |
2365 | if (auto *Result = |
2366 | cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()])) |
2367 | return Result; |
2368 | |
2369 | return std::nullopt; |
2370 | } |
2371 | |
2372 | unsigned getNumPlacementArgs() const { |
2373 | return CXXNewExprBits.NumPlacementArgs; |
2374 | } |
2375 | |
2376 | Expr **getPlacementArgs() { |
2377 | return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>() + |
2378 | placementNewArgsOffset()); |
2379 | } |
2380 | |
2381 | Expr *getPlacementArg(unsigned I) { |
2382 | assert((I < getNumPlacementArgs()) && "Index out of range!" ); |
2383 | return getPlacementArgs()[I]; |
2384 | } |
2385 | const Expr *getPlacementArg(unsigned I) const { |
2386 | return const_cast<CXXNewExpr *>(this)->getPlacementArg(I); |
2387 | } |
2388 | |
2389 | bool isParenTypeId() const { return CXXNewExprBits.IsParenTypeId; } |
2390 | SourceRange getTypeIdParens() const { |
2391 | return isParenTypeId() ? getTrailingObjects<SourceRange>()[0] |
2392 | : SourceRange(); |
2393 | } |
2394 | |
2395 | bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; } |
2396 | |
2397 | /// Whether this new-expression has any initializer at all. |
2398 | bool hasInitializer() const { return CXXNewExprBits.HasInitializer; } |
2399 | |
2400 | /// The kind of initializer this new-expression has. |
2401 | CXXNewInitializationStyle getInitializationStyle() const { |
2402 | return static_cast<CXXNewInitializationStyle>( |
2403 | CXXNewExprBits.StoredInitializationStyle); |
2404 | } |
2405 | |
2406 | /// The initializer of this new-expression. |
2407 | Expr *getInitializer() { |
2408 | return hasInitializer() |
2409 | ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()]) |
2410 | : nullptr; |
2411 | } |
2412 | const Expr *getInitializer() const { |
2413 | return hasInitializer() |
2414 | ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()]) |
2415 | : nullptr; |
2416 | } |
2417 | |
2418 | /// Returns the CXXConstructExpr from this new-expression, or null. |
2419 | const CXXConstructExpr *getConstructExpr() const { |
2420 | return dyn_cast_or_null<CXXConstructExpr>(Val: getInitializer()); |
2421 | } |
2422 | |
2423 | /// Indicates whether the required alignment should be implicitly passed to |
2424 | /// the allocation function. |
2425 | bool passAlignment() const { return CXXNewExprBits.ShouldPassAlignment; } |
2426 | |
2427 | /// Answers whether the usual array deallocation function for the |
2428 | /// allocated type expects the size of the allocation as a |
2429 | /// parameter. |
2430 | bool doesUsualArrayDeleteWantSize() const { |
2431 | return CXXNewExprBits.UsualArrayDeleteWantsSize; |
2432 | } |
2433 | |
2434 | using arg_iterator = ExprIterator; |
2435 | using const_arg_iterator = ConstExprIterator; |
2436 | |
2437 | llvm::iterator_range<arg_iterator> placement_arguments() { |
2438 | return llvm::make_range(placement_arg_begin(), placement_arg_end()); |
2439 | } |
2440 | |
2441 | llvm::iterator_range<const_arg_iterator> placement_arguments() const { |
2442 | return llvm::make_range(placement_arg_begin(), placement_arg_end()); |
2443 | } |
2444 | |
2445 | arg_iterator placement_arg_begin() { |
2446 | return getTrailingObjects<Stmt *>() + placementNewArgsOffset(); |
2447 | } |
2448 | arg_iterator placement_arg_end() { |
2449 | return placement_arg_begin() + getNumPlacementArgs(); |
2450 | } |
2451 | const_arg_iterator placement_arg_begin() const { |
2452 | return getTrailingObjects<Stmt *>() + placementNewArgsOffset(); |
2453 | } |
2454 | const_arg_iterator placement_arg_end() const { |
2455 | return placement_arg_begin() + getNumPlacementArgs(); |
2456 | } |
2457 | |
2458 | using raw_arg_iterator = Stmt **; |
2459 | |
2460 | raw_arg_iterator raw_arg_begin() { return getTrailingObjects<Stmt *>(); } |
2461 | raw_arg_iterator raw_arg_end() { |
2462 | return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>()); |
2463 | } |
2464 | const_arg_iterator raw_arg_begin() const { |
2465 | return getTrailingObjects<Stmt *>(); |
2466 | } |
2467 | const_arg_iterator raw_arg_end() const { |
2468 | return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>()); |
2469 | } |
2470 | |
2471 | SourceLocation getBeginLoc() const { return Range.getBegin(); } |
2472 | SourceLocation getEndLoc() const { return Range.getEnd(); } |
2473 | |
2474 | SourceRange getDirectInitRange() const { return DirectInitRange; } |
2475 | SourceRange getSourceRange() const { return Range; } |
2476 | |
2477 | static bool classof(const Stmt *T) { |
2478 | return T->getStmtClass() == CXXNewExprClass; |
2479 | } |
2480 | |
2481 | // Iterators |
2482 | child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); } |
2483 | |
2484 | const_child_range children() const { |
2485 | return const_child_range(const_cast<CXXNewExpr *>(this)->children()); |
2486 | } |
2487 | }; |
2488 | |
2489 | /// Represents a \c delete expression for memory deallocation and |
2490 | /// destructor calls, e.g. "delete[] pArray". |
2491 | class CXXDeleteExpr : public Expr { |
2492 | friend class ASTStmtReader; |
2493 | |
2494 | /// Points to the operator delete overload that is used. Could be a member. |
2495 | FunctionDecl *OperatorDelete = nullptr; |
2496 | |
2497 | /// The pointer expression to be deleted. |
2498 | Stmt *Argument = nullptr; |
2499 | |
2500 | public: |
2501 | CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm, |
2502 | bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize, |
2503 | FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc) |
2504 | : Expr(CXXDeleteExprClass, Ty, VK_PRValue, OK_Ordinary), |
2505 | OperatorDelete(OperatorDelete), Argument(Arg) { |
2506 | CXXDeleteExprBits.GlobalDelete = GlobalDelete; |
2507 | CXXDeleteExprBits.ArrayForm = ArrayForm; |
2508 | CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten; |
2509 | CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize; |
2510 | CXXDeleteExprBits.Loc = Loc; |
2511 | setDependence(computeDependence(E: this)); |
2512 | } |
2513 | |
2514 | explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {} |
2515 | |
2516 | bool isGlobalDelete() const { return CXXDeleteExprBits.GlobalDelete; } |
2517 | bool isArrayForm() const { return CXXDeleteExprBits.ArrayForm; } |
2518 | bool isArrayFormAsWritten() const { |
2519 | return CXXDeleteExprBits.ArrayFormAsWritten; |
2520 | } |
2521 | |
2522 | /// Answers whether the usual array deallocation function for the |
2523 | /// allocated type expects the size of the allocation as a |
2524 | /// parameter. This can be true even if the actual deallocation |
2525 | /// function that we're using doesn't want a size. |
2526 | bool doesUsualArrayDeleteWantSize() const { |
2527 | return CXXDeleteExprBits.UsualArrayDeleteWantsSize; |
2528 | } |
2529 | |
2530 | FunctionDecl *getOperatorDelete() const { return OperatorDelete; } |
2531 | |
2532 | Expr *getArgument() { return cast<Expr>(Val: Argument); } |
2533 | const Expr *getArgument() const { return cast<Expr>(Val: Argument); } |
2534 | |
2535 | /// Retrieve the type being destroyed. |
2536 | /// |
2537 | /// If the type being destroyed is a dependent type which may or may not |
2538 | /// be a pointer, return an invalid type. |
2539 | QualType getDestroyedType() const; |
2540 | |
2541 | SourceLocation getBeginLoc() const { return CXXDeleteExprBits.Loc; } |
2542 | SourceLocation getEndLoc() const LLVM_READONLY { |
2543 | return Argument->getEndLoc(); |
2544 | } |
2545 | |
2546 | static bool classof(const Stmt *T) { |
2547 | return T->getStmtClass() == CXXDeleteExprClass; |
2548 | } |
2549 | |
2550 | // Iterators |
2551 | child_range children() { return child_range(&Argument, &Argument + 1); } |
2552 | |
2553 | const_child_range children() const { |
2554 | return const_child_range(&Argument, &Argument + 1); |
2555 | } |
2556 | }; |
2557 | |
2558 | /// Stores the type being destroyed by a pseudo-destructor expression. |
2559 | class PseudoDestructorTypeStorage { |
2560 | /// Either the type source information or the name of the type, if |
2561 | /// it couldn't be resolved due to type-dependence. |
2562 | llvm::PointerUnion<TypeSourceInfo *, const IdentifierInfo *> Type; |
2563 | |
2564 | /// The starting source location of the pseudo-destructor type. |
2565 | SourceLocation Location; |
2566 | |
2567 | public: |
2568 | PseudoDestructorTypeStorage() = default; |
2569 | |
2570 | PseudoDestructorTypeStorage(const IdentifierInfo *II, SourceLocation Loc) |
2571 | : Type(II), Location(Loc) {} |
2572 | |
2573 | PseudoDestructorTypeStorage(TypeSourceInfo *Info); |
2574 | |
2575 | TypeSourceInfo *getTypeSourceInfo() const { |
2576 | return Type.dyn_cast<TypeSourceInfo *>(); |
2577 | } |
2578 | |
2579 | const IdentifierInfo *getIdentifier() const { |
2580 | return Type.dyn_cast<const IdentifierInfo *>(); |
2581 | } |
2582 | |
2583 | SourceLocation getLocation() const { return Location; } |
2584 | }; |
2585 | |
2586 | /// Represents a C++ pseudo-destructor (C++ [expr.pseudo]). |
2587 | /// |
2588 | /// A pseudo-destructor is an expression that looks like a member access to a |
2589 | /// destructor of a scalar type, except that scalar types don't have |
2590 | /// destructors. For example: |
2591 | /// |
2592 | /// \code |
2593 | /// typedef int T; |
2594 | /// void f(int *p) { |
2595 | /// p->T::~T(); |
2596 | /// } |
2597 | /// \endcode |
2598 | /// |
2599 | /// Pseudo-destructors typically occur when instantiating templates such as: |
2600 | /// |
2601 | /// \code |
2602 | /// template<typename T> |
2603 | /// void destroy(T* ptr) { |
2604 | /// ptr->T::~T(); |
2605 | /// } |
2606 | /// \endcode |
2607 | /// |
2608 | /// for scalar types. A pseudo-destructor expression has no run-time semantics |
2609 | /// beyond evaluating the base expression. |
2610 | class CXXPseudoDestructorExpr : public Expr { |
2611 | friend class ASTStmtReader; |
2612 | |
2613 | /// The base expression (that is being destroyed). |
2614 | Stmt *Base = nullptr; |
2615 | |
2616 | /// Whether the operator was an arrow ('->'); otherwise, it was a |
2617 | /// period ('.'). |
2618 | LLVM_PREFERRED_TYPE(bool) |
2619 | bool IsArrow : 1; |
2620 | |
2621 | /// The location of the '.' or '->' operator. |
2622 | SourceLocation OperatorLoc; |
2623 | |
2624 | /// The nested-name-specifier that follows the operator, if present. |
2625 | NestedNameSpecifierLoc QualifierLoc; |
2626 | |
2627 | /// The type that precedes the '::' in a qualified pseudo-destructor |
2628 | /// expression. |
2629 | TypeSourceInfo *ScopeType = nullptr; |
2630 | |
2631 | /// The location of the '::' in a qualified pseudo-destructor |
2632 | /// expression. |
2633 | SourceLocation ColonColonLoc; |
2634 | |
2635 | /// The location of the '~'. |
2636 | SourceLocation TildeLoc; |
2637 | |
2638 | /// The type being destroyed, or its name if we were unable to |
2639 | /// resolve the name. |
2640 | PseudoDestructorTypeStorage DestroyedType; |
2641 | |
2642 | public: |
2643 | CXXPseudoDestructorExpr(const ASTContext &Context, |
2644 | Expr *Base, bool isArrow, SourceLocation OperatorLoc, |
2645 | NestedNameSpecifierLoc QualifierLoc, |
2646 | TypeSourceInfo *ScopeType, |
2647 | SourceLocation ColonColonLoc, |
2648 | SourceLocation TildeLoc, |
2649 | PseudoDestructorTypeStorage DestroyedType); |
2650 | |
2651 | explicit CXXPseudoDestructorExpr(EmptyShell Shell) |
2652 | : Expr(CXXPseudoDestructorExprClass, Shell), IsArrow(false) {} |
2653 | |
2654 | Expr *getBase() const { return cast<Expr>(Val: Base); } |
2655 | |
2656 | /// Determines whether this member expression actually had |
2657 | /// a C++ nested-name-specifier prior to the name of the member, e.g., |
2658 | /// x->Base::foo. |
2659 | bool hasQualifier() const { return QualifierLoc.hasQualifier(); } |
2660 | |
2661 | /// Retrieves the nested-name-specifier that qualifies the type name, |
2662 | /// with source-location information. |
2663 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
2664 | |
2665 | /// If the member name was qualified, retrieves the |
2666 | /// nested-name-specifier that precedes the member name. Otherwise, returns |
2667 | /// null. |
2668 | NestedNameSpecifier *getQualifier() const { |
2669 | return QualifierLoc.getNestedNameSpecifier(); |
2670 | } |
2671 | |
2672 | /// Determine whether this pseudo-destructor expression was written |
2673 | /// using an '->' (otherwise, it used a '.'). |
2674 | bool isArrow() const { return IsArrow; } |
2675 | |
2676 | /// Retrieve the location of the '.' or '->' operator. |
2677 | SourceLocation getOperatorLoc() const { return OperatorLoc; } |
2678 | |
2679 | /// Retrieve the scope type in a qualified pseudo-destructor |
2680 | /// expression. |
2681 | /// |
2682 | /// Pseudo-destructor expressions can have extra qualification within them |
2683 | /// that is not part of the nested-name-specifier, e.g., \c p->T::~T(). |
2684 | /// Here, if the object type of the expression is (or may be) a scalar type, |
2685 | /// \p T may also be a scalar type and, therefore, cannot be part of a |
2686 | /// nested-name-specifier. It is stored as the "scope type" of the pseudo- |
2687 | /// destructor expression. |
2688 | TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; } |
2689 | |
2690 | /// Retrieve the location of the '::' in a qualified pseudo-destructor |
2691 | /// expression. |
2692 | SourceLocation getColonColonLoc() const { return ColonColonLoc; } |
2693 | |
2694 | /// Retrieve the location of the '~'. |
2695 | SourceLocation getTildeLoc() const { return TildeLoc; } |
2696 | |
2697 | /// Retrieve the source location information for the type |
2698 | /// being destroyed. |
2699 | /// |
2700 | /// This type-source information is available for non-dependent |
2701 | /// pseudo-destructor expressions and some dependent pseudo-destructor |
2702 | /// expressions. Returns null if we only have the identifier for a |
2703 | /// dependent pseudo-destructor expression. |
2704 | TypeSourceInfo *getDestroyedTypeInfo() const { |
2705 | return DestroyedType.getTypeSourceInfo(); |
2706 | } |
2707 | |
2708 | /// In a dependent pseudo-destructor expression for which we do not |
2709 | /// have full type information on the destroyed type, provides the name |
2710 | /// of the destroyed type. |
2711 | const IdentifierInfo *getDestroyedTypeIdentifier() const { |
2712 | return DestroyedType.getIdentifier(); |
2713 | } |
2714 | |
2715 | /// Retrieve the type being destroyed. |
2716 | QualType getDestroyedType() const; |
2717 | |
2718 | /// Retrieve the starting location of the type being destroyed. |
2719 | SourceLocation getDestroyedTypeLoc() const { |
2720 | return DestroyedType.getLocation(); |
2721 | } |
2722 | |
2723 | /// Set the name of destroyed type for a dependent pseudo-destructor |
2724 | /// expression. |
2725 | void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) { |
2726 | DestroyedType = PseudoDestructorTypeStorage(II, Loc); |
2727 | } |
2728 | |
2729 | /// Set the destroyed type. |
2730 | void setDestroyedType(TypeSourceInfo *Info) { |
2731 | DestroyedType = PseudoDestructorTypeStorage(Info); |
2732 | } |
2733 | |
2734 | SourceLocation getBeginLoc() const LLVM_READONLY { |
2735 | return Base->getBeginLoc(); |
2736 | } |
2737 | SourceLocation getEndLoc() const LLVM_READONLY; |
2738 | |
2739 | static bool classof(const Stmt *T) { |
2740 | return T->getStmtClass() == CXXPseudoDestructorExprClass; |
2741 | } |
2742 | |
2743 | // Iterators |
2744 | child_range children() { return child_range(&Base, &Base + 1); } |
2745 | |
2746 | const_child_range children() const { |
2747 | return const_child_range(&Base, &Base + 1); |
2748 | } |
2749 | }; |
2750 | |
2751 | /// A type trait used in the implementation of various C++11 and |
2752 | /// Library TR1 trait templates. |
2753 | /// |
2754 | /// \code |
2755 | /// __is_pod(int) == true |
2756 | /// __is_enum(std::string) == false |
2757 | /// __is_trivially_constructible(vector<int>, int*, int*) |
2758 | /// \endcode |
2759 | class TypeTraitExpr final |
2760 | : public Expr, |
2761 | private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> { |
2762 | /// The location of the type trait keyword. |
2763 | SourceLocation Loc; |
2764 | |
2765 | /// The location of the closing parenthesis. |
2766 | SourceLocation RParenLoc; |
2767 | |
2768 | // Note: The TypeSourceInfos for the arguments are allocated after the |
2769 | // TypeTraitExpr. |
2770 | |
2771 | TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind, |
2772 | ArrayRef<TypeSourceInfo *> Args, |
2773 | SourceLocation RParenLoc, |
2774 | bool Value); |
2775 | |
2776 | TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {} |
2777 | |
2778 | size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const { |
2779 | return getNumArgs(); |
2780 | } |
2781 | |
2782 | public: |
2783 | friend class ASTStmtReader; |
2784 | friend class ASTStmtWriter; |
2785 | friend TrailingObjects; |
2786 | |
2787 | /// Create a new type trait expression. |
2788 | static TypeTraitExpr *Create(const ASTContext &C, QualType T, |
2789 | SourceLocation Loc, TypeTrait Kind, |
2790 | ArrayRef<TypeSourceInfo *> Args, |
2791 | SourceLocation RParenLoc, |
2792 | bool Value); |
2793 | |
2794 | static TypeTraitExpr *CreateDeserialized(const ASTContext &C, |
2795 | unsigned NumArgs); |
2796 | |
2797 | /// Determine which type trait this expression uses. |
2798 | TypeTrait getTrait() const { |
2799 | return static_cast<TypeTrait>(TypeTraitExprBits.Kind); |
2800 | } |
2801 | |
2802 | bool getValue() const { |
2803 | assert(!isValueDependent()); |
2804 | return TypeTraitExprBits.Value; |
2805 | } |
2806 | |
2807 | /// Determine the number of arguments to this type trait. |
2808 | unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; } |
2809 | |
2810 | /// Retrieve the Ith argument. |
2811 | TypeSourceInfo *getArg(unsigned I) const { |
2812 | assert(I < getNumArgs() && "Argument out-of-range" ); |
2813 | return getArgs()[I]; |
2814 | } |
2815 | |
2816 | /// Retrieve the argument types. |
2817 | ArrayRef<TypeSourceInfo *> getArgs() const { |
2818 | return llvm::ArrayRef(getTrailingObjects<TypeSourceInfo *>(), getNumArgs()); |
2819 | } |
2820 | |
2821 | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
2822 | SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } |
2823 | |
2824 | static bool classof(const Stmt *T) { |
2825 | return T->getStmtClass() == TypeTraitExprClass; |
2826 | } |
2827 | |
2828 | // Iterators |
2829 | child_range children() { |
2830 | return child_range(child_iterator(), child_iterator()); |
2831 | } |
2832 | |
2833 | const_child_range children() const { |
2834 | return const_child_range(const_child_iterator(), const_child_iterator()); |
2835 | } |
2836 | }; |
2837 | |
2838 | /// An Embarcadero array type trait, as used in the implementation of |
2839 | /// __array_rank and __array_extent. |
2840 | /// |
2841 | /// Example: |
2842 | /// \code |
2843 | /// __array_rank(int[10][20]) == 2 |
2844 | /// __array_extent(int, 1) == 20 |
2845 | /// \endcode |
2846 | class ArrayTypeTraitExpr : public Expr { |
2847 | /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned. |
2848 | LLVM_PREFERRED_TYPE(ArrayTypeTrait) |
2849 | unsigned ATT : 2; |
2850 | |
2851 | /// The value of the type trait. Unspecified if dependent. |
2852 | uint64_t Value = 0; |
2853 | |
2854 | /// The array dimension being queried, or -1 if not used. |
2855 | Expr *Dimension; |
2856 | |
2857 | /// The location of the type trait keyword. |
2858 | SourceLocation Loc; |
2859 | |
2860 | /// The location of the closing paren. |
2861 | SourceLocation RParen; |
2862 | |
2863 | /// The type being queried. |
2864 | TypeSourceInfo *QueriedType = nullptr; |
2865 | |
2866 | public: |
2867 | friend class ASTStmtReader; |
2868 | |
2869 | ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att, |
2870 | TypeSourceInfo *queried, uint64_t value, Expr *dimension, |
2871 | SourceLocation rparen, QualType ty) |
2872 | : Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary), ATT(att), |
2873 | Value(value), Dimension(dimension), Loc(loc), RParen(rparen), |
2874 | QueriedType(queried) { |
2875 | assert(att <= ATT_Last && "invalid enum value!" ); |
2876 | assert(static_cast<unsigned>(att) == ATT && "ATT overflow!" ); |
2877 | setDependence(computeDependence(E: this)); |
2878 | } |
2879 | |
2880 | explicit ArrayTypeTraitExpr(EmptyShell Empty) |
2881 | : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {} |
2882 | |
2883 | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
2884 | SourceLocation getEndLoc() const LLVM_READONLY { return RParen; } |
2885 | |
2886 | ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); } |
2887 | |
2888 | QualType getQueriedType() const { return QueriedType->getType(); } |
2889 | |
2890 | TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; } |
2891 | |
2892 | uint64_t getValue() const { assert(!isTypeDependent()); return Value; } |
2893 | |
2894 | Expr *getDimensionExpression() const { return Dimension; } |
2895 | |
2896 | static bool classof(const Stmt *T) { |
2897 | return T->getStmtClass() == ArrayTypeTraitExprClass; |
2898 | } |
2899 | |
2900 | // Iterators |
2901 | child_range children() { |
2902 | return child_range(child_iterator(), child_iterator()); |
2903 | } |
2904 | |
2905 | const_child_range children() const { |
2906 | return const_child_range(const_child_iterator(), const_child_iterator()); |
2907 | } |
2908 | }; |
2909 | |
2910 | /// An expression trait intrinsic. |
2911 | /// |
2912 | /// Example: |
2913 | /// \code |
2914 | /// __is_lvalue_expr(std::cout) == true |
2915 | /// __is_lvalue_expr(1) == false |
2916 | /// \endcode |
2917 | class ExpressionTraitExpr : public Expr { |
2918 | /// The trait. A ExpressionTrait enum in MSVC compatible unsigned. |
2919 | LLVM_PREFERRED_TYPE(ExpressionTrait) |
2920 | unsigned ET : 31; |
2921 | |
2922 | /// The value of the type trait. Unspecified if dependent. |
2923 | LLVM_PREFERRED_TYPE(bool) |
2924 | unsigned Value : 1; |
2925 | |
2926 | /// The location of the type trait keyword. |
2927 | SourceLocation Loc; |
2928 | |
2929 | /// The location of the closing paren. |
2930 | SourceLocation RParen; |
2931 | |
2932 | /// The expression being queried. |
2933 | Expr* QueriedExpression = nullptr; |
2934 | |
2935 | public: |
2936 | friend class ASTStmtReader; |
2937 | |
2938 | ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried, |
2939 | bool value, SourceLocation rparen, QualType resultType) |
2940 | : Expr(ExpressionTraitExprClass, resultType, VK_PRValue, OK_Ordinary), |
2941 | ET(et), Value(value), Loc(loc), RParen(rparen), |
2942 | QueriedExpression(queried) { |
2943 | assert(et <= ET_Last && "invalid enum value!" ); |
2944 | assert(static_cast<unsigned>(et) == ET && "ET overflow!" ); |
2945 | setDependence(computeDependence(E: this)); |
2946 | } |
2947 | |
2948 | explicit ExpressionTraitExpr(EmptyShell Empty) |
2949 | : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {} |
2950 | |
2951 | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
2952 | SourceLocation getEndLoc() const LLVM_READONLY { return RParen; } |
2953 | |
2954 | ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); } |
2955 | |
2956 | Expr *getQueriedExpression() const { return QueriedExpression; } |
2957 | |
2958 | bool getValue() const { return Value; } |
2959 | |
2960 | static bool classof(const Stmt *T) { |
2961 | return T->getStmtClass() == ExpressionTraitExprClass; |
2962 | } |
2963 | |
2964 | // Iterators |
2965 | child_range children() { |
2966 | return child_range(child_iterator(), child_iterator()); |
2967 | } |
2968 | |
2969 | const_child_range children() const { |
2970 | return const_child_range(const_child_iterator(), const_child_iterator()); |
2971 | } |
2972 | }; |
2973 | |
2974 | /// A reference to an overloaded function set, either an |
2975 | /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr. |
2976 | class OverloadExpr : public Expr { |
2977 | friend class ASTStmtReader; |
2978 | friend class ASTStmtWriter; |
2979 | |
2980 | /// The common name of these declarations. |
2981 | DeclarationNameInfo NameInfo; |
2982 | |
2983 | /// The nested-name-specifier that qualifies the name, if any. |
2984 | NestedNameSpecifierLoc QualifierLoc; |
2985 | |
2986 | protected: |
2987 | OverloadExpr(StmtClass SC, const ASTContext &Context, |
2988 | NestedNameSpecifierLoc QualifierLoc, |
2989 | SourceLocation TemplateKWLoc, |
2990 | const DeclarationNameInfo &NameInfo, |
2991 | const TemplateArgumentListInfo *TemplateArgs, |
2992 | UnresolvedSetIterator Begin, UnresolvedSetIterator End, |
2993 | bool KnownDependent, bool KnownInstantiationDependent, |
2994 | bool KnownContainsUnexpandedParameterPack); |
2995 | |
2996 | OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults, |
2997 | bool HasTemplateKWAndArgsInfo); |
2998 | |
2999 | /// Return the results. Defined after UnresolvedMemberExpr. |
3000 | inline DeclAccessPair *getTrailingResults(); |
3001 | const DeclAccessPair *getTrailingResults() const { |
3002 | return const_cast<OverloadExpr *>(this)->getTrailingResults(); |
3003 | } |
3004 | |
3005 | /// Return the optional template keyword and arguments info. |
3006 | /// Defined after UnresolvedMemberExpr. |
3007 | inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo(); |
3008 | const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const { |
3009 | return const_cast<OverloadExpr *>(this) |
3010 | ->getTrailingASTTemplateKWAndArgsInfo(); |
3011 | } |
3012 | |
3013 | /// Return the optional template arguments. Defined after |
3014 | /// UnresolvedMemberExpr. |
3015 | inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); |
3016 | const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const { |
3017 | return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc(); |
3018 | } |
3019 | |
3020 | bool hasTemplateKWAndArgsInfo() const { |
3021 | return OverloadExprBits.HasTemplateKWAndArgsInfo; |
3022 | } |
3023 | |
3024 | public: |
3025 | struct FindResult { |
3026 | OverloadExpr *Expression; |
3027 | bool IsAddressOfOperand; |
3028 | bool HasFormOfMemberPointer; |
3029 | }; |
3030 | |
3031 | /// Finds the overloaded expression in the given expression \p E of |
3032 | /// OverloadTy. |
3033 | /// |
3034 | /// \return the expression (which must be there) and true if it has |
3035 | /// the particular form of a member pointer expression |
3036 | static FindResult find(Expr *E) { |
3037 | assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload)); |
3038 | |
3039 | FindResult Result; |
3040 | |
3041 | E = E->IgnoreParens(); |
3042 | if (isa<UnaryOperator>(Val: E)) { |
3043 | assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf); |
3044 | E = cast<UnaryOperator>(Val: E)->getSubExpr(); |
3045 | auto *Ovl = cast<OverloadExpr>(Val: E->IgnoreParens()); |
3046 | |
3047 | Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier()); |
3048 | Result.IsAddressOfOperand = true; |
3049 | Result.Expression = Ovl; |
3050 | } else { |
3051 | Result.HasFormOfMemberPointer = false; |
3052 | Result.IsAddressOfOperand = false; |
3053 | Result.Expression = cast<OverloadExpr>(Val: E); |
3054 | } |
3055 | |
3056 | return Result; |
3057 | } |
3058 | |
3059 | /// Gets the naming class of this lookup, if any. |
3060 | /// Defined after UnresolvedMemberExpr. |
3061 | inline CXXRecordDecl *getNamingClass(); |
3062 | const CXXRecordDecl *getNamingClass() const { |
3063 | return const_cast<OverloadExpr *>(this)->getNamingClass(); |
3064 | } |
3065 | |
3066 | using decls_iterator = UnresolvedSetImpl::iterator; |
3067 | |
3068 | decls_iterator decls_begin() const { |
3069 | return UnresolvedSetIterator(getTrailingResults()); |
3070 | } |
3071 | decls_iterator decls_end() const { |
3072 | return UnresolvedSetIterator(getTrailingResults() + getNumDecls()); |
3073 | } |
3074 | llvm::iterator_range<decls_iterator> decls() const { |
3075 | return llvm::make_range(x: decls_begin(), y: decls_end()); |
3076 | } |
3077 | |
3078 | /// Gets the number of declarations in the unresolved set. |
3079 | unsigned getNumDecls() const { return OverloadExprBits.NumResults; } |
3080 | |
3081 | /// Gets the full name info. |
3082 | const DeclarationNameInfo &getNameInfo() const { return NameInfo; } |
3083 | |
3084 | /// Gets the name looked up. |
3085 | DeclarationName getName() const { return NameInfo.getName(); } |
3086 | |
3087 | /// Gets the location of the name. |
3088 | SourceLocation getNameLoc() const { return NameInfo.getLoc(); } |
3089 | |
3090 | /// Fetches the nested-name qualifier, if one was given. |
3091 | NestedNameSpecifier *getQualifier() const { |
3092 | return QualifierLoc.getNestedNameSpecifier(); |
3093 | } |
3094 | |
3095 | /// Fetches the nested-name qualifier with source-location |
3096 | /// information, if one was given. |
3097 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
3098 | |
3099 | /// Retrieve the location of the template keyword preceding |
3100 | /// this name, if any. |
3101 | SourceLocation getTemplateKeywordLoc() const { |
3102 | if (!hasTemplateKWAndArgsInfo()) |
3103 | return SourceLocation(); |
3104 | return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc; |
3105 | } |
3106 | |
3107 | /// Retrieve the location of the left angle bracket starting the |
3108 | /// explicit template argument list following the name, if any. |
3109 | SourceLocation getLAngleLoc() const { |
3110 | if (!hasTemplateKWAndArgsInfo()) |
3111 | return SourceLocation(); |
3112 | return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc; |
3113 | } |
3114 | |
3115 | /// Retrieve the location of the right angle bracket ending the |
3116 | /// explicit template argument list following the name, if any. |
3117 | SourceLocation getRAngleLoc() const { |
3118 | if (!hasTemplateKWAndArgsInfo()) |
3119 | return SourceLocation(); |
3120 | return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc; |
3121 | } |
3122 | |
3123 | /// Determines whether the name was preceded by the template keyword. |
3124 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } |
3125 | |
3126 | /// Determines whether this expression had explicit template arguments. |
3127 | bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } |
3128 | |
3129 | TemplateArgumentLoc const *getTemplateArgs() const { |
3130 | if (!hasExplicitTemplateArgs()) |
3131 | return nullptr; |
3132 | return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc(); |
3133 | } |
3134 | |
3135 | unsigned getNumTemplateArgs() const { |
3136 | if (!hasExplicitTemplateArgs()) |
3137 | return 0; |
3138 | |
3139 | return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs; |
3140 | } |
3141 | |
3142 | ArrayRef<TemplateArgumentLoc> template_arguments() const { |
3143 | return {getTemplateArgs(), getNumTemplateArgs()}; |
3144 | } |
3145 | |
3146 | /// Copies the template arguments into the given structure. |
3147 | void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { |
3148 | if (hasExplicitTemplateArgs()) |
3149 | getTrailingASTTemplateKWAndArgsInfo()->copyInto(ArgArray: getTemplateArgs(), List); |
3150 | } |
3151 | |
3152 | static bool classof(const Stmt *T) { |
3153 | return T->getStmtClass() == UnresolvedLookupExprClass || |
3154 | T->getStmtClass() == UnresolvedMemberExprClass; |
3155 | } |
3156 | }; |
3157 | |
3158 | /// A reference to a name which we were able to look up during |
3159 | /// parsing but could not resolve to a specific declaration. |
3160 | /// |
3161 | /// This arises in several ways: |
3162 | /// * we might be waiting for argument-dependent lookup; |
3163 | /// * the name might resolve to an overloaded function; |
3164 | /// and eventually: |
3165 | /// * the lookup might have included a function template. |
3166 | /// |
3167 | /// These never include UnresolvedUsingValueDecls, which are always class |
3168 | /// members and therefore appear only in UnresolvedMemberLookupExprs. |
3169 | class UnresolvedLookupExpr final |
3170 | : public OverloadExpr, |
3171 | private llvm::TrailingObjects<UnresolvedLookupExpr, DeclAccessPair, |
3172 | ASTTemplateKWAndArgsInfo, |
3173 | TemplateArgumentLoc> { |
3174 | friend class ASTStmtReader; |
3175 | friend class OverloadExpr; |
3176 | friend TrailingObjects; |
3177 | |
3178 | /// The naming class (C++ [class.access.base]p5) of the lookup, if |
3179 | /// any. This can generally be recalculated from the context chain, |
3180 | /// but that can be fairly expensive for unqualified lookups. |
3181 | CXXRecordDecl *NamingClass; |
3182 | |
3183 | // UnresolvedLookupExpr is followed by several trailing objects. |
3184 | // They are in order: |
3185 | // |
3186 | // * An array of getNumResults() DeclAccessPair for the results. These are |
3187 | // undesugared, which is to say, they may include UsingShadowDecls. |
3188 | // Access is relative to the naming class. |
3189 | // |
3190 | // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified |
3191 | // template keyword and arguments. Present if and only if |
3192 | // hasTemplateKWAndArgsInfo(). |
3193 | // |
3194 | // * An array of getNumTemplateArgs() TemplateArgumentLoc containing |
3195 | // location information for the explicitly specified template arguments. |
3196 | |
3197 | UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass, |
3198 | NestedNameSpecifierLoc QualifierLoc, |
3199 | SourceLocation TemplateKWLoc, |
3200 | const DeclarationNameInfo &NameInfo, bool RequiresADL, |
3201 | const TemplateArgumentListInfo *TemplateArgs, |
3202 | UnresolvedSetIterator Begin, UnresolvedSetIterator End, |
3203 | bool KnownDependent); |
3204 | |
3205 | UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults, |
3206 | bool HasTemplateKWAndArgsInfo); |
3207 | |
3208 | unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const { |
3209 | return getNumDecls(); |
3210 | } |
3211 | |
3212 | unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { |
3213 | return hasTemplateKWAndArgsInfo(); |
3214 | } |
3215 | |
3216 | public: |
3217 | static UnresolvedLookupExpr * |
3218 | Create(const ASTContext &Context, CXXRecordDecl *NamingClass, |
3219 | NestedNameSpecifierLoc QualifierLoc, |
3220 | const DeclarationNameInfo &NameInfo, bool RequiresADL, |
3221 | UnresolvedSetIterator Begin, UnresolvedSetIterator End, |
3222 | bool KnownDependent); |
3223 | |
3224 | // After canonicalization, there may be dependent template arguments in |
3225 | // CanonicalConverted But none of Args is dependent. When any of |
3226 | // CanonicalConverted dependent, KnownDependent is true. |
3227 | static UnresolvedLookupExpr * |
3228 | Create(const ASTContext &Context, CXXRecordDecl *NamingClass, |
3229 | NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, |
3230 | const DeclarationNameInfo &NameInfo, bool RequiresADL, |
3231 | const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin, |
3232 | UnresolvedSetIterator End, bool KnownDependent); |
3233 | |
3234 | static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context, |
3235 | unsigned NumResults, |
3236 | bool HasTemplateKWAndArgsInfo, |
3237 | unsigned NumTemplateArgs); |
3238 | |
3239 | /// True if this declaration should be extended by |
3240 | /// argument-dependent lookup. |
3241 | bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; } |
3242 | |
3243 | /// Gets the 'naming class' (in the sense of C++0x |
3244 | /// [class.access.base]p5) of the lookup. This is the scope |
3245 | /// that was looked in to find these results. |
3246 | CXXRecordDecl *getNamingClass() { return NamingClass; } |
3247 | const CXXRecordDecl *getNamingClass() const { return NamingClass; } |
3248 | |
3249 | SourceLocation getBeginLoc() const LLVM_READONLY { |
3250 | if (NestedNameSpecifierLoc l = getQualifierLoc()) |
3251 | return l.getBeginLoc(); |
3252 | return getNameInfo().getBeginLoc(); |
3253 | } |
3254 | |
3255 | SourceLocation getEndLoc() const LLVM_READONLY { |
3256 | if (hasExplicitTemplateArgs()) |
3257 | return getRAngleLoc(); |
3258 | return getNameInfo().getEndLoc(); |
3259 | } |
3260 | |
3261 | child_range children() { |
3262 | return child_range(child_iterator(), child_iterator()); |
3263 | } |
3264 | |
3265 | const_child_range children() const { |
3266 | return const_child_range(const_child_iterator(), const_child_iterator()); |
3267 | } |
3268 | |
3269 | static bool classof(const Stmt *T) { |
3270 | return T->getStmtClass() == UnresolvedLookupExprClass; |
3271 | } |
3272 | }; |
3273 | |
3274 | /// A qualified reference to a name whose declaration cannot |
3275 | /// yet be resolved. |
3276 | /// |
3277 | /// DependentScopeDeclRefExpr is similar to DeclRefExpr in that |
3278 | /// it expresses a reference to a declaration such as |
3279 | /// X<T>::value. The difference, however, is that an |
3280 | /// DependentScopeDeclRefExpr node is used only within C++ templates when |
3281 | /// the qualification (e.g., X<T>::) refers to a dependent type. In |
3282 | /// this case, X<T>::value cannot resolve to a declaration because the |
3283 | /// declaration will differ from one instantiation of X<T> to the |
3284 | /// next. Therefore, DependentScopeDeclRefExpr keeps track of the |
3285 | /// qualifier (X<T>::) and the name of the entity being referenced |
3286 | /// ("value"). Such expressions will instantiate to a DeclRefExpr once the |
3287 | /// declaration can be found. |
3288 | class DependentScopeDeclRefExpr final |
3289 | : public Expr, |
3290 | private llvm::TrailingObjects<DependentScopeDeclRefExpr, |
3291 | ASTTemplateKWAndArgsInfo, |
3292 | TemplateArgumentLoc> { |
3293 | friend class ASTStmtReader; |
3294 | friend class ASTStmtWriter; |
3295 | friend TrailingObjects; |
3296 | |
3297 | /// The nested-name-specifier that qualifies this unresolved |
3298 | /// declaration name. |
3299 | NestedNameSpecifierLoc QualifierLoc; |
3300 | |
3301 | /// The name of the entity we will be referencing. |
3302 | DeclarationNameInfo NameInfo; |
3303 | |
3304 | DependentScopeDeclRefExpr(QualType Ty, NestedNameSpecifierLoc QualifierLoc, |
3305 | SourceLocation TemplateKWLoc, |
3306 | const DeclarationNameInfo &NameInfo, |
3307 | const TemplateArgumentListInfo *Args); |
3308 | |
3309 | size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { |
3310 | return hasTemplateKWAndArgsInfo(); |
3311 | } |
3312 | |
3313 | bool hasTemplateKWAndArgsInfo() const { |
3314 | return DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo; |
3315 | } |
3316 | |
3317 | public: |
3318 | static DependentScopeDeclRefExpr * |
3319 | Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, |
3320 | SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, |
3321 | const TemplateArgumentListInfo *TemplateArgs); |
3322 | |
3323 | static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &Context, |
3324 | bool HasTemplateKWAndArgsInfo, |
3325 | unsigned NumTemplateArgs); |
3326 | |
3327 | /// Retrieve the name that this expression refers to. |
3328 | const DeclarationNameInfo &getNameInfo() const { return NameInfo; } |
3329 | |
3330 | /// Retrieve the name that this expression refers to. |
3331 | DeclarationName getDeclName() const { return NameInfo.getName(); } |
3332 | |
3333 | /// Retrieve the location of the name within the expression. |
3334 | /// |
3335 | /// For example, in "X<T>::value" this is the location of "value". |
3336 | SourceLocation getLocation() const { return NameInfo.getLoc(); } |
3337 | |
3338 | /// Retrieve the nested-name-specifier that qualifies the |
3339 | /// name, with source location information. |
3340 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
3341 | |
3342 | /// Retrieve the nested-name-specifier that qualifies this |
3343 | /// declaration. |
3344 | NestedNameSpecifier *getQualifier() const { |
3345 | return QualifierLoc.getNestedNameSpecifier(); |
3346 | } |
3347 | |
3348 | /// Retrieve the location of the template keyword preceding |
3349 | /// this name, if any. |
3350 | SourceLocation getTemplateKeywordLoc() const { |
3351 | if (!hasTemplateKWAndArgsInfo()) |
3352 | return SourceLocation(); |
3353 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; |
3354 | } |
3355 | |
3356 | /// Retrieve the location of the left angle bracket starting the |
3357 | /// explicit template argument list following the name, if any. |
3358 | SourceLocation getLAngleLoc() const { |
3359 | if (!hasTemplateKWAndArgsInfo()) |
3360 | return SourceLocation(); |
3361 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; |
3362 | } |
3363 | |
3364 | /// Retrieve the location of the right angle bracket ending the |
3365 | /// explicit template argument list following the name, if any. |
3366 | SourceLocation getRAngleLoc() const { |
3367 | if (!hasTemplateKWAndArgsInfo()) |
3368 | return SourceLocation(); |
3369 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; |
3370 | } |
3371 | |
3372 | /// Determines whether the name was preceded by the template keyword. |
3373 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } |
3374 | |
3375 | /// Determines whether this lookup had explicit template arguments. |
3376 | bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } |
3377 | |
3378 | /// Copies the template arguments (if present) into the given |
3379 | /// structure. |
3380 | void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { |
3381 | if (hasExplicitTemplateArgs()) |
3382 | getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( |
3383 | getTrailingObjects<TemplateArgumentLoc>(), List); |
3384 | } |
3385 | |
3386 | TemplateArgumentLoc const *getTemplateArgs() const { |
3387 | if (!hasExplicitTemplateArgs()) |
3388 | return nullptr; |
3389 | |
3390 | return getTrailingObjects<TemplateArgumentLoc>(); |
3391 | } |
3392 | |
3393 | unsigned getNumTemplateArgs() const { |
3394 | if (!hasExplicitTemplateArgs()) |
3395 | return 0; |
3396 | |
3397 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; |
3398 | } |
3399 | |
3400 | ArrayRef<TemplateArgumentLoc> template_arguments() const { |
3401 | return {getTemplateArgs(), getNumTemplateArgs()}; |
3402 | } |
3403 | |
3404 | /// Note: getBeginLoc() is the start of the whole DependentScopeDeclRefExpr, |
3405 | /// and differs from getLocation().getStart(). |
3406 | SourceLocation getBeginLoc() const LLVM_READONLY { |
3407 | return QualifierLoc.getBeginLoc(); |
3408 | } |
3409 | |
3410 | SourceLocation getEndLoc() const LLVM_READONLY { |
3411 | if (hasExplicitTemplateArgs()) |
3412 | return getRAngleLoc(); |
3413 | return getLocation(); |
3414 | } |
3415 | |
3416 | static bool classof(const Stmt *T) { |
3417 | return T->getStmtClass() == DependentScopeDeclRefExprClass; |
3418 | } |
3419 | |
3420 | child_range children() { |
3421 | return child_range(child_iterator(), child_iterator()); |
3422 | } |
3423 | |
3424 | const_child_range children() const { |
3425 | return const_child_range(const_child_iterator(), const_child_iterator()); |
3426 | } |
3427 | }; |
3428 | |
3429 | /// Represents an expression -- generally a full-expression -- that |
3430 | /// introduces cleanups to be run at the end of the sub-expression's |
3431 | /// evaluation. The most common source of expression-introduced |
3432 | /// cleanups is temporary objects in C++, but several other kinds of |
3433 | /// expressions can create cleanups, including basically every |
3434 | /// call in ARC that returns an Objective-C pointer. |
3435 | /// |
3436 | /// This expression also tracks whether the sub-expression contains a |
3437 | /// potentially-evaluated block literal. The lifetime of a block |
3438 | /// literal is the extent of the enclosing scope. |
3439 | class ExprWithCleanups final |
3440 | : public FullExpr, |
3441 | private llvm::TrailingObjects< |
3442 | ExprWithCleanups, |
3443 | llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>> { |
3444 | public: |
3445 | /// The type of objects that are kept in the cleanup. |
3446 | /// It's useful to remember the set of blocks and block-scoped compound |
3447 | /// literals; we could also remember the set of temporaries, but there's |
3448 | /// currently no need. |
3449 | using CleanupObject = llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>; |
3450 | |
3451 | private: |
3452 | friend class ASTStmtReader; |
3453 | friend TrailingObjects; |
3454 | |
3455 | ExprWithCleanups(EmptyShell, unsigned NumObjects); |
3456 | ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects, |
3457 | ArrayRef<CleanupObject> Objects); |
3458 | |
3459 | public: |
3460 | static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty, |
3461 | unsigned numObjects); |
3462 | |
3463 | static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr, |
3464 | bool CleanupsHaveSideEffects, |
3465 | ArrayRef<CleanupObject> objects); |
3466 | |
3467 | ArrayRef<CleanupObject> getObjects() const { |
3468 | return llvm::ArrayRef(getTrailingObjects<CleanupObject>(), getNumObjects()); |
3469 | } |
3470 | |
3471 | unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; } |
3472 | |
3473 | CleanupObject getObject(unsigned i) const { |
3474 | assert(i < getNumObjects() && "Index out of range" ); |
3475 | return getObjects()[i]; |
3476 | } |
3477 | |
3478 | bool cleanupsHaveSideEffects() const { |
3479 | return ExprWithCleanupsBits.CleanupsHaveSideEffects; |
3480 | } |
3481 | |
3482 | SourceLocation getBeginLoc() const LLVM_READONLY { |
3483 | return SubExpr->getBeginLoc(); |
3484 | } |
3485 | |
3486 | SourceLocation getEndLoc() const LLVM_READONLY { |
3487 | return SubExpr->getEndLoc(); |
3488 | } |
3489 | |
3490 | // Implement isa/cast/dyncast/etc. |
3491 | static bool classof(const Stmt *T) { |
3492 | return T->getStmtClass() == ExprWithCleanupsClass; |
3493 | } |
3494 | |
3495 | // Iterators |
3496 | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } |
3497 | |
3498 | const_child_range children() const { |
3499 | return const_child_range(&SubExpr, &SubExpr + 1); |
3500 | } |
3501 | }; |
3502 | |
3503 | /// Describes an explicit type conversion that uses functional |
3504 | /// notion but could not be resolved because one or more arguments are |
3505 | /// type-dependent. |
3506 | /// |
3507 | /// The explicit type conversions expressed by |
3508 | /// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>, |
3509 | /// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and |
3510 | /// either \c T is a dependent type or one or more of the <tt>a</tt>'s is |
3511 | /// type-dependent. For example, this would occur in a template such |
3512 | /// as: |
3513 | /// |
3514 | /// \code |
3515 | /// template<typename T, typename A1> |
3516 | /// inline T make_a(const A1& a1) { |
3517 | /// return T(a1); |
3518 | /// } |
3519 | /// \endcode |
3520 | /// |
3521 | /// When the returned expression is instantiated, it may resolve to a |
3522 | /// constructor call, conversion function call, or some kind of type |
3523 | /// conversion. |
3524 | class CXXUnresolvedConstructExpr final |
3525 | : public Expr, |
3526 | private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> { |
3527 | friend class ASTStmtReader; |
3528 | friend TrailingObjects; |
3529 | |
3530 | /// The type being constructed, and whether the construct expression models |
3531 | /// list initialization or not. |
3532 | llvm::PointerIntPair<TypeSourceInfo *, 1> TypeAndInitForm; |
3533 | |
3534 | /// The location of the left parentheses ('('). |
3535 | SourceLocation LParenLoc; |
3536 | |
3537 | /// The location of the right parentheses (')'). |
3538 | SourceLocation RParenLoc; |
3539 | |
3540 | CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI, |
3541 | SourceLocation LParenLoc, ArrayRef<Expr *> Args, |
3542 | SourceLocation RParenLoc, bool IsListInit); |
3543 | |
3544 | CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs) |
3545 | : Expr(CXXUnresolvedConstructExprClass, Empty) { |
3546 | CXXUnresolvedConstructExprBits.NumArgs = NumArgs; |
3547 | } |
3548 | |
3549 | public: |
3550 | static CXXUnresolvedConstructExpr * |
3551 | Create(const ASTContext &Context, QualType T, TypeSourceInfo *TSI, |
3552 | SourceLocation LParenLoc, ArrayRef<Expr *> Args, |
3553 | SourceLocation RParenLoc, bool IsListInit); |
3554 | |
3555 | static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context, |
3556 | unsigned NumArgs); |
3557 | |
3558 | /// Retrieve the type that is being constructed, as specified |
3559 | /// in the source code. |
3560 | QualType getTypeAsWritten() const { return getTypeSourceInfo()->getType(); } |
3561 | |
3562 | /// Retrieve the type source information for the type being |
3563 | /// constructed. |
3564 | TypeSourceInfo *getTypeSourceInfo() const { |
3565 | return TypeAndInitForm.getPointer(); |
3566 | } |
3567 | |
3568 | /// Retrieve the location of the left parentheses ('(') that |
3569 | /// precedes the argument list. |
3570 | SourceLocation getLParenLoc() const { return LParenLoc; } |
3571 | void setLParenLoc(SourceLocation L) { LParenLoc = L; } |
3572 | |
3573 | /// Retrieve the location of the right parentheses (')') that |
3574 | /// follows the argument list. |
3575 | SourceLocation getRParenLoc() const { return RParenLoc; } |
3576 | void setRParenLoc(SourceLocation L) { RParenLoc = L; } |
3577 | |
3578 | /// Determine whether this expression models list-initialization. |
3579 | /// If so, there will be exactly one subexpression, which will be |
3580 | /// an InitListExpr. |
3581 | bool isListInitialization() const { return TypeAndInitForm.getInt(); } |
3582 | |
3583 | /// Retrieve the number of arguments. |
3584 | unsigned getNumArgs() const { return CXXUnresolvedConstructExprBits.NumArgs; } |
3585 | |
3586 | using arg_iterator = Expr **; |
3587 | using arg_range = llvm::iterator_range<arg_iterator>; |
3588 | |
3589 | arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); } |
3590 | arg_iterator arg_end() { return arg_begin() + getNumArgs(); } |
3591 | arg_range arguments() { return arg_range(arg_begin(), arg_end()); } |
3592 | |
3593 | using const_arg_iterator = const Expr* const *; |
3594 | using const_arg_range = llvm::iterator_range<const_arg_iterator>; |
3595 | |
3596 | const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); } |
3597 | const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); } |
3598 | const_arg_range arguments() const { |
3599 | return const_arg_range(arg_begin(), arg_end()); |
3600 | } |
3601 | |
3602 | Expr *getArg(unsigned I) { |
3603 | assert(I < getNumArgs() && "Argument index out-of-range" ); |
3604 | return arg_begin()[I]; |
3605 | } |
3606 | |
3607 | const Expr *getArg(unsigned I) const { |
3608 | assert(I < getNumArgs() && "Argument index out-o |
---|