blob: eaa150e78ace9b154c3061496305f83443c5b5f3 [file] [log] [blame]
//===-- Type.h --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_Type_h_
#define liblldb_Type_h_
#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/UserID.h"
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/Declaration.h"
#include "llvm/ADT/APSInt.h"
#include <set>
namespace lldb_private {
class SymbolFileType :
public std::enable_shared_from_this<SymbolFileType>,
public UserID
{
public:
SymbolFileType (SymbolFile &symbol_file, lldb::user_id_t uid) :
UserID (uid),
m_symbol_file (symbol_file)
{
}
~SymbolFileType ()
{
}
Type *
operator->()
{
return GetType ();
}
Type *
GetType ();
protected:
SymbolFile &m_symbol_file;
lldb::TypeSP m_type_sp;
};
class Type :
public std::enable_shared_from_this<Type>,
public UserID
{
public:
typedef enum EncodingDataTypeTag
{
eEncodingInvalid,
eEncodingIsUID, ///< This type is the type whose UID is m_encoding_uid
eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid with the const qualifier added
eEncodingIsRestrictUID, ///< This type is the type whose UID is m_encoding_uid with the restrict qualifier added
eEncodingIsVolatileUID, ///< This type is the type whose UID is m_encoding_uid with the volatile qualifier added
eEncodingIsTypedefUID, ///< This type is pointer to a type whose UID is m_encoding_uid
eEncodingIsPointerUID, ///< This type is pointer to a type whose UID is m_encoding_uid
eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type whose UID is m_encoding_uid
eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type whose UID is m_encoding_uid
eEncodingIsSyntheticUID
} EncodingDataType;
typedef enum ResolveStateTag
{
eResolveStateUnresolved = 0,
eResolveStateForward = 1,
eResolveStateLayout = 2,
eResolveStateFull = 3
} ResolveState;
Type (lldb::user_id_t uid,
SymbolFile* symbol_file,
const ConstString &name,
uint64_t byte_size,
SymbolContextScope *context,
lldb::user_id_t encoding_uid,
EncodingDataType encoding_uid_type,
const Declaration& decl,
const ClangASTType &clang_qual_type,
ResolveState clang_type_resolve_state);
// This makes an invalid type. Used for functions that return a Type when they
// get an error.
Type();
Type (const Type &rhs);
const Type&
operator= (const Type& rhs);
void
Dump(Stream *s, bool show_context);
void
DumpTypeName(Stream *s);
// Since Type instances only keep a "SymbolFile *" internally, other classes
// like TypeImpl need make sure the module is still around before playing with
// Type instances. They can store a weak pointer to the Module;
lldb::ModuleSP
GetModule();
void
GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name);
SymbolFile *
GetSymbolFile()
{
return m_symbol_file;
}
const SymbolFile *
GetSymbolFile() const
{
return m_symbol_file;
}
TypeList*
GetTypeList();
const ConstString&
GetName();
uint64_t
GetByteSize();
uint32_t
GetNumChildren (bool omit_empty_base_classes);
bool
IsAggregateType ();
bool
IsValidType ()
{
return m_encoding_uid_type != eEncodingInvalid;
}
bool
IsTypedef ()
{
return m_encoding_uid_type == eEncodingIsTypedefUID;
}
lldb::TypeSP
GetTypedefType();
const ConstString &
GetName () const
{
return m_name;
}
ConstString
GetQualifiedName ();
void
DumpValue(ExecutionContext *exe_ctx,
Stream *s,
const DataExtractor &data,
uint32_t data_offset,
bool show_type,
bool show_summary,
bool verbose,
lldb::Format format = lldb::eFormatDefault);
bool
DumpValueInMemory(ExecutionContext *exe_ctx,
Stream *s,
lldb::addr_t address,
AddressType address_type,
bool show_types,
bool show_summary,
bool verbose);
bool
ReadFromMemory (ExecutionContext *exe_ctx,
lldb::addr_t address,
AddressType address_type,
DataExtractor &data);
bool
WriteToMemory (ExecutionContext *exe_ctx,
lldb::addr_t address,
AddressType address_type,
DataExtractor &data);
bool
GetIsDeclaration() const;
void
SetIsDeclaration(bool b);
bool
GetIsExternal() const;
void
SetIsExternal(bool b);
lldb::Format
GetFormat ();
lldb::Encoding
GetEncoding (uint64_t &count);
SymbolContextScope *
GetSymbolContextScope()
{
return m_context;
}
const SymbolContextScope *
GetSymbolContextScope() const
{
return m_context;
}
void
SetSymbolContextScope(SymbolContextScope *context)
{
m_context = context;
}
const lldb_private::Declaration &
GetDeclaration () const;
// Get the clang type, and resolve definitions for any
// class/struct/union/enum types completely.
ClangASTType
GetClangFullType ();
// Get the clang type, and resolve definitions enough so that the type could
// have layout performed. This allows ptrs and refs to class/struct/union/enum
// types remain forward declarations.
ClangASTType
GetClangLayoutType ();
// Get the clang type and leave class/struct/union/enum types as forward
// declarations if they haven't already been fully defined.
ClangASTType
GetClangForwardType ();
ClangASTContext &
GetClangASTContext ();
static int
Compare(const Type &a, const Type &b);
// From a fully qualified typename, split the type into the type basename
// and the remaining type scope (namespaces/classes).
static bool
GetTypeScopeAndBasename (const char* &name_cstr,
std::string &scope,
std::string &basename,
lldb::TypeClass &type_class);
void
SetEncodingType (Type *encoding_type)
{
m_encoding_type = encoding_type;
}
uint32_t
GetEncodingMask ();
ClangASTType
CreateClangTypedefType (Type *typedef_type, Type *base_type);
bool
IsRealObjCClass();
bool
IsCompleteObjCClass()
{
return m_flags.is_complete_objc_class;
}
void
SetIsCompleteObjCClass(bool is_complete_objc_class)
{
m_flags.is_complete_objc_class = is_complete_objc_class;
}
protected:
ConstString m_name;
SymbolFile *m_symbol_file;
SymbolContextScope *m_context; // The symbol context in which this type is defined
Type *m_encoding_type;
lldb::user_id_t m_encoding_uid;
EncodingDataType m_encoding_uid_type;
uint64_t m_byte_size;
Declaration m_decl;
ClangASTType m_clang_type;
struct Flags {
ResolveState clang_type_resolve_state : 2;
bool is_complete_objc_class : 1;
} m_flags;
Type *
GetEncodingType ();
bool
ResolveClangType (ResolveState clang_type_resolve_state);
};
// these classes are used to back the SBType* objects
class TypePair
{
public:
TypePair () :
clang_type(),
type_sp()
{
}
TypePair (ClangASTType type) :
clang_type(type),
type_sp()
{
}
TypePair (lldb::TypeSP type) :
clang_type(),
type_sp(type)
{
clang_type = type_sp->GetClangForwardType();
}
bool
IsValid () const
{
return clang_type.IsValid() || (type_sp.get() != nullptr);
}
explicit operator bool () const
{
return IsValid();
}
bool
operator == (const TypePair& rhs) const
{
return clang_type == rhs.clang_type &&
type_sp.get() == rhs.type_sp.get();
}
bool
operator != (const TypePair& rhs) const
{
return clang_type != rhs.clang_type ||
type_sp.get() != rhs.type_sp.get();
}
void
Clear ()
{
clang_type.Clear();
type_sp.reset();
}
ConstString
GetName () const
{
if (type_sp)
return type_sp->GetName();
if (clang_type)
return clang_type.GetTypeName();
return ConstString ();
}
ConstString
GetDisplayTypeName () const
{
if (type_sp)
return type_sp->GetClangForwardType().GetDisplayTypeName();
if (clang_type)
return clang_type.GetDisplayTypeName();
return ConstString();
}
void
SetType (ClangASTType type)
{
type_sp.reset();
clang_type = type;
}
void
SetType (lldb::TypeSP type)
{
type_sp = type;
clang_type = type_sp->GetClangForwardType();
}
lldb::TypeSP
GetTypeSP () const
{
return type_sp;
}
ClangASTType
GetClangASTType () const
{
return clang_type;
}
ClangASTType
GetPointerType () const
{
if (type_sp)
return type_sp->GetClangLayoutType().GetPointerType();
return clang_type.GetPointerType();
}
ClangASTType
GetPointeeType () const
{
if (type_sp)
return type_sp->GetClangFullType().GetPointeeType();
return clang_type.GetPointeeType();
}
ClangASTType
GetReferenceType () const
{
if (type_sp)
return type_sp->GetClangLayoutType().GetLValueReferenceType();
return clang_type.GetLValueReferenceType();
}
ClangASTType
GetTypedefedType () const
{
if (type_sp)
return type_sp->GetClangFullType().GetTypedefedType();
return clang_type.GetTypedefedType();
}
ClangASTType
GetDereferencedType () const
{
if (type_sp)
return type_sp->GetClangFullType().GetNonReferenceType();
return clang_type.GetNonReferenceType();
}
ClangASTType
GetUnqualifiedType () const
{
if (type_sp)
return type_sp->GetClangLayoutType().GetFullyUnqualifiedType();
return clang_type.GetFullyUnqualifiedType();
}
ClangASTType
GetCanonicalType () const
{
if (type_sp)
return type_sp->GetClangFullType().GetCanonicalType();
return clang_type.GetCanonicalType();
}
clang::ASTContext *
GetClangASTContext () const
{
return clang_type.GetASTContext();
}
lldb::ModuleSP
GetModule () const
{
if (type_sp)
return type_sp->GetModule();
return lldb::ModuleSP();
}
protected:
ClangASTType clang_type;
lldb::TypeSP type_sp;
};
class TypeImpl
{
public:
TypeImpl();
~TypeImpl () {}
TypeImpl(const TypeImpl& rhs);
TypeImpl (const lldb::TypeSP &type_sp);
TypeImpl (const ClangASTType &clang_type);
TypeImpl (const lldb::TypeSP &type_sp, const ClangASTType &dynamic);
TypeImpl (const ClangASTType &clang_type, const ClangASTType &dynamic);
TypeImpl (const TypePair &pair, const ClangASTType &dynamic);
void
SetType (const lldb::TypeSP &type_sp);
void
SetType (const ClangASTType &clang_type);
void
SetType (const lldb::TypeSP &type_sp, const ClangASTType &dynamic);
void
SetType (const ClangASTType &clang_type, const ClangASTType &dynamic);
void
SetType (const TypePair &pair, const ClangASTType &dynamic);
TypeImpl&
operator = (const TypeImpl& rhs);
bool
operator == (const TypeImpl& rhs) const;
bool
operator != (const TypeImpl& rhs) const;
bool
IsValid() const;
explicit operator bool () const;
void Clear();
ConstString
GetName () const;
ConstString
GetDisplayTypeName () const;
TypeImpl
GetPointerType () const;
TypeImpl
GetPointeeType () const;
TypeImpl
GetReferenceType () const;
TypeImpl
GetTypedefedType () const;
TypeImpl
GetDereferencedType () const;
TypeImpl
GetUnqualifiedType() const;
TypeImpl
GetCanonicalType() const;
ClangASTType
GetClangASTType (bool prefer_dynamic);
clang::ASTContext *
GetClangASTContext (bool prefer_dynamic);
bool
GetDescription (lldb_private::Stream &strm,
lldb::DescriptionLevel description_level);
private:
bool
CheckModule (lldb::ModuleSP &module_sp) const;
lldb::ModuleWP m_module_wp;
TypePair m_static_type;
ClangASTType m_dynamic_type;
};
class TypeListImpl
{
public:
TypeListImpl() :
m_content()
{
}
void
Append (const lldb::TypeImplSP& type)
{
m_content.push_back(type);
}
class AppendVisitor
{
public:
AppendVisitor(TypeListImpl &type_list) :
m_type_list(type_list)
{
}
void
operator() (const lldb::TypeImplSP& type)
{
m_type_list.Append(type);
}
private:
TypeListImpl &m_type_list;
};
void
Append (const lldb_private::TypeList &type_list);
lldb::TypeImplSP
GetTypeAtIndex(size_t idx)
{
lldb::TypeImplSP type_sp;
if (idx < GetSize())
type_sp = m_content[idx];
return type_sp;
}
size_t
GetSize()
{
return m_content.size();
}
private:
std::vector<lldb::TypeImplSP> m_content;
};
class TypeMemberImpl
{
public:
TypeMemberImpl () :
m_type_impl_sp (),
m_bit_offset (0),
m_name (),
m_bitfield_bit_size (0),
m_is_bitfield (false)
{
}
TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp,
uint64_t bit_offset,
const ConstString &name,
uint32_t bitfield_bit_size = 0,
bool is_bitfield = false) :
m_type_impl_sp (type_impl_sp),
m_bit_offset (bit_offset),
m_name (name),
m_bitfield_bit_size (bitfield_bit_size),
m_is_bitfield (is_bitfield)
{
}
TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp,
uint64_t bit_offset):
m_type_impl_sp (type_impl_sp),
m_bit_offset (bit_offset),
m_name (),
m_bitfield_bit_size (0),
m_is_bitfield (false)
{
if (m_type_impl_sp)
m_name = m_type_impl_sp->GetName();
}
const lldb::TypeImplSP &
GetTypeImpl ()
{
return m_type_impl_sp;
}
const ConstString &
GetName () const
{
return m_name;
}
uint64_t
GetBitOffset () const
{
return m_bit_offset;
}
uint32_t
GetBitfieldBitSize () const
{
return m_bitfield_bit_size;
}
void
SetBitfieldBitSize (uint32_t bitfield_bit_size)
{
m_bitfield_bit_size = bitfield_bit_size;
}
bool
GetIsBitfield () const
{
return m_is_bitfield;
}
void
SetIsBitfield (bool is_bitfield)
{
m_is_bitfield = is_bitfield;
}
protected:
lldb::TypeImplSP m_type_impl_sp;
uint64_t m_bit_offset;
ConstString m_name;
uint32_t m_bitfield_bit_size; // Bit size for bitfield members only
bool m_is_bitfield;
};
///
/// Sometimes you can find the name of the type corresponding to an object, but we don't have debug
/// information for it. If that is the case, you can return one of these objects, and then if it
/// has a full type, you can use that, but if not at least you can print the name for informational
/// purposes.
///
class TypeAndOrName
{
public:
TypeAndOrName ();
TypeAndOrName (lldb::TypeSP &type_sp);
TypeAndOrName (const ClangASTType &clang_type);
TypeAndOrName (const char *type_str);
TypeAndOrName (const TypeAndOrName &rhs);
TypeAndOrName (ConstString &type_const_string);
TypeAndOrName &
operator= (const TypeAndOrName &rhs);
bool
operator==(const TypeAndOrName &other) const;
bool
operator!=(const TypeAndOrName &other) const;
ConstString GetName () const;
lldb::TypeSP
GetTypeSP () const
{
return m_type_pair.GetTypeSP();
}
ClangASTType
GetClangASTType () const
{
return m_type_pair.GetClangASTType();
}
void
SetName (const ConstString &type_name);
void
SetName (const char *type_name_cstr);
void
SetTypeSP (lldb::TypeSP type_sp);
void
SetClangASTType (ClangASTType clang_type);
bool
IsEmpty () const;
bool
HasName () const;
bool
HasTypeSP () const;
bool
HasClangASTType () const;
bool
HasType () const
{
return HasTypeSP() || HasClangASTType();
}
void
Clear ();
explicit operator bool ()
{
return !IsEmpty();
}
private:
TypePair m_type_pair;
ConstString m_type_name;
};
class TypeEnumMemberImpl
{
public:
TypeEnumMemberImpl () :
m_integer_type_sp(),
m_name("<invalid>"),
m_value(),
m_valid(false)
{
}
TypeEnumMemberImpl (const clang::EnumConstantDecl* enum_member_decl,
const lldb_private::ClangASTType& integer_type);
TypeEnumMemberImpl (const TypeEnumMemberImpl& rhs) :
m_integer_type_sp(rhs.m_integer_type_sp),
m_name(rhs.m_name),
m_value(rhs.m_value),
m_valid(rhs.m_valid)
{
}
TypeEnumMemberImpl&
operator = (const TypeEnumMemberImpl& rhs);
bool
IsValid ()
{
return m_valid;
}
const ConstString &
GetName () const
{
return m_name;
}
const lldb::TypeImplSP &
GetIntegerType () const
{
return m_integer_type_sp;
}
uint64_t
GetValueAsUnsigned () const
{
return *m_value.getRawData();
}
int64_t
GetValueAsSigned () const
{
return (int64_t) *m_value.getRawData();
}
protected:
lldb::TypeImplSP m_integer_type_sp;
ConstString m_name;
llvm::APSInt m_value;
bool m_valid;
};
class TypeEnumMemberListImpl
{
public:
TypeEnumMemberListImpl() :
m_content()
{
}
void
Append (const lldb::TypeEnumMemberImplSP& type)
{
m_content.push_back(type);
}
void
Append (const lldb_private::TypeEnumMemberListImpl& type_list);
lldb::TypeEnumMemberImplSP
GetTypeEnumMemberAtIndex(size_t idx)
{
lldb::TypeEnumMemberImplSP enum_member;
if (idx < GetSize())
enum_member = m_content[idx];
return enum_member;
}
size_t
GetSize()
{
return m_content.size();
}
private:
std::vector<lldb::TypeEnumMemberImplSP> m_content;
};
} // namespace lldb_private
#endif // liblldb_Type_h_