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