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