1 //===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines FunctionScopeInfo and BlockScopeInfo.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
15 #define LLVM_CLANG_SEMA_SCOPE_INFO_H
17 #include "clang/AST/Type.h"
18 #include "clang/Basic/PartialDiagnostic.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/SmallVector.h"
35 /// \brief Contains information about the compound statement currently being
37 class CompoundScopeInfo {
40 : HasEmptyLoopBodies(false) { }
42 /// \brief Whether this compound stamement contains `for' or `while' loops
43 /// with empty bodies.
44 bool HasEmptyLoopBodies;
46 void setHasEmptyLoopBodies() {
47 HasEmptyLoopBodies = true;
51 class PossiblyUnreachableDiag {
57 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
59 : PD(PD), Loc(Loc), stmt(stmt) {}
62 /// \brief Retains information about a function, method, or block that is
63 /// currently being parsed.
64 class FunctionScopeInfo {
73 /// \brief What kind of scope we are describing.
77 /// \brief Whether this function contains a VLA, \@try, try, C++
78 /// initializer, or anything else that can't be jumped past.
79 bool HasBranchProtectedScope;
81 /// \brief Whether this function contains any switches or direct gotos.
82 bool HasBranchIntoScope;
84 /// \brief Whether this function contains any indirect gotos.
87 /// A flag that is set when parsing a -dealloc method and no [super dealloc]
88 /// call was found yet.
89 bool ObjCShouldCallSuperDealloc;
91 /// A flag that is set when parsing a -finalize method and no [super finalize]
92 /// call was found yet.
93 bool ObjCShouldCallSuperFinalize;
95 /// \brief Used to determine if errors occurred in this function or block.
96 DiagnosticErrorTrap ErrorTrap;
98 /// SwitchStack - This is the current set of active switch statements in the
100 SmallVector<SwitchStmt*, 8> SwitchStack;
102 /// \brief The list of return statements that occur within the function or
103 /// block, if there is any chance of applying the named return value
104 /// optimization, or if we need to infer a return type.
105 SmallVector<ReturnStmt*, 4> Returns;
107 /// \brief The stack of currently active compound stamement scopes in the
109 SmallVector<CompoundScopeInfo, 4> CompoundScopes;
111 /// \brief A list of PartialDiagnostics created but delayed within the
112 /// current function scope. These diagnostics are vetted for reachability
113 /// prior to being emitted.
114 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
116 void setHasBranchIntoScope() {
117 HasBranchIntoScope = true;
120 void setHasBranchProtectedScope() {
121 HasBranchProtectedScope = true;
124 void setHasIndirectGoto() {
125 HasIndirectGoto = true;
128 bool NeedsScopeChecking() const {
129 return HasIndirectGoto ||
130 (HasBranchProtectedScope && HasBranchIntoScope);
133 FunctionScopeInfo(DiagnosticsEngine &Diag)
135 HasBranchProtectedScope(false),
136 HasBranchIntoScope(false),
137 HasIndirectGoto(false),
138 ObjCShouldCallSuperDealloc(false),
139 ObjCShouldCallSuperFinalize(false),
142 virtual ~FunctionScopeInfo();
144 /// \brief Clear out the information in this function scope, making it
145 /// suitable for reuse.
148 static bool classof(const FunctionScopeInfo *FSI) { return true; }
151 class CapturingScopeInfo : public FunctionScopeInfo {
153 enum ImplicitCaptureStyle {
154 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
157 ImplicitCaptureStyle ImpCaptureStyle;
160 // There are two categories of capture: capturing 'this', and capturing
161 // local variables. There are three ways to capture a local variable:
162 // capture by copy in the C++11 sense, capture by reference
163 // in the C++11 sense, and __block capture. Lambdas explicitly specify
164 // capture by copy or capture by reference. For blocks, __block capture
165 // applies to variables with that annotation, variables of reference type
166 // are captured by reference, and other variables are captured by copy.
168 Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
171 // The variable being captured (if we are not capturing 'this'),
172 // and misc bits descibing the capture.
173 llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
175 // Expression to initialize a field of the given type, and whether this
176 // is a nested capture; the expression is only required if we are
177 // capturing ByVal and the variable's type has a non-trivial
179 llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
181 /// \brief The source location at which the first capture occurred..
184 /// \brief The location of the ellipsis that expands a parameter pack.
185 SourceLocation EllipsisLoc;
187 /// \brief The type as it was captured, which is in effect the type of the
188 /// non-static data member that would hold the capture.
189 QualType CaptureType;
192 Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
193 SourceLocation Loc, SourceLocation EllipsisLoc,
194 QualType CaptureType, Expr *Cpy)
195 : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
196 CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
197 CaptureType(CaptureType){}
199 enum IsThisCapture { ThisCapture };
200 Capture(IsThisCapture, bool isNested, SourceLocation Loc,
201 QualType CaptureType, Expr *Cpy)
202 : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
203 EllipsisLoc(), CaptureType(CaptureType) { }
205 bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
206 bool isVariableCapture() const { return !isThisCapture(); }
207 bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
208 bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
209 bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
210 bool isNested() { return CopyExprAndNested.getInt(); }
212 VarDecl *getVariable() const {
213 return VarAndKind.getPointer();
216 /// \brief Retrieve the location at which this variable was captured.
217 SourceLocation getLocation() const { return Loc; }
219 /// \brief Retrieve the source location of the ellipsis, whose presence
220 /// indicates that the capture is a pack expansion.
221 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
223 /// \brief Retrieve the capture type for this capture, which is effectively
224 /// the type of the non-static data member in the lambda/block structure
225 /// that would store this capture.
226 QualType getCaptureType() const { return CaptureType; }
228 Expr *getCopyExpr() const {
229 return CopyExprAndNested.getPointer();
233 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
234 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
235 HasImplicitReturnType(false)
238 /// CaptureMap - A map of captured variables to (index+1) into Captures.
239 llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
241 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
242 /// zero if 'this' is not captured.
243 unsigned CXXThisCaptureIndex;
245 /// Captures - The captures.
246 SmallVector<Capture, 4> Captures;
248 /// \brief - Whether the target type of return statements in this context
249 /// is deduced (e.g. a lambda or block with omitted return type).
250 bool HasImplicitReturnType;
252 /// ReturnType - The target type of return statements in this context,
253 /// or null if unknown.
256 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
257 SourceLocation Loc, SourceLocation EllipsisLoc,
258 QualType CaptureType, Expr *Cpy) {
259 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
260 EllipsisLoc, CaptureType, Cpy));
261 CaptureMap[Var] = Captures.size();
264 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
266 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
268 CXXThisCaptureIndex = Captures.size();
271 /// \brief Determine whether the C++ 'this' is captured.
272 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
274 /// \brief Retrieve the capture of C++ 'this', if it has been captured.
275 Capture &getCXXThisCapture() {
276 assert(isCXXThisCaptured() && "this has not been captured");
277 return Captures[CXXThisCaptureIndex - 1];
280 /// \brief Determine whether the given variable has been captured.
281 bool isCaptured(VarDecl *Var) const {
282 return CaptureMap.count(Var);
285 /// \brief Retrieve the capture of the given variable, if it has been
286 /// captured already.
287 Capture &getCapture(VarDecl *Var) {
288 assert(isCaptured(Var) && "Variable has not been captured");
289 return Captures[CaptureMap[Var] - 1];
292 const Capture &getCapture(VarDecl *Var) const {
293 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
294 = CaptureMap.find(Var);
295 assert(Known != CaptureMap.end() && "Variable has not been captured");
296 return Captures[Known->second - 1];
299 static bool classof(const FunctionScopeInfo *FSI) {
300 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
302 static bool classof(const CapturingScopeInfo *BSI) { return true; }
305 /// \brief Retains information about a block that is currently being parsed.
306 class BlockScopeInfo : public CapturingScopeInfo {
310 /// TheScope - This is the scope for the block itself, which contains
314 /// BlockType - The function type of the block, if one was given.
315 /// Its return type may be BuiltinType::Dependent.
316 QualType FunctionType;
318 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
319 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
325 virtual ~BlockScopeInfo();
327 static bool classof(const FunctionScopeInfo *FSI) {
328 return FSI->Kind == SK_Block;
330 static bool classof(const BlockScopeInfo *BSI) { return true; }
333 class LambdaScopeInfo : public CapturingScopeInfo {
335 /// \brief The class that describes the lambda.
336 CXXRecordDecl *Lambda;
338 /// \brief The class that describes the lambda.
339 CXXMethodDecl *CallOperator;
341 /// \brief Source range covering the lambda introducer [...].
342 SourceRange IntroducerRange;
344 /// \brief The number of captures in the \c Captures list that are
345 /// explicit captures.
346 unsigned NumExplicitCaptures;
348 /// \brief Whether this is a mutable lambda.
351 /// \brief Whether the (empty) parameter list is explicit.
354 /// \brief Whether any of the capture expressions requires cleanups.
355 bool ExprNeedsCleanups;
357 /// \brief Whether the lambda contains an unexpanded parameter pack.
358 bool ContainsUnexpandedParameterPack;
360 /// \brief Variables used to index into by-copy array captures.
361 llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
363 /// \brief Offsets into the ArrayIndexVars array at which each capture starts
364 /// its list of array index variables.
365 llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
367 LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
368 CXXMethodDecl *CallOperator)
369 : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
370 CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
371 ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
376 virtual ~LambdaScopeInfo();
379 void finishedExplicitCaptures() {
380 NumExplicitCaptures = Captures.size();
383 static bool classof(const FunctionScopeInfo *FSI) {
384 return FSI->Kind == SK_Lambda;
386 static bool classof(const LambdaScopeInfo *BSI) { return true; }