ScopeInfo.h revision b43d87b0646aa04951056c7e0d1ab9a58eb09f66
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 313class CapturingScopeInfo : public FunctionScopeInfo { 314public: 315 enum ImplicitCaptureStyle { 316 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block 317 }; 318 319 ImplicitCaptureStyle ImpCaptureStyle; 320 321 class Capture { 322 // There are two categories of capture: capturing 'this', and capturing 323 // local variables. There are three ways to capture a local variable: 324 // capture by copy in the C++11 sense, capture by reference 325 // in the C++11 sense, and __block capture. Lambdas explicitly specify 326 // capture by copy or capture by reference. For blocks, __block capture 327 // applies to variables with that annotation, variables of reference type 328 // are captured by reference, and other variables are captured by copy. 329 enum CaptureKind { 330 Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block 331 }; 332 333 // The variable being captured (if we are not capturing 'this'), 334 // and misc bits descibing the capture. 335 llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; 336 337 // Expression to initialize a field of the given type, and whether this 338 // is a nested capture; the expression is only required if we are 339 // capturing ByVal and the variable's type has a non-trivial 340 // copy constructor. 341 llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; 342 343 /// \brief The source location at which the first capture occurred.. 344 SourceLocation Loc; 345 346 /// \brief The location of the ellipsis that expands a parameter pack. 347 SourceLocation EllipsisLoc; 348 349 /// \brief The type as it was captured, which is in effect the type of the 350 /// non-static data member that would hold the capture. 351 QualType CaptureType; 352 353 public: 354 Capture(VarDecl *Var, bool block, bool byRef, bool isNested, 355 SourceLocation Loc, SourceLocation EllipsisLoc, 356 QualType CaptureType, Expr *Cpy) 357 : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), 358 CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc), 359 CaptureType(CaptureType){} 360 361 enum IsThisCapture { ThisCapture }; 362 Capture(IsThisCapture, bool isNested, SourceLocation Loc, 363 QualType CaptureType, Expr *Cpy) 364 : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc), 365 EllipsisLoc(), CaptureType(CaptureType) { } 366 367 bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } 368 bool isVariableCapture() const { return !isThisCapture(); } 369 bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } 370 bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } 371 bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } 372 bool isNested() { return CopyExprAndNested.getInt(); } 373 374 VarDecl *getVariable() const { 375 return VarAndKind.getPointer(); 376 } 377 378 /// \brief Retrieve the location at which this variable was captured. 379 SourceLocation getLocation() const { return Loc; } 380 381 /// \brief Retrieve the source location of the ellipsis, whose presence 382 /// indicates that the capture is a pack expansion. 383 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 384 385 /// \brief Retrieve the capture type for this capture, which is effectively 386 /// the type of the non-static data member in the lambda/block structure 387 /// that would store this capture. 388 QualType getCaptureType() const { return CaptureType; } 389 390 Expr *getCopyExpr() const { 391 return CopyExprAndNested.getPointer(); 392 } 393 }; 394 395 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 396 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 397 HasImplicitReturnType(false) 398 {} 399 400 /// CaptureMap - A map of captured variables to (index+1) into Captures. 401 llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 402 403 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 404 /// zero if 'this' is not captured. 405 unsigned CXXThisCaptureIndex; 406 407 /// Captures - The captures. 408 SmallVector<Capture, 4> Captures; 409 410 /// \brief - Whether the target type of return statements in this context 411 /// is deduced (e.g. a lambda or block with omitted return type). 412 bool HasImplicitReturnType; 413 414 /// ReturnType - The target type of return statements in this context, 415 /// or null if unknown. 416 QualType ReturnType; 417 418 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 419 SourceLocation Loc, SourceLocation EllipsisLoc, 420 QualType CaptureType, Expr *Cpy) { 421 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 422 EllipsisLoc, CaptureType, Cpy)); 423 CaptureMap[Var] = Captures.size(); 424 } 425 426 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, 427 Expr *Cpy) { 428 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, 429 Cpy)); 430 CXXThisCaptureIndex = Captures.size(); 431 } 432 433 /// \brief Determine whether the C++ 'this' is captured. 434 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 435 436 /// \brief Retrieve the capture of C++ 'this', if it has been captured. 437 Capture &getCXXThisCapture() { 438 assert(isCXXThisCaptured() && "this has not been captured"); 439 return Captures[CXXThisCaptureIndex - 1]; 440 } 441 442 /// \brief Determine whether the given variable has been captured. 443 bool isCaptured(VarDecl *Var) const { 444 return CaptureMap.count(Var); 445 } 446 447 /// \brief Retrieve the capture of the given variable, if it has been 448 /// captured already. 449 Capture &getCapture(VarDecl *Var) { 450 assert(isCaptured(Var) && "Variable has not been captured"); 451 return Captures[CaptureMap[Var] - 1]; 452 } 453 454 const Capture &getCapture(VarDecl *Var) const { 455 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 456 = CaptureMap.find(Var); 457 assert(Known != CaptureMap.end() && "Variable has not been captured"); 458 return Captures[Known->second - 1]; 459 } 460 461 static bool classof(const FunctionScopeInfo *FSI) { 462 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; 463 } 464}; 465 466/// \brief Retains information about a block that is currently being parsed. 467class BlockScopeInfo : public CapturingScopeInfo { 468public: 469 BlockDecl *TheDecl; 470 471 /// TheScope - This is the scope for the block itself, which contains 472 /// arguments etc. 473 Scope *TheScope; 474 475 /// BlockType - The function type of the block, if one was given. 476 /// Its return type may be BuiltinType::Dependent. 477 QualType FunctionType; 478 479 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 480 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 481 TheScope(BlockScope) 482 { 483 Kind = SK_Block; 484 } 485 486 virtual ~BlockScopeInfo(); 487 488 static bool classof(const FunctionScopeInfo *FSI) { 489 return FSI->Kind == SK_Block; 490 } 491}; 492 493class LambdaScopeInfo : public CapturingScopeInfo { 494public: 495 /// \brief The class that describes the lambda. 496 CXXRecordDecl *Lambda; 497 498 /// \brief The class that describes the lambda. 499 CXXMethodDecl *CallOperator; 500 501 /// \brief Source range covering the lambda introducer [...]. 502 SourceRange IntroducerRange; 503 504 /// \brief The number of captures in the \c Captures list that are 505 /// explicit captures. 506 unsigned NumExplicitCaptures; 507 508 /// \brief Whether this is a mutable lambda. 509 bool Mutable; 510 511 /// \brief Whether the (empty) parameter list is explicit. 512 bool ExplicitParams; 513 514 /// \brief Whether any of the capture expressions requires cleanups. 515 bool ExprNeedsCleanups; 516 517 /// \brief Whether the lambda contains an unexpanded parameter pack. 518 bool ContainsUnexpandedParameterPack; 519 520 /// \brief Variables used to index into by-copy array captures. 521 llvm::SmallVector<VarDecl *, 4> ArrayIndexVars; 522 523 /// \brief Offsets into the ArrayIndexVars array at which each capture starts 524 /// its list of array index variables. 525 llvm::SmallVector<unsigned, 4> ArrayIndexStarts; 526 527 LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, 528 CXXMethodDecl *CallOperator) 529 : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), 530 CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), 531 ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false) 532 { 533 Kind = SK_Lambda; 534 } 535 536 virtual ~LambdaScopeInfo(); 537 538 /// \brief Note when 539 void finishedExplicitCaptures() { 540 NumExplicitCaptures = Captures.size(); 541 } 542 543 static bool classof(const FunctionScopeInfo *FSI) { 544 return FSI->Kind == SK_Lambda; 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