1//===- ScopeInfo.h - Information about a semantic context -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines FunctionScopeInfo and its subclasses, which contain
10// information about a single function, block, lambda, or method body.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SEMA_SCOPEINFO_H
15#define LLVM_CLANG_SEMA_SCOPEINFO_H
16
17#include "clang/AST/Expr.h"
18#include "clang/AST/ExprCXX.h"
19#include "clang/AST/Type.h"
20#include "clang/Basic/CapturedStmt.h"
21#include "clang/Basic/LLVM.h"
22#include "clang/Basic/PartialDiagnostic.h"
23#include "clang/Basic/SourceLocation.h"
24#include "clang/Sema/CleanupInfo.h"
25#include "clang/Sema/DeclSpec.h"
26#include "llvm/ADT/DenseMap.h"
27#include "llvm/ADT/DenseMapInfo.h"
28#include "llvm/ADT/MapVector.h"
29#include "llvm/ADT/PointerIntPair.h"
30#include "llvm/ADT/SmallPtrSet.h"
31#include "llvm/ADT/SmallSet.h"
32#include "llvm/ADT/SmallVector.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/ADT/StringSwitch.h"
35#include "llvm/ADT/TinyPtrVector.h"
36#include "llvm/Support/Casting.h"
37#include "llvm/Support/ErrorHandling.h"
38#include <algorithm>
39#include <cassert>
40#include <utility>
41
42namespace clang {
43
44class BlockDecl;
45class CapturedDecl;
46class CXXMethodDecl;
47class CXXRecordDecl;
48class ImplicitParamDecl;
49class NamedDecl;
50class ObjCIvarRefExpr;
51class ObjCMessageExpr;
52class ObjCPropertyDecl;
53class ObjCPropertyRefExpr;
54class ParmVarDecl;
55class RecordDecl;
56class ReturnStmt;
57class Scope;
58class Stmt;
59class SwitchStmt;
60class TemplateParameterList;
61class VarDecl;
62
63namespace sema {
64
65/// Contains information about the compound statement currently being
66/// parsed.
67class CompoundScopeInfo {
68public:
69 /// Whether this compound stamement contains `for' or `while' loops
70 /// with empty bodies.
71 bool HasEmptyLoopBodies = false;
72
73 /// Whether this compound statement corresponds to a GNU statement
74 /// expression.
75 bool IsStmtExpr;
76
77 /// FP options at the beginning of the compound statement, prior to
78 /// any pragma.
79 FPOptions InitialFPFeatures;
80
81 CompoundScopeInfo(bool IsStmtExpr, FPOptions FPO)
82 : IsStmtExpr(IsStmtExpr), InitialFPFeatures(FPO) {}
83
84 void setHasEmptyLoopBodies() {
85 HasEmptyLoopBodies = true;
86 }
87};
88
89class PossiblyUnreachableDiag {
90public:
91 PartialDiagnostic PD;
92 SourceLocation Loc;
93 llvm::TinyPtrVector<const Stmt*> Stmts;
94
95 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
96 ArrayRef<const Stmt *> Stmts)
97 : PD(PD), Loc(Loc), Stmts(Stmts) {}
98};
99
100/// Retains information about a function, method, or block that is
101/// currently being parsed.
102class FunctionScopeInfo {
103protected:
104 enum ScopeKind {
105 SK_Function,
106 SK_Block,
107 SK_Lambda,
108 SK_CapturedRegion
109 };
110
111public:
112 /// What kind of scope we are describing.
113 ScopeKind Kind : 3;
114
115 /// Whether this function contains a VLA, \@try, try, C++
116 /// initializer, or anything else that can't be jumped past.
117 bool HasBranchProtectedScope : 1;
118
119 /// Whether this function contains any switches or direct gotos.
120 bool HasBranchIntoScope : 1;
121
122 /// Whether this function contains any indirect gotos.
123 bool HasIndirectGoto : 1;
124
125 /// Whether this function contains any statement marked with
126 /// \c [[clang::musttail]].
127 bool HasMustTail : 1;
128
129 /// Whether a statement was dropped because it was invalid.
130 bool HasDroppedStmt : 1;
131
132 /// True if current scope is for OpenMP declare reduction combiner.
133 bool HasOMPDeclareReductionCombiner : 1;
134
135 /// Whether there is a fallthrough statement in this function.
136 bool HasFallthroughStmt : 1;
137
138 /// Whether this function uses constrained floating point intrinsics
139 bool UsesFPIntrin : 1;
140
141 /// Whether we make reference to a declaration that could be
142 /// unavailable.
143 bool HasPotentialAvailabilityViolations : 1;
144
145 /// A flag that is set when parsing a method that must call super's
146 /// implementation, such as \c -dealloc, \c -finalize, or any method marked
147 /// with \c __attribute__((objc_requires_super)).
148 bool ObjCShouldCallSuper : 1;
149
150 /// True when this is a method marked as a designated initializer.
151 bool ObjCIsDesignatedInit : 1;
152
153 /// This starts true for a method marked as designated initializer and will
154 /// be set to false if there is an invocation to a designated initializer of
155 /// the super class.
156 bool ObjCWarnForNoDesignatedInitChain : 1;
157
158 /// True when this is an initializer method not marked as a designated
159 /// initializer within a class that has at least one initializer marked as a
160 /// designated initializer.
161 bool ObjCIsSecondaryInit : 1;
162
163 /// This starts true for a secondary initializer method and will be set to
164 /// false if there is an invocation of an initializer on 'self'.
165 bool ObjCWarnForNoInitDelegation : 1;
166
167 /// True only when this function has not already built, or attempted
168 /// to build, the initial and final coroutine suspend points
169 bool NeedsCoroutineSuspends : 1;
170
171 /// An enumeration represeting the kind of the first coroutine statement
172 /// in the function. One of co_return, co_await, or co_yield.
173 unsigned char FirstCoroutineStmtKind : 2;
174
175 /// Whether we found an immediate-escalating expression.
176 bool FoundImmediateEscalatingExpression : 1;
177
178 /// First coroutine statement in the current function.
179 /// (ex co_return, co_await, co_yield)
180 SourceLocation FirstCoroutineStmtLoc;
181
182 /// First 'return' statement in the current function.
183 SourceLocation FirstReturnLoc;
184
185 /// First C++ 'try' or ObjC @try statement in the current function.
186 SourceLocation FirstCXXOrObjCTryLoc;
187 enum { TryLocIsCXX, TryLocIsObjC, Unknown } FirstTryType = Unknown;
188
189 /// First SEH '__try' statement in the current function.
190 SourceLocation FirstSEHTryLoc;
191
192private:
193 /// Used to determine if errors occurred in this function or block.
194 DiagnosticErrorTrap ErrorTrap;
195
196public:
197 /// A SwitchStmt, along with a flag indicating if its list of case statements
198 /// is incomplete (because we dropped an invalid one while parsing).
199 using SwitchInfo = llvm::PointerIntPair<SwitchStmt*, 1, bool>;
200
201 /// SwitchStack - This is the current set of active switch statements in the
202 /// block.
203 SmallVector<SwitchInfo, 8> SwitchStack;
204
205 /// The list of return statements that occur within the function or
206 /// block, if there is any chance of applying the named return value
207 /// optimization, or if we need to infer a return type.
208 SmallVector<ReturnStmt*, 4> Returns;
209
210 /// The promise object for this coroutine, if any.
211 VarDecl *CoroutinePromise = nullptr;
212
213 /// A mapping between the coroutine function parameters that were moved
214 /// to the coroutine frame, and their move statements.
215 llvm::SmallMapVector<ParmVarDecl *, Stmt *, 4> CoroutineParameterMoves;
216
217 /// The initial and final coroutine suspend points.
218 std::pair<Stmt *, Stmt *> CoroutineSuspends;
219
220 /// The stack of currently active compound stamement scopes in the
221 /// function.
222 SmallVector<CompoundScopeInfo, 4> CompoundScopes;
223
224 /// The set of blocks that are introduced in this function.
225 llvm::SmallPtrSet<const BlockDecl *, 1> Blocks;
226
227 /// The set of __block variables that are introduced in this function.
228 llvm::TinyPtrVector<VarDecl *> ByrefBlockVars;
229
230 /// A list of PartialDiagnostics created but delayed within the
231 /// current function scope. These diagnostics are vetted for reachability
232 /// prior to being emitted.
233 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
234
235 /// A list of parameters which have the nonnull attribute and are
236 /// modified in the function.
237 llvm::SmallPtrSet<const ParmVarDecl *, 8> ModifiedNonNullParams;
238
239 /// The set of GNU address of label extension "&&label".
240 llvm::SmallVector<AddrLabelExpr *, 4> AddrLabels;
241
242public:
243 /// Represents a simple identification of a weak object.
244 ///
245 /// Part of the implementation of -Wrepeated-use-of-weak.
246 ///
247 /// This is used to determine if two weak accesses refer to the same object.
248 /// Here are some examples of how various accesses are "profiled":
249 ///
250 /// Access Expression | "Base" Decl | "Property" Decl
251 /// :---------------: | :-----------------: | :------------------------------:
252 /// self.property | self (VarDecl) | property (ObjCPropertyDecl)
253 /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl)
254 /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
255 /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl)
256 /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl)
257 /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl)
258 /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
259 /// MyClass.foo.prop | +foo (ObjCMethodDecl) | -prop (ObjCPropertyDecl)
260 /// weakVar | 0 (known) | weakVar (VarDecl)
261 /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl)
262 ///
263 /// Objects are identified with only two Decls to make it reasonably fast to
264 /// compare them.
265 class WeakObjectProfileTy {
266 /// The base object decl, as described in the class documentation.
267 ///
268 /// The extra flag is "true" if the Base and Property are enough to uniquely
269 /// identify the object in memory.
270 ///
271 /// \sa isExactProfile()
272 using BaseInfoTy = llvm::PointerIntPair<const NamedDecl *, 1, bool>;
273 BaseInfoTy Base;
274
275 /// The "property" decl, as described in the class documentation.
276 ///
277 /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
278 /// case of "implicit" properties (regular methods accessed via dot syntax).
279 const NamedDecl *Property = nullptr;
280
281 /// Used to find the proper base profile for a given base expression.
282 static BaseInfoTy getBaseInfo(const Expr *BaseE);
283
284 inline WeakObjectProfileTy();
285 static inline WeakObjectProfileTy getSentinel();
286
287 public:
288 WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
289 WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
290 WeakObjectProfileTy(const DeclRefExpr *RE);
291 WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
292
293 const NamedDecl *getBase() const { return Base.getPointer(); }
294 const NamedDecl *getProperty() const { return Property; }
295
296 /// Returns true if the object base specifies a known object in memory,
297 /// rather than, say, an instance variable or property of another object.
298 ///
299 /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
300 /// considered an exact profile if \c foo is a local variable, even if
301 /// another variable \c foo2 refers to the same object as \c foo.
302 ///
303 /// For increased precision, accesses with base variables that are
304 /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
305 /// be exact, though this is not true for arbitrary variables
306 /// (foo.prop1.prop2).
307 bool isExactProfile() const {
308 return Base.getInt();
309 }
310
311 bool operator==(const WeakObjectProfileTy &Other) const {
312 return Base == Other.Base && Property == Other.Property;
313 }
314
315 // For use in DenseMap.
316 // We can't specialize the usual llvm::DenseMapInfo at the end of the file
317 // because by that point the DenseMap in FunctionScopeInfo has already been
318 // instantiated.
319 class DenseMapInfo {
320 public:
321 static inline WeakObjectProfileTy getEmptyKey() {
322 return WeakObjectProfileTy();
323 }
324
325 static inline WeakObjectProfileTy getTombstoneKey() {
326 return WeakObjectProfileTy::getSentinel();
327 }
328
329 static unsigned getHashValue(const WeakObjectProfileTy &Val) {
330 using Pair = std::pair<BaseInfoTy, const NamedDecl *>;
331
332 return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
333 Val.Property));
334 }
335
336 static bool isEqual(const WeakObjectProfileTy &LHS,
337 const WeakObjectProfileTy &RHS) {
338 return LHS == RHS;
339 }
340 };
341 };
342
343 /// Represents a single use of a weak object.
344 ///
345 /// Stores both the expression and whether the access is potentially unsafe
346 /// (i.e. it could potentially be warned about).
347 ///
348 /// Part of the implementation of -Wrepeated-use-of-weak.
349 class WeakUseTy {
350 llvm::PointerIntPair<const Expr *, 1, bool> Rep;
351
352 public:
353 WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
354
355 const Expr *getUseExpr() const { return Rep.getPointer(); }
356 bool isUnsafe() const { return Rep.getInt(); }
357 void markSafe() { Rep.setInt(false); }
358
359 bool operator==(const WeakUseTy &Other) const {
360 return Rep == Other.Rep;
361 }
362 };
363
364 /// Used to collect uses of a particular weak object in a function body.
365 ///
366 /// Part of the implementation of -Wrepeated-use-of-weak.
367 using WeakUseVector = SmallVector<WeakUseTy, 4>;
368
369 /// Used to collect all uses of weak objects in a function body.
370 ///
371 /// Part of the implementation of -Wrepeated-use-of-weak.
372 using WeakObjectUseMap =
373 llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
374 WeakObjectProfileTy::DenseMapInfo>;
375
376private:
377 /// Used to collect all uses of weak objects in this function body.
378 ///
379 /// Part of the implementation of -Wrepeated-use-of-weak.
380 WeakObjectUseMap WeakObjectUses;
381
382protected:
383 FunctionScopeInfo(const FunctionScopeInfo&) = default;
384
385public:
386 FunctionScopeInfo(DiagnosticsEngine &Diag)
387 : Kind(SK_Function), HasBranchProtectedScope(false),
388 HasBranchIntoScope(false), HasIndirectGoto(false), HasMustTail(false),
389 HasDroppedStmt(false), HasOMPDeclareReductionCombiner(false),
390 HasFallthroughStmt(false), UsesFPIntrin(false),
391 HasPotentialAvailabilityViolations(false), ObjCShouldCallSuper(false),
392 ObjCIsDesignatedInit(false), ObjCWarnForNoDesignatedInitChain(false),
393 ObjCIsSecondaryInit(false), ObjCWarnForNoInitDelegation(false),
394 NeedsCoroutineSuspends(true), FoundImmediateEscalatingExpression(false),
395 ErrorTrap(Diag) {}
396
397 virtual ~FunctionScopeInfo();
398
399 /// Determine whether an unrecoverable error has occurred within this
400 /// function. Note that this may return false even if the function body is
401 /// invalid, because the errors may be suppressed if they're caused by prior
402 /// invalid declarations.
403 ///
404 /// FIXME: Migrate the caller of this to use containsErrors() instead once
405 /// it's ready.
406 bool hasUnrecoverableErrorOccurred() const {
407 return ErrorTrap.hasUnrecoverableErrorOccurred();
408 }
409
410 /// Record that a weak object was accessed.
411 ///
412 /// Part of the implementation of -Wrepeated-use-of-weak.
413 template <typename ExprT>
414 inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
415
416 void recordUseOfWeak(const ObjCMessageExpr *Msg,
417 const ObjCPropertyDecl *Prop);
418
419 /// Record that a given expression is a "safe" access of a weak object (e.g.
420 /// assigning it to a strong variable.)
421 ///
422 /// Part of the implementation of -Wrepeated-use-of-weak.
423 void markSafeWeakUse(const Expr *E);
424
425 const WeakObjectUseMap &getWeakObjectUses() const {
426 return WeakObjectUses;
427 }
428
429 void setHasBranchIntoScope() {
430 HasBranchIntoScope = true;
431 }
432
433 void setHasBranchProtectedScope() {
434 HasBranchProtectedScope = true;
435 }
436
437 void setHasIndirectGoto() {
438 HasIndirectGoto = true;
439 }
440
441 void setHasMustTail() { HasMustTail = true; }
442
443 void setHasDroppedStmt() {
444 HasDroppedStmt = true;
445 }
446
447 void setHasOMPDeclareReductionCombiner() {
448 HasOMPDeclareReductionCombiner = true;
449 }
450
451 void setHasFallthroughStmt() {
452 HasFallthroughStmt = true;
453 }
454
455 void setUsesFPIntrin() {
456 UsesFPIntrin = true;
457 }
458
459 void setHasCXXTry(SourceLocation TryLoc) {
460 setHasBranchProtectedScope();
461 FirstCXXOrObjCTryLoc = TryLoc;
462 FirstTryType = TryLocIsCXX;
463 }
464
465 void setHasObjCTry(SourceLocation TryLoc) {
466 setHasBranchProtectedScope();
467 FirstCXXOrObjCTryLoc = TryLoc;
468 FirstTryType = TryLocIsObjC;
469 }
470
471 void setHasSEHTry(SourceLocation TryLoc) {
472 setHasBranchProtectedScope();
473 FirstSEHTryLoc = TryLoc;
474 }
475
476 bool NeedsScopeChecking() const {
477 return !HasDroppedStmt && (HasIndirectGoto || HasMustTail ||
478 (HasBranchProtectedScope && HasBranchIntoScope));
479 }
480
481 // Add a block introduced in this function.
482 void addBlock(const BlockDecl *BD) {
483 Blocks.insert(BD);
484 }
485
486 // Add a __block variable introduced in this function.
487 void addByrefBlockVar(VarDecl *VD) {
488 ByrefBlockVars.push_back(VD);
489 }
490
491 bool isCoroutine() const { return !FirstCoroutineStmtLoc.isInvalid(); }
492
493 void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword) {
494 assert(FirstCoroutineStmtLoc.isInvalid() &&
495 "first coroutine statement location already set");
496 FirstCoroutineStmtLoc = Loc;
497 FirstCoroutineStmtKind = llvm::StringSwitch<unsigned char>(Keyword)
498 .Case("co_return", 0)
499 .Case("co_await", 1)
500 .Case("co_yield", 2);
501 }
502
503 StringRef getFirstCoroutineStmtKeyword() const {
504 assert(FirstCoroutineStmtLoc.isValid()
505 && "no coroutine statement available");
506 switch (FirstCoroutineStmtKind) {
507 case 0: return "co_return";
508 case 1: return "co_await";
509 case 2: return "co_yield";
510 default:
511 llvm_unreachable("FirstCoroutineStmtKind has an invalid value");
512 };
513 }
514
515 void setNeedsCoroutineSuspends(bool value = true) {
516 assert((!value || CoroutineSuspends.first == nullptr) &&
517 "we already have valid suspend points");
518 NeedsCoroutineSuspends = value;
519 }
520
521 bool hasInvalidCoroutineSuspends() const {
522 return !NeedsCoroutineSuspends && CoroutineSuspends.first == nullptr;
523 }
524
525 void setCoroutineSuspends(Stmt *Initial, Stmt *Final) {
526 assert(Initial && Final && "suspend points cannot be null");
527 assert(CoroutineSuspends.first == nullptr && "suspend points already set");
528 NeedsCoroutineSuspends = false;
529 CoroutineSuspends.first = Initial;
530 CoroutineSuspends.second = Final;
531 }
532
533 /// Clear out the information in this function scope, making it
534 /// suitable for reuse.
535 void Clear();
536
537 bool isPlainFunction() const { return Kind == SK_Function; }
538};
539
540class Capture {
541 // There are three categories of capture: capturing 'this', capturing
542 // local variables, and C++1y initialized captures (which can have an
543 // arbitrary initializer, and don't really capture in the traditional
544 // sense at all).
545 //
546 // There are three ways to capture a local variable:
547 // - capture by copy in the C++11 sense,
548 // - capture by reference in the C++11 sense, and
549 // - __block capture.
550 // Lambdas explicitly specify capture by copy or capture by reference.
551 // For blocks, __block capture applies to variables with that annotation,
552 // variables of reference type are captured by reference, and other
553 // variables are captured by copy.
554 enum CaptureKind {
555 Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
556 };
557
558 union {
559 /// If Kind == Cap_VLA, the captured type.
560 const VariableArrayType *CapturedVLA;
561
562 /// Otherwise, the captured variable (if any).
563 ValueDecl *CapturedVar;
564 };
565
566 /// The source location at which the first capture occurred.
567 SourceLocation Loc;
568
569 /// The location of the ellipsis that expands a parameter pack.
570 SourceLocation EllipsisLoc;
571
572 /// The type as it was captured, which is the type of the non-static data
573 /// member that would hold the capture.
574 QualType CaptureType;
575
576 /// The CaptureKind of this capture.
577 unsigned Kind : 2;
578
579 /// Whether this is a nested capture (a capture of an enclosing capturing
580 /// scope's capture).
581 unsigned Nested : 1;
582
583 /// Whether this is a capture of '*this'.
584 unsigned CapturesThis : 1;
585
586 /// Whether an explicit capture has been odr-used in the body of the
587 /// lambda.
588 unsigned ODRUsed : 1;
589
590 /// Whether an explicit capture has been non-odr-used in the body of
591 /// the lambda.
592 unsigned NonODRUsed : 1;
593
594 /// Whether the capture is invalid (a capture was required but the entity is
595 /// non-capturable).
596 unsigned Invalid : 1;
597
598public:
599 Capture(ValueDecl *Var, bool Block, bool ByRef, bool IsNested,
600 SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType,
601 bool Invalid)
602 : CapturedVar(Var), Loc(Loc), EllipsisLoc(EllipsisLoc),
603 CaptureType(CaptureType), Kind(Block ? Cap_Block
604 : ByRef ? Cap_ByRef
605 : Cap_ByCopy),
606 Nested(IsNested), CapturesThis(false), ODRUsed(false),
607 NonODRUsed(false), Invalid(Invalid) {}
608
609 enum IsThisCapture { ThisCapture };
610 Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
611 QualType CaptureType, const bool ByCopy, bool Invalid)
612 : Loc(Loc), CaptureType(CaptureType),
613 Kind(ByCopy ? Cap_ByCopy : Cap_ByRef), Nested(IsNested),
614 CapturesThis(true), ODRUsed(false), NonODRUsed(false),
615 Invalid(Invalid) {}
616
617 enum IsVLACapture { VLACapture };
618 Capture(IsVLACapture, const VariableArrayType *VLA, bool IsNested,
619 SourceLocation Loc, QualType CaptureType)
620 : CapturedVLA(VLA), Loc(Loc), CaptureType(CaptureType), Kind(Cap_VLA),
621 Nested(IsNested), CapturesThis(false), ODRUsed(false),
622 NonODRUsed(false), Invalid(false) {}
623
624 bool isThisCapture() const { return CapturesThis; }
625 bool isVariableCapture() const {
626 return !isThisCapture() && !isVLATypeCapture();
627 }
628
629 bool isCopyCapture() const { return Kind == Cap_ByCopy; }
630 bool isReferenceCapture() const { return Kind == Cap_ByRef; }
631 bool isBlockCapture() const { return Kind == Cap_Block; }
632 bool isVLATypeCapture() const { return Kind == Cap_VLA; }
633
634 bool isNested() const { return Nested; }
635
636 bool isInvalid() const { return Invalid; }
637
638 /// Determine whether this capture is an init-capture.
639 bool isInitCapture() const;
640
641 bool isODRUsed() const { return ODRUsed; }
642 bool isNonODRUsed() const { return NonODRUsed; }
643 void markUsed(bool IsODRUse) {
644 if (IsODRUse)
645 ODRUsed = true;
646 else
647 NonODRUsed = true;
648 }
649
650 ValueDecl *getVariable() const {
651 assert(isVariableCapture());
652 return CapturedVar;
653 }
654
655 const VariableArrayType *getCapturedVLAType() const {
656 assert(isVLATypeCapture());
657 return CapturedVLA;
658 }
659
660 /// Retrieve the location at which this variable was captured.
661 SourceLocation getLocation() const { return Loc; }
662
663 /// Retrieve the source location of the ellipsis, whose presence
664 /// indicates that the capture is a pack expansion.
665 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
666
667 /// Retrieve the capture type for this capture, which is effectively
668 /// the type of the non-static data member in the lambda/block structure
669 /// that would store this capture.
670 QualType getCaptureType() const { return CaptureType; }
671};
672
673class CapturingScopeInfo : public FunctionScopeInfo {
674protected:
675 CapturingScopeInfo(const CapturingScopeInfo&) = default;
676
677public:
678 enum ImplicitCaptureStyle {
679 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
680 ImpCap_CapturedRegion
681 };
682
683 ImplicitCaptureStyle ImpCaptureStyle;
684
685 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
686 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
687
688 /// CaptureMap - A map of captured variables to (index+1) into Captures.
689 llvm::DenseMap<ValueDecl *, unsigned> CaptureMap;
690
691 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
692 /// zero if 'this' is not captured.
693 unsigned CXXThisCaptureIndex = 0;
694
695 /// Captures - The captures.
696 SmallVector<Capture, 4> Captures;
697
698 /// - Whether the target type of return statements in this context
699 /// is deduced (e.g. a lambda or block with omitted return type).
700 bool HasImplicitReturnType = false;
701
702 /// ReturnType - The target type of return statements in this context,
703 /// or null if unknown.
704 QualType ReturnType;
705
706 void addCapture(ValueDecl *Var, bool isBlock, bool isByref, bool isNested,
707 SourceLocation Loc, SourceLocation EllipsisLoc,
708 QualType CaptureType, bool Invalid) {
709 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
710 EllipsisLoc, CaptureType, Invalid));
711 CaptureMap[Var] = Captures.size();
712 }
713
714 void addVLATypeCapture(SourceLocation Loc, const VariableArrayType *VLAType,
715 QualType CaptureType) {
716 Captures.push_back(Capture(Capture::VLACapture, VLAType,
717 /*FIXME: IsNested*/ false, Loc, CaptureType));
718 }
719
720 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
721 bool ByCopy);
722
723 /// Determine whether the C++ 'this' is captured.
724 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
725
726 /// Retrieve the capture of C++ 'this', if it has been captured.
727 Capture &getCXXThisCapture() {
728 assert(isCXXThisCaptured() && "this has not been captured");
729 return Captures[CXXThisCaptureIndex - 1];
730 }
731
732 /// Determine whether the given variable has been captured.
733 bool isCaptured(ValueDecl *Var) const { return CaptureMap.count(Var); }
734
735 /// Determine whether the given variable-array type has been captured.
736 bool isVLATypeCaptured(const VariableArrayType *VAT) const;
737
738 /// Retrieve the capture of the given variable, if it has been
739 /// captured already.
740 Capture &getCapture(ValueDecl *Var) {
741 assert(isCaptured(Var) && "Variable has not been captured");
742 return Captures[CaptureMap[Var] - 1];
743 }
744
745 const Capture &getCapture(ValueDecl *Var) const {
746 llvm::DenseMap<ValueDecl *, unsigned>::const_iterator Known =
747 CaptureMap.find(Var);
748 assert(Known != CaptureMap.end() && "Variable has not been captured");
749 return Captures[Known->second - 1];
750 }
751
752 static bool classof(const FunctionScopeInfo *FSI) {
753 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
754 || FSI->Kind == SK_CapturedRegion;
755 }
756};
757
758/// Retains information about a block that is currently being parsed.
759class BlockScopeInfo final : public CapturingScopeInfo {
760public:
761 BlockDecl *TheDecl;
762
763 /// TheScope - This is the scope for the block itself, which contains
764 /// arguments etc.
765 Scope *TheScope;
766
767 /// BlockType - The function type of the block, if one was given.
768 /// Its return type may be BuiltinType::Dependent.
769 QualType FunctionType;
770
771 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
772 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
773 TheScope(BlockScope) {
774 Kind = SK_Block;
775 }
776
777 ~BlockScopeInfo() override;
778
779 static bool classof(const FunctionScopeInfo *FSI) {
780 return FSI->Kind == SK_Block;
781 }
782};
783
784/// Retains information about a captured region.
785class CapturedRegionScopeInfo final : public CapturingScopeInfo {
786public:
787 /// The CapturedDecl for this statement.
788 CapturedDecl *TheCapturedDecl;
789
790 /// The captured record type.
791 RecordDecl *TheRecordDecl;
792
793 /// This is the enclosing scope of the captured region.
794 Scope *TheScope;
795
796 /// The implicit parameter for the captured variables.
797 ImplicitParamDecl *ContextParam;
798
799 /// The kind of captured region.
800 unsigned short CapRegionKind;
801
802 unsigned short OpenMPLevel;
803 unsigned short OpenMPCaptureLevel;
804
805 CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
806 RecordDecl *RD, ImplicitParamDecl *Context,
807 CapturedRegionKind K, unsigned OpenMPLevel,
808 unsigned OpenMPCaptureLevel)
809 : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
810 TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
811 ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel),
812 OpenMPCaptureLevel(OpenMPCaptureLevel) {
813 Kind = SK_CapturedRegion;
814 }
815
816 ~CapturedRegionScopeInfo() override;
817
818 /// A descriptive name for the kind of captured region this is.
819 StringRef getRegionName() const {
820 switch (CapRegionKind) {
821 case CR_Default:
822 return "default captured statement";
823 case CR_ObjCAtFinally:
824 return "Objective-C @finally statement";
825 case CR_OpenMP:
826 return "OpenMP region";
827 }
828 llvm_unreachable("Invalid captured region kind!");
829 }
830
831 static bool classof(const FunctionScopeInfo *FSI) {
832 return FSI->Kind == SK_CapturedRegion;
833 }
834};
835
836class LambdaScopeInfo final :
837 public CapturingScopeInfo, public InventedTemplateParameterInfo {
838public:
839 /// The class that describes the lambda.
840 CXXRecordDecl *Lambda = nullptr;
841
842 /// The lambda's compiler-generated \c operator().
843 CXXMethodDecl *CallOperator = nullptr;
844
845 /// Indicate that we parsed the parameter list
846 /// at which point the mutability of the lambda
847 /// is known.
848 bool AfterParameterList = true;
849
850 /// Source range covering the lambda introducer [...].
851 SourceRange IntroducerRange;
852
853 /// Source location of the '&' or '=' specifying the default capture
854 /// type, if any.
855 SourceLocation CaptureDefaultLoc;
856
857 /// The number of captures in the \c Captures list that are
858 /// explicit captures.
859 unsigned NumExplicitCaptures = 0;
860
861 /// Whether this is a mutable lambda. Until the mutable keyword is parsed,
862 /// we assume the lambda is mutable.
863 bool Mutable = true;
864
865 /// Whether the (empty) parameter list is explicit.
866 bool ExplicitParams = false;
867
868 /// Whether any of the capture expressions requires cleanups.
869 CleanupInfo Cleanup;
870
871 /// Whether the lambda contains an unexpanded parameter pack.
872 bool ContainsUnexpandedParameterPack = false;
873
874 /// Packs introduced by this lambda, if any.
875 SmallVector<NamedDecl*, 4> LocalPacks;
876
877 /// Source range covering the explicit template parameter list (if it exists).
878 SourceRange ExplicitTemplateParamsRange;
879
880 /// The requires-clause immediately following the explicit template parameter
881 /// list, if any. (Note that there may be another requires-clause included as
882 /// part of the lambda-declarator.)
883 ExprResult RequiresClause;
884
885 /// If this is a generic lambda, and the template parameter
886 /// list has been created (from the TemplateParams) then store
887 /// a reference to it (cache it to avoid reconstructing it).
888 TemplateParameterList *GLTemplateParameterList = nullptr;
889
890 /// Contains all variable-referring-expressions (i.e. DeclRefExprs
891 /// or MemberExprs) that refer to local variables in a generic lambda
892 /// or a lambda in a potentially-evaluated-if-used context.
893 ///
894 /// Potentially capturable variables of a nested lambda that might need
895 /// to be captured by the lambda are housed here.
896 /// This is specifically useful for generic lambdas or
897 /// lambdas within a potentially evaluated-if-used context.
898 /// If an enclosing variable is named in an expression of a lambda nested
899 /// within a generic lambda, we don't always know whether the variable
900 /// will truly be odr-used (i.e. need to be captured) by that nested lambda,
901 /// until its instantiation. But we still need to capture it in the
902 /// enclosing lambda if all intervening lambdas can capture the variable.
903 llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
904
905 /// Contains all variable-referring-expressions that refer
906 /// to local variables that are usable as constant expressions and
907 /// do not involve an odr-use (they may still need to be captured
908 /// if the enclosing full-expression is instantiation dependent).
909 llvm::SmallSet<Expr *, 8> NonODRUsedCapturingExprs;
910
911 /// A map of explicit capture indices to their introducer source ranges.
912 llvm::DenseMap<unsigned, SourceRange> ExplicitCaptureRanges;
913
914 /// Contains all of the variables defined in this lambda that shadow variables
915 /// that were defined in parent contexts. Used to avoid warnings when the
916 /// shadowed variables are uncaptured by this lambda.
917 struct ShadowedOuterDecl {
918 const VarDecl *VD;
919 const VarDecl *ShadowedDecl;
920 };
921 llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls;
922
923 SourceLocation PotentialThisCaptureLocation;
924
925 LambdaScopeInfo(DiagnosticsEngine &Diag)
926 : CapturingScopeInfo(Diag, ImpCap_None) {
927 Kind = SK_Lambda;
928 }
929
930 /// Note when all explicit captures have been added.
931 void finishedExplicitCaptures() {
932 NumExplicitCaptures = Captures.size();
933 }
934
935 static bool classof(const FunctionScopeInfo *FSI) {
936 return FSI->Kind == SK_Lambda;
937 }
938
939 /// Is this scope known to be for a generic lambda? (This will be false until
940 /// we parse a template parameter list or the first 'auto'-typed parameter).
941 bool isGenericLambda() const {
942 return !TemplateParams.empty() || GLTemplateParameterList;
943 }
944
945 /// Add a variable that might potentially be captured by the
946 /// lambda and therefore the enclosing lambdas.
947 ///
948 /// This is also used by enclosing lambda's to speculatively capture
949 /// variables that nested lambda's - depending on their enclosing
950 /// specialization - might need to capture.
951 /// Consider:
952 /// void f(int, int); <-- don't capture
953 /// void f(const int&, double); <-- capture
954 /// void foo() {
955 /// const int x = 10;
956 /// auto L = [=](auto a) { // capture 'x'
957 /// return [=](auto b) {
958 /// f(x, a); // we may or may not need to capture 'x'
959 /// };
960 /// };
961 /// }
962 void addPotentialCapture(Expr *VarExpr) {
963 assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr) ||
964 isa<FunctionParmPackExpr>(VarExpr));
965 PotentiallyCapturingExprs.push_back(VarExpr);
966 }
967
968 void addPotentialThisCapture(SourceLocation Loc) {
969 PotentialThisCaptureLocation = Loc;
970 }
971
972 bool hasPotentialThisCapture() const {
973 return PotentialThisCaptureLocation.isValid();
974 }
975
976 /// Mark a variable's reference in a lambda as non-odr using.
977 ///
978 /// For generic lambdas, if a variable is named in a potentially evaluated
979 /// expression, where the enclosing full expression is dependent then we
980 /// must capture the variable (given a default capture).
981 /// This is accomplished by recording all references to variables
982 /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of
983 /// PotentialCaptures. All such variables have to be captured by that lambda,
984 /// except for as described below.
985 /// If that variable is usable as a constant expression and is named in a
986 /// manner that does not involve its odr-use (e.g. undergoes
987 /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
988 /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
989 /// if we can determine that the full expression is not instantiation-
990 /// dependent, then we can entirely avoid its capture.
991 ///
992 /// const int n = 0;
993 /// [&] (auto x) {
994 /// (void)+n + x;
995 /// };
996 /// Interestingly, this strategy would involve a capture of n, even though
997 /// it's obviously not odr-used here, because the full-expression is
998 /// instantiation-dependent. It could be useful to avoid capturing such
999 /// variables, even when they are referred to in an instantiation-dependent
1000 /// expression, if we can unambiguously determine that they shall never be
1001 /// odr-used. This would involve removal of the variable-referring-expression
1002 /// from the array of PotentialCaptures during the lvalue-to-rvalue
1003 /// conversions. But per the working draft N3797, (post-chicago 2013) we must
1004 /// capture such variables.
1005 /// Before anyone is tempted to implement a strategy for not-capturing 'n',
1006 /// consider the insightful warning in:
1007 /// /cfe-commits/Week-of-Mon-20131104/092596.html
1008 /// "The problem is that the set of captures for a lambda is part of the ABI
1009 /// (since lambda layout can be made visible through inline functions and the
1010 /// like), and there are no guarantees as to which cases we'll manage to build
1011 /// an lvalue-to-rvalue conversion in, when parsing a template -- some
1012 /// seemingly harmless change elsewhere in Sema could cause us to start or stop
1013 /// building such a node. So we need a rule that anyone can implement and get
1014 /// exactly the same result".
1015 void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
1016 assert(isa<DeclRefExpr>(CapturingVarExpr) ||
1017 isa<MemberExpr>(CapturingVarExpr) ||
1018 isa<FunctionParmPackExpr>(CapturingVarExpr));
1019 NonODRUsedCapturingExprs.insert(CapturingVarExpr);
1020 }
1021 bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
1022 assert(isa<DeclRefExpr>(CapturingVarExpr) ||
1023 isa<MemberExpr>(CapturingVarExpr) ||
1024 isa<FunctionParmPackExpr>(CapturingVarExpr));
1025 return NonODRUsedCapturingExprs.count(CapturingVarExpr);
1026 }
1027 void removePotentialCapture(Expr *E) {
1028 llvm::erase_value(PotentiallyCapturingExprs, E);
1029 }
1030 void clearPotentialCaptures() {
1031 PotentiallyCapturingExprs.clear();
1032 PotentialThisCaptureLocation = SourceLocation();
1033 }
1034 unsigned getNumPotentialVariableCaptures() const {
1035 return PotentiallyCapturingExprs.size();
1036 }
1037
1038 bool hasPotentialCaptures() const {
1039 return getNumPotentialVariableCaptures() ||
1040 PotentialThisCaptureLocation.isValid();
1041 }
1042
1043 void visitPotentialCaptures(
1044 llvm::function_ref<void(ValueDecl *, Expr *)> Callback) const;
1045};
1046
1047FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
1048 : Base(nullptr, false) {}
1049
1050FunctionScopeInfo::WeakObjectProfileTy
1051FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
1052 FunctionScopeInfo::WeakObjectProfileTy Result;
1053 Result.Base.setInt(true);
1054 return Result;
1055}
1056
1057template <typename ExprT>
1058void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
1059 assert(E);
1060 WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
1061 Uses.push_back(WeakUseTy(E, IsRead));
1062}
1063
1064inline void CapturingScopeInfo::addThisCapture(bool isNested,
1065 SourceLocation Loc,
1066 QualType CaptureType,
1067 bool ByCopy) {
1068 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
1069 ByCopy, /*Invalid*/ false));
1070 CXXThisCaptureIndex = Captures.size();
1071}
1072
1073} // namespace sema
1074
1075} // namespace clang
1076
1077#endif // LLVM_CLANG_SEMA_SCOPEINFO_H
1078