aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorStefan Gränitz <stefan.graenitz@gmail.com>2024-03-07 14:27:04 +0100
committerGitHub <noreply@github.com>2024-03-07 14:27:04 +0100
commit4b70d17bcffaffd75a5d8c420396f8dc755b4652 (patch)
treedc0e10a86c18a13597048ceeb51a1ba33f00dacc /clang/lib/Parse/ParseDecl.cpp
parent464d9d96b3565ead06396ffb8d02b4dcf9cb9556 (diff)
downloadllvm-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.cpp24
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);
}