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