clang API Documentation

Scope.h
Go to the documentation of this file.
00001 //===--- Scope.h - Scope interface ------------------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the Scope interface.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_SEMA_SCOPE_H
00015 #define LLVM_CLANG_SEMA_SCOPE_H
00016 
00017 #include "clang/Basic/Diagnostic.h"
00018 #include "llvm/ADT/SmallPtrSet.h"
00019 #include "llvm/ADT/SmallVector.h"
00020 
00021 namespace clang {
00022 
00023 class Decl;
00024 class UsingDirectiveDecl;
00025 
00026 /// Scope - A scope is a transient data structure that is used while parsing the
00027 /// program.  It assists with resolving identifiers to the appropriate
00028 /// declaration.
00029 ///
00030 class Scope {
00031 public:
00032   /// ScopeFlags - These are bitfields that are or'd together when creating a
00033   /// scope, which defines the sorts of things the scope contains.
00034   enum ScopeFlags {
00035     /// FnScope - This indicates that the scope corresponds to a function, which
00036     /// means that labels are set here.
00037     FnScope       = 0x01,
00038 
00039     /// BreakScope - This is a while,do,switch,for, etc that can have break
00040     /// stmts embedded into it.
00041     BreakScope    = 0x02,
00042 
00043     /// ContinueScope - This is a while,do,for, which can have continue
00044     /// stmt embedded into it.
00045     ContinueScope = 0x04,
00046 
00047     /// DeclScope - This is a scope that can contain a declaration.  Some scopes
00048     /// just contain loop constructs but don't contain decls.
00049     DeclScope = 0x08,
00050 
00051     /// ControlScope - The controlling scope in a if/switch/while/for statement.
00052     ControlScope = 0x10,
00053 
00054     /// ClassScope - The scope of a struct/union/class definition.
00055     ClassScope = 0x20,
00056 
00057     /// BlockScope - This is a scope that corresponds to a block/closure object.
00058     /// Blocks serve as top-level scopes for some objects like labels, they
00059     /// also prevent things like break and continue.  BlockScopes always have
00060     /// the FnScope and DeclScope flags set as well.
00061     BlockScope = 0x40,
00062 
00063     /// TemplateParamScope - This is a scope that corresponds to the
00064     /// template parameters of a C++ template. Template parameter
00065     /// scope starts at the 'template' keyword and ends when the
00066     /// template declaration ends.
00067     TemplateParamScope = 0x80,
00068 
00069     /// FunctionPrototypeScope - This is a scope that corresponds to the
00070     /// parameters within a function prototype.
00071     FunctionPrototypeScope = 0x100,
00072 
00073     /// AtCatchScope - This is a scope that corresponds to the Objective-C
00074     /// @catch statement.
00075     AtCatchScope = 0x200,
00076     
00077     /// ObjCMethodScope - This scope corresponds to an Objective-C method body.
00078     /// It always has FnScope and DeclScope set as well.
00079     ObjCMethodScope = 0x400,
00080 
00081     /// SwitchScope - This is a scope that corresponds to a switch statement.
00082     SwitchScope = 0x800,
00083 
00084     /// TryScope - This is the scope of a C++ try statement.
00085     TryScope = 0x1000
00086   };
00087 private:
00088   /// The parent scope for this scope.  This is null for the translation-unit
00089   /// scope.
00090   Scope *AnyParent;
00091 
00092   /// Depth - This is the depth of this scope.  The translation-unit scope has
00093   /// depth 0.
00094   unsigned short Depth;
00095 
00096   /// Flags - This contains a set of ScopeFlags, which indicates how the scope
00097   /// interrelates with other control flow statements.
00098   unsigned short Flags;
00099 
00100   /// PrototypeDepth - This is the number of function prototype scopes
00101   /// enclosing this scope, including this scope.
00102   unsigned short PrototypeDepth;
00103 
00104   /// PrototypeIndex - This is the number of parameters currently
00105   /// declared in this scope.
00106   unsigned short PrototypeIndex;
00107 
00108   /// FnParent - If this scope has a parent scope that is a function body, this
00109   /// pointer is non-null and points to it.  This is used for label processing.
00110   Scope *FnParent;
00111 
00112   /// BreakParent/ContinueParent - This is a direct link to the innermost
00113   /// BreakScope/ContinueScope which contains the contents of this scope
00114   /// for control flow purposes (and might be this scope itself), or null
00115   /// if there is no such scope.
00116   Scope *BreakParent, *ContinueParent;
00117 
00118   /// BlockParent - This is a direct link to the immediately containing
00119   /// BlockScope if this scope is not one, or null if there is none.
00120   Scope *BlockParent;
00121 
00122   /// TemplateParamParent - This is a direct link to the
00123   /// immediately containing template parameter scope. In the
00124   /// case of nested templates, template parameter scopes can have
00125   /// other template parameter scopes as parents.
00126   Scope *TemplateParamParent;
00127 
00128   /// DeclsInScope - This keeps track of all declarations in this scope.  When
00129   /// the declaration is added to the scope, it is set as the current
00130   /// declaration for the identifier in the IdentifierTable.  When the scope is
00131   /// popped, these declarations are removed from the IdentifierTable's notion
00132   /// of current declaration.  It is up to the current Action implementation to
00133   /// implement these semantics.
00134   typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy;
00135   DeclSetTy DeclsInScope;
00136 
00137   /// Entity - The entity with which this scope is associated. For
00138   /// example, the entity of a class scope is the class itself, the
00139   /// entity of a function scope is a function, etc. This field is
00140   /// maintained by the Action implementation.
00141   void *Entity;
00142 
00143   typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy;
00144   UsingDirectivesTy UsingDirectives;
00145 
00146   /// \brief Used to determine if errors occurred in this scope.
00147   DiagnosticErrorTrap ErrorTrap;
00148   
00149 public:
00150   Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
00151     : ErrorTrap(Diag) {
00152     Init(Parent, ScopeFlags);
00153   }
00154 
00155   /// getFlags - Return the flags for this scope.
00156   ///
00157   unsigned getFlags() const { return Flags; }
00158   void setFlags(unsigned F) { Flags = F; }
00159 
00160   /// isBlockScope - Return true if this scope correspond to a closure.
00161   bool isBlockScope() const { return Flags & BlockScope; }
00162 
00163   /// getParent - Return the scope that this is nested in.
00164   ///
00165   const Scope *getParent() const { return AnyParent; }
00166   Scope *getParent() { return AnyParent; }
00167 
00168   /// getFnParent - Return the closest scope that is a function body.
00169   ///
00170   const Scope *getFnParent() const { return FnParent; }
00171   Scope *getFnParent() { return FnParent; }
00172 
00173   /// getContinueParent - Return the closest scope that a continue statement
00174   /// would be affected by.
00175   Scope *getContinueParent() {
00176     return ContinueParent;
00177   }
00178 
00179   const Scope *getContinueParent() const {
00180     return const_cast<Scope*>(this)->getContinueParent();
00181   }
00182 
00183   /// getBreakParent - Return the closest scope that a break statement
00184   /// would be affected by.
00185   Scope *getBreakParent() {
00186     return BreakParent;
00187   }
00188   const Scope *getBreakParent() const {
00189     return const_cast<Scope*>(this)->getBreakParent();
00190   }
00191 
00192   Scope *getBlockParent() { return BlockParent; }
00193   const Scope *getBlockParent() const { return BlockParent; }
00194 
00195   Scope *getTemplateParamParent() { return TemplateParamParent; }
00196   const Scope *getTemplateParamParent() const { return TemplateParamParent; }
00197 
00198   /// Returns the number of function prototype scopes in this scope
00199   /// chain.
00200   unsigned getFunctionPrototypeDepth() const {
00201     return PrototypeDepth;
00202   }
00203 
00204   /// Return the number of parameters declared in this function
00205   /// prototype, increasing it by one for the next call.
00206   unsigned getNextFunctionPrototypeIndex() {
00207     assert(isFunctionPrototypeScope());
00208     return PrototypeIndex++;
00209   }
00210 
00211   typedef DeclSetTy::iterator decl_iterator;
00212   decl_iterator decl_begin() const { return DeclsInScope.begin(); }
00213   decl_iterator decl_end()   const { return DeclsInScope.end(); }
00214   bool decl_empty()          const { return DeclsInScope.empty(); }
00215 
00216   void AddDecl(Decl *D) {
00217     DeclsInScope.insert(D);
00218   }
00219 
00220   void RemoveDecl(Decl *D) {
00221     DeclsInScope.erase(D);
00222   }
00223 
00224   /// isDeclScope - Return true if this is the scope that the specified decl is
00225   /// declared in.
00226   bool isDeclScope(Decl *D) {
00227     return DeclsInScope.count(D) != 0;
00228   }
00229 
00230   void* getEntity() const { return Entity; }
00231   void setEntity(void *E) { Entity = E; }
00232 
00233   bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); }
00234                            
00235   /// isClassScope - Return true if this scope is a class/struct/union scope.
00236   bool isClassScope() const {
00237     return (getFlags() & Scope::ClassScope);
00238   }
00239 
00240   /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
00241   /// method scope or is inside one.
00242   bool isInCXXInlineMethodScope() const {
00243     if (const Scope *FnS = getFnParent()) {
00244       assert(FnS->getParent() && "TUScope not created?");
00245       return FnS->getParent()->isClassScope();
00246     }
00247     return false;
00248   }
00249   
00250   /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
00251   /// Objective-C method body.  Note that this method is not constant time.
00252   bool isInObjcMethodScope() const {
00253     for (const Scope *S = this; S; S = S->getParent()) {
00254       // If this scope is an objc method scope, then we succeed.
00255       if (S->getFlags() & ObjCMethodScope)
00256         return true;
00257     }
00258     return false;
00259   }
00260 
00261   /// isTemplateParamScope - Return true if this scope is a C++
00262   /// template parameter scope.
00263   bool isTemplateParamScope() const {
00264     return getFlags() & Scope::TemplateParamScope;
00265   }
00266 
00267   /// isFunctionPrototypeScope - Return true if this scope is a
00268   /// function prototype scope.
00269   bool isFunctionPrototypeScope() const {
00270     return getFlags() & Scope::FunctionPrototypeScope;
00271   }
00272 
00273   /// isAtCatchScope - Return true if this scope is @catch.
00274   bool isAtCatchScope() const {
00275     return getFlags() & Scope::AtCatchScope;
00276   }
00277 
00278   /// isSwitchScope - Return true if this scope is a switch scope.
00279   bool isSwitchScope() const {
00280     for (const Scope *S = this; S; S = S->getParent()) {
00281       if (S->getFlags() & Scope::SwitchScope)
00282         return true;
00283       else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
00284                                 Scope::BlockScope | Scope::TemplateParamScope |
00285                                 Scope::FunctionPrototypeScope |
00286                                 Scope::AtCatchScope | Scope::ObjCMethodScope))
00287         return false;
00288     }
00289     return false;
00290   }
00291   
00292   /// \brief Determine whether this scope is a C++ 'try' block.
00293   bool isTryScope() const { return getFlags() & Scope::TryScope; }
00294 
00295   /// containedInPrototypeScope - Return true if this or a parent scope
00296   /// is a FunctionPrototypeScope.
00297   bool containedInPrototypeScope() const;
00298 
00299   typedef UsingDirectivesTy::iterator udir_iterator;
00300   typedef UsingDirectivesTy::const_iterator const_udir_iterator;
00301 
00302   void PushUsingDirective(UsingDirectiveDecl *UDir) {
00303     UsingDirectives.push_back(UDir);
00304   }
00305 
00306   udir_iterator using_directives_begin() {
00307     return UsingDirectives.begin();
00308   }
00309 
00310   udir_iterator using_directives_end() {
00311     return UsingDirectives.end();
00312   }
00313 
00314   const_udir_iterator using_directives_begin() const {
00315     return UsingDirectives.begin();
00316   }
00317 
00318   const_udir_iterator using_directives_end() const {
00319     return UsingDirectives.end();
00320   }
00321 
00322   /// Init - This is used by the parser to implement scope caching.
00323   ///
00324   void Init(Scope *parent, unsigned flags);
00325 };
00326 
00327 }  // end namespace clang
00328 
00329 #endif