/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/ExprCXX.h
Line | Count | Source (jump to first uncovered line) |
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/None.h" |
44 | | #include "llvm/ADT/Optional.h" |
45 | | #include "llvm/ADT/PointerUnion.h" |
46 | | #include "llvm/ADT/StringRef.h" |
47 | | #include "llvm/ADT/iterator_range.h" |
48 | | #include "llvm/Support/Casting.h" |
49 | | #include "llvm/Support/Compiler.h" |
50 | | #include "llvm/Support/TrailingObjects.h" |
51 | | #include <cassert> |
52 | | #include <cstddef> |
53 | | #include <cstdint> |
54 | | #include <memory> |
55 | | |
56 | | namespace clang { |
57 | | |
58 | | class ASTContext; |
59 | | class DeclAccessPair; |
60 | | class IdentifierInfo; |
61 | | class LambdaCapture; |
62 | | class NonTypeTemplateParmDecl; |
63 | | class TemplateParameterList; |
64 | | |
65 | | //===--------------------------------------------------------------------===// |
66 | | // C++ Expressions. |
67 | | //===--------------------------------------------------------------------===// |
68 | | |
69 | | /// A call to an overloaded operator written using operator |
70 | | /// syntax. |
71 | | /// |
72 | | /// Represents a call to an overloaded operator written using operator |
73 | | /// syntax, e.g., "x + y" or "*p". While semantically equivalent to a |
74 | | /// normal call, this AST node provides better information about the |
75 | | /// syntactic representation of the call. |
76 | | /// |
77 | | /// In a C++ template, this expression node kind will be used whenever |
78 | | /// any of the arguments are type-dependent. In this case, the |
79 | | /// function itself will be a (possibly empty) set of functions and |
80 | | /// function templates that were found by name lookup at template |
81 | | /// definition time. |
82 | | class CXXOperatorCallExpr final : public CallExpr { |
83 | | friend class ASTStmtReader; |
84 | | friend class ASTStmtWriter; |
85 | | |
86 | | SourceRange Range; |
87 | | |
88 | | // CXXOperatorCallExpr has some trailing objects belonging |
89 | | // to CallExpr. See CallExpr for the details. |
90 | | |
91 | | SourceRange getSourceRangeImpl() const LLVM_READONLY; |
92 | | |
93 | | CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn, |
94 | | ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK, |
95 | | SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, |
96 | | ADLCallKind UsesADL); |
97 | | |
98 | | CXXOperatorCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty); |
99 | | |
100 | | public: |
101 | | static CXXOperatorCallExpr * |
102 | | Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, |
103 | | ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK, |
104 | | SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, |
105 | | ADLCallKind UsesADL = NotADL); |
106 | | |
107 | | static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx, |
108 | | unsigned NumArgs, bool HasFPFeatures, |
109 | | EmptyShell Empty); |
110 | | |
111 | | /// Returns the kind of overloaded operator that this expression refers to. |
112 | 2.80M | OverloadedOperatorKind getOperator() const { |
113 | 2.80M | return static_cast<OverloadedOperatorKind>( |
114 | 2.80M | CXXOperatorCallExprBits.OperatorKind); |
115 | 2.80M | } |
116 | | |
117 | 45.2k | static bool isAssignmentOp(OverloadedOperatorKind Opc) { |
118 | 45.2k | return Opc == OO_Equal || Opc == OO_StarEqual42.1k || Opc == OO_SlashEqual42.1k || |
119 | 42.1k | Opc == OO_PercentEqual || Opc == OO_PlusEqual42.1k || |
120 | 41.9k | Opc == OO_MinusEqual || Opc == OO_LessLessEqual41.9k || |
121 | 41.8k | Opc == OO_GreaterGreaterEqual || Opc == OO_AmpEqual41.8k || |
122 | 41.8k | Opc == OO_CaretEqual || Opc == OO_PipeEqual41.8k ; |
123 | 45.2k | } |
124 | 45.2k | bool isAssignmentOp() const { return isAssignmentOp(getOperator()); } |
125 | | |
126 | 20 | static bool isComparisonOp(OverloadedOperatorKind Opc) { |
127 | 20 | switch (Opc) { |
128 | 20 | case OO_EqualEqual: |
129 | 20 | case OO_ExclaimEqual: |
130 | 20 | case OO_Greater: |
131 | 20 | case OO_GreaterEqual: |
132 | 20 | case OO_Less: |
133 | 20 | case OO_LessEqual: |
134 | 20 | case OO_Spaceship: |
135 | 20 | return true; |
136 | 0 | default: |
137 | 0 | return false; |
138 | 20 | } |
139 | 20 | } |
140 | 20 | bool isComparisonOp() const { return isComparisonOp(getOperator()); } |
141 | | |
142 | | /// Is this written as an infix binary operator? |
143 | | bool isInfixBinaryOp() const; |
144 | | |
145 | | /// Returns the location of the operator symbol in the expression. |
146 | | /// |
147 | | /// When \c getOperator()==OO_Call, this is the location of the right |
148 | | /// parentheses; when \c getOperator()==OO_Subscript, this is the location |
149 | | /// of the right bracket. |
150 | 596k | SourceLocation getOperatorLoc() const { return getRParenLoc(); } |
151 | | |
152 | 649k | SourceLocation getExprLoc() const LLVM_READONLY { |
153 | 649k | OverloadedOperatorKind Operator = getOperator(); |
154 | 649k | return (Operator < OO_Plus || Operator >= OO_Arrow || |
155 | 537k | Operator == OO_PlusPlus || Operator == OO_MinusMinus490k ) |
156 | 164k | ? getBeginLoc() |
157 | 484k | : getOperatorLoc(); |
158 | 649k | } |
159 | | |
160 | 713k | SourceLocation getBeginLoc() const { return Range.getBegin(); } |
161 | 189k | SourceLocation getEndLoc() const { return Range.getEnd(); } |
162 | 104k | SourceRange getSourceRange() const { return Range; } |
163 | | |
164 | 33.5M | static bool classof(const Stmt *T) { |
165 | 33.5M | return T->getStmtClass() == CXXOperatorCallExprClass; |
166 | 33.5M | } |
167 | | }; |
168 | | |
169 | | /// Represents a call to a member function that |
170 | | /// may be written either with member call syntax (e.g., "obj.func()" |
171 | | /// or "objptr->func()") or with normal function-call syntax |
172 | | /// ("func()") within a member function that ends up calling a member |
173 | | /// function. The callee in either case is a MemberExpr that contains |
174 | | /// both the object argument and the member function, while the |
175 | | /// arguments are the arguments within the parentheses (not including |
176 | | /// the object argument). |
177 | | class CXXMemberCallExpr final : public CallExpr { |
178 | | // CXXMemberCallExpr has some trailing objects belonging |
179 | | // to CallExpr. See CallExpr for the details. |
180 | | |
181 | | CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty, |
182 | | ExprValueKind VK, SourceLocation RP, |
183 | | FPOptionsOverride FPOptions, unsigned MinNumArgs); |
184 | | |
185 | | CXXMemberCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty); |
186 | | |
187 | | public: |
188 | | static CXXMemberCallExpr *Create(const ASTContext &Ctx, Expr *Fn, |
189 | | ArrayRef<Expr *> Args, QualType Ty, |
190 | | ExprValueKind VK, SourceLocation RP, |
191 | | FPOptionsOverride FPFeatures, |
192 | | unsigned MinNumArgs = 0); |
193 | | |
194 | | static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs, |
195 | | bool HasFPFeatures, EmptyShell Empty); |
196 | | |
197 | | /// Retrieve the implicit object argument for the member call. |
198 | | /// |
199 | | /// For example, in "x.f(5)", this returns the sub-expression "x". |
200 | | Expr *getImplicitObjectArgument() const; |
201 | | |
202 | | /// Retrieve the type of the object argument. |
203 | | /// |
204 | | /// Note that this always returns a non-pointer type. |
205 | | QualType getObjectType() const; |
206 | | |
207 | | /// Retrieve the declaration of the called method. |
208 | | CXXMethodDecl *getMethodDecl() const; |
209 | | |
210 | | /// Retrieve the CXXRecordDecl for the underlying type of |
211 | | /// the implicit object argument. |
212 | | /// |
213 | | /// Note that this is may not be the same declaration as that of the class |
214 | | /// context of the CXXMethodDecl which this function is calling. |
215 | | /// FIXME: Returns 0 for member pointer call exprs. |
216 | | CXXRecordDecl *getRecordDecl() const; |
217 | | |
218 | 947k | SourceLocation getExprLoc() const LLVM_READONLY { |
219 | 947k | SourceLocation CLoc = getCallee()->getExprLoc(); |
220 | 947k | if (CLoc.isValid()) |
221 | 929k | return CLoc; |
222 | | |
223 | 17.6k | return getBeginLoc(); |
224 | 17.6k | } |
225 | | |
226 | 8.80M | static bool classof(const Stmt *T) { |
227 | 8.80M | return T->getStmtClass() == CXXMemberCallExprClass; |
228 | 8.80M | } |
229 | | }; |
230 | | |
231 | | /// Represents a call to a CUDA kernel function. |
232 | | class CUDAKernelCallExpr final : public CallExpr { |
233 | | friend class ASTStmtReader; |
234 | | |
235 | | enum { CONFIG, END_PREARG }; |
236 | | |
237 | | // CUDAKernelCallExpr has some trailing objects belonging |
238 | | // to CallExpr. See CallExpr for the details. |
239 | | |
240 | | CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef<Expr *> Args, |
241 | | QualType Ty, ExprValueKind VK, SourceLocation RP, |
242 | | FPOptionsOverride FPFeatures, unsigned MinNumArgs); |
243 | | |
244 | | CUDAKernelCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty); |
245 | | |
246 | | public: |
247 | | static CUDAKernelCallExpr *Create(const ASTContext &Ctx, Expr *Fn, |
248 | | CallExpr *Config, ArrayRef<Expr *> Args, |
249 | | QualType Ty, ExprValueKind VK, |
250 | | SourceLocation RP, |
251 | | FPOptionsOverride FPFeatures, |
252 | | unsigned MinNumArgs = 0); |
253 | | |
254 | | static CUDAKernelCallExpr *CreateEmpty(const ASTContext &Ctx, |
255 | | unsigned NumArgs, bool HasFPFeatures, |
256 | | EmptyShell Empty); |
257 | | |
258 | 32 | const CallExpr *getConfig() const { |
259 | 32 | return cast_or_null<CallExpr>(getPreArg(CONFIG)); |
260 | 32 | } |
261 | 13 | CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); } |
262 | | |
263 | 232k | static bool classof(const Stmt *T) { |
264 | 232k | return T->getStmtClass() == CUDAKernelCallExprClass; |
265 | 232k | } |
266 | | }; |
267 | | |
268 | | /// A rewritten comparison expression that was originally written using |
269 | | /// operator syntax. |
270 | | /// |
271 | | /// In C++20, the following rewrites are performed: |
272 | | /// - <tt>a == b</tt> -> <tt>b == a</tt> |
273 | | /// - <tt>a != b</tt> -> <tt>!(a == b)</tt> |
274 | | /// - <tt>a != b</tt> -> <tt>!(b == a)</tt> |
275 | | /// - For \c \@ in \c <, \c <=, \c >, \c >=, \c <=>: |
276 | | /// - <tt>a @ b</tt> -> <tt>(a <=> b) @ 0</tt> |
277 | | /// - <tt>a @ b</tt> -> <tt>0 @ (b <=> a)</tt> |
278 | | /// |
279 | | /// This expression provides access to both the original syntax and the |
280 | | /// rewritten expression. |
281 | | /// |
282 | | /// Note that the rewritten calls to \c ==, \c <=>, and \c \@ are typically |
283 | | /// \c CXXOperatorCallExprs, but could theoretically be \c BinaryOperators. |
284 | | class CXXRewrittenBinaryOperator : public Expr { |
285 | | friend class ASTStmtReader; |
286 | | |
287 | | /// The rewritten semantic form. |
288 | | Stmt *SemanticForm; |
289 | | |
290 | | public: |
291 | | CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed) |
292 | | : Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(), |
293 | | SemanticForm->getValueKind(), SemanticForm->getObjectKind()), |
294 | 299 | SemanticForm(SemanticForm) { |
295 | 299 | CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed; |
296 | 299 | setDependence(computeDependence(this)); |
297 | 299 | } |
298 | | CXXRewrittenBinaryOperator(EmptyShell Empty) |
299 | 2 | : Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {} |
300 | | |
301 | | /// Get an equivalent semantic form for this expression. |
302 | 304 | Expr *getSemanticForm() { return cast<Expr>(SemanticForm); } |
303 | 2.35k | const Expr *getSemanticForm() const { return cast<Expr>(SemanticForm); } |
304 | | |
305 | | struct DecomposedForm { |
306 | | /// The original opcode, prior to rewriting. |
307 | | BinaryOperatorKind Opcode; |
308 | | /// The original left-hand side. |
309 | | const Expr *LHS; |
310 | | /// The original right-hand side. |
311 | | const Expr *RHS; |
312 | | /// The inner \c == or \c <=> operator expression. |
313 | | const Expr *InnerBinOp; |
314 | | }; |
315 | | |
316 | | /// Decompose this operator into its syntactic form. |
317 | | DecomposedForm getDecomposedForm() const LLVM_READONLY; |
318 | | |
319 | | /// Determine whether this expression was rewritten in reverse form. |
320 | 3.68k | bool isReversed() const { return CXXRewrittenBinaryOperatorBits.IsReversed; } |
321 | | |
322 | 188 | BinaryOperatorKind getOperator() const { return getDecomposedForm().Opcode; } |
323 | 188 | BinaryOperatorKind getOpcode() const { return getOperator(); } |
324 | 0 | static StringRef getOpcodeStr(BinaryOperatorKind Op) { |
325 | 0 | return BinaryOperator::getOpcodeStr(Op); |
326 | 0 | } |
327 | 188 | StringRef getOpcodeStr() const { |
328 | 188 | return BinaryOperator::getOpcodeStr(getOpcode()); |
329 | 188 | } |
330 | 28 | bool isComparisonOp() const { return true; } |
331 | 0 | bool isAssignmentOp() const { return false; } |
332 | | |
333 | 303 | const Expr *getLHS() const { return getDecomposedForm().LHS; } |
334 | 275 | const Expr *getRHS() const { return getDecomposedForm().RHS; } |
335 | | |
336 | 476 | SourceLocation getOperatorLoc() const LLVM_READONLY { |
337 | 476 | return getDecomposedForm().InnerBinOp->getExprLoc(); |
338 | 476 | } |
339 | 466 | SourceLocation getExprLoc() const LLVM_READONLY { return getOperatorLoc(); } |
340 | | |
341 | | /// Compute the begin and end locations from the decomposed form. |
342 | | /// The locations of the semantic form are not reliable if this is |
343 | | /// a reversed expression. |
344 | | //@{ |
345 | 744 | SourceLocation getBeginLoc() const LLVM_READONLY { |
346 | 744 | return getDecomposedForm().LHS->getBeginLoc(); |
347 | 744 | } |
348 | 175 | SourceLocation getEndLoc() const LLVM_READONLY { |
349 | 175 | return getDecomposedForm().RHS->getEndLoc(); |
350 | 175 | } |
351 | 21 | SourceRange getSourceRange() const LLVM_READONLY { |
352 | 21 | DecomposedForm DF = getDecomposedForm(); |
353 | 21 | return SourceRange(DF.LHS->getBeginLoc(), DF.RHS->getEndLoc()); |
354 | 21 | } |
355 | | //@} |
356 | | |
357 | 829 | child_range children() { |
358 | 829 | return child_range(&SemanticForm, &SemanticForm + 1); |
359 | 829 | } |
360 | | |
361 | 93.9k | static bool classof(const Stmt *T) { |
362 | 93.9k | return T->getStmtClass() == CXXRewrittenBinaryOperatorClass; |
363 | 93.9k | } |
364 | | }; |
365 | | |
366 | | /// Abstract class common to all of the C++ "named"/"keyword" casts. |
367 | | /// |
368 | | /// This abstract class is inherited by all of the classes |
369 | | /// representing "named" casts: CXXStaticCastExpr for \c static_cast, |
370 | | /// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for |
371 | | /// reinterpret_cast, CXXConstCastExpr for \c const_cast and |
372 | | /// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL). |
373 | | class CXXNamedCastExpr : public ExplicitCastExpr { |
374 | | private: |
375 | | // the location of the casting op |
376 | | SourceLocation Loc; |
377 | | |
378 | | // the location of the right parenthesis |
379 | | SourceLocation RParenLoc; |
380 | | |
381 | | // range for '<' '>' |
382 | | SourceRange AngleBrackets; |
383 | | |
384 | | protected: |
385 | | friend class ASTStmtReader; |
386 | | |
387 | | CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, CastKind kind, |
388 | | Expr *op, unsigned PathSize, bool HasFPFeatures, |
389 | | TypeSourceInfo *writtenTy, SourceLocation l, |
390 | | SourceLocation RParenLoc, SourceRange AngleBrackets) |
391 | | : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, HasFPFeatures, |
392 | | writtenTy), |
393 | 203k | Loc(l), RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {} |
394 | | |
395 | | explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize, |
396 | | bool HasFPFeatures) |
397 | 25.3k | : ExplicitCastExpr(SC, Shell, PathSize, HasFPFeatures) {} |
398 | | |
399 | | public: |
400 | | const char *getCastName() const; |
401 | | |
402 | | /// Retrieve the location of the cast operator keyword, e.g., |
403 | | /// \c static_cast. |
404 | 74.0k | SourceLocation getOperatorLoc() const { return Loc; } |
405 | | |
406 | | /// Retrieve the location of the closing parenthesis. |
407 | 73.9k | SourceLocation getRParenLoc() const { return RParenLoc; } |
408 | | |
409 | 463k | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
410 | 44.9k | SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } |
411 | 152k | SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; } |
412 | | |
413 | 97 | static bool classof(const Stmt *T) { |
414 | 97 | switch (T->getStmtClass()) { |
415 | 32 | case CXXStaticCastExprClass: |
416 | 32 | case CXXDynamicCastExprClass: |
417 | 44 | case CXXReinterpretCastExprClass: |
418 | 44 | case CXXConstCastExprClass: |
419 | 44 | case CXXAddrspaceCastExprClass: |
420 | 44 | return true; |
421 | 53 | default: |
422 | 53 | return false; |
423 | 97 | } |
424 | 97 | } |
425 | | }; |
426 | | |
427 | | /// A C++ \c static_cast expression (C++ [expr.static.cast]). |
428 | | /// |
429 | | /// This expression node represents a C++ static cast, e.g., |
430 | | /// \c static_cast<int>(1.0). |
431 | | class CXXStaticCastExpr final |
432 | | : public CXXNamedCastExpr, |
433 | | private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *, |
434 | | FPOptionsOverride> { |
435 | | CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, |
436 | | unsigned pathSize, TypeSourceInfo *writtenTy, |
437 | | FPOptionsOverride FPO, SourceLocation l, |
438 | | SourceLocation RParenLoc, SourceRange AngleBrackets) |
439 | | : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize, |
440 | | FPO.requiresTrailingStorage(), writtenTy, l, RParenLoc, |
441 | 186k | AngleBrackets) { |
442 | 186k | if (hasStoredFPFeatures()) |
443 | 2 | *getTrailingFPFeatures() = FPO; |
444 | 186k | } |
445 | | |
446 | | explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize, |
447 | | bool HasFPFeatures) |
448 | | : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize, |
449 | 23.3k | HasFPFeatures) {} |
450 | | |
451 | 6 | unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const { |
452 | 6 | return path_size(); |
453 | 6 | } |
454 | | |
455 | | public: |
456 | | friend class CastExpr; |
457 | | friend TrailingObjects; |
458 | | |
459 | | static CXXStaticCastExpr * |
460 | | Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, |
461 | | Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, |
462 | | FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc, |
463 | | SourceRange AngleBrackets); |
464 | | static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context, |
465 | | unsigned PathSize, bool hasFPFeatures); |
466 | | |
467 | 81.9k | static bool classof(const Stmt *T) { |
468 | 81.9k | return T->getStmtClass() == CXXStaticCastExprClass; |
469 | 81.9k | } |
470 | | }; |
471 | | |
472 | | /// A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]). |
473 | | /// |
474 | | /// This expression node represents a dynamic cast, e.g., |
475 | | /// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time |
476 | | /// check to determine how to perform the type conversion. |
477 | | class CXXDynamicCastExpr final |
478 | | : public CXXNamedCastExpr, |
479 | | private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> { |
480 | | CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op, |
481 | | unsigned pathSize, TypeSourceInfo *writtenTy, |
482 | | SourceLocation l, SourceLocation RParenLoc, |
483 | | SourceRange AngleBrackets) |
484 | | : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize, |
485 | | /*HasFPFeatures*/ false, writtenTy, l, RParenLoc, |
486 | 1.18k | AngleBrackets) {} |
487 | | |
488 | | explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize) |
489 | | : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize, |
490 | 3 | /*HasFPFeatures*/ false) {} |
491 | | |
492 | | public: |
493 | | friend class CastExpr; |
494 | | friend TrailingObjects; |
495 | | |
496 | | static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T, |
497 | | ExprValueKind VK, CastKind Kind, Expr *Op, |
498 | | const CXXCastPath *Path, |
499 | | TypeSourceInfo *Written, SourceLocation L, |
500 | | SourceLocation RParenLoc, |
501 | | SourceRange AngleBrackets); |
502 | | |
503 | | static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context, |
504 | | unsigned pathSize); |
505 | | |
506 | | bool isAlwaysNull() const; |
507 | | |
508 | 296k | static bool classof(const Stmt *T) { |
509 | 296k | return T->getStmtClass() == CXXDynamicCastExprClass; |
510 | 296k | } |
511 | | }; |
512 | | |
513 | | /// A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]). |
514 | | /// |
515 | | /// This expression node represents a reinterpret cast, e.g., |
516 | | /// @c reinterpret_cast<int>(VoidPtr). |
517 | | /// |
518 | | /// A reinterpret_cast provides a differently-typed view of a value but |
519 | | /// (in Clang, as in most C++ implementations) performs no actual work at |
520 | | /// run time. |
521 | | class CXXReinterpretCastExpr final |
522 | | : public CXXNamedCastExpr, |
523 | | private llvm::TrailingObjects<CXXReinterpretCastExpr, |
524 | | CXXBaseSpecifier *> { |
525 | | CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, |
526 | | unsigned pathSize, TypeSourceInfo *writtenTy, |
527 | | SourceLocation l, SourceLocation RParenLoc, |
528 | | SourceRange AngleBrackets) |
529 | | : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op, |
530 | | pathSize, /*HasFPFeatures*/ false, writtenTy, l, |
531 | 8.66k | RParenLoc, AngleBrackets) {} |
532 | | |
533 | | CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize) |
534 | | : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize, |
535 | 453 | /*HasFPFeatures*/ false) {} |
536 | | |
537 | | public: |
538 | | friend class CastExpr; |
539 | | friend TrailingObjects; |
540 | | |
541 | | static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T, |
542 | | ExprValueKind VK, CastKind Kind, |
543 | | Expr *Op, const CXXCastPath *Path, |
544 | | TypeSourceInfo *WrittenTy, SourceLocation L, |
545 | | SourceLocation RParenLoc, |
546 | | SourceRange AngleBrackets); |
547 | | static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context, |
548 | | unsigned pathSize); |
549 | | |
550 | 121k | static bool classof(const Stmt *T) { |
551 | 121k | return T->getStmtClass() == CXXReinterpretCastExprClass; |
552 | 121k | } |
553 | | }; |
554 | | |
555 | | /// A C++ \c const_cast expression (C++ [expr.const.cast]). |
556 | | /// |
557 | | /// This expression node represents a const cast, e.g., |
558 | | /// \c const_cast<char*>(PtrToConstChar). |
559 | | /// |
560 | | /// A const_cast can remove type qualifiers but does not change the underlying |
561 | | /// value. |
562 | | class CXXConstCastExpr final |
563 | | : public CXXNamedCastExpr, |
564 | | private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> { |
565 | | CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, |
566 | | TypeSourceInfo *writtenTy, SourceLocation l, |
567 | | SourceLocation RParenLoc, SourceRange AngleBrackets) |
568 | | : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, 0, |
569 | | /*HasFPFeatures*/ false, writtenTy, l, RParenLoc, |
570 | 7.11k | AngleBrackets) {} |
571 | | |
572 | | explicit CXXConstCastExpr(EmptyShell Empty) |
573 | | : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0, |
574 | 1.54k | /*HasFPFeatures*/ false) {} |
575 | | |
576 | | public: |
577 | | friend class CastExpr; |
578 | | friend TrailingObjects; |
579 | | |
580 | | static CXXConstCastExpr *Create(const ASTContext &Context, QualType T, |
581 | | ExprValueKind VK, Expr *Op, |
582 | | TypeSourceInfo *WrittenTy, SourceLocation L, |
583 | | SourceLocation RParenLoc, |
584 | | SourceRange AngleBrackets); |
585 | | static CXXConstCastExpr *CreateEmpty(const ASTContext &Context); |
586 | | |
587 | 2.56k | static bool classof(const Stmt *T) { |
588 | 2.56k | return T->getStmtClass() == CXXConstCastExprClass; |
589 | 2.56k | } |
590 | | }; |
591 | | |
592 | | /// A C++ addrspace_cast expression (currently only enabled for OpenCL). |
593 | | /// |
594 | | /// This expression node represents a cast between pointers to objects in |
595 | | /// different address spaces e.g., |
596 | | /// \c addrspace_cast<global int*>(PtrToGenericInt). |
597 | | /// |
598 | | /// A addrspace_cast can cast address space type qualifiers but does not change |
599 | | /// the underlying value. |
600 | | class CXXAddrspaceCastExpr final |
601 | | : public CXXNamedCastExpr, |
602 | | private llvm::TrailingObjects<CXXAddrspaceCastExpr, CXXBaseSpecifier *> { |
603 | | CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op, |
604 | | TypeSourceInfo *writtenTy, SourceLocation l, |
605 | | SourceLocation RParenLoc, SourceRange AngleBrackets) |
606 | | : CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0, |
607 | | /*HasFPFeatures*/ false, writtenTy, l, RParenLoc, |
608 | 10 | AngleBrackets) {} |
609 | | |
610 | | explicit CXXAddrspaceCastExpr(EmptyShell Empty) |
611 | | : CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0, |
612 | 0 | /*HasFPFeatures*/ false) {} |
613 | | |
614 | | public: |
615 | | friend class CastExpr; |
616 | | friend TrailingObjects; |
617 | | |
618 | | static CXXAddrspaceCastExpr * |
619 | | Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, |
620 | | Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, |
621 | | SourceLocation RParenLoc, SourceRange AngleBrackets); |
622 | | static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context); |
623 | | |
624 | 3 | static bool classof(const Stmt *T) { |
625 | 3 | return T->getStmtClass() == CXXAddrspaceCastExprClass; |
626 | 3 | } |
627 | | }; |
628 | | |
629 | | /// A call to a literal operator (C++11 [over.literal]) |
630 | | /// written as a user-defined literal (C++11 [lit.ext]). |
631 | | /// |
632 | | /// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this |
633 | | /// is semantically equivalent to a normal call, this AST node provides better |
634 | | /// information about the syntactic representation of the literal. |
635 | | /// |
636 | | /// Since literal operators are never found by ADL and can only be declared at |
637 | | /// namespace scope, a user-defined literal is never dependent. |
638 | | class UserDefinedLiteral final : public CallExpr { |
639 | | friend class ASTStmtReader; |
640 | | friend class ASTStmtWriter; |
641 | | |
642 | | /// The location of a ud-suffix within the literal. |
643 | | SourceLocation UDSuffixLoc; |
644 | | |
645 | | // UserDefinedLiteral has some trailing objects belonging |
646 | | // to CallExpr. See CallExpr for the details. |
647 | | |
648 | | UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty, |
649 | | ExprValueKind VK, SourceLocation LitEndLoc, |
650 | | SourceLocation SuffixLoc, FPOptionsOverride FPFeatures); |
651 | | |
652 | | UserDefinedLiteral(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty); |
653 | | |
654 | | public: |
655 | | static UserDefinedLiteral *Create(const ASTContext &Ctx, Expr *Fn, |
656 | | ArrayRef<Expr *> Args, QualType Ty, |
657 | | ExprValueKind VK, SourceLocation LitEndLoc, |
658 | | SourceLocation SuffixLoc, |
659 | | FPOptionsOverride FPFeatures); |
660 | | |
661 | | static UserDefinedLiteral *CreateEmpty(const ASTContext &Ctx, |
662 | | unsigned NumArgs, bool HasFPOptions, |
663 | | EmptyShell Empty); |
664 | | |
665 | | /// The kind of literal operator which is invoked. |
666 | | enum LiteralOperatorKind { |
667 | | /// Raw form: operator "" X (const char *) |
668 | | LOK_Raw, |
669 | | |
670 | | /// Raw form: operator "" X<cs...> () |
671 | | LOK_Template, |
672 | | |
673 | | /// operator "" X (unsigned long long) |
674 | | LOK_Integer, |
675 | | |
676 | | /// operator "" X (long double) |
677 | | LOK_Floating, |
678 | | |
679 | | /// operator "" X (const CharT *, size_t) |
680 | | LOK_String, |
681 | | |
682 | | /// operator "" X (CharT) |
683 | | LOK_Character |
684 | | }; |
685 | | |
686 | | /// Returns the kind of literal operator invocation |
687 | | /// which this expression represents. |
688 | | LiteralOperatorKind getLiteralOperatorKind() const; |
689 | | |
690 | | /// If this is not a raw user-defined literal, get the |
691 | | /// underlying cooked literal (representing the literal with the suffix |
692 | | /// removed). |
693 | | Expr *getCookedLiteral(); |
694 | 0 | const Expr *getCookedLiteral() const { |
695 | 0 | return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral(); |
696 | 0 | } |
697 | | |
698 | 8.79k | SourceLocation getBeginLoc() const { |
699 | 8.79k | if (getLiteralOperatorKind() == LOK_Template) |
700 | 671 | return getRParenLoc(); |
701 | 8.12k | return getArg(0)->getBeginLoc(); |
702 | 8.12k | } |
703 | | |
704 | 142 | SourceLocation getEndLoc() const { return getRParenLoc(); } |
705 | | |
706 | | /// Returns the location of a ud-suffix in the expression. |
707 | | /// |
708 | | /// For a string literal, there may be multiple identical suffixes. This |
709 | | /// returns the first. |
710 | 0 | SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; } |
711 | | |
712 | | /// Returns the ud-suffix specified for this literal. |
713 | | const IdentifierInfo *getUDSuffix() const; |
714 | | |
715 | 9 | static bool classof(const Stmt *S) { |
716 | 9 | return S->getStmtClass() == UserDefinedLiteralClass; |
717 | 9 | } |
718 | | }; |
719 | | |
720 | | /// A boolean literal, per ([C++ lex.bool] Boolean literals). |
721 | | class CXXBoolLiteralExpr : public Expr { |
722 | | public: |
723 | | CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc) |
724 | 621k | : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary) { |
725 | 621k | CXXBoolLiteralExprBits.Value = Val; |
726 | 621k | CXXBoolLiteralExprBits.Loc = Loc; |
727 | 621k | setDependence(ExprDependence::None); |
728 | 621k | } |
729 | | |
730 | | explicit CXXBoolLiteralExpr(EmptyShell Empty) |
731 | 122k | : Expr(CXXBoolLiteralExprClass, Empty) {} |
732 | | |
733 | 896k | bool getValue() const { return CXXBoolLiteralExprBits.Value; } |
734 | 122k | void setValue(bool V) { CXXBoolLiteralExprBits.Value = V; } |
735 | | |
736 | 2.64M | SourceLocation getBeginLoc() const { return getLocation(); } |
737 | 52.8k | SourceLocation getEndLoc() const { return getLocation(); } |
738 | | |
739 | 2.76M | SourceLocation getLocation() const { return CXXBoolLiteralExprBits.Loc; } |
740 | 122k | void setLocation(SourceLocation L) { CXXBoolLiteralExprBits.Loc = L; } |
741 | | |
742 | 412k | static bool classof(const Stmt *T) { |
743 | 412k | return T->getStmtClass() == CXXBoolLiteralExprClass; |
744 | 412k | } |
745 | | |
746 | | // Iterators |
747 | 1.65M | child_range children() { |
748 | 1.65M | return child_range(child_iterator(), child_iterator()); |
749 | 1.65M | } |
750 | | |
751 | 0 | const_child_range children() const { |
752 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
753 | 0 | } |
754 | | }; |
755 | | |
756 | | /// The null pointer literal (C++11 [lex.nullptr]) |
757 | | /// |
758 | | /// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr. |
759 | | class CXXNullPtrLiteralExpr : public Expr { |
760 | | public: |
761 | | CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc) |
762 | 99.9k | : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary) { |
763 | 99.9k | CXXNullPtrLiteralExprBits.Loc = Loc; |
764 | 99.9k | setDependence(ExprDependence::None); |
765 | 99.9k | } |
766 | | |
767 | | explicit CXXNullPtrLiteralExpr(EmptyShell Empty) |
768 | 19.6k | : Expr(CXXNullPtrLiteralExprClass, Empty) {} |
769 | | |
770 | 239k | SourceLocation getBeginLoc() const { return getLocation(); } |
771 | 37.2k | SourceLocation getEndLoc() const { return getLocation(); } |
772 | | |
773 | 304k | SourceLocation getLocation() const { return CXXNullPtrLiteralExprBits.Loc; } |
774 | 19.6k | void setLocation(SourceLocation L) { CXXNullPtrLiteralExprBits.Loc = L; } |
775 | | |
776 | 14.3k | static bool classof(const Stmt *T) { |
777 | 14.3k | return T->getStmtClass() == CXXNullPtrLiteralExprClass; |
778 | 14.3k | } |
779 | | |
780 | 113k | child_range children() { |
781 | 113k | return child_range(child_iterator(), child_iterator()); |
782 | 113k | } |
783 | | |
784 | 0 | const_child_range children() const { |
785 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
786 | 0 | } |
787 | | }; |
788 | | |
789 | | /// Implicit construction of a std::initializer_list<T> object from an |
790 | | /// array temporary within list-initialization (C++11 [dcl.init.list]p5). |
791 | | class CXXStdInitializerListExpr : public Expr { |
792 | | Stmt *SubExpr = nullptr; |
793 | | |
794 | | CXXStdInitializerListExpr(EmptyShell Empty) |
795 | 3 | : Expr(CXXStdInitializerListExprClass, Empty) {} |
796 | | |
797 | | public: |
798 | | friend class ASTReader; |
799 | | friend class ASTStmtReader; |
800 | | |
801 | | CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr) |
802 | | : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary), |
803 | 646 | SubExpr(SubExpr) { |
804 | 646 | setDependence(computeDependence(this)); |
805 | 646 | } |
806 | | |
807 | 1.21k | Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); } |
808 | 288 | const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); } |
809 | | |
810 | 2.38k | SourceLocation getBeginLoc() const LLVM_READONLY { |
811 | 2.38k | return SubExpr->getBeginLoc(); |
812 | 2.38k | } |
813 | | |
814 | 31 | SourceLocation getEndLoc() const LLVM_READONLY { |
815 | 31 | return SubExpr->getEndLoc(); |
816 | 31 | } |
817 | | |
818 | | /// Retrieve the source range of the expression. |
819 | 56 | SourceRange getSourceRange() const LLVM_READONLY { |
820 | 56 | return SubExpr->getSourceRange(); |
821 | 56 | } |
822 | | |
823 | 3.92M | static bool classof(const Stmt *S) { |
824 | 3.92M | return S->getStmtClass() == CXXStdInitializerListExprClass; |
825 | 3.92M | } |
826 | | |
827 | 2.07k | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } |
828 | | |
829 | 0 | const_child_range children() const { |
830 | 0 | return const_child_range(&SubExpr, &SubExpr + 1); |
831 | 0 | } |
832 | | }; |
833 | | |
834 | | /// A C++ \c typeid expression (C++ [expr.typeid]), which gets |
835 | | /// the \c type_info that corresponds to the supplied type, or the (possibly |
836 | | /// dynamic) type of the supplied expression. |
837 | | /// |
838 | | /// This represents code like \c typeid(int) or \c typeid(*objPtr) |
839 | | class CXXTypeidExpr : public Expr { |
840 | | friend class ASTStmtReader; |
841 | | |
842 | | private: |
843 | | llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; |
844 | | SourceRange Range; |
845 | | |
846 | | public: |
847 | | CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) |
848 | | : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), |
849 | 5.25k | Range(R) { |
850 | 5.25k | setDependence(computeDependence(this)); |
851 | 5.25k | } |
852 | | |
853 | | CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R) |
854 | | : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), |
855 | 281 | Range(R) { |
856 | 281 | setDependence(computeDependence(this)); |
857 | 281 | } |
858 | | |
859 | | CXXTypeidExpr(EmptyShell Empty, bool isExpr) |
860 | 138 | : Expr(CXXTypeidExprClass, Empty) { |
861 | 138 | if (isExpr) |
862 | 2 | Operand = (Expr*)nullptr; |
863 | 136 | else |
864 | 136 | Operand = (TypeSourceInfo*)nullptr; |
865 | 138 | } |
866 | | |
867 | | /// Determine whether this typeid has a type operand which is potentially |
868 | | /// evaluated, per C++11 [expr.typeid]p3. |
869 | | bool isPotentiallyEvaluated() const; |
870 | | |
871 | | /// Best-effort check if the expression operand refers to a most derived |
872 | | /// object. This is not a strong guarantee. |
873 | | bool isMostDerived(ASTContext &Context) const; |
874 | | |
875 | 23.5k | bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); } |
876 | | |
877 | | /// Retrieves the type operand of this typeid() expression after |
878 | | /// various required adjustments (removing reference types, cv-qualifiers). |
879 | | QualType getTypeOperand(ASTContext &Context) const; |
880 | | |
881 | | /// Retrieve source information for the type operand. |
882 | 6.08k | TypeSourceInfo *getTypeOperandSourceInfo() const { |
883 | 6.08k | assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); |
884 | 6.08k | return Operand.get<TypeSourceInfo *>(); |
885 | 6.08k | } |
886 | 1.40k | Expr *getExprOperand() const { |
887 | 1.40k | assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); |
888 | 1.40k | return static_cast<Expr*>(Operand.get<Stmt *>()); |
889 | 1.40k | } |
890 | | |
891 | 16.2k | SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } |
892 | 1.58k | SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } |
893 | 353 | SourceRange getSourceRange() const LLVM_READONLY { return Range; } |
894 | 138 | void setSourceRange(SourceRange R) { Range = R; } |
895 | | |
896 | 5.30k | static bool classof(const Stmt *T) { |
897 | 5.30k | return T->getStmtClass() == CXXTypeidExprClass; |
898 | 5.30k | } |
899 | | |
900 | | // Iterators |
901 | 2.07k | child_range children() { |
902 | 2.07k | if (isTypeOperand()) |
903 | 1.72k | return child_range(child_iterator(), child_iterator()); |
904 | 354 | auto **begin = reinterpret_cast<Stmt **>(&Operand); |
905 | 354 | return child_range(begin, begin + 1); |
906 | 354 | } |
907 | | |
908 | 0 | const_child_range children() const { |
909 | 0 | if (isTypeOperand()) |
910 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
911 | 0 |
|
912 | 0 | auto **begin = |
913 | 0 | reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand); |
914 | 0 | return const_child_range(begin, begin + 1); |
915 | 0 | } |
916 | | }; |
917 | | |
918 | | /// A member reference to an MSPropertyDecl. |
919 | | /// |
920 | | /// This expression always has pseudo-object type, and therefore it is |
921 | | /// typically not encountered in a fully-typechecked expression except |
922 | | /// within the syntactic form of a PseudoObjectExpr. |
923 | | class MSPropertyRefExpr : public Expr { |
924 | | Expr *BaseExpr; |
925 | | MSPropertyDecl *TheDecl; |
926 | | SourceLocation MemberLoc; |
927 | | bool IsArrow; |
928 | | NestedNameSpecifierLoc QualifierLoc; |
929 | | |
930 | | public: |
931 | | friend class ASTStmtReader; |
932 | | |
933 | | MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow, |
934 | | QualType ty, ExprValueKind VK, |
935 | | NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc) |
936 | | : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary), BaseExpr(baseExpr), |
937 | | TheDecl(decl), MemberLoc(nameLoc), IsArrow(isArrow), |
938 | 532 | QualifierLoc(qualifierLoc) { |
939 | 532 | setDependence(computeDependence(this)); |
940 | 532 | } |
941 | | |
942 | 22 | MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {} |
943 | | |
944 | 601 | SourceRange getSourceRange() const LLVM_READONLY { |
945 | 601 | return SourceRange(getBeginLoc(), getEndLoc()); |
946 | 601 | } |
947 | | |
948 | 1.92k | bool isImplicitAccess() const { |
949 | 1.92k | return getBaseExpr() && getBaseExpr()->isImplicitCXXThis(); |
950 | 1.92k | } |
951 | | |
952 | 1.92k | SourceLocation getBeginLoc() const { |
953 | 1.92k | if (!isImplicitAccess()) |
954 | 1.68k | return BaseExpr->getBeginLoc(); |
955 | 237 | else if (QualifierLoc) |
956 | 18 | return QualifierLoc.getBeginLoc(); |
957 | 219 | else |
958 | 219 | return MemberLoc; |
959 | 1.92k | } |
960 | | |
961 | 648 | SourceLocation getEndLoc() const { return getMemberLoc(); } |
962 | | |
963 | 368 | child_range children() { |
964 | 368 | return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1); |
965 | 368 | } |
966 | | |
967 | 0 | const_child_range children() const { |
968 | 0 | auto Children = const_cast<MSPropertyRefExpr *>(this)->children(); |
969 | 0 | return const_child_range(Children.begin(), Children.end()); |
970 | 0 | } |
971 | | |
972 | 1.55k | static bool classof(const Stmt *T) { |
973 | 1.55k | return T->getStmtClass() == MSPropertyRefExprClass; |
974 | 1.55k | } |
975 | | |
976 | 5.26k | Expr *getBaseExpr() const { return BaseExpr; } |
977 | 1.01k | MSPropertyDecl *getPropertyDecl() const { return TheDecl; } |
978 | 611 | bool isArrow() const { return IsArrow; } |
979 | 1.29k | SourceLocation getMemberLoc() const { return MemberLoc; } |
980 | 613 | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
981 | | }; |
982 | | |
983 | | /// MS property subscript expression. |
984 | | /// MSVC supports 'property' attribute and allows to apply it to the |
985 | | /// declaration of an empty array in a class or structure definition. |
986 | | /// For example: |
987 | | /// \code |
988 | | /// __declspec(property(get=GetX, put=PutX)) int x[]; |
989 | | /// \endcode |
990 | | /// The above statement indicates that x[] can be used with one or more array |
991 | | /// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and |
992 | | /// p->x[a][b] = i will be turned into p->PutX(a, b, i). |
993 | | /// This is a syntactic pseudo-object expression. |
994 | | class MSPropertySubscriptExpr : public Expr { |
995 | | friend class ASTStmtReader; |
996 | | |
997 | | enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 }; |
998 | | |
999 | | Stmt *SubExprs[NUM_SUBEXPRS]; |
1000 | | SourceLocation RBracketLoc; |
1001 | | |
1002 | 36 | void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; } |
1003 | 36 | void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; } |
1004 | | |
1005 | | public: |
1006 | | MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK, |
1007 | | ExprObjectKind OK, SourceLocation RBracketLoc) |
1008 | | : Expr(MSPropertySubscriptExprClass, Ty, VK, OK), |
1009 | 312 | RBracketLoc(RBracketLoc) { |
1010 | 312 | SubExprs[BASE_EXPR] = Base; |
1011 | 312 | SubExprs[IDX_EXPR] = Idx; |
1012 | 312 | setDependence(computeDependence(this)); |
1013 | 312 | } |
1014 | | |
1015 | | /// Create an empty array subscript expression. |
1016 | | explicit MSPropertySubscriptExpr(EmptyShell Shell) |
1017 | 36 | : Expr(MSPropertySubscriptExprClass, Shell) {} |
1018 | | |
1019 | 596 | Expr *getBase() { return cast<Expr>(SubExprs[BASE_EXPR]); } |
1020 | 938 | const Expr *getBase() const { return cast<Expr>(SubExprs[BASE_EXPR]); } |
1021 | | |
1022 | 886 | Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); } |
1023 | 0 | const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); } |
1024 | | |
1025 | 542 | SourceLocation getBeginLoc() const LLVM_READONLY { |
1026 | 542 | return getBase()->getBeginLoc(); |
1027 | 542 | } |
1028 | | |
1029 | 97 | SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } |
1030 | | |
1031 | 224 | SourceLocation getRBracketLoc() const { return RBracketLoc; } |
1032 | 36 | void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } |
1033 | | |
1034 | 396 | SourceLocation getExprLoc() const LLVM_READONLY { |
1035 | 396 | return getBase()->getExprLoc(); |
1036 | 396 | } |
1037 | | |
1038 | 863 | static bool classof(const Stmt *T) { |
1039 | 863 | return T->getStmtClass() == MSPropertySubscriptExprClass; |
1040 | 863 | } |
1041 | | |
1042 | | // Iterators |
1043 | 220 | child_range children() { |
1044 | 220 | return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); |
1045 | 220 | } |
1046 | | |
1047 | 0 | const_child_range children() const { |
1048 | 0 | return const_child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); |
1049 | 0 | } |
1050 | | }; |
1051 | | |
1052 | | /// A Microsoft C++ @c __uuidof expression, which gets |
1053 | | /// the _GUID that corresponds to the supplied type or expression. |
1054 | | /// |
1055 | | /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr) |
1056 | | class CXXUuidofExpr : public Expr { |
1057 | | friend class ASTStmtReader; |
1058 | | |
1059 | | private: |
1060 | | llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; |
1061 | | MSGuidDecl *Guid; |
1062 | | SourceRange Range; |
1063 | | |
1064 | | public: |
1065 | | CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, MSGuidDecl *Guid, |
1066 | | SourceRange R) |
1067 | | : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), |
1068 | 152 | Guid(Guid), Range(R) { |
1069 | 152 | setDependence(computeDependence(this)); |
1070 | 152 | } |
1071 | | |
1072 | | CXXUuidofExpr(QualType Ty, Expr *Operand, MSGuidDecl *Guid, SourceRange R) |
1073 | | : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), |
1074 | 22 | Guid(Guid), Range(R) { |
1075 | 22 | setDependence(computeDependence(this)); |
1076 | 22 | } |
1077 | | |
1078 | | CXXUuidofExpr(EmptyShell Empty, bool isExpr) |
1079 | 1 | : Expr(CXXUuidofExprClass, Empty) { |
1080 | 1 | if (isExpr) |
1081 | 1 | Operand = (Expr*)nullptr; |
1082 | 0 | else |
1083 | 0 | Operand = (TypeSourceInfo*)nullptr; |
1084 | 1 | } |
1085 | | |
1086 | 547 | bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); } |
1087 | | |
1088 | | /// Retrieves the type operand of this __uuidof() expression after |
1089 | | /// various required adjustments (removing reference types, cv-qualifiers). |
1090 | | QualType getTypeOperand(ASTContext &Context) const; |
1091 | | |
1092 | | /// Retrieve source information for the type operand. |
1093 | 193 | TypeSourceInfo *getTypeOperandSourceInfo() const { |
1094 | 193 | assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)"); |
1095 | 193 | return Operand.get<TypeSourceInfo *>(); |
1096 | 193 | } |
1097 | 23 | Expr *getExprOperand() const { |
1098 | 23 | assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)"); |
1099 | 23 | return static_cast<Expr*>(Operand.get<Stmt *>()); |
1100 | 23 | } |
1101 | | |
1102 | 259 | MSGuidDecl *getGuidDecl() const { return Guid; } |
1103 | | |
1104 | 692 | SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } |
1105 | 53 | SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } |
1106 | 44 | SourceRange getSourceRange() const LLVM_READONLY { return Range; } |
1107 | 1 | void setSourceRange(SourceRange R) { Range = R; } |
1108 | | |
1109 | 335 | static bool classof(const Stmt *T) { |
1110 | 335 | return T->getStmtClass() == CXXUuidofExprClass; |
1111 | 335 | } |
1112 | | |
1113 | | // Iterators |
1114 | 132 | child_range children() { |
1115 | 132 | if (isTypeOperand()) |
1116 | 110 | return child_range(child_iterator(), child_iterator()); |
1117 | 22 | auto **begin = reinterpret_cast<Stmt **>(&Operand); |
1118 | 22 | return child_range(begin, begin + 1); |
1119 | 22 | } |
1120 | | |
1121 | 0 | const_child_range children() const { |
1122 | 0 | if (isTypeOperand()) |
1123 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1124 | 0 | auto **begin = |
1125 | 0 | reinterpret_cast<Stmt **>(&const_cast<CXXUuidofExpr *>(this)->Operand); |
1126 | 0 | return const_child_range(begin, begin + 1); |
1127 | 0 | } |
1128 | | }; |
1129 | | |
1130 | | /// Represents the \c this expression in C++. |
1131 | | /// |
1132 | | /// This is a pointer to the object on which the current member function is |
1133 | | /// executing (C++ [expr.prim]p3). Example: |
1134 | | /// |
1135 | | /// \code |
1136 | | /// class Foo { |
1137 | | /// public: |
1138 | | /// void bar(); |
1139 | | /// void test() { this->bar(); } |
1140 | | /// }; |
1141 | | /// \endcode |
1142 | | class CXXThisExpr : public Expr { |
1143 | | public: |
1144 | | CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit) |
1145 | 1.21M | : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary) { |
1146 | 1.21M | CXXThisExprBits.IsImplicit = IsImplicit; |
1147 | 1.21M | CXXThisExprBits.Loc = L; |
1148 | 1.21M | setDependence(computeDependence(this)); |
1149 | 1.21M | } |
1150 | | |
1151 | 190k | CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} |
1152 | | |
1153 | 2.39M | SourceLocation getLocation() const { return CXXThisExprBits.Loc; } |
1154 | 190k | void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; } |
1155 | | |
1156 | 1.94M | SourceLocation getBeginLoc() const { return getLocation(); } |
1157 | 182k | SourceLocation getEndLoc() const { return getLocation(); } |
1158 | | |
1159 | 4.07M | bool isImplicit() const { return CXXThisExprBits.IsImplicit; } |
1160 | 190k | void setImplicit(bool I) { CXXThisExprBits.IsImplicit = I; } |
1161 | | |
1162 | 15.4M | static bool classof(const Stmt *T) { |
1163 | 15.4M | return T->getStmtClass() == CXXThisExprClass; |
1164 | 15.4M | } |
1165 | | |
1166 | | // Iterators |
1167 | 629k | child_range children() { |
1168 | 629k | return child_range(child_iterator(), child_iterator()); |
1169 | 629k | } |
1170 | | |
1171 | 0 | const_child_range children() const { |
1172 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1173 | 0 | } |
1174 | | }; |
1175 | | |
1176 | | /// A C++ throw-expression (C++ [except.throw]). |
1177 | | /// |
1178 | | /// This handles 'throw' (for re-throwing the current exception) and |
1179 | | /// 'throw' assignment-expression. When assignment-expression isn't |
1180 | | /// present, Op will be null. |
1181 | | class CXXThrowExpr : public Expr { |
1182 | | friend class ASTStmtReader; |
1183 | | |
1184 | | /// The optional expression in the throw statement. |
1185 | | Stmt *Operand; |
1186 | | |
1187 | | public: |
1188 | | // \p Ty is the void type which is used as the result type of the |
1189 | | // expression. The \p Loc is the location of the throw keyword. |
1190 | | // \p Operand is the expression in the throw statement, and can be |
1191 | | // null if not present. |
1192 | | CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc, |
1193 | | bool IsThrownVariableInScope) |
1194 | 13.6k | : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary), Operand(Operand) { |
1195 | 13.6k | CXXThrowExprBits.ThrowLoc = Loc; |
1196 | 13.6k | CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope; |
1197 | 13.6k | setDependence(computeDependence(this)); |
1198 | 13.6k | } |
1199 | 59 | CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} |
1200 | | |
1201 | 1.68k | const Expr *getSubExpr() const { return cast_or_null<Expr>(Operand); } |
1202 | 14.5k | Expr *getSubExpr() { return cast_or_null<Expr>(Operand); } |
1203 | | |
1204 | 42.8k | SourceLocation getThrowLoc() const { return CXXThrowExprBits.ThrowLoc; } |
1205 | | |
1206 | | /// Determines whether the variable thrown by this expression (if any!) |
1207 | | /// is within the innermost try block. |
1208 | | /// |
1209 | | /// This information is required to determine whether the NRVO can apply to |
1210 | | /// this variable. |
1211 | 697 | bool isThrownVariableInScope() const { |
1212 | 697 | return CXXThrowExprBits.IsThrownVariableInScope; |
1213 | 697 | } |
1214 | | |
1215 | 42.0k | SourceLocation getBeginLoc() const { return getThrowLoc(); } |
1216 | 46 | SourceLocation getEndLoc() const LLVM_READONLY { |
1217 | 46 | if (!getSubExpr()) |
1218 | 16 | return getThrowLoc(); |
1219 | 30 | return getSubExpr()->getEndLoc(); |
1220 | 30 | } |
1221 | | |
1222 | 369k | static bool classof(const Stmt *T) { |
1223 | 369k | return T->getStmtClass() == CXXThrowExprClass; |
1224 | 369k | } |
1225 | | |
1226 | | // Iterators |
1227 | 28.6k | child_range children() { |
1228 | 14.6k | return child_range(&Operand, Operand ? &Operand + 1 : &Operand13.9k ); |
1229 | 28.6k | } |
1230 | | |
1231 | 0 | const_child_range children() const { |
1232 | 0 | return const_child_range(&Operand, Operand ? &Operand + 1 : &Operand); |
1233 | 0 | } |
1234 | | }; |
1235 | | |
1236 | | /// A default argument (C++ [dcl.fct.default]). |
1237 | | /// |
1238 | | /// This wraps up a function call argument that was created from the |
1239 | | /// corresponding parameter's default argument, when the call did not |
1240 | | /// explicitly supply arguments for all of the parameters. |
1241 | | class CXXDefaultArgExpr final : public Expr { |
1242 | | friend class ASTStmtReader; |
1243 | | |
1244 | | /// The parameter whose default is being used. |
1245 | | ParmVarDecl *Param; |
1246 | | |
1247 | | /// The context where the default argument expression was used. |
1248 | | DeclContext *UsedContext; |
1249 | | |
1250 | | CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param, |
1251 | | DeclContext *UsedContext) |
1252 | | : Expr(SC, |
1253 | | Param->hasUnparsedDefaultArg() |
1254 | | ? Param->getType().getNonReferenceType() |
1255 | | : Param->getDefaultArg()->getType(), |
1256 | | Param->getDefaultArg()->getValueKind(), |
1257 | | Param->getDefaultArg()->getObjectKind()), |
1258 | 30.1k | Param(Param), UsedContext(UsedContext) { |
1259 | 30.1k | CXXDefaultArgExprBits.Loc = Loc; |
1260 | 30.1k | setDependence(ExprDependence::None); |
1261 | 30.1k | } |
1262 | | |
1263 | | public: |
1264 | 1.33k | CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {} |
1265 | | |
1266 | | // \p Param is the parameter whose default argument is used by this |
1267 | | // expression. |
1268 | | static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, |
1269 | | ParmVarDecl *Param, |
1270 | 30.1k | DeclContext *UsedContext) { |
1271 | 30.1k | return new (C) |
1272 | 30.1k | CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext); |
1273 | 30.1k | } |
1274 | | |
1275 | | // Retrieve the parameter that the argument was created from. |
1276 | 12.6k | const ParmVarDecl *getParam() const { return Param; } |
1277 | 12.1k | ParmVarDecl *getParam() { return Param; } |
1278 | | |
1279 | | // Retrieve the actual argument to the function call. |
1280 | 11.1k | const Expr *getExpr() const { return getParam()->getDefaultArg(); } |
1281 | 8.97k | Expr *getExpr() { return getParam()->getDefaultArg(); } |
1282 | | |
1283 | 315 | const DeclContext *getUsedContext() const { return UsedContext; } |
1284 | 3.12k | DeclContext *getUsedContext() { return UsedContext; } |
1285 | | |
1286 | | /// Retrieve the location where this default argument was actually used. |
1287 | 38.0k | SourceLocation getUsedLocation() const { return CXXDefaultArgExprBits.Loc; } |
1288 | | |
1289 | | /// Default argument expressions have no representation in the |
1290 | | /// source, so they have an empty source range. |
1291 | 13.3k | SourceLocation getBeginLoc() const { return SourceLocation(); } |
1292 | 5.93k | SourceLocation getEndLoc() const { return SourceLocation(); } |
1293 | | |
1294 | 34.6k | SourceLocation getExprLoc() const { return getUsedLocation(); } |
1295 | | |
1296 | 3.45M | static bool classof(const Stmt *T) { |
1297 | 3.45M | return T->getStmtClass() == CXXDefaultArgExprClass; |
1298 | 3.45M | } |
1299 | | |
1300 | | // Iterators |
1301 | 68.6k | child_range children() { |
1302 | 68.6k | return child_range(child_iterator(), child_iterator()); |
1303 | 68.6k | } |
1304 | | |
1305 | 0 | const_child_range children() const { |
1306 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1307 | 0 | } |
1308 | | }; |
1309 | | |
1310 | | /// A use of a default initializer in a constructor or in aggregate |
1311 | | /// initialization. |
1312 | | /// |
1313 | | /// This wraps a use of a C++ default initializer (technically, |
1314 | | /// a brace-or-equal-initializer for a non-static data member) when it |
1315 | | /// is implicitly used in a mem-initializer-list in a constructor |
1316 | | /// (C++11 [class.base.init]p8) or in aggregate initialization |
1317 | | /// (C++1y [dcl.init.aggr]p7). |
1318 | | class CXXDefaultInitExpr : public Expr { |
1319 | | friend class ASTReader; |
1320 | | friend class ASTStmtReader; |
1321 | | |
1322 | | /// The field whose default is being used. |
1323 | | FieldDecl *Field; |
1324 | | |
1325 | | /// The context where the default initializer expression was used. |
1326 | | DeclContext *UsedContext; |
1327 | | |
1328 | | CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc, |
1329 | | FieldDecl *Field, QualType Ty, DeclContext *UsedContext); |
1330 | | |
1331 | 110 | CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {} |
1332 | | |
1333 | | public: |
1334 | | /// \p Field is the non-static data member whose default initializer is used |
1335 | | /// by this expression. |
1336 | | static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc, |
1337 | 2.17k | FieldDecl *Field, DeclContext *UsedContext) { |
1338 | 2.17k | return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(), UsedContext); |
1339 | 2.17k | } |
1340 | | |
1341 | | /// Get the field whose initializer will be used. |
1342 | 1.96k | FieldDecl *getField() { return Field; } |
1343 | 1.66k | const FieldDecl *getField() const { return Field; } |
1344 | | |
1345 | | /// Get the initialization expression that will be used. |
1346 | 5.52k | const Expr *getExpr() const { |
1347 | 5.52k | assert(Field->getInClassInitializer() && "initializer hasn't been parsed"); |
1348 | 5.52k | return Field->getInClassInitializer(); |
1349 | 5.52k | } |
1350 | 5.86k | Expr *getExpr() { |
1351 | 5.86k | assert(Field->getInClassInitializer() && "initializer hasn't been parsed"); |
1352 | 5.86k | return Field->getInClassInitializer(); |
1353 | 5.86k | } |
1354 | | |
1355 | 184 | const DeclContext *getUsedContext() const { return UsedContext; } |
1356 | 144 | DeclContext *getUsedContext() { return UsedContext; } |
1357 | | |
1358 | | /// Retrieve the location where this default initializer expression was |
1359 | | /// actually used. |
1360 | 184 | SourceLocation getUsedLocation() const { return getBeginLoc(); } |
1361 | | |
1362 | 3.87k | SourceLocation getBeginLoc() const { return CXXDefaultInitExprBits.Loc; } |
1363 | 1.67k | SourceLocation getEndLoc() const { return CXXDefaultInitExprBits.Loc; } |
1364 | | |
1365 | 9.76M | static bool classof(const Stmt *T) { |
1366 | 9.76M | return T->getStmtClass() == CXXDefaultInitExprClass; |
1367 | 9.76M | } |
1368 | | |
1369 | | // Iterators |
1370 | 1.59k | child_range children() { |
1371 | 1.59k | return child_range(child_iterator(), child_iterator()); |
1372 | 1.59k | } |
1373 | | |
1374 | 0 | const_child_range children() const { |
1375 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1376 | 0 | } |
1377 | | }; |
1378 | | |
1379 | | /// Represents a C++ temporary. |
1380 | | class CXXTemporary { |
1381 | | /// The destructor that needs to be called. |
1382 | | const CXXDestructorDecl *Destructor; |
1383 | | |
1384 | | explicit CXXTemporary(const CXXDestructorDecl *destructor) |
1385 | 33.7k | : Destructor(destructor) {} |
1386 | | |
1387 | | public: |
1388 | | static CXXTemporary *Create(const ASTContext &C, |
1389 | | const CXXDestructorDecl *Destructor); |
1390 | | |
1391 | 21.7k | const CXXDestructorDecl *getDestructor() const { return Destructor; } |
1392 | | |
1393 | 2.08k | void setDestructor(const CXXDestructorDecl *Dtor) { |
1394 | 2.08k | Destructor = Dtor; |
1395 | 2.08k | } |
1396 | | }; |
1397 | | |
1398 | | /// Represents binding an expression to a temporary. |
1399 | | /// |
1400 | | /// This ensures the destructor is called for the temporary. It should only be |
1401 | | /// needed for non-POD, non-trivially destructable class types. For example: |
1402 | | /// |
1403 | | /// \code |
1404 | | /// struct S { |
1405 | | /// S() { } // User defined constructor makes S non-POD. |
1406 | | /// ~S() { } // User defined destructor makes it non-trivial. |
1407 | | /// }; |
1408 | | /// void test() { |
1409 | | /// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr. |
1410 | | /// } |
1411 | | /// \endcode |
1412 | | class CXXBindTemporaryExpr : public Expr { |
1413 | | CXXTemporary *Temp = nullptr; |
1414 | | Stmt *SubExpr = nullptr; |
1415 | | |
1416 | | CXXBindTemporaryExpr(CXXTemporary *temp, Expr *SubExpr) |
1417 | | : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_RValue, |
1418 | | OK_Ordinary), |
1419 | 31.3k | Temp(temp), SubExpr(SubExpr) { |
1420 | 31.3k | setDependence(computeDependence(this)); |
1421 | 31.3k | } |
1422 | | |
1423 | | public: |
1424 | | CXXBindTemporaryExpr(EmptyShell Empty) |
1425 | 2.40k | : Expr(CXXBindTemporaryExprClass, Empty) {} |
1426 | | |
1427 | | static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp, |
1428 | | Expr* SubExpr); |
1429 | | |
1430 | 20.7k | CXXTemporary *getTemporary() { return Temp; } |
1431 | 3.88k | const CXXTemporary *getTemporary() const { return Temp; } |
1432 | 2.40k | void setTemporary(CXXTemporary *T) { Temp = T; } |
1433 | | |
1434 | 73.6k | const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } |
1435 | 96.1k | Expr *getSubExpr() { return cast<Expr>(SubExpr); } |
1436 | 2.40k | void setSubExpr(Expr *E) { SubExpr = E; } |
1437 | | |
1438 | 250k | SourceLocation getBeginLoc() const LLVM_READONLY { |
1439 | 250k | return SubExpr->getBeginLoc(); |
1440 | 250k | } |
1441 | | |
1442 | 29.3k | SourceLocation getEndLoc() const LLVM_READONLY { |
1443 | 29.3k | return SubExpr->getEndLoc(); |
1444 | 29.3k | } |
1445 | | |
1446 | | // Implement isa/cast/dyncast/etc. |
1447 | 16.8M | static bool classof(const Stmt *T) { |
1448 | 16.8M | return T->getStmtClass() == CXXBindTemporaryExprClass; |
1449 | 16.8M | } |
1450 | | |
1451 | | // Iterators |
1452 | 58.7k | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } |
1453 | | |
1454 | 0 | const_child_range children() const { |
1455 | 0 | return const_child_range(&SubExpr, &SubExpr + 1); |
1456 | 0 | } |
1457 | | }; |
1458 | | |
1459 | | /// Represents a call to a C++ constructor. |
1460 | | class CXXConstructExpr : public Expr { |
1461 | | friend class ASTStmtReader; |
1462 | | |
1463 | | public: |
1464 | | enum ConstructionKind { |
1465 | | CK_Complete, |
1466 | | CK_NonVirtualBase, |
1467 | | CK_VirtualBase, |
1468 | | CK_Delegating |
1469 | | }; |
1470 | | |
1471 | | private: |
1472 | | /// A pointer to the constructor which will be ultimately called. |
1473 | | CXXConstructorDecl *Constructor; |
1474 | | |
1475 | | SourceRange ParenOrBraceRange; |
1476 | | |
1477 | | /// The number of arguments. |
1478 | | unsigned NumArgs; |
1479 | | |
1480 | | // We would like to stash the arguments of the constructor call after |
1481 | | // CXXConstructExpr. However CXXConstructExpr is used as a base class of |
1482 | | // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects |
1483 | | // impossible. |
1484 | | // |
1485 | | // Instead we manually stash the trailing object after the full object |
1486 | | // containing CXXConstructExpr (that is either CXXConstructExpr or |
1487 | | // CXXTemporaryObjectExpr). |
1488 | | // |
1489 | | // The trailing objects are: |
1490 | | // |
1491 | | // * An array of getNumArgs() "Stmt *" for the arguments of the |
1492 | | // constructor call. |
1493 | | |
1494 | | /// Return a pointer to the start of the trailing arguments. |
1495 | | /// Defined just after CXXTemporaryObjectExpr. |
1496 | | inline Stmt **getTrailingArgs(); |
1497 | 526k | const Stmt *const *getTrailingArgs() const { |
1498 | 526k | return const_cast<CXXConstructExpr *>(this)->getTrailingArgs(); |
1499 | 526k | } |
1500 | | |
1501 | | protected: |
1502 | | /// Build a C++ construction expression. |
1503 | | CXXConstructExpr(StmtClass SC, QualType Ty, SourceLocation Loc, |
1504 | | CXXConstructorDecl *Ctor, bool Elidable, |
1505 | | ArrayRef<Expr *> Args, bool HadMultipleCandidates, |
1506 | | bool ListInitialization, bool StdInitListInitialization, |
1507 | | bool ZeroInitialization, ConstructionKind ConstructKind, |
1508 | | SourceRange ParenOrBraceRange); |
1509 | | |
1510 | | /// Build an empty C++ construction expression. |
1511 | | CXXConstructExpr(StmtClass SC, EmptyShell Empty, unsigned NumArgs); |
1512 | | |
1513 | | /// Return the size in bytes of the trailing objects. Used by |
1514 | | /// CXXTemporaryObjectExpr to allocate the right amount of storage. |
1515 | 358k | static unsigned sizeOfTrailingObjects(unsigned NumArgs) { |
1516 | 358k | return NumArgs * sizeof(Stmt *); |
1517 | 358k | } |
1518 | | |
1519 | | public: |
1520 | | /// Create a C++ construction expression. |
1521 | | static CXXConstructExpr * |
1522 | | Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, |
1523 | | CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args, |
1524 | | bool HadMultipleCandidates, bool ListInitialization, |
1525 | | bool StdInitListInitialization, bool ZeroInitialization, |
1526 | | ConstructionKind ConstructKind, SourceRange ParenOrBraceRange); |
1527 | | |
1528 | | /// Create an empty C++ construction expression. |
1529 | | static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs); |
1530 | | |
1531 | | /// Get the constructor that this expression will (ultimately) call. |
1532 | 1.74M | CXXConstructorDecl *getConstructor() const { return Constructor; } |
1533 | | |
1534 | 1.36M | SourceLocation getLocation() const { return CXXConstructExprBits.Loc; } |
1535 | 0 | void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; } |
1536 | | |
1537 | | /// Whether this construction is elidable. |
1538 | 174k | bool isElidable() const { return CXXConstructExprBits.Elidable; } |
1539 | 0 | void setElidable(bool E) { CXXConstructExprBits.Elidable = E; } |
1540 | | |
1541 | | /// Whether the referred constructor was resolved from |
1542 | | /// an overloaded set having size greater than 1. |
1543 | 32.1k | bool hadMultipleCandidates() const { |
1544 | 32.1k | return CXXConstructExprBits.HadMultipleCandidates; |
1545 | 32.1k | } |
1546 | 0 | void setHadMultipleCandidates(bool V) { |
1547 | 0 | CXXConstructExprBits.HadMultipleCandidates = V; |
1548 | 0 | } |
1549 | | |
1550 | | /// Whether this constructor call was written as list-initialization. |
1551 | 288k | bool isListInitialization() const { |
1552 | 288k | return CXXConstructExprBits.ListInitialization; |
1553 | 288k | } |
1554 | 0 | void setListInitialization(bool V) { |
1555 | 0 | CXXConstructExprBits.ListInitialization = V; |
1556 | 0 | } |
1557 | | |
1558 | | /// Whether this constructor call was written as list-initialization, |
1559 | | /// but was interpreted as forming a std::initializer_list<T> from the list |
1560 | | /// and passing that as a single constructor argument. |
1561 | | /// See C++11 [over.match.list]p1 bullet 1. |
1562 | 35.4k | bool isStdInitListInitialization() const { |
1563 | 35.4k | return CXXConstructExprBits.StdInitListInitialization; |
1564 | 35.4k | } |
1565 | 0 | void setStdInitListInitialization(bool V) { |
1566 | 0 | CXXConstructExprBits.StdInitListInitialization = V; |
1567 | 0 | } |
1568 | | |
1569 | | /// Whether this construction first requires |
1570 | | /// zero-initialization before the initializer is called. |
1571 | 201k | bool requiresZeroInitialization() const { |
1572 | 201k | return CXXConstructExprBits.ZeroInitialization; |
1573 | 201k | } |
1574 | 0 | void setRequiresZeroInitialization(bool ZeroInit) { |
1575 | 0 | CXXConstructExprBits.ZeroInitialization = ZeroInit; |
1576 | 0 | } |
1577 | | |
1578 | | /// Determine whether this constructor is actually constructing |
1579 | | /// a base class (rather than a complete object). |
1580 | 142k | ConstructionKind getConstructionKind() const { |
1581 | 142k | return static_cast<ConstructionKind>(CXXConstructExprBits.ConstructionKind); |
1582 | 142k | } |
1583 | 0 | void setConstructionKind(ConstructionKind CK) { |
1584 | 0 | CXXConstructExprBits.ConstructionKind = CK; |
1585 | 0 | } |
1586 | | |
1587 | | using arg_iterator = ExprIterator; |
1588 | | using const_arg_iterator = ConstExprIterator; |
1589 | | using arg_range = llvm::iterator_range<arg_iterator>; |
1590 | | using const_arg_range = llvm::iterator_range<const_arg_iterator>; |
1591 | | |
1592 | 351k | arg_range arguments() { return arg_range(arg_begin(), arg_end()); } |
1593 | 35.2k | const_arg_range arguments() const { |
1594 | 35.2k | return const_arg_range(arg_begin(), arg_end()); |
1595 | 35.2k | } |
1596 | | |
1597 | 704k | arg_iterator arg_begin() { return getTrailingArgs(); } |
1598 | 352k | arg_iterator arg_end() { return arg_begin() + getNumArgs(); } |
1599 | 75.5k | const_arg_iterator arg_begin() const { return getTrailingArgs(); } |
1600 | 37.7k | const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); } |
1601 | | |
1602 | 401k | Expr **getArgs() { return reinterpret_cast<Expr **>(getTrailingArgs()); } |
1603 | 450k | const Expr *const *getArgs() const { |
1604 | 450k | return reinterpret_cast<const Expr *const *>(getTrailingArgs()); |
1605 | 450k | } |
1606 | | |
1607 | | /// Return the number of arguments to the constructor call. |
1608 | 2.65M | unsigned getNumArgs() const { return NumArgs; } |
1609 | | |
1610 | | /// Return the specified argument. |
1611 | 166k | Expr *getArg(unsigned Arg) { |
1612 | 166k | assert(Arg < getNumArgs() && "Arg access out of range!"); |
1613 | 166k | return getArgs()[Arg]; |
1614 | 166k | } |
1615 | 431k | const Expr *getArg(unsigned Arg) const { |
1616 | 431k | assert(Arg < getNumArgs() && "Arg access out of range!"); |
1617 | 431k | return getArgs()[Arg]; |
1618 | 431k | } |
1619 | | |
1620 | | /// Set the specified argument. |
1621 | 11.0k | void setArg(unsigned Arg, Expr *ArgExpr) { |
1622 | 11.0k | assert(Arg < getNumArgs() && "Arg access out of range!"); |
1623 | 11.0k | getArgs()[Arg] = ArgExpr; |
1624 | 11.0k | } |
1625 | | |
1626 | | SourceLocation getBeginLoc() const LLVM_READONLY; |
1627 | | SourceLocation getEndLoc() const LLVM_READONLY; |
1628 | 81.9k | SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; } |
1629 | 24.1k | void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; } |
1630 | | |
1631 | 10.5M | static bool classof(const Stmt *T) { |
1632 | 10.5M | return T->getStmtClass() == CXXConstructExprClass || |
1633 | 7.63M | T->getStmtClass() == CXXTemporaryObjectExprClass; |
1634 | 10.5M | } |
1635 | | |
1636 | | // Iterators |
1637 | 681k | child_range children() { |
1638 | 681k | return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs()); |
1639 | 681k | } |
1640 | | |
1641 | 0 | const_child_range children() const { |
1642 | 0 | auto Children = const_cast<CXXConstructExpr *>(this)->children(); |
1643 | 0 | return const_child_range(Children.begin(), Children.end()); |
1644 | 0 | } |
1645 | | }; |
1646 | | |
1647 | | /// Represents a call to an inherited base class constructor from an |
1648 | | /// inheriting constructor. This call implicitly forwards the arguments from |
1649 | | /// the enclosing context (an inheriting constructor) to the specified inherited |
1650 | | /// base class constructor. |
1651 | | class CXXInheritedCtorInitExpr : public Expr { |
1652 | | private: |
1653 | | CXXConstructorDecl *Constructor = nullptr; |
1654 | | |
1655 | | /// The location of the using declaration. |
1656 | | SourceLocation Loc; |
1657 | | |
1658 | | /// Whether this is the construction of a virtual base. |
1659 | | unsigned ConstructsVirtualBase : 1; |
1660 | | |
1661 | | /// Whether the constructor is inherited from a virtual base class of the |
1662 | | /// class that we construct. |
1663 | | unsigned InheritedFromVirtualBase : 1; |
1664 | | |
1665 | | public: |
1666 | | friend class ASTStmtReader; |
1667 | | |
1668 | | /// Construct a C++ inheriting construction expression. |
1669 | | CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T, |
1670 | | CXXConstructorDecl *Ctor, bool ConstructsVirtualBase, |
1671 | | bool InheritedFromVirtualBase) |
1672 | | : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary), |
1673 | | Constructor(Ctor), Loc(Loc), |
1674 | | ConstructsVirtualBase(ConstructsVirtualBase), |
1675 | 319 | InheritedFromVirtualBase(InheritedFromVirtualBase) { |
1676 | 319 | assert(!T->isDependentType()); |
1677 | 319 | setDependence(ExprDependence::None); |
1678 | 319 | } |
1679 | | |
1680 | | /// Construct an empty C++ inheriting construction expression. |
1681 | | explicit CXXInheritedCtorInitExpr(EmptyShell Empty) |
1682 | | : Expr(CXXInheritedCtorInitExprClass, Empty), |
1683 | 0 | ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {} |
1684 | | |
1685 | | /// Get the constructor that this expression will call. |
1686 | 303 | CXXConstructorDecl *getConstructor() const { return Constructor; } |
1687 | | |
1688 | | /// Determine whether this constructor is actually constructing |
1689 | | /// a base class (rather than a complete object). |
1690 | 204 | bool constructsVBase() const { return ConstructsVirtualBase; } |
1691 | 5 | CXXConstructExpr::ConstructionKind getConstructionKind() const { |
1692 | 0 | return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase |
1693 | 5 | : CXXConstructExpr::CK_NonVirtualBase; |
1694 | 5 | } |
1695 | | |
1696 | | /// Determine whether the inherited constructor is inherited from a |
1697 | | /// virtual base of the object we construct. If so, we are not responsible |
1698 | | /// for calling the inherited constructor (the complete object constructor |
1699 | | /// does that), and so we don't need to pass any arguments. |
1700 | 204 | bool inheritedFromVBase() const { return InheritedFromVirtualBase; } |
1701 | | |
1702 | 495 | SourceLocation getLocation() const LLVM_READONLY { return Loc; } |
1703 | 329 | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
1704 | 69 | SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } |
1705 | | |
1706 | 415k | static bool classof(const Stmt *T) { |
1707 | 415k | return T->getStmtClass() == CXXInheritedCtorInitExprClass; |
1708 | 415k | } |
1709 | | |
1710 | 450 | child_range children() { |
1711 | 450 | return child_range(child_iterator(), child_iterator()); |
1712 | 450 | } |
1713 | | |
1714 | 0 | const_child_range children() const { |
1715 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
1716 | 0 | } |
1717 | | }; |
1718 | | |
1719 | | /// Represents an explicit C++ type conversion that uses "functional" |
1720 | | /// notation (C++ [expr.type.conv]). |
1721 | | /// |
1722 | | /// Example: |
1723 | | /// \code |
1724 | | /// x = int(0.5); |
1725 | | /// \endcode |
1726 | | class CXXFunctionalCastExpr final |
1727 | | : public ExplicitCastExpr, |
1728 | | private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *, |
1729 | | FPOptionsOverride> { |
1730 | | SourceLocation LParenLoc; |
1731 | | SourceLocation RParenLoc; |
1732 | | |
1733 | | CXXFunctionalCastExpr(QualType ty, ExprValueKind VK, |
1734 | | TypeSourceInfo *writtenTy, CastKind kind, |
1735 | | Expr *castExpr, unsigned pathSize, |
1736 | | FPOptionsOverride FPO, SourceLocation lParenLoc, |
1737 | | SourceLocation rParenLoc) |
1738 | | : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, castExpr, |
1739 | | pathSize, FPO.requiresTrailingStorage(), writtenTy), |
1740 | 72.1k | LParenLoc(lParenLoc), RParenLoc(rParenLoc) { |
1741 | 72.1k | if (hasStoredFPFeatures()) |
1742 | 2 | *getTrailingFPFeatures() = FPO; |
1743 | 72.1k | } |
1744 | | |
1745 | | explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize, |
1746 | | bool HasFPFeatures) |
1747 | | : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize, |
1748 | 5.11k | HasFPFeatures) {} |
1749 | | |
1750 | 6 | unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const { |
1751 | 6 | return path_size(); |
1752 | 6 | } |
1753 | | |
1754 | | public: |
1755 | | friend class CastExpr; |
1756 | | friend TrailingObjects; |
1757 | | |
1758 | | static CXXFunctionalCastExpr * |
1759 | | Create(const ASTContext &Context, QualType T, ExprValueKind VK, |
1760 | | TypeSourceInfo *Written, CastKind Kind, Expr *Op, |
1761 | | const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc, |
1762 | | SourceLocation RPLoc); |
1763 | | static CXXFunctionalCastExpr * |
1764 | | CreateEmpty(const ASTContext &Context, unsigned PathSize, bool HasFPFeatures); |
1765 | | |
1766 | 15.6k | SourceLocation getLParenLoc() const { return LParenLoc; } |
1767 | 5.11k | void setLParenLoc(SourceLocation L) { LParenLoc = L; } |
1768 | 15.1k | SourceLocation getRParenLoc() const { return RParenLoc; } |
1769 | 5.11k | void setRParenLoc(SourceLocation L) { RParenLoc = L; } |
1770 | | |
1771 | | /// Determine whether this expression models list-initialization. |
1772 | 7.87k | bool isListInitialization() const { return LParenLoc.isInvalid(); } |
1773 | | |
1774 | | SourceLocation getBeginLoc() const LLVM_READONLY; |
1775 | | SourceLocation getEndLoc() const LLVM_READONLY; |
1776 | | |
1777 | 80.3k | static bool classof(const Stmt *T) { |
1778 | 80.3k | return T->getStmtClass() == CXXFunctionalCastExprClass; |
1779 | 80.3k | } |
1780 | | }; |
1781 | | |
1782 | | /// Represents a C++ functional cast expression that builds a |
1783 | | /// temporary object. |
1784 | | /// |
1785 | | /// This expression type represents a C++ "functional" cast |
1786 | | /// (C++[expr.type.conv]) with N != 1 arguments that invokes a |
1787 | | /// constructor to build a temporary object. With N == 1 arguments the |
1788 | | /// functional cast expression will be represented by CXXFunctionalCastExpr. |
1789 | | /// Example: |
1790 | | /// \code |
1791 | | /// struct X { X(int, float); } |
1792 | | /// |
1793 | | /// X create_X() { |
1794 | | /// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr |
1795 | | /// }; |
1796 | | /// \endcode |
1797 | | class CXXTemporaryObjectExpr final : public CXXConstructExpr { |
1798 | | friend class ASTStmtReader; |
1799 | | |
1800 | | // CXXTemporaryObjectExpr has some trailing objects belonging |
1801 | | // to CXXConstructExpr. See the comment inside CXXConstructExpr |
1802 | | // for more details. |
1803 | | |
1804 | | TypeSourceInfo *TSI; |
1805 | | |
1806 | | CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty, |
1807 | | TypeSourceInfo *TSI, ArrayRef<Expr *> Args, |
1808 | | SourceRange ParenOrBraceRange, |
1809 | | bool HadMultipleCandidates, bool ListInitialization, |
1810 | | bool StdInitListInitialization, |
1811 | | bool ZeroInitialization); |
1812 | | |
1813 | | CXXTemporaryObjectExpr(EmptyShell Empty, unsigned NumArgs); |
1814 | | |
1815 | | public: |
1816 | | static CXXTemporaryObjectExpr * |
1817 | | Create(const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty, |
1818 | | TypeSourceInfo *TSI, ArrayRef<Expr *> Args, |
1819 | | SourceRange ParenOrBraceRange, bool HadMultipleCandidates, |
1820 | | bool ListInitialization, bool StdInitListInitialization, |
1821 | | bool ZeroInitialization); |
1822 | | |
1823 | | static CXXTemporaryObjectExpr *CreateEmpty(const ASTContext &Ctx, |
1824 | | unsigned NumArgs); |
1825 | | |
1826 | 656k | TypeSourceInfo *getTypeSourceInfo() const { return TSI; } |
1827 | | |
1828 | | SourceLocation getBeginLoc() const LLVM_READONLY; |
1829 | | SourceLocation getEndLoc() const LLVM_READONLY; |
1830 | | |
1831 | 5.22M | static bool classof(const Stmt *T) { |
1832 | 5.22M | return T->getStmtClass() == CXXTemporaryObjectExprClass; |
1833 | 5.22M | } |
1834 | | }; |
1835 | | |
1836 | 3.33M | Stmt **CXXConstructExpr::getTrailingArgs() { |
1837 | 3.33M | if (auto *E = dyn_cast<CXXTemporaryObjectExpr>(this)) |
1838 | 402k | return reinterpret_cast<Stmt **>(E + 1); |
1839 | 2.93M | assert((getStmtClass() == CXXConstructExprClass) && |
1840 | 2.93M | "Unexpected class deriving from CXXConstructExpr!"); |
1841 | 2.93M | return reinterpret_cast<Stmt **>(this + 1); |
1842 | 2.93M | } |
1843 | | |
1844 | | /// A C++ lambda expression, which produces a function object |
1845 | | /// (of unspecified type) that can be invoked later. |
1846 | | /// |
1847 | | /// Example: |
1848 | | /// \code |
1849 | | /// void low_pass_filter(std::vector<double> &values, double cutoff) { |
1850 | | /// values.erase(std::remove_if(values.begin(), values.end(), |
1851 | | /// [=](double value) { return value > cutoff; }); |
1852 | | /// } |
1853 | | /// \endcode |
1854 | | /// |
1855 | | /// C++11 lambda expressions can capture local variables, either by copying |
1856 | | /// the values of those local variables at the time the function |
1857 | | /// object is constructed (not when it is called!) or by holding a |
1858 | | /// reference to the local variable. These captures can occur either |
1859 | | /// implicitly or can be written explicitly between the square |
1860 | | /// brackets ([...]) that start the lambda expression. |
1861 | | /// |
1862 | | /// C++1y introduces a new form of "capture" called an init-capture that |
1863 | | /// includes an initializing expression (rather than capturing a variable), |
1864 | | /// and which can never occur implicitly. |
1865 | | class LambdaExpr final : public Expr, |
1866 | | private llvm::TrailingObjects<LambdaExpr, Stmt *> { |
1867 | | // LambdaExpr has some data stored in LambdaExprBits. |
1868 | | |
1869 | | /// The source range that covers the lambda introducer ([...]). |
1870 | | SourceRange IntroducerRange; |
1871 | | |
1872 | | /// The source location of this lambda's capture-default ('=' or '&'). |
1873 | | SourceLocation CaptureDefaultLoc; |
1874 | | |
1875 | | /// The location of the closing brace ('}') that completes |
1876 | | /// the lambda. |
1877 | | /// |
1878 | | /// The location of the brace is also available by looking up the |
1879 | | /// function call operator in the lambda class. However, it is |
1880 | | /// stored here to improve the performance of getSourceRange(), and |
1881 | | /// to avoid having to deserialize the function call operator from a |
1882 | | /// module file just to determine the source range. |
1883 | | SourceLocation ClosingBrace; |
1884 | | |
1885 | | /// Construct a lambda expression. |
1886 | | LambdaExpr(QualType T, SourceRange IntroducerRange, |
1887 | | LambdaCaptureDefault CaptureDefault, |
1888 | | SourceLocation CaptureDefaultLoc, bool ExplicitParams, |
1889 | | bool ExplicitResultType, ArrayRef<Expr *> CaptureInits, |
1890 | | SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack); |
1891 | | |
1892 | | /// Construct an empty lambda expression. |
1893 | | LambdaExpr(EmptyShell Empty, unsigned NumCaptures); |
1894 | | |
1895 | 53.7k | Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); } |
1896 | 35.6k | Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); } |
1897 | | |
1898 | | void initBodyIfNeeded() const; |
1899 | | |
1900 | | public: |
1901 | | friend class ASTStmtReader; |
1902 | | friend class ASTStmtWriter; |
1903 | | friend TrailingObjects; |
1904 | | |
1905 | | /// Construct a new lambda expression. |
1906 | | static LambdaExpr * |
1907 | | Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange, |
1908 | | LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc, |
1909 | | bool ExplicitParams, bool ExplicitResultType, |
1910 | | ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace, |
1911 | | bool ContainsUnexpandedParameterPack); |
1912 | | |
1913 | | /// Construct a new lambda expression that will be deserialized from |
1914 | | /// an external source. |
1915 | | static LambdaExpr *CreateDeserialized(const ASTContext &C, |
1916 | | unsigned NumCaptures); |
1917 | | |
1918 | | /// Determine the default capture kind for this lambda. |
1919 | 14.6k | LambdaCaptureDefault getCaptureDefault() const { |
1920 | 14.6k | return static_cast<LambdaCaptureDefault>(LambdaExprBits.CaptureDefault); |
1921 | 14.6k | } |
1922 | | |
1923 | | /// Retrieve the location of this lambda's capture-default, if any. |
1924 | 2.51k | SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; } |
1925 | | |
1926 | | /// Determine whether one of this lambda's captures is an init-capture. |
1927 | | bool isInitCapture(const LambdaCapture *Capture) const; |
1928 | | |
1929 | | /// An iterator that walks over the captures of the lambda, |
1930 | | /// both implicit and explicit. |
1931 | | using capture_iterator = const LambdaCapture *; |
1932 | | |
1933 | | /// An iterator over a range of lambda captures. |
1934 | | using capture_range = llvm::iterator_range<capture_iterator>; |
1935 | | |
1936 | | /// Retrieve this lambda's captures. |
1937 | | capture_range captures() const; |
1938 | | |
1939 | | /// Retrieve an iterator pointing to the first lambda capture. |
1940 | | capture_iterator capture_begin() const; |
1941 | | |
1942 | | /// Retrieve an iterator pointing past the end of the |
1943 | | /// sequence of lambda captures. |
1944 | | capture_iterator capture_end() const; |
1945 | | |
1946 | | /// Determine the number of captures in this lambda. |
1947 | 64.9k | unsigned capture_size() const { return LambdaExprBits.NumCaptures; } |
1948 | | |
1949 | | /// Retrieve this lambda's explicit captures. |
1950 | | capture_range explicit_captures() const; |
1951 | | |
1952 | | /// Retrieve an iterator pointing to the first explicit |
1953 | | /// lambda capture. |
1954 | | capture_iterator explicit_capture_begin() const; |
1955 | | |
1956 | | /// Retrieve an iterator pointing past the end of the sequence of |
1957 | | /// explicit lambda captures. |
1958 | | capture_iterator explicit_capture_end() const; |
1959 | | |
1960 | | /// Retrieve this lambda's implicit captures. |
1961 | | capture_range implicit_captures() const; |
1962 | | |
1963 | | /// Retrieve an iterator pointing to the first implicit |
1964 | | /// lambda capture. |
1965 | | capture_iterator implicit_capture_begin() const; |
1966 | | |
1967 | | /// Retrieve an iterator pointing past the end of the sequence of |
1968 | | /// implicit lambda captures. |
1969 | | capture_iterator implicit_capture_end() const; |
1970 | | |
1971 | | /// Iterator that walks over the capture initialization |
1972 | | /// arguments. |
1973 | | using capture_init_iterator = Expr **; |
1974 | | |
1975 | | /// Const iterator that walks over the capture initialization |
1976 | | /// arguments. |
1977 | | /// FIXME: This interface is prone to being used incorrectly. |
1978 | | using const_capture_init_iterator = Expr *const *; |
1979 | | |
1980 | | /// Retrieve the initialization expressions for this lambda's captures. |
1981 | 4.95k | llvm::iterator_range<capture_init_iterator> capture_inits() { |
1982 | 4.95k | return llvm::make_range(capture_init_begin(), capture_init_end()); |
1983 | 4.95k | } |
1984 | | |
1985 | | /// Retrieve the initialization expressions for this lambda's captures. |
1986 | 1.23k | llvm::iterator_range<const_capture_init_iterator> capture_inits() const { |
1987 | 1.23k | return llvm::make_range(capture_init_begin(), capture_init_end()); |
1988 | 1.23k | } |
1989 | | |
1990 | | /// Retrieve the first initialization argument for this |
1991 | | /// lambda expression (which initializes the first capture field). |
1992 | 26.4k | capture_init_iterator capture_init_begin() { |
1993 | 26.4k | return reinterpret_cast<Expr **>(getStoredStmts()); |
1994 | 26.4k | } |
1995 | | |
1996 | | /// Retrieve the first initialization argument for this |
1997 | | /// lambda expression (which initializes the first capture field). |
1998 | 18.9k | const_capture_init_iterator capture_init_begin() const { |
1999 | 18.9k | return reinterpret_cast<Expr *const *>(getStoredStmts()); |
2000 | 18.9k | } |
2001 | | |
2002 | | /// Retrieve the iterator pointing one past the last |
2003 | | /// initialization argument for this lambda expression. |
2004 | 13.0k | capture_init_iterator capture_init_end() { |
2005 | 13.0k | return capture_init_begin() + capture_size(); |
2006 | 13.0k | } |
2007 | | |
2008 | | /// Retrieve the iterator pointing one past the last |
2009 | | /// initialization argument for this lambda expression. |
2010 | 9.21k | const_capture_init_iterator capture_init_end() const { |
2011 | 9.21k | return capture_init_begin() + capture_size(); |
2012 | 9.21k | } |
2013 | | |
2014 | | /// Retrieve the source range covering the lambda introducer, |
2015 | | /// which contains the explicit capture list surrounded by square |
2016 | | /// brackets ([...]). |
2017 | 7.45k | SourceRange getIntroducerRange() const { return IntroducerRange; } |
2018 | | |
2019 | | /// Retrieve the class that corresponds to the lambda. |
2020 | | /// |
2021 | | /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the |
2022 | | /// captures in its fields and provides the various operations permitted |
2023 | | /// on a lambda (copying, calling). |
2024 | | CXXRecordDecl *getLambdaClass() const; |
2025 | | |
2026 | | /// Retrieve the function call operator associated with this |
2027 | | /// lambda expression. |
2028 | | CXXMethodDecl *getCallOperator() const; |
2029 | | |
2030 | | /// Retrieve the function template call operator associated with this |
2031 | | /// lambda expression. |
2032 | | FunctionTemplateDecl *getDependentCallOperator() const; |
2033 | | |
2034 | | /// If this is a generic lambda expression, retrieve the template |
2035 | | /// parameter list associated with it, or else return null. |
2036 | | TemplateParameterList *getTemplateParameterList() const; |
2037 | | |
2038 | | /// Get the template parameters were explicitly specified (as opposed to being |
2039 | | /// invented by use of an auto parameter). |
2040 | | ArrayRef<NamedDecl *> getExplicitTemplateParameters() const; |
2041 | | |
2042 | | /// Get the trailing requires clause, if any. |
2043 | | Expr *getTrailingRequiresClause() const; |
2044 | | |
2045 | | /// Whether this is a generic lambda. |
2046 | 5 | bool isGenericLambda() const { return getTemplateParameterList(); } |
2047 | | |
2048 | | /// Retrieve the body of the lambda. This will be most of the time |
2049 | | /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping |
2050 | | /// a \p CompoundStmt. Note that unlike functions, lambda-expressions |
2051 | | /// cannot have a function-try-block. |
2052 | | Stmt *getBody() const; |
2053 | | |
2054 | | /// Retrieve the \p CompoundStmt representing the body of the lambda. |
2055 | | /// This is a convenience function for callers who do not need |
2056 | | /// to handle node(s) which may wrap a \p CompoundStmt. |
2057 | | const CompoundStmt *getCompoundStmtBody() const; |
2058 | 139 | CompoundStmt *getCompoundStmtBody() { |
2059 | 139 | const auto *ConstThis = this; |
2060 | 139 | return const_cast<CompoundStmt *>(ConstThis->getCompoundStmtBody()); |
2061 | 139 | } |
2062 | | |
2063 | | /// Determine whether the lambda is mutable, meaning that any |
2064 | | /// captures values can be modified. |
2065 | | bool isMutable() const; |
2066 | | |
2067 | | /// Determine whether this lambda has an explicit parameter |
2068 | | /// list vs. an implicit (empty) parameter list. |
2069 | 3.51k | bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; } |
2070 | | |
2071 | | /// Whether this lambda had its result type explicitly specified. |
2072 | 3.46k | bool hasExplicitResultType() const { |
2073 | 3.46k | return LambdaExprBits.ExplicitResultType; |
2074 | 3.46k | } |
2075 | | |
2076 | 3.55M | static bool classof(const Stmt *T) { |
2077 | 3.55M | return T->getStmtClass() == LambdaExprClass; |
2078 | 3.55M | } |
2079 | | |
2080 | 87.5k | SourceLocation getBeginLoc() const LLVM_READONLY { |
2081 | 87.5k | return IntroducerRange.getBegin(); |
2082 | 87.5k | } |
2083 | | |
2084 | 3.62k | SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; } |
2085 | | |
2086 | | /// Includes the captures and the body of the lambda. |
2087 | | child_range children(); |
2088 | | const_child_range children() const; |
2089 | | }; |
2090 | | |
2091 | | /// An expression "T()" which creates a value-initialized rvalue of type |
2092 | | /// T, which is a non-class type. See (C++98 [5.2.3p2]). |
2093 | | class CXXScalarValueInitExpr : public Expr { |
2094 | | friend class ASTStmtReader; |
2095 | | |
2096 | | TypeSourceInfo *TypeInfo; |
2097 | | |
2098 | | public: |
2099 | | /// Create an explicitly-written scalar-value initialization |
2100 | | /// expression. |
2101 | | CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo, |
2102 | | SourceLocation RParenLoc) |
2103 | | : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary), |
2104 | 16.3k | TypeInfo(TypeInfo) { |
2105 | 16.3k | CXXScalarValueInitExprBits.RParenLoc = RParenLoc; |
2106 | 16.3k | setDependence(computeDependence(this)); |
2107 | 16.3k | } |
2108 | | |
2109 | | explicit CXXScalarValueInitExpr(EmptyShell Shell) |
2110 | 677 | : Expr(CXXScalarValueInitExprClass, Shell) {} |
2111 | | |
2112 | 2.08k | TypeSourceInfo *getTypeSourceInfo() const { |
2113 | 2.08k | return TypeInfo; |
2114 | 2.08k | } |
2115 | | |
2116 | 1.53k | SourceLocation getRParenLoc() const { |
2117 | 1.53k | return CXXScalarValueInitExprBits.RParenLoc; |
2118 | 1.53k | } |
2119 | | |
2120 | | SourceLocation getBeginLoc() const LLVM_READONLY; |
2121 | 294 | SourceLocation getEndLoc() const { return getRParenLoc(); } |
2122 | | |
2123 | 74.6k | static bool classof(const Stmt *T) { |
2124 | 74.6k | return T->getStmtClass() == CXXScalarValueInitExprClass; |
2125 | 74.6k | } |
2126 | | |
2127 | | // Iterators |
2128 | 26.6k | child_range children() { |
2129 | 26.6k | return child_range(child_iterator(), child_iterator()); |
2130 | 26.6k | } |
2131 | | |
2132 | 0 | const_child_range children() const { |
2133 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
2134 | 0 | } |
2135 | | }; |
2136 | | |
2137 | | /// Represents a new-expression for memory allocation and constructor |
2138 | | /// calls, e.g: "new CXXNewExpr(foo)". |
2139 | | class CXXNewExpr final |
2140 | | : public Expr, |
2141 | | private llvm::TrailingObjects<CXXNewExpr, Stmt *, SourceRange> { |
2142 | | friend class ASTStmtReader; |
2143 | | friend class ASTStmtWriter; |
2144 | | friend TrailingObjects; |
2145 | | |
2146 | | /// Points to the allocation function used. |
2147 | | FunctionDecl *OperatorNew; |
2148 | | |
2149 | | /// Points to the deallocation function used in case of error. May be null. |
2150 | | FunctionDecl *OperatorDelete; |
2151 | | |
2152 | | /// The allocated type-source information, as written in the source. |
2153 | | TypeSourceInfo *AllocatedTypeInfo; |
2154 | | |
2155 | | /// Range of the entire new expression. |
2156 | | SourceRange Range; |
2157 | | |
2158 | | /// Source-range of a paren-delimited initializer. |
2159 | | SourceRange DirectInitRange; |
2160 | | |
2161 | | // CXXNewExpr is followed by several optional trailing objects. |
2162 | | // They are in order: |
2163 | | // |
2164 | | // * An optional "Stmt *" for the array size expression. |
2165 | | // Present if and ony if isArray(). |
2166 | | // |
2167 | | // * An optional "Stmt *" for the init expression. |
2168 | | // Present if and only if hasInitializer(). |
2169 | | // |
2170 | | // * An array of getNumPlacementArgs() "Stmt *" for the placement new |
2171 | | // arguments, if any. |
2172 | | // |
2173 | | // * An optional SourceRange for the range covering the parenthesized type-id |
2174 | | // if the allocated type was expressed as a parenthesized type-id. |
2175 | | // Present if and only if isParenTypeId(). |
2176 | 154k | unsigned arraySizeOffset() const { return 0; } |
2177 | 149k | unsigned initExprOffset() const { return arraySizeOffset() + isArray(); } |
2178 | 88.8k | unsigned placementNewArgsOffset() const { |
2179 | 88.8k | return initExprOffset() + hasInitializer(); |
2180 | 88.8k | } |
2181 | | |
2182 | 23.2k | unsigned numTrailingObjects(OverloadToken<Stmt *>) const { |
2183 | 23.2k | return isArray() + hasInitializer() + getNumPlacementArgs(); |
2184 | 23.2k | } |
2185 | | |
2186 | 0 | unsigned numTrailingObjects(OverloadToken<SourceRange>) const { |
2187 | 0 | return isParenTypeId(); |
2188 | 0 | } |
2189 | | |
2190 | | public: |
2191 | | enum InitializationStyle { |
2192 | | /// New-expression has no initializer as written. |
2193 | | NoInit, |
2194 | | |
2195 | | /// New-expression has a C++98 paren-delimited initializer. |
2196 | | CallInit, |
2197 | | |
2198 | | /// New-expression has a C++11 list-initializer. |
2199 | | ListInit |
2200 | | }; |
2201 | | |
2202 | | private: |
2203 | | /// Build a c++ new expression. |
2204 | | CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew, |
2205 | | FunctionDecl *OperatorDelete, bool ShouldPassAlignment, |
2206 | | bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs, |
2207 | | SourceRange TypeIdParens, Optional<Expr *> ArraySize, |
2208 | | InitializationStyle InitializationStyle, Expr *Initializer, |
2209 | | QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, |
2210 | | SourceRange DirectInitRange); |
2211 | | |
2212 | | /// Build an empty c++ new expression. |
2213 | | CXXNewExpr(EmptyShell Empty, bool IsArray, unsigned NumPlacementArgs, |
2214 | | bool IsParenTypeId); |
2215 | | |
2216 | | public: |
2217 | | /// Create a c++ new expression. |
2218 | | static CXXNewExpr * |
2219 | | Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew, |
2220 | | FunctionDecl *OperatorDelete, bool ShouldPassAlignment, |
2221 | | bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs, |
2222 | | SourceRange TypeIdParens, Optional<Expr *> ArraySize, |
2223 | | InitializationStyle InitializationStyle, Expr *Initializer, |
2224 | | QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, |
2225 | | SourceRange DirectInitRange); |
2226 | | |
2227 | | /// Create an empty c++ new expression. |
2228 | | static CXXNewExpr *CreateEmpty(const ASTContext &Ctx, bool IsArray, |
2229 | | bool HasInit, unsigned NumPlacementArgs, |
2230 | | bool IsParenTypeId); |
2231 | | |
2232 | 9.22k | QualType getAllocatedType() const { |
2233 | 9.22k | return getType()->castAs<PointerType>()->getPointeeType(); |
2234 | 9.22k | } |
2235 | | |
2236 | 10.2k | TypeSourceInfo *getAllocatedTypeSourceInfo() const { |
2237 | 10.2k | return AllocatedTypeInfo; |
2238 | 10.2k | } |
2239 | | |
2240 | | /// True if the allocation result needs to be null-checked. |
2241 | | /// |
2242 | | /// C++11 [expr.new]p13: |
2243 | | /// If the allocation function returns null, initialization shall |
2244 | | /// not be done, the deallocation function shall not be called, |
2245 | | /// and the value of the new-expression shall be null. |
2246 | | /// |
2247 | | /// C++ DR1748: |
2248 | | /// If the allocation function is a reserved placement allocation |
2249 | | /// function that returns null, the behavior is undefined. |
2250 | | /// |
2251 | | /// An allocation function is not allowed to return null unless it |
2252 | | /// has a non-throwing exception-specification. The '03 rule is |
2253 | | /// identical except that the definition of a non-throwing |
2254 | | /// exception specification is just "is it throw()?". |
2255 | | bool shouldNullCheckAllocation() const; |
2256 | | |
2257 | 52.8k | FunctionDecl *getOperatorNew() const { return OperatorNew; } |
2258 | 1.07k | void setOperatorNew(FunctionDecl *D) { OperatorNew = D; } |
2259 | 10.9k | FunctionDecl *getOperatorDelete() const { return OperatorDelete; } |
2260 | 1.07k | void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; } |
2261 | | |
2262 | 226k | bool isArray() const { return CXXNewExprBits.IsArray; } |
2263 | | |
2264 | 30.8k | Optional<Expr *> getArraySize() { |
2265 | 30.8k | if (!isArray()) |
2266 | 28.4k | return None; |
2267 | 2.42k | return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]); |
2268 | 2.42k | } |
2269 | 1.98k | Optional<const Expr *> getArraySize() const { |
2270 | 1.98k | if (!isArray()) |
2271 | 634 | return None; |
2272 | 1.34k | return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]); |
2273 | 1.34k | } |
2274 | | |
2275 | 75.3k | unsigned getNumPlacementArgs() const { |
2276 | 75.3k | return CXXNewExprBits.NumPlacementArgs; |
2277 | 75.3k | } |
2278 | | |
2279 | 4.45k | Expr **getPlacementArgs() { |
2280 | 4.45k | return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>() + |
2281 | 4.45k | placementNewArgsOffset()); |
2282 | 4.45k | } |
2283 | | |
2284 | 2.82k | Expr *getPlacementArg(unsigned I) { |
2285 | 2.82k | assert((I < getNumPlacementArgs()) && "Index out of range!"); |
2286 | 2.82k | return getPlacementArgs()[I]; |
2287 | 2.82k | } |
2288 | 2.78k | const Expr *getPlacementArg(unsigned I) const { |
2289 | 2.78k | return const_cast<CXXNewExpr *>(this)->getPlacementArg(I); |
2290 | 2.78k | } |
2291 | | |
2292 | 8.16k | bool isParenTypeId() const { return CXXNewExprBits.IsParenTypeId; } |
2293 | 2.53k | SourceRange getTypeIdParens() const { |
2294 | 10 | return isParenTypeId() ? getTrailingObjects<SourceRange>()[0] |
2295 | 2.52k | : SourceRange(); |
2296 | 2.53k | } |
2297 | | |
2298 | 5.50k | bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; } |
2299 | | |
2300 | | /// Whether this new-expression has any initializer at all. |
2301 | 155k | bool hasInitializer() const { |
2302 | 155k | return CXXNewExprBits.StoredInitializationStyle > 0; |
2303 | 155k | } |
2304 | | |
2305 | | /// The kind of initializer this new-expression has. |
2306 | 29.3k | InitializationStyle getInitializationStyle() const { |
2307 | 29.3k | if (CXXNewExprBits.StoredInitializationStyle == 0) |
2308 | 1.97k | return NoInit; |
2309 | 27.3k | return static_cast<InitializationStyle>( |
2310 | 27.3k | CXXNewExprBits.StoredInitializationStyle - 1); |
2311 | 27.3k | } |
2312 | | |
2313 | | /// The initializer of this new-expression. |
2314 | 33.5k | Expr *getInitializer() { |
2315 | 33.5k | return hasInitializer() |
2316 | 30.7k | ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()]) |
2317 | 2.82k | : nullptr; |
2318 | 33.5k | } |
2319 | 6.18k | const Expr *getInitializer() const { |
2320 | 6.18k | return hasInitializer() |
2321 | 4.68k | ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()]) |
2322 | 1.50k | : nullptr; |
2323 | 6.18k | } |
2324 | | |
2325 | | /// Returns the CXXConstructExpr from this new-expression, or null. |
2326 | 2.38k | const CXXConstructExpr *getConstructExpr() const { |
2327 | 2.38k | return dyn_cast_or_null<CXXConstructExpr>(getInitializer()); |
2328 | 2.38k | } |
2329 | | |
2330 | | /// Indicates whether the required alignment should be implicitly passed to |
2331 | | /// the allocation function. |
2332 | 23.5k | bool passAlignment() const { return CXXNewExprBits.ShouldPassAlignment; } |
2333 | | |
2334 | | /// Answers whether the usual array deallocation function for the |
2335 | | /// allocated type expects the size of the allocation as a |
2336 | | /// parameter. |
2337 | 3.11k | bool doesUsualArrayDeleteWantSize() const { |
2338 | 3.11k | return CXXNewExprBits.UsualArrayDeleteWantsSize; |
2339 | 3.11k | } |
2340 | | |
2341 | | using arg_iterator = ExprIterator; |
2342 | | using const_arg_iterator = ConstExprIterator; |
2343 | | |
2344 | 27.9k | llvm::iterator_range<arg_iterator> placement_arguments() { |
2345 | 27.9k | return llvm::make_range(placement_arg_begin(), placement_arg_end()); |
2346 | 27.9k | } |
2347 | | |
2348 | 1.95k | llvm::iterator_range<const_arg_iterator> placement_arguments() const { |
2349 | 1.95k | return llvm::make_range(placement_arg_begin(), placement_arg_end()); |
2350 | 1.95k | } |
2351 | | |
2352 | 60.6k | arg_iterator placement_arg_begin() { |
2353 | 60.6k | return getTrailingObjects<Stmt *>() + placementNewArgsOffset(); |
2354 | 60.6k | } |
2355 | 30.3k | arg_iterator placement_arg_end() { |
2356 | 30.3k | return placement_arg_begin() + getNumPlacementArgs(); |
2357 | 30.3k | } |
2358 | 3.91k | const_arg_iterator placement_arg_begin() const { |
2359 | 3.91k | return getTrailingObjects<Stmt *>() + placementNewArgsOffset(); |
2360 | 3.91k | } |
2361 | 1.95k | const_arg_iterator placement_arg_end() const { |
2362 | 1.95k | return placement_arg_begin() + getNumPlacementArgs(); |
2363 | 1.95k | } |
2364 | | |
2365 | | using raw_arg_iterator = Stmt **; |
2366 | | |
2367 | 46.4k | raw_arg_iterator raw_arg_begin() { return getTrailingObjects<Stmt *>(); } |
2368 | 23.2k | raw_arg_iterator raw_arg_end() { |
2369 | 23.2k | return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>()); |
2370 | 23.2k | } |
2371 | 0 | const_arg_iterator raw_arg_begin() const { |
2372 | 0 | return getTrailingObjects<Stmt *>(); |
2373 | 0 | } |
2374 | 0 | const_arg_iterator raw_arg_end() const { |
2375 | 0 | return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>()); |
2376 | 0 | } |
2377 | | |
2378 | 84.4k | SourceLocation getBeginLoc() const { return Range.getBegin(); } |
2379 | 1.07k | SourceLocation getEndLoc() const { return Range.getEnd(); } |
2380 | | |
2381 | 4.06k | SourceRange getDirectInitRange() const { return DirectInitRange; } |
2382 | 10.8k | SourceRange getSourceRange() const { return Range; } |
2383 | | |
2384 | 1.41M | static bool classof(const Stmt *T) { |
2385 | 1.41M | return T->getStmtClass() == CXXNewExprClass; |
2386 | 1.41M | } |
2387 | | |
2388 | | // Iterators |
2389 | 20.5k | child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); } |
2390 | | |
2391 | 0 | const_child_range children() const { |
2392 | 0 | return const_child_range(const_cast<CXXNewExpr *>(this)->children()); |
2393 | 0 | } |
2394 | | }; |
2395 | | |
2396 | | /// Represents a \c delete expression for memory deallocation and |
2397 | | /// destructor calls, e.g. "delete[] pArray". |
2398 | | class CXXDeleteExpr : public Expr { |
2399 | | friend class ASTStmtReader; |
2400 | | |
2401 | | /// Points to the operator delete overload that is used. Could be a member. |
2402 | | FunctionDecl *OperatorDelete = nullptr; |
2403 | | |
2404 | | /// The pointer expression to be deleted. |
2405 | | Stmt *Argument = nullptr; |
2406 | | |
2407 | | public: |
2408 | | CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm, |
2409 | | bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize, |
2410 | | FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc) |
2411 | | : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary), |
2412 | 4.83k | OperatorDelete(OperatorDelete), Argument(Arg) { |
2413 | 4.83k | CXXDeleteExprBits.GlobalDelete = GlobalDelete; |
2414 | 4.83k | CXXDeleteExprBits.ArrayForm = ArrayForm; |
2415 | 4.83k | CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten; |
2416 | 4.83k | CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize; |
2417 | 4.83k | CXXDeleteExprBits.Loc = Loc; |
2418 | 4.83k | setDependence(computeDependence(this)); |
2419 | 4.83k | } |
2420 | | |
2421 | 411 | explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {} |
2422 | | |
2423 | 1.79k | bool isGlobalDelete() const { return CXXDeleteExprBits.GlobalDelete; } |
2424 | 8.31k | bool isArrayForm() const { return CXXDeleteExprBits.ArrayForm; } |
2425 | 646 | bool isArrayFormAsWritten() const { |
2426 | 646 | return CXXDeleteExprBits.ArrayFormAsWritten; |
2427 | 646 | } |
2428 | | |
2429 | | /// Answers whether the usual array deallocation function for the |
2430 | | /// allocated type expects the size of the allocation as a |
2431 | | /// parameter. This can be true even if the actual deallocation |
2432 | | /// function that we're using doesn't want a size. |
2433 | 838 | bool doesUsualArrayDeleteWantSize() const { |
2434 | 838 | return CXXDeleteExprBits.UsualArrayDeleteWantsSize; |
2435 | 838 | } |
2436 | | |
2437 | 18.0k | FunctionDecl *getOperatorDelete() const { return OperatorDelete; } |
2438 | | |
2439 | 6.90k | Expr *getArgument() { return cast<Expr>(Argument); } |
2440 | 9.96k | const Expr *getArgument() const { return cast<Expr>(Argument); } |
2441 | | |
2442 | | /// Retrieve the type being destroyed. |
2443 | | /// |
2444 | | /// If the type being destroyed is a dependent type which may or may not |
2445 | | /// be a pointer, return an invalid type. |
2446 | | QualType getDestroyedType() const; |
2447 | | |
2448 | 18.9k | SourceLocation getBeginLoc() const { return CXXDeleteExprBits.Loc; } |
2449 | 1.97k | SourceLocation getEndLoc() const LLVM_READONLY { |
2450 | 1.97k | return Argument->getEndLoc(); |
2451 | 1.97k | } |
2452 | | |
2453 | 28.1k | static bool classof(const Stmt *T) { |
2454 | 28.1k | return T->getStmtClass() == CXXDeleteExprClass; |
2455 | 28.1k | } |
2456 | | |
2457 | | // Iterators |
2458 | 7.46k | child_range children() { return child_range(&Argument, &Argument + 1); } |
2459 | | |
2460 | 0 | const_child_range children() const { |
2461 | 0 | return const_child_range(&Argument, &Argument + 1); |
2462 | 0 | } |
2463 | | }; |
2464 | | |
2465 | | /// Stores the type being destroyed by a pseudo-destructor expression. |
2466 | | class PseudoDestructorTypeStorage { |
2467 | | /// Either the type source information or the name of the type, if |
2468 | | /// it couldn't be resolved due to type-dependence. |
2469 | | llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type; |
2470 | | |
2471 | | /// The starting source location of the pseudo-destructor type. |
2472 | | SourceLocation Location; |
2473 | | |
2474 | | public: |
2475 | 9.27k | PseudoDestructorTypeStorage() = default; |
2476 | | |
2477 | | PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc) |
2478 | 7 | : Type(II), Location(Loc) {} |
2479 | | |
2480 | | PseudoDestructorTypeStorage(TypeSourceInfo *Info); |
2481 | | |
2482 | 40.9k | TypeSourceInfo *getTypeSourceInfo() const { |
2483 | 40.9k | return Type.dyn_cast<TypeSourceInfo *>(); |
2484 | 40.9k | } |
2485 | | |
2486 | 2.07k | IdentifierInfo *getIdentifier() const { |
2487 | 2.07k | return Type.dyn_cast<IdentifierInfo *>(); |
2488 | 2.07k | } |
2489 | | |
2490 | 1.12k | SourceLocation getLocation() const { return Location; } |
2491 | | }; |
2492 | | |
2493 | | /// Represents a C++ pseudo-destructor (C++ [expr.pseudo]). |
2494 | | /// |
2495 | | /// A pseudo-destructor is an expression that looks like a member access to a |
2496 | | /// destructor of a scalar type, except that scalar types don't have |
2497 | | /// destructors. For example: |
2498 | | /// |
2499 | | /// \code |
2500 | | /// typedef int T; |
2501 | | /// void f(int *p) { |
2502 | | /// p->T::~T(); |
2503 | | /// } |
2504 | | /// \endcode |
2505 | | /// |
2506 | | /// Pseudo-destructors typically occur when instantiating templates such as: |
2507 | | /// |
2508 | | /// \code |
2509 | | /// template<typename T> |
2510 | | /// void destroy(T* ptr) { |
2511 | | /// ptr->T::~T(); |
2512 | | /// } |
2513 | | /// \endcode |
2514 | | /// |
2515 | | /// for scalar types. A pseudo-destructor expression has no run-time semantics |
2516 | | /// beyond evaluating the base expression. |
2517 | | class CXXPseudoDestructorExpr : public Expr { |
2518 | | friend class ASTStmtReader; |
2519 | | |
2520 | | /// The base expression (that is being destroyed). |
2521 | | Stmt *Base = nullptr; |
2522 | | |
2523 | | /// Whether the operator was an arrow ('->'); otherwise, it was a |
2524 | | /// period ('.'). |
2525 | | bool IsArrow : 1; |
2526 | | |
2527 | | /// The location of the '.' or '->' operator. |
2528 | | SourceLocation OperatorLoc; |
2529 | | |
2530 | | /// The nested-name-specifier that follows the operator, if present. |
2531 | | NestedNameSpecifierLoc QualifierLoc; |
2532 | | |
2533 | | /// The type that precedes the '::' in a qualified pseudo-destructor |
2534 | | /// expression. |
2535 | | TypeSourceInfo *ScopeType = nullptr; |
2536 | | |
2537 | | /// The location of the '::' in a qualified pseudo-destructor |
2538 | | /// expression. |
2539 | | SourceLocation ColonColonLoc; |
2540 | | |
2541 | | /// The location of the '~'. |
2542 | | SourceLocation TildeLoc; |
2543 | | |
2544 | | /// The type being destroyed, or its name if we were unable to |
2545 | | /// resolve the name. |
2546 | | PseudoDestructorTypeStorage DestroyedType; |
2547 | | |
2548 | | public: |
2549 | | CXXPseudoDestructorExpr(const ASTContext &Context, |
2550 | | Expr *Base, bool isArrow, SourceLocation OperatorLoc, |
2551 | | NestedNameSpecifierLoc QualifierLoc, |
2552 | | TypeSourceInfo *ScopeType, |
2553 | | SourceLocation ColonColonLoc, |
2554 | | SourceLocation TildeLoc, |
2555 | | PseudoDestructorTypeStorage DestroyedType); |
2556 | | |
2557 | | explicit CXXPseudoDestructorExpr(EmptyShell Shell) |
2558 | 460 | : Expr(CXXPseudoDestructorExprClass, Shell), IsArrow(false) {} |
2559 | | |
2560 | 10.0k | Expr *getBase() const { return cast<Expr>(Base); } |
2561 | | |
2562 | | /// Determines whether this member expression actually had |
2563 | | /// a C++ nested-name-specifier prior to the name of the member, e.g., |
2564 | | /// x->Base::foo. |
2565 | 0 | bool hasQualifier() const { return QualifierLoc.hasQualifier(); } |
2566 | | |
2567 | | /// Retrieves the nested-name-specifier that qualifies the type name, |
2568 | | /// with source-location information. |
2569 | 2.17k | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
2570 | | |
2571 | | /// If the member name was qualified, retrieves the |
2572 | | /// nested-name-specifier that precedes the member name. Otherwise, returns |
2573 | | /// null. |
2574 | 12.2k | NestedNameSpecifier *getQualifier() const { |
2575 | 12.2k | return QualifierLoc.getNestedNameSpecifier(); |
2576 | 12.2k | } |
2577 | | |
2578 | | /// Determine whether this pseudo-destructor expression was written |
2579 | | /// using an '->' (otherwise, it used a '.'). |
2580 | 7.01k | bool isArrow() const { return IsArrow; } |
2581 | | |
2582 | | /// Retrieve the location of the '.' or '->' operator. |
2583 | 2.82k | SourceLocation getOperatorLoc() const { return OperatorLoc; } |
2584 | | |
2585 | | /// Retrieve the scope type in a qualified pseudo-destructor |
2586 | | /// expression. |
2587 | | /// |
2588 | | /// Pseudo-destructor expressions can have extra qualification within them |
2589 | | /// that is not part of the nested-name-specifier, e.g., \c p->T::~T(). |
2590 | | /// Here, if the object type of the expression is (or may be) a scalar type, |
2591 | | /// \p T may also be a scalar type and, therefore, cannot be part of a |
2592 | | /// nested-name-specifier. It is stored as the "scope type" of the pseudo- |
2593 | | /// destructor expression. |
2594 | 18.7k | TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; } |
2595 | | |
2596 | | /// Retrieve the location of the '::' in a qualified pseudo-destructor |
2597 | | /// expression. |
2598 | 1.74k | SourceLocation getColonColonLoc() const { return ColonColonLoc; } |
2599 | | |
2600 | | /// Retrieve the location of the '~'. |
2601 | 1.75k | SourceLocation getTildeLoc() const { return TildeLoc; } |
2602 | | |
2603 | | /// Retrieve the source location information for the type |
2604 | | /// being destroyed. |
2605 | | /// |
2606 | | /// This type-source information is available for non-dependent |
2607 | | /// pseudo-destructor expressions and some dependent pseudo-destructor |
2608 | | /// expressions. Returns null if we only have the identifier for a |
2609 | | /// dependent pseudo-destructor expression. |
2610 | 11.5k | TypeSourceInfo *getDestroyedTypeInfo() const { |
2611 | 11.5k | return DestroyedType.getTypeSourceInfo(); |
2612 | 11.5k | } |
2613 | | |
2614 | | /// In a dependent pseudo-destructor expression for which we do not |
2615 | | /// have full type information on the destroyed type, provides the name |
2616 | | /// of the destroyed type. |
2617 | 1.03k | IdentifierInfo *getDestroyedTypeIdentifier() const { |
2618 | 1.03k | return DestroyedType.getIdentifier(); |
2619 | 1.03k | } |
2620 | | |
2621 | | /// Retrieve the type being destroyed. |
2622 | | QualType getDestroyedType() const; |
2623 | | |
2624 | | /// Retrieve the starting location of the type being destroyed. |
2625 | 12 | SourceLocation getDestroyedTypeLoc() const { |
2626 | 12 | return DestroyedType.getLocation(); |
2627 | 12 | } |
2628 | | |
2629 | | /// Set the name of destroyed type for a dependent pseudo-destructor |
2630 | | /// expression. |
2631 | 0 | void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) { |
2632 | 0 | DestroyedType = PseudoDestructorTypeStorage(II, Loc); |
2633 | 0 | } |
2634 | | |
2635 | | /// Set the destroyed type. |
2636 | 460 | void setDestroyedType(TypeSourceInfo *Info) { |
2637 | 460 | DestroyedType = PseudoDestructorTypeStorage(Info); |
2638 | 460 | } |
2639 | | |
2640 | 15.8k | SourceLocation getBeginLoc() const LLVM_READONLY { |
2641 | 15.8k | return Base->getBeginLoc(); |
2642 | 15.8k | } |
2643 | | SourceLocation getEndLoc() const LLVM_READONLY; |
2644 | | |
2645 | 3.10M | static bool classof(const Stmt *T) { |
2646 | 3.10M | return T->getStmtClass() == CXXPseudoDestructorExprClass; |
2647 | 3.10M | } |
2648 | | |
2649 | | // Iterators |
2650 | 5.63k | child_range children() { return child_range(&Base, &Base + 1); } |
2651 | | |
2652 | 0 | const_child_range children() const { |
2653 | 0 | return const_child_range(&Base, &Base + 1); |
2654 | 0 | } |
2655 | | }; |
2656 | | |
2657 | | /// A type trait used in the implementation of various C++11 and |
2658 | | /// Library TR1 trait templates. |
2659 | | /// |
2660 | | /// \code |
2661 | | /// __is_pod(int) == true |
2662 | | /// __is_enum(std::string) == false |
2663 | | /// __is_trivially_constructible(vector<int>, int*, int*) |
2664 | | /// \endcode |
2665 | | class TypeTraitExpr final |
2666 | | : public Expr, |
2667 | | private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> { |
2668 | | /// The location of the type trait keyword. |
2669 | | SourceLocation Loc; |
2670 | | |
2671 | | /// The location of the closing parenthesis. |
2672 | | SourceLocation RParenLoc; |
2673 | | |
2674 | | // Note: The TypeSourceInfos for the arguments are allocated after the |
2675 | | // TypeTraitExpr. |
2676 | | |
2677 | | TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind, |
2678 | | ArrayRef<TypeSourceInfo *> Args, |
2679 | | SourceLocation RParenLoc, |
2680 | | bool Value); |
2681 | | |
2682 | 42.8k | TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {} |
2683 | | |
2684 | 0 | size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const { |
2685 | 0 | return getNumArgs(); |
2686 | 0 | } |
2687 | | |
2688 | | public: |
2689 | | friend class ASTStmtReader; |
2690 | | friend class ASTStmtWriter; |
2691 | | friend TrailingObjects; |
2692 | | |
2693 | | /// Create a new type trait expression. |
2694 | | static TypeTraitExpr *Create(const ASTContext &C, QualType T, |
2695 | | SourceLocation Loc, TypeTrait Kind, |
2696 | | ArrayRef<TypeSourceInfo *> Args, |
2697 | | SourceLocation RParenLoc, |
2698 | | bool Value); |
2699 | | |
2700 | | static TypeTraitExpr *CreateDeserialized(const ASTContext &C, |
2701 | | unsigned NumArgs); |
2702 | | |
2703 | | /// Determine which type trait this expression uses. |
2704 | 672k | TypeTrait getTrait() const { |
2705 | 672k | return static_cast<TypeTrait>(TypeTraitExprBits.Kind); |
2706 | 672k | } |
2707 | | |
2708 | 185k | bool getValue() const { |
2709 | 185k | assert(!isValueDependent()); |
2710 | 185k | return TypeTraitExprBits.Value; |
2711 | 185k | } |
2712 | | |
2713 | | /// Determine the number of arguments to this type trait. |
2714 | 3.39M | unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; } |
2715 | | |
2716 | | /// Retrieve the Ith argument. |
2717 | 1.00M | TypeSourceInfo *getArg(unsigned I) const { |
2718 | 1.00M | assert(I < getNumArgs() && "Argument out-of-range"); |
2719 | 1.00M | return getArgs()[I]; |
2720 | 1.00M | } |
2721 | | |
2722 | | /// Retrieve the argument types. |
2723 | 1.32M | ArrayRef<TypeSourceInfo *> getArgs() const { |
2724 | 1.32M | return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(), |
2725 | 1.32M | getNumArgs()); |
2726 | 1.32M | } |
2727 | | |
2728 | 1.23M | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
2729 | 245k | SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } |
2730 | | |
2731 | 219k | static bool classof(const Stmt *T) { |
2732 | 219k | return T->getStmtClass() == TypeTraitExprClass; |
2733 | 219k | } |
2734 | | |
2735 | | // Iterators |
2736 | 796k | child_range children() { |
2737 | 796k | return child_range(child_iterator(), child_iterator()); |
2738 | 796k | } |
2739 | | |
2740 | 0 | const_child_range children() const { |
2741 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
2742 | 0 | } |
2743 | | }; |
2744 | | |
2745 | | /// An Embarcadero array type trait, as used in the implementation of |
2746 | | /// __array_rank and __array_extent. |
2747 | | /// |
2748 | | /// Example: |
2749 | | /// \code |
2750 | | /// __array_rank(int[10][20]) == 2 |
2751 | | /// __array_extent(int, 1) == 20 |
2752 | | /// \endcode |
2753 | | class ArrayTypeTraitExpr : public Expr { |
2754 | | /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned. |
2755 | | unsigned ATT : 2; |
2756 | | |
2757 | | /// The value of the type trait. Unspecified if dependent. |
2758 | | uint64_t Value = 0; |
2759 | | |
2760 | | /// The array dimension being queried, or -1 if not used. |
2761 | | Expr *Dimension; |
2762 | | |
2763 | | /// The location of the type trait keyword. |
2764 | | SourceLocation Loc; |
2765 | | |
2766 | | /// The location of the closing paren. |
2767 | | SourceLocation RParen; |
2768 | | |
2769 | | /// The type being queried. |
2770 | | TypeSourceInfo *QueriedType = nullptr; |
2771 | | |
2772 | | public: |
2773 | | friend class ASTStmtReader; |
2774 | | |
2775 | | ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att, |
2776 | | TypeSourceInfo *queried, uint64_t value, Expr *dimension, |
2777 | | SourceLocation rparen, QualType ty) |
2778 | | : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary), ATT(att), |
2779 | | Value(value), Dimension(dimension), Loc(loc), RParen(rparen), |
2780 | 484 | QueriedType(queried) { |
2781 | 484 | assert(att <= ATT_Last && "invalid enum value!"); |
2782 | 484 | assert(static_cast<unsigned>(att) == ATT && "ATT overflow!"); |
2783 | 484 | setDependence(computeDependence(this)); |
2784 | 484 | } |
2785 | | |
2786 | | explicit ArrayTypeTraitExpr(EmptyShell Empty) |
2787 | 3 | : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {} |
2788 | | |
2789 | 1.46k | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
2790 | 46 | SourceLocation getEndLoc() const LLVM_READONLY { return RParen; } |
2791 | | |
2792 | 4.50k | ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); } |
2793 | | |
2794 | 4.95k | QualType getQueriedType() const { return QueriedType->getType(); } |
2795 | | |
2796 | 62 | TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; } |
2797 | | |
2798 | 64 | uint64_t getValue() const { assert(!isTypeDependent()); return Value; } |
2799 | | |
2800 | 524 | Expr *getDimensionExpression() const { return Dimension; } |
2801 | | |
2802 | 0 | static bool classof(const Stmt *T) { |
2803 | 0 | return T->getStmtClass() == ArrayTypeTraitExprClass; |
2804 | 0 | } |
2805 | | |
2806 | | // Iterators |
2807 | 4.50k | child_range children() { |
2808 | 4.50k | return child_range(child_iterator(), child_iterator()); |
2809 | 4.50k | } |
2810 | | |
2811 | 0 | const_child_range children() const { |
2812 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
2813 | 0 | } |
2814 | | }; |
2815 | | |
2816 | | /// An expression trait intrinsic. |
2817 | | /// |
2818 | | /// Example: |
2819 | | /// \code |
2820 | | /// __is_lvalue_expr(std::cout) == true |
2821 | | /// __is_lvalue_expr(1) == false |
2822 | | /// \endcode |
2823 | | class ExpressionTraitExpr : public Expr { |
2824 | | /// The trait. A ExpressionTrait enum in MSVC compatible unsigned. |
2825 | | unsigned ET : 31; |
2826 | | |
2827 | | /// The value of the type trait. Unspecified if dependent. |
2828 | | unsigned Value : 1; |
2829 | | |
2830 | | /// The location of the type trait keyword. |
2831 | | SourceLocation Loc; |
2832 | | |
2833 | | /// The location of the closing paren. |
2834 | | SourceLocation RParen; |
2835 | | |
2836 | | /// The expression being queried. |
2837 | | Expr* QueriedExpression = nullptr; |
2838 | | |
2839 | | public: |
2840 | | friend class ASTStmtReader; |
2841 | | |
2842 | | ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried, |
2843 | | bool value, SourceLocation rparen, QualType resultType) |
2844 | | : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary), |
2845 | | ET(et), Value(value), Loc(loc), RParen(rparen), |
2846 | 445 | QueriedExpression(queried) { |
2847 | 445 | assert(et <= ET_Last && "invalid enum value!"); |
2848 | 445 | assert(static_cast<unsigned>(et) == ET && "ET overflow!"); |
2849 | 445 | setDependence(computeDependence(this)); |
2850 | 445 | } |
2851 | | |
2852 | | explicit ExpressionTraitExpr(EmptyShell Empty) |
2853 | 2 | : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {} |
2854 | | |
2855 | 1.13k | SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } |
2856 | 21 | SourceLocation getEndLoc() const LLVM_READONLY { return RParen; } |
2857 | | |
2858 | 31 | ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); } |
2859 | | |
2860 | 923 | Expr *getQueriedExpression() const { return QueriedExpression; } |
2861 | | |
2862 | 440 | bool getValue() const { return Value; } |
2863 | | |
2864 | 8 | static bool classof(const Stmt *T) { |
2865 | 8 | return T->getStmtClass() == ExpressionTraitExprClass; |
2866 | 8 | } |
2867 | | |
2868 | | // Iterators |
2869 | 32 | child_range children() { |
2870 | 32 | return child_range(child_iterator(), child_iterator()); |
2871 | 32 | } |
2872 | | |
2873 | 0 | const_child_range children() const { |
2874 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
2875 | 0 | } |
2876 | | }; |
2877 | | |
2878 | | /// A reference to an overloaded function set, either an |
2879 | | /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr. |
2880 | | class OverloadExpr : public Expr { |
2881 | | friend class ASTStmtReader; |
2882 | | friend class ASTStmtWriter; |
2883 | | |
2884 | | /// The common name of these declarations. |
2885 | | DeclarationNameInfo NameInfo; |
2886 | | |
2887 | | /// The nested-name-specifier that qualifies the name, if any. |
2888 | | NestedNameSpecifierLoc QualifierLoc; |
2889 | | |
2890 | | protected: |
2891 | | OverloadExpr(StmtClass SC, const ASTContext &Context, |
2892 | | NestedNameSpecifierLoc QualifierLoc, |
2893 | | SourceLocation TemplateKWLoc, |
2894 | | const DeclarationNameInfo &NameInfo, |
2895 | | const TemplateArgumentListInfo *TemplateArgs, |
2896 | | UnresolvedSetIterator Begin, UnresolvedSetIterator End, |
2897 | | bool KnownDependent, bool KnownInstantiationDependent, |
2898 | | bool KnownContainsUnexpandedParameterPack); |
2899 | | |
2900 | | OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults, |
2901 | | bool HasTemplateKWAndArgsInfo); |
2902 | | |
2903 | | /// Return the results. Defined after UnresolvedMemberExpr. |
2904 | | inline DeclAccessPair *getTrailingResults(); |
2905 | 12.9M | const DeclAccessPair *getTrailingResults() const { |
2906 | 12.9M | return const_cast<OverloadExpr *>(this)->getTrailingResults(); |
2907 | 12.9M | } |
2908 | | |
2909 | | /// Return the optional template keyword and arguments info. |
2910 | | /// Defined after UnresolvedMemberExpr. |
2911 | | inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo(); |
2912 | 5.47M | const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const { |
2913 | 5.47M | return const_cast<OverloadExpr *>(this) |
2914 | 5.47M | ->getTrailingASTTemplateKWAndArgsInfo(); |
2915 | 5.47M | } |
2916 | | |
2917 | | /// Return the optional template arguments. Defined after |
2918 | | /// UnresolvedMemberExpr. |
2919 | | inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); |
2920 | 0 | const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const { |
2921 | 0 | return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc(); |
2922 | 0 | } |
2923 | | |
2924 | 20.3M | bool hasTemplateKWAndArgsInfo() const { |
2925 | 20.3M | return OverloadExprBits.HasTemplateKWAndArgsInfo; |
2926 | 20.3M | } |
2927 | | |
2928 | | public: |
2929 | | struct FindResult { |
2930 | | OverloadExpr *Expression; |
2931 | | bool IsAddressOfOperand; |
2932 | | bool HasFormOfMemberPointer; |
2933 | | }; |
2934 | | |
2935 | | /// Finds the overloaded expression in the given expression \p E of |
2936 | | /// OverloadTy. |
2937 | | /// |
2938 | | /// \return the expression (which must be there) and true if it has |
2939 | | /// the particular form of a member pointer expression |
2940 | 623k | static FindResult find(Expr *E) { |
2941 | 623k | assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload)); |
2942 | | |
2943 | 623k | FindResult Result; |
2944 | | |
2945 | 623k | E = E->IgnoreParens(); |
2946 | 623k | if (isa<UnaryOperator>(E)) { |
2947 | 2.40k | assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf); |
2948 | 2.40k | E = cast<UnaryOperator>(E)->getSubExpr(); |
2949 | 2.40k | auto *Ovl = cast<OverloadExpr>(E->IgnoreParens()); |
2950 | | |
2951 | 2.40k | Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier()2.38k ); |
2952 | 2.40k | Result.IsAddressOfOperand = true; |
2953 | 2.40k | Result.Expression = Ovl; |
2954 | 621k | } else { |
2955 | 621k | Result.HasFormOfMemberPointer = false; |
2956 | 621k | Result.IsAddressOfOperand = false; |
2957 | 621k | Result.Expression = cast<OverloadExpr>(E); |
2958 | 621k | } |
2959 | | |
2960 | 623k | return Result; |
2961 | 623k | } |
2962 | | |
2963 | | /// Gets the naming class of this lookup, if any. |
2964 | | /// Defined after UnresolvedMemberExpr. |
2965 | | inline CXXRecordDecl *getNamingClass(); |
2966 | 0 | const CXXRecordDecl *getNamingClass() const { |
2967 | 0 | return const_cast<OverloadExpr *>(this)->getNamingClass(); |
2968 | 0 | } |
2969 | | |
2970 | | using decls_iterator = UnresolvedSetImpl::iterator; |
2971 | | |
2972 | 6.97M | decls_iterator decls_begin() const { |
2973 | 6.97M | return UnresolvedSetIterator(getTrailingResults()); |
2974 | 6.97M | } |
2975 | 5.99M | decls_iterator decls_end() const { |
2976 | 5.99M | return UnresolvedSetIterator(getTrailingResults() + getNumDecls()); |
2977 | 5.99M | } |
2978 | 3.32M | llvm::iterator_range<decls_iterator> decls() const { |
2979 | 3.32M | return llvm::make_range(decls_begin(), decls_end()); |
2980 | 3.32M | } |
2981 | | |
2982 | | /// Gets the number of declarations in the unresolved set. |
2983 | 14.4M | unsigned getNumDecls() const { return OverloadExprBits.NumResults; } |
2984 | | |
2985 | | /// Gets the full name info. |
2986 | 5.87M | const DeclarationNameInfo &getNameInfo() const { return NameInfo; } |
2987 | | |
2988 | | /// Gets the name looked up. |
2989 | 1.61M | DeclarationName getName() const { return NameInfo.getName(); } |
2990 | | |
2991 | | /// Gets the location of the name. |
2992 | 2.48M | SourceLocation getNameLoc() const { return NameInfo.getLoc(); } |
2993 | | |
2994 | | /// Fetches the nested-name qualifier, if one was given. |
2995 | 3.57M | NestedNameSpecifier *getQualifier() const { |
2996 | 3.57M | return QualifierLoc.getNestedNameSpecifier(); |
2997 | 3.57M | } |
2998 | | |
2999 | | /// Fetches the nested-name qualifier with source-location |
3000 | | /// information, if one was given. |
3001 | 4.89M | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
3002 | | |
3003 | | /// Retrieve the location of the template keyword preceding |
3004 | | /// this name, if any. |
3005 | 977k | SourceLocation getTemplateKeywordLoc() const { |
3006 | 977k | if (!hasTemplateKWAndArgsInfo()) |
3007 | 699k | return SourceLocation(); |
3008 | 277k | return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc; |
3009 | 277k | } |
3010 | | |
3011 | | /// Retrieve the location of the left angle bracket starting the |
3012 | | /// explicit template argument list following the name, if any. |
3013 | 11.1M | SourceLocation getLAngleLoc() const { |
3014 | 11.1M | if (!hasTemplateKWAndArgsInfo()) |
3015 | 7.36M | return SourceLocation(); |
3016 | 3.82M | return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc; |
3017 | 3.82M | } |
3018 | | |
3019 | | /// Retrieve the location of the right angle bracket ending the |
3020 | | /// explicit template argument list following the name, if any. |
3021 | 279k | SourceLocation getRAngleLoc() const { |
3022 | 279k | if (!hasTemplateKWAndArgsInfo()) |
3023 | 0 | return SourceLocation(); |
3024 | 279k | return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc; |
3025 | 279k | } |
3026 | | |
3027 | | /// Determines whether the name was preceded by the template keyword. |
3028 | 48 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } |
3029 | | |
3030 | | /// Determines whether this expression had explicit template arguments. |
3031 | 11.0M | bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } |
3032 | | |
3033 | 3.44M | TemplateArgumentLoc const *getTemplateArgs() const { |
3034 | 3.44M | if (!hasExplicitTemplateArgs()) |
3035 | 2.37M | return nullptr; |
3036 | 1.06M | return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc(); |
3037 | 1.06M | } |
3038 | | |
3039 | 3.19M | unsigned getNumTemplateArgs() const { |
3040 | 3.19M | if (!hasExplicitTemplateArgs()) |
3041 | 2.37M | return 0; |
3042 | | |
3043 | 816k | return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs; |
3044 | 816k | } |
3045 | | |
3046 | 2.77M | ArrayRef<TemplateArgumentLoc> template_arguments() const { |
3047 | 2.77M | return {getTemplateArgs(), getNumTemplateArgs()}; |
3048 | 2.77M | } |
3049 | | |
3050 | | /// Copies the template arguments into the given structure. |
3051 | 273k | void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { |
3052 | 273k | if (hasExplicitTemplateArgs()) |
3053 | 273k | getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List); |
3054 | 273k | } |
3055 | | |
3056 | 629k | static bool classof(const Stmt *T) { |
3057 | 629k | return T->getStmtClass() == UnresolvedLookupExprClass || |
3058 | 9.33k | T->getStmtClass() == UnresolvedMemberExprClass; |
3059 | 629k | } |
3060 | | }; |
3061 | | |
3062 | | /// A reference to a name which we were able to look up during |
3063 | | /// parsing but could not resolve to a specific declaration. |
3064 | | /// |
3065 | | /// This arises in several ways: |
3066 | | /// * we might be waiting for argument-dependent lookup; |
3067 | | /// * the name might resolve to an overloaded function; |
3068 | | /// and eventually: |
3069 | | /// * the lookup might have included a function template. |
3070 | | /// |
3071 | | /// These never include UnresolvedUsingValueDecls, which are always class |
3072 | | /// members and therefore appear only in UnresolvedMemberLookupExprs. |
3073 | | class UnresolvedLookupExpr final |
3074 | | : public OverloadExpr, |
3075 | | private llvm::TrailingObjects<UnresolvedLookupExpr, DeclAccessPair, |
3076 | | ASTTemplateKWAndArgsInfo, |
3077 | | TemplateArgumentLoc> { |
3078 | | friend class ASTStmtReader; |
3079 | | friend class OverloadExpr; |
3080 | | friend TrailingObjects; |
3081 | | |
3082 | | /// The naming class (C++ [class.access.base]p5) of the lookup, if |
3083 | | /// any. This can generally be recalculated from the context chain, |
3084 | | /// but that can be fairly expensive for unqualified lookups. |
3085 | | CXXRecordDecl *NamingClass; |
3086 | | |
3087 | | // UnresolvedLookupExpr is followed by several trailing objects. |
3088 | | // They are in order: |
3089 | | // |
3090 | | // * An array of getNumResults() DeclAccessPair for the results. These are |
3091 | | // undesugared, which is to say, they may include UsingShadowDecls. |
3092 | | // Access is relative to the naming class. |
3093 | | // |
3094 | | // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified |
3095 | | // template keyword and arguments. Present if and only if |
3096 | | // hasTemplateKWAndArgsInfo(). |
3097 | | // |
3098 | | // * An array of getNumTemplateArgs() TemplateArgumentLoc containing |
3099 | | // location information for the explicitly specified template arguments. |
3100 | | |
3101 | | UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass, |
3102 | | NestedNameSpecifierLoc QualifierLoc, |
3103 | | SourceLocation TemplateKWLoc, |
3104 | | const DeclarationNameInfo &NameInfo, bool RequiresADL, |
3105 | | bool Overloaded, |
3106 | | const TemplateArgumentListInfo *TemplateArgs, |
3107 | | UnresolvedSetIterator Begin, UnresolvedSetIterator End); |
3108 | | |
3109 | | UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults, |
3110 | | bool HasTemplateKWAndArgsInfo); |
3111 | | |
3112 | 7.28M | unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const { |
3113 | 7.28M | return getNumDecls(); |
3114 | 7.28M | } |
3115 | | |
3116 | 1.45M | unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { |
3117 | 1.45M | return hasTemplateKWAndArgsInfo(); |
3118 | 1.45M | } |
3119 | | |
3120 | | public: |
3121 | | static UnresolvedLookupExpr * |
3122 | | Create(const ASTContext &Context, CXXRecordDecl *NamingClass, |
3123 | | NestedNameSpecifierLoc QualifierLoc, |
3124 | | const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, |
3125 | | UnresolvedSetIterator Begin, UnresolvedSetIterator End); |
3126 | | |
3127 | | static UnresolvedLookupExpr * |
3128 | | Create(const ASTContext &Context, CXXRecordDecl *NamingClass, |
3129 | | NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, |
3130 | | const DeclarationNameInfo &NameInfo, bool RequiresADL, |
3131 | | const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin, |
3132 | | UnresolvedSetIterator End); |
3133 | | |
3134 | | static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context, |
3135 | | unsigned NumResults, |
3136 | | bool HasTemplateKWAndArgsInfo, |
3137 | | unsigned NumTemplateArgs); |
3138 | | |
3139 | | /// True if this declaration should be extended by |
3140 | | /// argument-dependent lookup. |
3141 | 2.60M | bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; } |
3142 | | |
3143 | | /// True if this lookup is overloaded. |
3144 | 352k | bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; } |
3145 | | |
3146 | | /// Gets the 'naming class' (in the sense of C++0x |
3147 | | /// [class.access.base]p5) of the lookup. This is the scope |
3148 | | /// that was looked in to find these results. |
3149 | 1.51M | CXXRecordDecl *getNamingClass() { return NamingClass; } |
3150 | 0 | const CXXRecordDecl *getNamingClass() const { return NamingClass; } |
3151 | | |
3152 | 2.66M | SourceLocation getBeginLoc() const LLVM_READONLY { |
3153 | 2.66M | if (NestedNameSpecifierLoc l = getQualifierLoc()) |
3154 | 1.03M | return l.getBeginLoc(); |
3155 | 1.62M | return getNameInfo().getBeginLoc(); |
3156 | 1.62M | } |
3157 | | |
3158 | 189k | SourceLocation getEndLoc() const LLVM_READONLY { |
3159 | 189k | if (hasExplicitTemplateArgs()) |
3160 | 138k | return getRAngleLoc(); |
3161 | 50.8k | return getNameInfo().getEndLoc(); |
3162 | 50.8k | } |
3163 | | |
3164 | 524k | child_range children() { |
3165 | 524k | return child_range(child_iterator(), child_iterator()); |
3166 | 524k | } |
3167 | | |
3168 | 0 | const_child_range children() const { |
3169 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
3170 | 0 | } |
3171 | | |
3172 | 54.9M | static bool classof(const Stmt *T) { |
3173 | 54.9M | return T->getStmtClass() == UnresolvedLookupExprClass; |
3174 | 54.9M | } |
3175 | | }; |
3176 | | |
3177 | | /// A qualified reference to a name whose declaration cannot |
3178 | | /// yet be resolved. |
3179 | | /// |
3180 | | /// DependentScopeDeclRefExpr is similar to DeclRefExpr in that |
3181 | | /// it expresses a reference to a declaration such as |
3182 | | /// X<T>::value. The difference, however, is that an |
3183 | | /// DependentScopeDeclRefExpr node is used only within C++ templates when |
3184 | | /// the qualification (e.g., X<T>::) refers to a dependent type. In |
3185 | | /// this case, X<T>::value cannot resolve to a declaration because the |
3186 | | /// declaration will differ from one instantiation of X<T> to the |
3187 | | /// next. Therefore, DependentScopeDeclRefExpr keeps track of the |
3188 | | /// qualifier (X<T>::) and the name of the entity being referenced |
3189 | | /// ("value"). Such expressions will instantiate to a DeclRefExpr once the |
3190 | | /// declaration can be found. |
3191 | | class DependentScopeDeclRefExpr final |
3192 | | : public Expr, |
3193 | | private llvm::TrailingObjects<DependentScopeDeclRefExpr, |
3194 | | ASTTemplateKWAndArgsInfo, |
3195 | | TemplateArgumentLoc> { |
3196 | | friend class ASTStmtReader; |
3197 | | friend class ASTStmtWriter; |
3198 | | friend TrailingObjects; |
3199 | | |
3200 | | /// The nested-name-specifier that qualifies this unresolved |
3201 | | /// declaration name. |
3202 | | NestedNameSpecifierLoc QualifierLoc; |
3203 | | |
3204 | | /// The name of the entity we will be referencing. |
3205 | | DeclarationNameInfo NameInfo; |
3206 | | |
3207 | | DependentScopeDeclRefExpr(QualType Ty, NestedNameSpecifierLoc QualifierLoc, |
3208 | | SourceLocation TemplateKWLoc, |
3209 | | const DeclarationNameInfo &NameInfo, |
3210 | | const TemplateArgumentListInfo *Args); |
3211 | | |
3212 | 234k | size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { |
3213 | 234k | return hasTemplateKWAndArgsInfo(); |
3214 | 234k | } |
3215 | | |
3216 | 14.7M | bool hasTemplateKWAndArgsInfo() const { |
3217 | 14.7M | return DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo; |
3218 | 14.7M | } |
3219 | | |
3220 | | public: |
3221 | | static DependentScopeDeclRefExpr * |
3222 | | Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, |
3223 | | SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, |
3224 | | const TemplateArgumentListInfo *TemplateArgs); |
3225 | | |
3226 | | static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &Context, |
3227 | | bool HasTemplateKWAndArgsInfo, |
3228 | | unsigned NumTemplateArgs); |
3229 | | |
3230 | | /// Retrieve the name that this expression refers to. |
3231 | 2.99M | const DeclarationNameInfo &getNameInfo() const { return NameInfo; } |
3232 | | |
3233 | | /// Retrieve the name that this expression refers to. |
3234 | 4.38M | DeclarationName getDeclName() const { return NameInfo.getName(); } |
3235 | | |
3236 | | /// Retrieve the location of the name within the expression. |
3237 | | /// |
3238 | | /// For example, in "X<T>::value" this is the location of "value". |
3239 | 64.2k | SourceLocation getLocation() const { return NameInfo.getLoc(); } |
3240 | | |
3241 | | /// Retrieve the nested-name-specifier that qualifies the |
3242 | | /// name, with source location information. |
3243 | 3.74M | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
3244 | | |
3245 | | /// Retrieve the nested-name-specifier that qualifies this |
3246 | | /// declaration. |
3247 | 5.78M | NestedNameSpecifier *getQualifier() const { |
3248 | 5.78M | return QualifierLoc.getNestedNameSpecifier(); |
3249 | 5.78M | } |
3250 | | |
3251 | | /// Retrieve the location of the template keyword preceding |
3252 | | /// this name, if any. |
3253 | 1.30M | SourceLocation getTemplateKeywordLoc() const { |
3254 | 1.30M | if (!hasTemplateKWAndArgsInfo()) |
3255 | 1.26M | return SourceLocation(); |
3256 | 43.3k | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; |
3257 | 43.3k | } |
3258 | | |
3259 | | /// Retrieve the location of the left angle bracket starting the |
3260 | | /// explicit template argument list following the name, if any. |
3261 | 13.0M | SourceLocation getLAngleLoc() const { |
3262 | 13.0M | if (!hasTemplateKWAndArgsInfo()) |
3263 | 12.3M | return SourceLocation(); |
3264 | 672k | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; |
3265 | 672k | } |
3266 | | |
3267 | | /// Retrieve the location of the right angle bracket ending the |
3268 | | /// explicit template argument list following the name, if any. |
3269 | 185k | SourceLocation getRAngleLoc() const { |
3270 | 185k | if (!hasTemplateKWAndArgsInfo()) |
3271 | 120k | return SourceLocation(); |
3272 | 65.5k | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; |
3273 | 65.5k | } |
3274 | | |
3275 | | /// Determines whether the name was preceded by the template keyword. |
3276 | 152 | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } |
3277 | | |
3278 | | /// Determines whether this lookup had explicit template arguments. |
3279 | 12.9M | bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } |
3280 | | |
3281 | | /// Copies the template arguments (if present) into the given |
3282 | | /// structure. |
3283 | 0 | void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { |
3284 | 0 | if (hasExplicitTemplateArgs()) |
3285 | 0 | getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( |
3286 | 0 | getTrailingObjects<TemplateArgumentLoc>(), List); |
3287 | 0 | } |
3288 | | |
3289 | 1.70M | TemplateArgumentLoc const *getTemplateArgs() const { |
3290 | 1.70M | if (!hasExplicitTemplateArgs()) |
3291 | 1.52M | return nullptr; |
3292 | | |
3293 | 181k | return getTrailingObjects<TemplateArgumentLoc>(); |
3294 | 181k | } |
3295 | | |
3296 | 1.70M | unsigned getNumTemplateArgs() const { |
3297 | 1.70M | if (!hasExplicitTemplateArgs()) |
3298 | 1.52M | return 0; |
3299 | | |
3300 | 181k | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; |
3301 | 181k | } |
3302 | | |
3303 | 1.52M | ArrayRef<TemplateArgumentLoc> template_arguments() const { |
3304 | 1.52M | return {getTemplateArgs(), getNumTemplateArgs()}; |
3305 | 1.52M | } |
3306 | | |
3307 | | /// Note: getBeginLoc() is the start of the whole DependentScopeDeclRefExpr, |
3308 | | /// and differs from getLocation().getStart(). |
3309 | 1.67M | SourceLocation getBeginLoc() const LLVM_READONLY { |
3310 | 1.67M | return QualifierLoc.getBeginLoc(); |
3311 | 1.67M | } |
3312 | | |
3313 | 86.4k | SourceLocation getEndLoc() const LLVM_READONLY { |
3314 | 86.4k | if (hasExplicitTemplateArgs()) |
3315 | 22.1k | return getRAngleLoc(); |
3316 | 64.2k | return getLocation(); |
3317 | 64.2k | } |
3318 | | |
3319 | 1.24M | static bool classof(const Stmt *T) { |
3320 | 1.24M | return T->getStmtClass() == DependentScopeDeclRefExprClass; |
3321 | 1.24M | } |
3322 | | |
3323 | 4.32M | child_range children() { |
3324 | 4.32M | return child_range(child_iterator(), child_iterator()); |
3325 | 4.32M | } |
3326 | | |
3327 | 0 | const_child_range children() const { |
3328 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
3329 | 0 | } |
3330 | | }; |
3331 | | |
3332 | | /// Represents an expression -- generally a full-expression -- that |
3333 | | /// introduces cleanups to be run at the end of the sub-expression's |
3334 | | /// evaluation. The most common source of expression-introduced |
3335 | | /// cleanups is temporary objects in C++, but several other kinds of |
3336 | | /// expressions can create cleanups, including basically every |
3337 | | /// call in ARC that returns an Objective-C pointer. |
3338 | | /// |
3339 | | /// This expression also tracks whether the sub-expression contains a |
3340 | | /// potentially-evaluated block literal. The lifetime of a block |
3341 | | /// literal is the extent of the enclosing scope. |
3342 | | class ExprWithCleanups final |
3343 | | : public FullExpr, |
3344 | | private llvm::TrailingObjects< |
3345 | | ExprWithCleanups, |
3346 | | llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>> { |
3347 | | public: |
3348 | | /// The type of objects that are kept in the cleanup. |
3349 | | /// It's useful to remember the set of blocks and block-scoped compound |
3350 | | /// literals; we could also remember the set of temporaries, but there's |
3351 | | /// currently no need. |
3352 | | using CleanupObject = llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>; |
3353 | | |
3354 | | private: |
3355 | | friend class ASTStmtReader; |
3356 | | friend TrailingObjects; |
3357 | | |
3358 | | ExprWithCleanups(EmptyShell, unsigned NumObjects); |
3359 | | ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects, |
3360 | | ArrayRef<CleanupObject> Objects); |
3361 | | |
3362 | | public: |
3363 | | static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty, |
3364 | | unsigned numObjects); |
3365 | | |
3366 | | static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr, |
3367 | | bool CleanupsHaveSideEffects, |
3368 | | ArrayRef<CleanupObject> objects); |
3369 | | |
3370 | 10.8k | ArrayRef<CleanupObject> getObjects() const { |
3371 | 10.8k | return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(), |
3372 | 10.8k | getNumObjects()); |
3373 | 10.8k | } |
3374 | | |
3375 | 32.3k | unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; } |
3376 | | |
3377 | 126 | CleanupObject getObject(unsigned i) const { |
3378 | 126 | assert(i < getNumObjects() && "Index out of range"); |
3379 | 126 | return getObjects()[i]; |
3380 | 126 | } |
3381 | | |
3382 | 27.5k | bool cleanupsHaveSideEffects() const { |
3383 | 27.5k | return ExprWithCleanupsBits.CleanupsHaveSideEffects; |
3384 | 27.5k | } |
3385 | | |
3386 | 36.6k | SourceLocation getBeginLoc() const LLVM_READONLY { |
3387 | 36.6k | return SubExpr->getBeginLoc(); |
3388 | 36.6k | } |
3389 | | |
3390 | 51.2k | SourceLocation getEndLoc() const LLVM_READONLY { |
3391 | 51.2k | return SubExpr->getEndLoc(); |
3392 | 51.2k | } |
3393 | | |
3394 | | // Implement isa/cast/dyncast/etc. |
3395 | 2.35M | static bool classof(const Stmt *T) { |
3396 | 2.35M | return T->getStmtClass() == ExprWithCleanupsClass; |
3397 | 2.35M | } |
3398 | | |
3399 | | // Iterators |
3400 | 62.0k | child_range children() { return child_range(&SubExpr, &SubExpr + 1); } |
3401 | | |
3402 | 0 | const_child_range children() const { |
3403 | 0 | return const_child_range(&SubExpr, &SubExpr + 1); |
3404 | 0 | } |
3405 | | }; |
3406 | | |
3407 | | /// Describes an explicit type conversion that uses functional |
3408 | | /// notion but could not be resolved because one or more arguments are |
3409 | | /// type-dependent. |
3410 | | /// |
3411 | | /// The explicit type conversions expressed by |
3412 | | /// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>, |
3413 | | /// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and |
3414 | | /// either \c T is a dependent type or one or more of the <tt>a</tt>'s is |
3415 | | /// type-dependent. For example, this would occur in a template such |
3416 | | /// as: |
3417 | | /// |
3418 | | /// \code |
3419 | | /// template<typename T, typename A1> |
3420 | | /// inline T make_a(const A1& a1) { |
3421 | | /// return T(a1); |
3422 | | /// } |
3423 | | /// \endcode |
3424 | | /// |
3425 | | /// When the returned expression is instantiated, it may resolve to a |
3426 | | /// constructor call, conversion function call, or some kind of type |
3427 | | /// conversion. |
3428 | | class CXXUnresolvedConstructExpr final |
3429 | | : public Expr, |
3430 | | private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> { |
3431 | | friend class ASTStmtReader; |
3432 | | friend TrailingObjects; |
3433 | | |
3434 | | /// The type being constructed. |
3435 | | TypeSourceInfo *TSI; |
3436 | | |
3437 | | /// The location of the left parentheses ('('). |
3438 | | SourceLocation LParenLoc; |
3439 | | |
3440 | | /// The location of the right parentheses (')'). |
3441 | | SourceLocation RParenLoc; |
3442 | | |
3443 | | CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI, |
3444 | | SourceLocation LParenLoc, ArrayRef<Expr *> Args, |
3445 | | SourceLocation RParenLoc); |
3446 | | |
3447 | | CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs) |
3448 | 43.9k | : Expr(CXXUnresolvedConstructExprClass, Empty), TSI(nullptr) { |
3449 | 43.9k | CXXUnresolvedConstructExprBits.NumArgs = NumArgs; |
3450 | 43.9k | } |
3451 | | |
3452 | | public: |
3453 | | static CXXUnresolvedConstructExpr *Create(const ASTContext &Context, |
3454 | | QualType T, TypeSourceInfo *TSI, |
3455 | | SourceLocation LParenLoc, |
3456 | | ArrayRef<Expr *> Args, |
3457 | | SourceLocation RParenLoc); |
3458 | | |
3459 | | static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context, |
3460 | | unsigned NumArgs); |
3461 | | |
3462 | | /// Retrieve the type that is being constructed, as specified |
3463 | | /// in the source code. |
3464 | 45.0k | QualType getTypeAsWritten() const { return TSI->getType(); } |
3465 | | |
3466 | | /// Retrieve the type source information for the type being |
3467 | | /// constructed. |
3468 | 200k | TypeSourceInfo *getTypeSourceInfo() const { return TSI; } |
3469 | | |
3470 | | /// Retrieve the location of the left parentheses ('(') that |
3471 | | /// precedes the argument list. |
3472 | 116k | SourceLocation getLParenLoc() const { return LParenLoc; } |
3473 | 43.9k | void setLParenLoc(SourceLocation L) { LParenLoc = L; } |
3474 | | |
3475 | | /// Retrieve the location of the right parentheses (')') that |
3476 | | /// follows the argument list. |
3477 | 116k | SourceLocation getRParenLoc() const { return RParenLoc; } |
3478 | 43.9k | void setRParenLoc(SourceLocation L) { RParenLoc = L; } |
3479 | | |
3480 | | /// Determine whether this expression models list-initialization. |
3481 | | /// If so, there will be exactly one subexpression, which will be |
3482 | | /// an InitListExpr. |
3483 | 150k | bool isListInitialization() const { return LParenLoc.isInvalid(); } |
3484 | | |
3485 | | /// Retrieve the number of arguments. |
3486 | 725k | unsigned getNumArgs() const { return CXXUnresolvedConstructExprBits.NumArgs; } |
3487 | | |
3488 | | using arg_iterator = Expr **; |
3489 | | using arg_range = llvm::iterator_range<arg_iterator>; |
3490 | | |
3491 | 850k | arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); } |
3492 | 337k | arg_iterator arg_end() { return arg_begin() + getNumArgs(); } |
3493 | 274k | arg_range arguments() { return arg_range(arg_begin(), arg_end()); } |
3494 | | |
3495 | | using const_arg_iterator = const Expr* const *; |
3496 | | using const_arg_range = llvm::iterator_range<const_arg_iterator>; |
3497 | | |
3498 | 2.70k | const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); } |
3499 | 8 | const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); } |
3500 | 8 | const_arg_range arguments() const { |
3501 | 8 | return const_arg_range(arg_begin(), arg_end()); |
3502 | 8 | } |
3503 | | |
3504 | 0 | Expr *getArg(unsigned I) { |
3505 | 0 | assert(I < getNumArgs() && "Argument index out-of-range"); |
3506 | 0 | return arg_begin()[I]; |
3507 | 0 | } |
3508 | | |
3509 | 2.68k | const Expr *getArg(unsigned I) const { |
3510 | 2.68k | assert(I < getNumArgs() && "Argument index out-of-range"); |
3511 | 2.68k | return arg_begin()[I]; |
3512 | 2.68k | } |
3513 | | |
3514 | 33.2k | void setArg(unsigned I, Expr *E) { |
3515 | 33.2k | assert(I < getNumArgs() && "Argument index out-of-range"); |
3516 | 33.2k | arg_begin()[I] = E; |
3517 | 33.2k | } |
3518 | | |
3519 | | SourceLocation getBeginLoc() const LLVM_READONLY; |
3520 | 9.70k | SourceLocation getEndLoc() const LLVM_READONLY { |
3521 | 9.70k | if (!RParenLoc.isValid() && getNumArgs() > 02.65k ) |
3522 | 2.65k | return getArg(getNumArgs() - 1)->getEndLoc(); |
3523 | 7.04k | return RParenLoc; |
3524 | 7.04k | } |
3525 | | |
3526 | 60.2k | static bool classof(const Stmt *T) { |
3527 | 60.2k | return T->getStmtClass() == CXXUnresolvedConstructExprClass; |
3528 | 60.2k | } |
3529 | | |
3530 | | // Iterators |
3531 | 88.9k | child_range children() { |
3532 | 88.9k | auto **begin = reinterpret_cast<Stmt **>(arg_begin()); |
3533 | 88.9k | return child_range(begin, begin + getNumArgs()); |
3534 | 88.9k | } |
3535 | | |
3536 | 0 | const_child_range children() const { |
3537 | 0 | auto **begin = reinterpret_cast<Stmt **>( |
3538 | 0 | const_cast<CXXUnresolvedConstructExpr *>(this)->arg_begin()); |
3539 | 0 | return const_child_range(begin, begin + getNumArgs()); |
3540 | 0 | } |
3541 | | }; |
3542 | | |
3543 | | /// Represents a C++ member access expression where the actual |
3544 | | /// member referenced could not be resolved because the base |
3545 | | /// expression or the member name was dependent. |
3546 | | /// |
3547 | | /// Like UnresolvedMemberExprs, these can be either implicit or |
3548 | | /// explicit accesses. It is only possible to get one of these with |
3549 | | /// an implicit access if a qualifier is provided. |
3550 | | class CXXDependentScopeMemberExpr final |
3551 | | : public Expr, |
3552 | | private llvm::TrailingObjects<CXXDependentScopeMemberExpr, |
3553 | | ASTTemplateKWAndArgsInfo, |
3554 | | TemplateArgumentLoc, NamedDecl *> { |
3555 | | friend class ASTStmtReader; |
3556 | | friend class ASTStmtWriter; |
3557 | | friend TrailingObjects; |
3558 | | |
3559 | | /// The expression for the base pointer or class reference, |
3560 | | /// e.g., the \c x in x.f. Can be null in implicit accesses. |
3561 | | Stmt *Base; |
3562 | | |
3563 | | /// The type of the base expression. Never null, even for |
3564 | | /// implicit accesses. |
3565 | | QualType BaseType; |
3566 | | |
3567 | | /// The nested-name-specifier that precedes the member name, if any. |
3568 | | /// FIXME: This could be in principle store as a trailing object. |
3569 | | /// However the performance impact of doing so should be investigated first. |
3570 | | NestedNameSpecifierLoc QualifierLoc; |
3571 | | |
3572 | | /// The member to which this member expression refers, which |
3573 | | /// can be name, overloaded operator, or destructor. |
3574 | | /// |
3575 | | /// FIXME: could also be a template-id |
3576 | | DeclarationNameInfo MemberNameInfo; |
3577 | | |
3578 | | // CXXDependentScopeMemberExpr is followed by several trailing objects, |
3579 | | // some of which optional. They are in order: |
3580 | | // |
3581 | | // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified |
3582 | | // template keyword and arguments. Present if and only if |
3583 | | // hasTemplateKWAndArgsInfo(). |
3584 | | // |
3585 | | // * An array of getNumTemplateArgs() TemplateArgumentLoc containing location |
3586 | | // information for the explicitly specified template arguments. |
3587 | | // |
3588 | | // * An optional NamedDecl *. In a qualified member access expression such |
3589 | | // as t->Base::f, this member stores the resolves of name lookup in the |
3590 | | // context of the member access expression, to be used at instantiation |
3591 | | // time. Present if and only if hasFirstQualifierFoundInScope(). |
3592 | | |
3593 | 4.65M | bool hasTemplateKWAndArgsInfo() const { |
3594 | 4.65M | return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo; |
3595 | 4.65M | } |
3596 | | |
3597 | 2.05M | bool hasFirstQualifierFoundInScope() const { |
3598 | 2.05M | return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope; |
3599 | 2.05M | } |
3600 | | |
3601 | 5.62k | unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { |
3602 | 5.62k | return hasTemplateKWAndArgsInfo(); |
3603 | 5.62k | } |
3604 | | |
3605 | 117 | unsigned numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const { |
3606 | 117 | return getNumTemplateArgs(); |
3607 | 117 | } |
3608 | | |
3609 | 0 | unsigned numTrailingObjects(OverloadToken<NamedDecl *>) const { |
3610 | 0 | return hasFirstQualifierFoundInScope(); |
3611 | 0 | } |
3612 | | |
3613 | | CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base, |
3614 | | QualType BaseType, bool IsArrow, |
3615 | | SourceLocation OperatorLoc, |
3616 | | NestedNameSpecifierLoc QualifierLoc, |
3617 | | SourceLocation TemplateKWLoc, |
3618 | | NamedDecl *FirstQualifierFoundInScope, |
3619 | | DeclarationNameInfo MemberNameInfo, |
3620 | | const TemplateArgumentListInfo *TemplateArgs); |
3621 | | |
3622 | | CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo, |
3623 | | bool HasFirstQualifierFoundInScope); |
3624 | | |
3625 | | public: |
3626 | | static CXXDependentScopeMemberExpr * |
3627 | | Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow, |
3628 | | SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, |
3629 | | SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, |
3630 | | DeclarationNameInfo MemberNameInfo, |
3631 | | const TemplateArgumentListInfo *TemplateArgs); |
3632 | | |
3633 | | static CXXDependentScopeMemberExpr * |
3634 | | CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo, |
3635 | | unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope); |
3636 | | |
3637 | | /// True if this is an implicit access, i.e. one in which the |
3638 | | /// member being accessed was not written in the source. The source |
3639 | | /// location of the operator is invalid in this case. |
3640 | 5.07M | bool isImplicitAccess() const { |
3641 | 5.07M | if (!Base) |
3642 | 584k | return true; |
3643 | 4.48M | return cast<Expr>(Base)->isImplicitCXXThis(); |
3644 | 4.48M | } |
3645 | | |
3646 | | /// Retrieve the base object of this member expressions, |
3647 | | /// e.g., the \c x in \c x.m. |
3648 | 1.37M | Expr *getBase() const { |
3649 | 1.37M | assert(!isImplicitAccess()); |
3650 | 1.37M | return cast<Expr>(Base); |
3651 | 1.37M | } |
3652 | | |
3653 | 145k | QualType getBaseType() const { return BaseType; } |
3654 | | |
3655 | | /// Determine whether this member expression used the '->' |
3656 | | /// operator; otherwise, it used the '.' operator. |
3657 | 770k | bool isArrow() const { return CXXDependentScopeMemberExprBits.IsArrow; } |
3658 | | |
3659 | | /// Retrieve the location of the '->' or '.' operator. |
3660 | 574k | SourceLocation getOperatorLoc() const { |
3661 | 574k | return CXXDependentScopeMemberExprBits.OperatorLoc; |
3662 | 574k | } |
3663 | | |
3664 | | /// Retrieve the nested-name-specifier that qualifies the member name. |
3665 | 1.73M | NestedNameSpecifier *getQualifier() const { |
3666 | 1.73M | return QualifierLoc.getNestedNameSpecifier(); |
3667 | 1.73M | } |
3668 | | |
3669 | | /// Retrieve the nested-name-specifier that qualifies the member |
3670 | | /// name, with source location information. |
3671 | 852k | NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } |
3672 | | |
3673 | | /// Retrieve the first part of the nested-name-specifier that was |
3674 | | /// found in the scope of the member access expression when the member access |
3675 | | /// was initially parsed. |
3676 | | /// |
3677 | | /// This function only returns a useful result when member access expression |
3678 | | /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration |
3679 | | /// returned by this function describes what was found by unqualified name |
3680 | | /// lookup for the identifier "Base" within the scope of the member access |
3681 | | /// expression itself. At template instantiation time, this information is |
3682 | | /// combined with the results of name lookup into the type of the object |
3683 | | /// expression itself (the class type of x). |
3684 | 369k | NamedDecl *getFirstQualifierFoundInScope() const { |
3685 | 369k | if (!hasFirstQualifierFoundInScope()) |
3686 | 368k | return nullptr; |
3687 | 59 | return *getTrailingObjects<NamedDecl *>(); |
3688 | 59 | } |
3689 | | |
3690 | | /// Retrieve the name of the member that this expression refers to. |
3691 | 1.66M | const DeclarationNameInfo &getMemberNameInfo() const { |
3692 | 1.66M | return MemberNameInfo; |
3693 | 1.66M | } |
3694 | | |
3695 | | /// Retrieve the name of the member that this expression refers to. |
3696 | 486k | DeclarationName getMember() const { return MemberNameInfo.getName(); } |
3697 | | |
3698 | | // Retrieve the location of the name of the member that this |
3699 | | // expression refers to. |
3700 | 260k | SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); } |
3701 | | |
3702 | | /// Retrieve the location of the template keyword preceding the |
3703 | | /// member name, if any. |
3704 | 370k | SourceLocation getTemplateKeywordLoc() const { |
3705 | 370k | if (!hasTemplateKWAndArgsInfo()) |
3706 | 370k | return SourceLocation(); |
3707 | 347 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; |
3708 | 347 | } |
3709 | | |
3710 | | /// Retrieve the location of the left angle bracket starting the |
3711 | | /// explicit template argument list following the member name, if any. |
3712 | 3.76M | SourceLocation getLAngleLoc() const { |
3713 | 3.76M | if (!hasTemplateKWAndArgsInfo()) |
3714 | 3.75M | return SourceLocation(); |
3715 | 7.35k | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; |
3716 | 7.35k | } |
3717 | | |
3718 | | /// Retrieve the location of the right angle bracket ending the |
3719 | | /// explicit template argument list following the member name, if any. |
3720 | 318 | SourceLocation getRAngleLoc() const { |
3721 | 318 | if (!hasTemplateKWAndArgsInfo()) |
3722 | 0 | return SourceLocation(); |
3723 | 318 | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; |
3724 | 318 | } |
3725 | | |
3726 | | /// Determines whether the member name was preceded by the template keyword. |
3727 | 1.95k | bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } |
3728 | | |
3729 | | /// Determines whether this member expression actually had a C++ |
3730 | | /// template argument list explicitly specified, e.g., x.f<int>. |
3731 | 3.76M | bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } |
3732 | | |
3733 | | /// Copies the template arguments (if present) into the given |
3734 | | /// structure. |
3735 | 0 | void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { |
3736 | 0 | if (hasExplicitTemplateArgs()) |
3737 | 0 | getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( |
3738 | 0 | getTrailingObjects<TemplateArgumentLoc>(), List); |
3739 | 0 | } |
3740 | | |
3741 | | /// Retrieve the template arguments provided as part of this |
3742 | | /// template-id. |
3743 | 1.16M | const TemplateArgumentLoc *getTemplateArgs() const { |
3744 | 1.16M | if (!hasExplicitTemplateArgs()) |
3745 | 1.16M | return nullptr; |
3746 | | |
3747 | 2.96k | return getTrailingObjects<TemplateArgumentLoc>(); |
3748 | 2.96k | } |
3749 | | |
3750 | | /// Retrieve the number of template arguments provided as part of this |
3751 | | /// template-id. |
3752 | 1.57M | unsigned getNumTemplateArgs() const { |
3753 | 1.57M | if (!hasExplicitTemplateArgs()) |
3754 | 1.56M | return 0; |
3755 | | |
3756 | 3.20k | return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; |
3757 | 3.20k | } |
3758 | | |
3759 | 1.16M | ArrayRef<TemplateArgumentLoc> template_arguments() const { |
3760 | 1.16M | return {getTemplateArgs(), getNumTemplateArgs()}; |
3761 | 1.16M | } |
3762 | | |
3763 | 1.19M | SourceLocation getBeginLoc() const LLVM_READONLY { |
3764 | 1.19M | if (!isImplicitAccess()) |
3765 | 971k | return Base->getBeginLoc(); |
3766 | 225k | if (getQualifier()) |
3767 | 225k | return getQualifierLoc().getBeginLoc(); |
3768 | 5 | return MemberNameInfo.getBeginLoc(); |
3769 | 5 | } |
3770 | | |
3771 | 68.6k | SourceLocation getEndLoc() const LLVM_READONLY { |
3772 | 68.6k | if (hasExplicitTemplateArgs()) |
3773 | 5 | return getRAngleLoc(); |
3774 | 68.6k | return MemberNameInfo.getEndLoc(); |
3775 | 68.6k | } |
3776 | | |
3777 | 116k | static bool classof(const Stmt *T) { |
3778 | 116k | return T->getStmtClass() == CXXDependentScopeMemberExprClass; |
3779 | 116k | } |
3780 | | |
3781 | | // Iterators |
3782 | 391k | child_range children() { |
3783 | 391k | if (isImplicitAccess()) |
3784 | 21.7k | return child_range(child_iterator(), child_iterator()); |
3785 | 369k | return child_range(&Base, &Base + 1); |
3786 | 369k | } |
3787 | | |
3788 | 0 | const_child_range children() const { |
3789 | 0 | if (isImplicitAccess()) |
3790 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
3791 | 0 | return const_child_range(&Base, &Base + 1); |
3792 | 0 | } |
3793 | | }; |
3794 | | |
3795 | | /// Represents a C++ member access expression for which lookup |
3796 | | /// produced a set of overloaded functions. |
3797 | | /// |
3798 | | /// The member access may be explicit or implicit: |
3799 | | /// \code |
3800 | | /// struct A { |
3801 | | /// int a, b; |
3802 | | /// int explicitAccess() { return this->a + this->A::b; } |
3803 | | /// int implicitAccess() { return a + A::b; } |
3804 | | /// }; |
3805 | | /// \endcode |
3806 | | /// |
3807 | | /// In the final AST, an explicit access always becomes a MemberExpr. |
3808 | | /// An implicit access may become either a MemberExpr or a |
3809 | | /// DeclRefExpr, depending on whether the member is static. |
3810 | | class UnresolvedMemberExpr final |
3811 | | : public OverloadExpr, |
3812 | | private llvm::TrailingObjects<UnresolvedMemberExpr, DeclAccessPair, |
3813 | | ASTTemplateKWAndArgsInfo, |
3814 | | TemplateArgumentLoc> { |
3815 | | friend class ASTStmtReader; |
3816 | | friend class OverloadExpr; |
3817 | | friend TrailingObjects; |
3818 | | |
3819 | | /// The expression for the base pointer or class reference, |
3820 | | /// e.g., the \c x in x.f. |
3821 | | /// |
3822 | | /// This can be null if this is an 'unbased' member expression. |
3823 | | Stmt *Base; |
3824 | | |
3825 | | /// The type of the base expression; never null. |
3826 | | QualType BaseType; |
3827 | | |
3828 | | /// The location of the '->' or '.' operator. |
3829 | | SourceLocation OperatorLoc; |
3830 | | |
3831 | | // UnresolvedMemberExpr is followed by several trailing objects. |
3832 | | // They are in order: |
3833 | | // |
3834 | | // * An array of getNumResults() DeclAccessPair for the results. These are |
3835 | | // undesugared, which is to say, they may include UsingShadowDecls. |
3836 | | // Access is relative to the naming class. |
3837 | | // |
3838 | | // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified |
3839 | | // template keyword and arguments. Present if and only if |
3840 | | // hasTemplateKWAndArgsInfo(). |
3841 | | // |
3842 | | // * An array of getNumTemplateArgs() TemplateArgumentLoc containing |
3843 | | // location information for the explicitly specified template arguments. |
3844 | | |
3845 | | UnresolvedMemberExpr(const ASTContext &Context, bool HasUnresolvedUsing, |
3846 | | Expr *Base, QualType BaseType, bool IsArrow, |
3847 | | SourceLocation OperatorLoc, |
3848 | | NestedNameSpecifierLoc QualifierLoc, |
3849 | | SourceLocation TemplateKWLoc, |
3850 | | const DeclarationNameInfo &MemberNameInfo, |
3851 | | const TemplateArgumentListInfo *TemplateArgs, |
3852 | | UnresolvedSetIterator Begin, UnresolvedSetIterator End); |
3853 | | |
3854 | | UnresolvedMemberExpr(EmptyShell Empty, unsigned NumResults, |
3855 | | bool HasTemplateKWAndArgsInfo); |
3856 | | |
3857 | 84.8k | unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const { |
3858 | 84.8k | return getNumDecls(); |
3859 | 84.8k | } |
3860 | | |
3861 | 23.7k | unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { |
3862 | 23.7k | return hasTemplateKWAndArgsInfo(); |
3863 | 23.7k | } |
3864 | | |
3865 | | public: |
3866 | | static UnresolvedMemberExpr * |
3867 | | Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base, |
3868 | | QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, |
3869 | | NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, |
3870 | | const DeclarationNameInfo &MemberNameInfo, |
3871 | | const TemplateArgumentListInfo *TemplateArgs, |
3872 | | UnresolvedSetIterator Begin, UnresolvedSetIterator End); |
3873 | | |
3874 | | static UnresolvedMemberExpr *CreateEmpty(const ASTContext &Context, |
3875 | | unsigned NumResults, |
3876 | | bool HasTemplateKWAndArgsInfo, |
3877 | | unsigned NumTemplateArgs); |
3878 | | |
3879 | | /// True if this is an implicit access, i.e., one in which the |
3880 | | /// member being accessed was not written in the source. |
3881 | | /// |
3882 | | /// The source location of the operator is invalid in this case. |
3883 | | bool isImplicitAccess() const; |
3884 | | |
3885 | | /// Retrieve the base object of this member expressions, |
3886 | | /// e.g., the \c x in \c x.m. |
3887 | 92.8k | Expr *getBase() { |
3888 | 92.8k | assert(!isImplicitAccess()); |
3889 | 92.8k | return cast<Expr>(Base); |
3890 | 92.8k | } |
3891 | 18 | const Expr *getBase() const { |
3892 | 18 | assert(!isImplicitAccess()); |
3893 | 18 | return cast<Expr>(Base); |
3894 | 18 | } |
3895 | | |
3896 | 160k | QualType getBaseType() const { return BaseType; } |
3897 | | |
3898 | | /// Determine whether the lookup results contain an unresolved using |
3899 | | /// declaration. |
3900 | 59.0k | bool hasUnresolvedUsing() const { |
3901 | 59.0k | return UnresolvedMemberExprBits.HasUnresolvedUsing; |
3902 | 59.0k | } |
3903 | | |
3904 | | /// Determine whether this member expression used the '->' |
3905 | | /// operator; otherwise, it used the '.' operator. |
3906 | 255k | bool isArrow() const { return UnresolvedMemberExprBits.IsArrow; } |
3907 | | |
3908 | | /// Retrieve the location of the '->' or '.' operator. |
3909 | 138k | SourceLocation getOperatorLoc() const { return OperatorLoc; } |
3910 | | |
3911 | | /// Retrieve the naming class of this lookup. |
3912 | | CXXRecordDecl *getNamingClass(); |
3913 | 132 | const CXXRecordDecl *getNamingClass() const { |
3914 | 132 | return const_cast<UnresolvedMemberExpr *>(this)->getNamingClass(); |
3915 | 132 | } |
3916 | | |
3917 | | /// Retrieve the full name info for the member that this expression |
3918 | | /// refers to. |
3919 | 436k | const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); } |
3920 | | |
3921 | | /// Retrieve the name of the member that this expression refers to. |
3922 | 87.9k | DeclarationName getMemberName() const { return getName(); } |
3923 | | |
3924 | | /// Retrieve the location of the name of the member that this |
3925 | | /// expression refers to. |
3926 | 110k | SourceLocation getMemberLoc() const { return getNameLoc(); } |
3927 | | |
3928 | | /// Return the preferred location (the member name) for the arrow when |
3929 | | /// diagnosing a problem with this expression. |
3930 | 306 | SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); } |
3931 | | |
3932 | 413k | SourceLocation getBeginLoc() const LLVM_READONLY { |
3933 | 413k | if (!isImplicitAccess()) |
3934 | 99.8k | return Base->getBeginLoc(); |
3935 | 314k | if (NestedNameSpecifierLoc l = getQualifierLoc()) |
3936 | 13.1k | return l.getBeginLoc(); |
3937 | 301k | return getMemberNameInfo().getBeginLoc(); |
3938 | 301k | } |
3939 | | |
3940 | 55.8k | SourceLocation getEndLoc() const LLVM_READONLY { |
3941 | 55.8k | if (hasExplicitTemplateArgs()) |
3942 | 417 | return getRAngleLoc(); |
3943 | 55.4k | return getMemberNameInfo().getEndLoc(); |
3944 | 55.4k | } |
3945 | | |
3946 | 3.26M | static bool classof(const Stmt *T) { |
3947 | 3.26M | return T->getStmtClass() == UnresolvedMemberExprClass; |
3948 | 3.26M | } |
3949 | | |
3950 | | // Iterators |
3951 | 26.5k | child_range children() { |
3952 | 26.5k | if (isImplicitAccess()) |
3953 | 22.6k | return child_range(child_iterator(), child_iterator()); |
3954 | 3.90k | return child_range(&Base, &Base + 1); |
3955 | 3.90k | } |
3956 | | |
3957 | 0 | const_child_range children() const { |
3958 | 0 | if (isImplicitAccess()) |
3959 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
3960 | 0 | return const_child_range(&Base, &Base + 1); |
3961 | 0 | } |
3962 | | }; |
3963 | | |
3964 | 15.9M | DeclAccessPair *OverloadExpr::getTrailingResults() { |
3965 | 15.9M | if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this)) |
3966 | 14.8M | return ULE->getTrailingObjects<DeclAccessPair>(); |
3967 | 1.16M | return cast<UnresolvedMemberExpr>(this)->getTrailingObjects<DeclAccessPair>(); |
3968 | 1.16M | } |
3969 | | |
3970 | 5.89M | ASTTemplateKWAndArgsInfo *OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() { |
3971 | 5.89M | if (!hasTemplateKWAndArgsInfo()) |
3972 | 0 | return nullptr; |
3973 | | |
3974 | 5.89M | if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this)) |
3975 | 5.82M | return ULE->getTrailingObjects<ASTTemplateKWAndArgsInfo>(); |
3976 | 61.1k | return cast<UnresolvedMemberExpr>(this) |
3977 | 61.1k | ->getTrailingObjects<ASTTemplateKWAndArgsInfo>(); |
3978 | 61.1k | } |
3979 | | |
3980 | 1.47M | TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() { |
3981 | 1.47M | if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this)) |
3982 | 1.45M | return ULE->getTrailingObjects<TemplateArgumentLoc>(); |
3983 | 23.7k | return cast<UnresolvedMemberExpr>(this) |
3984 | 23.7k | ->getTrailingObjects<TemplateArgumentLoc>(); |
3985 | 23.7k | } |
3986 | | |
3987 | 69 | CXXRecordDecl *OverloadExpr::getNamingClass() { |
3988 | 69 | if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this)) |
3989 | 69 | return ULE->getNamingClass(); |
3990 | 0 | return cast<UnresolvedMemberExpr>(this)->getNamingClass(); |
3991 | 0 | } |
3992 | | |
3993 | | /// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]). |
3994 | | /// |
3995 | | /// The noexcept expression tests whether a given expression might throw. Its |
3996 | | /// result is a boolean constant. |
3997 | | class CXXNoexceptExpr : public Expr { |
3998 | | friend class ASTStmtReader; |
3999 | | |
4000 | | Stmt *Operand; |
4001 | | SourceRange Range; |
4002 | | |
4003 | | public: |
4004 | | CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val, |
4005 | | SourceLocation Keyword, SourceLocation RParen) |
4006 | | : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary), |
4007 | 13.6k | Operand(Operand), Range(Keyword, RParen) { |
4008 | 13.6k | CXXNoexceptExprBits.Value = Val == CT_Cannot; |
4009 | 13.6k | setDependence(computeDependence(this, Val)); |
4010 | 13.6k | } |
4011 | | |
4012 | 7.65k | CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {} |
4013 | | |
4014 | 16.6k | Expr *getOperand() const { return static_cast<Expr *>(Operand); } |
4015 | | |
4016 | 18.0k | SourceLocation getBeginLoc() const { return Range.getBegin(); } |
4017 | 1.09k | SourceLocation getEndLoc() const { return Range.getEnd(); } |
4018 | 1.39k | SourceRange getSourceRange() const { return Range; } |
4019 | | |
4020 | 2.21k | bool getValue() const { return CXXNoexceptExprBits.Value; } |
4021 | | |
4022 | 5.35k | static bool classof(const Stmt *T) { |
4023 | 5.35k | return T->getStmtClass() == CXXNoexceptExprClass; |
4024 | 5.35k | } |
4025 | | |
4026 | | // Iterators |
4027 | 148k | child_range children() { return child_range(&Operand, &Operand + 1); } |
4028 | | |
4029 | 0 | const_child_range children() const { |
4030 | 0 | return const_child_range(&Operand, &Operand + 1); |
4031 | 0 | } |
4032 | | }; |
4033 | | |
4034 | | /// Represents a C++11 pack expansion that produces a sequence of |
4035 | | /// expressions. |
4036 | | /// |
4037 | | /// A pack expansion expression contains a pattern (which itself is an |
4038 | | /// expression) followed by an ellipsis. For example: |
4039 | | /// |
4040 | | /// \code |
4041 | | /// template<typename F, typename ...Types> |
4042 | | /// void forward(F f, Types &&...args) { |
4043 | | /// f(static_cast<Types&&>(args)...); |
4044 | | /// } |
4045 | | /// \endcode |
4046 | | /// |
4047 | | /// Here, the argument to the function object \c f is a pack expansion whose |
4048 | | /// pattern is \c static_cast<Types&&>(args). When the \c forward function |
4049 | | /// template is instantiated, the pack expansion will instantiate to zero or |
4050 | | /// or more function arguments to the function object \c f. |
4051 | | class PackExpansionExpr : public Expr { |
4052 | | friend class ASTStmtReader; |
4053 | | friend class ASTStmtWriter; |
4054 | | |
4055 | | SourceLocation EllipsisLoc; |
4056 | | |
4057 | | /// The number of expansions that will be produced by this pack |
4058 | | /// expansion expression, if known. |
4059 | | /// |
4060 | | /// When zero, the number of expansions is not known. Otherwise, this value |
4061 | | /// is the number of expansions + 1. |
4062 | | unsigned NumExpansions; |
4063 | | |
4064 | | Stmt *Pattern; |
4065 | | |
4066 | | public: |
4067 | | PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc, |
4068 | | Optional<unsigned> NumExpansions) |
4069 | | : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), |
4070 | | Pattern->getObjectKind()), |
4071 | | EllipsisLoc(EllipsisLoc), |
4072 | | NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), |
4073 | 164k | Pattern(Pattern) { |
4074 | 164k | setDependence(computeDependence(this)); |
4075 | 164k | } |
4076 | | |
4077 | 37.6k | PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {} |
4078 | | |
4079 | | /// Retrieve the pattern of the pack expansion. |
4080 | 313k | Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); } |
4081 | | |
4082 | | /// Retrieve the pattern of the pack expansion. |
4083 | 7.85k | const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); } |
4084 | | |
4085 | | /// Retrieve the location of the ellipsis that describes this pack |
4086 | | /// expansion. |
4087 | 122k | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } |
4088 | | |
4089 | | /// Determine the number of expansions that will be produced when |
4090 | | /// this pack expansion is instantiated, if already known. |
4091 | 115k | Optional<unsigned> getNumExpansions() const { |
4092 | 115k | if (NumExpansions) |
4093 | 17 | return NumExpansions - 1; |
4094 | | |
4095 | 115k | return None; |
4096 | 115k | } |
4097 | | |
4098 | 54.5k | SourceLocation getBeginLoc() const LLVM_READONLY { |
4099 | 54.5k | return Pattern->getBeginLoc(); |
4100 | 54.5k | } |
4101 | | |
4102 | 16 | SourceLocation getEndLoc() const LLVM_READONLY { return EllipsisLoc; } |
4103 | | |
4104 | 11.0M | static bool classof(const Stmt *T) { |
4105 | 11.0M | return T->getStmtClass() == PackExpansionExprClass; |
4106 | 11.0M | } |
4107 | | |
4108 | | // Iterators |
4109 | 266k | child_range children() { |
4110 | 266k | return child_range(&Pattern, &Pattern + 1); |
4111 | 266k | } |
4112 | | |
4113 | 0 | const_child_range children() const { |
4114 | 0 | return const_child_range(&Pattern, &Pattern + 1); |
4115 | 0 | } |
4116 | | }; |
4117 | | |
4118 | | /// Represents an expression that computes the length of a parameter |
4119 | | /// pack. |
4120 | | /// |
4121 | | /// \code |
4122 | | /// template<typename ...Types> |
4123 | | /// struct count { |
4124 | | /// static const unsigned value = sizeof...(Types); |
4125 | | /// }; |
4126 | | /// \endcode |
4127 | | class SizeOfPackExpr final |
4128 | | : public Expr, |
4129 | | private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> { |
4130 | | friend class ASTStmtReader; |
4131 | | friend class ASTStmtWriter; |
4132 | | friend TrailingObjects; |
4133 | | |
4134 | | /// The location of the \c sizeof keyword. |
4135 | | SourceLocation OperatorLoc; |
4136 | | |
4137 | | /// The location of the name of the parameter pack. |
4138 | | SourceLocation PackLoc; |
4139 | | |
4140 | | /// The location of the closing parenthesis. |
4141 | | SourceLocation RParenLoc; |
4142 | | |
4143 | | /// The length of the parameter pack, if known. |
4144 | | /// |
4145 | | /// When this expression is not value-dependent, this is the length of |
4146 | | /// the pack. When the expression was parsed rather than instantiated |
4147 | | /// (and thus is value-dependent), this is zero. |
4148 | | /// |
4149 | | /// After partial substitution into a sizeof...(X) expression (for instance, |
4150 | | /// within an alias template or during function template argument deduction), |
4151 | | /// we store a trailing array of partially-substituted TemplateArguments, |
4152 | | /// and this is the length of that array. |
4153 | | unsigned Length; |
4154 | | |
4155 | | /// The parameter pack. |
4156 | | NamedDecl *Pack = nullptr; |
4157 | | |
4158 | | /// Create an expression that computes the length of |
4159 | | /// the given parameter pack. |
4160 | | SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, |
4161 | | SourceLocation PackLoc, SourceLocation RParenLoc, |
4162 | | Optional<unsigned> Length, |
4163 | | ArrayRef<TemplateArgument> PartialArgs) |
4164 | | : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary), |
4165 | | OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), |
4166 | 123k | Length(Length ? *Length : PartialArgs.size()), Pack(Pack) { |
4167 | 123k | assert((!Length || PartialArgs.empty()) && |
4168 | 123k | "have partial args for non-dependent sizeof... expression"); |
4169 | 123k | auto *Args = getTrailingObjects<TemplateArgument>(); |
4170 | 123k | std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args); |
4171 | 49.4k | setDependence(Length ? ExprDependence::None |
4172 | 74.4k | : ExprDependence::ValueInstantiation); |
4173 | 123k | } |
4174 | | |
4175 | | /// Create an empty expression. |
4176 | | SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs) |
4177 | 36.5k | : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {} |
4178 | | |
4179 | | public: |
4180 | | static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc, |
4181 | | NamedDecl *Pack, SourceLocation PackLoc, |
4182 | | SourceLocation RParenLoc, |
4183 | | Optional<unsigned> Length = None, |
4184 | | ArrayRef<TemplateArgument> PartialArgs = None); |
4185 | | static SizeOfPackExpr *CreateDeserialized(ASTContext &Context, |
4186 | | unsigned NumPartialArgs); |
4187 | | |
4188 | | /// Determine the location of the 'sizeof' keyword. |
4189 | 143k | SourceLocation getOperatorLoc() const { return OperatorLoc; } |
4190 | | |
4191 | | /// Determine the location of the parameter pack. |
4192 | 227k | SourceLocation getPackLoc() const { return PackLoc; } |
4193 | | |
4194 | | /// Determine the location of the right parenthesis. |
4195 | 77.4k | SourceLocation getRParenLoc() const { return RParenLoc; } |
4196 | | |
4197 | | /// Retrieve the parameter pack. |
4198 | 452k | NamedDecl *getPack() const { return Pack; } |
4199 | | |
4200 | | /// Retrieve the length of the parameter pack. |
4201 | | /// |
4202 | | /// This routine may only be invoked when the expression is not |
4203 | | /// value-dependent. |
4204 | 94.2k | unsigned getPackLength() const { |
4205 | 94.2k | assert(!isValueDependent() && |
4206 | 94.2k | "Cannot get the length of a value-dependent pack size expression"); |
4207 | 94.2k | return Length; |
4208 | 94.2k | } |
4209 | | |
4210 | | /// Determine whether this represents a partially-substituted sizeof... |
4211 | | /// expression, such as is produced for: |
4212 | | /// |
4213 | | /// template<typename ...Ts> using X = int[sizeof...(Ts)]; |
4214 | | /// template<typename ...Us> void f(X<Us..., 1, 2, 3, Us...>); |
4215 | 385k | bool isPartiallySubstituted() const { |
4216 | 385k | return isValueDependent() && Length354k ; |
4217 | 385k | } |
4218 | | |
4219 | | /// Get |
4220 | 434 | ArrayRef<TemplateArgument> getPartialArguments() const { |
4221 | 434 | assert(isPartiallySubstituted()); |
4222 | 434 | const auto *Args = getTrailingObjects<TemplateArgument>(); |
4223 | 434 | return llvm::makeArrayRef(Args, Args + Length); |
4224 | 434 | } |
4225 | | |
4226 | 352k | SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; } |
4227 | 24.7k | SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } |
4228 | | |
4229 | 94.2k | static bool classof(const Stmt *T) { |
4230 | 94.2k | return T->getStmtClass() == SizeOfPackExprClass; |
4231 | 94.2k | } |
4232 | | |
4233 | | // Iterators |
4234 | 362k | child_range children() { |
4235 | 362k | return child_range(child_iterator(), child_iterator()); |
4236 | 362k | } |
4237 | | |
4238 | 0 | const_child_range children() const { |
4239 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
4240 | 0 | } |
4241 | | }; |
4242 | | |
4243 | | /// Represents a reference to a non-type template parameter |
4244 | | /// that has been substituted with a template argument. |
4245 | | class SubstNonTypeTemplateParmExpr : public Expr { |
4246 | | friend class ASTReader; |
4247 | | friend class ASTStmtReader; |
4248 | | |
4249 | | /// The replaced parameter and a flag indicating if it was a reference |
4250 | | /// parameter. For class NTTPs, we can't determine that based on the value |
4251 | | /// category alone. |
4252 | | llvm::PointerIntPair<NonTypeTemplateParmDecl*, 1, bool> ParamAndRef; |
4253 | | |
4254 | | /// The replacement expression. |
4255 | | Stmt *Replacement; |
4256 | | |
4257 | | explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty) |
4258 | 95.2k | : Expr(SubstNonTypeTemplateParmExprClass, Empty) {} |
4259 | | |
4260 | | public: |
4261 | | SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind, |
4262 | | SourceLocation Loc, |
4263 | | NonTypeTemplateParmDecl *Param, bool RefParam, |
4264 | | Expr *Replacement) |
4265 | | : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary), |
4266 | 789k | ParamAndRef(Param, RefParam), Replacement(Replacement) { |
4267 | 789k | SubstNonTypeTemplateParmExprBits.NameLoc = Loc; |
4268 | 789k | setDependence(computeDependence(this)); |
4269 | 789k | } |
4270 | | |
4271 | 2.62M | SourceLocation getNameLoc() const { |
4272 | 2.62M | return SubstNonTypeTemplateParmExprBits.NameLoc; |
4273 | 2.62M | } |
4274 | 2.54M | SourceLocation getBeginLoc() const { return getNameLoc(); } |
4275 | 51.7k | SourceLocation getEndLoc() const { return getNameLoc(); } |
4276 | | |
4277 | 4.36M | Expr *getReplacement() const { return cast<Expr>(Replacement); } |
4278 | | |
4279 | 58.9k | NonTypeTemplateParmDecl *getParameter() const { |
4280 | 58.9k | return ParamAndRef.getPointer(); |
4281 | 58.9k | } |
4282 | | |
4283 | 48.0k | bool isReferenceParameter() const { return ParamAndRef.getInt(); } |
4284 | | |
4285 | | /// Determine the substituted type of the template parameter. |
4286 | | QualType getParameterType(const ASTContext &Ctx) const; |
4287 | | |
4288 | 202M | static bool classof(const Stmt *s) { |
4289 | 202M | return s->getStmtClass() == SubstNonTypeTemplateParmExprClass; |
4290 | 202M | } |
4291 | | |
4292 | | // Iterators |
4293 | 712k | child_range children() { return child_range(&Replacement, &Replacement + 1); } |
4294 | | |
4295 | 0 | const_child_range children() const { |
4296 | 0 | return const_child_range(&Replacement, &Replacement + 1); |
4297 | 0 | } |
4298 | | }; |
4299 | | |
4300 | | /// Represents a reference to a non-type template parameter pack that |
4301 | | /// has been substituted with a non-template argument pack. |
4302 | | /// |
4303 | | /// When a pack expansion in the source code contains multiple parameter packs |
4304 | | /// and those parameter packs correspond to different levels of template |
4305 | | /// parameter lists, this node is used to represent a non-type template |
4306 | | /// parameter pack from an outer level, which has already had its argument pack |
4307 | | /// substituted but that still lives within a pack expansion that itself |
4308 | | /// could not be instantiated. When actually performing a substitution into |
4309 | | /// that pack expansion (e.g., when all template parameters have corresponding |
4310 | | /// arguments), this type will be replaced with the appropriate underlying |
4311 | | /// expression at the current pack substitution index. |
4312 | | class SubstNonTypeTemplateParmPackExpr : public Expr { |
4313 | | friend class ASTReader; |
4314 | | friend class ASTStmtReader; |
4315 | | |
4316 | | /// The non-type template parameter pack itself. |
4317 | | NonTypeTemplateParmDecl *Param; |
4318 | | |
4319 | | /// A pointer to the set of template arguments that this |
4320 | | /// parameter pack is instantiated with. |
4321 | | const TemplateArgument *Arguments; |
4322 | | |
4323 | | /// The number of template arguments in \c Arguments. |
4324 | | unsigned NumArguments; |
4325 | | |
4326 | | /// The location of the non-type template parameter pack reference. |
4327 | | SourceLocation NameLoc; |
4328 | | |
4329 | | explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty) |
4330 | 0 | : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) {} |
4331 | | |
4332 | | public: |
4333 | | SubstNonTypeTemplateParmPackExpr(QualType T, |
4334 | | ExprValueKind ValueKind, |
4335 | | NonTypeTemplateParmDecl *Param, |
4336 | | SourceLocation NameLoc, |
4337 | | const TemplateArgument &ArgPack); |
4338 | | |
4339 | | /// Retrieve the non-type template parameter pack being substituted. |
4340 | 171 | NonTypeTemplateParmDecl *getParameterPack() const { return Param; } |
4341 | | |
4342 | | /// Retrieve the location of the parameter pack name. |
4343 | 145 | SourceLocation getParameterPackLocation() const { return NameLoc; } |
4344 | | |
4345 | | /// Retrieve the template argument pack containing the substituted |
4346 | | /// template arguments. |
4347 | | TemplateArgument getArgumentPack() const; |
4348 | | |
4349 | 40 | SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; } |
4350 | 1 | SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; } |
4351 | | |
4352 | 5.76k | static bool classof(const Stmt *T) { |
4353 | 5.76k | return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass; |
4354 | 5.76k | } |
4355 | | |
4356 | | // Iterators |
4357 | 88 | child_range children() { |
4358 | 88 | return child_range(child_iterator(), child_iterator()); |
4359 | 88 | } |
4360 | | |
4361 | 0 | const_child_range children() const { |
4362 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
4363 | 0 | } |
4364 | | }; |
4365 | | |
4366 | | /// Represents a reference to a function parameter pack or init-capture pack |
4367 | | /// that has been substituted but not yet expanded. |
4368 | | /// |
4369 | | /// When a pack expansion contains multiple parameter packs at different levels, |
4370 | | /// this node is used to represent a function parameter pack at an outer level |
4371 | | /// which we have already substituted to refer to expanded parameters, but where |
4372 | | /// the containing pack expansion cannot yet be expanded. |
4373 | | /// |
4374 | | /// \code |
4375 | | /// template<typename...Ts> struct S { |
4376 | | /// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...)); |
4377 | | /// }; |
4378 | | /// template struct S<int, int>; |
4379 | | /// \endcode |
4380 | | class FunctionParmPackExpr final |
4381 | | : public Expr, |
4382 | | private llvm::TrailingObjects<FunctionParmPackExpr, VarDecl *> { |
4383 | | friend class ASTReader; |
4384 | | friend class ASTStmtReader; |
4385 | | friend TrailingObjects; |
4386 | | |
4387 | | /// The function parameter pack which was referenced. |
4388 | | VarDecl *ParamPack; |
4389 | | |
4390 | | /// The location of the function parameter pack reference. |
4391 | | SourceLocation NameLoc; |
4392 | | |
4393 | | /// The number of expansions of this pack. |
4394 | | unsigned NumParameters; |
4395 | | |
4396 | | FunctionParmPackExpr(QualType T, VarDecl *ParamPack, |
4397 | | SourceLocation NameLoc, unsigned NumParams, |
4398 | | VarDecl *const *Params); |
4399 | | |
4400 | | public: |
4401 | | static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T, |
4402 | | VarDecl *ParamPack, |
4403 | | SourceLocation NameLoc, |
4404 | | ArrayRef<VarDecl *> Params); |
4405 | | static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context, |
4406 | | unsigned NumParams); |
4407 | | |
4408 | | /// Get the parameter pack which this expression refers to. |
4409 | 160 | VarDecl *getParameterPack() const { return ParamPack; } |
4410 | | |
4411 | | /// Get the location of the parameter pack. |
4412 | 1.33k | SourceLocation getParameterPackLocation() const { return NameLoc; } |
4413 | | |
4414 | | /// Iterators over the parameters which the parameter pack expanded |
4415 | | /// into. |
4416 | | using iterator = VarDecl * const *; |
4417 | 1.43k | iterator begin() const { return getTrailingObjects<VarDecl *>(); } |
4418 | 692 | iterator end() const { return begin() + NumParameters; } |
4419 | | |
4420 | | /// Get the number of parameters in this parameter pack. |
4421 | 301 | unsigned getNumExpansions() const { return NumParameters; } |
4422 | | |
4423 | | /// Get an expansion of the parameter pack by index. |
4424 | 54 | VarDecl *getExpansion(unsigned I) const { return begin()[I]; } |
4425 | | |
4426 | 201 | SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; } |
4427 | 0 | SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; } |
4428 | | |
4429 | 3.23k | static bool classof(const Stmt *T) { |
4430 | 3.23k | return T->getStmtClass() == FunctionParmPackExprClass; |
4431 | 3.23k | } |
4432 | | |
4433 | 170 | child_range children() { |
4434 | 170 | return child_range(child_iterator(), child_iterator()); |
4435 | 170 | } |
4436 | | |
4437 | 0 | const_child_range children() const { |
4438 | 0 | return const_child_range(const_child_iterator(), const_child_iterator()); |
4439 | 0 | } |
4440 | | }; |
4441 | | |
4442 | | /// Represents a prvalue temporary that is written into memory so that |
4443 | | /// a reference can bind to it. |
4444 | | /// |
4445 | | /// Prvalue expressions are materialized when they need to have an address |
4446 | | /// in memory for a reference to bind to. This happens when binding a |
4447 | | /// reference to the result of a conversion, e.g., |
4448 | | /// |
4449 | | /// \code |
4450 | | /// const int &r = 1.0; |
4451 | | /// \endcode |
4452 | | /// |
4453 | | /// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is |
4454 | | /// then materialized via a \c MaterializeTemporaryExpr, and the reference |
4455 | | /// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues |
4456 | | /// (either an lvalue or an xvalue, depending on the kind of reference binding |
4457 | | /// to it), maintaining the invariant that references always bind to glvalues. |
4458 | | /// |
4459 | | /// Reference binding and copy-elision can both extend the lifetime of a |
4460 | | /// temporary. When either happens, the expression will also track the |
4461 | | /// declaration which is responsible for the lifetime extension. |
4462 | | class MaterializeTemporaryExpr : public Expr { |
4463 | | private: |
4464 | | friend class ASTStmtReader; |
4465 | | friend class ASTStmtWriter; |
4466 | | |
4467 | | llvm::PointerUnion<Stmt *, LifetimeExtendedTemporaryDecl *> State; |
4468 | | |
4469 | | public: |
4470 | | MaterializeTemporaryExpr(QualType T, Expr *Temporary, |
4471 | | bool BoundToLvalueReference, |
4472 | | LifetimeExtendedTemporaryDecl *MTD = nullptr); |
4473 | | |
4474 | | MaterializeTemporaryExpr(EmptyShell Empty) |
4475 | 6.69k | : Expr(MaterializeTemporaryExprClass, Empty) {} |
4476 | | |
4477 | | /// Retrieve the temporary-generating subexpression whose value will |
4478 | | /// be materialized into a glvalue. |
4479 | 5.23M | Expr *getSubExpr() const { |
4480 | 5.23M | return cast<Expr>( |
4481 | 5.23M | State.is<Stmt *>() |
4482 | 5.20M | ? State.get<Stmt *>() |
4483 | 25.7k | : State.get<LifetimeExtendedTemporaryDecl *>()->getTemporaryExpr()); |
4484 | 5.23M | } |
4485 | | |
4486 | | /// Retrieve the storage duration for the materialized temporary. |
4487 | 235k | StorageDuration getStorageDuration() const { |
4488 | 226k | return State.is<Stmt *>() ? SD_FullExpression |
4489 | 9.08k | : State.get<LifetimeExtendedTemporaryDecl *>() |
4490 | 9.08k | ->getStorageDuration(); |
4491 | 235k | } |
4492 | | |
4493 | | /// Get the storage for the constant value of a materialized temporary |
4494 | | /// of static storage duration. |
4495 | 1.50k | APValue *getOrCreateValue(bool MayCreate) const { |
4496 | 1.50k | assert(State.is<LifetimeExtendedTemporaryDecl *>() && |
4497 | 1.50k | "the temporary has not been lifetime extended"); |
4498 | 1.50k | return State.get<LifetimeExtendedTemporaryDecl *>()->getOrCreateValue( |
4499 | 1.50k | MayCreate); |
4500 | 1.50k | } |
4501 | | |
4502 | 38.4k | LifetimeExtendedTemporaryDecl *getLifetimeExtendedTemporaryDecl() { |
4503 | 38.4k | return State.dyn_cast<LifetimeExtendedTemporaryDecl *>(); |
4504 | 38.4k | } |
4505 | | const LifetimeExtendedTemporaryDecl * |
4506 | 0 | getLifetimeExtendedTemporaryDecl() const { |
4507 | 0 | return State.dyn_cast<LifetimeExtendedTemporaryDecl *>(); |
4508 | 0 | } |
4509 | | |
4510 | | /// Get the declaration which triggered the lifetime-extension of this |
4511 | | /// temporary, if any. |
4512 | 20.4k | ValueDecl *getExtendingDecl() { |
4513 | 18.7k | return State.is<Stmt *>() ? nullptr |
4514 | 1.67k | : State.get<LifetimeExtendedTemporaryDecl *>() |
4515 | 1.67k | ->getExtendingDecl(); |
4516 | 20.4k | } |
4517 | 16.4k | const ValueDecl *getExtendingDecl() const { |
4518 | 16.4k | return const_cast<MaterializeTemporaryExpr *>(this)->getExtendingDecl(); |
4519 | 16.4k | } |
4520 | | |
4521 | | void setExtendingDecl(ValueDecl *ExtendedBy, unsigned ManglingNumber); |
4522 | | |
4523 | 234 | unsigned getManglingNumber() const { |
4524 | 0 | return State.is<Stmt *>() ? 0 |
4525 | 234 | : State.get<LifetimeExtendedTemporaryDecl *>() |
4526 | 234 | ->getManglingNumber(); |
4527 | 234 | } |
4528 | | |
4529 | | /// Determine whether this materialized temporary is bound to an |
4530 | | /// lvalue reference; otherwise, it's bound to an rvalue reference. |
4531 | 15.9k | bool isBoundToLvalueReference() const { |
4532 | 15.9k | return getValueKind() == VK_LValue; |
4533 | 15.9k | } |
4534 | | |
4535 | | /// Determine whether this temporary object is usable in constant |
4536 | | /// expressions, as specified in C++20 [expr.const]p4. |
4537 | | bool isUsableInConstantExpressions(const ASTContext &Context) const; |
4538 | | |
4539 | 292k | SourceLocation getBeginLoc() const LLVM_READONLY { |
4540 | 292k | return getSubExpr()->getBeginLoc(); |
4541 | 292k | } |
4542 | | |
4543 | 174k | SourceLocation getEndLoc() const LLVM_READONLY { |
4544 | 174k | return getSubExpr()->getEndLoc(); |
4545 | 174k | } |
4546 | | |
4547 | 215M | static bool classof(const Stmt *T) { |
4548 | 215M | return T->getStmtClass() == MaterializeTemporaryExprClass; |
4549 | 215M | } |
4550 | | |
4551 | | // Iterators |
4552 | 232k | child_range children() { |
4553 | 232k | return State.is<Stmt *>() |
4554 | 225k | ? child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1) |
4555 | 6.19k | : State.get<LifetimeExtendedTemporaryDecl *>()->childrenExpr(); |
4556 | 232k | } |
4557 | | |
4558 | 0 | const_child_range children() const { |
4559 | 0 | return State.is<Stmt *>() |
4560 | 0 | ? const_child_range(State.getAddrOfPtr1(), |
4561 | 0 | State.getAddrOfPtr1() + 1) |
4562 | 0 | : const_cast<const LifetimeExtendedTemporaryDecl *>( |
4563 | 0 | State.get<LifetimeExtendedTemporaryDecl *>()) |
4564 | 0 | ->childrenExpr(); |
4565 | 0 | } |
4566 | | }; |
4567 | | |
4568 | | /// Represents a folding of a pack over an operator. |
4569 | | /// |
4570 | | /// This expression is always dependent and represents a pack expansion of the |
4571 | | /// forms: |
4572 | | /// |
4573 | | /// ( expr op ... ) |
4574 | | /// ( ... op expr ) |
4575 | | /// ( expr op ... op expr ) |
4576 | | class CXXFoldExpr : public Expr { |
4577 | | friend class ASTStmtReader; |
4578 | | friend class ASTStmtWriter; |
4579 | | |
4580 | | enum SubExpr { Callee, LHS, RHS, Count }; |
4581 | | |
4582 | | SourceLocation LParenLoc; |
4583 | | SourceLocation EllipsisLoc; |
4584 | | SourceLocation RParenLoc; |
4585 | | // When 0, the number of expansions is not known. Otherwise, this is one more |
4586 | | // than the number of expansions. |
4587 | | unsigned NumExpansions; |
4588 | | Stmt *SubExprs[SubExpr::Count]; |
4589 | | BinaryOperatorKind Opcode; |
4590 | | |
4591 | | public: |
4592 | | CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee, |
4593 | | SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode, |
4594 | | SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, |
4595 | | Optional<unsigned> NumExpansions) |
4596 | | : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary), LParenLoc(LParenLoc), |
4597 | | EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), |
4598 | 261 | NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) { |
4599 | 261 | SubExprs[SubExpr::Callee] = Callee; |
4600 | 261 | SubExprs[SubExpr::LHS] = LHS; |
4601 | 261 | SubExprs[SubExpr::RHS] = RHS; |
4602 | 261 | setDependence(computeDependence(this)); |
4603 | 261 | } |
4604 | | |
4605 | 7 | CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {} |
4606 | | |
4607 | 304 | UnresolvedLookupExpr *getCallee() const { |
4608 | 304 | return static_cast<UnresolvedLookupExpr *>(SubExprs[SubExpr::Callee]); |
4609 | 304 | } |
4610 | 2.80k | Expr *getLHS() const { return static_cast<Expr*>(SubExprs[SubExpr::LHS]); } |
4611 | 638 | Expr *getRHS() const { return static_cast<Expr*>(SubExprs[SubExpr::RHS]); } |
4612 | | |
4613 | | /// Does this produce a right-associated sequence of operators? |
4614 | 1.05k | bool isRightFold() const { |
4615 | 1.05k | return getLHS() && getLHS()->containsUnexpandedParameterPack()993 ; |
4616 | 1.05k | } |
4617 | | |
4618 | | /// Does this produce a left-associated sequence of operators? |
4619 | 992 | bool isLeftFold() const { return !isRightFold(); } |
4620 | | |
4621 | | /// Get the pattern, that is, the operand that contains an unexpanded pack. |
4622 | 288 | Expr *getPattern() const { return isLeftFold() ? getRHS()45 : getLHS()243 ; } |
4623 | | |
4624 | | /// Get the operand that doesn't contain a pack, for a binary fold. |
4625 | 317 | Expr *getInit() const { return isLeftFold() ? getLHS()66 : getRHS()251 ; } |
4626 | | |
4627 | 16 | SourceLocation getLParenLoc() const { return LParenLoc; } |
4628 | 16 | SourceLocation getRParenLoc() const { return RParenLoc; } |
4629 | 868 | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } |
4630 | 723 | BinaryOperatorKind getOperator() const { return Opcode; } |
4631 | | |
4632 | 304 | Optional<unsigned> getNumExpansions() const { |
4633 | 304 | if (NumExpansions) |
4634 | 7 | return NumExpansions - 1; |
4635 | 297 | return None; |
4636 | 297 | } |
4637 | | |
4638 | 506 | SourceLocation getBeginLoc() const LLVM_READONLY { |
4639 | 506 | if (LParenLoc.isValid()) |
4640 | 420 | return LParenLoc; |
4641 | 86 | if (isLeftFold()) |
4642 | 0 | return getEllipsisLoc(); |
4643 | 86 | return getLHS()->getBeginLoc(); |
4644 | 86 | } |
4645 | | |
4646 | 188 | SourceLocation getEndLoc() const LLVM_READONLY { |
4647 | 188 | if (RParenLoc.isValid()) |
4648 | 143 | return RParenLoc; |
4649 | 45 | if (isRightFold()) |
4650 | 45 | return getEllipsisLoc(); |
4651 | 0 | return getRHS()->getEndLoc(); |
4652 | 0 | } |
4653 | | |
4654 | 453 | static bool classof(const Stmt *T) { |
4655 | 453 | return T->getStmtClass() == CXXFoldExprClass; |
4656 | 453 | } |
4657 | | |
4658 | | // Iterators |
4659 | 173 | child_range children() { |
4660 | 173 | return child_range(SubExprs, SubExprs + SubExpr::Count); |
4661 | 173 | } |
4662 | | |
4663 | 0 | const_child_range children() const { |
4664 | 0 | return const_child_range(SubExprs, SubExprs + SubExpr::Count); |
4665 | 0 | } |
4666 | | }; |
4667 | | |
4668 | | /// Represents an expression that might suspend coroutine execution; |
4669 | | /// either a co_await or co_yield expression. |
4670 | | /// |
4671 | | /// Evaluation of this expression first evaluates its 'ready' expression. If |
4672 | | /// that returns 'false': |
4673 | | /// -- execution of the coroutine is suspended |
4674 | | /// -- the 'suspend' expression is evaluated |
4675 | | /// -- if the 'suspend' expression returns 'false', the coroutine is |
4676 | | /// resumed |
4677 | | /// -- otherwise, control passes back to the resumer. |
4678 | | /// If the coroutine is not suspended, or when it is resumed, the 'resume' |
4679 | | /// expression is evaluated, and its result is the result of the overall |
4680 | | /// expression. |
4681 | | class CoroutineSuspendExpr : public Expr { |
4682 | | friend class ASTStmtReader; |
4683 | | |
4684 | | SourceLocation KeywordLoc; |
4685 | | |
4686 | | enum SubExpr { Common, Ready, Suspend, Resume, Count }; |
4687 | | |
4688 | | Stmt *SubExprs[SubExpr::Count]; |
4689 | | OpaqueValueExpr *OpaqueValue = nullptr; |
4690 | | |
4691 | | public: |
4692 | | CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common, |
4693 | | Expr *Ready, Expr *Suspend, Expr *Resume, |
4694 | | OpaqueValueExpr *OpaqueValue) |
4695 | | : Expr(SC, Resume->getType(), Resume->getValueKind(), |
4696 | | Resume->getObjectKind()), |
4697 | 574 | KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) { |
4698 | 574 | SubExprs[SubExpr::Common] = Common; |
4699 | 574 | SubExprs[SubExpr::Ready] = Ready; |
4700 | 574 | SubExprs[SubExpr::Suspend] = Suspend; |
4701 | 574 | SubExprs[SubExpr::Resume] = Resume; |
4702 | 574 | setDependence(computeDependence(this)); |
4703 | 574 | } |
4704 | | |
4705 | | CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty, |
4706 | | Expr *Common) |
4707 | 135 | : Expr(SC, Ty, VK_RValue, OK_Ordinary), KeywordLoc(KeywordLoc) { |
4708 | 135 | assert(Common->isTypeDependent() && Ty->isDependentType() && |
4709 | 135 | "wrong constructor for non-dependent co_await/co_yield expression"); |
4710 | 135 | SubExprs[SubExpr::Common] = Common; |
4711 | 135 | SubExprs[SubExpr::Ready] = nullptr; |
4712 | 135 | SubExprs[SubExpr::Suspend] = nullptr; |
4713 | 135 | SubExprs[SubExpr::Resume] = nullptr; |
4714 | 135 | setDependence(computeDependence(this)); |
4715 | 135 | } |
4716 | | |
4717 | 8 | CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { |
4718 | 8 | SubExprs[SubExpr::Common] = nullptr; |
4719 | 8 | SubExprs[SubExpr::Ready] = nullptr; |
4720 | 8 | SubExprs[SubExpr::Suspend] = nullptr; |
4721 | 8 | SubExprs[SubExpr::Resume] = nullptr; |
4722 | 8 | } |
4723 | | |
4724 | 149 | SourceLocation getKeywordLoc() const { return KeywordLoc; } |
4725 | | |
4726 | 1.03k | Expr *getCommonExpr() const { |
4727 | 1.03k | return static_cast<Expr*>(SubExprs[SubExpr::Common]); |
4728 | 1.03k | } |
4729 | | |
4730 | | /// getOpaqueValue - Return the opaque value placeholder. |
4731 | 141 | OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; } |
4732 | | |
4733 | 131 | Expr *getReadyExpr() const { |
4734 | 131 | return static_cast<Expr*>(SubExprs[SubExpr::Ready]); |
4735 | 131 | } |
4736 | | |
4737 | 131 | Expr *getSuspendExpr() const { |
4738 | 131 | return static_cast<Expr*>(SubExprs[SubExpr::Suspend]); |
4739 | 131 | } |
4740 | | |
4741 | 1.20k | Expr *getResumeExpr() const { |
4742 | 1.20k | return static_cast<Expr*>(SubExprs[SubExpr::Resume]); |
4743 | 1.20k | } |
4744 | | |
4745 | 2.11k | SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; } |
4746 | | |
4747 | 49 | SourceLocation getEndLoc() const LLVM_READONLY { |
4748 | 49 | return getCommonExpr()->getEndLoc(); |
4749 | 49 | } |
4750 | | |
4751 | 1.52k | child_range children() { |
4752 | 1.52k | return child_range(SubExprs, SubExprs + SubExpr::Count); |
4753 | 1.52k | } |
4754 | | |
4755 | 0 | const_child_range children() const { |
4756 | 0 | return const_child_range(SubExprs, SubExprs + SubExpr::Count); |
4757 | 0 | } |
4758 | | |
4759 | 347 | static bool classof(const Stmt *T) { |
4760 | 347 | return T->getStmtClass() == CoawaitExprClass || |
4761 | 148 | T->getStmtClass() == CoyieldExprClass; |
4762 | 347 | } |
4763 | | }; |
4764 | | |
4765 | | /// Represents a 'co_await' expression. |
4766 | | class CoawaitExpr : public CoroutineSuspendExpr { |
4767 | | friend class ASTStmtReader; |
4768 | | |
4769 | | public: |
4770 | | CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready, |
4771 | | Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue, |
4772 | | bool IsImplicit = false) |
4773 | | : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready, |
4774 | 519 | Suspend, Resume, OpaqueValue) { |
4775 | 519 | CoawaitBits.IsImplicit = IsImplicit; |
4776 | 519 | } |
4777 | | |
4778 | | CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand, |
4779 | | bool IsImplicit = false) |
4780 | 113 | : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) { |
4781 | 113 | CoawaitBits.IsImplicit = IsImplicit; |
4782 | 113 | } |
4783 | | |
4784 | | CoawaitExpr(EmptyShell Empty) |
4785 | 7 | : CoroutineSuspendExpr(CoawaitExprClass, Empty) {} |
4786 | | |
4787 | 122 | Expr *getOperand() const { |
4788 | | // FIXME: Dig out the actual operand or store it. |
4789 | 122 | return getCommonExpr(); |
4790 | 122 | } |
4791 | | |
4792 | 127 | bool isImplicit() const { return CoawaitBits.IsImplicit; } |
4793 | 7 | void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; } |
4794 | | |
4795 | 120 | static bool classof(const Stmt *T) { |
4796 | 120 | return T->getStmtClass() == CoawaitExprClass; |
4797 | 120 | } |
4798 | | }; |
4799 | | |
4800 | | /// Represents a 'co_await' expression while the type of the promise |
4801 | | /// is dependent. |
4802 | | class DependentCoawaitExpr : public Expr { |
4803 | | friend class ASTStmtReader; |
4804 | | |
4805 | | SourceLocation KeywordLoc; |
4806 | | Stmt *SubExprs[2]; |
4807 | | |
4808 | | public: |
4809 | | DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op, |
4810 | | UnresolvedLookupExpr *OpCoawait) |
4811 | | : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary), |
4812 | 29 | KeywordLoc(KeywordLoc) { |
4813 | | // NOTE: A co_await expression is dependent on the coroutines promise |
4814 | | // type and may be dependent even when the `Op` expression is not. |
4815 | 29 | assert(Ty->isDependentType() && |
4816 | 29 | "wrong constructor for non-dependent co_await/co_yield expression"); |
4817 | 29 | SubExprs[0] = Op; |
4818 | 29 | SubExprs[1] = OpCoawait; |
4819 | 29 | setDependence(computeDependence(this)); |
4820 | 29 | } |
4821 | | |
4822 | | DependentCoawaitExpr(EmptyShell Empty) |
4823 | 1 | : Expr(DependentCoawaitExprClass, Empty) {} |
4824 | | |
4825 | 54 | Expr *getOperand() const { return cast<Expr>(SubExprs[0]); } |
4826 | | |
4827 | 25 | UnresolvedLookupExpr *getOperatorCoawaitLookup() const { |
4828 | 25 | return cast<UnresolvedLookupExpr>(SubExprs[1]); |
4829 | 25 | } |
4830 | | |
4831 | 27 | SourceLocation getKeywordLoc() const { return KeywordLoc; } |
4832 | | |
4833 | 53 | SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; } |
4834 | | |
4835 | 0 | SourceLocation getEndLoc() const LLVM_READONLY { |
4836 | 0 | return getOperand()->getEndLoc(); |
4837 | 0 | } |
4838 | | |
4839 | 4 | child_range children() { return child_range(SubExprs, SubExprs + 2); } |
4840 | | |
4841 | 0 | const_child_range children() const { |
4842 | 0 | return const_child_range(SubExprs, SubExprs + 2); |
4843 | 0 | } |
4844 | | |
4845 | 25 | static bool classof(const Stmt *T) { |
4846 | 25 | return T->getStmtClass() == DependentCoawaitExprClass; |
4847 | 25 | } |
4848 | | }; |
4849 | | |
4850 | | /// Represents a 'co_yield' expression. |
4851 | | class CoyieldExpr : public CoroutineSuspendExpr { |
4852 | | friend class ASTStmtReader; |
4853 | | |
4854 | | public: |
4855 | | CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready, |
4856 | | Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue) |
4857 | | : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready, |
4858 | 55 | Suspend, Resume, OpaqueValue) {} |
4859 | | CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand) |
4860 | 22 | : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {} |
4861 | | CoyieldExpr(EmptyShell Empty) |
4862 | 1 | : CoroutineSuspendExpr(CoyieldExprClass, Empty) {} |
4863 | | |
4864 | 25 | Expr *getOperand() const { |
4865 | | // FIXME: Dig out the actual operand or store it. |
4866 | 25 | return getCommonExpr(); |
4867 | 25 | } |
4868 | | |
4869 | 24 | static bool classof(const Stmt *T) { |
4870 | 24 | return T->getStmtClass() == CoyieldExprClass; |
4871 | 24 | } |
4872 | | }; |
4873 | | |
4874 | | /// Represents a C++2a __builtin_bit_cast(T, v) expression. Used to implement |
4875 | | /// std::bit_cast. These can sometimes be evaluated as part of a constant |
4876 | | /// expression, but otherwise CodeGen to a simple memcpy in general. |
4877 | | class BuiltinBitCastExpr final |
4878 | | : public ExplicitCastExpr, |
4879 | | private llvm::TrailingObjects<BuiltinBitCastExpr, CXXBaseSpecifier *> { |
4880 | | friend class ASTStmtReader; |
4881 | | friend class CastExpr; |
4882 | | friend TrailingObjects; |
4883 | | |
4884 | | SourceLocation KWLoc; |
4885 | | SourceLocation RParenLoc; |
4886 | | |
4887 | | public: |
4888 | | BuiltinBitCastExpr(QualType T, ExprValueKind VK, CastKind CK, Expr *SrcExpr, |
4889 | | TypeSourceInfo *DstType, SourceLocation KWLoc, |
4890 | | SourceLocation RParenLoc) |
4891 | | : ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, false, |
4892 | | DstType), |
4893 | 681 | KWLoc(KWLoc), RParenLoc(RParenLoc) {} |
4894 | | BuiltinBitCastExpr(EmptyShell Empty) |
4895 | 1 | : ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0, false) {} |
4896 | | |
4897 | 3.85k | SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; } |
4898 | 196 | SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } |
4899 | | |
4900 | 85 | static bool classof(const Stmt *T) { |
4901 | 85 | return T->getStmtClass() == BuiltinBitCastExprClass; |
4902 | 85 | } |
4903 | | }; |
4904 | | |
4905 | | } // namespace clang |
4906 | | |
4907 | | #endif // LLVM_CLANG_AST_EXPRCXX_H |