14 #ifndef LLVM_CLANG_SEMA_SCOPEINFO_H 15 #define LLVM_CLANG_SEMA_SCOPEINFO_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" 48 class ImplicitParamDecl;
50 class ObjCIvarRefExpr;
51 class ObjCMessageExpr;
52 class ObjCPropertyDecl;
53 class ObjCPropertyRefExpr;
60 class TemplateParameterList;
61 class TemplateTypeParmDecl;
81 HasEmptyLoopBodies =
true;
89 llvm::TinyPtrVector<const Stmt*>
Stmts;
93 : PD(PD), Loc(Loc), Stmts(Stmts) {}
182 using SwitchInfo = llvm::PointerIntPair<SwitchStmt*, 1, bool>;
208 llvm::SmallPtrSet<const BlockDecl *, 1>
Blocks;
252 using BaseInfoTy = llvm::PointerIntPair<const NamedDecl *, 1, bool>;
262 static BaseInfoTy getBaseInfo(
const Expr *BaseE);
288 return Base.getInt();
292 return Base == Other.Base && Property == Other.Property;
306 return WeakObjectProfileTy::getSentinel();
310 using Pair = std::pair<BaseInfoTy, const NamedDecl *>;
330 llvm::PointerIntPair<const Expr *, 1, bool> Rep;
340 return Rep == Other.Rep;
367 :
Kind(SK_Function), HasBranchProtectedScope(
false),
368 HasBranchIntoScope(
false), HasIndirectGoto(
false),
369 HasDroppedStmt(
false), HasOMPDeclareReductionCombiner(
false),
370 HasFallthroughStmt(
false), HasPotentialAvailabilityViolations(
false),
371 ObjCShouldCallSuper(
false), ObjCIsDesignatedInit(
false),
372 ObjCWarnForNoDesignatedInitChain(
false), ObjCIsSecondaryInit(
false),
373 ObjCWarnForNoInitDelegation(
false), NeedsCoroutineSuspends(
true),
381 template <
typename ExprT>
382 inline void recordUseOfWeak(
const ExprT *E,
bool IsRead =
true);
391 void markSafeWeakUse(
const Expr *E);
394 return WeakObjectUses;
398 HasBranchIntoScope =
true;
402 HasBranchProtectedScope =
true;
406 HasIndirectGoto =
true;
410 HasDroppedStmt =
true;
414 HasOMPDeclareReductionCombiner =
true;
418 HasFallthroughStmt =
true;
422 setHasBranchProtectedScope();
423 FirstCXXTryLoc = TryLoc;
427 setHasBranchProtectedScope();
428 FirstSEHTryLoc = TryLoc;
432 return !HasDroppedStmt &&
434 (HasBranchProtectedScope && HasBranchIntoScope));
444 ByrefBlockVars.push_back(VD);
450 assert(FirstCoroutineStmtLoc.
isInvalid() &&
451 "first coroutine statement location already set");
452 FirstCoroutineStmtLoc = Loc;
453 FirstCoroutineStmtKind = llvm::StringSwitch<unsigned char>(Keyword)
454 .Case(
"co_return", 0)
456 .Case(
"co_yield", 2);
460 assert(FirstCoroutineStmtLoc.
isValid()
461 &&
"no coroutine statement available");
462 switch (FirstCoroutineStmtKind) {
463 case 0:
return "co_return";
464 case 1:
return "co_await";
465 case 2:
return "co_yield";
467 llvm_unreachable(
"FirstCoroutineStmtKind has an invalid value");
472 assert((!value || CoroutineSuspends.first ==
nullptr) &&
473 "we already have valid suspend points");
474 NeedsCoroutineSuspends = value;
478 return !NeedsCoroutineSuspends && CoroutineSuspends.first ==
nullptr;
482 assert(Initial && Final &&
"suspend points cannot be null");
483 assert(CoroutineSuspends.first ==
nullptr &&
"suspend points already set");
484 NeedsCoroutineSuspends =
false;
485 CoroutineSuspends.first = Initial;
486 CoroutineSuspends.second = Final;
511 Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
540 unsigned CapturesThis : 1;
544 unsigned ODRUsed : 1;
548 unsigned NonODRUsed : 1;
552 unsigned Invalid : 1;
558 : CapturedVar(Var), Loc(Loc), EllipsisLoc(EllipsisLoc),
559 CaptureType(CaptureType),
560 Kind(Block ? Cap_Block : ByRef ? Cap_ByRef : Cap_ByCopy),
561 Nested(IsNested), CapturesThis(
false), ODRUsed(
false),
562 NonODRUsed(
false), Invalid(Invalid) {}
566 QualType CaptureType,
const bool ByCopy,
bool Invalid)
567 : Loc(Loc), CaptureType(CaptureType),
568 Kind(ByCopy ? Cap_ByCopy : Cap_ByRef), Nested(IsNested),
575 : CapturedVLA(VLA), Loc(Loc), CaptureType(CaptureType),
Kind(Cap_VLA),
576 Nested(IsNested), CapturesThis(
false), ODRUsed(
false),
581 return !isThisCapture() && !isVLATypeCapture();
594 bool isInitCapture()
const;
606 assert(isVariableCapture());
611 assert(isVLATypeCapture());
634 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
635 ImpCap_CapturedRegion
648 unsigned CXXThisCaptureIndex = 0;
655 bool HasImplicitReturnType =
false;
663 QualType CaptureType,
bool Invalid) {
664 Captures.push_back(
Capture(Var, isBlock, isByref, isNested, Loc,
665 EllipsisLoc, CaptureType, Invalid));
666 CaptureMap[Var] = Captures.size();
672 false, Loc, CaptureType));
683 assert(isCXXThisCaptured() &&
"this has not been captured");
684 return Captures[CXXThisCaptureIndex - 1];
689 return CaptureMap.count(Var);
698 assert(isCaptured(Var) &&
"Variable has not been captured");
699 return Captures[CaptureMap[Var] - 1];
703 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
704 = CaptureMap.find(Var);
705 assert(Known != CaptureMap.end() &&
"Variable has not been captured");
706 return Captures[Known->second - 1];
710 return FSI->
Kind == SK_Block || FSI->
Kind == SK_Lambda
711 || FSI->
Kind == SK_CapturedRegion;
730 TheScope(BlockScope) {
737 return FSI->
Kind == SK_Block;
765 unsigned OpenMPCaptureLevel)
767 TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
768 ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel),
769 OpenMPCaptureLevel(OpenMPCaptureLevel) {
770 Kind = SK_CapturedRegion;
777 switch (CapRegionKind) {
779 return "default captured statement";
781 return "Objective-C @finally statement";
783 return "OpenMP region";
785 llvm_unreachable(
"Invalid captured region kind!");
789 return FSI->
Kind == SK_CapturedRegion;
811 unsigned NumExplicitCaptures = 0;
814 bool Mutable =
false;
817 bool ExplicitParams =
false;
823 bool ContainsUnexpandedParameterPack =
false;
878 NumExplicitCaptures = Captures.size();
882 return FSI->
Kind == SK_Lambda;
888 return !TemplateParams.empty() || GLTemplateParameterList;
909 assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr) ||
910 isa<FunctionParmPackExpr>(VarExpr));
911 PotentiallyCapturingExprs.push_back(VarExpr);
915 PotentialThisCaptureLocation = Loc;
919 return PotentialThisCaptureLocation.
isValid();
962 assert(isa<DeclRefExpr>(CapturingVarExpr) ||
963 isa<MemberExpr>(CapturingVarExpr) ||
964 isa<FunctionParmPackExpr>(CapturingVarExpr));
965 NonODRUsedCapturingExprs.insert(CapturingVarExpr);
968 assert(isa<DeclRefExpr>(CapturingVarExpr) ||
969 isa<MemberExpr>(CapturingVarExpr) ||
970 isa<FunctionParmPackExpr>(CapturingVarExpr));
971 return NonODRUsedCapturingExprs.count(CapturingVarExpr);
974 PotentiallyCapturingExprs.erase(
976 PotentiallyCapturingExprs.end(), E),
977 PotentiallyCapturingExprs.end());
980 PotentiallyCapturingExprs.clear();
984 return PotentiallyCapturingExprs.size();
988 return getNumPotentialVariableCaptures() ||
989 PotentialThisCaptureLocation.
isValid();
992 void visitPotentialCaptures(
993 llvm::function_ref<
void(
VarDecl *,
Expr *)> Callback)
const;
996 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
997 :
Base(
nullptr,
false) {}
1000 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
1002 Result.Base.setInt(
true);
1006 template <
typename ExprT>
1019 CXXThisCaptureIndex = Captures.size();
1026 #endif // LLVM_CLANG_SEMA_SCOPEINFO_H ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
void clearPotentialCaptures()
SourceRange IntroducerRange
Source range covering the lambda introducer [...].
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
A (possibly-)qualified type.
const NamedDecl * getProperty() const
bool HasFallthroughStmt
Whether there is a fallthrough statement in this function.
bool HasEmptyLoopBodies
Whether this compound stamement contains `for' or `while' loops with empty bodies.
void setNeedsCoroutineSuspends(bool value=true)
Stmt - This represents one statement.
QualType ReturnType
ReturnType - The target type of return statements in this context, or null if unknown.
C Language Family Type Representation.
bool NeedsScopeChecking() const
QualType getCaptureType() const
Retrieve the capture type for this capture, which is effectively the type of the non-static data memb...
bool hasPotentialCaptures() const
bool operator==(const WeakUseTy &Other) const
bool isCopyCapture() const
const WeakObjectUseMap & getWeakObjectUses() const
static WeakObjectProfileTy getTombstoneKey()
StringRef getFirstCoroutineStmtKeyword() const
static unsigned getHashValue(const WeakObjectProfileTy &Val)
bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const
std::pair< Stmt *, Stmt * > CoroutineSuspends
The initial and final coroutine suspend points.
llvm::TinyPtrVector< const Stmt * > Stmts
static bool classof(const FunctionScopeInfo *FSI)
Retains information about a function, method, or block that is currently being parsed.
Represents a variable declaration or definition.
static bool classof(const FunctionScopeInfo *FSI)
bool hasPotentialThisCapture() const
static bool classof(const FunctionScopeInfo *FSI)
RAII class that determines when any errors have occurred between the time the instance was created an...
Stores a list of template parameters for a TemplateDecl and its derived classes.
llvm::SmallVector< ShadowedOuterDecl, 4 > ShadowingDecls
llvm::PointerIntPair< SwitchStmt *, 1, bool > SwitchInfo
A SwitchStmt, along with a flag indicating if its list of case statements is incomplete (because we d...
bool NeedsCoroutineSuspends
True only when this function has not already built, or attempted to build, the initial and final coro...
Defines the clang::Expr interface and subclasses for C++ expressions.
void setHasBranchProtectedScope()
void addVLATypeCapture(SourceLocation Loc, const VariableArrayType *VLAType, QualType CaptureType)
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
bool HasDroppedStmt
Whether a statement was dropped because it was invalid.
llvm::SmallMapVector< ParmVarDecl *, Stmt *, 4 > CoroutineParameterMoves
A mapping between the coroutine function parameters that were moved to the coroutine frame...
Represents a struct/union/class.
unsigned char FirstCoroutineStmtKind
An enumeration represeting the kind of the first coroutine statement in the function.
void setHasIndirectGoto()
void setHasOMPDeclareReductionCombiner()
void addByrefBlockVar(VarDecl *VD)
ScopeKind Kind
What kind of scope we are describing.
Scope * TheScope
This is the enclosing scope of the captured region.
llvm::SmallSet< Expr *, 8 > NonODRUsedCapturingExprs
Contains all variable-referring-expressions that refer to local variables that are usable as constant...
llvm::SmallPtrSet< const BlockDecl *, 1 > Blocks
The set of blocks that are introduced in this function.
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
void setHasBranchIntoScope()
bool operator==(const WeakObjectProfileTy &Other) const
DiagnosticErrorTrap ErrorTrap
Used to determine if errors occurred in this function or block.
bool isThisCapture() const
CompoundScopeInfo(bool IsStmtExpr)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
WeakUseTy(const Expr *Use, bool IsRead)
const VariableArrayType * getCapturedVLAType() const
Concrete class used by the front-end to report problems and issues.
QualType FunctionType
BlockType - The function type of the block, if one was given.
void finishedExplicitCaptures()
Note when all explicit captures have been added.
bool IsStmtExpr
Whether this compound statement corresponds to a GNU statement expression.
static WeakObjectProfileTy getEmptyKey()
Scope - A scope is a transient data structure that is used while parsing the program.
FunctionScopeInfo(DiagnosticsEngine &Diag)
Represents the body of a CapturedStmt, and serves as its DeclContext.
Contains information about the compound statement currently being parsed.
SourceLocation FirstCXXTryLoc
First C++ 'try' statement in the current function.
CleanupInfo Cleanup
Whether any of the capture expressions requires cleanups.
ImplicitCaptureStyle ImpCaptureStyle
void addPotentialCapture(Expr *VarExpr)
Add a variable that might potentially be captured by the lambda and therefore the enclosing lambdas...
void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr)
Mark a variable's reference in a lambda as non-odr using.
SmallVector< ReturnStmt *, 4 > Returns
The list of return statements that occur within the function or block, if there is any chance of appl...
Retains information about a captured region.
void recordUseOfWeak(const ExprT *E, bool IsRead=true)
Record that a weak object was accessed.
SourceLocation getEllipsisLoc() const
Retrieve the source location of the ellipsis, whose presence indicates that the capture is a pack exp...
SourceLocation PotentialThisCaptureLocation
bool isVariableCapture() const
Retains information about a block that is currently being parsed.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
This represents one expression.
void removePotentialCapture(Expr *E)
This file defines the classes used to store parsed information about declaration-specifiers and decla...
SmallVector< SwitchInfo, 8 > SwitchStack
SwitchStack - This is the current set of active switch statements in the block.
bool HasBranchProtectedScope
Whether this function contains a VLA, @try, try, C++ initializer, or anything else that can't be jump...
llvm::DenseMap< unsigned, SourceRange > ExplicitCaptureRanges
A map of explicit capture indices to their introducer source ranges.
bool isCaptured(VarDecl *Var) const
Determine whether the given variable has been captured.
const Expr * getUseExpr() const
Capture & getCapture(VarDecl *Var)
Retrieve the capture of the given variable, if it has been captured already.
An expression that sends a message to the given Objective-C object or class.
void setHasCXXTry(SourceLocation TryLoc)
const VariableArrayType * CapturedVLA
If Kind == Cap_VLA, the captured type.
unsigned short CapRegionKind
The kind of captured region.
SourceLocation getLocation() const
Retrieve the location at which this variable was captured.
CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
VarDecl * getVariable() const
void setHasSEHTry(SourceLocation TryLoc)
bool HasPotentialAvailabilityViolations
Whether we make reference to a declaration that could be unavailable.
Encodes a location in the source.
Capture(IsThisCapture, bool IsNested, SourceLocation Loc, QualType CaptureType, const bool ByCopy, bool Invalid)
SourceRange ExplicitTemplateParamsRange
Source range covering the explicit template parameter list (if it exists).
bool ObjCWarnForNoDesignatedInitChain
This starts true for a method marked as designated initializer and will be set to false if there is a...
Represents a static or instance method of a struct/union/class.
SmallVector< NamedDecl *, 4 > LocalPacks
Packs introduced by this lambda, if any.
bool isVLATypeCapture() const
SmallVector< Capture, 4 > Captures
Captures - The captures.
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
Represents one property declaration in an Objective-C interface.
void addPotentialThisCapture(SourceLocation Loc)
bool ObjCIsDesignatedInit
True when this is a method marked as a designated initializer.
bool ObjCShouldCallSuper
A flag that is set when parsing a method that must call super's implementation, such as -dealloc...
SourceLocation CaptureDefaultLoc
Source location of the '&' or '=' specifying the default capture type, if any.
const VarDecl * ShadowedDecl
bool HasOMPDeclareReductionCombiner
True if current scope is for OpenMP declare reduction combiner.
llvm::SmallVector< Expr *, 4 > PotentiallyCapturingExprs
Contains all variable-referring-expressions (i.e.
Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, bool Invalid)
bool isGenericLambda() const
Is this scope known to be for a generic lambda? (This will be false until we parse a template paramet...
Dataflow Directional Tag Classes.
PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, ArrayRef< const Stmt *> Stmts)
bool isValid() const
Return true if this is a valid SourceLocation object.
CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, RecordDecl *RD, ImplicitParamDecl *Context, CapturedRegionKind K, unsigned OpenMPLevel, unsigned OpenMPCaptureLevel)
bool ObjCIsSecondaryInit
True when this is an initializer method not marked as a designated initializer within a class that ha...
bool HasIndirectGoto
Whether this function contains any indirect gotos.
const Capture & getCapture(VarDecl *Var) const
StringRef getRegionName() const
A descriptive name for the kind of captured region this is.
Represents a simple identification of a weak object.
bool ObjCWarnForNoInitDelegation
This starts true for a secondary initializer method and will be set to false if there is an invocatio...
const NamedDecl * getBase() const
BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
unsigned short OpenMPLevel
LambdaScopeInfo(DiagnosticsEngine &Diag)
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
Contains all of the variables defined in this lambda that shadow variables that were defined in paren...
RecordDecl * TheRecordDecl
The captured record type.
void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, bool ByCopy)
bool isReferenceCapture() const
void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword)
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
llvm::DenseMap< VarDecl *, unsigned > CaptureMap
CaptureMap - A map of captured variables to (index+1) into Captures.
unsigned getNumPotentialVariableCaptures() const
Capture & getCXXThisCapture()
Retrieve the capture of C++ 'this', if it has been captured.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
static bool isEqual(const WeakObjectProfileTy &LHS, const WeakObjectProfileTy &RHS)
VarDecl * CapturedVar
Otherwise, the captured variable (if any).
Capture(IsVLACapture, const VariableArrayType *VLA, bool IsNested, SourceLocation Loc, QualType CaptureType)
Defines the clang::SourceLocation class and associated facilities.
void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, bool Invalid)
SmallVector< PossiblyUnreachableDiag, 4 > PossiblyUnreachableDiags
A list of PartialDiagnostics created but delayed within the current function scope.
Represents a C++ struct/union/class.
void markUsed(bool IsODRUse)
void setHasEmptyLoopBodies()
static bool classof(const FunctionScopeInfo *FSI)
llvm::SmallPtrSet< const ParmVarDecl *, 8 > ModifiedNonNullParams
A list of parameters which have the nonnull attribute and are modified in the function.
bool isCXXThisCaptured() const
Determine whether the C++ 'this' is captured.
Represents a single use of a weak object.
Scope * TheScope
TheScope - This is the scope for the block itself, which contains arguments etc.
void addBlock(const BlockDecl *BD)
llvm::SmallDenseMap< WeakObjectProfileTy, WeakUseVector, 8, WeakObjectProfileTy::DenseMapInfo > WeakObjectUseMap
Used to collect all uses of weak objects in a function body.
A reference to a declared variable, function, enum, etc.
CapturedRegionKind
The different kinds of captured statement.
bool isNonODRUsed() const
bool hasInvalidCoroutineSuspends() const
ImplicitParamDecl * ContextParam
The implicit parameter for the captured variables.
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
bool isExactProfile() const
Returns true if the object base specifies a known object in memory, rather than, say, an instance variable or property of another object.
A trivial tuple used to represent a source range.
llvm::TinyPtrVector< VarDecl * > ByrefBlockVars
The set of __block variables that are introduced in this function.
This represents a decl that may have a name.
Represents a C array with a specified size that is not an integer-constant-expression.
unsigned short OpenMPCaptureLevel
bool HasBranchIntoScope
Whether this function contains any switches or direct gotos.
bool isPlainFunction() const
void setHasFallthroughStmt()
bool isBlockCapture() const
void setCoroutineSuspends(Stmt *Initial, Stmt *Final)