Pavel Labath 565bdb5545
[lldb] Add SB API to access static constexpr member values (#89730)
The main change is the addition of a new SBTypeStaticField class,
representing a static member of a class. It can be retrieved created
through SBType::GetStaticFieldWithName. It contains several methods
(GetName, GetMangledName, etc.) whose meaning is hopefully obvious. The
most interesting method is
	lldb::SBValue GetConstantValue(lldb::SBTarget)
which returns a the value of the field -- if it is a compile time
constant. The reason for that is that only constants have their values
represented in the clang AST.

For non-constants, we need to go back to the module containing that
constant, and ask retrieve the associated ValueObjectVariable. That's
easy enough if the we are still in the type system of the module
(because then the type system will contain the pointer to the module
symbol file), but it's hard when the type has been copied into another
AST (e.g. during expression evaluation). To do that we would need to
walk the ast import chain backwards to find the source TypeSystem, and I
haven't found a nice way to do that.

Another possibility would be to use the mangled name of the variable to
perform a lookup (in all modules). That is sort of what happens when
evaluating the variable in an expression (which does work), but I did
not want to commit to that implementation as it's not necessary for my
use case (and if anyone wants to, he can use the GetMangledName function
and perform the lookup manually).

The patch adds a couple of new TypeSystem functions to surface the
information needed to implement this functionality.
2024-04-25 09:06:48 +02:00

112 lines
3.5 KiB
C++

//===-- CompilerDecl.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_SYMBOL_COMPILERDECL_H
#define LLDB_SYMBOL_COMPILERDECL_H
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
namespace lldb_private {
/// Represents a generic declaration such as a function declaration.
///
/// This class serves as an abstraction for a declaration inside one of the
/// TypeSystems implemented by the language plugins. It does not have any actual
/// logic in it but only stores an opaque pointer and a pointer to the
/// TypeSystem that gives meaning to this opaque pointer. All methods of this
/// class should call their respective method in the TypeSystem interface and
/// pass the opaque pointer along.
///
/// \see lldb_private::TypeSystem
class CompilerDecl {
public:
// Constructors and Destructors
CompilerDecl() = default;
/// Creates a CompilerDecl with the given TypeSystem and opaque pointer.
///
/// This constructor should only be called from the respective TypeSystem
/// implementation.
CompilerDecl(TypeSystem *type_system, void *decl)
: m_type_system(type_system), m_opaque_decl(decl) {}
// Tests
explicit operator bool() const { return IsValid(); }
bool operator<(const CompilerDecl &rhs) const {
if (m_type_system == rhs.m_type_system)
return m_opaque_decl < rhs.m_opaque_decl;
return m_type_system < rhs.m_type_system;
}
bool IsValid() const {
return m_type_system != nullptr && m_opaque_decl != nullptr;
}
// Accessors
TypeSystem *GetTypeSystem() const { return m_type_system; }
void *GetOpaqueDecl() const { return m_opaque_decl; }
void SetDecl(TypeSystem *type_system, void *decl) {
m_type_system = type_system;
m_opaque_decl = decl;
}
void Clear() {
m_type_system = nullptr;
m_opaque_decl = nullptr;
}
ConstString GetName() const;
ConstString GetMangledName() const;
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;
// If this decl represents a function, return the number of arguments for the
// function
size_t GetNumFunctionArguments() const;
// If this decl represents a function, return the argument type given a zero
// based argument index
CompilerType GetFunctionArgumentType(size_t arg_idx) const;
/// Populate a valid compiler context from the current declaration.
///
/// \returns A valid vector of CompilerContext entries that describes
/// this declaration. The first entry in the vector is the parent of
/// 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;
};
bool operator==(const CompilerDecl &lhs, const CompilerDecl &rhs);
bool operator!=(const CompilerDecl &lhs, const CompilerDecl &rhs);
} // namespace lldb_private
#endif // LLDB_SYMBOL_COMPILERDECL_H