Skip to content

Commit 89b0e78

Browse files
committed
[clang] Add dump() support for lvalue APValues
Add some lvalue information to the `dump()` output of lvalue APValues.
1 parent dac49e8 commit 89b0e78

File tree

3 files changed

+81
-6
lines changed

3 files changed

+81
-6
lines changed

clang/lib/AST/TextNodeDumper.cpp

+31-2
Original file line numberDiff line numberDiff line change
@@ -710,10 +710,39 @@ void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
710710
<< GetApproxValue(Value.getComplexFloatImag()) << 'i';
711711
}
712712
return;
713-
case APValue::LValue:
713+
case APValue::LValue: {
714714
(void)Context;
715-
OS << "LValue <todo>";
715+
OS << "LValue Base=";
716+
APValue::LValueBase B = Value.getLValueBase();
717+
if (B.isNull())
718+
OS << "null";
719+
else if (const auto *BE = B.dyn_cast<const Expr *>()) {
720+
OS << BE->getStmtClassName() << ' ';
721+
dumpPointer(BE);
722+
} else {
723+
const auto *VDB = B.get<const ValueDecl *>();
724+
OS << VDB->getDeclKindName() << "Decl";
725+
dumpPointer(VDB);
726+
}
727+
OS << ", Null=" << Value.isNullPointer()
728+
<< ", Offset=" << Value.getLValueOffset().getQuantity()
729+
<< ", HasPath=" << Value.hasLValuePath();
730+
if (Value.hasLValuePath()) {
731+
OS << ", PathLength=" << Value.getLValuePath().size();
732+
OS << ", Path=(";
733+
bool First = true;
734+
for (const auto &PathEntry : Value.getLValuePath()) {
735+
// We're printing all entries as array indices because don't have the
736+
// type information here to do anything else.
737+
OS << PathEntry.getAsArrayIndex();
738+
if (First && Value.getLValuePath().size() > 1)
739+
OS << ", ";
740+
First = false;
741+
}
742+
OS << ")";
743+
}
716744
return;
745+
}
717746
case APValue::Array: {
718747
unsigned ArraySize = Value.getArraySize();
719748
unsigned NumInitializedElements = Value.getArrayInitializedElts();
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Test without serialization:
2+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
3+
// RUN: -ast-dump %s -ast-dump-filter Test \
4+
// RUN: | FileCheck --strict-whitespace --match-full-lines %s
5+
//
6+
// Test with serialization:
7+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s
8+
// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
9+
// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \
10+
// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
11+
// RUN: | FileCheck --strict-whitespace --match-full-lines %s
12+
13+
int i;
14+
struct S {
15+
int i;
16+
int ii;
17+
};
18+
S s;
19+
20+
struct F {
21+
char padding[12];
22+
S s;
23+
};
24+
F f;
25+
26+
void Test() {
27+
constexpr int *pi = &i;
28+
// CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pi 'int *const' constexpr cinit
29+
// CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=0, HasPath=1, PathLength=0, Path=()
30+
31+
constexpr int *psi = &s.i;
32+
// CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} psi 'int *const' constexpr cinit
33+
// CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=0, HasPath=1, PathLength=1, Path=({{.*}})
34+
35+
constexpr int *psii = &s.ii;
36+
// CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} psii 'int *const' constexpr cinit
37+
// CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=4, HasPath=1, PathLength=1, Path=({{.*}})
38+
39+
constexpr int *pf = &f.s.ii;
40+
// CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pf 'int *const' constexpr cinit
41+
// CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=12, HasPath=1, PathLength=2, Path=({{.*}}, {{.*}})
42+
43+
constexpr char *pc = &f.padding[2];
44+
// CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pf 'char *const' constexpr cinit
45+
// CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=2, HasPath=1, PathLength=2, Path=({{.*}}, 2)
46+
47+
constexpr const int *n = nullptr;
48+
// CHECK: `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} n 'const int *const' constexpr cinit
49+
// CHECK-NEXT: |-value: LValue Base=null, Null=1, Offset=0, HasPath=1, PathLength=0, Path=()
50+
}

clang/test/AST/ast-dump-APValue-todo.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ struct S {
1616
};
1717

1818
void Test() {
19-
constexpr int *pi = &i;
20-
// CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pi 'int *const' constexpr cinit
21-
// CHECK-NEXT: | |-value: LValue <todo>
22-
2319
constexpr int(S::*pmi) = &S::i;
2420
// CHECK: `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pmi 'int (S::*const)' constexpr cinit
2521
// CHECK-NEXT: |-value: MemberPointer <todo>

0 commit comments

Comments
 (0)