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 /// \brief Used to determine if errors occurred in this function or block.
88 DiagnosticErrorTrap ErrorTrap;
90 /// SwitchStack - This is the current set of active switch statements in the
92 SmallVector<SwitchStmt*, 8> SwitchStack;
94 /// \brief The list of return statements that occur within the function or
95 /// block, if there is any chance of applying the named return value
97 SmallVector<ReturnStmt*, 4> Returns;
99 /// \brief The stack of currently active compound stamement scopes in the
101 SmallVector<CompoundScopeInfo, 4> CompoundScopes;
103 /// \brief A list of PartialDiagnostics created but delayed within the
104 /// current function scope. These diagnostics are vetted for reachability
105 /// prior to being emitted.
106 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
108 void setHasBranchIntoScope() {
109 HasBranchIntoScope = true;
112 void setHasBranchProtectedScope() {
113 HasBranchProtectedScope = true;
116 void setHasIndirectGoto() {
117 HasIndirectGoto = true;
120 bool NeedsScopeChecking() const {
121 return HasIndirectGoto ||
122 (HasBranchProtectedScope && HasBranchIntoScope);
125 FunctionScopeInfo(DiagnosticsEngine &Diag)
127 HasBranchProtectedScope(false),
128 HasBranchIntoScope(false),
129 HasIndirectGoto(false),
132 virtual ~FunctionScopeInfo();
134 /// \brief Clear out the information in this function scope, making it
135 /// suitable for reuse.
138 static bool classof(const FunctionScopeInfo *FSI) { return true; }
141 class CapturingScopeInfo : public FunctionScopeInfo {
143 enum ImplicitCaptureStyle {
144 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
147 ImplicitCaptureStyle ImpCaptureStyle;
150 // There are two categories of capture: capturing 'this', and capturing
151 // local variables. There are three ways to capture a local variable:
152 // capture by copy in the C++11 sense, capture by reference
153 // in the C++11 sense, and __block capture. Lambdas explicitly specify
154 // capture by copy or capture by reference. For blocks, __block capture
155 // applies to variables with that annotation, variables of reference type
156 // are captured by reference, and other variables are captured by copy.
158 Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
161 // The variable being captured (if we are not capturing 'this'),
162 // and misc bits descibing the capture.
163 llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
165 // Expression to initialize a field of the given type, and whether this
166 // is a nested capture; the expression is only required if we are
167 // capturing ByVal and the variable's type has a non-trivial
169 llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
171 /// \brief The source location at which the first capture occurred..
174 /// \brief The location of the ellipsis that expands a parameter pack.
175 SourceLocation EllipsisLoc;
177 /// \brief The type as it was captured, which is in effect the type of the
178 /// non-static data member that would hold the capture.
179 QualType CaptureType;
182 Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
183 SourceLocation Loc, SourceLocation EllipsisLoc,
184 QualType CaptureType, Expr *Cpy)
185 : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
186 CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
187 CaptureType(CaptureType){}
189 enum IsThisCapture { ThisCapture };
190 Capture(IsThisCapture, bool isNested, SourceLocation Loc,
191 QualType CaptureType, Expr *Cpy)
192 : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
193 EllipsisLoc(), CaptureType(CaptureType) { }
195 bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
196 bool isVariableCapture() const { return !isThisCapture(); }
197 bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
198 bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
199 bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
200 bool isNested() { return CopyExprAndNested.getInt(); }
202 VarDecl *getVariable() const {
203 return VarAndKind.getPointer();
206 /// \brief Retrieve the location at which this variable was captured.
207 SourceLocation getLocation() const { return Loc; }
209 /// \brief Retrieve the source location of the ellipsis, whose presence
210 /// indicates that the capture is a pack expansion.
211 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
213 /// \brief Retrieve the capture type for this capture, which is effectively
214 /// the type of the non-static data member in the lambda/block structure
215 /// that would store this capture.
216 QualType getCaptureType() const { return CaptureType; }
218 Expr *getCopyExpr() const {
219 return CopyExprAndNested.getPointer();
223 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
224 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
225 HasImplicitReturnType(false)
228 /// CaptureMap - A map of captured variables to (index+1) into Captures.
229 llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
231 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
232 /// zero if 'this' is not captured.
233 unsigned CXXThisCaptureIndex;
235 /// Captures - The captures.
236 SmallVector<Capture, 4> Captures;
238 /// \brief - Whether the target type of return statements in this context
239 /// is deduced (e.g. a lambda or block with omitted return type).
240 bool HasImplicitReturnType;
242 /// ReturnType - The target type of return statements in this context,
243 /// or null if unknown.
246 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
247 SourceLocation Loc, SourceLocation EllipsisLoc,
248 QualType CaptureType, Expr *Cpy) {
249 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
250 EllipsisLoc, CaptureType, Cpy));
251 CaptureMap[Var] = Captures.size();
254 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
256 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
258 CXXThisCaptureIndex = Captures.size();
261 /// \brief Determine whether the C++ 'this' is captured.
262 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
264 /// \brief Retrieve the capture of C++ 'this', if it has been captured.
265 Capture &getCXXThisCapture() {
266 assert(isCXXThisCaptured() && "this has not been captured");
267 return Captures[CXXThisCaptureIndex - 1];
270 /// \brief Determine whether the given variable has been captured.
271 bool isCaptured(VarDecl *Var) const {
272 return CaptureMap.count(Var);
275 /// \brief Retrieve the capture of the given variable, if it has been
276 /// captured already.
277 Capture &getCapture(VarDecl *Var) {
278 assert(isCaptured(Var) && "Variable has not been captured");
279 return Captures[CaptureMap[Var] - 1];
282 const Capture &getCapture(VarDecl *Var) const {
283 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
284 = CaptureMap.find(Var);
285 assert(Known != CaptureMap.end() && "Variable has not been captured");
286 return Captures[Known->second - 1];
289 static bool classof(const FunctionScopeInfo *FSI) {
290 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
292 static bool classof(const CapturingScopeInfo *BSI) { return true; }
295 /// \brief Retains information about a block that is currently being parsed.
296 class BlockScopeInfo : public CapturingScopeInfo {
300 /// TheScope - This is the scope for the block itself, which contains
304 /// BlockType - The function type of the block, if one was given.
305 /// Its return type may be BuiltinType::Dependent.
306 QualType FunctionType;
308 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
309 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
315 virtual ~BlockScopeInfo();
317 static bool classof(const FunctionScopeInfo *FSI) {
318 return FSI->Kind == SK_Block;
320 static bool classof(const BlockScopeInfo *BSI) { return true; }
323 class LambdaScopeInfo : public CapturingScopeInfo {
325 /// \brief The class that describes the lambda.
326 CXXRecordDecl *Lambda;
328 /// \brief The class that describes the lambda.
329 CXXMethodDecl *CallOperator;
331 /// \brief Source range covering the lambda introducer [...].
332 SourceRange IntroducerRange;
334 /// \brief The number of captures in the \c Captures list that are
335 /// explicit captures.
336 unsigned NumExplicitCaptures;
338 /// \brief Whether this is a mutable lambda.
341 /// \brief Whether the (empty) parameter list is explicit.
344 /// \brief Whether any of the capture expressions requires cleanups.
345 bool ExprNeedsCleanups;
347 /// \brief Variables used to index into by-copy array captures.
348 llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
350 /// \brief Offsets into the ArrayIndexVars array at which each capture starts
351 /// its list of array index variables.
352 llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
354 LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
355 CXXMethodDecl *CallOperator)
356 : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
357 CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
358 ExprNeedsCleanups(false)
363 virtual ~LambdaScopeInfo();
366 void finishedExplicitCaptures() {
367 NumExplicitCaptures = Captures.size();
370 static bool classof(const FunctionScopeInfo *FSI) {
371 return FSI->Kind == SK_Lambda;
373 static bool classof(const LambdaScopeInfo *BSI) { return true; }