Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- Scope.h - Scope interface --------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file defines the Scope interface.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_CLANG_SEMA_SCOPE_H
  14. #define LLVM_CLANG_SEMA_SCOPE_H
  15.  
  16. #include "clang/AST/Decl.h"
  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. #include "llvm/ADT/iterator_range.h"
  22. #include <cassert>
  23. #include <optional>
  24.  
  25. namespace llvm {
  26.  
  27. class raw_ostream;
  28.  
  29. } // namespace llvm
  30.  
  31. namespace clang {
  32.  
  33. class Decl;
  34. class DeclContext;
  35. class UsingDirectiveDecl;
  36. class VarDecl;
  37.  
  38. /// Scope - A scope is a transient data structure that is used while parsing the
  39. /// program.  It assists with resolving identifiers to the appropriate
  40. /// declaration.
  41. class Scope {
  42. public:
  43.   /// ScopeFlags - These are bitfields that are or'd together when creating a
  44.   /// scope, which defines the sorts of things the scope contains.
  45.   enum ScopeFlags {
  46.     /// This indicates that the scope corresponds to a function, which
  47.     /// means that labels are set here.
  48.     FnScope = 0x01,
  49.  
  50.     /// This is a while, do, switch, for, etc that can have break
  51.     /// statements embedded into it.
  52.     BreakScope = 0x02,
  53.  
  54.     /// This is a while, do, for, which can have continue statements
  55.     /// embedded into it.
  56.     ContinueScope = 0x04,
  57.  
  58.     /// This is a scope that can contain a declaration.  Some scopes
  59.     /// just contain loop constructs but don't contain decls.
  60.     DeclScope = 0x08,
  61.  
  62.     /// The controlling scope in a if/switch/while/for statement.
  63.     ControlScope = 0x10,
  64.  
  65.     /// The scope of a struct/union/class definition.
  66.     ClassScope = 0x20,
  67.  
  68.     /// This is a scope that corresponds to a block/closure object.
  69.     /// Blocks serve as top-level scopes for some objects like labels, they
  70.     /// also prevent things like break and continue.  BlockScopes always have
  71.     /// the FnScope and DeclScope flags set as well.
  72.     BlockScope = 0x40,
  73.  
  74.     /// This is a scope that corresponds to the
  75.     /// template parameters of a C++ template. Template parameter
  76.     /// scope starts at the 'template' keyword and ends when the
  77.     /// template declaration ends.
  78.     TemplateParamScope = 0x80,
  79.  
  80.     /// This is a scope that corresponds to the
  81.     /// parameters within a function prototype.
  82.     FunctionPrototypeScope = 0x100,
  83.  
  84.     /// This is a scope that corresponds to the parameters within
  85.     /// a function prototype for a function declaration (as opposed to any
  86.     /// other kind of function declarator). Always has FunctionPrototypeScope
  87.     /// set as well.
  88.     FunctionDeclarationScope = 0x200,
  89.  
  90.     /// This is a scope that corresponds to the Objective-C
  91.     /// \@catch statement.
  92.     AtCatchScope = 0x400,
  93.  
  94.     /// This scope corresponds to an Objective-C method body.
  95.     /// It always has FnScope and DeclScope set as well.
  96.     ObjCMethodScope = 0x800,
  97.  
  98.     /// This is a scope that corresponds to a switch statement.
  99.     SwitchScope = 0x1000,
  100.  
  101.     /// This is the scope of a C++ try statement.
  102.     TryScope = 0x2000,
  103.  
  104.     /// This is the scope for a function-level C++ try or catch scope.
  105.     FnTryCatchScope = 0x4000,
  106.  
  107.     /// This is the scope of OpenMP executable directive.
  108.     OpenMPDirectiveScope = 0x8000,
  109.  
  110.     /// This is the scope of some OpenMP loop directive.
  111.     OpenMPLoopDirectiveScope = 0x10000,
  112.  
  113.     /// This is the scope of some OpenMP simd directive.
  114.     /// For example, it is used for 'omp simd', 'omp for simd'.
  115.     /// This flag is propagated to children scopes.
  116.     OpenMPSimdDirectiveScope = 0x20000,
  117.  
  118.     /// This scope corresponds to an enum.
  119.     EnumScope = 0x40000,
  120.  
  121.     /// This scope corresponds to an SEH try.
  122.     SEHTryScope = 0x80000,
  123.  
  124.     /// This scope corresponds to an SEH except.
  125.     SEHExceptScope = 0x100000,
  126.  
  127.     /// We are currently in the filter expression of an SEH except block.
  128.     SEHFilterScope = 0x200000,
  129.  
  130.     /// This is a compound statement scope.
  131.     CompoundStmtScope = 0x400000,
  132.  
  133.     /// We are between inheritance colon and the real class/struct definition
  134.     /// scope.
  135.     ClassInheritanceScope = 0x800000,
  136.  
  137.     /// This is the scope of a C++ catch statement.
  138.     CatchScope = 0x1000000,
  139.  
  140.     /// This is a scope in which a condition variable is currently being
  141.     /// parsed. If such a scope is a ContinueScope, it's invalid to jump to the
  142.     /// continue block from here.
  143.     ConditionVarScope = 0x2000000,
  144.  
  145.     /// This is a scope of some OpenMP directive with
  146.     /// order clause which specifies concurrent
  147.     OpenMPOrderClauseScope = 0x4000000,
  148.   };
  149.  
  150. private:
  151.   /// The parent scope for this scope.  This is null for the translation-unit
  152.   /// scope.
  153.   Scope *AnyParent;
  154.  
  155.   /// Flags - This contains a set of ScopeFlags, which indicates how the scope
  156.   /// interrelates with other control flow statements.
  157.   unsigned Flags;
  158.  
  159.   /// Depth - This is the depth of this scope.  The translation-unit scope has
  160.   /// depth 0.
  161.   unsigned short Depth;
  162.  
  163.   /// Declarations with static linkage are mangled with the number of
  164.   /// scopes seen as a component.
  165.   unsigned short MSLastManglingNumber;
  166.  
  167.   unsigned short MSCurManglingNumber;
  168.  
  169.   /// PrototypeDepth - This is the number of function prototype scopes
  170.   /// enclosing this scope, including this scope.
  171.   unsigned short PrototypeDepth;
  172.  
  173.   /// PrototypeIndex - This is the number of parameters currently
  174.   /// declared in this scope.
  175.   unsigned short PrototypeIndex;
  176.  
  177.   /// FnParent - If this scope has a parent scope that is a function body, this
  178.   /// pointer is non-null and points to it.  This is used for label processing.
  179.   Scope *FnParent;
  180.   Scope *MSLastManglingParent;
  181.  
  182.   /// BreakParent/ContinueParent - This is a direct link to the innermost
  183.   /// BreakScope/ContinueScope which contains the contents of this scope
  184.   /// for control flow purposes (and might be this scope itself), or null
  185.   /// if there is no such scope.
  186.   Scope *BreakParent, *ContinueParent;
  187.  
  188.   /// BlockParent - This is a direct link to the immediately containing
  189.   /// BlockScope if this scope is not one, or null if there is none.
  190.   Scope *BlockParent;
  191.  
  192.   /// TemplateParamParent - This is a direct link to the
  193.   /// immediately containing template parameter scope. In the
  194.   /// case of nested templates, template parameter scopes can have
  195.   /// other template parameter scopes as parents.
  196.   Scope *TemplateParamParent;
  197.  
  198.   /// DeclsInScope - This keeps track of all declarations in this scope.  When
  199.   /// the declaration is added to the scope, it is set as the current
  200.   /// declaration for the identifier in the IdentifierTable.  When the scope is
  201.   /// popped, these declarations are removed from the IdentifierTable's notion
  202.   /// of current declaration.  It is up to the current Action implementation to
  203.   /// implement these semantics.
  204.   using DeclSetTy = llvm::SmallPtrSet<Decl *, 32>;
  205.   DeclSetTy DeclsInScope;
  206.  
  207.   /// The DeclContext with which this scope is associated. For
  208.   /// example, the entity of a class scope is the class itself, the
  209.   /// entity of a function scope is a function, etc.
  210.   DeclContext *Entity;
  211.  
  212.   using UsingDirectivesTy = SmallVector<UsingDirectiveDecl *, 2>;
  213.   UsingDirectivesTy UsingDirectives;
  214.  
  215.   /// Used to determine if errors occurred in this scope.
  216.   DiagnosticErrorTrap ErrorTrap;
  217.  
  218.   /// A single NRVO candidate variable in this scope.
  219.   /// There are three possible values:
  220.   ///  1) pointer to VarDecl that denotes NRVO candidate itself.
  221.   ///  2) nullptr value means that NRVO is not allowed in this scope
  222.   ///     (e.g. return a function parameter).
  223.   ///  3) std::nullopt value means that there is no NRVO candidate in this scope
  224.   ///     (i.e. there are no return statements in this scope).
  225.   std::optional<VarDecl *> NRVO;
  226.  
  227.   /// Represents return slots for NRVO candidates in the current scope.
  228.   /// If a variable is present in this set, it means that a return slot is
  229.   /// available for this variable in the current scope.
  230.   llvm::SmallPtrSet<VarDecl *, 8> ReturnSlots;
  231.  
  232.   void setFlags(Scope *Parent, unsigned F);
  233.  
  234. public:
  235.   Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
  236.       : ErrorTrap(Diag) {
  237.     Init(Parent, ScopeFlags);
  238.   }
  239.  
  240.   /// getFlags - Return the flags for this scope.
  241.   unsigned getFlags() const { return Flags; }
  242.  
  243.   void setFlags(unsigned F) { setFlags(getParent(), F); }
  244.  
  245.   /// isBlockScope - Return true if this scope correspond to a closure.
  246.   bool isBlockScope() const { return Flags & BlockScope; }
  247.  
  248.   /// getParent - Return the scope that this is nested in.
  249.   const Scope *getParent() const { return AnyParent; }
  250.   Scope *getParent() { return AnyParent; }
  251.  
  252.   /// getFnParent - Return the closest scope that is a function body.
  253.   const Scope *getFnParent() const { return FnParent; }
  254.   Scope *getFnParent() { return FnParent; }
  255.  
  256.   const Scope *getMSLastManglingParent() const {
  257.     return MSLastManglingParent;
  258.   }
  259.   Scope *getMSLastManglingParent() { return MSLastManglingParent; }
  260.  
  261.   /// getContinueParent - Return the closest scope that a continue statement
  262.   /// would be affected by.
  263.   Scope *getContinueParent() {
  264.     return ContinueParent;
  265.   }
  266.  
  267.   const Scope *getContinueParent() const {
  268.     return const_cast<Scope*>(this)->getContinueParent();
  269.   }
  270.  
  271.   // Set whether we're in the scope of a condition variable, where 'continue'
  272.   // is disallowed despite being a continue scope.
  273.   void setIsConditionVarScope(bool InConditionVarScope) {
  274.     Flags = (Flags & ~ConditionVarScope) |
  275.             (InConditionVarScope ? ConditionVarScope : 0);
  276.   }
  277.  
  278.   bool isConditionVarScope() const {
  279.     return Flags & ConditionVarScope;
  280.   }
  281.  
  282.   /// getBreakParent - Return the closest scope that a break statement
  283.   /// would be affected by.
  284.   Scope *getBreakParent() {
  285.     return BreakParent;
  286.   }
  287.   const Scope *getBreakParent() const {
  288.     return const_cast<Scope*>(this)->getBreakParent();
  289.   }
  290.  
  291.   Scope *getBlockParent() { return BlockParent; }
  292.   const Scope *getBlockParent() const { return BlockParent; }
  293.  
  294.   Scope *getTemplateParamParent() { return TemplateParamParent; }
  295.   const Scope *getTemplateParamParent() const { return TemplateParamParent; }
  296.  
  297.   /// Returns the depth of this scope. The translation-unit has scope depth 0.
  298.   unsigned getDepth() const { return Depth; }
  299.  
  300.   /// Returns the number of function prototype scopes in this scope
  301.   /// chain.
  302.   unsigned getFunctionPrototypeDepth() const {
  303.     return PrototypeDepth;
  304.   }
  305.  
  306.   /// Return the number of parameters declared in this function
  307.   /// prototype, increasing it by one for the next call.
  308.   unsigned getNextFunctionPrototypeIndex() {
  309.     assert(isFunctionPrototypeScope());
  310.     return PrototypeIndex++;
  311.   }
  312.  
  313.   using decl_range = llvm::iterator_range<DeclSetTy::iterator>;
  314.  
  315.   decl_range decls() const {
  316.     return decl_range(DeclsInScope.begin(), DeclsInScope.end());
  317.   }
  318.  
  319.   bool decl_empty() const { return DeclsInScope.empty(); }
  320.  
  321.   void AddDecl(Decl *D) {
  322.     if (auto *VD = dyn_cast<VarDecl>(D))
  323.       if (!isa<ParmVarDecl>(VD))
  324.         ReturnSlots.insert(VD);
  325.  
  326.     DeclsInScope.insert(D);
  327.   }
  328.  
  329.   void RemoveDecl(Decl *D) { DeclsInScope.erase(D); }
  330.  
  331.   void incrementMSManglingNumber() {
  332.     if (Scope *MSLMP = getMSLastManglingParent()) {
  333.       MSLMP->MSLastManglingNumber += 1;
  334.       MSCurManglingNumber += 1;
  335.     }
  336.   }
  337.  
  338.   void decrementMSManglingNumber() {
  339.     if (Scope *MSLMP = getMSLastManglingParent()) {
  340.       MSLMP->MSLastManglingNumber -= 1;
  341.       MSCurManglingNumber -= 1;
  342.     }
  343.   }
  344.  
  345.   unsigned getMSLastManglingNumber() const {
  346.     if (const Scope *MSLMP = getMSLastManglingParent())
  347.       return MSLMP->MSLastManglingNumber;
  348.     return 1;
  349.   }
  350.  
  351.   unsigned getMSCurManglingNumber() const {
  352.     return MSCurManglingNumber;
  353.   }
  354.  
  355.   /// isDeclScope - Return true if this is the scope that the specified decl is
  356.   /// declared in.
  357.   bool isDeclScope(const Decl *D) const { return DeclsInScope.contains(D); }
  358.  
  359.   /// Get the entity corresponding to this scope.
  360.   DeclContext *getEntity() const {
  361.     return isTemplateParamScope() ? nullptr : Entity;
  362.   }
  363.  
  364.   /// Get the DeclContext in which to continue unqualified lookup after a
  365.   /// lookup in this scope.
  366.   DeclContext *getLookupEntity() const { return Entity; }
  367.  
  368.   void setEntity(DeclContext *E) {
  369.     assert(!isTemplateParamScope() &&
  370.            "entity associated with template param scope");
  371.     Entity = E;
  372.   }
  373.   void setLookupEntity(DeclContext *E) { Entity = E; }
  374.  
  375.   /// Determine whether any unrecoverable errors have occurred within this
  376.   /// scope. Note that this may return false even if the scope contains invalid
  377.   /// declarations or statements, if the errors for those invalid constructs
  378.   /// were suppressed because some prior invalid construct was referenced.
  379.   bool hasUnrecoverableErrorOccurred() const {
  380.     return ErrorTrap.hasUnrecoverableErrorOccurred();
  381.   }
  382.  
  383.   /// isFunctionScope() - Return true if this scope is a function scope.
  384.   bool isFunctionScope() const { return getFlags() & Scope::FnScope; }
  385.  
  386.   /// isClassScope - Return true if this scope is a class/struct/union scope.
  387.   bool isClassScope() const { return getFlags() & Scope::ClassScope; }
  388.  
  389.   /// Determines whether this scope is between inheritance colon and the real
  390.   /// class/struct definition.
  391.   bool isClassInheritanceScope() const {
  392.     return getFlags() & Scope::ClassInheritanceScope;
  393.   }
  394.  
  395.   /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
  396.   /// method scope or is inside one.
  397.   bool isInCXXInlineMethodScope() const {
  398.     if (const Scope *FnS = getFnParent()) {
  399.       assert(FnS->getParent() && "TUScope not created?");
  400.       return FnS->getParent()->isClassScope();
  401.     }
  402.     return false;
  403.   }
  404.  
  405.   /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
  406.   /// Objective-C method body.  Note that this method is not constant time.
  407.   bool isInObjcMethodScope() const {
  408.     for (const Scope *S = this; S; S = S->getParent()) {
  409.       // If this scope is an objc method scope, then we succeed.
  410.       if (S->getFlags() & ObjCMethodScope)
  411.         return true;
  412.     }
  413.     return false;
  414.   }
  415.  
  416.   /// isInObjcMethodOuterScope - Return true if this scope is an
  417.   /// Objective-C method outer most body.
  418.   bool isInObjcMethodOuterScope() const {
  419.     if (const Scope *S = this) {
  420.       // If this scope is an objc method scope, then we succeed.
  421.       if (S->getFlags() & ObjCMethodScope)
  422.         return true;
  423.     }
  424.     return false;
  425.   }
  426.  
  427.   /// isTemplateParamScope - Return true if this scope is a C++
  428.   /// template parameter scope.
  429.   bool isTemplateParamScope() const {
  430.     return getFlags() & Scope::TemplateParamScope;
  431.   }
  432.  
  433.   /// isFunctionPrototypeScope - Return true if this scope is a
  434.   /// function prototype scope.
  435.   bool isFunctionPrototypeScope() const {
  436.     return getFlags() & Scope::FunctionPrototypeScope;
  437.   }
  438.  
  439.   /// isFunctionDeclarationScope - Return true if this scope is a
  440.   /// function prototype scope.
  441.   bool isFunctionDeclarationScope() const {
  442.     return getFlags() & Scope::FunctionDeclarationScope;
  443.   }
  444.  
  445.   /// isAtCatchScope - Return true if this scope is \@catch.
  446.   bool isAtCatchScope() const {
  447.     return getFlags() & Scope::AtCatchScope;
  448.   }
  449.  
  450.   /// isCatchScope - Return true if this scope is a C++ catch statement.
  451.   bool isCatchScope() const { return getFlags() & Scope::CatchScope; }
  452.  
  453.   /// isSwitchScope - Return true if this scope is a switch scope.
  454.   bool isSwitchScope() const {
  455.     for (const Scope *S = this; S; S = S->getParent()) {
  456.       if (S->getFlags() & Scope::SwitchScope)
  457.         return true;
  458.       else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
  459.                                 Scope::BlockScope | Scope::TemplateParamScope |
  460.                                 Scope::FunctionPrototypeScope |
  461.                                 Scope::AtCatchScope | Scope::ObjCMethodScope))
  462.         return false;
  463.     }
  464.     return false;
  465.   }
  466.  
  467.   /// Determines whether this scope is the OpenMP directive scope
  468.   bool isOpenMPDirectiveScope() const {
  469.     return (getFlags() & Scope::OpenMPDirectiveScope);
  470.   }
  471.  
  472.   /// Determine whether this scope is some OpenMP loop directive scope
  473.   /// (for example, 'omp for', 'omp simd').
  474.   bool isOpenMPLoopDirectiveScope() const {
  475.     if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
  476.       assert(isOpenMPDirectiveScope() &&
  477.              "OpenMP loop directive scope is not a directive scope");
  478.       return true;
  479.     }
  480.     return false;
  481.   }
  482.  
  483.   /// Determine whether this scope is (or is nested into) some OpenMP
  484.   /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
  485.   bool isOpenMPSimdDirectiveScope() const {
  486.     return getFlags() & Scope::OpenMPSimdDirectiveScope;
  487.   }
  488.  
  489.   /// Determine whether this scope is a loop having OpenMP loop
  490.   /// directive attached.
  491.   bool isOpenMPLoopScope() const {
  492.     const Scope *P = getParent();
  493.     return P && P->isOpenMPLoopDirectiveScope();
  494.   }
  495.  
  496.   /// Determine whether this scope is some OpenMP directive with
  497.   /// order clause which specifies concurrent scope.
  498.   bool isOpenMPOrderClauseScope() const {
  499.     return getFlags() & Scope::OpenMPOrderClauseScope;
  500.   }
  501.  
  502.   /// Determine whether this scope is a while/do/for statement, which can have
  503.   /// continue statements embedded into it.
  504.   bool isContinueScope() const {
  505.     return getFlags() & ScopeFlags::ContinueScope;
  506.   }
  507.  
  508.   /// Determine whether this scope is a C++ 'try' block.
  509.   bool isTryScope() const { return getFlags() & Scope::TryScope; }
  510.  
  511.   /// Determine whether this scope is a function-level C++ try or catch scope.
  512.   bool isFnTryCatchScope() const {
  513.     return getFlags() & ScopeFlags::FnTryCatchScope;
  514.   }
  515.  
  516.   /// Determine whether this scope is a SEH '__try' block.
  517.   bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
  518.  
  519.   /// Determine whether this scope is a SEH '__except' block.
  520.   bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }
  521.  
  522.   /// Determine whether this scope is a compound statement scope.
  523.   bool isCompoundStmtScope() const {
  524.     return getFlags() & Scope::CompoundStmtScope;
  525.   }
  526.  
  527.   /// Determine whether this scope is a controlling scope in a
  528.   /// if/switch/while/for statement.
  529.   bool isControlScope() const { return getFlags() & Scope::ControlScope; }
  530.  
  531.   /// Returns if rhs has a higher scope depth than this.
  532.   ///
  533.   /// The caller is responsible for calling this only if one of the two scopes
  534.   /// is an ancestor of the other.
  535.   bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; }
  536.  
  537.   /// containedInPrototypeScope - Return true if this or a parent scope
  538.   /// is a FunctionPrototypeScope.
  539.   bool containedInPrototypeScope() const;
  540.  
  541.   void PushUsingDirective(UsingDirectiveDecl *UDir) {
  542.     UsingDirectives.push_back(UDir);
  543.   }
  544.  
  545.   using using_directives_range =
  546.       llvm::iterator_range<UsingDirectivesTy::iterator>;
  547.  
  548.   using_directives_range using_directives() {
  549.     return using_directives_range(UsingDirectives.begin(),
  550.                                   UsingDirectives.end());
  551.   }
  552.  
  553.   void updateNRVOCandidate(VarDecl *VD);
  554.  
  555.   void applyNRVO();
  556.  
  557.   /// Init - This is used by the parser to implement scope caching.
  558.   void Init(Scope *parent, unsigned flags);
  559.  
  560.   /// Sets up the specified scope flags and adjusts the scope state
  561.   /// variables accordingly.
  562.   void AddFlags(unsigned Flags);
  563.  
  564.   void dumpImpl(raw_ostream &OS) const;
  565.   void dump() const;
  566. };
  567.  
  568. } // namespace clang
  569.  
  570. #endif // LLVM_CLANG_SEMA_SCOPE_H
  571.