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/PointerIntPair.h"
00019 #include "llvm/ADT/SmallPtrSet.h"
00020 #include "llvm/ADT/SmallVector.h"
00021 
00022 namespace llvm {
00023 
00024 class raw_ostream;
00025 
00026 }
00027 
00028 namespace clang {
00029 
00030 class Decl;
00031 class UsingDirectiveDecl;
00032 class VarDecl;
00033 
00034 /// Scope - A scope is a transient data structure that is used while parsing the
00035 /// program.  It assists with resolving identifiers to the appropriate
00036 /// declaration.
00037 ///
00038 class Scope {
00039 public:
00040   /// ScopeFlags - These are bitfields that are or'd together when creating a
00041   /// scope, which defines the sorts of things the scope contains.
00042   enum ScopeFlags {
00043     /// \brief This indicates that the scope corresponds to a function, which
00044     /// means that labels are set here.
00045     FnScope       = 0x01,
00046 
00047     /// \brief This is a while, do, switch, for, etc that can have break
00048     /// statements embedded into it.
00049     BreakScope    = 0x02,
00050 
00051     /// \brief This is a while, do, for, which can have continue statements
00052     /// embedded into it.
00053     ContinueScope = 0x04,
00054 
00055     /// \brief This is a scope that can contain a declaration.  Some scopes
00056     /// just contain loop constructs but don't contain decls.
00057     DeclScope = 0x08,
00058 
00059     /// \brief The controlling scope in a if/switch/while/for statement.
00060     ControlScope = 0x10,
00061 
00062     /// \brief The scope of a struct/union/class definition.
00063     ClassScope = 0x20,
00064 
00065     /// \brief This is a scope that corresponds to a block/closure object.
00066     /// Blocks serve as top-level scopes for some objects like labels, they
00067     /// also prevent things like break and continue.  BlockScopes always have
00068     /// the FnScope and DeclScope flags set as well.
00069     BlockScope = 0x40,
00070 
00071     /// \brief This is a scope that corresponds to the
00072     /// template parameters of a C++ template. Template parameter
00073     /// scope starts at the 'template' keyword and ends when the
00074     /// template declaration ends.
00075     TemplateParamScope = 0x80,
00076 
00077     /// \brief This is a scope that corresponds to the
00078     /// parameters within a function prototype.
00079     FunctionPrototypeScope = 0x100,
00080 
00081     /// \brief This is a scope that corresponds to the parameters within
00082     /// a function prototype for a function declaration (as opposed to any
00083     /// other kind of function declarator). Always has FunctionPrototypeScope
00084     /// set as well.
00085     FunctionDeclarationScope = 0x200,
00086 
00087     /// \brief This is a scope that corresponds to the Objective-C
00088     /// \@catch statement.
00089     AtCatchScope = 0x400,
00090     
00091     /// \brief This scope corresponds to an Objective-C method body.
00092     /// It always has FnScope and DeclScope set as well.
00093     ObjCMethodScope = 0x800,
00094 
00095     /// \brief This is a scope that corresponds to a switch statement.
00096     SwitchScope = 0x1000,
00097 
00098     /// \brief This is the scope of a C++ try statement.
00099     TryScope = 0x2000,
00100 
00101     /// \brief This is the scope for a function-level C++ try or catch scope.
00102     FnTryCatchScope = 0x4000,
00103 
00104     /// \brief This is the scope of OpenMP executable directive.
00105     OpenMPDirectiveScope = 0x8000,
00106 
00107     /// \brief This is the scope of some OpenMP loop directive.
00108     OpenMPLoopDirectiveScope = 0x10000,
00109 
00110     /// \brief This is the scope of some OpenMP simd directive.
00111     /// For example, it is used for 'omp simd', 'omp for simd'.
00112     /// This flag is propagated to children scopes.
00113     OpenMPSimdDirectiveScope = 0x20000,
00114 
00115     /// This scope corresponds to an enum.
00116     EnumScope = 0x40000,
00117 
00118     /// This scope corresponds to a SEH try.
00119     SEHTryScope = 0x80000,
00120   };
00121 private:
00122   /// The parent scope for this scope.  This is null for the translation-unit
00123   /// scope.
00124   Scope *AnyParent;
00125 
00126   /// Flags - This contains a set of ScopeFlags, which indicates how the scope
00127   /// interrelates with other control flow statements.
00128   unsigned Flags;
00129 
00130   /// Depth - This is the depth of this scope.  The translation-unit scope has
00131   /// depth 0.
00132   unsigned short Depth;
00133 
00134   /// \brief Declarations with static linkage are mangled with the number of
00135   /// scopes seen as a component.
00136   unsigned short MSLocalManglingNumber;
00137 
00138   /// PrototypeDepth - This is the number of function prototype scopes
00139   /// enclosing this scope, including this scope.
00140   unsigned short PrototypeDepth;
00141 
00142   /// PrototypeIndex - This is the number of parameters currently
00143   /// declared in this scope.
00144   unsigned short PrototypeIndex;
00145 
00146   /// FnParent - If this scope has a parent scope that is a function body, this
00147   /// pointer is non-null and points to it.  This is used for label processing.
00148   Scope *FnParent;
00149   Scope *MSLocalManglingParent;
00150 
00151   /// BreakParent/ContinueParent - This is a direct link to the innermost
00152   /// BreakScope/ContinueScope which contains the contents of this scope
00153   /// for control flow purposes (and might be this scope itself), or null
00154   /// if there is no such scope.
00155   Scope *BreakParent, *ContinueParent;
00156 
00157   /// BlockParent - This is a direct link to the immediately containing
00158   /// BlockScope if this scope is not one, or null if there is none.
00159   Scope *BlockParent;
00160 
00161   /// TemplateParamParent - This is a direct link to the
00162   /// immediately containing template parameter scope. In the
00163   /// case of nested templates, template parameter scopes can have
00164   /// other template parameter scopes as parents.
00165   Scope *TemplateParamParent;
00166 
00167   /// DeclsInScope - This keeps track of all declarations in this scope.  When
00168   /// the declaration is added to the scope, it is set as the current
00169   /// declaration for the identifier in the IdentifierTable.  When the scope is
00170   /// popped, these declarations are removed from the IdentifierTable's notion
00171   /// of current declaration.  It is up to the current Action implementation to
00172   /// implement these semantics.
00173   typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy;
00174   DeclSetTy DeclsInScope;
00175 
00176   /// The DeclContext with which this scope is associated. For
00177   /// example, the entity of a class scope is the class itself, the
00178   /// entity of a function scope is a function, etc.
00179   DeclContext *Entity;
00180 
00181   typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy;
00182   UsingDirectivesTy UsingDirectives;
00183 
00184   /// \brief Used to determine if errors occurred in this scope.
00185   DiagnosticErrorTrap ErrorTrap;
00186 
00187   /// A lattice consisting of undefined, a single NRVO candidate variable in
00188   /// this scope, or over-defined. The bit is true when over-defined.
00189   llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
00190 
00191 public:
00192   Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
00193     : ErrorTrap(Diag) {
00194     Init(Parent, ScopeFlags);
00195   }
00196 
00197   /// getFlags - Return the flags for this scope.
00198   ///
00199   unsigned getFlags() const { return Flags; }
00200   void setFlags(unsigned F) { Flags = F; }
00201 
00202   /// isBlockScope - Return true if this scope correspond to a closure.
00203   bool isBlockScope() const { return Flags & BlockScope; }
00204 
00205   /// getParent - Return the scope that this is nested in.
00206   ///
00207   const Scope *getParent() const { return AnyParent; }
00208   Scope *getParent() { return AnyParent; }
00209 
00210   /// getFnParent - Return the closest scope that is a function body.
00211   ///
00212   const Scope *getFnParent() const { return FnParent; }
00213   Scope *getFnParent() { return FnParent; }
00214 
00215   const Scope *getMSLocalManglingParent() const {
00216     return MSLocalManglingParent;
00217   }
00218   Scope *getMSLocalManglingParent() { return MSLocalManglingParent; }
00219 
00220   /// getContinueParent - Return the closest scope that a continue statement
00221   /// would be affected by.
00222   Scope *getContinueParent() {
00223     return ContinueParent;
00224   }
00225 
00226   const Scope *getContinueParent() const {
00227     return const_cast<Scope*>(this)->getContinueParent();
00228   }
00229 
00230   /// getBreakParent - Return the closest scope that a break statement
00231   /// would be affected by.
00232   Scope *getBreakParent() {
00233     return BreakParent;
00234   }
00235   const Scope *getBreakParent() const {
00236     return const_cast<Scope*>(this)->getBreakParent();
00237   }
00238 
00239   Scope *getBlockParent() { return BlockParent; }
00240   const Scope *getBlockParent() const { return BlockParent; }
00241 
00242   Scope *getTemplateParamParent() { return TemplateParamParent; }
00243   const Scope *getTemplateParamParent() const { return TemplateParamParent; }
00244 
00245   /// Returns the number of function prototype scopes in this scope
00246   /// chain.
00247   unsigned getFunctionPrototypeDepth() const {
00248     return PrototypeDepth;
00249   }
00250 
00251   /// Return the number of parameters declared in this function
00252   /// prototype, increasing it by one for the next call.
00253   unsigned getNextFunctionPrototypeIndex() {
00254     assert(isFunctionPrototypeScope());
00255     return PrototypeIndex++;
00256   }
00257 
00258   typedef llvm::iterator_range<DeclSetTy::iterator> decl_range;
00259   decl_range decls() const {
00260     return decl_range(DeclsInScope.begin(), DeclsInScope.end());
00261   }
00262   bool decl_empty() const { return DeclsInScope.empty(); }
00263 
00264   void AddDecl(Decl *D) {
00265     DeclsInScope.insert(D);
00266   }
00267 
00268   void RemoveDecl(Decl *D) {
00269     DeclsInScope.erase(D);
00270   }
00271 
00272   void incrementMSLocalManglingNumber() {
00273     if (Scope *MSLMP = getMSLocalManglingParent())
00274       MSLMP->MSLocalManglingNumber += 1;
00275   }
00276 
00277   void decrementMSLocalManglingNumber() {
00278     if (Scope *MSLMP = getMSLocalManglingParent())
00279       MSLMP->MSLocalManglingNumber -= 1;
00280   }
00281 
00282   unsigned getMSLocalManglingNumber() const {
00283     if (const Scope *MSLMP = getMSLocalManglingParent())
00284       return MSLMP->MSLocalManglingNumber;
00285     return 1;
00286   }
00287 
00288   /// isDeclScope - Return true if this is the scope that the specified decl is
00289   /// declared in.
00290   bool isDeclScope(Decl *D) {
00291     return DeclsInScope.count(D) != 0;
00292   }
00293 
00294   DeclContext *getEntity() const { return Entity; }
00295   void setEntity(DeclContext *E) { Entity = E; }
00296 
00297   bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); }
00298 
00299   bool hasUnrecoverableErrorOccurred() const {
00300     return ErrorTrap.hasUnrecoverableErrorOccurred();
00301   }
00302 
00303   /// isFunctionScope() - Return true if this scope is a function scope.
00304   bool isFunctionScope() const { return (getFlags() & Scope::FnScope); }
00305 
00306   /// isClassScope - Return true if this scope is a class/struct/union scope.
00307   bool isClassScope() const {
00308     return (getFlags() & Scope::ClassScope);
00309   }
00310 
00311   /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
00312   /// method scope or is inside one.
00313   bool isInCXXInlineMethodScope() const {
00314     if (const Scope *FnS = getFnParent()) {
00315       assert(FnS->getParent() && "TUScope not created?");
00316       return FnS->getParent()->isClassScope();
00317     }
00318     return false;
00319   }
00320   
00321   /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
00322   /// Objective-C method body.  Note that this method is not constant time.
00323   bool isInObjcMethodScope() const {
00324     for (const Scope *S = this; S; S = S->getParent()) {
00325       // If this scope is an objc method scope, then we succeed.
00326       if (S->getFlags() & ObjCMethodScope)
00327         return true;
00328     }
00329     return false;
00330   }
00331 
00332   /// isInObjcMethodOuterScope - Return true if this scope is an
00333   /// Objective-C method outer most body.
00334   bool isInObjcMethodOuterScope() const {
00335     if (const Scope *S = this) {
00336       // If this scope is an objc method scope, then we succeed.
00337       if (S->getFlags() & ObjCMethodScope)
00338         return true;
00339     }
00340     return false;
00341   }
00342 
00343   
00344   /// isTemplateParamScope - Return true if this scope is a C++
00345   /// template parameter scope.
00346   bool isTemplateParamScope() const {
00347     return getFlags() & Scope::TemplateParamScope;
00348   }
00349 
00350   /// isFunctionPrototypeScope - Return true if this scope is a
00351   /// function prototype scope.
00352   bool isFunctionPrototypeScope() const {
00353     return getFlags() & Scope::FunctionPrototypeScope;
00354   }
00355 
00356   /// isAtCatchScope - Return true if this scope is \@catch.
00357   bool isAtCatchScope() const {
00358     return getFlags() & Scope::AtCatchScope;
00359   }
00360 
00361   /// isSwitchScope - Return true if this scope is a switch scope.
00362   bool isSwitchScope() const {
00363     for (const Scope *S = this; S; S = S->getParent()) {
00364       if (S->getFlags() & Scope::SwitchScope)
00365         return true;
00366       else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
00367                                 Scope::BlockScope | Scope::TemplateParamScope |
00368                                 Scope::FunctionPrototypeScope |
00369                                 Scope::AtCatchScope | Scope::ObjCMethodScope))
00370         return false;
00371     }
00372     return false;
00373   }
00374 
00375   /// \brief Determines whether this scope is the OpenMP directive scope
00376   bool isOpenMPDirectiveScope() const {
00377     return (getFlags() & Scope::OpenMPDirectiveScope);
00378   }
00379 
00380   /// \brief Determine whether this scope is some OpenMP loop directive scope
00381   /// (for example, 'omp for', 'omp simd').
00382   bool isOpenMPLoopDirectiveScope() const {
00383     if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
00384       assert(isOpenMPDirectiveScope() &&
00385              "OpenMP loop directive scope is not a directive scope");
00386       return true;
00387     }
00388     return false;
00389   }
00390 
00391   /// \brief Determine whether this scope is (or is nested into) some OpenMP
00392   /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
00393   bool isOpenMPSimdDirectiveScope() const {
00394     return getFlags() & Scope::OpenMPSimdDirectiveScope;
00395   }
00396 
00397   /// \brief Determine whether this scope is a loop having OpenMP loop
00398   /// directive attached.
00399   bool isOpenMPLoopScope() const {
00400     const Scope *P = getParent();
00401     return P && P->isOpenMPLoopDirectiveScope();
00402   }
00403 
00404   /// \brief Determine whether this scope is a C++ 'try' block.
00405   bool isTryScope() const { return getFlags() & Scope::TryScope; }
00406 
00407   /// \brief Determine whether this scope is a SEH '__try' block.
00408   bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
00409 
00410   /// containedInPrototypeScope - Return true if this or a parent scope
00411   /// is a FunctionPrototypeScope.
00412   bool containedInPrototypeScope() const;
00413 
00414   void PushUsingDirective(UsingDirectiveDecl *UDir) {
00415     UsingDirectives.push_back(UDir);
00416   }
00417 
00418   typedef llvm::iterator_range<UsingDirectivesTy::iterator>
00419     using_directives_range;
00420 
00421   using_directives_range using_directives() {
00422     return using_directives_range(UsingDirectives.begin(),
00423                                   UsingDirectives.end());
00424   }
00425 
00426   void addNRVOCandidate(VarDecl *VD) {
00427     if (NRVO.getInt())
00428       return;
00429     if (NRVO.getPointer() == nullptr) {
00430       NRVO.setPointer(VD);
00431       return;
00432     }
00433     if (NRVO.getPointer() != VD)
00434       setNoNRVO();
00435   }
00436 
00437   void setNoNRVO() {
00438     NRVO.setInt(1);
00439     NRVO.setPointer(nullptr);
00440   }
00441 
00442   void mergeNRVOIntoParent();
00443 
00444   /// Init - This is used by the parser to implement scope caching.
00445   ///
00446   void Init(Scope *parent, unsigned flags);
00447 
00448   /// \brief Sets up the specified scope flags and adjusts the scope state
00449   /// variables accordingly.
00450   ///
00451   void AddFlags(unsigned Flags);
00452 
00453   void dumpImpl(raw_ostream &OS) const;
00454   void dump() const;
00455 };
00456 
00457 }  // end namespace clang
00458 
00459 #endif