[all-commits] [llvm/llvm-project] 486787: [lldb] Add support for using integral const static...

Andy Hippo via All-commits all-commits at lists.llvm.org
Thu Jul 14 08:15:55 PDT 2022


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 486787210df5ce5eabadc90a7de353ae81101feb
      https://github.com/llvm/llvm-project/commit/486787210df5ce5eabadc90a7de353ae81101feb
  Author: Andy Yankovsky <weratt at gmail.com>
  Date:   2022-07-14 (Thu, 14 Jul 2022)

  Changed paths:
    M lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
    M lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    M lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
    A lldb/test/API/lang/cpp/const_static_integral_member/Makefile
    A lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
    A lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
    A lldb/test/API/lang/cpp/const_static_integral_member_int128/Makefile
    A lldb/test/API/lang/cpp/const_static_integral_member_int128/TestConstStaticIntegralMemberInt128.py
    A lldb/test/API/lang/cpp/const_static_integral_member_int128/main.cpp
    M lldb/unittests/SymbolFile/DWARF/CMakeLists.txt
    M lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp

  Log Message:
  -----------
  [lldb] Add support for using integral const static data members in the expression evaluator

This adds support for using const static integral data members as described by C++11 [class.static.data]p3
to LLDB's expression evaluator.

So far LLDB treated these data members are normal static variables. They already work as intended when they are declared in the class definition and then defined in a namespace scope. However, if they are declared and initialised in the class definition but never defined in a namespace scope, all LLDB expressions that use them will fail to link when LLDB can't find the respective symbol for the variable.

The reason for this is that the data members which are only declared in the class are not emitted into any object file so LLDB can never resolve them. Expressions that use these variables are expected to directly use their constant value if possible. Clang can do this for us during codegen, but it requires that we add the constant value to the VarDecl we generate for these data members.

This patch implements this by:
* parsing the constant values from the debug info and adding it to variable declarations we encounter.
* ensuring that LLDB doesn't implicitly try to take the address of expressions that might be an lvalue that points to such a special data member.

The second change is caused by LLDB's way of storing lvalues in the expression parser. When LLDB parses an expression, it tries to keep the result around via two mechanisms:

1. For lvalues, LLDB generates a static pointer variable and stores the address of the last expression in it: `T *$__lldb_expr_result_ptr = &LastExpression`
2. For everything else, LLDB generates a static variable of the same type as the last expression and then direct initialises that variable: `T $__lldb_expr_result(LastExpression)`

If we try to print a special const static data member via something like `expr Class::Member`, then LLDB will try to take the address of this expression as it's an lvalue. This means LLDB will try to take the address of the variable which causes that Clang can't replace the use with the constant value. There isn't any good way to detect this case (as there a lot of different expressions that could yield an lvalue that points to such a data member), so this patch also changes that we only use the first way of capturing the result if the last expression does not have a type that could potentially indicate it's coming from such a special data member.

This change shouldn't break most workflows for users. The only observable side effect I could find is that the implicit persistent result variables for const int's now have their own memory address:

Before this change:
```
(lldb) p i
(const int) $0 = 123
(lldb) p &$0
(const int *) $1 = 0x00007ffeefbff8e8
(lldb) p &i
(const int *) $2 = 0x00007ffeefbff8e8
```

After this change we capture `i` by value so it has its own value.
```
(lldb) p i
(const int) $0 = 123
(lldb) p &$0
(const int *) $1 = 0x0000000100155320
(lldb) p &i
(const int *) $2 = 0x00007ffeefbff8e8
```

Reviewed By: Michael137

Differential Revision: https://reviews.llvm.org/D81471




More information about the All-commits mailing list