Author: gclayton Date: Mon Dec 7 19:02:08 2015 New Revision: 254980 URL: http://llvm.org/viewvc/llvm-project?rev=254980&view=rev Log: Trying to submit 254476 one more time. This implement -gmodule debugging support.
It was previously reverted due to issues that showed up only on linux. I was able to reproduce these issues and fix the underlying cause. So this is the same patch as 254476 with the following two fixes: - Fix not trying to complete classes that don't have external sources - Fix ClangASTSource::CompleteType() to check the decl context of types that it finds by basename to ensure we don't complete a type "S" with a type like "std::S". Before this fix ClangASTSource::CompleteType() would accept _any_ type that had a matching basename and copy it into the other type. <rdar://problem/22992457> Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/include/lldb/Symbol/ClangASTImporter.h lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h lldb/trunk/include/lldb/Symbol/SymbolFile.h lldb/trunk/include/lldb/Symbol/SymbolVendor.h lldb/trunk/include/lldb/Symbol/Type.h lldb/trunk/include/lldb/lldb-forward.h lldb/trunk/include/lldb/lldb-private-enumerations.h lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h lldb/trunk/source/Symbol/ClangASTContext.cpp lldb/trunk/source/Symbol/ClangASTImporter.cpp lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp lldb/trunk/source/Symbol/SymbolFile.cpp lldb/trunk/source/Symbol/SymbolVendor.cpp lldb/trunk/source/Symbol/Type.cpp Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Mon Dec 7 19:02:08 2015 @@ -151,7 +151,16 @@ public: { return ClangASTContext::GetCompleteDecl(getASTContext(), decl); } - + + static void + DumpDeclHiearchy (clang::Decl *decl); + + static void + DumpDeclContextHiearchy (clang::DeclContext *decl_ctx); + + static bool + DeclsAreEquivalent (clang::Decl *lhs_decl, clang::Decl *rhs_decl); + static bool GetCompleteDecl (clang::ASTContext *ast, clang::Decl *decl); @@ -1006,10 +1015,18 @@ public: lldb::AccessType access, bool is_artificial); - bool + static bool SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern); - + + static bool + CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer); + + static bool + Import (const CompilerType &type, lldb_private::ClangASTImporter &importer); + + static bool + GetHasExternalStorage (const CompilerType &type); //------------------------------------------------------------------ // Tag Declarations //------------------------------------------------------------------ @@ -1092,13 +1109,19 @@ public: void DumpTypeDescription (lldb::opaque_compiler_type_t type, Stream *s) override; - + + static void + DumpTypeName (const CompilerType &type); + static clang::EnumDecl * GetAsEnumDecl (const CompilerType& type); static clang::RecordDecl * GetAsRecordDecl (const CompilerType& type); - + + static clang::TagDecl * + GetAsTagDecl (const CompilerType& type); + clang::CXXRecordDecl * GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type); @@ -1109,9 +1132,12 @@ public: GetQualType (const CompilerType& type) { // Make sure we have a clang type before making a clang::QualType - ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem()); - if (ast) - return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType()); + if (type.GetOpaqueQualType()) + { + ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem()); + if (ast) + return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType()); + } return clang::QualType(); } Modified: lldb/trunk/include/lldb/Symbol/ClangASTImporter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTImporter.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTImporter.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTImporter.h Mon Dec 7 19:02:08 2015 @@ -107,7 +107,11 @@ public: CopyType (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx, lldb::opaque_compiler_type_t type); - + + CompilerType + CopyType (ClangASTContext &dst, + const CompilerType &src_type); + clang::Decl * CopyDecl (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx, @@ -134,7 +138,10 @@ public: bool CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl); - + + bool + CompleteAndFetchChildren (clang::QualType type); + bool RequireCompleteType (clang::QualType type); Modified: lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h Mon Dec 7 19:02:08 2015 @@ -97,6 +97,11 @@ public: { } + void + FindExternalLexicalDecls(const clang::DeclContext *DC, + llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, + llvm::SmallVectorImpl<clang::Decl *> &Result) override; + bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName decl_name) override; void CompleteType(clang::TagDecl *tag_decl) override; Modified: lldb/trunk/include/lldb/Symbol/SymbolFile.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolFile.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolFile.h (original) +++ lldb/trunk/include/lldb/Symbol/SymbolFile.h Mon Dec 7 19:02:08 2015 @@ -15,7 +15,6 @@ #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" - #include "lldb/Symbol/Type.h" namespace lldb_private { @@ -142,6 +141,8 @@ public: virtual uint32_t FindFunctions (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list); virtual uint32_t FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list); virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types); + virtual size_t FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types); + // virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0; virtual TypeList * GetTypeList (); virtual size_t GetTypes (lldb_private::SymbolContextScope *sc_scope, Modified: lldb/trunk/include/lldb/Symbol/SymbolVendor.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolVendor.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolVendor.h (original) +++ lldb/trunk/include/lldb/Symbol/SymbolVendor.h Mon Dec 7 19:02:08 2015 @@ -128,6 +128,9 @@ public: size_t max_matches, TypeMap& types); + virtual size_t + FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types); + virtual CompilerDeclContext FindNamespace (const SymbolContext& sc, const ConstString &name, Modified: lldb/trunk/include/lldb/Symbol/Type.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Type.h (original) +++ lldb/trunk/include/lldb/Symbol/Type.h Mon Dec 7 19:02:08 2015 @@ -24,6 +24,31 @@ namespace lldb_private { +//---------------------------------------------------------------------- +// CompilerContext allows an array of these items to be passed to +// perform detailed lookups in SymbolVendor and SymbolFile functions. +//---------------------------------------------------------------------- +struct CompilerContext +{ + CompilerContext (CompilerContextKind t, const ConstString &n) : + type(t), + name(n) + { + } + + bool + operator == (const CompilerContext &rhs) const + { + return type == rhs.type && name == rhs.name; + } + + void + Dump () const; + + CompilerContextKind type; + ConstString name; +}; + class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>, public UserID @@ -35,6 +60,9 @@ class SymbolFileType : { } + SymbolFileType (SymbolFile &symbol_file, const lldb::TypeSP &type_sp); + + ~SymbolFileType () { } Modified: lldb/trunk/include/lldb/lldb-forward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward.h (original) +++ lldb/trunk/include/lldb/lldb-forward.h Mon Dec 7 19:02:08 2015 @@ -62,6 +62,7 @@ class CommandObject; class CommandReturnObject; class Communication; class CompactUnwindInfo; +struct CompilerContext; class CompilerDecl; class CompilerDeclContext; class CompilerType; Modified: lldb/trunk/include/lldb/lldb-private-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-enumerations.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-private-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-private-enumerations.h Mon Dec 7 19:02:08 2015 @@ -241,6 +241,25 @@ enum class TypeValidatorResult : bool { Success = true, Failure = false }; + +//---------------------------------------------------------------------- +// Enumerations that can be used to specify scopes types when looking up +// types. +//---------------------------------------------------------------------- +enum class CompilerContextKind +{ + Invalid = 0, + TranslationUnit, + Module, + Namespace, + Class, + Structure, + Union, + Function, + Variable, + Enumeration, + Typedef +}; } // namespace lldb_private Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py (original) +++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py Mon Dec 7 19:02:08 2015 @@ -14,11 +14,11 @@ class TestCppIncompleteTypes(TestBase): value_f = frame.EvaluateExpression("f") self.assertTrue(value_f.IsValid(), "'expr f' results in a valid SBValue object") - self.assertFalse(value_f.GetError().Success(), "'expr f' results in an error, but LLDB does not crash") + self.assertTrue(value_f.GetError().Success(), "'expr f' is successful") value_a = frame.EvaluateExpression("a") self.assertTrue(value_a.IsValid(), "'expr a' results in a valid SBValue object") - self.assertFalse(value_a.GetError().Success(), "'expr a' results in an error, but LLDB does not crash") + self.assertTrue(value_a.GetError().Success(), "'expr a' is successful") @skipIfGcc @skipIfWindows # Clang on Windows asserts in external record layout in this case. Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp Mon Dec 7 19:02:08 2015 @@ -322,6 +322,11 @@ ClangASTSource::CompleteType (TagDecl *t TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl()); + // We have found a type by basename and we need to make sure the decl contexts + // are the same before we can try to complete this type with another + if (!ClangASTContext::DeclsAreEquivalent (tag_decl, candidate_tag_decl)) + continue; + if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl)) found = true; } Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h Mon Dec 7 19:02:08 2015 @@ -33,6 +33,18 @@ public: const DWARFDIE &die) = 0; virtual bool + CanCompleteType (const lldb_private::CompilerType &compiler_type) + { + return false; + } + + virtual bool + CompleteType (const lldb_private::CompilerType &compiler_type) + { + return false; + } + + virtual bool CompleteTypeFromDWARF (const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &compiler_type) = 0; Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Mon Dec 7 19:02:08 2015 @@ -24,11 +24,14 @@ #include "lldb/Core/StreamString.h" #include "lldb/Core/Value.h" #include "lldb/Host/Host.h" +#include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/TypeMap.h" #include "lldb/Target/Language.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" @@ -114,6 +117,78 @@ struct BitfieldInfo } }; + +ClangASTImporter & +DWARFASTParserClang::GetClangASTImporter() +{ + if (!m_clang_ast_importer_ap) + { + m_clang_ast_importer_ap.reset (new ClangASTImporter); + } + return *m_clang_ast_importer_ap; +} + + +TypeSP +DWARFASTParserClang::ParseTypeFromDWO (const DWARFDIE &die, Log *log) +{ + ModuleSP dwo_module_sp = die.GetContainingDWOModule(); + if (dwo_module_sp) + { + // This type comes from an external DWO module + std::vector<CompilerContext> dwo_context; + die.GetDWOContext(dwo_context); + TypeMap dwo_types; + if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, dwo_types)) + { + const size_t num_dwo_types = dwo_types.GetSize(); + if (num_dwo_types == 1) + { + // We found a real definition for this type elsewhere + // so lets use it and cache the fact that we found + // a complete type for this die + TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0); + if (dwo_type_sp) + { + lldb_private::CompilerType dwo_type = dwo_type_sp->GetForwardCompilerType(); + + lldb_private::CompilerType type = GetClangASTImporter().CopyType (m_ast, dwo_type); + + //printf ("copied_qual_type: ast = %p, clang_type = %p, name = '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(), external_type->GetName().GetCString()); + if (type) + { + SymbolFileDWARF *dwarf = die.GetDWARF(); + TypeSP type_sp (new Type (die.GetID(), + dwarf, + dwo_type_sp->GetName(), + dwo_type_sp->GetByteSize(), + NULL, + LLDB_INVALID_UID, + Type::eEncodingInvalid, + &dwo_type_sp->GetDeclaration(), + type, + Type::eResolveStateForward)); + + dwarf->GetTypeList()->Insert(type_sp); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type); + if (tag_decl) + LinkDeclContextToDIE(tag_decl, die); + else + { + clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die); + if (defn_decl_ctx) + LinkDeclContextToDIE(defn_decl_ctx, die); + } + return type_sp; + } + } + } + } + } + return TypeSP(); +} + TypeSP DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, const DWARFDIE &die, @@ -487,15 +562,15 @@ DWARFASTParserClang::ParseTypeFromDWARF if (dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl, byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) - { - type_sp = unique_ast_entry_ap->m_type_sp; - if (type_sp) { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - return type_sp; + type_sp = unique_ast_entry_ap->m_type_sp; + if (type_sp) + { + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + return type_sp; + } } } - } } DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); @@ -600,6 +675,11 @@ DWARFASTParserClang::ParseTypeFromDWARF type_name_cstr); } + // See if the type comes from a DWO module and if so, track down that type. + type_sp = ParseTypeFromDWO(die, log); + if (type_sp) + return type_sp; + DWARFDeclContext die_decl_ctx; die.GetDWARFDeclContext(die_decl_ctx); @@ -833,7 +913,7 @@ DWARFASTParserClang::ParseTypeFromDWARF case DW_AT_type: encoding_form = form_value; break; case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; - case DW_AT_declaration: break; //is_forward_declaration = form_value.Boolean(); break; + case DW_AT_declaration: is_forward_declaration = form_value.Boolean(); break; case DW_AT_allocated: case DW_AT_associated: case DW_AT_bit_stride: @@ -850,6 +930,54 @@ DWARFASTParserClang::ParseTypeFromDWARF } } + if (is_forward_declaration) + { + type_sp = ParseTypeFromDWO(die, log); + if (type_sp) + return type_sp; + + DWARFDeclContext die_decl_ctx; + die.GetDWARFDeclContext(die_decl_ctx); + + type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); + + if (!type_sp) + { + SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); + if (debug_map_symfile) + { + // We weren't able to find a full declaration in + // this DWARF, see if we have a declaration anywhere + // else... + type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); + } + } + + if (type_sp) + { + if (log) + { + dwarf->GetObjectFile()->GetModule()->LogMessage (log, + "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64, + static_cast<void*>(this), + die.GetOffset(), + DW_TAG_value_to_name(tag), + type_name_cstr, + type_sp->GetID()); + } + + // We found a real definition for this type elsewhere + // so lets use it and cache the fact that we found + // a complete type for this die + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE( + dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID()))); + if (defn_decl_ctx) + LinkDeclContextToDIE(defn_decl_ctx, die); + return type_sp; + } + + } DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); CompilerType enumerator_clang_type; @@ -1130,7 +1258,7 @@ DWARFASTParserClang::ParseTypeFromDWARF if (class_type) { bool alternate_defn = false; - if (class_type->GetID() != decl_ctx_die.GetID()) + if (class_type->GetID() != decl_ctx_die.GetID() || decl_ctx_die.GetContainingDWOModuleDIE()) { alternate_defn = true; @@ -1798,6 +1926,33 @@ DWARFASTParserClang::ParseTemplateParame } bool +DWARFASTParserClang::CanCompleteType (const lldb_private::CompilerType &compiler_type) +{ + if (m_clang_ast_importer_ap) + return ClangASTContext::CanImport(compiler_type, GetClangASTImporter()); + else + return false; +} + +bool +DWARFASTParserClang::CompleteType (const lldb_private::CompilerType &compiler_type) +{ + if (CanCompleteType(compiler_type)) + { + if (ClangASTContext::Import(compiler_type, GetClangASTImporter())) + { + ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); + return true; + } + else + { + ClangASTContext::SetHasExternalStorage (compiler_type.GetOpaqueQualType(), false); + } + } + return false; +} + +bool DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) @@ -1868,25 +2023,17 @@ DWARFASTParserClang::CompleteTypeFromDWA DWARFDIECollection member_function_dies; DelayedPropertyList delayed_properties; - if (!ParseChildMembers (sc, - die, - clang_type, - class_language, - base_classes, - member_accessibilities, - member_function_dies, - delayed_properties, - default_accessibility, - is_a_class, - layout_info)) - { - auto module = dwarf->GetObjectFile()->GetModule(); - module->ReportError (":: Class %s has members with incomplete type.", die.GetName()); - if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) - module->ReportError(":: Try compiling the source file with -fno-limit-debug-info."); - - return false; - } + ParseChildMembers (sc, + die, + clang_type, + class_language, + base_classes, + member_accessibilities, + member_function_dies, + delayed_properties, + default_accessibility, + is_a_class, + layout_info); // Now parse any methods if there were any... size_t num_functions = member_function_dies.Size(); @@ -1977,7 +2124,14 @@ DWARFASTParserClang::CompleteTypeFromDWA if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) module->ReportError (":: Try compiling the source file with -fno-limit-debug-info."); - return false; + // We have no choice other than to pretend that the base class + // is complete. If we don't do this, clang will crash when we + // call setBases() inside of "clang_type.SetBaseClassesForClassType()" + // below. Since we provide layout assistance, all ivars in this + // class and other classes will be fine, this is the best we can do + // short of crashing. + ClangASTContext::StartTagDeclarationDefinition (base_class_type); + ClangASTContext::CompleteTagDeclarationDefinition (base_class_type); } } } @@ -2420,7 +2574,6 @@ DWARFASTParserClang::ParseChildMembers ( if (!parent_die) return 0; - uint32_t incomplete_member_info_count = 0; uint32_t member_idx = 0; BitfieldInfo last_field_info; @@ -2754,8 +2907,8 @@ DWARFASTParserClang::ParseChildMembers ( } CompilerType member_clang_type = member_type->GetLayoutCompilerType (); - if (!member_clang_type.IsCompleteType() && !member_clang_type.GetCompleteType()) - incomplete_member_info_count += 1; + if (!member_clang_type.IsCompleteType()) + member_clang_type.GetCompleteType(); { // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>). @@ -2789,6 +2942,30 @@ DWARFASTParserClang::ParseChildMembers ( } } + if (ClangASTContext::IsCXXClassType(member_clang_type) && member_clang_type.GetCompleteType() == false) + { + if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) + module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info", + parent_die.GetOffset(), + parent_die.GetName(), + die.GetOffset(), + name); + else + module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s", + parent_die.GetOffset(), + parent_die.GetName(), + die.GetOffset(), + name, + sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file"); + // We have no choice other than to pretend that the member class + // is complete. If we don't do this, clang will crash when trying + // to layout the class. Since we provide layout assistance, all + // ivars in this class and other classes will be fine, this is + // the best we can do short of crashing. + ClangASTContext::StartTagDeclarationDefinition(member_clang_type); + ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type); + } + field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type, name, member_clang_type, @@ -2978,7 +3155,7 @@ DWARFASTParserClang::ParseChildMembers ( } } - return incomplete_member_info_count == 0; + return true; } Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h Mon Dec 7 19:02:08 2015 @@ -47,6 +47,12 @@ public: const DWARFDIE &die) override; bool + CanCompleteType (const lldb_private::CompilerType &compiler_type) override; + + bool + CompleteType (const lldb_private::CompilerType &compiler_type) override; + + bool CompleteTypeFromDWARF (const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &compiler_type) override; @@ -175,6 +181,19 @@ protected: void LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die); + lldb_private::ClangASTImporter & + GetClangASTImporter(); + + lldb::TypeSP + ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log); + + //---------------------------------------------------------------------- + // Return true if this type is a declaration to a type in an external + // module. + //---------------------------------------------------------------------- + lldb::ModuleSP + GetModuleForType (const DWARFDIE &die); + typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap; //typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap; @@ -188,6 +207,7 @@ protected: DIEToDeclContextMap m_die_to_decl_ctx; DeclContextToDIEMap m_decl_ctx_to_die; RecordDeclToLayoutMap m_record_decl_to_layout_map; + std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap; }; #endif // SymbolFileDWARF_DWARFASTParserClang_h_ Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp Mon Dec 7 19:02:08 2015 @@ -22,8 +22,11 @@ #include "lldb/Core/Module.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeSystem.h" +using namespace lldb_private; + DIERef DWARFDIE::GetDIERef() const { @@ -307,6 +310,50 @@ DWARFDIE::GetDWARFDeclContext (DWARFDecl } } +void +DWARFDIE::GetDWOContext (std::vector<CompilerContext> &context) const +{ + const dw_tag_t tag = Tag(); + if (tag == DW_TAG_compile_unit) + return; + DWARFDIE parent = GetParent(); + if (parent) + parent.GetDWOContext(context); + switch (tag) + { + case DW_TAG_module: + context.push_back(CompilerContext(CompilerContextKind::Module, ConstString(GetName()))); + break; + case DW_TAG_namespace: + context.push_back(CompilerContext(CompilerContextKind::Namespace, ConstString(GetName()))); + break; + case DW_TAG_structure_type: + context.push_back(CompilerContext(CompilerContextKind::Structure, ConstString(GetName()))); + break; + case DW_TAG_union_type: + context.push_back(CompilerContext(CompilerContextKind::Union, ConstString(GetName()))); + break; + case DW_TAG_class_type: + context.push_back(CompilerContext(CompilerContextKind::Class, ConstString(GetName()))); + break; + case DW_TAG_enumeration_type: + context.push_back(CompilerContext(CompilerContextKind::Enumeration, ConstString(GetName()))); + break; + case DW_TAG_subprogram: + context.push_back(CompilerContext(CompilerContextKind::Function, ConstString(GetPubname()))); + break; + case DW_TAG_variable: + context.push_back(CompilerContext(CompilerContextKind::Variable, ConstString(GetPubname()))); + break; + case DW_TAG_typedef: + context.push_back(CompilerContext(CompilerContextKind::Typedef, ConstString(GetName()))); + break; + default: + break; + } +} + + DWARFDIE DWARFDIE::GetParentDeclContextDIE () const @@ -371,6 +418,45 @@ DWARFDIE::IsStructOrClass () const return tag == DW_TAG_class_type || tag == DW_TAG_structure_type; } + +DWARFDIE +DWARFDIE::GetContainingDWOModuleDIE () const +{ + if (IsValid()) + { + DWARFDIE top_module_die; + // Now make sure this DIE is scoped in a DW_TAG_module tag and return true if so + for (DWARFDIE parent = GetParent(); parent.IsValid(); parent = parent.GetParent()) + { + const dw_tag_t tag = parent.Tag(); + if (tag == DW_TAG_module) + top_module_die = parent; + else if (tag == DW_TAG_compile_unit) + break; + } + + return top_module_die; + } + return DWARFDIE(); +} + +lldb::ModuleSP +DWARFDIE::GetContainingDWOModule () const +{ + if (IsValid()) + { + DWARFDIE dwo_module_die = GetContainingDWOModuleDIE(); + + if (dwo_module_die) + { + const char *module_name = dwo_module_die.GetName(); + if (module_name) + return GetDWARF()->GetDWOModule (lldb_private::ConstString(module_name)); + } + } + return lldb::ModuleSP(); +} + bool DWARFDIE::HasChildren () const { Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h Mon Dec 7 19:02:08 2015 @@ -126,6 +126,12 @@ public: m_die = nullptr; } + lldb::ModuleSP + GetContainingDWOModule () const; + + DWARFDIE + GetContainingDWOModuleDIE () const; + //---------------------------------------------------------------------- // Accessing information about a DIE //---------------------------------------------------------------------- @@ -217,6 +223,9 @@ public: void GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const; + void + GetDWOContext (std::vector<lldb_private::CompilerContext> &context) const; + //---------------------------------------------------------------------- // Getting attribute values from the DIE. // Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Dec 7 19:02:08 2015 @@ -1077,9 +1077,9 @@ SymbolFileDWARF::ParseImportedModules (c if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage())) { UpdateExternalModuleListIfNeeded(); - for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules) + for (const auto &pair : m_external_type_modules) { - imported_modules.push_back(external_type_module.second.m_name); + imported_modules.push_back(pair.first); } } } @@ -1515,13 +1515,32 @@ bool SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type) { CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type); - return GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()); + if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType())) + { + return true; + } + TypeSystem *type_system = compiler_type.GetTypeSystem(); + if (type_system) + { + DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); + if (dwarf_ast) + return dwarf_ast->CanCompleteType(compiler_type); + } + return false; } bool SymbolFileDWARF::CompleteType (CompilerType &compiler_type) { + TypeSystem *type_system = compiler_type.GetTypeSystem(); + if (type_system) + { + DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); + if (dwarf_ast && dwarf_ast->CanCompleteType(compiler_type)) + return dwarf_ast->CompleteType(compiler_type); + } + // We have a struct/union/class/enum that needs to be fully resolved. CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type); auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType()); @@ -1641,6 +1660,17 @@ SymbolFileDWARF::GetFunction (const DWAR return false; } +lldb::ModuleSP +SymbolFileDWARF::GetDWOModule (ConstString name) +{ + UpdateExternalModuleListIfNeeded(); + const auto &pos = m_external_type_modules.find(name); + if (pos != m_external_type_modules.end()) + return pos->second; + else + return lldb::ModuleSP(); +} + void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { @@ -1658,37 +1688,24 @@ SymbolFileDWARF::UpdateExternalModuleLis const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly(); if (die && die.HasChildren() == false) { - const uint64_t name_strp = die.GetAttributeValueAsUnsigned (DW_AT_name, UINT64_MAX); - const uint64_t dwo_path_strp = die.GetAttributeValueAsUnsigned (DW_AT_GNU_dwo_name, UINT64_MAX); - - if (name_strp != UINT64_MAX) + const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr); + + if (name) { - if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end()) + ConstString const_name(name); + if (m_external_type_modules.find(const_name) == m_external_type_modules.end()) { - const char *name = get_debug_str_data().PeekCStr(name_strp); - const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp); - if (name || dwo_path) + ModuleSP module_sp; + const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr); + if (dwo_path) { - ModuleSP module_sp; - if (dwo_path) - { - ModuleSpec dwo_module_spec; - dwo_module_spec.GetFileSpec().SetFile(dwo_path, false); - dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture(); - //printf ("Loading dwo = '%s'\n", dwo_path); - Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL); - } - - if (dwo_path_strp != LLDB_INVALID_UID) - { - m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp }; - } - else - { - // This hack should be removed promptly once clang emits both. - m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp }; - } + ModuleSpec dwo_module_spec; + dwo_module_spec.GetFileSpec().SetFile(dwo_path, false); + dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture(); + //printf ("Loading dwo = '%s'\n", dwo_path); + Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL); } + m_external_type_modules[const_name] = module_sp; } } } @@ -2970,6 +2987,104 @@ SymbolFileDWARF::FindTypes (const Symbol } return num_matches; } + else + { + UpdateExternalModuleListIfNeeded(); + + for (const auto &pair : m_external_type_modules) + { + ModuleSP external_module_sp = pair.second; + if (external_module_sp) + { + SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor(); + if (sym_vendor) + { + const uint32_t num_external_matches = sym_vendor->FindTypes (sc, + name, + parent_decl_ctx, + append, + max_matches, + types); + if (num_external_matches) + return num_external_matches; + } + } + } + } + + return 0; +} + + +size_t +SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context, + bool append, + TypeMap& types) +{ + if (!append) + types.Clear(); + + if (context.empty()) + return 0; + + DIEArray die_offsets; + + ConstString name = context.back().name; + + if (m_using_apple_tables) + { + if (m_apple_types_ap.get()) + { + const char *name_cstr = name.GetCString(); + m_apple_types_ap->FindByName (name_cstr, die_offsets); + } + } + else + { + if (!m_indexed) + Index (); + + m_type_index.Find (name, die_offsets); + } + + const size_t num_die_matches = die_offsets.size(); + + if (num_die_matches) + { + size_t num_matches = 0; + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_die_matches; ++i) + { + const DIERef& die_ref = die_offsets[i]; + DWARFDIE die = debug_info->GetDIE (die_ref); + + if (die) + { + std::vector<CompilerContext> die_context; + die.GetDWOContext(die_context); + if (die_context != context) + continue; + + Type *matching_type = ResolveType (die, true, true); + if (matching_type) + { + // We found a type pointer, now find the shared pointer form our type list + types.InsertUnique (matching_type->shared_from_this()); + ++num_matches; + } + } + else + { + if (m_using_apple_tables) + { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, name.GetCString()); + } + } + + } + return num_matches; + } return 0; } Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Mon Dec 7 19:02:08 2015 @@ -211,6 +211,11 @@ public: uint32_t max_matches, lldb_private::TypeMap& types) override; + size_t + FindTypes (const std::vector<lldb_private::CompilerContext> &context, + bool append, + lldb_private::TypeMap& types) override; + lldb_private::TypeList * GetTypeList () override; @@ -306,6 +311,9 @@ public: virtual lldb_private::DWARFExpression::LocationListFormat GetLocationListFormat() const; + lldb::ModuleSP + GetDWOModule (lldb_private::ConstString name); + protected: typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP; @@ -483,12 +491,7 @@ protected: typedef std::set<lldb_private::Type *> TypeSet; - typedef struct { - lldb_private::ConstString m_name; - lldb::ModuleSP m_module_sp; - } ClangModuleInfo; - - typedef std::map<uint64_t, ClangModuleInfo> ExternalTypeModuleMap; + typedef std::map<lldb_private::ConstString, lldb::ModuleSP> ExternalTypeModuleMap; void GetTypes (const DWARFDIE &die, Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Mon Dec 7 19:02:08 2015 @@ -2280,6 +2280,157 @@ ClangASTContext::GetPointerSizedIntType return CompilerType(); } +void +ClangASTContext::DumpDeclContextHiearchy (clang::DeclContext *decl_ctx) +{ + if (decl_ctx) + { + DumpDeclContextHiearchy (decl_ctx->getParent()); + + clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx); + if (named_decl) + { + printf ("%20s: %s\n", decl_ctx->getDeclKindName(), named_decl->getDeclName().getAsString().c_str()); + } + else + { + printf ("%20s\n", decl_ctx->getDeclKindName()); + } + } +} + +void +ClangASTContext::DumpDeclHiearchy (clang::Decl *decl) +{ + if (decl == nullptr) + return; + DumpDeclContextHiearchy(decl->getDeclContext()); + + clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl); + if (record_decl) + { + printf ("%20s: %s%s\n", decl->getDeclKindName(), record_decl->getDeclName().getAsString().c_str(), record_decl->isInjectedClassName() ? " (injected class name)" : ""); + + } + else + { + clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl); + if (named_decl) + { + printf ("%20s: %s\n", decl->getDeclKindName(), named_decl->getDeclName().getAsString().c_str()); + } + else + { + printf ("%20s\n", decl->getDeclKindName()); + } + } +} + +bool +ClangASTContext::DeclsAreEquivalent (clang::Decl *lhs_decl, clang::Decl *rhs_decl) +{ + if (lhs_decl && rhs_decl) + { + //---------------------------------------------------------------------- + // Make sure the decl kinds match first + //---------------------------------------------------------------------- + const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind(); + const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind(); + + if (lhs_decl_kind == rhs_decl_kind) + { + //------------------------------------------------------------------ + // Now check that the decl contexts kinds are all equivalent + // before we have to check any names of the decl contexts... + //------------------------------------------------------------------ + clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext(); + clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext(); + if (lhs_decl_ctx && rhs_decl_ctx) + { + while (1) + { + if (lhs_decl_ctx && rhs_decl_ctx) + { + const clang::Decl::Kind lhs_decl_ctx_kind = lhs_decl_ctx->getDeclKind(); + const clang::Decl::Kind rhs_decl_ctx_kind = rhs_decl_ctx->getDeclKind(); + if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) + { + lhs_decl_ctx = lhs_decl_ctx->getParent(); + rhs_decl_ctx = rhs_decl_ctx->getParent(); + + if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr) + break; + } + else + return false; + } + else + return false; + } + + //-------------------------------------------------------------- + // Now make sure the name of the decls match + //-------------------------------------------------------------- + clang::NamedDecl *lhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(lhs_decl); + clang::NamedDecl *rhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(rhs_decl); + if (lhs_named_decl && rhs_named_decl) + { + clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName(); + clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName(); + if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) + { + if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) + return false; + } + else + return false; + } + else + return false; + + //-------------------------------------------------------------- + // We know that the decl context kinds all match, so now we need + // to make sure the names match as well + //-------------------------------------------------------------- + lhs_decl_ctx = lhs_decl->getDeclContext(); + rhs_decl_ctx = rhs_decl->getDeclContext(); + while (1) + { + switch (lhs_decl_ctx->getDeclKind()) + { + case clang::Decl::TranslationUnit: + // We don't care about the translation unit names + return true; + default: + { + clang::NamedDecl *lhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx); + clang::NamedDecl *rhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx); + if (lhs_named_decl && rhs_named_decl) + { + clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName(); + clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName(); + if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) + { + if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) + return false; + } + else + return false; + } + else + return false; + } + break; + + } + lhs_decl_ctx = lhs_decl_ctx->getParent(); + rhs_decl_ctx = rhs_decl_ctx->getParent(); + } + } + } + } + return false; +} bool ClangASTContext::GetCompleteDecl (clang::ASTContext *ast, clang::Decl *decl) @@ -2451,81 +2602,112 @@ GetCompleteQualType (clang::ASTContext * case clang::Type::ConstantArray: case clang::Type::IncompleteArray: case clang::Type::VariableArray: - { - const clang::ArrayType *array_type = llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr()); - - if (array_type) - return GetCompleteQualType (ast, array_type->getElementType(), allow_completion); - } + { + const clang::ArrayType *array_type = llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr()); + + if (array_type) + return GetCompleteQualType (ast, array_type->getElementType(), allow_completion); + } break; - case clang::Type::Record: + { + clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + if (cxx_record_decl->hasExternalLexicalStorage()) + { + const bool is_complete = cxx_record_decl->isCompleteDefinition(); + const bool fields_loaded = cxx_record_decl->hasLoadedFieldsFromExternalStorage(); + if (is_complete && fields_loaded) + return true; + + if (!allow_completion) + return false; + + // Call the field_begin() accessor to for it to use the external source + // to load the fields... + clang::ExternalASTSource *external_ast_source = ast->getExternalSource(); + if (external_ast_source) + { + external_ast_source->CompleteType(cxx_record_decl); + if (cxx_record_decl->isCompleteDefinition()) + { + cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true); + cxx_record_decl->field_begin(); + } + } + } + } + const clang::TagType *tag_type = llvm::cast<clang::TagType>(qual_type.getTypePtr()); + return !tag_type->isIncompleteType(); + } + break; + 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) + const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()); + if (tag_type) { - if (tag_decl->isCompleteDefinition()) - return true; - - if (!allow_completion) - return false; - - if (tag_decl->hasExternalLexicalStorage()) + clang::TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) { - if (ast) + if (tag_decl->getDefinition()) + return true; + + if (!allow_completion) + return false; + + if (tag_decl->hasExternalLexicalStorage()) { - clang::ExternalASTSource *external_ast_source = ast->getExternalSource(); - if (external_ast_source) + if (ast) { - external_ast_source->CompleteType(tag_decl); - return !tag_type->isIncompleteType(); + clang::ExternalASTSource *external_ast_source = ast->getExternalSource(); + if (external_ast_source) + { + external_ast_source->CompleteType(tag_decl); + return !tag_type->isIncompleteType(); + } } } + return false; } - return false; } + } - - } break; - case clang::Type::ObjCObject: case clang::Type::ObjCInterface: - { - const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); - if (objc_class_type) { - clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - // We currently can't complete objective C types through the newly added ASTContext - // because it only supports TagDecl objects right now... - if (class_interface_decl) + const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); + if (objc_class_type) { - if (class_interface_decl->getDefinition()) - return true; - - if (!allow_completion) - return false; - - if (class_interface_decl->hasExternalLexicalStorage()) + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added ASTContext + // because it only supports TagDecl objects right now... + if (class_interface_decl) { - if (ast) + if (class_interface_decl->getDefinition()) + return true; + + if (!allow_completion) + return false; + + if (class_interface_decl->hasExternalLexicalStorage()) { - clang::ExternalASTSource *external_ast_source = ast->getExternalSource(); - if (external_ast_source) + if (ast) { - external_ast_source->CompleteType (class_interface_decl); - return !objc_class_type->isIncompleteType(); + clang::ExternalASTSource *external_ast_source = ast->getExternalSource(); + if (external_ast_source) + { + external_ast_source->CompleteType (class_interface_decl); + return !objc_class_type->isIncompleteType(); + } } } + return false; } - return false; } } - } break; case clang::Type::Typedef: @@ -2536,7 +2718,10 @@ GetCompleteQualType (clang::ASTContext * case clang::Type::Paren: return GetCompleteQualType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar(), allow_completion); - + + case clang::Type::Attributed: + return GetCompleteQualType (ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(), allow_completion); + default: break; } @@ -7160,6 +7345,16 @@ ClangASTContext::GetAsRecordDecl (const return nullptr; } +clang::TagDecl * +ClangASTContext::GetAsTagDecl (const CompilerType& type) +{ + clang::QualType qual_type = GetCanonicalQualType(type); + if (qual_type.isNull()) + return nullptr; + else + return qual_type->getAsTagDecl(); +} + clang::CXXRecordDecl * ClangASTContext::GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type) { @@ -8037,6 +8232,64 @@ ClangASTContext::AddMethodToObjCObjectTy } bool +ClangASTContext::GetHasExternalStorage (const CompilerType &type) +{ + if (IsClangType(type)) + return false; + + clang::QualType qual_type (GetCanonicalQualType(type)); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + { + clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + return cxx_record_decl->hasExternalLexicalStorage () || cxx_record_decl->hasExternalVisibleStorage(); + } + break; + + case clang::Type::Enum: + { + clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); + if (enum_decl) + return enum_decl->hasExternalLexicalStorage () || enum_decl->hasExternalVisibleStorage(); + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + return class_interface_decl->hasExternalLexicalStorage () || class_interface_decl->hasExternalVisibleStorage (); + } + } + break; + + case clang::Type::Typedef: + return GetHasExternalStorage (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr())); + + case clang::Type::Elaborated: + return GetHasExternalStorage (CompilerType(type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr())); + + case clang::Type::Paren: + return GetHasExternalStorage (CompilerType(type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); + + default: + break; + } + return false; +} + + +bool ClangASTContext::SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern) { if (!type) @@ -8106,39 +8359,174 @@ ClangASTContext::SetHasExternalStorage ( } -#pragma mark TagDecl +bool +ClangASTContext::CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer) +{ + if (IsClangType(type)) + { + // TODO: remove external completion BOOL + // CompleteAndFetchChildren should get the Decl out and check for the + + clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + { + const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL)) + return true; + } + } + break; + + case clang::Type::Enum: + { + clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); + if (enum_decl) + { + if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL)) + return true; + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added ASTContext + // because it only supports TagDecl objects right now... + if (class_interface_decl) + { + if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL)) + return true; + } + } + } + break; + + + case clang::Type::Typedef: + return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer); + + case clang::Type::Elaborated: + return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer); + case clang::Type::Paren: + return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer); + + default: + break; + } + } + return false; +} bool -ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type) +ClangASTContext::Import (const CompilerType &type, lldb_private::ClangASTImporter &importer) { - if (type) + if (IsClangType(type)) { - - clang::QualType qual_type (GetQualType(type)); - const clang::Type *t = qual_type.getTypePtr(); - if (t) + // TODO: remove external completion BOOL + // CompleteAndFetchChildren should get the Decl out and check for the + + clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { - const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(t); - if (tag_type) + case clang::Type::Record: { - clang::TagDecl *tag_decl = tag_type->getDecl(); - if (tag_decl) + const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) { - tag_decl->startDefinition(); - return true; + if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL)) + return importer.CompleteAndFetchChildren(qual_type); } } - - const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(t); - if (object_type) + break; + + case clang::Type::Enum: { - clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface(); - if (interface_decl) + clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); + if (enum_decl) { - interface_decl->startDefinition(); - return true; + if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL)) + return importer.CompleteAndFetchChildren(qual_type); } } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added ASTContext + // because it only supports TagDecl objects right now... + if (class_interface_decl) + { + if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL)) + return importer.CompleteAndFetchChildren(qual_type); + } + } + } + break; + + + case clang::Type::Typedef: + return Import (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer); + + case clang::Type::Elaborated: + return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer); + + case clang::Type::Paren: + return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer); + + default: + break; + } + } + return false; +} + + +#pragma mark TagDecl + +bool +ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type) +{ + clang::QualType qual_type (ClangASTContext::GetQualType(type)); + if (!qual_type.isNull()) + { + const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); + if (tag_type) + { + clang::TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) + { + tag_decl->startDefinition(); + return true; + } + } + + const clang::ObjCObjectType *object_type = qual_type->getAs<clang::ObjCObjectType>(); + if (object_type) + { + clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface(); + if (interface_decl) + { + interface_decl->startDefinition(); + return true; + } } } return false; @@ -8147,26 +8535,22 @@ ClangASTContext::StartTagDeclarationDefi bool ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type) { - if (type) + clang::QualType qual_type (ClangASTContext::GetQualType(type)); + if (!qual_type.isNull()) { - clang::QualType qual_type (GetQualType(type)); - if (qual_type.isNull()) - return false; - ClangASTContext *lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); - if (lldb_ast == nullptr) - return false; - clang::ASTContext *ast = lldb_ast->getASTContext(); - clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); if (cxx_record_decl) { - cxx_record_decl->completeDefinition(); - + if (!cxx_record_decl->isCompleteDefinition()) + cxx_record_decl->completeDefinition(); + cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); + cxx_record_decl->setHasExternalLexicalStorage (false); + cxx_record_decl->setHasExternalVisibleStorage (false); return true; } - const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(qual_type.getTypePtr()); + const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>(); if (enutype) { @@ -8174,25 +8558,33 @@ ClangASTContext::CompleteTagDeclarationD if (enum_decl) { - /// TODO This really needs to be fixed. - - unsigned NumPositiveBits = 1; - unsigned NumNegativeBits = 0; - - clang::QualType promotion_qual_type; - // If the enum integer type is less than an integer in bit width, - // then we must promote it to an integer size. - if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy)) + if (!enum_decl->isCompleteDefinition()) { - if (enum_decl->getIntegerType()->isSignedIntegerType()) - promotion_qual_type = ast->IntTy; + ClangASTContext *lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); + if (lldb_ast == nullptr) + return false; + clang::ASTContext *ast = lldb_ast->getASTContext(); + + /// TODO This really needs to be fixed. + + unsigned NumPositiveBits = 1; + unsigned NumNegativeBits = 0; + + clang::QualType promotion_qual_type; + // If the enum integer type is less than an integer in bit width, + // then we must promote it to an integer size. + if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy)) + { + if (enum_decl->getIntegerType()->isSignedIntegerType()) + promotion_qual_type = ast->IntTy; + else + promotion_qual_type = ast->UnsignedIntTy; + } else - promotion_qual_type = ast->UnsignedIntTy; + promotion_qual_type = enum_decl->getIntegerType(); + + enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); } - else - promotion_qual_type = enum_decl->getIntegerType(); - - enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); return true; } } @@ -8976,6 +9368,72 @@ ClangASTContext::DumpTypeDescription (ll } } +void +ClangASTContext::DumpTypeName (const CompilerType &type) +{ + if (IsClangType(type)) + { + clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); + + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + { + const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + printf("class %s", cxx_record_decl->getName().str().c_str()); + } + break; + + case clang::Type::Enum: + { + clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); + if (enum_decl) + { + printf("enum %s", enum_decl->getName().str().c_str()); + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + // We currently can't complete objective C types through the newly added ASTContext + // because it only supports TagDecl objects right now... + if (class_interface_decl) + printf("@class %s", class_interface_decl->getName().str().c_str()); + } + } + break; + + + case clang::Type::Typedef: + printf("typedef %s", llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getName().str().c_str()); + break; + + case clang::Type::Elaborated: + printf("elaborated "); + return DumpTypeName (CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr())); + + case clang::Type::Paren: + printf("paren "); + return DumpTypeName (CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); + + default: + printf("ClangASTContext::DumpTypeName() type_class = %u", type_class); + break; + } + } + +} + + + clang::ClassTemplateDecl * ClangASTContext::ParseClassTemplateDecl (clang::DeclContext *decl_ctx, lldb::AccessType access_type, Modified: lldb/trunk/source/Symbol/ClangASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTImporter.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTImporter.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTImporter.cpp Mon Dec 7 19:02:08 2015 @@ -67,6 +67,31 @@ ClangASTImporter::CopyType (clang::ASTCo return CopyType (dst_ast, src_ast, QualType::getFromOpaquePtr(type)).getAsOpaquePtr(); } +CompilerType +ClangASTImporter::CopyType (ClangASTContext &dst_ast, + const CompilerType &src_type) +{ + clang::ASTContext *dst_clang_ast = dst_ast.getASTContext(); + if (dst_clang_ast) + { + ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); + if (src_ast) + { + clang::ASTContext *src_clang_ast = src_ast->getASTContext(); + if (src_clang_ast) + { + lldb::opaque_compiler_type_t dst_clang_type = CopyType(dst_clang_ast, + src_clang_ast, + src_type.GetOpaqueQualType()); + + if (dst_clang_type) + return CompilerType(&dst_ast, dst_clang_type); + } + } + } + return CompilerType(); +} + clang::Decl * ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast, clang::ASTContext *src_ast, @@ -429,6 +454,68 @@ ClangASTImporter::CompleteObjCInterfaceD } bool +ClangASTImporter::CompleteAndFetchChildren (clang::QualType type) +{ + if (!RequireCompleteType(type)) + return false; + + if (const TagType *tag_type = type->getAs<TagType>()) + { + TagDecl *tag_decl = tag_type->getDecl(); + + DeclOrigin decl_origin = GetDeclOrigin(tag_decl); + + if (!decl_origin.Valid()) + return false; + + MinionSP minion_sp (GetMinion(&tag_decl->getASTContext(), decl_origin.ctx)); + + TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl); + + for (Decl *origin_child_decl : origin_tag_decl->decls()) + { + minion_sp->Import(origin_child_decl); + } + + if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) + { + record_decl->setHasLoadedFieldsFromExternalStorage(true); + } + + return true; + } + + if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) + { + if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) + { + DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl); + + if (!decl_origin.Valid()) + return false; + + MinionSP minion_sp (GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx)); + + ObjCInterfaceDecl *origin_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl); + + for (Decl *origin_child_decl : origin_interface_decl->decls()) + { + minion_sp->Import(origin_child_decl); + } + + return true; + } + else + { + return false; + } + } + + return true; +} + + +bool ClangASTImporter::RequireCompleteType (clang::QualType type) { if (type.isNull()) @@ -793,10 +880,14 @@ ClangASTImporter::Minion::Imported (clan { if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) { - NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to); - - if (!m_decls_already_deported->count(to_named_decl)) - m_decls_to_deport->insert(to_named_decl); + RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from); + if (from_record_decl == nullptr || from_record_decl->isInjectedClassName() == false) + { + NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to); + + if (!m_decls_already_deported->count(to_named_decl)) + m_decls_to_deport->insert(to_named_decl); + } } } Modified: lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp (original) +++ lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp Mon Dec 7 19:02:08 2015 @@ -41,6 +41,7 @@ #endif #include "lldb/Core/Log.h" +#include "clang/AST/Decl.h" using namespace clang; using namespace lldb_private; @@ -160,3 +161,16 @@ ClangExternalASTSourceCallbacks::layoutR return false; } +void +ClangExternalASTSourceCallbacks::FindExternalLexicalDecls (const clang::DeclContext *decl_ctx, + llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, + llvm::SmallVectorImpl<clang::Decl *> &decls) +{ + if (m_callback_tag_decl && decl_ctx) + { + clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(const_cast<clang::DeclContext *>(decl_ctx)); + if (tag_decl) + CompleteType(tag_decl); + } +} + Modified: lldb/trunk/source/Symbol/SymbolFile.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolFile.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Symbol/SymbolFile.cpp (original) +++ lldb/trunk/source/Symbol/SymbolFile.cpp Mon Dec 7 19:02:08 2015 @@ -142,3 +142,11 @@ SymbolFile::FindTypes (const SymbolConte return 0; } + +size_t +SymbolFile::FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types) +{ + if (!append) + types.Clear(); + return 0; +} Modified: lldb/trunk/source/Symbol/SymbolVendor.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolVendor.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Symbol/SymbolVendor.cpp (original) +++ lldb/trunk/source/Symbol/SymbolVendor.cpp Mon Dec 7 19:02:08 2015 @@ -361,6 +361,21 @@ SymbolVendor::FindTypes (const SymbolCon } size_t +SymbolVendor::FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types) +{ + ModuleSP module_sp(GetModule()); + if (module_sp) + { + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (m_sym_file_ap.get()) + return m_sym_file_ap->FindTypes(context, append, types); + } + if (!append) + types.Clear(); + return 0; +} + +size_t SymbolVendor::GetTypes (SymbolContextScope *sc_scope, uint32_t type_mask, lldb_private::TypeList &type_list) Modified: lldb/trunk/source/Symbol/Type.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=254980&r1=254979&r2=254980&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Type.cpp (original) +++ lldb/trunk/source/Symbol/Type.cpp Mon Dec 7 19:02:08 2015 @@ -7,8 +7,12 @@ // //===----------------------------------------------------------------------===// -// Other libraries and framework includes +// C Includes +#include <stdio.h> +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/Core/DataExtractor.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Module.h" @@ -36,6 +40,27 @@ using namespace lldb; using namespace lldb_private; +void +CompilerContext::Dump() const +{ + switch (type) + { + case CompilerContextKind::Invalid: printf("Invalid"); break; + case CompilerContextKind::TranslationUnit: printf("TranslationUnit"); break; + case CompilerContextKind::Module: printf("Module"); break; + case CompilerContextKind::Namespace: printf("Namespace"); break; + case CompilerContextKind::Class: printf("Class"); break; + case CompilerContextKind::Structure: printf("Structure"); break; + case CompilerContextKind::Union: printf("Union"); break; + case CompilerContextKind::Function: printf("Function"); break; + case CompilerContextKind::Variable: printf("Variable"); break; + case CompilerContextKind::Enumeration: printf("Enumeration"); break; + case CompilerContextKind::Typedef: printf("Typedef"); break; + default: printf("???(%u)", type); + } + printf("(\"%s\")\n", name.GetCString()); +} + class TypeAppendVisitor { public: @@ -62,6 +87,13 @@ TypeListImpl::Append (const lldb_private type_list.ForEach(cb); } +SymbolFileType::SymbolFileType (SymbolFile &symbol_file, const lldb::TypeSP &type_sp) : + UserID (type_sp ? type_sp->GetID() : LLDB_INVALID_UID), + m_symbol_file (symbol_file), + m_type_sp (type_sp) +{ +} + Type * SymbolFileType::GetType () _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits