-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement is_structured_binding
metafunction
#58
Conversation
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
I created this PR to receive feedback about my current progress while I am dealing with new implementation of #11 . I tried to cover 3 main cases mentioned in the issue but will come back and add more tests later. Plus, need to investigate needs for changes of related functions -- |
clang/lib/Sema/Metafunctions.cpp
Outdated
result = isa<const VarDecl>(R.getReflectedDecl()); | ||
Decl *D = R.getReflectedDecl(); | ||
if (auto *BD = dyn_cast<BindingDecl>(D)) { | ||
result = (BD->getHoldingVar() != nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decided to go this way because of documentation:
/// Get the variable (if any) that holds the value of evaluating the binding.
/// Only present for user-defined bindings for tuple-like types.
VarDecl *getHoldingVar() const;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon more careful reading of the Standard, I think I led you astray - we should not return true
for is_variable
in any of these cases.
I realized this while attempting to verify that getHoldingVar
was the right API for this task, during which I came upon this code which implements tuple-like binding decomposition in clang. The synthesized variable RefVD
corresponds to the variable
S U_i r_i = initializer ;
mandated by [dcl.struct.bind]/4
, but notice that it's never stored as a property of the BindingDecl B
that's being constructed. Instead, the Sema::BuildDeclarationNameExpr()
function is used to synthesize an expression referencing the variable, and that expression is set as the "binding" via B->setBinding(E)
.
Looking back at the Standard, this lines up:
Each
v_i
is the name of an lvalue of typeT_i
that refers to the object bound tor_i
; the referenced type isT_i
.
So even though a variable is synthesized for each binding in a tuple-like decomposition, I believe the binding itself is still not a variable, but rather a named expression referencing the synthesized variable.
Sorry for the mixup!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for deep dive! I reverted changes to implementation but left existing tests
clang/lib/Sema/Metafunctions.cpp
Outdated
result = isa<const VarDecl>(R.getReflectedDecl()); | ||
Decl *D = R.getReflectedDecl(); | ||
if (auto *BD = dyn_cast<BindingDecl>(D)) { | ||
result = (BD->getHoldingVar() != nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon more careful reading of the Standard, I think I led you astray - we should not return true
for is_variable
in any of these cases.
I realized this while attempting to verify that getHoldingVar
was the right API for this task, during which I came upon this code which implements tuple-like binding decomposition in clang. The synthesized variable RefVD
corresponds to the variable
S U_i r_i = initializer ;
mandated by [dcl.struct.bind]/4
, but notice that it's never stored as a property of the BindingDecl B
that's being constructed. Instead, the Sema::BuildDeclarationNameExpr()
function is used to synthesize an expression referencing the variable, and that expression is set as the "binding" via B->setBinding(E)
.
Looking back at the Standard, this lines up:
Each
v_i
is the name of an lvalue of typeT_i
that refers to the object bound tor_i
; the referenced type isT_i
.
So even though a variable is synthesized for each binding in a tuple-like decomposition, I believe the binding itself is still not a variable, but rather a named expression referencing the synthesized variable.
Sorry for the mixup!
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Thanks for the initial review! I will work on testing and adapting So far, at least After my test&fixes, I'll request your review again + meanwhile will investigate which implemented functions might need some changes |
…inding Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Signed-off-by: Valentyn Yukhymenko <valentin.yukhymenko@gmail.com>
I think I am ready for next iteration of review. I slightly changed implementations of One remark about my changes: I am not sure about my changes to constexpr auto p = std::pair{1, 2};
auto& [x4, y4] = p;
static_assert(extract<int>(^x4) == x4);
static_assert(extract<int&>(^x4) == x4);
static_assert(&extract<int&>(^x4) == &x4);
static_assert(extract<int>(^y4) == y4);
static_assert(extract<int&>(^y4) == y4);
static_assert(&extract<int&>(^y4) == &y4); |
Valentyn, I think these look great! Note that it hasn't been decided yet whether to support Thanks so much for the contribution!! |
Implements #44
Describe your changes
Added implementation of
is_structured_binding
+ adapted implementation oftype_of
andextract
functionsTesting performed
Added tests for my changes to
entity-classification.pass.cpp
env LIT_FILTER=entity-classification.pass.cpp ninja check-cxx -C build-llvm/ .... Testing Time: 1.17s Total Discovered Tests: 9692 Excluded: 9691 (99.99%) Passed : 1 (0.01%)