diff options
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/Sema/Scope.h')
-rw-r--r-- | contrib/llvm-project/clang/include/clang/Sema/Scope.h | 92 |
1 files changed, 64 insertions, 28 deletions
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Scope.h b/contrib/llvm-project/clang/include/clang/Sema/Scope.h index b499ba1e7c2a..9e81706cd2aa 100644 --- a/contrib/llvm-project/clang/include/clang/Sema/Scope.h +++ b/contrib/llvm-project/clang/include/clang/Sema/Scope.h @@ -20,6 +20,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator_range.h" #include <cassert> +#include <optional> namespace llvm { @@ -44,11 +45,11 @@ public: enum ScopeFlags { /// This indicates that the scope corresponds to a function, which /// means that labels are set here. - FnScope = 0x01, + FnScope = 0x01, /// This is a while, do, switch, for, etc that can have break /// statements embedded into it. - BreakScope = 0x02, + BreakScope = 0x02, /// This is a while, do, for, which can have continue statements /// embedded into it. @@ -140,6 +141,15 @@ public: /// parsed. If such a scope is a ContinueScope, it's invalid to jump to the /// continue block from here. ConditionVarScope = 0x2000000, + + /// This is a scope of some OpenMP directive with + /// order clause which specifies concurrent + OpenMPOrderClauseScope = 0x4000000, + /// This is the scope for a lambda, after the lambda introducer. + /// Lambdas need two FunctionPrototypeScope scopes (because there is a + /// template scope in between), the outer scope does not increase the + /// depth of recursion. + LambdaScope = 0x8000000, }; private: @@ -210,9 +220,19 @@ private: /// Used to determine if errors occurred in this scope. DiagnosticErrorTrap ErrorTrap; - /// A lattice consisting of undefined, a single NRVO candidate variable in - /// this scope, or over-defined. The bit is true when over-defined. - llvm::PointerIntPair<VarDecl *, 1, bool> NRVO; + /// A single NRVO candidate variable in this scope. + /// There are three possible values: + /// 1) pointer to VarDecl that denotes NRVO candidate itself. + /// 2) nullptr value means that NRVO is not allowed in this scope + /// (e.g. return a function parameter). + /// 3) std::nullopt value means that there is no NRVO candidate in this scope + /// (i.e. there are no return statements in this scope). + std::optional<VarDecl *> NRVO; + + /// Represents return slots for NRVO candidates in the current scope. + /// If a variable is present in this set, it means that a return slot is + /// available for this variable in the current scope. + llvm::SmallPtrSet<VarDecl *, 8> ReturnSlots; void setFlags(Scope *Parent, unsigned F); @@ -304,12 +324,14 @@ public: bool decl_empty() const { return DeclsInScope.empty(); } void AddDecl(Decl *D) { + if (auto *VD = dyn_cast<VarDecl>(D)) + if (!isa<ParmVarDecl>(VD)) + ReturnSlots.insert(VD); + DeclsInScope.insert(D); } - void RemoveDecl(Decl *D) { - DeclsInScope.erase(D); - } + void RemoveDecl(Decl *D) { DeclsInScope.erase(D); } void incrementMSManglingNumber() { if (Scope *MSLMP = getMSLastManglingParent()) { @@ -337,7 +359,7 @@ public: /// isDeclScope - Return true if this is the scope that the specified decl is /// declared in. - bool isDeclScope(const Decl *D) const { return DeclsInScope.count(D) != 0; } + bool isDeclScope(const Decl *D) const { return DeclsInScope.contains(D); } /// Get the entity corresponding to this scope. DeclContext *getEntity() const { @@ -364,11 +386,15 @@ public: } /// isFunctionScope() - Return true if this scope is a function scope. - bool isFunctionScope() const { return (getFlags() & Scope::FnScope); } + bool isFunctionScope() const { return getFlags() & Scope::FnScope; } /// isClassScope - Return true if this scope is a class/struct/union scope. - bool isClassScope() const { - return (getFlags() & Scope::ClassScope); + bool isClassScope() const { return getFlags() & Scope::ClassScope; } + + /// Determines whether this scope is between inheritance colon and the real + /// class/struct definition. + bool isClassInheritanceScope() const { + return getFlags() & Scope::ClassInheritanceScope; } /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline @@ -426,6 +452,9 @@ public: return getFlags() & Scope::AtCatchScope; } + /// isCatchScope - Return true if this scope is a C++ catch statement. + bool isCatchScope() const { return getFlags() & Scope::CatchScope; } + /// isSwitchScope - Return true if this scope is a switch scope. bool isSwitchScope() const { for (const Scope *S = this; S; S = S->getParent()) { @@ -469,9 +498,26 @@ public: return P && P->isOpenMPLoopDirectiveScope(); } + /// Determine whether this scope is some OpenMP directive with + /// order clause which specifies concurrent scope. + bool isOpenMPOrderClauseScope() const { + return getFlags() & Scope::OpenMPOrderClauseScope; + } + + /// Determine whether this scope is a while/do/for statement, which can have + /// continue statements embedded into it. + bool isContinueScope() const { + return getFlags() & ScopeFlags::ContinueScope; + } + /// Determine whether this scope is a C++ 'try' block. bool isTryScope() const { return getFlags() & Scope::TryScope; } + /// Determine whether this scope is a function-level C++ try or catch scope. + bool isFnTryCatchScope() const { + return getFlags() & ScopeFlags::FnTryCatchScope; + } + /// Determine whether this scope is a SEH '__try' block. bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; } @@ -483,6 +529,10 @@ public: return getFlags() & Scope::CompoundStmtScope; } + /// Determine whether this scope is a controlling scope in a + /// if/switch/while/for statement. + bool isControlScope() const { return getFlags() & Scope::ControlScope; } + /// Returns if rhs has a higher scope depth than this. /// /// The caller is responsible for calling this only if one of the two scopes @@ -505,23 +555,9 @@ public: UsingDirectives.end()); } - void addNRVOCandidate(VarDecl *VD) { - if (NRVO.getInt()) - return; - if (NRVO.getPointer() == nullptr) { - NRVO.setPointer(VD); - return; - } - if (NRVO.getPointer() != VD) - setNoNRVO(); - } - - void setNoNRVO() { - NRVO.setInt(true); - NRVO.setPointer(nullptr); - } + void updateNRVOCandidate(VarDecl *VD); - void mergeNRVOIntoParent(); + void applyNRVO(); /// Init - This is used by the parser to implement scope caching. void Init(Scope *parent, unsigned flags); |