zcov: / include/clang/Parse/Scope.h


Files: 1 Branches Taken: 100.0% 12 / 12
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 12 / 12
Line Coverage: 95.9% 70 / 73


Programs: 30 Runs 45270


       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_PARSE_SCOPE_H
      15                 : #define LLVM_CLANG_PARSE_SCOPE_H
      16                 : 
      17                 : #include "clang/Parse/Action.h"
      18                 : #include "llvm/ADT/SmallPtrSet.h"
      19                 : 
      20                 : namespace clang {
      21                 : 
      22                 : /// Scope - A scope is a transient data structure that is used while parsing the
      23                 : /// program.  It assists with resolving identifiers to the appropriate
      24                 : /// declaration.
      25                 : ///
      26             6536: class Scope {
      27                 : public:
      28                 :   /// ScopeFlags - These are bitfields that are or'd together when creating a
      29                 :   /// scope, which defines the sorts of things the scope contains.
      30                 :   enum ScopeFlags {
      31                 :     /// FnScope - This indicates that the scope corresponds to a function, which
      32                 :     /// means that labels are set here.
      33                 :     FnScope       = 0x01,
      34                 : 
      35                 :     /// BreakScope - This is a while,do,switch,for, etc that can have break
      36                 :     /// stmts embedded into it.
      37                 :     BreakScope    = 0x02,
      38                 : 
      39                 :     /// ContinueScope - This is a while,do,for, which can have continue
      40                 :     /// stmt embedded into it.
      41                 :     ContinueScope = 0x04,
      42                 : 
      43                 :     /// DeclScope - This is a scope that can contain a declaration.  Some scopes
      44                 :     /// just contain loop constructs but don't contain decls.
      45                 :     DeclScope = 0x08,
      46                 : 
      47                 :     /// ControlScope - The controlling scope in a if/switch/while/for statement.
      48                 :     ControlScope = 0x10,
      49                 : 
      50                 :     /// ClassScope - The scope of a struct/union/class definition.
      51                 :     ClassScope = 0x20,
      52                 : 
      53                 :     /// BlockScope - This is a scope that corresponds to a block object.
      54                 :     /// Blocks serve as top-level scopes for some objects like labels, they
      55                 :     /// also prevent things like break and continue.  BlockScopes have the
      56                 :     /// other flags set as well.
      57                 :     BlockScope = 0x40,
      58                 : 
      59                 :     /// TemplateParamScope - This is a scope that corresponds to the
      60                 :     /// template parameters of a C++ template. Template parameter
      61                 :     /// scope starts at the 'template' keyword and ends when the
      62                 :     /// template declaration ends.
      63                 :     TemplateParamScope = 0x80,
      64                 : 
      65                 :     /// FunctionPrototypeScope - This is a scope that corresponds to the
      66                 :     /// parameters within a function prototype.
      67                 :     FunctionPrototypeScope = 0x100,
      68                 : 
      69                 :     /// AtCatchScope - This is a scope that corresponds to the Objective-C
      70                 :     /// @catch statement.
      71                 :     AtCatchScope = 0x200
      72                 :   };
      73                 : private:
      74                 :   /// The parent scope for this scope.  This is null for the translation-unit
      75                 :   /// scope.
      76                 :   Scope *AnyParent;
      77                 : 
      78                 :   /// Depth - This is the depth of this scope.  The translation-unit scope has
      79                 :   /// depth 0.
      80                 :   unsigned Depth : 16;
      81                 : 
      82                 :   /// Flags - This contains a set of ScopeFlags, which indicates how the scope
      83                 :   /// interrelates with other control flow statements.
      84                 :   unsigned Flags : 10;
      85                 : 
      86                 :   /// WithinElse - Whether this scope is part of the "else" branch in
      87                 :   /// its parent ControlScope.
      88                 :   bool WithinElse : 1;
      89                 : 
      90                 :   /// FnParent - If this scope has a parent scope that is a function body, this
      91                 :   /// pointer is non-null and points to it.  This is used for label processing.
      92                 :   Scope *FnParent;
      93                 : 
      94                 :   /// BreakParent/ContinueParent - This is a direct link to the immediately
      95                 :   /// preceeding BreakParent/ContinueParent if this scope is not one, or null if
      96                 :   /// there is no containing break/continue scope.
      97                 :   Scope *BreakParent, *ContinueParent;
      98                 : 
      99                 :   /// ControlParent - This is a direct link to the immediately
     100                 :   /// preceeding ControlParent if this scope is not one, or null if
     101                 :   /// there is no containing control scope.
     102                 :   Scope *ControlParent;
     103                 : 
     104                 :   /// BlockParent - This is a direct link to the immediately containing
     105                 :   /// BlockScope if this scope is not one, or null if there is none.
     106                 :   Scope *BlockParent;
     107                 : 
     108                 :   /// TemplateParamParent - This is a direct link to the
     109                 :   /// immediately containing template parameter scope. In the
     110                 :   /// case of nested templates, template parameter scopes can have
     111                 :   /// other template parameter scopes as parents.
     112                 :   Scope *TemplateParamParent;
     113                 : 
     114                 :   /// DeclsInScope - This keeps track of all declarations in this scope.  When
     115                 :   /// the declaration is added to the scope, it is set as the current
     116                 :   /// declaration for the identifier in the IdentifierTable.  When the scope is
     117                 :   /// popped, these declarations are removed from the IdentifierTable's notion
     118                 :   /// of current declaration.  It is up to the current Action implementation to
     119                 :   /// implement these semantics.
     120                 :   typedef llvm::SmallPtrSet<Action::DeclPtrTy, 32> DeclSetTy;
     121                 :   DeclSetTy DeclsInScope;
     122                 : 
     123                 :   /// Entity - The entity with which this scope is associated. For
     124                 :   /// example, the entity of a class scope is the class itself, the
     125                 :   /// entity of a function scope is a function, etc. This field is
     126                 :   /// maintained by the Action implementation.
     127                 :   void *Entity;
     128                 : 
     129                 :   typedef llvm::SmallVector<Action::DeclPtrTy, 2> UsingDirectivesTy;
     130                 :   UsingDirectivesTy UsingDirectives;
     131                 : 
     132                 : public:
     133             6536:   Scope(Scope *Parent, unsigned ScopeFlags) {
     134             6536:     Init(Parent, ScopeFlags);
     135             6536:   }
     136                 : 
     137                 :   /// getFlags - Return the flags for this scope.
     138                 :   ///
     139           117387:   unsigned getFlags() const { return Flags; }
     140                 : 
     141                 :   /// isBlockScope - Return true if this scope does not correspond to a
     142                 :   /// closure.
     143              285:   bool isBlockScope() const { return Flags & BlockScope; }
     144                 : 
     145                 :   /// getParent - Return the scope that this is nested in.
     146                 :   ///
     147               63:   const Scope *getParent() const { return AnyParent; }
     148           199933:   Scope *getParent() { return AnyParent; }
     149                 : 
     150                 :   /// getFnParent - Return the closest scope that is a function body.
     151                 :   ///
     152                 :   const Scope *getFnParent() const { return FnParent; }
     153            10044:   Scope *getFnParent() { return FnParent; }
     154                 : 
     155                 :   /// getContinueParent - Return the closest scope that a continue statement
     156                 :   /// would be affected by.  If the closest scope is a closure scope, we know
     157                 :   /// that there is no loop *inside* the closure.
     158               35:   Scope *getContinueParent() {
                       29: branch 0 taken
                        6: branch 1 taken
                       28: branch 3 taken
                        1: branch 4 taken
                       28: branch 5 taken
                        7: branch 6 taken
     159               35:     if (ContinueParent && !ContinueParent->isBlockScope())
     160               28:       return ContinueParent;
     161                7:     return 0;
     162                 :   }
     163                 : 
     164                 :   const Scope *getContinueParent() const {
     165                 :     return const_cast<Scope*>(this)->getContinueParent();
     166                 :   }
     167                 : 
     168                 :   /// getBreakParent - Return the closest scope that a break statement
     169                 :   /// would be affected by.  If the closest scope is a block scope, we know
     170                 :   /// that there is no loop *inside* the block.
     171              262:   Scope *getBreakParent() {
                      256: branch 0 taken
                        6: branch 1 taken
                      253: branch 3 taken
                        3: branch 4 taken
                      253: branch 5 taken
                        9: branch 6 taken
     172              262:     if (BreakParent && !BreakParent->isBlockScope())
     173              253:       return BreakParent;
     174                9:     return 0;
     175                 :   }
     176                 :   const Scope *getBreakParent() const {
     177                 :     return const_cast<Scope*>(this)->getBreakParent();
     178                 :   }
     179                 : 
     180              105:   Scope *getControlParent() { return ControlParent; }
     181                 :   const Scope *getControlParent() const { return ControlParent; }
     182                 : 
     183                 :   Scope *getBlockParent() { return BlockParent; }
     184                 :   const Scope *getBlockParent() const { return BlockParent; }
     185                 : 
     186                 :   Scope *getTemplateParamParent() { return TemplateParamParent; }
     187                 :   const Scope *getTemplateParamParent() const { return TemplateParamParent; }
     188                 : 
     189                 :   typedef DeclSetTy::iterator decl_iterator;
     190            23940:   decl_iterator decl_begin() const { return DeclsInScope.begin(); }
     191            23940:   decl_iterator decl_end()   const { return DeclsInScope.end(); }
     192            56855:   bool decl_empty()          const { return DeclsInScope.empty(); }
     193                 : 
     194            77962:   void AddDecl(Action::DeclPtrTy D) {
     195            77962:     DeclsInScope.insert(D);
     196            77962:   }
     197                 : 
     198              870:   void RemoveDecl(Action::DeclPtrTy D) {
     199              870:     DeclsInScope.erase(D);
     200              870:   }
     201                 : 
     202                 :   /// isDeclScope - Return true if this is the scope that the specified decl is
     203                 :   /// declared in.
     204            54967:   bool isDeclScope(Action::DeclPtrTy D) {
     205            54967:     return DeclsInScope.count(D) != 0;
     206                 :   }
     207                 : 
     208           499404:   void* getEntity() const { return Entity; }
     209            18061:   void setEntity(void *E) { Entity = E; }
     210                 : 
     211                 :   /// isClassScope - Return true if this scope is a class/struct/union scope.
     212             6136:   bool isClassScope() const {
     213             6136:     return (getFlags() & Scope::ClassScope);
     214                 :   }
     215                 : 
     216                 :   /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
     217                 :   /// method scope or is inside one.
     218                 :   bool isInCXXInlineMethodScope() const {
     219                 :     if (const Scope *FnS = getFnParent()) {
     220                 :       assert(FnS->getParent() && "TUScope not created?");
     221                 :       return FnS->getParent()->isClassScope();
     222                 :     }
     223                 :     return false;
     224                 :   }
     225                 : 
     226                 :   /// isTemplateParamScope - Return true if this scope is a C++
     227                 :   /// template parameter scope.
     228             3313:   bool isTemplateParamScope() const {
     229             3313:     return getFlags() & Scope::TemplateParamScope;
     230                 :   }
     231                 : 
     232                 :   /// isFunctionPrototypeScope - Return true if this scope is a
     233                 :   /// function prototype scope.
     234             4125:   bool isFunctionPrototypeScope() const {
     235             4125:     return getFlags() & Scope::FunctionPrototypeScope;
     236                 :   }
     237                 : 
     238                 :   /// isAtCatchScope - Return true if this scope is @catch.
     239               14:   bool isAtCatchScope() const {
     240               14:     return getFlags() & Scope::AtCatchScope;
     241                 :   }
     242                 : 
     243                 :   /// isWithinElse - Whether we are within the "else" of the
     244                 :   /// ControlParent (if any).
     245              280:   bool isWithinElse() const { return WithinElse; }
     246                 : 
     247              412:   void setWithinElse(bool WE) { WithinElse = WE; }
     248                 : 
     249                 :   typedef UsingDirectivesTy::iterator udir_iterator;
     250                 :   typedef UsingDirectivesTy::const_iterator const_udir_iterator;
     251                 : 
     252                0:   void PushUsingDirective(Action::DeclPtrTy UDir) {
     253                0:     UsingDirectives.push_back(UDir);
     254                0:   }
     255                 : 
     256            12265:   udir_iterator using_directives_begin() {
     257            12265:     return UsingDirectives.begin();
     258                 :   }
     259                 : 
     260            12265:   udir_iterator using_directives_end() {
     261            12265:     return UsingDirectives.end();
     262                 :   }
     263                 : 
     264                 :   const_udir_iterator using_directives_begin() const {
     265                 :     return UsingDirectives.begin();
     266                 :   }
     267                 : 
     268                 :   const_udir_iterator using_directives_end() const {
     269                 :     return UsingDirectives.end();
     270                 :   }
     271                 : 
     272                 :   /// Init - This is used by the parser to implement scope caching.
     273                 :   ///
     274            35381:   void Init(Scope *Parent, unsigned ScopeFlags) {
     275            35381:     AnyParent = Parent;
     276            35381:     Depth = AnyParent ? AnyParent->Depth+1 : 0;
     277            35381:     Flags = ScopeFlags;
     278            35381:     WithinElse = false;
     279                 :     
     280            35381:     if (AnyParent) {
     281            33130:       FnParent       = AnyParent->FnParent;
     282            33130:       BreakParent    = AnyParent->BreakParent;
     283            33130:       ContinueParent = AnyParent->ContinueParent;
     284            33130:       ControlParent = AnyParent->ControlParent;
     285            33130:       BlockParent  = AnyParent->BlockParent;
     286            33130:       TemplateParamParent = AnyParent->TemplateParamParent;
     287                 :     } else {
     288             2251:       FnParent = BreakParent = ContinueParent = BlockParent = 0;
     289             2251:       ControlParent = 0;
     290             2251:       TemplateParamParent = 0;
     291                 :     }
     292                 : 
     293                 :     // If this scope is a function or contains breaks/continues, remember it.
     294            35381:     if (Flags & FnScope)            FnParent = this;
     295            35381:     if (Flags & BreakScope)         BreakParent = this;
     296            35381:     if (Flags & ContinueScope)      ContinueParent = this;
     297            35381:     if (Flags & ControlScope)       ControlParent = this;
     298            35381:     if (Flags & BlockScope)         BlockParent = this;
     299            35381:     if (Flags & TemplateParamScope) TemplateParamParent = this;
     300            35381:     DeclsInScope.clear();
     301            35381:     UsingDirectives.clear();
     302            35381:     Entity = 0;
     303            35381:   }
     304                 : };
     305                 : 
     306                 : }  // end namespace clang
     307                 : 
     308                 : #endif

Generated: 2010-02-10 01:31 by zcov