clang API Documentation
00001 //===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines FunctionScopeInfo and BlockScopeInfo. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H 00015 #define LLVM_CLANG_SEMA_SCOPE_INFO_H 00016 00017 #include "clang/AST/Type.h" 00018 #include "clang/Basic/PartialDiagnostic.h" 00019 #include "llvm/ADT/DenseMap.h" 00020 #include "llvm/ADT/SmallVector.h" 00021 00022 namespace clang { 00023 00024 class BlockDecl; 00025 class CXXMethodDecl; 00026 class IdentifierInfo; 00027 class LabelDecl; 00028 class ReturnStmt; 00029 class Scope; 00030 class SwitchStmt; 00031 class VarDecl; 00032 00033 namespace sema { 00034 00035 /// \brief Contains information about the compound statement currently being 00036 /// parsed. 00037 class CompoundScopeInfo { 00038 public: 00039 CompoundScopeInfo() 00040 : HasEmptyLoopBodies(false) { } 00041 00042 /// \brief Whether this compound stamement contains `for' or `while' loops 00043 /// with empty bodies. 00044 bool HasEmptyLoopBodies; 00045 00046 void setHasEmptyLoopBodies() { 00047 HasEmptyLoopBodies = true; 00048 } 00049 }; 00050 00051 class PossiblyUnreachableDiag { 00052 public: 00053 PartialDiagnostic PD; 00054 SourceLocation Loc; 00055 const Stmt *stmt; 00056 00057 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 00058 const Stmt *stmt) 00059 : PD(PD), Loc(Loc), stmt(stmt) {} 00060 }; 00061 00062 /// \brief Retains information about a function, method, or block that is 00063 /// currently being parsed. 00064 class FunctionScopeInfo { 00065 protected: 00066 enum ScopeKind { 00067 SK_Function, 00068 SK_Block, 00069 SK_Lambda 00070 }; 00071 00072 public: 00073 /// \brief What kind of scope we are describing. 00074 /// 00075 ScopeKind Kind; 00076 00077 /// \brief Whether this function contains a VLA, @try, try, C++ 00078 /// initializer, or anything else that can't be jumped past. 00079 bool HasBranchProtectedScope; 00080 00081 /// \brief Whether this function contains any switches or direct gotos. 00082 bool HasBranchIntoScope; 00083 00084 /// \brief Whether this function contains any indirect gotos. 00085 bool HasIndirectGoto; 00086 00087 /// \brief Used to determine if errors occurred in this function or block. 00088 DiagnosticErrorTrap ErrorTrap; 00089 00090 /// SwitchStack - This is the current set of active switch statements in the 00091 /// block. 00092 SmallVector<SwitchStmt*, 8> SwitchStack; 00093 00094 /// \brief The list of return statements that occur within the function or 00095 /// block, if there is any chance of applying the named return value 00096 /// optimization. 00097 SmallVector<ReturnStmt*, 4> Returns; 00098 00099 /// \brief The stack of currently active compound stamement scopes in the 00100 /// function. 00101 SmallVector<CompoundScopeInfo, 4> CompoundScopes; 00102 00103 /// \brief A list of PartialDiagnostics created but delayed within the 00104 /// current function scope. These diagnostics are vetted for reachability 00105 /// prior to being emitted. 00106 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 00107 00108 void setHasBranchIntoScope() { 00109 HasBranchIntoScope = true; 00110 } 00111 00112 void setHasBranchProtectedScope() { 00113 HasBranchProtectedScope = true; 00114 } 00115 00116 void setHasIndirectGoto() { 00117 HasIndirectGoto = true; 00118 } 00119 00120 bool NeedsScopeChecking() const { 00121 return HasIndirectGoto || 00122 (HasBranchProtectedScope && HasBranchIntoScope); 00123 } 00124 00125 FunctionScopeInfo(DiagnosticsEngine &Diag) 00126 : Kind(SK_Function), 00127 HasBranchProtectedScope(false), 00128 HasBranchIntoScope(false), 00129 HasIndirectGoto(false), 00130 ErrorTrap(Diag) { } 00131 00132 virtual ~FunctionScopeInfo(); 00133 00134 /// \brief Clear out the information in this function scope, making it 00135 /// suitable for reuse. 00136 void Clear(); 00137 00138 static bool classof(const FunctionScopeInfo *FSI) { return true; } 00139 }; 00140 00141 class CapturingScopeInfo : public FunctionScopeInfo { 00142 public: 00143 enum ImplicitCaptureStyle { 00144 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block 00145 }; 00146 00147 ImplicitCaptureStyle ImpCaptureStyle; 00148 00149 class Capture { 00150 // There are two categories of capture: capturing 'this', and capturing 00151 // local variables. There are three ways to capture a local variable: 00152 // capture by copy in the C++11 sense, capture by reference 00153 // in the C++11 sense, and __block capture. Lambdas explicitly specify 00154 // capture by copy or capture by reference. For blocks, __block capture 00155 // applies to variables with that annotation, variables of reference type 00156 // are captured by reference, and other variables are captured by copy. 00157 enum CaptureKind { 00158 Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block 00159 }; 00160 00161 // The variable being captured (if we are not capturing 'this'), 00162 // and misc bits descibing the capture. 00163 llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; 00164 00165 // Expression to initialize a field of the given type, and whether this 00166 // is a nested capture; the expression is only required if we are 00167 // capturing ByVal and the variable's type has a non-trivial 00168 // copy constructor. 00169 llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; 00170 00171 /// \brief The source location at which the first capture occurred.. 00172 SourceLocation Loc; 00173 00174 /// \brief The location of the ellipsis that expands a parameter pack. 00175 SourceLocation EllipsisLoc; 00176 00177 /// \brief The type as it was captured, which is in effect the type of the 00178 /// non-static data member that would hold the capture. 00179 QualType CaptureType; 00180 00181 public: 00182 Capture(VarDecl *Var, bool block, bool byRef, bool isNested, 00183 SourceLocation Loc, SourceLocation EllipsisLoc, 00184 QualType CaptureType, Expr *Cpy) 00185 : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), 00186 CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc), 00187 CaptureType(CaptureType){} 00188 00189 enum IsThisCapture { ThisCapture }; 00190 Capture(IsThisCapture, bool isNested, SourceLocation Loc, 00191 QualType CaptureType, Expr *Cpy) 00192 : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc), 00193 EllipsisLoc(), CaptureType(CaptureType) { } 00194 00195 bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } 00196 bool isVariableCapture() const { return !isThisCapture(); } 00197 bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } 00198 bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } 00199 bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } 00200 bool isNested() { return CopyExprAndNested.getInt(); } 00201 00202 VarDecl *getVariable() const { 00203 return VarAndKind.getPointer(); 00204 } 00205 00206 /// \brief Retrieve the location at which this variable was captured. 00207 SourceLocation getLocation() const { return Loc; } 00208 00209 /// \brief Retrieve the source location of the ellipsis, whose presence 00210 /// indicates that the capture is a pack expansion. 00211 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 00212 00213 /// \brief Retrieve the capture type for this capture, which is effectively 00214 /// the type of the non-static data member in the lambda/block structure 00215 /// that would store this capture. 00216 QualType getCaptureType() const { return CaptureType; } 00217 00218 Expr *getCopyExpr() const { 00219 return CopyExprAndNested.getPointer(); 00220 } 00221 }; 00222 00223 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 00224 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 00225 HasImplicitReturnType(false) 00226 {} 00227 00228 /// CaptureMap - A map of captured variables to (index+1) into Captures. 00229 llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 00230 00231 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 00232 /// zero if 'this' is not captured. 00233 unsigned CXXThisCaptureIndex; 00234 00235 /// Captures - The captures. 00236 SmallVector<Capture, 4> Captures; 00237 00238 /// \brief - Whether the target type of return statements in this context 00239 /// is deduced (e.g. a lambda or block with omitted return type). 00240 bool HasImplicitReturnType; 00241 00242 /// ReturnType - The target type of return statements in this context, 00243 /// or null if unknown. 00244 QualType ReturnType; 00245 00246 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 00247 SourceLocation Loc, SourceLocation EllipsisLoc, 00248 QualType CaptureType, Expr *Cpy) { 00249 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 00250 EllipsisLoc, CaptureType, Cpy)); 00251 CaptureMap[Var] = Captures.size(); 00252 } 00253 00254 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, 00255 Expr *Cpy) { 00256 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, 00257 Cpy)); 00258 CXXThisCaptureIndex = Captures.size(); 00259 } 00260 00261 /// \brief Determine whether the C++ 'this' is captured. 00262 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 00263 00264 /// \brief Retrieve the capture of C++ 'this', if it has been captured. 00265 Capture &getCXXThisCapture() { 00266 assert(isCXXThisCaptured() && "this has not been captured"); 00267 return Captures[CXXThisCaptureIndex - 1]; 00268 } 00269 00270 /// \brief Determine whether the given variable has been captured. 00271 bool isCaptured(VarDecl *Var) const { 00272 return CaptureMap.count(Var); 00273 } 00274 00275 /// \brief Retrieve the capture of the given variable, if it has been 00276 /// captured already. 00277 Capture &getCapture(VarDecl *Var) { 00278 assert(isCaptured(Var) && "Variable has not been captured"); 00279 return Captures[CaptureMap[Var] - 1]; 00280 } 00281 00282 const Capture &getCapture(VarDecl *Var) const { 00283 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 00284 = CaptureMap.find(Var); 00285 assert(Known != CaptureMap.end() && "Variable has not been captured"); 00286 return Captures[Known->second - 1]; 00287 } 00288 00289 static bool classof(const FunctionScopeInfo *FSI) { 00290 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; 00291 } 00292 static bool classof(const CapturingScopeInfo *BSI) { return true; } 00293 }; 00294 00295 /// \brief Retains information about a block that is currently being parsed. 00296 class BlockScopeInfo : public CapturingScopeInfo { 00297 public: 00298 BlockDecl *TheDecl; 00299 00300 /// TheScope - This is the scope for the block itself, which contains 00301 /// arguments etc. 00302 Scope *TheScope; 00303 00304 /// BlockType - The function type of the block, if one was given. 00305 /// Its return type may be BuiltinType::Dependent. 00306 QualType FunctionType; 00307 00308 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 00309 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 00310 TheScope(BlockScope) 00311 { 00312 Kind = SK_Block; 00313 } 00314 00315 virtual ~BlockScopeInfo(); 00316 00317 static bool classof(const FunctionScopeInfo *FSI) { 00318 return FSI->Kind == SK_Block; 00319 } 00320 static bool classof(const BlockScopeInfo *BSI) { return true; } 00321 }; 00322 00323 class LambdaScopeInfo : public CapturingScopeInfo { 00324 public: 00325 /// \brief The class that describes the lambda. 00326 CXXRecordDecl *Lambda; 00327 00328 /// \brief The class that describes the lambda. 00329 CXXMethodDecl *CallOperator; 00330 00331 /// \brief Source range covering the lambda introducer [...]. 00332 SourceRange IntroducerRange; 00333 00334 /// \brief The number of captures in the \c Captures list that are 00335 /// explicit captures. 00336 unsigned NumExplicitCaptures; 00337 00338 /// \brief Whether this is a mutable lambda. 00339 bool Mutable; 00340 00341 /// \brief Whether the (empty) parameter list is explicit. 00342 bool ExplicitParams; 00343 00344 /// \brief Whether any of the capture expressions requires cleanups. 00345 bool ExprNeedsCleanups; 00346 00347 /// \brief Variables used to index into by-copy array captures. 00348 llvm::SmallVector<VarDecl *, 4> ArrayIndexVars; 00349 00350 /// \brief Offsets into the ArrayIndexVars array at which each capture starts 00351 /// its list of array index variables. 00352 llvm::SmallVector<unsigned, 4> ArrayIndexStarts; 00353 00354 LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, 00355 CXXMethodDecl *CallOperator) 00356 : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), 00357 CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), 00358 ExprNeedsCleanups(false) 00359 { 00360 Kind = SK_Lambda; 00361 } 00362 00363 virtual ~LambdaScopeInfo(); 00364 00365 /// \brief Note when 00366 void finishedExplicitCaptures() { 00367 NumExplicitCaptures = Captures.size(); 00368 } 00369 00370 static bool classof(const FunctionScopeInfo *FSI) { 00371 return FSI->Kind == SK_Lambda; 00372 } 00373 static bool classof(const LambdaScopeInfo *BSI) { return true; } 00374 00375 }; 00376 00377 } 00378 } 00379 00380 #endif