Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 2 additions & 83 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,6 @@ class Parser : public CodeCompletionHandler {
const Token &getCurToken() const { return Tok; }
Scope *getCurScope() const { return Actions.getCurScope(); }

void incrementMSManglingNumber() const {
return Actions.incrementMSManglingNumber();
}

// Type forwarding. All of these are statically 'void*', but they may all be
// different actual classes based on the actions in place.
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
Expand Down Expand Up @@ -384,78 +380,6 @@ class Parser : public CodeCompletionHandler {
return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
}

//===--------------------------------------------------------------------===//
// Scope manipulation

/// ParseScope - Introduces a new scope for parsing. The kind of
/// scope is determined by ScopeFlags. Objects of this type should
/// be created on the stack to coincide with the position where the
/// parser enters the new scope, and this object's constructor will
/// create that new scope. Similarly, once the object is destroyed
/// the parser will exit the scope.
class ParseScope {
Parser *Self;
ParseScope(const ParseScope &) = delete;
void operator=(const ParseScope &) = delete;

public:
// ParseScope - Construct a new object to manage a scope in the
// parser Self where the new Scope is created with the flags
// ScopeFlags, but only when we aren't about to enter a compound statement.
ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
bool BeforeCompoundStmt = false)
: Self(Self) {
if (EnteredScope && !BeforeCompoundStmt)
Self->EnterScope(ScopeFlags);
else {
if (BeforeCompoundStmt)
Self->incrementMSManglingNumber();

this->Self = nullptr;
}
}

// Exit - Exit the scope associated with this object now, rather
// than waiting until the object is destroyed.
void Exit() {
if (Self) {
Self->ExitScope();
Self = nullptr;
}
}

~ParseScope() { Exit(); }
};

/// Introduces zero or more scopes for parsing. The scopes will all be exited
/// when the object is destroyed.
class MultiParseScope {
Parser &Self;
unsigned NumScopes = 0;

MultiParseScope(const MultiParseScope &) = delete;

public:
MultiParseScope(Parser &Self) : Self(Self) {}
void Enter(unsigned ScopeFlags) {
Self.EnterScope(ScopeFlags);
++NumScopes;
}
void Exit() {
while (NumScopes) {
Self.ExitScope();
--NumScopes;
}
}
~MultiParseScope() { Exit(); }
};

/// EnterScope - Start a new scope.
void EnterScope(unsigned ScopeFlags);

/// ExitScope - Pop a scope off the scope stack.
void ExitScope();

//===--------------------------------------------------------------------===//
// Diagnostic Emission and Error recovery.

Expand Down Expand Up @@ -546,11 +470,6 @@ class Parser : public CodeCompletionHandler {

StackExhaustionHandler StackHandler;

/// ScopeCache - Cache scopes to reduce malloc traffic.
static constexpr int ScopeCacheSize = 16;
unsigned NumCachedScopes;
Scope *ScopeCache[ScopeCacheSize];

/// Identifiers used for SEH handling in Borland. These are only
/// allowed in particular circumstances
// __except block
Expand Down Expand Up @@ -2532,7 +2451,7 @@ class Parser : public CodeCompletionHandler {
assert(SS.isSet() && "C++ scope was not set!");

CreatedScope = true;
P.EnterScope(0); // Not a decl scope.
P.Actions.EnterScope(0); // Not a decl scope.

if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.getCurScope(), SS))
EnteredScope = true;
Expand All @@ -2544,7 +2463,7 @@ class Parser : public CodeCompletionHandler {
P.Actions.ActOnCXXExitDeclaratorScope(P.getCurScope(), SS);
}
if (CreatedScope)
P.ExitScope();
P.Actions.ExitScope();
}
};

Expand Down
41 changes: 40 additions & 1 deletion clang/include/clang/Sema/Scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ class raw_ostream;
} // namespace llvm

namespace clang {

class Decl;
class DeclContext;
class UsingDirectiveDecl;
class VarDecl;
class Sema;

/// Scope - A scope is a transient data structure that is used while parsing the
/// program. It assists with resolving identifiers to the appropriate
Expand Down Expand Up @@ -667,6 +667,45 @@ class Scope {
void dump() const;
};

/// ParseScope - Introduces a new scope for parsing. The kind of
/// scope is determined by ScopeFlags. Objects of this type should
/// be created on the stack to coincide with the position where the
/// parser enters the new scope, and this object's constructor will
/// create that new scope. Similarly, once the object is destroyed
/// the parser will exit the scope.
class ParseScope {
Sema *S;
ParseScope(const ParseScope &) = delete;
void operator=(const ParseScope &) = delete;

public:
// ParseScope - Construct a new object to manage a scope in the
// parser Self where the new Scope is created with the flags
// ScopeFlags, but only when we aren't about to enter a compound statement.
ParseScope(Sema &S, unsigned ScopeFlags, bool EnteredScope = true,
bool BeforeCompoundStmt = false);

// Exit - Exit the scope associated with this object now, rather
// than waiting until the object is destroyed.
void Exit();

~ParseScope() { Exit(); }
};

/// Introduces zero or more scopes for parsing. The scopes will all be exited
/// when the object is destroyed.
class MultiParseScope {
Sema &S;
unsigned NumScopes = 0;

MultiParseScope(const MultiParseScope &) = delete;

public:
MultiParseScope(Sema &S) : S(S) {}
void Enter(unsigned ScopeFlags);
void Exit();
~MultiParseScope() { Exit(); }
};
} // namespace clang

