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 > <lldb-dev@lists.llvm.org> wrote: > >> >> On Sep 2, 2015, at 3:15 PM, Ryan Brown via lldb-dev >> <lldb-dev@lists.llvm.org> 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 > lldb-dev@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev _______________________________________________ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev