[lldb][TypeSystemClang] Desugar an elaborated type before checking if it's a typedef or getting a typedefed type

Summary:
Sometimes a result variable of some expression can be presented as an elaborated
type. In this case the methods `IsTypedefType()` and `GetTypedefedType()` of
`SBType` didn't work. This patch fixes that.

I didn't find the test for these API methods, so I added a basic test for this
too.

Reviewers: aprantl, teemperor, labath, leonid.mashinskiy

Reviewed By: teemperor

Subscribers: labath, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D78697
This commit is contained in:
Aleksandr Urakov 2020-04-24 16:09:06 +03:00
parent 49d8625aef
commit 84c398d375
4 changed files with 74 additions and 3 deletions

View File

@ -3541,7 +3541,8 @@ bool TypeSystemClang::IsScalarType(lldb::opaque_compiler_type_t type) {
bool TypeSystemClang::IsTypedefType(lldb::opaque_compiler_type_t type) {
if (!type)
return false;
return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
return RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef})
->getTypeClass() == clang::Type::Typedef;
}
bool TypeSystemClang::IsVoidType(lldb::opaque_compiler_type_t type) {
@ -4525,8 +4526,8 @@ CompilerType TypeSystemClang::CreateTypedef(
CompilerType
TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) {
if (type) {
const clang::TypedefType *typedef_type =
llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(
RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}));
if (typedef_type)
return GetType(typedef_type->getDecl()->getUnderlyingType());
}

View File

@ -0,0 +1,2 @@
CXX_SOURCES := main.cpp
include Makefile.rules

View File

@ -0,0 +1,55 @@
"""
Test that we can retrieve typedefed types correctly
"""
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.lldbtest import *
from lldbsuite.test import decorators
class TestCppTypedef(TestBase):
mydir = TestBase.compute_mydir(__file__)
def test_typedef(self):
"""
Test that we retrieve typedefed types correctly
"""
# Build and run until the breakpoint
self.build()
self.main_source_file = lldb.SBFileSpec("main.cpp")
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
self, "Set a breakpoint here", self.main_source_file)
# Get the current frame
frame = thread.GetSelectedFrame()
# First of all, check that we can get a typedefed type correctly in a simple case
expr_result = frame.EvaluateExpression("(SF)s")
self.assertTrue(expr_result.IsValid(), "Expression failed with: " + str(expr_result.GetError()))
typedef_type = expr_result.GetType();
self.assertTrue(typedef_type.IsValid(), "Can't get `SF` type of evaluated expression")
self.assertTrue(typedef_type.IsTypedefType(), "Type `SF` should be a typedef")
typedefed_type = typedef_type.GetTypedefedType()
self.assertTrue(typedefed_type.IsValid(), "Can't get `SF` typedefed type")
self.assertEqual(typedefed_type.GetName(), "S<float>", "Got invalid `SF` typedefed type")
# Check that we can get a typedefed type correctly in the case
# when an elaborated type is created during the parsing
expr_result = frame.EvaluateExpression("(SF::V)s.value")
self.assertTrue(expr_result.IsValid(), "Expression failed with: " + str(expr_result.GetError()))
typedef_type = expr_result.GetType();
self.assertTrue(typedef_type.IsValid(), "Can't get `SF::V` type of evaluated expression")
self.assertTrue(typedef_type.IsTypedefType(), "Type `SF::V` should be a typedef")
typedefed_type = typedef_type.GetTypedefedType()
self.assertTrue(typedefed_type.IsValid(), "Can't get `SF::V` typedefed type")
self.assertEqual(typedefed_type.GetName(), "float", "Got invalid `SF::V` typedefed type")

View File

@ -0,0 +1,13 @@
template<typename T>
struct S {
typedef T V;
V value;
};
typedef S<float> SF;
int main (int argc, char const *argv[]) {
SF s{ .5 };
return 0; // Set a breakpoint here
}