Timm =?utf-8?q?Bäder?= <tbae...@redhat.com>, Timm =?utf-8?q?Bäder?= <tbae...@redhat.com>, Timm =?utf-8?q?Bäder?= <tbae...@redhat.com> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/124...@github.com>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/124476 >From 373dda500b436a5ee4ca44383ccbb711090fa844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Sun, 26 Jan 2025 19:17:28 +0100 Subject: [PATCH 1/4] [clang] Add dump() support for lvalue APValues Add some lvalue information to the `dump()` output of lvalue APValues. --- clang/lib/AST/TextNodeDumper.cpp | 33 +++++++++++++- clang/test/AST/ast-dump-APValue-lvalue.cpp | 50 ++++++++++++++++++++++ clang/test/AST/ast-dump-APValue-todo.cpp | 4 -- 3 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 clang/test/AST/ast-dump-APValue-lvalue.cpp diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 670641242cae2fe..7ff758d5f78a137 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -710,10 +710,39 @@ void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { << GetApproxValue(Value.getComplexFloatImag()) << 'i'; } return; - case APValue::LValue: + case APValue::LValue: { (void)Context; - OS << "LValue <todo>"; + OS << "LValue Base="; + APValue::LValueBase B = Value.getLValueBase(); + if (B.isNull()) + OS << "null"; + else if (const auto *BE = B.dyn_cast<const Expr *>()) { + OS << BE->getStmtClassName() << ' '; + dumpPointer(BE); + } else { + const auto *VDB = B.get<const ValueDecl *>(); + OS << VDB->getDeclKindName() << "Decl"; + dumpPointer(VDB); + } + OS << ", Null=" << Value.isNullPointer() + << ", Offset=" << Value.getLValueOffset().getQuantity() + << ", HasPath=" << Value.hasLValuePath(); + if (Value.hasLValuePath()) { + OS << ", PathLength=" << Value.getLValuePath().size(); + OS << ", Path=("; + bool First = true; + for (const auto &PathEntry : Value.getLValuePath()) { + // We're printing all entries as array indices because don't have the + // type information here to do anything else. + OS << PathEntry.getAsArrayIndex(); + if (First && Value.getLValuePath().size() > 1) + OS << ", "; + First = false; + } + OS << ")"; + } return; + } case APValue::Array: { unsigned ArraySize = Value.getArraySize(); unsigned NumInitializedElements = Value.getArrayInitializedElts(); diff --git a/clang/test/AST/ast-dump-APValue-lvalue.cpp b/clang/test/AST/ast-dump-APValue-lvalue.cpp new file mode 100644 index 000000000000000..d2efbc201406bd1 --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-lvalue.cpp @@ -0,0 +1,50 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +int i; +struct S { + int i; + int ii; +}; +S s; + +struct F { + char padding[12]; + S s; +}; +F f; + +void Test() { + constexpr int *pi = &i; + // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pi 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=0, HasPath=1, PathLength=0, Path=() + + constexpr int *psi = &s.i; + // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} psi 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=0, HasPath=1, PathLength=1, Path=({{.*}}) + + constexpr int *psii = &s.ii; + // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} psii 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=4, HasPath=1, PathLength=1, Path=({{.*}}) + + constexpr int *pf = &f.s.ii; + // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pf 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=12, HasPath=1, PathLength=2, Path=({{.*}}, {{.*}}) + + constexpr char *pc = &f.padding[2]; + // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pf 'char *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=2, HasPath=1, PathLength=2, Path=({{.*}}, 2) + + constexpr const int *n = nullptr; + // CHECK: `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} n 'const int *const' constexpr cinit + // CHECK-NEXT: |-value: LValue Base=null, Null=1, Offset=0, HasPath=1, PathLength=0, Path=() +} diff --git a/clang/test/AST/ast-dump-APValue-todo.cpp b/clang/test/AST/ast-dump-APValue-todo.cpp index 78cc9cf36c73c14..acaa82ba53b6fdd 100644 --- a/clang/test/AST/ast-dump-APValue-todo.cpp +++ b/clang/test/AST/ast-dump-APValue-todo.cpp @@ -16,10 +16,6 @@ struct S { }; void Test() { - constexpr int *pi = &i; - // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pi 'int *const' constexpr cinit - // CHECK-NEXT: | |-value: LValue <todo> - constexpr int(S::*pmi) = &S::i; // CHECK: `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pmi 'int (S::*const)' constexpr cinit // CHECK-NEXT: |-value: MemberPointer <todo> >From f6f0ae62d98c28691c4c66e2d338427062d74bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Sun, 26 Jan 2025 19:32:26 +0100 Subject: [PATCH 2/4] Add test for constexpr unknown value --- clang/test/AST/ast-dump-APValue-lvalue.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/test/AST/ast-dump-APValue-lvalue.cpp b/clang/test/AST/ast-dump-APValue-lvalue.cpp index d2efbc201406bd1..d6d1892560a14b1 100644 --- a/clang/test/AST/ast-dump-APValue-lvalue.cpp +++ b/clang/test/AST/ast-dump-APValue-lvalue.cpp @@ -23,7 +23,7 @@ struct F { }; F f; -void Test() { +void Test(int (&arr)[10]) { constexpr int *pi = &i; // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pi 'int *const' constexpr cinit // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=0, HasPath=1, PathLength=0, Path=() @@ -44,6 +44,10 @@ void Test() { // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pf 'char *const' constexpr cinit // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=2, HasPath=1, PathLength=2, Path=({{.*}}, 2) + constexpr const int *parr = arr + 10; + // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} parr 'char *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=41, HasPath=0 + constexpr const int *n = nullptr; // CHECK: `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} n 'const int *const' constexpr cinit // CHECK-NEXT: |-value: LValue Base=null, Null=1, Offset=0, HasPath=1, PathLength=0, Path=() >From 509d2f95492e05ecca5f077ce3503c100998528a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Mon, 27 Jan 2025 08:28:38 +0100 Subject: [PATCH 3/4] Use llvm::ListSeparator --- clang/lib/AST/TextNodeDumper.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 7ff758d5f78a137..9d067baef2505c9 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -730,14 +730,11 @@ void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { if (Value.hasLValuePath()) { OS << ", PathLength=" << Value.getLValuePath().size(); OS << ", Path=("; - bool First = true; + llvm::ListSeparator Sep; for (const auto &PathEntry : Value.getLValuePath()) { // We're printing all entries as array indices because don't have the // type information here to do anything else. - OS << PathEntry.getAsArrayIndex(); - if (First && Value.getLValuePath().size() > 1) - OS << ", "; - First = false; + OS << PathEntry.getAsArrayIndex() << Sep; } OS << ")"; } >From b867a9293be3ea98a209d0d7ab6808c998225635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Mon, 27 Jan 2025 08:46:16 +0100 Subject: [PATCH 4/4] Fix tests --- clang/lib/AST/TextNodeDumper.cpp | 2 +- clang/test/AST/ast-dump-APValue-lvalue.cpp | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 9d067baef2505c9..46ec553fc05f01c 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -734,7 +734,7 @@ void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { for (const auto &PathEntry : Value.getLValuePath()) { // We're printing all entries as array indices because don't have the // type information here to do anything else. - OS << PathEntry.getAsArrayIndex() << Sep; + OS << Sep << PathEntry.getAsArrayIndex(); } OS << ")"; } diff --git a/clang/test/AST/ast-dump-APValue-lvalue.cpp b/clang/test/AST/ast-dump-APValue-lvalue.cpp index d6d1892560a14b1..224caddb3eabe61 100644 --- a/clang/test/AST/ast-dump-APValue-lvalue.cpp +++ b/clang/test/AST/ast-dump-APValue-lvalue.cpp @@ -38,16 +38,12 @@ void Test(int (&arr)[10]) { constexpr int *pf = &f.s.ii; // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pf 'int *const' constexpr cinit - // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=12, HasPath=1, PathLength=2, Path=({{.*}}, {{.*}}) + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=16, HasPath=1, PathLength=2, Path=({{.*}}, {{.*}}) constexpr char *pc = &f.padding[2]; - // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pf 'char *const' constexpr cinit + // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pc 'char *const' constexpr cinit // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=2, HasPath=1, PathLength=2, Path=({{.*}}, 2) - constexpr const int *parr = arr + 10; - // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} parr 'char *const' constexpr cinit - // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=41, HasPath=0 - constexpr const int *n = nullptr; // CHECK: `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} n 'const int *const' constexpr cinit // CHECK-NEXT: |-value: LValue Base=null, Null=1, Offset=0, HasPath=1, PathLength=0, Path=() _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits