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