Index: clang/include/clang/AST/ExternalASTSource.h =================================================================== --- clang/include/clang/AST/ExternalASTSource.h +++ clang/include/clang/AST/ExternalASTSource.h @@ -311,6 +311,7 @@ SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name); +public: /// Increment the current generation. uint32_t incrementGeneration(ASTContext &C); }; Index: clang/include/clang/AST/Redeclarable.h =================================================================== --- clang/include/clang/AST/Redeclarable.h +++ clang/include/clang/AST/Redeclarable.h @@ -182,7 +182,9 @@ /// #3 int f(int x, int y) { return x + y; } // /// /// If there is only one declaration, it is +public: DeclLink RedeclLink; +protected: decl_type *First; Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h +++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h @@ -147,7 +147,7 @@ bool CompleteType(const CompilerType &compiler_type); - bool CompleteTagDecl(clang::TagDecl *decl); + bool CompleteTagDecl(const clang::TagDecl *decl); bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin); @@ -262,7 +262,7 @@ ASTImporterDelegate(ClangASTImporter &master, clang::ASTContext *target_ctx, clang::ASTContext *source_ctx) : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx, - master.m_file_manager, true /*minimal*/), + master.m_file_manager, false /*minimal*/), m_master(master), m_source_ctx(source_ctx) { // Target and source ASTContext shouldn't be identical. Importing AST // nodes within the same AST doesn't make any sense as the whole idea Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -266,12 +266,6 @@ tag_decl->setCompleteDefinition(true); } } - - tag_decl->setHasExternalLexicalStorage(false); - tag_decl->setHasExternalVisibleStorage(false); - } else if (auto *container_decl = dyn_cast(decl)) { - container_decl->setHasExternalLexicalStorage(false); - container_decl->setHasExternalVisibleStorage(false); } to_context_md->removeOrigin(decl); @@ -506,14 +500,7 @@ if (!CanImport(compiler_type)) return false; - if (Import(compiler_type)) { - TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); - return true; - } - - TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), - false); - return false; + return Import(compiler_type); } bool ClangASTImporter::LayoutRecordType( @@ -524,6 +511,7 @@ &base_offsets, llvm::DenseMap &vbase_offsets) { + record_decl = record_decl->getDefinition(); RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find(record_decl); bool success = false; @@ -535,7 +523,6 @@ field_offsets.swap(pos->second.field_offsets); base_offsets.swap(pos->second.base_offsets); vbase_offsets.swap(pos->second.vbase_offsets); - m_record_decl_to_layout_map.erase(pos); success = true; } else { bit_size = 0; @@ -550,7 +537,7 @@ m_record_decl_to_layout_map.insert(std::make_pair(decl, layout)); } -bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { +bool ClangASTImporter::CompleteTagDecl(const TagDecl *decl) { DeclOrigin decl_origin = GetDeclOrigin(decl); if (!decl_origin.Valid()) @@ -564,29 +551,36 @@ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, &decl->getASTContext()); - if (delegate_sp) - delegate_sp->ImportDefinitionTo(decl, decl_origin.decl); + if (!delegate_sp) + return false; - return true; + clang::TagDecl *origin_decl = llvm::cast(decl_origin.decl); + + origin_decl = origin_decl->getDefinition(); + if (!origin_decl) + return false; + + llvm::Expected result = delegate_sp->Import(origin_decl); + if (result) + return true; + llvm::handleAllErrors(result.takeError(), [](clang::ImportError &e){ + abort(); + }); + + return false; } bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl) { - clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); - - if (!TypeSystemClang::GetCompleteDecl(origin_ast_ctx, origin_decl)) + origin_decl = origin_decl->getDefinition(); + if (!origin_decl) return false; - ImporterDelegateSP delegate_sp( - GetDelegate(&decl->getASTContext(), origin_ast_ctx)); - - if (delegate_sp) - delegate_sp->ImportDefinitionTo(decl, origin_decl); - + clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - context_md->setOrigin(decl, DeclOrigin(origin_ast_ctx, origin_decl)); - return true; + + return CompleteTagDecl(decl); } bool ClangASTImporter::CompleteObjCInterfaceDecl( @@ -721,8 +715,15 @@ ClangASTImporter::DeclOrigin ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) { ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); - - return context_md->getOrigin(decl); + DeclOrigin o = context_md->getOrigin(decl); + if (o.Valid()) + return o; + if (const clang::TagDecl *td = dyn_cast(decl)) { + if (const clang::TagDecl *def = td->getDefinition()) { + o = context_md->getOrigin(def); + } + } + return o; } void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl, @@ -860,6 +861,10 @@ } } + if (isa(From)) + if (clang::ExternalASTSource *s = getToContext().getExternalSource()) + s->incrementGeneration(getToContext()); + // If we have a forcefully completed type, try to find an actual definition // for it in other modules. const ClangASTMetadata *md = m_master.GetDeclMetadata(From); @@ -1128,45 +1133,24 @@ from, m_source_ctx, &to->getASTContext()); } - if (auto *to_tag_decl = dyn_cast(to)) { - to_tag_decl->setHasExternalLexicalStorage(); - to_tag_decl->getPrimaryContext()->setMustBuildLookupTable(); - auto from_tag_decl = cast(from); - - LLDB_LOG( - log, - " [ClangASTImporter] To is a TagDecl - attributes {0}{1} [{2}->{3}]", - (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""), - (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""), - (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"), - (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete")); - } - if (auto *to_namespace_decl = dyn_cast(to)) { m_master.BuildNamespaceMap(to_namespace_decl); to_namespace_decl->setHasExternalVisibleStorage(); } if (auto *to_container_decl = dyn_cast(to)) { - to_container_decl->setHasExternalLexicalStorage(); - to_container_decl->setHasExternalVisibleStorage(); - if (log) { if (ObjCInterfaceDecl *to_interface_decl = llvm::dyn_cast(to_container_decl)) { LLDB_LOG( log, " [ClangASTImporter] To is an ObjCInterfaceDecl - attributes " - "{0}{1}{2}", - (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""), - (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""), + "{0}", (to_interface_decl->hasDefinition() ? " HasDefinition" : "")); } else { LLDB_LOG( - log, " [ClangASTImporter] To is an {0}Decl - attributes {1}{2}", - ((Decl *)to_container_decl)->getDeclKindName(), - (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""), - (to_container_decl->hasExternalVisibleStorage() ? " Visible" : "")); + log, " [ClangASTImporter] To is an {0}Decl", + ((Decl *)to_container_decl)->getDeclKindName()); } } } Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h +++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h @@ -153,6 +153,8 @@ /// The Decl to be completed in place. void CompleteType(clang::ObjCInterfaceDecl *Class) override; + void CompleteRedeclChain(const clang::Decl *D) override; + /// Called on entering a translation unit. Tells Clang by calling /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that /// this object has something to say about undefined names. @@ -231,6 +233,11 @@ return m_original.CompleteType(Class); } + void CompleteRedeclChain(const clang::Decl *D) override { + return m_original.CompleteRedeclChain(D); + } + + bool layoutRecordType( const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, llvm::DenseMap &FieldOffsets, Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -341,6 +341,12 @@ LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl)); } +void ClangASTSource::CompleteRedeclChain(const Decl *d) { + if (const clang::TagDecl *td = llvm::dyn_cast(d)) { + m_ast_importer_sp->CompleteTagDecl(td); + } +} + clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface( const clang::ObjCInterfaceDecl *interface_decl) { lldb::ProcessSP process(m_target->GetProcessSP()); Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h @@ -37,6 +37,8 @@ void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override; + void CompleteRedeclChain(const clang::Decl *D) override; + bool layoutRecordType( const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, llvm::DenseMap &FieldOffsets, @@ -47,6 +49,10 @@ TypeSystemClang &GetTypeSystem() const { return m_ast; } + void bumpGeneration() { + incrementGeneration(m_ast.getASTContext()); + } + /// Module-related methods. /// \{ llvm::Optional Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp @@ -17,7 +17,7 @@ char ClangExternalASTSourceCallbacks::ID; void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) { - m_ast.CompleteTagDecl(tag_decl); + //m_ast.CompleteTagDecl(tag_decl); } void ClangExternalASTSourceCallbacks::CompleteType( @@ -25,6 +25,11 @@ m_ast.CompleteObjCInterfaceDecl(objc_decl); } +void ClangExternalASTSourceCallbacks::CompleteRedeclChain(const clang::Decl *d) { + if (const clang::TagDecl *td = llvm::dyn_cast(d)) + m_ast.CompleteTagDecl(td); +} + bool ClangExternalASTSourceCallbacks::layoutRecordType( const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, llvm::DenseMap &FieldOffsets, Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -201,7 +201,7 @@ FieldInfo &last_field_info); bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &clang_type); + lldb_private::CompilerType clang_type); bool CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type, lldb_private::CompilerType &clang_type); Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1654,7 +1654,7 @@ // Store a forward declaration to this class type in case any // parameters in any class methods need it for the clang types for // function prototypes. - LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(GetClangDeclContextContainingDIE(die, nullptr), die); type_sp = std::make_shared( die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type, @@ -1699,18 +1699,6 @@ } } } else if (clang_type_was_created) { - // Start the definition if the class is not objective C since the - // underlying decls respond to isCompleteDefinition(). Objective - // C decls don't respond to isCompleteDefinition() so we can't - // start the declaration definition right away. For C++ - // class/union/structs we want to start the definition in case the - // class is needed as the declaration context for a contained class - // or type without the need to complete that type.. - - if (attrs.class_language != eLanguageTypeObjC && - attrs.class_language != eLanguageTypeObjC_plus_plus) - TypeSystemClang::StartTagDeclarationDefinition(clang_type); - // Leave this as a forward declaration until we need to know the // details of the type. lldb_private::Type will automatically call // the SymbolFile virtual function @@ -1728,7 +1716,6 @@ dwarf->GetForwardDeclClangTypeToDie().try_emplace( ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(), *die.GetDIERef()); - m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); } } @@ -1736,7 +1723,7 @@ // do this for pass by value - which implies the Trivial ABI. There // isn't a way to assert that something that would normally be pass by // value is pass by reference, so we ignore that attribute if set. - if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) { + /*if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) { clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()); if (record_decl && record_decl->getDefinition()) { @@ -1750,7 +1737,7 @@ if (record_decl) record_decl->setArgPassingRestrictions( clang::RecordDecl::APK_CannotPassInRegs); - } + } */ return type_sp; } @@ -1953,21 +1940,15 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type, - CompilerType &clang_type) { + CompilerType clang_type) { const dw_tag_t tag = die.Tag(); SymbolFileDWARF *dwarf = die.GetDWARF(); ClangASTImporter::LayoutInfo layout_info; if (die.HasChildren()) { - const bool type_is_objc_object_or_interface = - TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type); - if (type_is_objc_object_or_interface) { - // For objective C we don't start the definition when the class is - // created. - TypeSystemClang::StartTagDeclarationDefinition(clang_type); - } - + clang_type = m_ast.RedeclTagDecl(clang_type); + TypeSystemClang::StartTagDeclarationDefinition(clang_type); int tag_decl_kind = -1; AccessType default_accessibility = eAccessNone; if (tag == DW_TAG_structure_type) { @@ -1996,6 +1977,8 @@ for (const DWARFDIE &die : member_function_dies) dwarf->ResolveType(die); + const bool type_is_objc_object_or_interface = + TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type); if (type_is_objc_object_or_interface) { ConstString class_name(clang_type.GetTypeName()); if (class_name) { @@ -2069,7 +2052,6 @@ if (record_decl) GetClangASTImporter().SetRecordLayout(record_decl, layout_info); } - return (bool)clang_type; } @@ -2085,6 +2067,7 @@ } TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } + return (bool)clang_type; } @@ -2096,10 +2079,6 @@ std::lock_guard guard( dwarf->GetObjectFile()->GetModule()->GetMutex()); - // Disable external storage for this type so we don't get anymore - // clang::ExternalASTSource queries for this type. - m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), false); - if (!die) return false; Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -49,6 +49,7 @@ namespace lldb_private { +class ClangExternalASTSourceCallbacks; class ClangASTMetadata; class ClangASTSource; class Declaration; @@ -454,10 +455,12 @@ PDBASTParser *GetPDBParser() override; // TypeSystemClang callbacks for external source lookups. - void CompleteTagDecl(clang::TagDecl *); + void CompleteTagDecl(const clang::TagDecl *); void CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *); + CompilerType RedeclTagDecl(CompilerType ct); + bool LayoutRecordType( const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, llvm::DenseMap &field_offsets, @@ -1062,6 +1065,7 @@ GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); // Classes that inherit from TypeSystemClang can see and modify these + ClangExternalASTSourceCallbacks *m_ast_callbacks = nullptr; std::string m_target_triple; std::unique_ptr m_ast_up; std::unique_ptr m_language_options_up; Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -41,6 +41,7 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/Threading.h" +#include "llvm/ADT/ScopeExit.h" #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" @@ -761,7 +762,7 @@ GetASTMap().Insert(m_ast_up.get(), this); llvm::IntrusiveRefCntPtr ast_source_up( - new ClangExternalASTSourceCallbacks(*this)); + m_ast_callbacks = new ClangExternalASTSourceCallbacks(*this)); SetExternalSource(ast_source_up); } @@ -1290,6 +1291,11 @@ if (decl_ctx == nullptr) decl_ctx = ast.getTranslationUnitDecl(); + auto bumper = llvm::make_scope_exit([this](){ + if (m_ast_up) + m_ast_up->getExternalSource()->incrementGeneration(*m_ast_up); + }); + if (language == eLanguageTypeObjC || language == eLanguageTypeObjC_plus_plus) { bool isForwardDecl = true; @@ -2411,23 +2417,21 @@ if (tag_decl->isCompleteDefinition()) return true; - if (!tag_decl->hasExternalLexicalStorage()) - return false; - ast_source->CompleteType(tag_decl); - return !tag_decl->getTypeForDecl()->isIncompleteType(); + tag_decl = tag_decl->getDefinition(); + + return tag_decl && !tag_decl->getTypeForDecl()->isIncompleteType(); } else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast(decl)) { if (objc_interface_decl->getDefinition()) return true; - if (!objc_interface_decl->hasExternalLexicalStorage()) - return false; - ast_source->CompleteType(objc_interface_decl); - return !objc_interface_decl->getTypeForDecl()->isIncompleteType(); + objc_interface_decl = objc_interface_decl->getDefinition(); + + return objc_interface_decl && !objc_interface_decl->getTypeForDecl()->isIncompleteType(); } else { return false; } @@ -2570,7 +2574,7 @@ return nullptr; } -static bool GetCompleteQualType(clang::ASTContext *ast, +static QualType GetCompleteQualType(clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true) { qual_type = RemoveWrappingTypes(qual_type); @@ -2588,33 +2592,10 @@ } 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->field_begin(); - cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); - } - } - } - } - const clang::TagType *tag_type = - llvm::cast(qual_type.getTypePtr()); - return !tag_type->isIncompleteType(); + cxx_record_decl = cxx_record_decl->getDefinition(); + if (!cxx_record_decl) + return QualType(); + return QualType(cxx_record_decl->getTypeForDecl(), 0); } break; case clang::Type::Enum: { @@ -2624,10 +2605,7 @@ clang::TagDecl *tag_decl = tag_type->getDecl(); if (tag_decl) { if (tag_decl->getDefinition()) - return true; - - if (!allow_completion) - return false; + return QualType(tag_decl->getTypeForDecl(), 0); if (tag_decl->hasExternalLexicalStorage()) { if (ast) { @@ -2635,11 +2613,11 @@ ast->getExternalSource(); if (external_ast_source) { external_ast_source->CompleteType(tag_decl); - return !tag_type->isIncompleteType(); + return QualType(tag_decl->getTypeForDecl(), 0); } } } - return false; + return QualType(tag_decl->getTypeForDecl(), 0); } } @@ -2651,27 +2629,8 @@ 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 (class_interface_decl->getDefinition()) - return true; - - if (!allow_completion) - return false; - - if (class_interface_decl->hasExternalLexicalStorage()) { - if (ast) { - 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; - } + class_interface_decl = class_interface_decl->getDefinition(); + return QualType(class_interface_decl->getTypeForDecl(), 0); } } break; @@ -2684,7 +2643,7 @@ break; } - return true; + return qual_type; } static clang::ObjCIvarDecl::AccessControl @@ -2883,8 +2842,8 @@ bool TypeSystemClang::IsCompleteType(lldb::opaque_compiler_type_t type) { const bool allow_completion = false; - return GetCompleteQualType(&getASTContext(), GetQualType(type), - allow_completion); + return !GetCompleteQualType(&getASTContext(), GetQualType(type), + allow_completion).isNull(); } bool TypeSystemClang::IsConst(lldb::opaque_compiler_type_t type) { @@ -3669,8 +3628,8 @@ if (!type) return false; const bool allow_completion = true; - return GetCompleteQualType(&getASTContext(), GetQualType(type), - allow_completion); + return !GetCompleteQualType(&getASTContext(), GetQualType(type), + allow_completion).isNull(); } ConstString TypeSystemClang::GetTypeName(lldb::opaque_compiler_type_t type) { @@ -4247,7 +4206,8 @@ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); switch (qual_type->getTypeClass()) { case clang::Type::Record: - if (GetCompleteQualType(&getASTContext(), qual_type)) { + qual_type = GetCompleteQualType(&getASTContext(), qual_type); + if (!qual_type.isNull()) { const clang::RecordType *record_type = llvm::cast(qual_type.getTypePtr()); const clang::RecordDecl *record_decl = record_type->getDecl(); @@ -4311,7 +4271,8 @@ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); switch (qual_type->getTypeClass()) { case clang::Type::Record: - if (GetCompleteQualType(&getASTContext(), qual_type)) { + qual_type = GetCompleteQualType(&getASTContext(), qual_type); + if (!qual_type.isNull()) { const clang::RecordType *record_type = llvm::cast(qual_type.getTypePtr()); const clang::RecordDecl *record_decl = record_type->getDecl(); @@ -5233,7 +5194,8 @@ case clang::Type::Complex: return 0; case clang::Type::Record: - if (GetCompleteQualType(&getASTContext(), qual_type)) { + qual_type = GetCompleteQualType(&getASTContext(), qual_type); + if (!qual_type.isNull()) { const clang::RecordType *record_type = llvm::cast(qual_type.getTypePtr()); const clang::RecordDecl *record_decl = record_type->getDecl(); @@ -5277,7 +5239,8 @@ case clang::Type::ObjCObject: case clang::Type::ObjCInterface: - if (GetCompleteQualType(&getASTContext(), qual_type)) { + qual_type = GetCompleteQualType(&getASTContext(), qual_type); + if (!qual_type.isNull()) { const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast(qual_type.getTypePtr()); assert(objc_class_type); @@ -8153,9 +8116,6 @@ 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; } } @@ -9162,10 +9122,10 @@ return nullptr; } -void TypeSystemClang::CompleteTagDecl(clang::TagDecl *decl) { +void TypeSystemClang::CompleteTagDecl(const clang::TagDecl *decl) { SymbolFile *sym_file = GetSymbolFile(); if (sym_file) { - CompilerType clang_type = GetTypeForDecl(decl); + CompilerType clang_type = GetTypeForDecl(const_cast(decl)); if (clang_type) sym_file->CompleteType(clang_type); } @@ -9181,6 +9141,18 @@ } } +CompilerType TypeSystemClang::RedeclTagDecl(CompilerType ct) { + if (clang::TagDecl *d = ClangUtil::GetAsTagDecl(ct)) { + CompilerType res = CreateRecordType(d->getDeclContext()->getRedeclContext(), OptionalClangModuleID(), + lldb::eAccessPublic, d->getName(), d->getTagKind(), + eLanguageTypeC_plus_plus, nullptr); + clang::TagDecl *td = ClangUtil::GetAsTagDecl(res); + d->RedeclLink.setLatest(td); + return res; + } + return ct; +} + DWARFASTParser *TypeSystemClang::GetDWARFParser() { if (!m_dwarf_ast_parser_up) m_dwarf_ast_parser_up = std::make_unique(*this);