ScopeInfo.h revision b6d80fe68d30ebd14b20c96643c252c36041df8d
1//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines FunctionScopeInfo and its subclasses, which contain 11// information about a single function, block, lambda, or method body. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H 16#define LLVM_CLANG_SEMA_SCOPE_INFO_H 17 18#include "clang/AST/Type.h" 19#include "clang/Basic/PartialDiagnostic.h" 20#include "llvm/ADT/DenseMap.h" 21#include "llvm/ADT/SmallVector.h" 22 23namespace clang { 24 25class Decl; 26class BlockDecl; 27class CXXMethodDecl; 28class IdentifierInfo; 29class LabelDecl; 30class ReturnStmt; 31class Scope; 32class SwitchStmt; 33class VarDecl; 34class DeclRefExpr; 35class ObjCIvarRefExpr; 36class ObjCPropertyRefExpr; 37 38namespace sema { 39 40/// \brief Contains information about the compound statement currently being 41/// parsed. 42class CompoundScopeInfo { 43public: 44 CompoundScopeInfo() 45 : HasEmptyLoopBodies(false) { } 46 47 /// \brief Whether this compound stamement contains `for' or `while' loops 48 /// with empty bodies. 49 bool HasEmptyLoopBodies; 50 51 void setHasEmptyLoopBodies() { 52 HasEmptyLoopBodies = true; 53 } 54}; 55 56class PossiblyUnreachableDiag { 57public: 58 PartialDiagnostic PD; 59 SourceLocation Loc; 60 const Stmt *stmt; 61 62 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 63 const Stmt *stmt) 64 : PD(PD), Loc(Loc), stmt(stmt) {} 65}; 66 67/// \brief Retains information about a function, method, or block that is 68/// currently being parsed. 69class FunctionScopeInfo { 70protected: 71 enum ScopeKind { 72 SK_Function, 73 SK_Block, 74 SK_Lambda 75 }; 76 77public: 78 /// \brief What kind of scope we are describing. 79 /// 80 ScopeKind Kind; 81 82 /// \brief Whether this function contains a VLA, \@try, try, C++ 83 /// initializer, or anything else that can't be jumped past. 84 bool HasBranchProtectedScope; 85 86 /// \brief Whether this function contains any switches or direct gotos. 87 bool HasBranchIntoScope; 88 89 /// \brief Whether this function contains any indirect gotos. 90 bool HasIndirectGoto; 91 92 /// A flag that is set when parsing a -dealloc method and no [super dealloc] 93 /// call was found yet. 94 bool ObjCShouldCallSuperDealloc; 95 96 /// A flag that is set when parsing a -finalize method and no [super finalize] 97 /// call was found yet. 98 bool ObjCShouldCallSuperFinalize; 99 100 /// \brief Used to determine if errors occurred in this function or block. 101 DiagnosticErrorTrap ErrorTrap; 102 103 /// SwitchStack - This is the current set of active switch statements in the 104 /// block. 105 SmallVector<SwitchStmt*, 8> SwitchStack; 106 107 /// \brief The list of return statements that occur within the function or 108 /// block, if there is any chance of applying the named return value 109 /// optimization, or if we need to infer a return type. 110 SmallVector<ReturnStmt*, 4> Returns; 111 112 /// \brief The stack of currently active compound stamement scopes in the 113 /// function. 114 SmallVector<CompoundScopeInfo, 4> CompoundScopes; 115 116 /// \brief A list of PartialDiagnostics created but delayed within the 117 /// current function scope. These diagnostics are vetted for reachability 118 /// prior to being emitted. 119 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 120 121public: 122 /// Represents a simple identification of a weak object. 123 /// 124 /// Part of the implementation of -Wrepeated-use-of-weak. 125 /// 126 /// This is used to determine if two weak accesses refer to the same object. 127 /// Here are some examples of how various accesses are "profiled": 128 /// 129 /// Access Expression | "Base" Decl | "Property" Decl 130 /// :---------------: | :-----------------: | :------------------------------: 131 /// self.property | self (VarDecl) | property (ObjCPropertyDecl) 132 /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl) 133 /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl) 134 /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl) 135 /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) 136 /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) 137 /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) 138 /// weakVar | 0 (known) | weakVar (VarDecl) 139 /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) 140 /// 141 /// Objects are identified with only two Decls to make it reasonably fast to 142 /// compare them. 143 class WeakObjectProfileTy { 144 /// The base object decl, as described in the class documentation. 145 /// 146 /// The extra flag is "true" if the Base and Property are enough to uniquely 147 /// identify the object in memory. 148 /// 149 /// \sa isExactProfile() 150 typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy; 151 BaseInfoTy Base; 152 153 /// The "property" decl, as described in the class documentation. 154 /// 155 /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the 156 /// case of "implicit" properties (regular methods accessed via dot syntax). 157 const NamedDecl *Property; 158 159 /// Used to find the proper base profile for a given base expression. 160 static BaseInfoTy getBaseInfo(const Expr *BaseE); 161 162 // For use in DenseMap. 163 friend class DenseMapInfo; 164 inline WeakObjectProfileTy(); 165 static inline WeakObjectProfileTy getSentinel(); 166 167 public: 168 WeakObjectProfileTy(const ObjCPropertyRefExpr *RE); 169 WeakObjectProfileTy(const DeclRefExpr *RE); 170 WeakObjectProfileTy(const ObjCIvarRefExpr *RE); 171 172 const NamedDecl *getProperty() const { return Property; } 173 174 /// Returns true if the object base specifies a known object in memory, 175 /// rather than, say, an instance variable or property of another object. 176 /// 177 /// Note that this ignores the effects of aliasing; that is, \c foo.bar is 178 /// considered an exact profile if \c foo is a local variable, even if 179 /// another variable \c foo2 refers to the same object as \c foo. 180 /// 181 /// For increased precision, accesses with base variables that are 182 /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to 183 /// be exact, though this is not true for arbitrary variables 184 /// (foo.prop1.prop2). 185 bool isExactProfile() const { 186 return Base.getInt(); 187 } 188 189 bool operator==(const WeakObjectProfileTy &Other) const { 190 return Base == Other.Base && Property == Other.Property; 191 } 192 193 // For use in DenseMap. 194 // We can't specialize the usual llvm::DenseMapInfo at the end of the file 195 // because by that point the DenseMap in FunctionScopeInfo has already been 196 // instantiated. 197 class DenseMapInfo { 198 public: 199 static inline WeakObjectProfileTy getEmptyKey() { 200 return WeakObjectProfileTy(); 201 } 202 static inline WeakObjectProfileTy getTombstoneKey() { 203 return WeakObjectProfileTy::getSentinel(); 204 } 205 206 static unsigned getHashValue(const WeakObjectProfileTy &Val) { 207 typedef std::pair<BaseInfoTy, const NamedDecl *> Pair; 208 return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, 209 Val.Property)); 210 } 211 212 static bool isEqual(const WeakObjectProfileTy &LHS, 213 const WeakObjectProfileTy &RHS) { 214 return LHS == RHS; 215 } 216 }; 217 }; 218 219 /// Represents a single use of a weak object. 220 /// 221 /// Stores both the expression and whether the access is potentially unsafe 222 /// (i.e. it could potentially be warned about). 223 /// 224 /// Part of the implementation of -Wrepeated-use-of-weak. 225 class WeakUseTy { 226 llvm::PointerIntPair<const Expr *, 1, bool> Rep; 227 public: 228 WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {} 229 230 const Expr *getUseExpr() const { return Rep.getPointer(); } 231 bool isUnsafe() const { return Rep.getInt(); } 232 void markSafe() { Rep.setInt(false); } 233 234 bool operator==(const WeakUseTy &Other) const { 235 return Rep == Other.Rep; 236 } 237 }; 238 239 /// Used to collect uses of a particular weak object in a function body. 240 /// 241 /// Part of the implementation of -Wrepeated-use-of-weak. 242 typedef SmallVector<WeakUseTy, 4> WeakUseVector; 243 244 /// Used to collect all uses of weak objects in a function body. 245 /// 246 /// Part of the implementation of -Wrepeated-use-of-weak. 247 typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8, 248 WeakObjectProfileTy::DenseMapInfo> 249 WeakObjectUseMap; 250 251private: 252 /// Used to collect all uses of weak objects in this function body. 253 /// 254 /// Part of the implementation of -Wrepeated-use-of-weak. 255 WeakObjectUseMap WeakObjectUses; 256 257public: 258 /// Record that a weak object was accessed. 259 /// 260 /// Part of the implementation of -Wrepeated-use-of-weak. 261 template <typename ExprT> 262 inline void recordUseOfWeak(const ExprT *E, bool IsRead = true); 263 264 /// Record that a given expression is a "safe" access of a weak object (e.g. 265 /// assigning it to a strong variable.) 266 /// 267 /// Part of the implementation of -Wrepeated-use-of-weak. 268 void markSafeWeakUse(const Expr *E); 269 270 const WeakObjectUseMap &getWeakObjectUses() const { 271 return WeakObjectUses; 272 } 273 274 void setHasBranchIntoScope() { 275 HasBranchIntoScope = true; 276 } 277 278 void setHasBranchProtectedScope() { 279 HasBranchProtectedScope = true; 280 } 281 282 void setHasIndirectGoto() { 283 HasIndirectGoto = true; 284 } 285 286 bool NeedsScopeChecking() const { 287 return HasIndirectGoto || 288 (HasBranchProtectedScope && HasBranchIntoScope); 289 } 290 291 FunctionScopeInfo(DiagnosticsEngine &Diag) 292 : Kind(SK_Function), 293 HasBranchProtectedScope(false), 294 HasBranchIntoScope(false), 295 HasIndirectGoto(false), 296 ObjCShouldCallSuperDealloc(false), 297 ObjCShouldCallSuperFinalize(false), 298 ErrorTrap(Diag) { } 299 300 virtual ~FunctionScopeInfo(); 301 302 /// \brief Clear out the information in this function scope, making it 303 /// suitable for reuse. 304 void Clear(); 305 306 static bool classof(const FunctionScopeInfo *FSI) { return true; } 307}; 308 309class CapturingScopeInfo : public FunctionScopeInfo { 310public: 311 enum ImplicitCaptureStyle { 312 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block 313 }; 314 315 ImplicitCaptureStyle ImpCaptureStyle; 316 317 class Capture { 318 // There are two categories of capture: capturing 'this', and capturing 319 // local variables. There are three ways to capture a local variable: 320 // capture by copy in the C++11 sense, capture by reference 321 // in the C++11 sense, and __block capture. Lambdas explicitly specify 322 // capture by copy or capture by reference. For blocks, __block capture 323 // applies to variables with that annotation, variables of reference type 324 // are captured by reference, and other variables are captured by copy. 325 enum CaptureKind { 326 Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block 327 }; 328 329 // The variable being captured (if we are not capturing 'this'), 330 // and misc bits descibing the capture. 331 llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; 332 333 // Expression to initialize a field of the given type, and whether this 334 // is a nested capture; the expression is only required if we are 335 // capturing ByVal and the variable's type has a non-trivial 336 // copy constructor. 337 llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; 338 339 /// \brief The source location at which the first capture occurred.. 340 SourceLocation Loc; 341 342 /// \brief The location of the ellipsis that expands a parameter pack. 343 SourceLocation EllipsisLoc; 344 345 /// \brief The type as it was captured, which is in effect the type of the 346 /// non-static data member that would hold the capture. 347 QualType CaptureType; 348 349 public: 350 Capture(VarDecl *Var, bool block, bool byRef, bool isNested, 351 SourceLocation Loc, SourceLocation EllipsisLoc, 352 QualType CaptureType, Expr *Cpy) 353 : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), 354 CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc), 355 CaptureType(CaptureType){} 356 357 enum IsThisCapture { ThisCapture }; 358 Capture(IsThisCapture, bool isNested, SourceLocation Loc, 359 QualType CaptureType, Expr *Cpy) 360 : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc), 361 EllipsisLoc(), CaptureType(CaptureType) { } 362 363 bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } 364 bool isVariableCapture() const { return !isThisCapture(); } 365 bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } 366 bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } 367 bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } 368 bool isNested() { return CopyExprAndNested.getInt(); } 369 370 VarDecl *getVariable() const { 371 return VarAndKind.getPointer(); 372 } 373 374 /// \brief Retrieve the location at which this variable was captured. 375 SourceLocation getLocation() const { return Loc; } 376 377 /// \brief Retrieve the source location of the ellipsis, whose presence 378 /// indicates that the capture is a pack expansion. 379 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 380 381 /// \brief Retrieve the capture type for this capture, which is effectively 382 /// the type of the non-static data member in the lambda/block structure 383 /// that would store this capture. 384 QualType getCaptureType() const { return CaptureType; } 385 386 Expr *getCopyExpr() const { 387 return CopyExprAndNested.getPointer(); 388 } 389 }; 390 391 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 392 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 393 HasImplicitReturnType(false) 394 {} 395 396 /// CaptureMap - A map of captured variables to (index+1) into Captures. 397 llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 398 399 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 400 /// zero if 'this' is not captured. 401 unsigned CXXThisCaptureIndex; 402 403 /// Captures - The captures. 404 SmallVector<Capture, 4> Captures; 405 406 /// \brief - Whether the target type of return statements in this context 407 /// is deduced (e.g. a lambda or block with omitted return type). 408 bool HasImplicitReturnType; 409 410 /// ReturnType - The target type of return statements in this context, 411 /// or null if unknown. 412 QualType ReturnType; 413 414 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 415 SourceLocation Loc, SourceLocation EllipsisLoc, 416 QualType CaptureType, Expr *Cpy) { 417 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 418 EllipsisLoc, CaptureType, Cpy)); 419 CaptureMap[Var] = Captures.size(); 420 } 421 422 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, 423 Expr *Cpy) { 424 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, 425 Cpy)); 426 CXXThisCaptureIndex = Captures.size(); 427 } 428 429 /// \brief Determine whether the C++ 'this' is captured. 430 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 431 432 /// \brief Retrieve the capture of C++ 'this', if it has been captured. 433 Capture &getCXXThisCapture() { 434 assert(isCXXThisCaptured() && "this has not been captured"); 435 return Captures[CXXThisCaptureIndex - 1]; 436 } 437 438 /// \brief Determine whether the given variable has been captured. 439 bool isCaptured(VarDecl *Var) const { 440 return CaptureMap.count(Var); 441 } 442 443 /// \brief Retrieve the capture of the given variable, if it has been 444 /// captured already. 445 Capture &getCapture(VarDecl *Var) { 446 assert(isCaptured(Var) && "Variable has not been captured"); 447 return Captures[CaptureMap[Var] - 1]; 448 } 449 450 const Capture &getCapture(VarDecl *Var) const { 451 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 452 = CaptureMap.find(Var); 453 assert(Known != CaptureMap.end() && "Variable has not been captured"); 454 return Captures[Known->second - 1]; 455 } 456 457 static bool classof(const FunctionScopeInfo *FSI) { 458 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; 459 } 460 static bool classof(const CapturingScopeInfo *BSI) { return true; } 461}; 462 463/// \brief Retains information about a block that is currently being parsed. 464class BlockScopeInfo : public CapturingScopeInfo { 465public: 466 BlockDecl *TheDecl; 467 468 /// TheScope - This is the scope for the block itself, which contains 469 /// arguments etc. 470 Scope *TheScope; 471 472 /// BlockType - The function type of the block, if one was given. 473 /// Its return type may be BuiltinType::Dependent. 474 QualType FunctionType; 475 476 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 477 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 478 TheScope(BlockScope) 479 { 480 Kind = SK_Block; 481 } 482 483 virtual ~BlockScopeInfo(); 484 485 static bool classof(const FunctionScopeInfo *FSI) { 486 return FSI->Kind == SK_Block; 487 } 488 static bool classof(const BlockScopeInfo *BSI) { return true; } 489}; 490 491class LambdaScopeInfo : public CapturingScopeInfo { 492public: 493 /// \brief The class that describes the lambda. 494 CXXRecordDecl *Lambda; 495 496 /// \brief The class that describes the lambda. 497 CXXMethodDecl *CallOperator; 498 499 /// \brief Source range covering the lambda introducer [...]. 500 SourceRange IntroducerRange; 501 502 /// \brief The number of captures in the \c Captures list that are 503 /// explicit captures. 504 unsigned NumExplicitCaptures; 505 506 /// \brief Whether this is a mutable lambda. 507 bool Mutable; 508 509 /// \brief Whether the (empty) parameter list is explicit. 510 bool ExplicitParams; 511 512 /// \brief Whether any of the capture expressions requires cleanups. 513 bool ExprNeedsCleanups; 514 515 /// \brief Whether the lambda contains an unexpanded parameter pack. 516 bool ContainsUnexpandedParameterPack; 517 518 /// \brief Variables used to index into by-copy array captures. 519 llvm::SmallVector<VarDecl *, 4> ArrayIndexVars; 520 521 /// \brief Offsets into the ArrayIndexVars array at which each capture starts 522 /// its list of array index variables. 523 llvm::SmallVector<unsigned, 4> ArrayIndexStarts; 524 525 LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, 526 CXXMethodDecl *CallOperator) 527 : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), 528 CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), 529 ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false) 530 { 531 Kind = SK_Lambda; 532 } 533 534 virtual ~LambdaScopeInfo(); 535 536 /// \brief Note when 537 void finishedExplicitCaptures() { 538 NumExplicitCaptures = Captures.size(); 539 } 540 541 static bool classof(const FunctionScopeInfo *FSI) { 542 return FSI->Kind == SK_Lambda; 543 } 544 static bool classof(const LambdaScopeInfo *BSI) { return true; } 545 546}; 547 548FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() 549 : Base(0, false), Property(0) {} 550 551FunctionScopeInfo::WeakObjectProfileTy 552FunctionScopeInfo::WeakObjectProfileTy::getSentinel() { 553 FunctionScopeInfo::WeakObjectProfileTy Result; 554 Result.Base.setInt(true); 555 return Result; 556} 557 558template <typename ExprT> 559void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { 560 assert(E); 561 WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)]; 562 Uses.push_back(WeakUseTy(E, IsRead)); 563} 564 565} // end namespace sema 566} // end namespace clang 567 568#endif 569