[clang] [clang] Add dump() support for lvalue APValues (PR #124476)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 26 23:48:00 PST 2025
Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>,
Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>,
Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/124476 at 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?= <tbaeder at 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?= <tbaeder at 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?= <tbaeder at 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?= <tbaeder at 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=()
More information about the cfe-commits
mailing list