diff options
author | Younan Zhang <zyn7109@gmail.com> | 2025-03-11 15:41:56 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-11 15:41:56 +0800 |
commit | f4218753ad93dd44b019e38bae61dceb93514aee (patch) | |
tree | d788b45565304a61352db297810417780096af63 /clang/lib/CodeGen/CGDecl.cpp | |
parent | f120b0d6d2629e226e6fa75974fbd17f46206bca (diff) | |
download | llvm-f4218753ad93dd44b019e38bae61dceb93514aee.zip llvm-f4218753ad93dd44b019e38bae61dceb93514aee.tar.gz llvm-f4218753ad93dd44b019e38bae61dceb93514aee.tar.bz2 |
[Clang] Implement P0963R3 "Structured binding declaration as a condition" (#130228)
This implements the R2 semantics of P0963.
The R1 semantics, as outlined in the paper, were introduced in Clang 6.
In addition to that, the paper proposes swapping the evaluation order of
condition expressions and the initialization of binding declarations
(i.e. std::tuple-like decompositions).
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 3ad9ebf..eab1ebf 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -48,7 +48,7 @@ using namespace CodeGen; static_assert(clang::Sema::MaximumAlignment <= llvm::Value::MaximumAlignment, "Clang max alignment greater than what LLVM supports?"); -void CodeGenFunction::EmitDecl(const Decl &D) { +void CodeGenFunction::EmitDecl(const Decl &D, bool EvaluateConditionDecl) { switch (D.getKind()) { case Decl::BuiltinTemplate: case Decl::TranslationUnit: @@ -152,7 +152,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { return; case Decl::UsingPack: for (auto *Using : cast<UsingPackDecl>(D).expansions()) - EmitDecl(*Using); + EmitDecl(*Using, /*EvaluateConditionDecl=*/EvaluateConditionDecl); return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getDebugInfo()) @@ -164,10 +164,8 @@ void CodeGenFunction::EmitDecl(const Decl &D) { assert(VD.isLocalVarDecl() && "Should not see file-scope variables inside a function!"); EmitVarDecl(VD); - if (auto *DD = dyn_cast<DecompositionDecl>(&VD)) - for (auto *B : DD->flat_bindings()) - if (auto *HD = B->getHoldingVar()) - EmitVarDecl(*HD); + if (EvaluateConditionDecl) + MaybeEmitDeferredVarDeclInit(&VD); return; } @@ -2059,6 +2057,14 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { /*IsAutoInit=*/false); } +void CodeGenFunction::MaybeEmitDeferredVarDeclInit(const VarDecl *VD) { + if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) { + for (auto *B : DD->flat_bindings()) + if (auto *HD = B->getHoldingVar()) + EmitVarDecl(*HD); + } +} + /// Emit an expression as an initializer for an object (variable, field, etc.) /// at the given location. The expression is not necessarily the normal /// initializer for the object, and the address is not necessarily |