[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice updated
https://github.com/llvm/llvm-project/pull/175061
>From cf0161bf183944ab37c1e6952e5cd2e883b4d212 Mon Sep 17 00:00:00 2001
From: Caroline Tice
Date: Thu, 8 Jan 2026 11:45:30 -0800
Subject: [PATCH 1/7] [LLDB] Add type casting to DIL, part 3 of 3
This PR updates type parsing in DIL to recognize user-defined types
(classes, namespaces, etc.), and allows this to be used in type casting.
---
lldb/include/lldb/ValueObject/DILParser.h | 7 +
lldb/source/ValueObject/DILEval.cpp | 14 +-
lldb/source/ValueObject/DILParser.cpp | 176 +-
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 26 +++
.../frame/var-dil/expr/Casts/main.cpp | 20 ++
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : pr
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice updated
https://github.com/llvm/llvm-project/pull/175061
>From cf0161bf183944ab37c1e6952e5cd2e883b4d212 Mon Sep 17 00:00:00 2001
From: Caroline Tice
Date: Thu, 8 Jan 2026 11:45:30 -0800
Subject: [PATCH 1/6] [LLDB] Add type casting to DIL, part 3 of 3
This PR updates type parsing in DIL to recognize user-defined types
(classes, namespaces, etc.), and allows this to be used in type casting.
---
lldb/include/lldb/ValueObject/DILParser.h | 7 +
lldb/source/ValueObject/DILEval.cpp | 14 +-
lldb/source/ValueObject/DILParser.cpp | 176 +-
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 26 +++
.../frame/var-dil/expr/Casts/main.cpp | 20 ++
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : pr
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +45,53 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ ExecutionContextScope &ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope.CalculateTarget();
+ if (!name_ref.empty() && target_sp) {
+ModuleList &images = target_sp->GetImages();
+TypeQuery query{ConstString(name_ref)};
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+ }
+
+ // We've found multiple types, try finding the "correct" one.
+ CompilerType full_match;
+ std::vector partial_matches;
cmtice wrote:
Done
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice updated
https://github.com/llvm/llvm-project/pull/175061
>From cf0161bf183944ab37c1e6952e5cd2e883b4d212 Mon Sep 17 00:00:00 2001
From: Caroline Tice
Date: Thu, 8 Jan 2026 11:45:30 -0800
Subject: [PATCH 1/6] [LLDB] Add type casting to DIL, part 3 of 3
This PR updates type parsing in DIL to recognize user-defined types
(classes, namespaces, etc.), and allows this to be used in type casting.
---
lldb/include/lldb/ValueObject/DILParser.h | 7 +
lldb/source/ValueObject/DILEval.cpp | 14 +-
lldb/source/ValueObject/DILParser.cpp | 176 +-
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 26 +++
.../frame/var-dil/expr/Casts/main.cpp | 20 ++
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : pr
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +45,53 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ ExecutionContextScope &ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope.CalculateTarget();
+ if (!name_ref.empty() && target_sp) {
+ModuleList &images = target_sp->GetImages();
+TypeQuery query{ConstString(name_ref)};
+TypeResults results;
+images.FindTypes(nullptr, query, results);
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -233,3 +259,17 @@ def test_type_cast(self):
self.expect_var_path("((int*)arr_2d)[1]", type="int", value="2")
self.expect_var_path("((int*)arr_2d)[2]", type="int", value="3")
self.expect_var_path("((int*)arr_2d[1])[1]", type="int", value="5")
+
+# Test casting to user-defined type with same name as variable.
+
+self.expect_var_path("myStruct", type="myName")
+self.expect_var_path("myName", type="int", value="37")
+
+# Here 'myName' is treated as a variable, not a type, so '(myName)'
+# is parsed as a variable expression and 'InnerFoo' is unexpected,
+# and a type cast is not attempted.
+self.expect(
+"frame variable '(myName)InnerFoo'",
+error=True,
+substrs=["expected 'eof', got: <'InnerFoo' (identifier)>"],
cmtice wrote:
It's not that simple. When the parser sees the token sequence
left-parentheses, identifier, right-parenthesis, the identifier could validly
either be a variable name or a type name. If it's a variable name, then the
entire 3-token sequence is evaluated to be the variable. If any tokens follow,
then they should be tokens that can reasonably follow a variable name, such as
'.', '->' '[...]', or an eof token. What the next immediate token cannot be is
another identifier. However if the identifier in the first 3-token sequence is
determined to be a type name, then an identifier is absolutely a valid next
token.
In this particular case, the first identifier happens to be a valid name for
both a type and a variable. In such cases we always choose the variable name
over the type name. SO the parser decides that the first three tokens refer to
a variable. At this point it moves on, remembering that it's holding a variable
but losing most of the previous context, and parses the next token and finds
that it is not a valid token to come right after a variable, so we get an error
message that basically says "I was expecting one type of token and I found the
wrong token type -- invalid sequence". At the point where this is generated
the parser does not really have the context of the previously made decision,
nor the knowledge that the variable name (in the first three tokens) is also a
valid type name.
Having ParseTypeId always return an error message of it doesn't find a compiler
type is not correct, because. e.g. '&(a)' is perfectly valid if 'a' is a
variable, and we would expect ParseTypeId to return no compiler type. (Note
"&((int)(b))" is also valid for DIL, so DIL always checks, when it sees a left
parenthesis, to see if it's doing a type cast or not.)
All of this is a very long-winded way of saying I don't think we can really
give you the error message you would like here.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -233,3 +259,17 @@ def test_type_cast(self):
self.expect_var_path("((int*)arr_2d)[1]", type="int", value="2")
self.expect_var_path("((int*)arr_2d)[2]", type="int", value="3")
self.expect_var_path("((int*)arr_2d[1])[1]", type="int", value="5")
+
+# Test casting to user-defined type with same name as variable.
+
+self.expect_var_path("myStruct", type="myName")
+self.expect_var_path("myName", type="int", value="37")
+
+# Here 'myName' is treated as a variable, not a type, so '(myName)'
+# is parsed as a variable expression and 'InnerFoo' is unexpected,
+# and a type cast is not attempted.
+self.expect(
+"frame variable '(myName)InnerFoo'",
+error=True,
+substrs=["expected 'eof', got: <'InnerFoo' (identifier)>"],
Michael137 wrote:
Something like about `myVariable` being a variable and not a type-name. I.e.,
give the user an indication of why this failed. Possibly
`DILParser::ParseTypeId` needs to return a `llvm::Expected`? Then
we can propagate the error message (and an empty `CompilerType` is what we
would return where we previously returned a `std::nullopt`. Does that make
sense?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +45,53 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ ExecutionContextScope &ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope.CalculateTarget();
+ if (!name_ref.empty() && target_sp) {
+ModuleList &images = target_sp->GetImages();
+TypeQuery query{ConstString(name_ref)};
+TypeResults results;
+images.FindTypes(nullptr, query, results);
Michael137 wrote:
Can we just use `e_exact_match` and `e_find_one` flags here in the query? Then
we don't need the loop that checks for a matching name below
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/Michael137 approved this pull request. LGTM with some remaining comments https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +45,53 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ ExecutionContextScope &ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope.CalculateTarget();
+ if (!name_ref.empty() && target_sp) {
+ModuleList &images = target_sp->GetImages();
+TypeQuery query{ConstString(name_ref)};
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+ }
+
+ // We've found multiple types, try finding the "correct" one.
+ CompilerType full_match;
+ std::vector partial_matches;
Michael137 wrote:
```suggestion
```
unused
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
cmtice wrote: I believe I have addressed all the comments and this is ready for review again. Thanks! https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -233,3 +259,17 @@ def test_type_cast(self):
self.expect_var_path("((int*)arr_2d)[1]", type="int", value="2")
self.expect_var_path("((int*)arr_2d)[2]", type="int", value="3")
self.expect_var_path("((int*)arr_2d[1])[1]", type="int", value="5")
+
+# Test casting to user-defined type with same name as variable.
+
+self.expect_var_path("myStruct", type="myName")
+self.expect_var_path("myName", type="int", value="37")
+
+# Here 'myName' is treated as a variable, not a type, so '(myName)'
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : process_sp->GetLanguageRuntimes()) {
+if (auto *vendor = runtime->GetDeclVendor()) {
+ auto types = vendor->FindTypes(const_type_name, UINT32_MAX);
+ for (auto type : types)
+result_type_list.push_back(type);
+}
+ }
+}
+ }
+
+ // We've found multiple types, try finding the "correct" one.
+ CompilerType full_match;
+ std::vector partial_matches;
+
+ for (uint32_t i = 0; i < result_type_list.size(); ++i) {
+CompilerType type = result_type_list[i];
+llvm::StringRef type_name_ref = type.GetTypeName().GetStringRef();
+
+if (type_name_ref == name_ref && type.IsValid())
+ return type;
+
+if (type_name_ref.ends_with(name_ref))
+ partial_matches.push_back(type);
+ }
+
+ // If we have partial matches, pick a "random" one.
+ if (partial_matches.size() > 0)
+return partial_matches.back();
cmtice wrote:
Ok, I've removed the partial matches stuff from here.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : process_sp->GetLanguageRuntimes()) {
+if (auto *vendor = runtime->GetDeclVendor()) {
+ auto types = vendor->FindTypes(const_type_name, UINT32_MAX);
+ for (auto type : types)
+result_type_list.push_back(type);
+}
+ }
+}
cmtice wrote:
Ok, I've removed it.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -11,6 +11,7 @@ #include "lldb/Host/common/DiagnosticsRendering.h" #include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/StackFrame.h" cmtice wrote: Done https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice updated
https://github.com/llvm/llvm-project/pull/175061
>From cf0161bf183944ab37c1e6952e5cd2e883b4d212 Mon Sep 17 00:00:00 2001
From: Caroline Tice
Date: Thu, 8 Jan 2026 11:45:30 -0800
Subject: [PATCH 1/5] [LLDB] Add type casting to DIL, part 3 of 3
This PR updates type parsing in DIL to recognize user-defined types
(classes, namespaces, etc.), and allows this to be used in type casting.
---
lldb/include/lldb/ValueObject/DILParser.h | 7 +
lldb/source/ValueObject/DILEval.cpp | 14 +-
lldb/source/ValueObject/DILParser.cpp | 176 +-
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 26 +++
.../frame/var-dil/expr/Casts/main.cpp | 20 ++
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : pr
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice edited https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -233,3 +259,17 @@ def test_type_cast(self):
self.expect_var_path("((int*)arr_2d)[1]", type="int", value="2")
self.expect_var_path("((int*)arr_2d)[2]", type="int", value="3")
self.expect_var_path("((int*)arr_2d[1])[1]", type="int", value="5")
+
+# Test casting to user-defined type with same name as variable.
+
+self.expect_var_path("myStruct", type="myName")
+self.expect_var_path("myName", type="int", value="37")
+
+# Here 'myName' is treated as a variable, not a type, so '(myName)'
+# is parsed as a variable expression and 'InnerFoo' is unexpected,
+# and a type cast is not attempted.
+self.expect(
+"frame variable '(myName)InnerFoo'",
+error=True,
+substrs=["expected 'eof', got: <'InnerFoo' (identifier)>"],
cmtice wrote:
The basic error message that we're "matching" here in the test case is
"expected 'particular-type-of-token', got <'text' (token-type)>". I'm not sure
how what a better error message would look like, but I'm open to suggestions.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : process_sp->GetLanguageRuntimes()) {
+if (auto *vendor = runtime->GetDeclVendor()) {
+ auto types = vendor->FindTypes(const_type_name, UINT32_MAX);
+ for (auto type : types)
+result_type_list.push_back(type);
+}
+ }
+}
+ }
+
+ // We've found multiple types, try finding the "correct" one.
+ CompilerType full_match;
+ std::vector partial_matches;
+
+ for (uint32_t i = 0; i < result_type_list.size(); ++i) {
+CompilerType type = result_type_list[i];
+llvm::StringRef type_name_ref = type.GetTypeName().GetStringRef();
+
+if (type_name_ref == name_ref && type.IsValid())
+ return type;
+
+if (type_name_ref.ends_with(name_ref))
+ partial_matches.push_back(type);
+ }
+
+ // If we have partial matches, pick a "random" one.
+ if (partial_matches.size() > 0)
+return partial_matches.back();
kuilpd wrote:
Actually, now that I checked again, full expression evaluator only does this
for variables to find them in different namespaces, but not for types. Then
maybe we shouldn't do this either.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : process_sp->GetLanguageRuntimes()) {
+if (auto *vendor = runtime->GetDeclVendor()) {
+ auto types = vendor->FindTypes(const_type_name, UINT32_MAX);
+ for (auto type : types)
+result_type_list.push_back(type);
+}
+ }
+}
+ }
+
+ // We've found multiple types, try finding the "correct" one.
+ CompilerType full_match;
+ std::vector partial_matches;
+
+ for (uint32_t i = 0; i < result_type_list.size(); ++i) {
+CompilerType type = result_type_list[i];
+llvm::StringRef type_name_ref = type.GetTypeName().GetStringRef();
+
+if (type_name_ref == name_ref && type.IsValid())
+ return type;
+
+if (type_name_ref.ends_with(name_ref))
+ partial_matches.push_back(type);
+ }
+
+ // If we have partial matches, pick a "random" one.
+ if (partial_matches.size() > 0)
+return partial_matches.back();
Michael137 wrote:
Mmmm I'm not sure I like that this is trying to do some sort of lookup
resolution. The user should provide us with the exact type. Maybe we can do a
global search and error out if there's partial matches, saying "did you mean on
of these fully-qualified names". Wdyt?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : process_sp->GetLanguageRuntimes()) {
+if (auto *vendor = runtime->GetDeclVendor()) {
+ auto types = vendor->FindTypes(const_type_name, UINT32_MAX);
+ for (auto type : types)
+result_type_list.push_back(type);
+}
+ }
+}
+ }
+
+ // We've found multiple types, try finding the "correct" one.
+ CompilerType full_match;
+ std::vector partial_matches;
+
+ for (uint32_t i = 0; i < result_type_list.size(); ++i) {
+CompilerType type = result_type_list[i];
+llvm::StringRef type_name_ref = type.GetTypeName().GetStringRef();
+
+if (type_name_ref == name_ref && type.IsValid())
+ return type;
+
+if (type_name_ref.ends_with(name_ref))
+ partial_matches.push_back(type);
+ }
+
+ // If we have partial matches, pick a "random" one.
+ if (partial_matches.size() > 0)
+return partial_matches.back();
kuilpd wrote:
As far as I remember, we're trying to have the same behavior as full expression
evaluation and old frame var here. If we're looking for `foo`, but we find only
`ns::foo`, this is a partial match, but we still return it as found. If there
is both `foo` and `ns::foo` found, then we prefer the full match without the
namespace.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -233,3 +259,17 @@ def test_type_cast(self):
self.expect_var_path("((int*)arr_2d)[1]", type="int", value="2")
self.expect_var_path("((int*)arr_2d)[2]", type="int", value="3")
self.expect_var_path("((int*)arr_2d[1])[1]", type="int", value="5")
+
+# Test casting to user-defined type with same name as variable.
+
+self.expect_var_path("myStruct", type="myName")
+self.expect_var_path("myName", type="int", value="37")
+
+# Here 'myName' is treated as a variable, not a type, so '(myName)'
Michael137 wrote:
This exercises the `LookupIdentifier` short-circuit in
`DILParser::ParseTypeId`? Can we also add a test that exercises the
`LookupGlobalIdentifier` path?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -233,3 +259,17 @@ def test_type_cast(self):
self.expect_var_path("((int*)arr_2d)[1]", type="int", value="2")
self.expect_var_path("((int*)arr_2d)[2]", type="int", value="3")
self.expect_var_path("((int*)arr_2d[1])[1]", type="int", value="5")
+
+# Test casting to user-defined type with same name as variable.
+
+self.expect_var_path("myStruct", type="myName")
+self.expect_var_path("myName", type="int", value="37")
+
+# Here 'myName' is treated as a variable, not a type, so '(myName)'
+# is parsed as a variable expression and 'InnerFoo' is unexpected,
+# and a type cast is not attempted.
+self.expect(
+"frame variable '(myName)InnerFoo'",
+error=True,
+substrs=["expected 'eof', got: <'InnerFoo' (identifier)>"],
Michael137 wrote:
Any chance we can make this error nicer? What does `eof` mean here?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : process_sp->GetLanguageRuntimes()) {
+if (auto *vendor = runtime->GetDeclVendor()) {
+ auto types = vendor->FindTypes(const_type_name, UINT32_MAX);
+ for (auto type : types)
+result_type_list.push_back(type);
+}
+ }
+}
+ }
+
+ // We've found multiple types, try finding the "correct" one.
+ CompilerType full_match;
+ std::vector partial_matches;
+
+ for (uint32_t i = 0; i < result_type_list.size(); ++i) {
+CompilerType type = result_type_list[i];
+llvm::StringRef type_name_ref = type.GetTypeName().GetStringRef();
+
+if (type_name_ref == name_ref && type.IsValid())
+ return type;
+
+if (type_name_ref.ends_with(name_ref))
+ partial_matches.push_back(type);
+ }
+
+ // If we have partial matches, pick a "random" one.
+ if (partial_matches.size() > 0)
+return partial_matches.back();
Michael137 wrote:
Can you elaborate on partial matches? Why aren't we just making a
`TypeQueryOptions::e_exact_match` query? We could also make it a `e_find_one`
query, but that I'm less certain of.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : process_sp->GetLanguageRuntimes()) {
+if (auto *vendor = runtime->GetDeclVendor()) {
+ auto types = vendor->FindTypes(const_type_name, UINT32_MAX);
+ for (auto type : types)
+result_type_list.push_back(type);
+}
+ }
+}
Michael137 wrote:
If there's no test coverage for this I'd prefer not to include this for now. I
assume this would just benefit Objective-C at the moment?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
Michael137 wrote:
```suggestion
TypeQuery query(ConstString(name_ref));
```
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
Michael137 wrote:
```suggestion
if (!name_ref.empty() && target_sp) {
```
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
Michael137 wrote:
```suggestion
ExecutionContextScope &ctx_scope) {
```
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -11,6 +11,7 @@ #include "lldb/Host/common/DiagnosticsRendering.h" #include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/StackFrame.h" Michael137 wrote: I think we should be forward declaring `StackFrame` here instead of pulling in the header. And include it in `DILParser.cpp`. https://llvm.org/docs/CodingStandards.html#include-as-little-as-possible https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
cmtice wrote: Review ping? This is ready for another review I think. https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
jimingham wrote:
That argues for pulling the implementation out of the SB layer, putting it in
lldb_private and calling from there. In general, whenever there's significant
code in an SB API it's in the wrong place...
Maybe that's a cleanup for a separate PR, however?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice updated
https://github.com/llvm/llvm-project/pull/175061
>From cf0161bf183944ab37c1e6952e5cd2e883b4d212 Mon Sep 17 00:00:00 2001
From: Caroline Tice
Date: Thu, 8 Jan 2026 11:45:30 -0800
Subject: [PATCH 1/4] [LLDB] Add type casting to DIL, part 3 of 3
This PR updates type parsing in DIL to recognize user-defined types
(classes, namespaces, etc.), and allows this to be used in type casting.
---
lldb/include/lldb/ValueObject/DILParser.h | 7 +
lldb/source/ValueObject/DILEval.cpp | 14 +-
lldb/source/ValueObject/DILParser.cpp | 176 +-
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 26 +++
.../frame/var-dil/expr/Casts/main.cpp | 20 ++
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : pr
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r origin/main...HEAD lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py `` :warning: The reproduction instructions above might return results for more than one PR in a stack if you are using a stacked PR workflow. You can limit the results by changing `origin/main` to the base branch/commit you want to compare against. :warning: View the diff from darker here. ``diff --- TestFrameVarDILCast.py 2026-01-15 23:15:42.00 + +++ TestFrameVarDILCast.py 2026-01-15 23:18:12.596496 + @@ -269,9 +269,7 @@ # is parsed as a variable expression and 'InnerFoo' is unexpected, # and a type cast is not attempted. self.expect( "frame variable '(myName)InnerFoo'", error=True, -substrs=[ -"expected 'eof', got: <'InnerFoo' (identifier)>" -], -) +substrs=["expected 'eof', got: <'InnerFoo' (identifier)>"], +) `` https://github.com/llvm/llvm-project/pull/175061 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
github-actions[bot] wrote:
:warning: C/C++ code formatter, clang-format found issues in your code.
:warning:
You can test this locally with the following command:
``bash
git-clang-format --diff origin/main HEAD --extensions h,cpp --
lldb/include/lldb/ValueObject/DILParser.h lldb/source/ValueObject/DILEval.cpp
lldb/source/ValueObject/DILParser.cpp
lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp
--diff_from_common_commit
``
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
View the diff from clang-format here.
``diff
diff --git a/lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp
b/lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp
index 4fffa1696..89676752b 100644
--- a/lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp
@@ -68,7 +68,7 @@ int main(int argc, char **argv) {
int y;
};
- struct myName myStruct = { 98, 99 };
+ struct myName myStruct = {98, 99};
int myName = 37;
return 0; // Set a breakpoint here
``
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -339,12 +405,32 @@ std::string DILParser::ParseNestedNameSpecifier() {
//
std::optional DILParser::ParseTypeId() {
CompilerType type;
- // For now only allow builtin types -- will expand add to this later.
auto maybe_builtin_type = ParseBuiltinType();
if (maybe_builtin_type) {
type = *maybe_builtin_type;
- } else
-return {};
+ } else {
+// Check to see if we have a user-defined type here.
+// First build up the user-defined type name.
+std::string type_name;
+ParseTypeSpecifierSeq(type_name);
+
+if (type_name.size() == 0)
+ return {};
+type = ResolveTypeByName(type_name, m_ctx_scope);
+if (!type.IsValid())
+ return {};
+
+// Same-name identifiers should be preferred over typenames.
+if (LookupIdentifier(type_name, m_ctx_scope, m_use_dynamic))
+ // TODO: Make type accessible with 'class', 'struct' and 'union'
keywords.
cmtice wrote:
Added the test now.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice updated
https://github.com/llvm/llvm-project/pull/175061
>From cf0161bf183944ab37c1e6952e5cd2e883b4d212 Mon Sep 17 00:00:00 2001
From: Caroline Tice
Date: Thu, 8 Jan 2026 11:45:30 -0800
Subject: [PATCH 1/3] [LLDB] Add type casting to DIL, part 3 of 3
This PR updates type parsing in DIL to recognize user-defined types
(classes, namespaces, etc.), and allows this to be used in type casting.
---
lldb/include/lldb/ValueObject/DILParser.h | 7 +
lldb/source/ValueObject/DILEval.cpp | 14 +-
lldb/source/ValueObject/DILParser.cpp | 176 +-
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 26 +++
.../frame/var-dil/expr/Casts/main.cpp | 20 ++
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : pr
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice updated
https://github.com/llvm/llvm-project/pull/175061
>From cf0161bf183944ab37c1e6952e5cd2e883b4d212 Mon Sep 17 00:00:00 2001
From: Caroline Tice
Date: Thu, 8 Jan 2026 11:45:30 -0800
Subject: [PATCH 1/2] [LLDB] Add type casting to DIL, part 3 of 3
This PR updates type parsing in DIL to recognize user-defined types
(classes, namespaces, etc.), and allows this to be used in type casting.
---
lldb/include/lldb/ValueObject/DILParser.h | 7 +
lldb/source/ValueObject/DILEval.cpp | 14 +-
lldb/source/ValueObject/DILParser.cpp | 176 +-
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 26 +++
.../frame/var-dil/expr/Casts/main.cpp | 20 ++
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : pr
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -400,6 +486,90 @@ std::optional DILParser::ParseBuiltinType() {
return {};
}
+// Parse a type_specifier_seq.
+//
+// type_specifier_seq:
+//type_specifier [type_specifier_seq]
+//
+void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
+ while (true) {
+bool type_specifier = ParseTypeSpecifier(type_name);
+if (!type_specifier) {
+ break;
+}
+ }
+}
+
+// Parse a type_specifier.
+//
+// type_specifier:
+//["::"] [nested_name_specifier] type_name
+//
+// Returns TRUE if a type_specifier was successfully parsed at this location.
+//
+bool DILParser::ParseTypeSpecifier(std::string &user_type_name) {
+ // The type_specifier must be a user-defined type. Try parsing a
+ // simple_type_specifier.
+ {
+// Try parsing optional global scope operator.
+bool global_scope = false;
+if (CurToken().Is(Token::coloncolon)) {
+ global_scope = true;
+ m_dil_lexer.Advance();
+}
+
+// uint32_t loc = CurToken().GetLocation();
+
+// Try parsing optional nested_name_specifier.
+auto nested_name_specifier = ParseNestedNameSpecifier();
+
+// Try parsing required type_name.
+auto type_name = ParseTypeName();
+
+// If there is a type_name, then this is indeed a simple_type_specifier.
+// Global and qualified (namespace/class) scopes can be empty, since
they're
+// optional. In this case type_name is type we're looking for.
+if (!type_name.empty()) {
+ // User-defined typenames can't be combined with builtin keywords.
+ user_type_name = llvm::formatv("{0}{1}{2}", global_scope ? "::" : "",
+ nested_name_specifier, type_name);
+ return true;
+}
+ }
+
+ // No type_specifier was found here.
+ return false;
+}
+
+// Parse a type_name.
+//
+// type_name:
+//class_name
+//enum_name
+//typedef_name
+//
+// class_name
+//identifier
+//
+// enum_name
+//identifier
+//
+// typedef_name
+//identifier
+//
+std::string DILParser::ParseTypeName() {
+ // Typename always starts with an identifier.
+ if (CurToken().IsNot(Token::identifier)) {
+return "";
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -400,6 +486,90 @@ std::optional DILParser::ParseBuiltinType() {
return {};
}
+// Parse a type_specifier_seq.
+//
+// type_specifier_seq:
+//type_specifier [type_specifier_seq]
+//
+void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
+ while (true) {
+bool type_specifier = ParseTypeSpecifier(type_name);
+if (!type_specifier) {
+ break;
+}
+ }
+}
+
+// Parse a type_specifier.
+//
+// type_specifier:
+//["::"] [nested_name_specifier] type_name
+//
+// Returns TRUE if a type_specifier was successfully parsed at this location.
+//
+bool DILParser::ParseTypeSpecifier(std::string &user_type_name) {
+ // The type_specifier must be a user-defined type. Try parsing a
+ // simple_type_specifier.
+ {
+// Try parsing optional global scope operator.
+bool global_scope = false;
+if (CurToken().Is(Token::coloncolon)) {
+ global_scope = true;
+ m_dil_lexer.Advance();
+}
+
+// uint32_t loc = CurToken().GetLocation();
+
+// Try parsing optional nested_name_specifier.
+auto nested_name_specifier = ParseNestedNameSpecifier();
+
+// Try parsing required type_name.
+auto type_name = ParseTypeName();
+
+// If there is a type_name, then this is indeed a simple_type_specifier.
+// Global and qualified (namespace/class) scopes can be empty, since
they're
+// optional. In this case type_name is type we're looking for.
+if (!type_name.empty()) {
+ // User-defined typenames can't be combined with builtin keywords.
+ user_type_name = llvm::formatv("{0}{1}{2}", global_scope ? "::" : "",
+ nested_name_specifier, type_name);
+ return true;
+}
+ }
+
+ // No type_specifier was found here.
+ return false;
+}
+
+// Parse a type_name.
+//
+// type_name:
+//class_name
+//enum_name
+//typedef_name
+//
+// class_name
+//identifier
+//
+// enum_name
+//identifier
+//
+// typedef_name
+//identifier
+//
+std::string DILParser::ParseTypeName() {
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -400,6 +486,90 @@ std::optional DILParser::ParseBuiltinType() {
return {};
}
+// Parse a type_specifier_seq.
+//
+// type_specifier_seq:
+//type_specifier [type_specifier_seq]
+//
+void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
+ while (true) {
+bool type_specifier = ParseTypeSpecifier(type_name);
+if (!type_specifier) {
+ break;
+}
+ }
+}
+
+// Parse a type_specifier.
+//
+// type_specifier:
+//["::"] [nested_name_specifier] type_name
+//
+// Returns TRUE if a type_specifier was successfully parsed at this location.
+//
+bool DILParser::ParseTypeSpecifier(std::string &user_type_name) {
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -339,12 +405,32 @@ std::string DILParser::ParseNestedNameSpecifier() {
//
std::optional DILParser::ParseTypeId() {
CompilerType type;
- // For now only allow builtin types -- will expand add to this later.
auto maybe_builtin_type = ParseBuiltinType();
if (maybe_builtin_type) {
type = *maybe_builtin_type;
- } else
-return {};
+ } else {
+// Check to see if we have a user-defined type here.
+// First build up the user-defined type name.
+std::string type_name;
+ParseTypeSpecifierSeq(type_name);
+
+if (type_name.size() == 0)
cmtice wrote:
Done.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
cmtice wrote:
There's SBTarget::FindTypes(const char *) and SBTarget::FindFirstType(const
char *). But those aren't for calling internally. This code in this function
is very close to the code in SBTarget::FindTypes...
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -400,6 +486,90 @@ std::optional DILParser::ParseBuiltinType() {
return {};
}
+// Parse a type_specifier_seq.
+//
+// type_specifier_seq:
+//type_specifier [type_specifier_seq]
+//
+void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
+ while (true) {
+bool type_specifier = ParseTypeSpecifier(type_name);
+if (!type_specifier) {
+ break;
+}
+ }
+}
+
+// Parse a type_specifier.
+//
+// type_specifier:
+//["::"] [nested_name_specifier] type_name
+//
+// Returns TRUE if a type_specifier was successfully parsed at this location.
+//
+bool DILParser::ParseTypeSpecifier(std::string &user_type_name) {
cmtice wrote:
Oh wait; think I was looking at the wrong thing. I might be able to make this
work. I'll give it a shot.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -339,12 +405,32 @@ std::string DILParser::ParseNestedNameSpecifier() {
//
std::optional DILParser::ParseTypeId() {
CompilerType type;
- // For now only allow builtin types -- will expand add to this later.
auto maybe_builtin_type = ParseBuiltinType();
if (maybe_builtin_type) {
type = *maybe_builtin_type;
- } else
-return {};
+ } else {
+// Check to see if we have a user-defined type here.
+// First build up the user-defined type name.
+std::string type_name;
+ParseTypeSpecifierSeq(type_name);
+
+if (type_name.size() == 0)
+ return {};
+type = ResolveTypeByName(type_name, m_ctx_scope);
+if (!type.IsValid())
+ return {};
+
+// Same-name identifiers should be preferred over typenames.
+if (LookupIdentifier(type_name, m_ctx_scope, m_use_dynamic))
+ // TODO: Make type accessible with 'class', 'struct' and 'union'
keywords.
jimingham wrote:
There are some projects we know and love (I'm looking at you, llvm) where using
the same name for types and variables is pretty common.
But given that, I think keeping some kind of disambiguation strategy - and the
one you suggested seems quite reasonable - is worthwhile.
I'd preserve the TODO's
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -400,6 +486,90 @@ std::optional DILParser::ParseBuiltinType() {
return {};
}
+// Parse a type_specifier_seq.
+//
+// type_specifier_seq:
+//type_specifier [type_specifier_seq]
+//
+void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
+ while (true) {
+bool type_specifier = ParseTypeSpecifier(type_name);
+if (!type_specifier) {
+ break;
+}
+ }
+}
+
+// Parse a type_specifier.
+//
+// type_specifier:
+//["::"] [nested_name_specifier] type_name
+//
+// Returns TRUE if a type_specifier was successfully parsed at this location.
+//
+bool DILParser::ParseTypeSpecifier(std::string &user_type_name) {
cmtice wrote:
It is not quite that easy; the 'output parameter' is ALSO an 'input parameter'.
ParseTypeSpecifier appends to it (if it is non-empty when passed in), so I
can't exactly eliminate it. Given that, I would really prefer to leave this
as-is...
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -339,12 +405,32 @@ std::string DILParser::ParseNestedNameSpecifier() {
//
std::optional DILParser::ParseTypeId() {
CompilerType type;
- // For now only allow builtin types -- will expand add to this later.
auto maybe_builtin_type = ParseBuiltinType();
if (maybe_builtin_type) {
type = *maybe_builtin_type;
- } else
-return {};
+ } else {
+// Check to see if we have a user-defined type here.
+// First build up the user-defined type name.
+std::string type_name;
+ParseTypeSpecifierSeq(type_name);
+
+if (type_name.size() == 0)
+ return {};
+type = ResolveTypeByName(type_name, m_ctx_scope);
+if (!type.IsValid())
+ return {};
+
+// Same-name identifiers should be preferred over typenames.
+if (LookupIdentifier(type_name, m_ctx_scope, m_use_dynamic))
+ // TODO: Make type accessible with 'class', 'struct' and 'union'
keywords.
cmtice wrote:
This was copied almost directly from the implementation in lldb-eval. The
intent is, at the moment, if a user-defined type (a class or struct or union)
happens to have the same name as a user-defined variable, then when we
encounter the name we only recognize it as a variable. The TODO is to
eventually allow the user to differentiate between the two by allowing the
keywords 'class', 'struct' or 'union' to be used in front of the name when a
type is meant.
That was never actually implemented in lldb-eval, and I'm not at all sure if we
want to implement it in DIL or not. If not, I can remove the TODO's.
To answer the testing question, no I don't think the new tests add coverage for
this particular case, but I will add that in.
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
Michael137 wrote:
Do we have a similar API already available to us in LLDB somewhere? Looking up
a type by name seems like we would've tried to do elsewhere already
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -400,6 +486,90 @@ std::optional DILParser::ParseBuiltinType() {
return {};
}
+// Parse a type_specifier_seq.
+//
+// type_specifier_seq:
+//type_specifier [type_specifier_seq]
+//
+void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
+ while (true) {
+bool type_specifier = ParseTypeSpecifier(type_name);
+if (!type_specifier) {
+ break;
+}
+ }
+}
+
+// Parse a type_specifier.
+//
+// type_specifier:
+//["::"] [nested_name_specifier] type_name
+//
+// Returns TRUE if a type_specifier was successfully parsed at this location.
+//
+bool DILParser::ParseTypeSpecifier(std::string &user_type_name) {
+ // The type_specifier must be a user-defined type. Try parsing a
+ // simple_type_specifier.
+ {
+// Try parsing optional global scope operator.
+bool global_scope = false;
+if (CurToken().Is(Token::coloncolon)) {
+ global_scope = true;
+ m_dil_lexer.Advance();
+}
+
+// uint32_t loc = CurToken().GetLocation();
+
+// Try parsing optional nested_name_specifier.
+auto nested_name_specifier = ParseNestedNameSpecifier();
+
+// Try parsing required type_name.
+auto type_name = ParseTypeName();
+
+// If there is a type_name, then this is indeed a simple_type_specifier.
+// Global and qualified (namespace/class) scopes can be empty, since
they're
+// optional. In this case type_name is type we're looking for.
+if (!type_name.empty()) {
+ // User-defined typenames can't be combined with builtin keywords.
+ user_type_name = llvm::formatv("{0}{1}{2}", global_scope ? "::" : "",
+ nested_name_specifier, type_name);
+ return true;
+}
+ }
+
+ // No type_specifier was found here.
+ return false;
+}
+
+// Parse a type_name.
+//
+// type_name:
+//class_name
+//enum_name
+//typedef_name
+//
+// class_name
+//identifier
+//
+// enum_name
+//identifier
+//
+// typedef_name
+//identifier
+//
+std::string DILParser::ParseTypeName() {
+ // Typename always starts with an identifier.
+ if (CurToken().IsNot(Token::identifier)) {
+return "";
Michael137 wrote:
`return std::nullopt`?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -339,12 +405,32 @@ std::string DILParser::ParseNestedNameSpecifier() {
//
std::optional DILParser::ParseTypeId() {
CompilerType type;
- // For now only allow builtin types -- will expand add to this later.
auto maybe_builtin_type = ParseBuiltinType();
if (maybe_builtin_type) {
type = *maybe_builtin_type;
- } else
-return {};
+ } else {
+// Check to see if we have a user-defined type here.
+// First build up the user-defined type name.
+std::string type_name;
+ParseTypeSpecifierSeq(type_name);
+
+if (type_name.size() == 0)
Michael137 wrote:
```suggestion
if (type_name.empty())
```
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -400,6 +486,90 @@ std::optional DILParser::ParseBuiltinType() {
return {};
}
+// Parse a type_specifier_seq.
+//
+// type_specifier_seq:
+//type_specifier [type_specifier_seq]
+//
+void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
+ while (true) {
+bool type_specifier = ParseTypeSpecifier(type_name);
+if (!type_specifier) {
+ break;
+}
+ }
+}
+
+// Parse a type_specifier.
+//
+// type_specifier:
+//["::"] [nested_name_specifier] type_name
+//
+// Returns TRUE if a type_specifier was successfully parsed at this location.
+//
+bool DILParser::ParseTypeSpecifier(std::string &user_type_name) {
Michael137 wrote:
Return `std::optional` and remove the output parameter?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -339,12 +405,32 @@ std::string DILParser::ParseNestedNameSpecifier() {
//
std::optional DILParser::ParseTypeId() {
CompilerType type;
- // For now only allow builtin types -- will expand add to this later.
auto maybe_builtin_type = ParseBuiltinType();
if (maybe_builtin_type) {
type = *maybe_builtin_type;
- } else
-return {};
+ } else {
+// Check to see if we have a user-defined type here.
+// First build up the user-defined type name.
+std::string type_name;
+ParseTypeSpecifierSeq(type_name);
+
+if (type_name.size() == 0)
+ return {};
+type = ResolveTypeByName(type_name, m_ctx_scope);
+if (!type.IsValid())
+ return {};
+
+// Same-name identifiers should be preferred over typenames.
+if (LookupIdentifier(type_name, m_ctx_scope, m_use_dynamic))
+ // TODO: Make type accessible with 'class', 'struct' and 'union'
keywords.
Michael137 wrote:
If so, do the new tests add coverage for this?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -339,12 +405,32 @@ std::string DILParser::ParseNestedNameSpecifier() {
//
std::optional DILParser::ParseTypeId() {
CompilerType type;
- // For now only allow builtin types -- will expand add to this later.
auto maybe_builtin_type = ParseBuiltinType();
if (maybe_builtin_type) {
type = *maybe_builtin_type;
- } else
-return {};
+ } else {
+// Check to see if we have a user-defined type here.
+// First build up the user-defined type name.
+std::string type_name;
+ParseTypeSpecifierSeq(type_name);
+
+if (type_name.size() == 0)
+ return {};
+type = ResolveTypeByName(type_name, m_ctx_scope);
+if (!type.IsValid())
+ return {};
+
+// Same-name identifiers should be preferred over typenames.
+if (LookupIdentifier(type_name, m_ctx_scope, m_use_dynamic))
+ // TODO: Make type accessible with 'class', 'struct' and 'union'
keywords.
Michael137 wrote:
Could you elaborate on these TODOs and what situations these blocks guard
against? Would we hit this if we had a local variable with the same name as
some type? So you want to avoid treating it as a type?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -400,6 +486,90 @@ std::optional DILParser::ParseBuiltinType() {
return {};
}
+// Parse a type_specifier_seq.
+//
+// type_specifier_seq:
+//type_specifier [type_specifier_seq]
+//
+void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
+ while (true) {
+bool type_specifier = ParseTypeSpecifier(type_name);
+if (!type_specifier) {
+ break;
+}
+ }
+}
+
+// Parse a type_specifier.
+//
+// type_specifier:
+//["::"] [nested_name_specifier] type_name
+//
+// Returns TRUE if a type_specifier was successfully parsed at this location.
+//
+bool DILParser::ParseTypeSpecifier(std::string &user_type_name) {
+ // The type_specifier must be a user-defined type. Try parsing a
+ // simple_type_specifier.
+ {
+// Try parsing optional global scope operator.
+bool global_scope = false;
+if (CurToken().Is(Token::coloncolon)) {
+ global_scope = true;
+ m_dil_lexer.Advance();
+}
+
+// uint32_t loc = CurToken().GetLocation();
+
+// Try parsing optional nested_name_specifier.
+auto nested_name_specifier = ParseNestedNameSpecifier();
+
+// Try parsing required type_name.
+auto type_name = ParseTypeName();
+
+// If there is a type_name, then this is indeed a simple_type_specifier.
+// Global and qualified (namespace/class) scopes can be empty, since
they're
+// optional. In this case type_name is type we're looking for.
+if (!type_name.empty()) {
+ // User-defined typenames can't be combined with builtin keywords.
+ user_type_name = llvm::formatv("{0}{1}{2}", global_scope ? "::" : "",
+ nested_name_specifier, type_name);
+ return true;
+}
+ }
+
+ // No type_specifier was found here.
+ return false;
+}
+
+// Parse a type_name.
+//
+// type_name:
+//class_name
+//enum_name
+//typedef_name
+//
+// class_name
+//identifier
+//
+// enum_name
+//identifier
+//
+// typedef_name
+//identifier
+//
+std::string DILParser::ParseTypeName() {
Michael137 wrote:
Return `std::optional`?
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
@@ -339,12 +405,32 @@ std::string DILParser::ParseNestedNameSpecifier() {
//
std::optional DILParser::ParseTypeId() {
CompilerType type;
- // For now only allow builtin types -- will expand add to this later.
auto maybe_builtin_type = ParseBuiltinType();
if (maybe_builtin_type) {
type = *maybe_builtin_type;
- } else
-return {};
+ } else {
+// Check to see if we have a user-defined type here.
+// First build up the user-defined type name.
+std::string type_name;
+ParseTypeSpecifierSeq(type_name);
+
+if (type_name.size() == 0)
Michael137 wrote:
Or if we use `std::optional` can check if it's valid
https://github.com/llvm/llvm-project/pull/175061
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
llvmbot wrote:
@llvm/pr-subscribers-lldb
Author: None (cmtice)
Changes
This PR updates type parsing in DIL to recognize user-defined types (classes,
namespaces, etc.), and allows this to be used in type casting.
---
Full diff: https://github.com/llvm/llvm-project/pull/175061.diff
5 Files Affected:
- (modified) lldb/include/lldb/ValueObject/DILParser.h (+7)
- (modified) lldb/source/ValueObject/DILEval.cpp (+1-13)
- (modified) lldb/source/ValueObject/DILParser.cpp (+173-3)
- (modified)
lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py (+26)
- (modified) lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp (+20)
``diff
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_type_list.push_back(type_sp->GetFullCompilerType());
+
+if (auto process_sp = target_sp->GetProcessSP()) {
+ for (auto *runtime : process_sp->GetLanguageRuntimes()) {
+if (auto *vendor = runtime->GetDeclVendor()) {
+
[Lldb-commits] [lldb] [LLDB] Add type casting to DIL, part 3 of 3 (PR #175061)
https://github.com/cmtice created
https://github.com/llvm/llvm-project/pull/175061
This PR updates type parsing in DIL to recognize user-defined types (classes,
namespaces, etc.), and allows this to be used in type casting.
>From cf0161bf183944ab37c1e6952e5cd2e883b4d212 Mon Sep 17 00:00:00 2001
From: Caroline Tice
Date: Thu, 8 Jan 2026 11:45:30 -0800
Subject: [PATCH] [LLDB] Add type casting to DIL, part 3 of 3
This PR updates type parsing in DIL to recognize user-defined types
(classes, namespaces, etc.), and allows this to be used in type casting.
---
lldb/include/lldb/ValueObject/DILParser.h | 7 +
lldb/source/ValueObject/DILEval.cpp | 14 +-
lldb/source/ValueObject/DILParser.cpp | 176 +-
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 26 +++
.../frame/var-dil/expr/Casts/main.cpp | 20 ++
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILParser.h
b/lldb/include/lldb/ValueObject/DILParser.h
index bd2fc373cd9b5..3a6261aaac5fc 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -11,6 +11,7 @@
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILLexer.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
kUnknown,
};
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx);
+
// The following is modeled on class OptionParseError.
class DILDiagnosticError
: public llvm::ErrorInfo {
@@ -103,6 +107,9 @@ class DILParser {
ASTNodeUP ParseCastExpression();
std::optional ParseBuiltinType();
std::optional ParseTypeId();
+ void ParseTypeSpecifierSeq(std::string &type_name);
+ bool ParseTypeSpecifier(std::string &user_type_name);
+ std::string ParseTypeName();
CompilerType ResolveTypeDeclarators(CompilerType type,
const std::vector &ptr_operators);
diff --git a/lldb/source/ValueObject/DILEval.cpp
b/lldb/source/ValueObject/DILEval.cpp
index 575dfae850c19..604c5da9d5aa7 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectRegister.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -43,19 +44,6 @@ GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp,
return value_sp;
}
-static llvm::Expected
-GetTypeSystemFromCU(std::shared_ptr ctx) {
- auto stack_frame = ctx->CalculateStackFrame();
- if (!stack_frame)
-return llvm::createStringError("no stack frame in this context");
- SymbolContext symbol_context =
- stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
- lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
- symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
- return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
lldb::BasicType basic_type) {
if (type_system)
diff --git a/lldb/source/ValueObject/DILParser.cpp
b/lldb/source/ValueObject/DILParser.cpp
index f3027a3d82fa2..de09dd5f612bc 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -44,6 +44,72 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
m_detail.rendered = std::move(rendered_msg);
}
+llvm::Expected
+GetTypeSystemFromCU(std::shared_ptr ctx) {
+ SymbolContext symbol_context =
+ ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+ lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+ symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+ return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+CompilerType
+ResolveTypeByName(const std::string &name,
+ std::shared_ptr ctx_scope) {
+ // Internally types don't have global scope qualifier in their names and
+ // LLDB doesn't support queries with it too.
+ llvm::StringRef name_ref(name);
+
+ if (name_ref.starts_with("::"))
+name_ref = name_ref.drop_front(2);
+
+ std::vector result_type_list;
+ lldb::TargetSP target_sp = ctx_scope->CalculateTarget();
+ const char *type_name = name_ref.data();
+ if (type_name && type_name[0] && target_sp) {
+ModuleList &images = target_sp->GetImages();
+ConstString const_type_name(type_name);
+TypeQuery query(type_name);
+TypeResults results;
+images.FindTypes(nullptr, query, results);
+for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types())
+ if (type_sp)
+result_ty
