diff options
author | Stefan Gränitz <stefan.graenitz@gmail.com> | 2024-03-07 14:27:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-07 14:27:04 +0100 |
commit | 4b70d17bcffaffd75a5d8c420396f8dc755b4652 (patch) | |
tree | dc0e10a86c18a13597048ceeb51a1ba33f00dacc /clang/lib/Parse/ParseDecl.cpp | |
parent | 464d9d96b3565ead06396ffb8d02b4dcf9cb9556 (diff) | |
download | llvm-4b70d17bcffaffd75a5d8c420396f8dc755b4652.zip llvm-4b70d17bcffaffd75a5d8c420396f8dc755b4652.tar.gz llvm-4b70d17bcffaffd75a5d8c420396f8dc755b4652.tar.bz2 |
[clang-repl] Names declared in if conditions and for-init statements are local to the inner context (#84150)
Make TopLevelStmtDecl a DeclContext so that variables defined in statements
are attached to the TopLevelDeclContext. This fixes redefinition errors
from variables declared in if conditions and for-init statements. These
must be local to the inner context (C++ 3.3.2p4), but they had generated
definitions on global scope instead.
This PR makes the TopLevelStmtDecl looking more like a FunctionDecl and
that's fine because the FunctionDecl is very close in terms of semantics.
Additionally, ActOnForStmt() requires a CompoundScope when processing a
NullStmt body.
---------
Co-authored-by: Vassil Vassilev <v.g.vassilev@gmail.com>
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 81f1c71..64b234e 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -5678,24 +5678,32 @@ Parser::DeclGroupPtrTy Parser::ParseTopLevelStmtDecl() { // Parse a top-level-stmt. Parser::StmtVector Stmts; ParsedStmtContext SubStmtCtx = ParsedStmtContext(); - Actions.PushFunctionScope(); + ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); + TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(getCurScope()); StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx); - Actions.PopFunctionScopeInfo(); if (!R.isUsable()) return nullptr; - SmallVector<Decl *, 2> DeclsInGroup; - DeclsInGroup.push_back(Actions.ActOnTopLevelStmtDecl(R.get())); + Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get()); if (Tok.is(tok::annot_repl_input_end) && Tok.getAnnotationValue() != nullptr) { ConsumeAnnotationToken(); - cast<TopLevelStmtDecl>(DeclsInGroup.back())->setSemiMissing(); + TLSD->setSemiMissing(); } - // Currently happens for things like -fms-extensions and use `__if_exists`. - for (Stmt *S : Stmts) - DeclsInGroup.push_back(Actions.ActOnTopLevelStmtDecl(S)); + SmallVector<Decl *, 2> DeclsInGroup; + DeclsInGroup.push_back(TLSD); + + // Currently happens for things like -fms-extensions and use `__if_exists`. + for (Stmt *S : Stmts) { + // Here we should be safe as `__if_exists` and friends are not introducing + // new variables which need to live outside file scope. + TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(getCurScope()); + Actions.ActOnFinishTopLevelStmtDecl(D, S); + DeclsInGroup.push_back(D); + } return Actions.BuildDeclaratorGroup(DeclsInGroup); } |