15 #ifndef LLVM_CLANG_SEMA_SCOPEINFO_H 16 #define LLVM_CLANG_SEMA_SCOPEINFO_H 24 #include "llvm/ADT/DenseMap.h" 25 #include "llvm/ADT/SmallSet.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/ADT/StringSwitch.h" 37 class ObjCPropertyDecl;
39 class ImplicitParamDecl;
44 class TemplateTypeParmDecl;
45 class TemplateParameterList;
47 class ObjCIvarRefExpr;
48 class ObjCPropertyRefExpr;
49 class ObjCMessageExpr;
65 HasEmptyLoopBodies =
true;
77 : PD(PD), Loc(Loc), stmt(stmt) {}
221 typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
231 static BaseInfoTy getBaseInfo(
const Expr *BaseE);
257 return Base.getInt();
261 return Base == Other.Base && Property == Other.Property;
274 return WeakObjectProfileTy::getSentinel();
278 typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
297 llvm::PointerIntPair<const Expr *, 1, bool> Rep;
306 return Rep == Other.Rep;
335 template <
typename ExprT>
336 inline void recordUseOfWeak(
const ExprT *E,
bool IsRead =
true);
345 void markSafeWeakUse(
const Expr *E);
348 return WeakObjectUses;
352 HasBranchIntoScope =
true;
356 HasBranchProtectedScope =
true;
360 HasIndirectGoto =
true;
364 HasDroppedStmt =
true;
368 HasOMPDeclareReductionCombiner =
true;
372 HasFallthroughStmt =
true;
376 setHasBranchProtectedScope();
377 FirstCXXTryLoc = TryLoc;
381 setHasBranchProtectedScope();
382 FirstSEHTryLoc = TryLoc;
386 return !HasDroppedStmt &&
388 (HasBranchProtectedScope && HasBranchIntoScope));
394 assert(FirstCoroutineStmtLoc.
isInvalid() &&
395 "first coroutine statement location already set");
396 FirstCoroutineStmtLoc = Loc;
397 FirstCoroutineStmtKind = llvm::StringSwitch<unsigned char>(Keyword)
398 .Case(
"co_return", 0)
400 .Case(
"co_yield", 2);
404 assert(FirstCoroutineStmtLoc.
isValid()
405 &&
"no coroutine statement available");
406 switch (FirstCoroutineStmtKind) {
407 case 0:
return "co_return";
408 case 1:
return "co_await";
409 case 2:
return "co_yield";
411 llvm_unreachable(
"FirstCoroutineStmtKind has an invalid value");
416 assert((!value || CoroutineSuspends.first ==
nullptr) &&
417 "we already have valid suspend points");
418 NeedsCoroutineSuspends = value;
422 return !NeedsCoroutineSuspends && CoroutineSuspends.first ==
nullptr;
426 assert(Initial && Final &&
"suspend points cannot be null");
427 assert(CoroutineSuspends.first ==
nullptr &&
"suspend points already set");
428 NeedsCoroutineSuspends =
false;
429 CoroutineSuspends.first = Initial;
430 CoroutineSuspends.second = Final;
435 HasBranchProtectedScope(
false),
436 HasBranchIntoScope(
false),
437 HasIndirectGoto(
false),
438 HasDroppedStmt(
false),
439 HasOMPDeclareReductionCombiner(
false),
440 HasFallthroughStmt(
false),
441 HasPotentialAvailabilityViolations(
false),
442 ObjCShouldCallSuper(
false),
443 ObjCIsDesignatedInit(
false),
444 ObjCWarnForNoDesignatedInitChain(
false),
445 ObjCIsSecondaryInit(
false),
446 ObjCWarnForNoInitDelegation(
false),
447 NeedsCoroutineSuspends(
true),
463 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
464 ImpCap_CapturedRegion
484 Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
487 IsNestedCapture = 0x1,
492 llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
497 llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
521 : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0),
522 InitExprAndCaptureKind(
523 Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
525 Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType),
531 : VarAndNestedAndThis(
532 nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
533 InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
534 Loc(Loc), EllipsisLoc(), CaptureType(CaptureType), ODRUsed(
false),
538 return VarAndNestedAndThis.getInt() & IsThisCaptured;
541 return !isThisCapture() && !isVLATypeCapture();
544 return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
547 return InitExprAndCaptureKind.getInt() == Cap_ByRef;
550 return InitExprAndCaptureKind.getInt() == Cap_Block;
553 return InitExprAndCaptureKind.getInt() == Cap_VLA;
556 return VarAndNestedAndThis.getInt() & IsNestedCapture;
560 void markUsed(
bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) =
true; }
563 assert(isVariableCapture());
564 return VarAndNestedAndThis.getPointer();
578 assert(!isThisCapture());
583 assert(!isVLATypeCapture() &&
"no init expression for type capture");
584 return static_cast<Expr *
>(InitExprAndCaptureKind.getPointer());
590 HasImplicitReturnType(
false)
614 Captures.push_back(
Capture(Var, isBlock, isByref, isNested, Loc,
615 EllipsisLoc, CaptureType, Cpy));
616 CaptureMap[Var] = Captures.size();
620 Captures.push_back(
Capture(
nullptr,
false,
630 Expr *Cpy,
bool ByCopy);
637 assert(isCXXThisCaptured() &&
"this has not been captured");
638 return Captures[CXXThisCaptureIndex - 1];
643 return CaptureMap.count(Var);
652 assert(isCaptured(Var) &&
"Variable has not been captured");
653 return Captures[CaptureMap[Var] - 1];
657 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
658 = CaptureMap.find(Var);
659 assert(Known != CaptureMap.end() &&
"Variable has not been captured");
660 return Captures[Known->second - 1];
664 return FSI->
Kind == SK_Block || FSI->
Kind == SK_Lambda
665 || FSI->
Kind == SK_CapturedRegion;
692 return FSI->
Kind == SK_Block;
715 TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
716 ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel)
718 Kind = SK_CapturedRegion;
725 switch (CapRegionKind) {
727 return "default captured statement";
729 return "OpenMP region";
731 llvm_unreachable(
"Invalid captured region kind!");
735 return FSI->
Kind == SK_CapturedRegion;
821 CallOperator(nullptr), NumExplicitCaptures(0), Mutable(
false),
822 ExplicitParams(
false), Cleanup{},
823 ContainsUnexpandedParameterPack(
false), AutoTemplateParameterDepth(0),
824 GLTemplateParameterList(
nullptr) {
830 NumExplicitCaptures = Captures.size();
834 return FSI->
Kind == SK_Lambda;
840 return !AutoTemplateParams.empty() || GLTemplateParameterList;
862 assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr));
863 PotentiallyCapturingExprs.push_back(VarExpr);
867 PotentialThisCaptureLocation = Loc;
870 return PotentialThisCaptureLocation.
isValid();
914 assert(isa<DeclRefExpr>(CapturingVarExpr)
915 || isa<MemberExpr>(CapturingVarExpr));
916 NonODRUsedCapturingExprs.insert(CapturingVarExpr);
919 assert(isa<DeclRefExpr>(CapturingVarExpr)
920 || isa<MemberExpr>(CapturingVarExpr));
921 return NonODRUsedCapturingExprs.count(CapturingVarExpr);
924 PotentiallyCapturingExprs.erase(
925 std::remove(PotentiallyCapturingExprs.begin(),
926 PotentiallyCapturingExprs.end(), E),
927 PotentiallyCapturingExprs.end());
930 PotentiallyCapturingExprs.clear();
934 return PotentiallyCapturingExprs.size();
938 return getNumPotentialVariableCaptures() ||
939 PotentialThisCaptureLocation.
isValid();
944 void getPotentialVariableCapture(
unsigned Idx,
VarDecl *&VD,
Expr *&E)
const;
947 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
951 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
953 Result.Base.setInt(
true);
957 template <
typename ExprT>
968 Captures.push_back(
Capture(Capture::ThisCapture, isNested, Loc,
QualType(),
970 CXXThisCaptureIndex = Captures.size();
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
QualType getCaptureType() const
Retrieve the capture type for this capture, which is effectively the type of the non-static data memb...
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.
void markUsed(bool IsODRUse)
A (possibly-)qualified type.
void addThisCapture(bool isNested, SourceLocation Loc, Expr *Cpy, bool ByCopy)
bool ExplicitParams
Whether the (empty) parameter list is explicit.
const NamedDecl * getProperty() const
bool HasFallthroughStmt
Whether there is a fallthrough statement in this function.
TemplateParameterList * GLTemplateParameterList
If this is a generic lambda, and the template parameter list has been created (from the AutoTemplateP...
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
bool hasPotentialCaptures() const
bool isBlockCapture() const
bool operator==(const WeakUseTy &Other) const
const WeakObjectUseMap & getWeakObjectUses() const
static WeakObjectProfileTy getTombstoneKey()
StringRef getFirstCoroutineStmtKeyword() const
static unsigned getHashValue(const WeakObjectProfileTy &Val)
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const
bool isNonODRUsed() const
std::pair< Stmt *, Stmt * > CoroutineSuspends
The initial and final coroutine suspend points.
static bool classof(const FunctionScopeInfo *FSI)
Retains information about a function, method, or block that is currently being parsed.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
static bool classof(const FunctionScopeInfo *FSI)
bool hasPotentialThisCapture() const
SmallVector< SwitchStmt *, 8 > SwitchStack
SwitchStack - This is the current set of active switch statements in the block.
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
bool NeedsCoroutineSuspends
True only when this function has not already built, or attempted to build, the initial and final coro...
void setHasBranchProtectedScope()
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
bool HasDroppedStmt
Whether a statement was dropped because it was invalid.
RecordDecl - Represents a struct/union/class.
unsigned char FirstCoroutineStmtKind
An enumeration represeting the kind of the first coroutine statement in the function.
VarDecl * getVariable() const
SourceLocation getEllipsisLoc() const
Retrieve the source location of the ellipsis, whose presence indicates that the capture is a pack exp...
void setHasIndirectGoto()
void setHasOMPDeclareReductionCombiner()
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...
bool ContainsUnexpandedParameterPack
Whether the lambda contains an unexpanded parameter pack.
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.
WeakUseTy(const Expr *Use, bool IsRead)
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.
static WeakObjectProfileTy getEmptyKey()
Scope - A scope is a transient data structure that is used while parsing the program.
FunctionScopeInfo(DiagnosticsEngine &Diag)
This represents the body of a CapturedStmt, and serves as its DeclContext.
PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, const Stmt *stmt)
SmallVector< TemplateTypeParmDecl *, 4 > AutoTemplateParams
Store the list of the auto parameters for a generic lambda.
SmallVector< WeakUseTy, 4 > WeakUseVector
Used to collect uses of a particular weak object in a function body.
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.
bool Mutable
Whether this is a mutable lambda.
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 PotentialThisCaptureLocation
unsigned NumExplicitCaptures
The number of captures in the Captures list that are explicit captures.
CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, RecordDecl *RD, ImplicitParamDecl *Context, CapturedRegionKind K, unsigned OpenMPLevel)
Retains information about a block that is currently being parsed.
CXXMethodDecl * CallOperator
The lambda's compiler-generated operator().
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
Expr - This represents one expression.
void removePotentialCapture(Expr *E)
bool HasBranchProtectedScope
Whether this function contains a VLA, @try, try, C++ initializer, or anything else that can't be jump...
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)
unsigned short CapRegionKind
The kind of captured region.
llvm::SmallPtrSet< const ParmVarDecl *, 8 > ModifiedNonNullParams
A list of parameters which have the nonnull attribute and are modified in the function.
bool isVariableCapture() const
CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
void setHasSEHTry(SourceLocation TryLoc)
bool HasPotentialAvailabilityViolations
Whether we make reference to a declaration that could be unavailable.
SourceLocation getLocation() const
Retrieve the location at which this variable was captured.
Encodes a location in the source.
CXXRecordDecl * Lambda
The class that describes the lambda.
bool isThisCapture() const
bool ObjCWarnForNoDesignatedInitChain
This starts true for a method marked as designated initializer and will be set to false if there is a...
bool isReferenceCapture() const
Represents a static or instance method of a struct/union/class.
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.
bool isGenericLambda() const
Is this scope known to be for a generic lambda? (This will be false until we parse the first 'auto'-t...
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool ObjCIsSecondaryInit
True when this is an initializer method not marked as a designated initializer within a class that ha...
llvm::SmallDenseMap< WeakObjectProfileTy, WeakUseVector, 8, WeakObjectProfileTy::DenseMapInfo > WeakObjectUseMap
Used to collect all uses of weak objects in a function body.
bool HasIndirectGoto
Whether this function contains any indirect gotos.
const Capture & getCapture(VarDecl *Var) const
unsigned CXXThisCaptureIndex
CXXThisCaptureIndex - The (index+1) of the capture of 'this'; zero if 'this' is not captured...
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 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)
Capture(IsThisCapture, bool IsNested, SourceLocation Loc, QualType CaptureType, Expr *Cpy, const bool ByCopy)
unsigned AutoTemplateParameterDepth
If this is a generic lambda, use this as the depth of each 'auto' parameter, during initial AST const...
SmallVector< PossiblyUnreachableDiag, 4 > PossiblyUnreachableDiags
A list of PartialDiagnostics created but delayed within the current function scope.
Represents a C++ struct/union/class.
bool isCopyCapture() const
void setHasEmptyLoopBodies()
static bool classof(const FunctionScopeInfo *FSI)
bool isCXXThisCaptured() const
Determine whether the C++ 'this' is captured.
Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, Expr *Cpy)
void addVLATypeCapture(SourceLocation Loc, QualType CaptureType)
Represents a single use of a weak object.
Scope * TheScope
TheScope - This is the scope for the block itself, which contains arguments etc.
bool HasImplicitReturnType
Whether the target type of return statements in this context is deduced (e.g.
A reference to a declared variable, function, enum, etc.
CapturedRegionKind
The different kinds of captured statement.
void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, Expr *Cpy)
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.
Expr * getInitExpr() const
NamedDecl - This represents a decl with a name.
Represents a C array with a specified size that is not an integer-constant-expression.
bool isVLATypeCapture() const
bool HasBranchIntoScope
Whether this function contains any switches or direct gotos.
void setHasFallthroughStmt()
void setCoroutineSuspends(Stmt *Initial, Stmt *Final)