This fixes a regression caused by us starting to parse types from declarations. The code in TypeSystemClang was assuming that the value held in ClangASTMetadata was authoritative, but this isn't (and cannot) be the case when the type is parsed from a forward-declaration. For the fix, I add a new "don't know" state to ClangASTMetadata, and make sure DWARFASTParserClang sets it only when it encounters a forward declaration. In this case, the type system will fall back to completing the type. This does mean that we will be completing more types than before, but I'm hoping this will offset by the fact that we don't search for definition DIEs eagerly. In particular, I don't expect it to make a difference in -fstandalone-debug scenarios, since types will nearly always be present as definitions. To avoid this cost, we'd need to create some sort of a back channel to query the DWARFASTParser about the dynamicness of the type without actually completing it. I'd like to avoid that if it is not necessary.
114 lines
3.0 KiB
C++
114 lines
3.0 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"
|
|
#include "lldb/lldb-private-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_forcefully_completed(false) {
|
|
SetIsDynamicCXXType(std::nullopt);
|
|
}
|
|
|
|
std::optional<bool> GetIsDynamicCXXType() const;
|
|
|
|
void SetIsDynamicCXXType(std::optional<bool> 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;
|
|
};
|
|
|
|
unsigned 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 : 2, m_is_forcefully_completed : 1;
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
|