Skip to content

[lldb] Add SB API to access static constexpr member values #89730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lldb/include/lldb/API/SBTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,7 @@ class LLDB_API SBTarget {
friend class SBSection;
friend class SBSourceManager;
friend class SBSymbol;
friend class SBTypeStaticField;
friend class SBValue;
friend class SBVariablesOptions;

Expand Down
32 changes: 32 additions & 0 deletions lldb/include/lldb/API/SBType.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,35 @@ class SBTypeMemberFunction {
lldb::TypeMemberFunctionImplSP m_opaque_sp;
};

class LLDB_API SBTypeStaticField {
public:
SBTypeStaticField();

SBTypeStaticField(const lldb::SBTypeStaticField &rhs);
lldb::SBTypeStaticField &operator=(const lldb::SBTypeStaticField &rhs);

~SBTypeStaticField();

explicit operator bool() const;

bool IsValid() const;

const char *GetName();

const char *GetMangledName();

lldb::SBType GetType();

lldb::SBValue GetConstantValue(lldb::SBTarget target);

protected:
friend class SBType;

explicit SBTypeStaticField(lldb_private::CompilerDecl decl);

std::unique_ptr<lldb_private::CompilerDecl> m_opaque_up;
};

class SBType {
public:
SBType();
Expand Down Expand Up @@ -182,6 +211,8 @@ class SBType {

lldb::SBTypeMember GetVirtualBaseClassAtIndex(uint32_t idx);

lldb::SBTypeStaticField GetStaticFieldWithName(const char *name);

lldb::SBTypeEnumMemberList GetEnumMembers();

uint32_t GetNumberOfTemplateArguments();
Expand Down Expand Up @@ -242,6 +273,7 @@ class SBType {
friend class SBTypeNameSpecifier;
friend class SBTypeMember;
friend class SBTypeMemberFunction;
friend class SBTypeStaticField;
friend class SBTypeList;
friend class SBValue;
friend class SBWatchpoint;
Expand Down
1 change: 1 addition & 0 deletions lldb/include/lldb/API/SBValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ class LLDB_API SBValue {
friend class SBModule;
friend class SBTarget;
friend class SBThread;
friend class SBTypeStaticField;
friend class SBTypeSummary;
friend class SBValueList;

Expand Down
7 changes: 7 additions & 0 deletions lldb/include/lldb/Symbol/CompilerDecl.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ class CompilerDecl {

CompilerDeclContext GetDeclContext() const;

// If this decl has a type, return it.
CompilerType GetType() const;

// If this decl represents a function, return the return type
CompilerType GetFunctionReturnType() const;

Expand All @@ -91,6 +94,10 @@ class CompilerDecl {
/// the subsequent entry, so the topmost entry is the global namespace.
std::vector<lldb_private::CompilerContext> GetCompilerContext() const;

// If decl represents a constant value, return it. Otherwise, return an
// invalid/empty Scalar.
Scalar GetConstantValue() const;

private:
TypeSystem *m_type_system = nullptr;
void *m_opaque_decl = nullptr;
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Symbol/CompilerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ class CompilerType {
CompilerType GetVirtualBaseClassAtIndex(size_t idx,
uint32_t *bit_offset_ptr) const;

CompilerDecl GetStaticFieldWithName(llvm::StringRef name) const;

uint32_t GetIndexOfFieldWithName(const char *name,
CompilerType *field_compiler_type = nullptr,
uint64_t *bit_offset_ptr = nullptr,
Expand Down
9 changes: 9 additions & 0 deletions lldb/include/lldb/Symbol/TypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
#include "lldb/lldb-types.h"

Expand Down Expand Up @@ -110,6 +112,8 @@ class TypeSystem : public PluginInterface,
virtual std::vector<lldb_private::CompilerContext>
DeclGetCompilerContext(void *opaque_decl);

virtual Scalar DeclGetConstantValue(void *opaque_decl) { return Scalar(); }

virtual CompilerType GetTypeForDecl(void *opaque_decl) = 0;

// CompilerDeclContext functions
Expand Down Expand Up @@ -339,6 +343,11 @@ class TypeSystem : public PluginInterface,
GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
uint32_t *bit_offset_ptr) = 0;

virtual CompilerDecl GetStaticFieldWithName(lldb::opaque_compiler_type_t type,
llvm::StringRef name) {
return CompilerDecl();
}

virtual CompilerType GetChildCompilerTypeAtIndex(
lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
bool transparent_pointers, bool omit_empty_base_classes,
Expand Down
88 changes: 88 additions & 0 deletions lldb/source/API/SBType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@
//===----------------------------------------------------------------------===//

#include "lldb/API/SBType.h"
#include "Utils.h"
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBModule.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTypeEnumMember.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Instrumentation.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Stream.h"

#include "llvm/ADT/APSInt.h"
Expand Down Expand Up @@ -325,6 +330,79 @@ lldb::SBTypeMemberFunction SBType::GetMemberFunctionAtIndex(uint32_t idx) {
return sb_func_type;
}

SBTypeStaticField::SBTypeStaticField() { LLDB_INSTRUMENT_VA(this); }

SBTypeStaticField::SBTypeStaticField(lldb_private::CompilerDecl decl)
: m_opaque_up(decl ? std::make_unique<CompilerDecl>(decl) : nullptr) {}

SBTypeStaticField::SBTypeStaticField(const SBTypeStaticField &rhs) {
LLDB_INSTRUMENT_VA(this, rhs);

m_opaque_up = clone(rhs.m_opaque_up);
}

SBTypeStaticField &SBTypeStaticField::operator=(const SBTypeStaticField &rhs) {
LLDB_INSTRUMENT_VA(this, rhs);

m_opaque_up = clone(rhs.m_opaque_up);
return *this;
}

SBTypeStaticField::~SBTypeStaticField() { LLDB_INSTRUMENT_VA(this); }

SBTypeStaticField::operator bool() const {
LLDB_INSTRUMENT_VA(this);

return IsValid();
}

bool SBTypeStaticField::IsValid() const {
LLDB_INSTRUMENT_VA(this);

return m_opaque_up != nullptr;
}

const char *SBTypeStaticField::GetName() {
LLDB_INSTRUMENT_VA(this);

if (!IsValid())
return "";
return m_opaque_up->GetName().GetCString();
}

const char *SBTypeStaticField::GetMangledName() {
LLDB_INSTRUMENT_VA(this);

if (!IsValid())
return "";
return m_opaque_up->GetMangledName().GetCString();
}

SBType SBTypeStaticField::GetType() {
LLDB_INSTRUMENT_VA(this);

if (!IsValid())
return SBType();
return SBType(m_opaque_up->GetType());
}

SBValue SBTypeStaticField::GetConstantValue(lldb::SBTarget target) {
LLDB_INSTRUMENT_VA(this, target);

if (!IsValid())
return SBValue();

Scalar value = m_opaque_up->GetConstantValue();
if (!value.IsValid())
return SBValue();
DataExtractor data;
value.GetData(data);
auto value_obj_sp = ValueObjectConstResult::Create(
target.GetSP().get(), m_opaque_up->GetType(), m_opaque_up->GetName(),
data);
return SBValue(std::move(value_obj_sp));
}

lldb::SBType SBType::GetUnqualifiedType() {
LLDB_INSTRUMENT_VA(this);

Expand Down Expand Up @@ -438,6 +516,16 @@ SBTypeMember SBType::GetVirtualBaseClassAtIndex(uint32_t idx) {
return sb_type_member;
}

SBTypeStaticField SBType::GetStaticFieldWithName(const char *name) {
LLDB_INSTRUMENT_VA(this, name);

if (!IsValid() || !name)
return SBTypeStaticField();

return SBTypeStaticField(m_opaque_sp->GetCompilerType(/*prefer_dynamic=*/true)
.GetStaticFieldWithName(name));
}

SBTypeEnumMemberList SBType::GetEnumMembers() {
LLDB_INSTRUMENT_VA(this);

Expand Down
52 changes: 52 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "TypeSystemClang.h"

#include "clang/AST/DeclBase.h"
#include "clang/AST/ExprCXX.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
Expand Down Expand Up @@ -1145,6 +1146,8 @@ CompilerType TypeSystemClang::GetTypeForDecl(clang::NamedDecl *decl) {
return GetTypeForDecl(interface_decl);
if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
return GetTypeForDecl(tag_decl);
if (clang::ValueDecl *value_decl = llvm::dyn_cast<clang::ValueDecl>(decl))
return GetTypeForDecl(value_decl);
return CompilerType();
}

Expand All @@ -1156,6 +1159,10 @@ CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) {
return GetType(getASTContext().getObjCInterfaceType(decl));
}

CompilerType TypeSystemClang::GetTypeForDecl(clang::ValueDecl *value_decl) {
return GetType(value_decl->getType());
}

#pragma mark Structure, Unions, Classes

void TypeSystemClang::SetOwningModule(clang::Decl *decl,
Expand Down Expand Up @@ -5900,6 +5907,36 @@ CompilerType TypeSystemClang::GetVirtualBaseClassAtIndex(
return CompilerType();
}

CompilerDecl
TypeSystemClang::GetStaticFieldWithName(lldb::opaque_compiler_type_t type,
llvm::StringRef name) {
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
switch (qual_type->getTypeClass()) {
case clang::Type::Record: {
if (!GetCompleteType(type))
return CompilerDecl();

const clang::RecordType *record_type =
llvm::cast<clang::RecordType>(qual_type.getTypePtr());
const clang::RecordDecl *record_decl = record_type->getDecl();

clang::DeclarationName decl_name(&getASTContext().Idents.get(name));
for (NamedDecl *decl : record_decl->lookup(decl_name)) {
auto *var_decl = dyn_cast<clang::VarDecl>(decl);
if (!var_decl || var_decl->getStorageClass() != clang::SC_Static)
continue;

return CompilerDecl(this, var_decl);
}
break;
}

default:
break;
}
return CompilerDecl();
}

// If a pointer to a pointee type (the clang_type arg) says that it has no
// children, then we either need to trust it, or override it and return a
// different result. For example, an "int *" has one child that is an integer,
Expand Down Expand Up @@ -9074,6 +9111,21 @@ CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl,
return CompilerType();
}

Scalar TypeSystemClang::DeclGetConstantValue(void *opaque_decl) {
clang::Decl *decl = static_cast<clang::Decl *>(opaque_decl);
clang::VarDecl *var_decl = llvm::dyn_cast<clang::VarDecl>(decl);
if (!var_decl)
return Scalar();
clang::Expr *init_expr = var_decl->getInit();
if (!init_expr)
return Scalar();
std::optional<llvm::APSInt> value =
init_expr->getIntegerConstantExpr(getASTContext());
if (!value)
return Scalar();
return Scalar(*value);
}

// CompilerDeclContext functions

std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName(
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Decl.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/TargetInfo.h"
Expand Down Expand Up @@ -251,6 +252,8 @@ class TypeSystemClang : public TypeSystem {

CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl);

CompilerType GetTypeForDecl(clang::ValueDecl *value_decl);

template <typename RecordDeclType>
CompilerType
GetTypeForIdentifier(llvm::StringRef type_name,
Expand Down Expand Up @@ -559,6 +562,8 @@ class TypeSystemClang : public TypeSystem {
std::vector<lldb_private::CompilerContext>
DeclGetCompilerContext(void *opaque_decl) override;

Scalar DeclGetConstantValue(void *opaque_decl) override;

CompilerType GetTypeForDecl(void *opaque_decl) override;

// CompilerDeclContext override functions
Expand Down Expand Up @@ -868,6 +873,9 @@ class TypeSystemClang : public TypeSystem {
size_t idx,
uint32_t *bit_offset_ptr) override;

CompilerDecl GetStaticFieldWithName(lldb::opaque_compiler_type_t type,
llvm::StringRef name) override;

static uint32_t GetNumPointeeChildren(clang::QualType type);

CompilerType GetChildCompilerTypeAtIndex(
Expand Down
9 changes: 9 additions & 0 deletions lldb/source/Symbol/CompilerDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/Scalar.h"

using namespace lldb_private;

Expand All @@ -24,6 +25,10 @@ CompilerDeclContext CompilerDecl::GetDeclContext() const {
return m_type_system->DeclGetDeclContext(m_opaque_decl);
}

CompilerType CompilerDecl::GetType() const {
return m_type_system->GetTypeForDecl(m_opaque_decl);
}

CompilerType CompilerDecl::GetFunctionReturnType() const {
return m_type_system->DeclGetFunctionReturnType(m_opaque_decl);
}
Expand Down Expand Up @@ -52,3 +57,7 @@ std::vector<lldb_private::CompilerContext>
CompilerDecl::GetCompilerContext() const {
return m_type_system->DeclGetCompilerContext(m_opaque_decl);
}

Scalar CompilerDecl::GetConstantValue() const {
return m_type_system->DeclGetConstantValue(m_opaque_decl);
}
Loading