Also: lldb_private::TypeSystem has a "SymbolFile *" registered with it:
virtual SymbolFile *
GetSymbolFile () const
{
return m_sym_file;
}
// Returns true if the symbol file changed during the set accessor.
virtual void
SetSymbolFile (SymbolFile *sym_file)
{
m_sym_file = sym_file;
}
So it can use the:
bool
SymbolFile::CompleteType (CompilerType &clang_type);
This is what ClangASTContext::CompleteTagDecl() uses:
void
ClangASTContext::CompleteTagDecl (void *baton, clang::TagDecl *decl)
{
ClangASTContext *ast = (ClangASTContext *)baton;
SymbolFile *sym_file = ast->GetSymbolFile();
if (sym_file)
{
CompilerType clang_type = GetTypeForDecl (decl);
if (clang_type)
sym_file->CompleteType (clang_type);
}
}
> On Sep 2, 2015, at 3:48 PM, Greg Clayton via lldb-dev
> <[email protected]> wrote:
>
>>
>> On Sep 2, 2015, at 3:15 PM, Ryan Brown via lldb-dev
>> <[email protected]> wrote:
>>
>> I'm trying to implement a DWARFASTParser for go, and have hit an issue with
>> fields for structs.
>> As I understand it, DWARFASTParserClang loads minimal type info for structs
>> at first, and registers the type in SymbolFileDWARF's
>> m_forward_decl_clang_type_to_die.
>> Then later when you call type.GetFullCompilerType() it calls back into the
>> DWARFASTParser to complete the type.
>>
>> But it seems like the SBValue's in the python API only get Forward types,
>> and never complete them. For example, I do:
>> var = frame.FindVariable('theStruct')
>> self.assertEqual(2, var.GetNumChildren())
>>
>> But I get 0 children, because the type is incomplete and there doesn't seem
>> to be any way to complete it.
>> ValueObject::GetNumChildren goes through
>> ValueObject::MaybeCalculateCompleteType, which seems promising. But it only
>> completes the type for objc.
>> Would a clang variable already have a full type at this point for some
>> reason? If so, how do I arrange that for go?
>>
>> Also, TypeSystem has a GetCompleteType method. I don't understand when this
>> would be called or how I can implement it without a reference to
>> SymbolFileDWARF.
>
> The story goes:
>
> lldb_private::ClangASTContext inherits from lldb_private::TypeSystem so it is
> the type system. The ClangASTContext also signs up to be a
> clang::ExternalASTSource so that it can complete types via:
>
> ClangASTContext::CompleteTagDecl()
> ClangASTContext::CompleteObjCInterfaceDecl()
>
> ClangASTContext::CompleteTagDecl() completes C and C++ structs, unions and
> classes.
>
> ClangASTContext::CompleteObjCInterfaceDecl() completes Objective C stuff.
>
> The function that actually figures out how many children will be routed
> through "CompilerType::GetNumChildren(bool)" with code like this:
>
> size_t
> ValueObjectVariable::CalculateNumChildren()
> {
> CompilerType type(GetCompilerType());
>
> if (!type.IsValid())
> return 0;
>
> const bool omit_empty_base_classes = true;
> return type.GetNumChildren(omit_empty_base_classes);
> }
>
>
> CompilerType passes the ball back to the TypeSystem class (ClangASTContext
> in this case):
>
> uint32_t
> CompilerType::GetNumChildren (bool omit_empty_base_classes) const
> {
> if (!IsValid())
> return 0;
> return m_type_system->GetNumChildren(m_type, omit_empty_base_classes);
> }
>
>
> Down in ClangASTContext it does:
>
>
> uint32_t
> ClangASTContext::GetNumChildren (void* type, bool omit_empty_base_classes)
> {
> if (!type)
> return 0;
>
> uint32_t num_children = 0;
> clang::QualType qual_type(GetQualType(type));
> const clang::Type::TypeClass type_class = qual_type->getTypeClass();
> switch (type_class)
> {
> ...
> case clang::Type::Record:
> if (GetCompleteQualType (getASTContext(), qual_type))
> {
>
>
>
>
> So it is a static function named GetCompleteQualType() in ClangASTContext.cpp
> that completes the type if it needs to:
>
>
> static bool
> GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool
> allow_completion = true)
> {
> const clang::Type::TypeClass type_class = qual_type->getTypeClass();
> switch (type_class)
> {
> ...
> case clang::Type::Record:
> case clang::Type::Enum:
> {
> const clang::TagType *tag_type =
> llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
> if (tag_type)
> {
> clang::TagDecl *tag_decl = tag_type->getDecl();
> if (tag_decl)
> {
> if (tag_decl->isCompleteDefinition())
> return true;
>
> if (!allow_completion)
> return false;
>
> if (tag_decl->hasExternalLexicalStorage())
> {
> if (ast)
> {
> clang::ExternalASTSource *external_ast_source =
> ast->getExternalSource();
> if (external_ast_source)
> {
> external_ast_source->CompleteType(tag_decl);
>
>
>
> So it will ask the clang::ExternalASTSource to complete the type which should
> call ClangASTContext::CompleteTagDecl() to complete your type.
>
> So this is how it would work if you used DWARFASTParserClang. Are you using
> that? Or are you using your own DWARFASTParserGo? If so, then you need to
> implement this type completion in your own TypeSystem. Your type system
> subclass is required to implement many different function for type
> introspection, one of which is:
>
> class TypeSystem {
>
> virtual uint32_t
> GetNumChildren (void *type, bool omit_empty_base_classes) = 0;
>
> };
>
> So the clang version in ClangASTContext::GetNumChildren() knows to complete
> the type if it a forward declaration. If you have a GoASTContext class that
> inherits from TypeSystem, then all function that might need to know about the
> contents of a class or struct, will need to know to complete the type. Or,
> you can fully parse the structs/unions/classes as you parse the DWARF and not
> worry about implementing lazy type completion for Go.
>
> So the main questions I have for you are:
> - Do you have a GoASTContext that inherits from TypeSystem?
> - If you do, in order for DWARF to parse Go types that use the GoASTContext,
> you will need to write a DWARFASTParser subclass that constructs Go types
> from DWARF. Then your TypeSystem subclass will need to implement:
>
> TypeSystem {
>
> virtual DWARFASTParser *
> GetDWARFParser ();
>
> };
>
>
> _______________________________________________
> lldb-dev mailing list
> [email protected]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev