Home | History | Annotate | Download | only in Sema
      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 
     23 namespace clang {
     24 
     25 class Decl;
     26 class BlockDecl;
     27 class CXXMethodDecl;
     28 class ObjCPropertyDecl;
     29 class IdentifierInfo;
     30 class LabelDecl;
     31 class ReturnStmt;
     32 class Scope;
     33 class SwitchStmt;
     34 class VarDecl;
     35 class DeclRefExpr;
     36 class ObjCIvarRefExpr;
     37 class ObjCPropertyRefExpr;
     38 class ObjCMessageExpr;
     39 
     40 namespace sema {
     41 
     42 /// \brief Contains information about the compound statement currently being
     43 /// parsed.
     44 class CompoundScopeInfo {
     45 public:
     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 
     58 class PossiblyUnreachableDiag {
     59 public:
     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.
     71 class FunctionScopeInfo {
     72 protected:
     73   enum ScopeKind {
     74     SK_Function,
     75     SK_Block,
     76     SK_Lambda
     77   };
     78 
     79 public:
     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   /// \brief Whether a statement was dropped because it was invalid.
     95   bool HasDroppedStmt;
     96 
     97   /// A flag that is set when parsing a method that must call super's
     98   /// implementation, such as \c -dealloc, \c -finalize, or any method marked
     99   /// with \c __attribute__((objc_requires_super)).
    100   bool ObjCShouldCallSuper;
    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 
    123 public:
    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 *getBase() const { return Base.getPointer(); }
    176     const NamedDecl *getProperty() const { return Property; }
    177 
    178     /// Returns true if the object base specifies a known object in memory,
    179     /// rather than, say, an instance variable or property of another object.
    180     ///
    181     /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
    182     /// considered an exact profile if \c foo is a local variable, even if
    183     /// another variable \c foo2 refers to the same object as \c foo.
    184     ///
    185     /// For increased precision, accesses with base variables that are
    186     /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
    187     /// be exact, though this is not true for arbitrary variables
    188     /// (foo.prop1.prop2).
    189     bool isExactProfile() const {
    190       return Base.getInt();
    191     }
    192 
    193     bool operator==(const WeakObjectProfileTy &Other) const {
    194       return Base == Other.Base && Property == Other.Property;
    195     }
    196 
    197     // For use in DenseMap.
    198     // We can't specialize the usual llvm::DenseMapInfo at the end of the file
    199     // because by that point the DenseMap in FunctionScopeInfo has already been
    200     // instantiated.
    201     class DenseMapInfo {
    202     public:
    203       static inline WeakObjectProfileTy getEmptyKey() {
    204         return WeakObjectProfileTy();
    205       }
    206       static inline WeakObjectProfileTy getTombstoneKey() {
    207         return WeakObjectProfileTy::getSentinel();
    208       }
    209 
    210       static unsigned getHashValue(const WeakObjectProfileTy &Val) {
    211         typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
    212         return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
    213                                                            Val.Property));
    214       }
    215 
    216       static bool isEqual(const WeakObjectProfileTy &LHS,
    217                           const WeakObjectProfileTy &RHS) {
    218         return LHS == RHS;
    219       }
    220     };
    221   };
    222 
    223   /// Represents a single use of a weak object.
    224   ///
    225   /// Stores both the expression and whether the access is potentially unsafe
    226   /// (i.e. it could potentially be warned about).
    227   ///
    228   /// Part of the implementation of -Wrepeated-use-of-weak.
    229   class WeakUseTy {
    230     llvm::PointerIntPair<const Expr *, 1, bool> Rep;
    231   public:
    232     WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
    233 
    234     const Expr *getUseExpr() const { return Rep.getPointer(); }
    235     bool isUnsafe() const { return Rep.getInt(); }
    236     void markSafe() { Rep.setInt(false); }
    237 
    238     bool operator==(const WeakUseTy &Other) const {
    239       return Rep == Other.Rep;
    240     }
    241   };
    242 
    243   /// Used to collect uses of a particular weak object in a function body.
    244   ///
    245   /// Part of the implementation of -Wrepeated-use-of-weak.
    246   typedef SmallVector<WeakUseTy, 4> WeakUseVector;
    247 
    248   /// Used to collect all uses of weak objects in a function body.
    249   ///
    250   /// Part of the implementation of -Wrepeated-use-of-weak.
    251   typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
    252                               WeakObjectProfileTy::DenseMapInfo>
    253           WeakObjectUseMap;
    254 
    255 private:
    256   /// Used to collect all uses of weak objects in this function body.
    257   ///
    258   /// Part of the implementation of -Wrepeated-use-of-weak.
    259   WeakObjectUseMap WeakObjectUses;
    260 
    261 public:
    262   /// Record that a weak object was accessed.
    263   ///
    264   /// Part of the implementation of -Wrepeated-use-of-weak.
    265   template <typename ExprT>
    266   inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
    267 
    268   void recordUseOfWeak(const ObjCMessageExpr *Msg,
    269                        const ObjCPropertyDecl *Prop);
    270 
    271   /// Record that a given expression is a "safe" access of a weak object (e.g.
    272   /// assigning it to a strong variable.)
    273   ///
    274   /// Part of the implementation of -Wrepeated-use-of-weak.
    275   void markSafeWeakUse(const Expr *E);
    276 
    277   const WeakObjectUseMap &getWeakObjectUses() const {
    278     return WeakObjectUses;
    279   }
    280 
    281   void setHasBranchIntoScope() {
    282     HasBranchIntoScope = true;
    283   }
    284 
    285   void setHasBranchProtectedScope() {
    286     HasBranchProtectedScope = true;
    287   }
    288 
    289   void setHasIndirectGoto() {
    290     HasIndirectGoto = true;
    291   }
    292 
    293   void setHasDroppedStmt() {
    294     HasDroppedStmt = true;
    295   }
    296 
    297   bool NeedsScopeChecking() const {
    298     return !HasDroppedStmt &&
    299         (HasIndirectGoto ||
    300           (HasBranchProtectedScope && HasBranchIntoScope));
    301   }
    302 
    303   FunctionScopeInfo(DiagnosticsEngine &Diag)
    304     : Kind(SK_Function),
    305       HasBranchProtectedScope(false),
    306       HasBranchIntoScope(false),
    307       HasIndirectGoto(false),
    308       HasDroppedStmt(false),
    309       ObjCShouldCallSuper(false),
    310       ErrorTrap(Diag) { }
    311 
    312   virtual ~FunctionScopeInfo();
    313 
    314   /// \brief Clear out the information in this function scope, making it
    315   /// suitable for reuse.
    316   void Clear();
    317 };
    318 
    319 class CapturingScopeInfo : public FunctionScopeInfo {
    320 public:
    321   enum ImplicitCaptureStyle {
    322     ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
    323   };
    324 
    325   ImplicitCaptureStyle ImpCaptureStyle;
    326 
    327   class Capture {
    328     // There are two categories of capture: capturing 'this', and capturing
    329     // local variables.  There are three ways to capture a local variable:
    330     // capture by copy in the C++11 sense, capture by reference
    331     // in the C++11 sense, and __block capture.  Lambdas explicitly specify
    332     // capture by copy or capture by reference.  For blocks, __block capture
    333     // applies to variables with that annotation, variables of reference type
    334     // are captured by reference, and other variables are captured by copy.
    335     enum CaptureKind {
    336       Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
    337     };
    338 
    339     // The variable being captured (if we are not capturing 'this'),
    340     // and misc bits descibing the capture.
    341     llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
    342 
    343     // Expression to initialize a field of the given type, and whether this
    344     // is a nested capture; the expression is only required if we are
    345     // capturing ByVal and the variable's type has a non-trivial
    346     // copy constructor.
    347     llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
    348 
    349     /// \brief The source location at which the first capture occurred..
    350     SourceLocation Loc;
    351 
    352     /// \brief The location of the ellipsis that expands a parameter pack.
    353     SourceLocation EllipsisLoc;
    354 
    355     /// \brief The type as it was captured, which is in effect the type of the
    356     /// non-static data member that would hold the capture.
    357     QualType CaptureType;
    358 
    359   public:
    360     Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
    361             SourceLocation Loc, SourceLocation EllipsisLoc,
    362             QualType CaptureType, Expr *Cpy)
    363       : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
    364         CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
    365         CaptureType(CaptureType){}
    366 
    367     enum IsThisCapture { ThisCapture };
    368     Capture(IsThisCapture, bool isNested, SourceLocation Loc,
    369             QualType CaptureType, Expr *Cpy)
    370       : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
    371         EllipsisLoc(), CaptureType(CaptureType) { }
    372 
    373     bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
    374     bool isVariableCapture() const { return !isThisCapture(); }
    375     bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
    376     bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
    377     bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
    378     bool isNested() { return CopyExprAndNested.getInt(); }
    379 
    380     VarDecl *getVariable() const {
    381       return VarAndKind.getPointer();
    382     }
    383 
    384     /// \brief Retrieve the location at which this variable was captured.
    385     SourceLocation getLocation() const { return Loc; }
    386 
    387     /// \brief Retrieve the source location of the ellipsis, whose presence
    388     /// indicates that the capture is a pack expansion.
    389     SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
    390 
    391     /// \brief Retrieve the capture type for this capture, which is effectively
    392     /// the type of the non-static data member in the lambda/block structure
    393     /// that would store this capture.
    394     QualType getCaptureType() const { return CaptureType; }
    395 
    396     Expr *getCopyExpr() const {
    397       return CopyExprAndNested.getPointer();
    398     }
    399   };
    400 
    401   CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
    402     : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
    403       HasImplicitReturnType(false)
    404      {}
    405 
    406   /// CaptureMap - A map of captured variables to (index+1) into Captures.
    407   llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
    408 
    409   /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
    410   /// zero if 'this' is not captured.
    411   unsigned CXXThisCaptureIndex;
    412 
    413   /// Captures - The captures.
    414   SmallVector<Capture, 4> Captures;
    415 
    416   /// \brief - Whether the target type of return statements in this context
    417   /// is deduced (e.g. a lambda or block with omitted return type).
    418   bool HasImplicitReturnType;
    419 
    420   /// ReturnType - The target type of return statements in this context,
    421   /// or null if unknown.
    422   QualType ReturnType;
    423 
    424   void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
    425                   SourceLocation Loc, SourceLocation EllipsisLoc,
    426                   QualType CaptureType, Expr *Cpy) {
    427     Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
    428                                EllipsisLoc, CaptureType, Cpy));
    429     CaptureMap[Var] = Captures.size();
    430   }
    431 
    432   void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
    433                       Expr *Cpy);
    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 };
    467 
    468 /// \brief Retains information about a block that is currently being parsed.
    469 class BlockScopeInfo : public CapturingScopeInfo {
    470 public:
    471   BlockDecl *TheDecl;
    472 
    473   /// TheScope - This is the scope for the block itself, which contains
    474   /// arguments etc.
    475   Scope *TheScope;
    476 
    477   /// BlockType - The function type of the block, if one was given.
    478   /// Its return type may be BuiltinType::Dependent.
    479   QualType FunctionType;
    480 
    481   BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
    482     : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
    483       TheScope(BlockScope)
    484   {
    485     Kind = SK_Block;
    486   }
    487 
    488   virtual ~BlockScopeInfo();
    489 
    490   static bool classof(const FunctionScopeInfo *FSI) {
    491     return FSI->Kind == SK_Block;
    492   }
    493 };
    494 
    495 class LambdaScopeInfo : public CapturingScopeInfo {
    496 public:
    497   /// \brief The class that describes the lambda.
    498   CXXRecordDecl *Lambda;
    499 
    500   /// \brief The class that describes the lambda.
    501   CXXMethodDecl *CallOperator;
    502 
    503   /// \brief Source range covering the lambda introducer [...].
    504   SourceRange IntroducerRange;
    505 
    506   /// \brief The number of captures in the \c Captures list that are
    507   /// explicit captures.
    508   unsigned NumExplicitCaptures;
    509 
    510   /// \brief Whether this is a mutable lambda.
    511   bool Mutable;
    512 
    513   /// \brief Whether the (empty) parameter list is explicit.
    514   bool ExplicitParams;
    515 
    516   /// \brief Whether any of the capture expressions requires cleanups.
    517   bool ExprNeedsCleanups;
    518 
    519   /// \brief Whether the lambda contains an unexpanded parameter pack.
    520   bool ContainsUnexpandedParameterPack;
    521 
    522   /// \brief Variables used to index into by-copy array captures.
    523   SmallVector<VarDecl *, 4> ArrayIndexVars;
    524 
    525   /// \brief Offsets into the ArrayIndexVars array at which each capture starts
    526   /// its list of array index variables.
    527   SmallVector<unsigned, 4> ArrayIndexStarts;
    528 
    529   LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
    530                   CXXMethodDecl *CallOperator)
    531     : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
    532       CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
    533       ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
    534   {
    535     Kind = SK_Lambda;
    536   }
    537 
    538   virtual ~LambdaScopeInfo();
    539 
    540   /// \brief Note when
    541   void finishedExplicitCaptures() {
    542     NumExplicitCaptures = Captures.size();
    543   }
    544 
    545   static bool classof(const FunctionScopeInfo *FSI) {
    546     return FSI->Kind == SK_Lambda;
    547   }
    548 };
    549 
    550 
    551 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
    552   : Base(0, false), Property(0) {}
    553 
    554 FunctionScopeInfo::WeakObjectProfileTy
    555 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
    556   FunctionScopeInfo::WeakObjectProfileTy Result;
    557   Result.Base.setInt(true);
    558   return Result;
    559 }
    560 
    561 template <typename ExprT>
    562 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
    563   assert(E);
    564   WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
    565   Uses.push_back(WeakUseTy(E, IsRead));
    566 }
    567 
    568 inline void
    569 CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
    570                                    QualType CaptureType, Expr *Cpy) {
    571   Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
    572                              Cpy));
    573   CXXThisCaptureIndex = Captures.size();
    574 
    575   if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
    576     LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
    577 }
    578 
    579 } // end namespace sema
    580 } // end namespace clang
    581 
    582 #endif
    583