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 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 
     22 namespace clang {
     23 
     24 class BlockDecl;
     25 class CXXMethodDecl;
     26 class IdentifierInfo;
     27 class LabelDecl;
     28 class ReturnStmt;
     29 class Scope;
     30 class SwitchStmt;
     31 class VarDecl;
     32 
     33 namespace sema {
     34 
     35 /// \brief Contains information about the compound statement currently being
     36 /// parsed.
     37 class CompoundScopeInfo {
     38 public:
     39   CompoundScopeInfo()
     40     : HasEmptyLoopBodies(false) { }
     41 
     42   /// \brief Whether this compound stamement contains `for' or `while' loops
     43   /// with empty bodies.
     44   bool HasEmptyLoopBodies;
     45 
     46   void setHasEmptyLoopBodies() {
     47     HasEmptyLoopBodies = true;
     48   }
     49 };
     50 
     51 class PossiblyUnreachableDiag {
     52 public:
     53   PartialDiagnostic PD;
     54   SourceLocation Loc;
     55   const Stmt *stmt;
     56 
     57   PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
     58                           const Stmt *stmt)
     59     : PD(PD), Loc(Loc), stmt(stmt) {}
     60 };
     61 
     62 /// \brief Retains information about a function, method, or block that is
     63 /// currently being parsed.
     64 class FunctionScopeInfo {
     65 protected:
     66   enum ScopeKind {
     67     SK_Function,
     68     SK_Block,
     69     SK_Lambda
     70   };
     71 
     72 public:
     73   /// \brief What kind of scope we are describing.
     74   ///
     75   ScopeKind Kind;
     76 
     77   /// \brief Whether this function contains a VLA, \@try, try, C++
     78   /// initializer, or anything else that can't be jumped past.
     79   bool HasBranchProtectedScope;
     80 
     81   /// \brief Whether this function contains any switches or direct gotos.
     82   bool HasBranchIntoScope;
     83 
     84   /// \brief Whether this function contains any indirect gotos.
     85   bool HasIndirectGoto;
     86 
     87   /// A flag that is set when parsing a -dealloc method and no [super dealloc]
     88   /// call was found yet.
     89   bool ObjCShouldCallSuperDealloc;
     90 
     91   /// A flag that is set when parsing a -finalize method and no [super finalize]
     92   /// call was found yet.
     93   bool ObjCShouldCallSuperFinalize;
     94 
     95   /// \brief Used to determine if errors occurred in this function or block.
     96   DiagnosticErrorTrap ErrorTrap;
     97 
     98   /// SwitchStack - This is the current set of active switch statements in the
     99   /// block.
    100   SmallVector<SwitchStmt*, 8> SwitchStack;
    101 
    102   /// \brief The list of return statements that occur within the function or
    103   /// block, if there is any chance of applying the named return value
    104   /// optimization, or if we need to infer a return type.
    105   SmallVector<ReturnStmt*, 4> Returns;
    106 
    107   /// \brief The stack of currently active compound stamement scopes in the
    108   /// function.
    109   SmallVector<CompoundScopeInfo, 4> CompoundScopes;
    110 
    111   /// \brief A list of PartialDiagnostics created but delayed within the
    112   /// current function scope.  These diagnostics are vetted for reachability
    113   /// prior to being emitted.
    114   SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
    115 
    116   void setHasBranchIntoScope() {
    117     HasBranchIntoScope = true;
    118   }
    119 
    120   void setHasBranchProtectedScope() {
    121     HasBranchProtectedScope = true;
    122   }
    123 
    124   void setHasIndirectGoto() {
    125     HasIndirectGoto = true;
    126   }
    127 
    128   bool NeedsScopeChecking() const {
    129     return HasIndirectGoto ||
    130           (HasBranchProtectedScope && HasBranchIntoScope);
    131   }
    132 
    133   FunctionScopeInfo(DiagnosticsEngine &Diag)
    134     : Kind(SK_Function),
    135       HasBranchProtectedScope(false),
    136       HasBranchIntoScope(false),
    137       HasIndirectGoto(false),
    138       ObjCShouldCallSuperDealloc(false),
    139       ObjCShouldCallSuperFinalize(false),
    140       ErrorTrap(Diag) { }
    141 
    142   virtual ~FunctionScopeInfo();
    143 
    144   /// \brief Clear out the information in this function scope, making it
    145   /// suitable for reuse.
    146   void Clear();
    147 
    148   static bool classof(const FunctionScopeInfo *FSI) { return true; }
    149 };
    150 
    151 class CapturingScopeInfo : public FunctionScopeInfo {
    152 public:
    153   enum ImplicitCaptureStyle {
    154     ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
    155   };
    156 
    157   ImplicitCaptureStyle ImpCaptureStyle;
    158 
    159   class Capture {
    160     // There are two categories of capture: capturing 'this', and capturing
    161     // local variables.  There are three ways to capture a local variable:
    162     // capture by copy in the C++11 sense, capture by reference
    163     // in the C++11 sense, and __block capture.  Lambdas explicitly specify
    164     // capture by copy or capture by reference.  For blocks, __block capture
    165     // applies to variables with that annotation, variables of reference type
    166     // are captured by reference, and other variables are captured by copy.
    167     enum CaptureKind {
    168       Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
    169     };
    170 
    171     // The variable being captured (if we are not capturing 'this'),
    172     // and misc bits descibing the capture.
    173     llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
    174 
    175     // Expression to initialize a field of the given type, and whether this
    176     // is a nested capture; the expression is only required if we are
    177     // capturing ByVal and the variable's type has a non-trivial
    178     // copy constructor.
    179     llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
    180 
    181     /// \brief The source location at which the first capture occurred..
    182     SourceLocation Loc;
    183 
    184     /// \brief The location of the ellipsis that expands a parameter pack.
    185     SourceLocation EllipsisLoc;
    186 
    187     /// \brief The type as it was captured, which is in effect the type of the
    188     /// non-static data member that would hold the capture.
    189     QualType CaptureType;
    190 
    191   public:
    192     Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
    193             SourceLocation Loc, SourceLocation EllipsisLoc,
    194             QualType CaptureType, Expr *Cpy)
    195       : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
    196         CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
    197         CaptureType(CaptureType){}
    198 
    199     enum IsThisCapture { ThisCapture };
    200     Capture(IsThisCapture, bool isNested, SourceLocation Loc,
    201             QualType CaptureType, Expr *Cpy)
    202       : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
    203         EllipsisLoc(), CaptureType(CaptureType) { }
    204 
    205     bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
    206     bool isVariableCapture() const { return !isThisCapture(); }
    207     bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
    208     bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
    209     bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
    210     bool isNested() { return CopyExprAndNested.getInt(); }
    211 
    212     VarDecl *getVariable() const {
    213       return VarAndKind.getPointer();
    214     }
    215 
    216     /// \brief Retrieve the location at which this variable was captured.
    217     SourceLocation getLocation() const { return Loc; }
    218 
    219     /// \brief Retrieve the source location of the ellipsis, whose presence
    220     /// indicates that the capture is a pack expansion.
    221     SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
    222 
    223     /// \brief Retrieve the capture type for this capture, which is effectively
    224     /// the type of the non-static data member in the lambda/block structure
    225     /// that would store this capture.
    226     QualType getCaptureType() const { return CaptureType; }
    227 
    228     Expr *getCopyExpr() const {
    229       return CopyExprAndNested.getPointer();
    230     }
    231   };
    232 
    233   CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
    234     : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
    235       HasImplicitReturnType(false)
    236      {}
    237 
    238   /// CaptureMap - A map of captured variables to (index+1) into Captures.
    239   llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
    240 
    241   /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
    242   /// zero if 'this' is not captured.
    243   unsigned CXXThisCaptureIndex;
    244 
    245   /// Captures - The captures.
    246   SmallVector<Capture, 4> Captures;
    247 
    248   /// \brief - Whether the target type of return statements in this context
    249   /// is deduced (e.g. a lambda or block with omitted return type).
    250   bool HasImplicitReturnType;
    251 
    252   /// ReturnType - The target type of return statements in this context,
    253   /// or null if unknown.
    254   QualType ReturnType;
    255 
    256   void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
    257                   SourceLocation Loc, SourceLocation EllipsisLoc,
    258                   QualType CaptureType, Expr *Cpy) {
    259     Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
    260                                EllipsisLoc, CaptureType, Cpy));
    261     CaptureMap[Var] = Captures.size();
    262   }
    263 
    264   void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
    265                       Expr *Cpy) {
    266     Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
    267                                Cpy));
    268     CXXThisCaptureIndex = Captures.size();
    269   }
    270 
    271   /// \brief Determine whether the C++ 'this' is captured.
    272   bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
    273 
    274   /// \brief Retrieve the capture of C++ 'this', if it has been captured.
    275   Capture &getCXXThisCapture() {
    276     assert(isCXXThisCaptured() && "this has not been captured");
    277     return Captures[CXXThisCaptureIndex - 1];
    278   }
    279 
    280   /// \brief Determine whether the given variable has been captured.
    281   bool isCaptured(VarDecl *Var) const {
    282     return CaptureMap.count(Var);
    283   }
    284 
    285   /// \brief Retrieve the capture of the given variable, if it has been
    286   /// captured already.
    287   Capture &getCapture(VarDecl *Var) {
    288     assert(isCaptured(Var) && "Variable has not been captured");
    289     return Captures[CaptureMap[Var] - 1];
    290   }
    291 
    292   const Capture &getCapture(VarDecl *Var) const {
    293     llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
    294       = CaptureMap.find(Var);
    295     assert(Known != CaptureMap.end() && "Variable has not been captured");
    296     return Captures[Known->second - 1];
    297   }
    298 
    299   static bool classof(const FunctionScopeInfo *FSI) {
    300     return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
    301   }
    302   static bool classof(const CapturingScopeInfo *BSI) { return true; }
    303 };
    304 
    305 /// \brief Retains information about a block that is currently being parsed.
    306 class BlockScopeInfo : public CapturingScopeInfo {
    307 public:
    308   BlockDecl *TheDecl;
    309 
    310   /// TheScope - This is the scope for the block itself, which contains
    311   /// arguments etc.
    312   Scope *TheScope;
    313 
    314   /// BlockType - The function type of the block, if one was given.
    315   /// Its return type may be BuiltinType::Dependent.
    316   QualType FunctionType;
    317 
    318   BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
    319     : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
    320       TheScope(BlockScope)
    321   {
    322     Kind = SK_Block;
    323   }
    324 
    325   virtual ~BlockScopeInfo();
    326 
    327   static bool classof(const FunctionScopeInfo *FSI) {
    328     return FSI->Kind == SK_Block;
    329   }
    330   static bool classof(const BlockScopeInfo *BSI) { return true; }
    331 };
    332 
    333 class LambdaScopeInfo : public CapturingScopeInfo {
    334 public:
    335   /// \brief The class that describes the lambda.
    336   CXXRecordDecl *Lambda;
    337 
    338   /// \brief The class that describes the lambda.
    339   CXXMethodDecl *CallOperator;
    340 
    341   /// \brief Source range covering the lambda introducer [...].
    342   SourceRange IntroducerRange;
    343 
    344   /// \brief The number of captures in the \c Captures list that are
    345   /// explicit captures.
    346   unsigned NumExplicitCaptures;
    347 
    348   /// \brief Whether this is a mutable lambda.
    349   bool Mutable;
    350 
    351   /// \brief Whether the (empty) parameter list is explicit.
    352   bool ExplicitParams;
    353 
    354   /// \brief Whether any of the capture expressions requires cleanups.
    355   bool ExprNeedsCleanups;
    356 
    357   /// \brief Whether the lambda contains an unexpanded parameter pack.
    358   bool ContainsUnexpandedParameterPack;
    359 
    360   /// \brief Variables used to index into by-copy array captures.
    361   llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
    362 
    363   /// \brief Offsets into the ArrayIndexVars array at which each capture starts
    364   /// its list of array index variables.
    365   llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
    366 
    367   LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
    368                   CXXMethodDecl *CallOperator)
    369     : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
    370       CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
    371       ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
    372   {
    373     Kind = SK_Lambda;
    374   }
    375 
    376   virtual ~LambdaScopeInfo();
    377 
    378   /// \brief Note when
    379   void finishedExplicitCaptures() {
    380     NumExplicitCaptures = Captures.size();
    381   }
    382 
    383   static bool classof(const FunctionScopeInfo *FSI) {
    384     return FSI->Kind == SK_Lambda;
    385   }
    386   static bool classof(const LambdaScopeInfo *BSI) { return true; }
    387 
    388 };
    389 
    390 }
    391 }
    392 
    393 #endif
    394