
Summary: This patch adds support for evaluation of expressions referring to types which were compiled in -flimit-debug-info (a.k.a -fno-standalone-debug) in clang. In this mode it's possible that the debug information needed to fully describe a c++ type is not present in a single shared library -- for example debug info for a base class or a member of a type can only be found in another shared library. This situation is not currently handled well within lldb as we are limited to searching within a single shared library (lldb_private::Module) when searching for the definition of these types. The way that this patch gets around this limitation is by doing the search at a later stage -- during the construction of the expression ast context. This works by having the parser (currently SymbolFileDWARF, but a similar approach is probably needed for PDBs too) mark a type as "forcefully completed". What this means is that the parser has marked the type as "complete" in the module ast context (as this is necessary to e.g. derive classes from it), but its definition is not really there. This is done via a new field on the ClangASTMetadata struct. Later, when we are importing such a type into the expression ast, we check this flag. If the flag is set, we try to find a better definition for the type in other shared libraries. We do this by initiating a new lookup for the "forcefully completed" classes, which then imports the type from a module with a full definition. This patch only implements this handling for base classes, but other cases (members, array element types, etc.). The changes for that should be fairly simple and mostly revolve around marking these types as "forcefully completed" at an approriate time -- the importing logic is generic already. Another aspect, which is also not handled by this patch is viewing these types via the "frame variable" command. This does not use the AST importer and so it will need to handle these types on its own -- that will be the subject of another patch. Differential Revision: https://reviews.llvm.org/D81561
111 lines
2.9 KiB
C++
111 lines
2.9 KiB
C++
//===-- ClangASTMetadata.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_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
|
|
#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
|
|
|
|
#include "lldb/Core/dwarf.h"
|
|
#include "lldb/lldb-defines.h"
|
|
#include "lldb/lldb-enumerations.h"
|
|
|
|
namespace lldb_private {
|
|
|
|
class ClangASTMetadata {
|
|
public:
|
|
ClangASTMetadata()
|
|
: m_user_id(0), m_union_is_user_id(false), m_union_is_isa_ptr(false),
|
|
m_has_object_ptr(false), m_is_self(false), m_is_dynamic_cxx(true),
|
|
m_is_forcefully_completed(false) {}
|
|
|
|
bool GetIsDynamicCXXType() const { return m_is_dynamic_cxx; }
|
|
|
|
void SetIsDynamicCXXType(bool b) { m_is_dynamic_cxx = b; }
|
|
|
|
void SetUserID(lldb::user_id_t user_id) {
|
|
m_user_id = user_id;
|
|
m_union_is_user_id = true;
|
|
m_union_is_isa_ptr = false;
|
|
}
|
|
|
|
lldb::user_id_t GetUserID() const {
|
|
if (m_union_is_user_id)
|
|
return m_user_id;
|
|
else
|
|
return LLDB_INVALID_UID;
|
|
}
|
|
|
|
void SetISAPtr(uint64_t isa_ptr) {
|
|
m_isa_ptr = isa_ptr;
|
|
m_union_is_user_id = false;
|
|
m_union_is_isa_ptr = true;
|
|
}
|
|
|
|
uint64_t GetISAPtr() const {
|
|
if (m_union_is_isa_ptr)
|
|
return m_isa_ptr;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void SetObjectPtrName(const char *name) {
|
|
m_has_object_ptr = true;
|
|
if (strcmp(name, "self") == 0)
|
|
m_is_self = true;
|
|
else if (strcmp(name, "this") == 0)
|
|
m_is_self = false;
|
|
else
|
|
m_has_object_ptr = false;
|
|
}
|
|
|
|
lldb::LanguageType GetObjectPtrLanguage() const {
|
|
if (m_has_object_ptr) {
|
|
if (m_is_self)
|
|
return lldb::eLanguageTypeObjC;
|
|
else
|
|
return lldb::eLanguageTypeC_plus_plus;
|
|
}
|
|
return lldb::eLanguageTypeUnknown;
|
|
}
|
|
|
|
const char *GetObjectPtrName() const {
|
|
if (m_has_object_ptr) {
|
|
if (m_is_self)
|
|
return "self";
|
|
else
|
|
return "this";
|
|
} else
|
|
return nullptr;
|
|
}
|
|
|
|
bool HasObjectPtr() const { return m_has_object_ptr; }
|
|
|
|
/// A type is "forcefully completed" if it was declared complete to satisfy an
|
|
/// AST invariant (e.g. base classes must be complete types), but in fact we
|
|
/// were not able to find a actual definition for it.
|
|
bool IsForcefullyCompleted() const { return m_is_forcefully_completed; }
|
|
|
|
void SetIsForcefullyCompleted(bool value = true) {
|
|
m_is_forcefully_completed = true;
|
|
}
|
|
|
|
void Dump(Stream *s);
|
|
|
|
private:
|
|
union {
|
|
lldb::user_id_t m_user_id;
|
|
uint64_t m_isa_ptr;
|
|
};
|
|
|
|
bool m_union_is_user_id : 1, m_union_is_isa_ptr : 1, m_has_object_ptr : 1,
|
|
m_is_self : 1, m_is_dynamic_cxx : 1, m_is_forcefully_completed : 1;
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
|