#endif // LLVM_CLANG_SEMA_SCOPE_H
51 changes: 48 additions & 3 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,15 @@ class Sema final : public SemaBase {
/// Scope actions.
void ActOnTranslationUnitScope(Scope *S);

/// EnterScope - Start a new scope.
void EnterScope(unsigned ScopeFlags);

/// ExitScope - Pop a scope off the scope stack.
void ExitScope();

/// Delete the scope stack and all cached scopes.
void FreeScopes();

/// Determine whether \param D is function like (function or function
/// template) for parsing.
bool isDeclaratorFunctionLike(Declarator &D);
Expand Down Expand Up @@ -1575,10 +1584,12 @@ class Sema final : public SemaBase {
sema::SemaPPCallbacks *SemaPPCallbackHandler;

/// The parser's current scope.
///
/// The parser maintains this state here.
Scope *CurScope;

/// ScopeCache - Cache scopes to reduce malloc traffic.
static constexpr unsigned MaxScopeCacheSize = 16;
SmallVector<std::unique_ptr<Scope>, MaxScopeCacheSize> ScopeCache;

mutable IdentifierInfo *Ident_super;

std::unique_ptr<SemaAMDGPU> AMDGPUPtr;
Expand Down Expand Up @@ -4218,7 +4229,7 @@ class Sema final : public SemaBase {
TopLevelStmtDecl *ActOnStartTopLevelStmtDecl(Scope *S);
void ActOnFinishTopLevelStmtDecl(TopLevelStmtDecl *D, Stmt *Statement);

void ActOnPopScope(SourceLocation Loc, Scope *S);
void ActOnPopScope(Scope *S);

/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
Expand Down Expand Up @@ -11066,6 +11077,37 @@ class Sema final : public SemaBase {
BuildForRangeKind Kind,
ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps = {});

/// Set the type of a for-range declaration whose for-range or expansion
/// initialiser is dependent.
void ActOnDependentForRangeInitializer(VarDecl *LoopVar,
BuildForRangeKind BFRK);

/// Holds the 'begin' and 'end' variables of a range-based for loop or
/// expansion statement; begin-expr and end-expr are also provided; the
/// latter are used in some diagnostics.
struct ForRangeBeginEndInfo {
VarDecl *BeginVar = nullptr;
VarDecl *EndVar = nullptr;
Expr *BeginExpr = nullptr;
Expr *EndExpr = nullptr;
bool isValid() const { return BeginVar != nullptr && EndVar != nullptr; }
};

/// Determine begin-expr and end-expr and build variable declarations for
/// them as per [stmt.ranged].
ForRangeBeginEndInfo BuildCXXForRangeBeginEndVars(
Scope *S, VarDecl *RangeVar, SourceLocation ColonLoc,
SourceLocation CoawaitLoc,
ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps,
BuildForRangeKind Kind, bool Constexpr,
StmtResult *RebuildResult = nullptr,
llvm::function_ref<StmtResult()> RebuildWithDereference = {});

/// Build the range variable of a range-based for loop or iterating
/// expansion statement and return its DeclStmt.
StmtResult BuildCXXForRangeRangeVar(Scope *S, Expr *Range, QualType Type,
bool Constexpr = false);

/// FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
/// This is a separate step from ActOnCXXForRangeStmt because analysis of the
/// body cannot be performed until after the type of the range variable is
Expand Down Expand Up @@ -11207,6 +11249,9 @@ class Sema final : public SemaBase {
SourceLocation Loc,
unsigned NumParams);

void ApplyForRangeOrExpansionStatementLifetimeExtension(
VarDecl *RangeVar, ArrayRef<MaterializeTemporaryExpr *> Temporaries);

private:
/// Check whether the given statement can have musttail applied to it,
/// issuing a diagnostic and returning false if not.
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Interpreter/IncrementalParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ IncrementalParser::ParseOrWrapTopLevelDecl() {
P->ConsumeAnyToken();
// FIXME: Clang does not call ExitScope on finalizing the regular TU, we
// might want to do that around HandleEndOfTranslationUnit.
P->ExitScope();
S.ExitScope();
S.CurContext = nullptr;
// Start a new PTU.
P->EnterScope(Scope::DeclScope);
S.EnterScope(Scope::DeclScope);
S.ActOnTranslationUnitScope(P->getCurScope());
}

Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Parse/ParseCXXInlineMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@ struct Parser::ReenterTemplateScopeRAII {
TemplateParameterDepthRAII CurTemplateDepthTracker;

ReenterTemplateScopeRAII(Parser &P, Decl *MaybeTemplated, bool Enter = true)
: P(P), Scopes(P), CurTemplateDepthTracker(P.TemplateParameterDepth) {
: P(P), Scopes(P.Actions),
CurTemplateDepthTracker(P.TemplateParameterDepth) {
if (Enter) {
CurTemplateDepthTracker.addDepth(
P.ReenterTemplateScopes(Scopes, MaybeTemplated));
Expand Down Expand Up @@ -510,7 +511,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
// };
// Setup the CurScope to match the function DeclContext - we have such
// assumption in IsInFnTryBlockHandler().
ParseScope FnScope(this, Scope::FnScope);
ParseScope FnScope(Actions, Scope::FnScope);
Sema::ContextRAII FnContext(Actions, FunctionToPush,
/*NewThisContext=*/false);
Sema::FunctionScopeRAII PopFnContext(Actions);
Expand Down Expand Up @@ -597,8 +598,8 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {

// Parse the method body. Function body parsing code is similar enough
// to be re-used for method bodies as well.
ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |
Scope::CompoundStmtScope);
ParseScope FnScope(Actions, Scope::FnScope | Scope::DeclScope |
Scope::CompoundStmtScope);
Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);

Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
Expand Down
Loading
Loading