Home | History | Annotate | Download | only in Sema
      1 //===--- Scope.h - Scope interface ------------------------------*- 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 the Scope interface.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_SEMA_SCOPE_H
     15 #define LLVM_CLANG_SEMA_SCOPE_H
     16 
     17 #include "clang/Basic/Diagnostic.h"
     18 #include "llvm/ADT/PointerIntPair.h"
     19 #include "llvm/ADT/SmallPtrSet.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 
     22 namespace llvm {
     23 
     24 class raw_ostream;
     25 
     26 }
     27 
     28 namespace clang {
     29 
     30 class Decl;
     31 class UsingDirectiveDecl;
     32 class VarDecl;
     33 
     34 /// Scope - A scope is a transient data structure that is used while parsing the
     35 /// program.  It assists with resolving identifiers to the appropriate
     36 /// declaration.
     37 ///
     38 class Scope {
     39 public:
     40   /// ScopeFlags - These are bitfields that are or'd together when creating a
     41   /// scope, which defines the sorts of things the scope contains.
     42   enum ScopeFlags {
     43     /// \brief This indicates that the scope corresponds to a function, which
     44     /// means that labels are set here.
     45     FnScope       = 0x01,
     46 
     47     /// \brief This is a while, do, switch, for, etc that can have break
     48     /// statements embedded into it.
     49     BreakScope    = 0x02,
     50 
     51     /// \brief This is a while, do, for, which can have continue statements
     52     /// embedded into it.
     53     ContinueScope = 0x04,
     54 
     55     /// \brief This is a scope that can contain a declaration.  Some scopes
     56     /// just contain loop constructs but don't contain decls.
     57     DeclScope = 0x08,
     58 
     59     /// \brief The controlling scope in a if/switch/while/for statement.
     60     ControlScope = 0x10,
     61 
     62     /// \brief The scope of a struct/union/class definition.
     63     ClassScope = 0x20,
     64 
     65     /// \brief This is a scope that corresponds to a block/closure object.
     66     /// Blocks serve as top-level scopes for some objects like labels, they
     67     /// also prevent things like break and continue.  BlockScopes always have
     68     /// the FnScope and DeclScope flags set as well.
     69     BlockScope = 0x40,
     70 
     71     /// \brief This is a scope that corresponds to the
     72     /// template parameters of a C++ template. Template parameter
     73     /// scope starts at the 'template' keyword and ends when the
     74     /// template declaration ends.
     75     TemplateParamScope = 0x80,
     76 
     77     /// \brief This is a scope that corresponds to the
     78     /// parameters within a function prototype.
     79     FunctionPrototypeScope = 0x100,
     80 
     81     /// \brief This is a scope that corresponds to the parameters within
     82     /// a function prototype for a function declaration (as opposed to any
     83     /// other kind of function declarator). Always has FunctionPrototypeScope
     84     /// set as well.
     85     FunctionDeclarationScope = 0x200,
     86 
     87     /// \brief This is a scope that corresponds to the Objective-C
     88     /// \@catch statement.
     89     AtCatchScope = 0x400,
     90 
     91     /// \brief This scope corresponds to an Objective-C method body.
     92     /// It always has FnScope and DeclScope set as well.
     93     ObjCMethodScope = 0x800,
     94 
     95     /// \brief This is a scope that corresponds to a switch statement.
     96     SwitchScope = 0x1000,
     97 
     98     /// \brief This is the scope of a C++ try statement.
     99     TryScope = 0x2000,
    100 
    101     /// \brief This is the scope for a function-level C++ try or catch scope.
    102     FnTryCatchScope = 0x4000,
    103 
    104     /// \brief This is the scope of OpenMP executable directive.
    105     OpenMPDirectiveScope = 0x8000,
    106 
    107     /// \brief This is the scope of some OpenMP loop directive.
    108     OpenMPLoopDirectiveScope = 0x10000,
    109 
    110     /// \brief This is the scope of some OpenMP simd directive.
    111     /// For example, it is used for 'omp simd', 'omp for simd'.
    112     /// This flag is propagated to children scopes.
    113     OpenMPSimdDirectiveScope = 0x20000,
    114 
    115     /// This scope corresponds to an enum.
    116     EnumScope = 0x40000,
    117 
    118     /// This scope corresponds to an SEH try.
    119     SEHTryScope = 0x80000,
    120 
    121     /// This scope corresponds to an SEH except.
    122     SEHExceptScope = 0x100000,
    123 
    124     /// We are currently in the filter expression of an SEH except block.
    125     SEHFilterScope = 0x200000,
    126   };
    127 private:
    128   /// The parent scope for this scope.  This is null for the translation-unit
    129   /// scope.
    130   Scope *AnyParent;
    131 
    132   /// Flags - This contains a set of ScopeFlags, which indicates how the scope
    133   /// interrelates with other control flow statements.
    134   unsigned Flags;
    135 
    136   /// Depth - This is the depth of this scope.  The translation-unit scope has
    137   /// depth 0.
    138   unsigned short Depth;
    139 
    140   /// \brief Declarations with static linkage are mangled with the number of
    141   /// scopes seen as a component.
    142   unsigned short MSLastManglingNumber;
    143 
    144   unsigned short MSCurManglingNumber;
    145 
    146   /// PrototypeDepth - This is the number of function prototype scopes
    147   /// enclosing this scope, including this scope.
    148   unsigned short PrototypeDepth;
    149 
    150   /// PrototypeIndex - This is the number of parameters currently
    151   /// declared in this scope.
    152   unsigned short PrototypeIndex;
    153 
    154   /// FnParent - If this scope has a parent scope that is a function body, this
    155   /// pointer is non-null and points to it.  This is used for label processing.
    156   Scope *FnParent;
    157   Scope *MSLastManglingParent;
    158 
    159   /// BreakParent/ContinueParent - This is a direct link to the innermost
    160   /// BreakScope/ContinueScope which contains the contents of this scope
    161   /// for control flow purposes (and might be this scope itself), or null
    162   /// if there is no such scope.
    163   Scope *BreakParent, *ContinueParent;
    164 
    165   /// BlockParent - This is a direct link to the immediately containing
    166   /// BlockScope if this scope is not one, or null if there is none.
    167   Scope *BlockParent;
    168 
    169   /// TemplateParamParent - This is a direct link to the
    170   /// immediately containing template parameter scope. In the
    171   /// case of nested templates, template parameter scopes can have
    172   /// other template parameter scopes as parents.
    173   Scope *TemplateParamParent;
    174 
    175   /// DeclsInScope - This keeps track of all declarations in this scope.  When
    176   /// the declaration is added to the scope, it is set as the current
    177   /// declaration for the identifier in the IdentifierTable.  When the scope is
    178   /// popped, these declarations are removed from the IdentifierTable's notion
    179   /// of current declaration.  It is up to the current Action implementation to
    180   /// implement these semantics.
    181   typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy;
    182   DeclSetTy DeclsInScope;
    183 
    184   /// The DeclContext with which this scope is associated. For
    185   /// example, the entity of a class scope is the class itself, the
    186   /// entity of a function scope is a function, etc.
    187   DeclContext *Entity;
    188 
    189   typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy;
    190   UsingDirectivesTy UsingDirectives;
    191 
    192   /// \brief Used to determine if errors occurred in this scope.
    193   DiagnosticErrorTrap ErrorTrap;
    194 
    195   /// A lattice consisting of undefined, a single NRVO candidate variable in
    196   /// this scope, or over-defined. The bit is true when over-defined.
    197   llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
    198 
    199 public:
    200   Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
    201     : ErrorTrap(Diag) {
    202     Init(Parent, ScopeFlags);
    203   }
    204 
    205   /// getFlags - Return the flags for this scope.
    206   ///
    207   unsigned getFlags() const { return Flags; }
    208   void setFlags(unsigned F) { Flags = F; }
    209 
    210   /// isBlockScope - Return true if this scope correspond to a closure.
    211   bool isBlockScope() const { return Flags & BlockScope; }
    212 
    213   /// getParent - Return the scope that this is nested in.
    214   ///
    215   const Scope *getParent() const { return AnyParent; }
    216   Scope *getParent() { return AnyParent; }
    217 
    218   /// getFnParent - Return the closest scope that is a function body.
    219   ///
    220   const Scope *getFnParent() const { return FnParent; }
    221   Scope *getFnParent() { return FnParent; }
    222 
    223   const Scope *getMSLastManglingParent() const {
    224     return MSLastManglingParent;
    225   }
    226   Scope *getMSLastManglingParent() { return MSLastManglingParent; }
    227 
    228   /// getContinueParent - Return the closest scope that a continue statement
    229   /// would be affected by.
    230   Scope *getContinueParent() {
    231     return ContinueParent;
    232   }
    233 
    234   const Scope *getContinueParent() const {
    235     return const_cast<Scope*>(this)->getContinueParent();
    236   }
    237 
    238   /// getBreakParent - Return the closest scope that a break statement
    239   /// would be affected by.
    240   Scope *getBreakParent() {
    241     return BreakParent;
    242   }
    243   const Scope *getBreakParent() const {
    244     return const_cast<Scope*>(this)->getBreakParent();
    245   }
    246 
    247   Scope *getBlockParent() { return BlockParent; }
    248   const Scope *getBlockParent() const { return BlockParent; }
    249 
    250   Scope *getTemplateParamParent() { return TemplateParamParent; }
    251   const Scope *getTemplateParamParent() const { return TemplateParamParent; }
    252 
    253   /// Returns the number of function prototype scopes in this scope
    254   /// chain.
    255   unsigned getFunctionPrototypeDepth() const {
    256     return PrototypeDepth;
    257   }
    258 
    259   /// Return the number of parameters declared in this function
    260   /// prototype, increasing it by one for the next call.
    261   unsigned getNextFunctionPrototypeIndex() {
    262     assert(isFunctionPrototypeScope());
    263     return PrototypeIndex++;
    264   }
    265 
    266   typedef llvm::iterator_range<DeclSetTy::iterator> decl_range;
    267   decl_range decls() const {
    268     return decl_range(DeclsInScope.begin(), DeclsInScope.end());
    269   }
    270   bool decl_empty() const { return DeclsInScope.empty(); }
    271 
    272   void AddDecl(Decl *D) {
    273     DeclsInScope.insert(D);
    274   }
    275 
    276   void RemoveDecl(Decl *D) {
    277     DeclsInScope.erase(D);
    278   }
    279 
    280   void incrementMSManglingNumber() {
    281     if (Scope *MSLMP = getMSLastManglingParent()) {
    282       MSLMP->MSLastManglingNumber += 1;
    283       MSCurManglingNumber += 1;
    284     }
    285   }
    286 
    287   void decrementMSManglingNumber() {
    288     if (Scope *MSLMP = getMSLastManglingParent()) {
    289       MSLMP->MSLastManglingNumber -= 1;
    290       MSCurManglingNumber -= 1;
    291     }
    292   }
    293 
    294   unsigned getMSLastManglingNumber() const {
    295     if (const Scope *MSLMP = getMSLastManglingParent())
    296       return MSLMP->MSLastManglingNumber;
    297     return 1;
    298   }
    299 
    300   unsigned getMSCurManglingNumber() const {
    301     return MSCurManglingNumber;
    302   }
    303 
    304   /// isDeclScope - Return true if this is the scope that the specified decl is
    305   /// declared in.
    306   bool isDeclScope(Decl *D) {
    307     return DeclsInScope.count(D) != 0;
    308   }
    309 
    310   DeclContext *getEntity() const { return Entity; }
    311   void setEntity(DeclContext *E) { Entity = E; }
    312 
    313   bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); }
    314 
    315   bool hasUnrecoverableErrorOccurred() const {
    316     return ErrorTrap.hasUnrecoverableErrorOccurred();
    317   }
    318 
    319   /// isFunctionScope() - Return true if this scope is a function scope.
    320   bool isFunctionScope() const { return (getFlags() & Scope::FnScope); }
    321 
    322   /// isClassScope - Return true if this scope is a class/struct/union scope.
    323   bool isClassScope() const {
    324     return (getFlags() & Scope::ClassScope);
    325   }
    326 
    327   /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
    328   /// method scope or is inside one.
    329   bool isInCXXInlineMethodScope() const {
    330     if (const Scope *FnS = getFnParent()) {
    331       assert(FnS->getParent() && "TUScope not created?");
    332       return FnS->getParent()->isClassScope();
    333     }
    334     return false;
    335   }
    336 
    337   /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
    338   /// Objective-C method body.  Note that this method is not constant time.
    339   bool isInObjcMethodScope() const {
    340     for (const Scope *S = this; S; S = S->getParent()) {
    341       // If this scope is an objc method scope, then we succeed.
    342       if (S->getFlags() & ObjCMethodScope)
    343         return true;
    344     }
    345     return false;
    346   }
    347 
    348   /// isInObjcMethodOuterScope - Return true if this scope is an
    349   /// Objective-C method outer most body.
    350   bool isInObjcMethodOuterScope() const {
    351     if (const Scope *S = this) {
    352       // If this scope is an objc method scope, then we succeed.
    353       if (S->getFlags() & ObjCMethodScope)
    354         return true;
    355     }
    356     return false;
    357   }
    358 
    359 
    360   /// isTemplateParamScope - Return true if this scope is a C++
    361   /// template parameter scope.
    362   bool isTemplateParamScope() const {
    363     return getFlags() & Scope::TemplateParamScope;
    364   }
    365 
    366   /// isFunctionPrototypeScope - Return true if this scope is a
    367   /// function prototype scope.
    368   bool isFunctionPrototypeScope() const {
    369     return getFlags() & Scope::FunctionPrototypeScope;
    370   }
    371 
    372   /// isAtCatchScope - Return true if this scope is \@catch.
    373   bool isAtCatchScope() const {
    374     return getFlags() & Scope::AtCatchScope;
    375   }
    376 
    377   /// isSwitchScope - Return true if this scope is a switch scope.
    378   bool isSwitchScope() const {
    379     for (const Scope *S = this; S; S = S->getParent()) {
    380       if (S->getFlags() & Scope::SwitchScope)
    381         return true;
    382       else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
    383                                 Scope::BlockScope | Scope::TemplateParamScope |
    384                                 Scope::FunctionPrototypeScope |
    385                                 Scope::AtCatchScope | Scope::ObjCMethodScope))
    386         return false;
    387     }
    388     return false;
    389   }
    390 
    391   /// \brief Determines whether this scope is the OpenMP directive scope
    392   bool isOpenMPDirectiveScope() const {
    393     return (getFlags() & Scope::OpenMPDirectiveScope);
    394   }
    395 
    396   /// \brief Determine whether this scope is some OpenMP loop directive scope
    397   /// (for example, 'omp for', 'omp simd').
    398   bool isOpenMPLoopDirectiveScope() const {
    399     if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
    400       assert(isOpenMPDirectiveScope() &&
    401              "OpenMP loop directive scope is not a directive scope");
    402       return true;
    403     }
    404     return false;
    405   }
    406 
    407   /// \brief Determine whether this scope is (or is nested into) some OpenMP
    408   /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
    409   bool isOpenMPSimdDirectiveScope() const {
    410     return getFlags() & Scope::OpenMPSimdDirectiveScope;
    411   }
    412 
    413   /// \brief Determine whether this scope is a loop having OpenMP loop
    414   /// directive attached.
    415   bool isOpenMPLoopScope() const {
    416     const Scope *P = getParent();
    417     return P && P->isOpenMPLoopDirectiveScope();
    418   }
    419 
    420   /// \brief Determine whether this scope is a C++ 'try' block.
    421   bool isTryScope() const { return getFlags() & Scope::TryScope; }
    422 
    423   /// \brief Determine whether this scope is a SEH '__try' block.
    424   bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
    425 
    426   /// \brief Determine whether this scope is a SEH '__except' block.
    427   bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }
    428 
    429   /// \brief Returns if rhs has a higher scope depth than this.
    430   ///
    431   /// The caller is responsible for calling this only if one of the two scopes
    432   /// is an ancestor of the other.
    433   bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; }
    434 
    435   /// containedInPrototypeScope - Return true if this or a parent scope
    436   /// is a FunctionPrototypeScope.
    437   bool containedInPrototypeScope() const;
    438 
    439   void PushUsingDirective(UsingDirectiveDecl *UDir) {
    440     UsingDirectives.push_back(UDir);
    441   }
    442 
    443   typedef llvm::iterator_range<UsingDirectivesTy::iterator>
    444     using_directives_range;
    445 
    446   using_directives_range using_directives() {
    447     return using_directives_range(UsingDirectives.begin(),
    448                                   UsingDirectives.end());
    449   }
    450 
    451   void addNRVOCandidate(VarDecl *VD) {
    452     if (NRVO.getInt())
    453       return;
    454     if (NRVO.getPointer() == nullptr) {
    455       NRVO.setPointer(VD);
    456       return;
    457     }
    458     if (NRVO.getPointer() != VD)
    459       setNoNRVO();
    460   }
    461 
    462   void setNoNRVO() {
    463     NRVO.setInt(1);
    464     NRVO.setPointer(nullptr);
    465   }
    466 
    467   void mergeNRVOIntoParent();
    468 
    469   /// Init - This is used by the parser to implement scope caching.
    470   ///
    471   void Init(Scope *parent, unsigned flags);
    472 
    473   /// \brief Sets up the specified scope flags and adjusts the scope state
    474   /// variables accordingly.
    475   ///
    476   void AddFlags(unsigned Flags);
    477 
    478   void dumpImpl(raw_ostream &OS) const;
    479   void dump() const;
    480 };
    481 
    482 }  // end namespace clang
    483 
    484 #endif
    485