diff options
author | Zachary Turner <zturner@google.com> | 2015-03-24 18:56:08 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2015-03-24 18:56:08 +0000 |
commit | a98fac28aa7636998158a3ac1bf764bf14ca8570 (patch) | |
tree | a6b5bbeacc6f7feb5e675d412084a99e6b4061d9 | |
parent | 0783ab9a7f92318830d94d41857c36726cf84eaa (diff) | |
download | bcm5719-llvm-a98fac28aa7636998158a3ac1bf764bf14ca8570.tar.gz bcm5719-llvm-a98fac28aa7636998158a3ac1bf764bf14ca8570.zip |
Fix error introduced by changing function signatures.
Since ClangASTSource::layoutRecordType() was overriding a virtual
function in the base, this was inadvertently causing a new method
to be introduced rather than an override. To fix this all method
signatures are changed back to taking DenseMaps, and the `override`
keyword is added to make sure this type of error doesn't happen
again.
To keep the original fix intact, which is that fields and bases
must be added in offset order, the ImportOffsetMap() function
now copies the DenseMap into a vector and then sorts the vector
on the value type (e.g. the offset) before iterating over the
sorted vector and inserting the items.
llvm-svn: 233099
12 files changed, 185 insertions, 177 deletions
diff --git a/lldb/include/lldb/Expression/ClangASTSource.h b/lldb/include/lldb/Expression/ClangASTSource.h index ab62e491766..da782b51512 100644 --- a/lldb/include/lldb/Expression/ClangASTSource.h +++ b/lldb/include/lldb/Expression/ClangASTSource.h @@ -11,7 +11,6 @@ #define liblldb_ClangASTSource_h_ #include <set> -#include <vector> #include "clang/Basic/IdentifierTable.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" @@ -21,12 +20,6 @@ #include "llvm/ADT/SmallSet.h" -namespace clang -{ -class CharUnits; -class FieldDecl; -} - namespace lldb_private { //---------------------------------------------------------------------- @@ -108,10 +101,8 @@ public: /// @return /// Whatever SetExternalVisibleDeclsForName returns. //------------------------------------------------------------------ - bool - FindExternalVisibleDeclsByName (const clang::DeclContext *DC, - clang::DeclarationName Name); - + bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override; + //------------------------------------------------------------------ /// Enumerate all Decls in a given lexical context. /// @@ -125,13 +116,9 @@ public: /// @param[in] Decls /// A vector that is filled in with matching Decls. //------------------------------------------------------------------ - clang::ExternalLoadResult - FindExternalLexicalDecls (const clang::DeclContext *DC, - bool (*isKindWeWant)(clang::Decl::Kind), - llvm::SmallVectorImpl<clang::Decl*> &Decls); - - typedef std::vector<std::pair<const clang::FieldDecl *, uint64_t>> FieldOffsetList; - typedef std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> BaseOffsetList; + clang::ExternalLoadResult FindExternalLexicalDecls(const clang::DeclContext *DC, + bool (*isKindWeWant)(clang::Decl::Kind), + llvm::SmallVectorImpl<clang::Decl *> &Decls) override; //------------------------------------------------------------------ /// Specify the layout of the contents of a RecordDecl. @@ -167,8 +154,9 @@ public: /// True <=> the layout is valid. //----------------------------------------------------------------- bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, - FieldOffsetList &FieldOffsets, BaseOffsetList &BaseOffsets, - BaseOffsetList &VirtualBaseOffsets); + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override; //------------------------------------------------------------------ /// Complete a TagDecl. @@ -176,18 +164,16 @@ public: /// @param[in] Tag /// The Decl to be completed in place. //------------------------------------------------------------------ - virtual void - CompleteType (clang::TagDecl *Tag); - + void CompleteType(clang::TagDecl *Tag) override; + //------------------------------------------------------------------ /// Complete an ObjCInterfaceDecl. /// /// @param[in] Class /// The Decl to be completed in place. //------------------------------------------------------------------ - virtual void - CompleteType (clang::ObjCInterfaceDecl *Class); - + void CompleteType(clang::ObjCInterfaceDecl *Class) override; + //------------------------------------------------------------------ /// Called on entering a translation unit. Tells Clang by calling /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() @@ -196,8 +182,8 @@ public: /// @param[in] ASTConsumer /// Unused. //------------------------------------------------------------------ - void StartTranslationUnit (clang::ASTConsumer *Consumer); - + void StartTranslationUnit(clang::ASTConsumer *Consumer) override; + // // APIs for NamespaceMapCompleter // @@ -216,10 +202,9 @@ public: /// The map for the namespace's parent namespace, if there is /// one. //------------------------------------------------------------------ - void CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map, - const ConstString &name, - ClangASTImporter::NamespaceMapSP &parent_map) const; - + void CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name, + ClangASTImporter::NamespaceMapSP &parent_map) const override; + // // Helper APIs // @@ -256,37 +241,37 @@ public: m_original(original) { } - + bool - FindExternalVisibleDeclsByName (const clang::DeclContext *DC, - clang::DeclarationName Name) + FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override { return m_original.FindExternalVisibleDeclsByName(DC, Name); } - - clang::ExternalLoadResult - FindExternalLexicalDecls (const clang::DeclContext *DC, - bool (*isKindWeWant)(clang::Decl::Kind), - llvm::SmallVectorImpl<clang::Decl*> &Decls) + + clang::ExternalLoadResult + FindExternalLexicalDecls(const clang::DeclContext *DC, bool (*isKindWeWant)(clang::Decl::Kind), + llvm::SmallVectorImpl<clang::Decl *> &Decls) override { return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls); } - + void - CompleteType (clang::TagDecl *Tag) + CompleteType(clang::TagDecl *Tag) override { return m_original.CompleteType(Tag); } - - void - CompleteType (clang::ObjCInterfaceDecl *Class) + + void + CompleteType(clang::ObjCInterfaceDecl *Class) override { return m_original.CompleteType(Class); } bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, - FieldOffsetList &FieldOffsets, BaseOffsetList &BaseOffsets, BaseOffsetList &VirtualBaseOffsets) + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override { return m_original.layoutRecordType(Record, Size, @@ -296,7 +281,8 @@ public: VirtualBaseOffsets); } - void StartTranslationUnit (clang::ASTConsumer *Consumer) + void + StartTranslationUnit(clang::ASTConsumer *Consumer) override { return m_original.StartTranslationUnit(Consumer); } diff --git a/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h b/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h index 70db4e3c458..91cb3d05c65 100644 --- a/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h +++ b/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h @@ -36,9 +36,9 @@ public: typedef void (*FindExternalVisibleDeclsByNameCallback)(void *baton, const clang::DeclContext *DC, clang::DeclarationName Name, llvm::SmallVectorImpl <clang::NamedDecl *> *results); typedef bool (*LayoutRecordTypeCallback)( void *baton, const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &FieldOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &BaseOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &VirtualBaseOffsets); + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets); ClangExternalASTSourceCallbacks (CompleteTagDeclCallback tag_decl_callback, CompleteObjCInterfaceDeclCallback objc_decl_callback, @@ -57,39 +57,39 @@ public: // clang::ExternalASTSource //------------------------------------------------------------------ - virtual clang::Decl * - GetExternalDecl (uint32_t ID) + clang::Decl * + GetExternalDecl(uint32_t ID) override { // This method only needs to be implemented if the AST source ever // passes back decl sets as VisibleDeclaration objects. return 0; } - - virtual clang::Stmt * - GetExternalDeclStmt (uint64_t Offset) + + clang::Stmt * + GetExternalDeclStmt(uint64_t Offset) override { // This operation is meant to be used via a LazyOffsetPtr. It only // needs to be implemented if the AST source uses methods like // FunctionDecl::setLazyBody when building decls. return 0; } - - virtual clang::Selector - GetExternalSelector (uint32_t ID) + + clang::Selector + GetExternalSelector(uint32_t ID) override { // This operation only needs to be implemented if the AST source // returns non-zero for GetNumKnownSelectors(). return clang::Selector(); } - virtual uint32_t - GetNumExternalSelectors() + uint32_t + GetNumExternalSelectors() override { return 0; } - - virtual clang::CXXBaseSpecifier * - GetExternalCXXBaseSpecifiers(uint64_t Offset) + + clang::CXXBaseSpecifier * + GetExternalCXXBaseSpecifiers(uint64_t Offset) override { return NULL; } @@ -99,31 +99,27 @@ public: { return; } - - virtual clang::ExternalLoadResult - FindExternalLexicalDecls (const clang::DeclContext *decl_ctx, - bool (*isKindWeWant)(clang::Decl::Kind), - llvm::SmallVectorImpl<clang::Decl*> &decls) + + virtual clang::ExternalLoadResult + FindExternalLexicalDecls(const clang::DeclContext *decl_ctx, bool (*isKindWeWant)(clang::Decl::Kind), + llvm::SmallVectorImpl<clang::Decl *> &decls) override { // This is used to support iterating through an entire lexical context, // which isn't something the debugger should ever need to do. return clang::ELR_Failure; } - - virtual bool - FindExternalVisibleDeclsByName (const clang::DeclContext *decl_ctx, - clang::DeclarationName decl_name); - - virtual void - CompleteType (clang::TagDecl *tag_decl); - - virtual void - CompleteType (clang::ObjCInterfaceDecl *objc_decl); + + virtual bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, + clang::DeclarationName decl_name) override; + + virtual void CompleteType(clang::TagDecl *tag_decl) override; + + virtual void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override; bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &FieldOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &BaseOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &VirtualBaseOffsets); + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override; void SetExternalSourceCallbacks (CompleteTagDeclCallback tag_decl_callback, CompleteObjCInterfaceDeclCallback objc_decl_callback, diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 8a39b7a38b5..e9a5c574f05 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -25,6 +25,8 @@ #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" +#include <vector> + using namespace clang; using namespace lldb_private; @@ -1532,21 +1534,36 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context) while(0); } +typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap; +typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap; + template <class D, class O> static bool -ImportOffsetList(std::vector<std::pair<const D *, O>> &destination_list, - const std::vector<std::pair<const D *, O>> &source_list, ClangASTImporter *importer, - ASTContext &dest_ctx) +ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map, llvm::DenseMap<const D *, O> &source_map, + ClangASTImporter *importer, ASTContext &dest_ctx) { - typedef std::vector<std::pair<const D *, O>> ListType; - - for (const auto &fi : source_list) + // When importing fields into a new record, clang has a hard requirement that + // fields be imported in field offset order. Since they are stored in a DenseMap + // with a pointer as the key type, this means we cannot simply iterate over the + // map, as the order will be non-deterministic. Instead we have to sort by the offset + // and then insert in sorted order. + typedef llvm::DenseMap<const D *, O> MapType; + std::vector<typename MapType::value_type> sorted_items; + sorted_items.reserve(source_map.size()); + sorted_items.assign(source_map.begin(), source_map.end()); + std::sort(sorted_items.begin(), sorted_items.end(), + [](const MapType::value_type &lhs, const MapType::value_type &rhs) + { + return lhs.second < rhs.second; + }); + + for (const auto &item : sorted_items) { - DeclFromUser<D> user_decl(const_cast<D *>(fi.first)); + DeclFromUser<D> user_decl(const_cast<D *>(item.first)); DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx)); if (parser_decl.IsInvalid()) return false; - destination_list.push_back(std::pair<const D *, O>(parser_decl.decl, fi.second)); + destination_map.insert(std::pair<const D *, O>(parser_decl.decl, item.second)); } return true; @@ -1555,14 +1572,16 @@ ImportOffsetList(std::vector<std::pair<const D *, O>> &destination_list, template <bool IsVirtual> bool ExtractBaseOffsets(const ASTRecordLayout &record_layout, DeclFromUser<const CXXRecordDecl> &record, - ClangASTSource::BaseOffsetList &base_offsets) + BaseOffsetMap &base_offsets) { - for (const auto &base : (IsVirtual ? record->vbases() : record->bases())) + for (CXXRecordDecl::base_class_const_iterator bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()), + be = (IsVirtual ? record->vbases_end() : record->bases_end()); + bi != be; ++bi) { - if (!IsVirtual && base.isVirtual()) + if (!IsVirtual && bi->isVirtual()) continue; - const clang::Type *origin_base_type = base.getType().getTypePtr(); + const clang::Type *origin_base_type = bi->getType().getTypePtr(); const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>(); if (!origin_base_record_type) @@ -1585,7 +1604,7 @@ ExtractBaseOffsets(const ASTRecordLayout &record_layout, DeclFromUser<const CXXR else base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl); - base_offsets.push_back(std::make_pair(origin_base_cxx_record.decl, base_offset)); + base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset)); } return true; @@ -1593,8 +1612,8 @@ ExtractBaseOffsets(const ASTRecordLayout &record_layout, DeclFromUser<const CXXR bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint64_t &alignment, - FieldOffsetList &field_offsets, BaseOffsetList &base_offsets, - BaseOffsetList &virtual_base_offsets) + FieldOffsetMap &field_offsets, BaseOffsetMap &base_offsets, + BaseOffsetMap &virtual_base_offsets) { ClangASTMetrics::RegisterRecordLayout(); @@ -1615,9 +1634,9 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint6 if (origin_record.IsInvalid()) return false; - FieldOffsetList origin_field_offsets; - BaseOffsetList origin_base_offsets; - BaseOffsetList origin_virtual_base_offsets; + FieldOffsetMap origin_field_offsets; + BaseOffsetMap origin_base_offsets; + BaseOffsetMap origin_virtual_base_offsets; ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl)); @@ -1628,15 +1647,14 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint6 int field_idx = 0, field_count = record_layout.getFieldCount(); - origin_field_offsets.reserve(field_count); - for (const auto &field : origin_record->fields()) + for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end(); fi != fe; ++fi) { if (field_idx >= field_count) return false; // Layout didn't go well. Bail out. uint64_t field_offset = record_layout.getFieldOffset(field_idx); - origin_field_offsets.push_back(std::pair<const FieldDecl *, uint64_t>(field, field_offset)); + origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset)); field_idx++; } @@ -1652,9 +1670,9 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint6 return false; } - if (!ImportOffsetList(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) || - !ImportOffsetList(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) || - !ImportOffsetList(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context)) + if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) || + !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) || + !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context)) return false; size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth(); @@ -1672,10 +1690,8 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint6 fi != fe; ++fi) { - log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits", current_id, - static_cast<void *>(*fi), fi->getNameAsString().c_str(), - record_layout.getFieldOffset(fi->getFieldIndex())); + static_cast<void *>(*fi), fi->getNameAsString().c_str(), field_offsets[*fi]); } DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record); if (parser_cxx_record.IsValid()) @@ -1692,11 +1708,11 @@ ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint6 DeclFromParser <RecordDecl> base_record(base_record_type->getDecl()); DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record); - clang::CharUnits base_offset = is_virtual ? record_layout.getVBaseClassOffset(base_cxx_record.decl) - : record_layout.getBaseClassOffset(base_cxx_record.decl); log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars", current_id, (is_virtual ? "Virtual " : ""), static_cast<void *>(base_cxx_record.decl), - base_cxx_record.decl->getNameAsString().c_str(), base_offset); + base_cxx_record.decl->getNameAsString().c_str(), + (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() + : base_offsets[base_cxx_record.decl].getQuantity())); } } else diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp index 9d949e4b33c..76ac690e717 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -31,8 +31,7 @@ public: } bool - FindExternalVisibleDeclsByName (const clang::DeclContext *decl_ctx, - clang::DeclarationName name) + FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName name) override { static unsigned int invocation_id = 0; unsigned int current_id = invocation_id++; @@ -71,15 +70,14 @@ public: } clang::ExternalLoadResult - FindExternalLexicalDecls (const clang::DeclContext *DC, - bool (*isKindWeWant)(clang::Decl::Kind), - llvm::SmallVectorImpl<clang::Decl*> &Decls) + FindExternalLexicalDecls(const clang::DeclContext *DC, bool (*isKindWeWant)(clang::Decl::Kind), + llvm::SmallVectorImpl<clang::Decl *> &Decls) override { return clang::ELR_Success; } void - CompleteType (clang::TagDecl *tag_decl) + CompleteType(clang::TagDecl *tag_decl) override { static unsigned int invocation_id = 0; unsigned int current_id = invocation_id++; @@ -109,7 +107,7 @@ public: } void - CompleteType (clang::ObjCInterfaceDecl *interface_decl) + CompleteType(clang::ObjCInterfaceDecl *interface_decl) override { static unsigned int invocation_id = 0; unsigned int current_id = invocation_id++; @@ -142,14 +140,15 @@ public: bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &FieldOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &BaseOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &VirtualBaseOffsets) + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override { return false; } - void StartTranslationUnit (clang::ASTConsumer *Consumer) + void + StartTranslationUnit(clang::ASTConsumer *Consumer) override { clang::TranslationUnitDecl *translation_unit_decl = m_decl_vendor.m_ast_ctx.getASTContext()->getTranslationUnitDecl(); translation_unit_decl->setHasExternalVisibleStorage(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 6df5768e964..a546542ca91 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2074,7 +2074,7 @@ SymbolFileDWARF::ParseChildMembers accessibility, anon_field_info.bit_size); - layout_info.field_offsets.push_back( + layout_info.field_offsets.insert( std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset)); } } @@ -2126,7 +2126,7 @@ SymbolFileDWARF::ParseChildMembers GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset())); - layout_info.field_offsets.push_back(std::make_pair(field_decl, field_bit_offset)); + layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset)); } else { @@ -2287,7 +2287,7 @@ SymbolFileDWARF::ParseChildMembers } else { - layout_info.base_offsets.push_back( + layout_info.base_offsets.insert( std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(), clang::CharUnits::fromQuantity(member_byte_offset))); } @@ -2670,36 +2670,46 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) static_cast<uint32_t>(layout_info.base_offsets.size()), static_cast<uint32_t>(layout_info.vbase_offsets.size())); - for (const auto &entry : layout_info.field_offsets) + uint32_t idx; + { + llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos, + end = layout_info.field_offsets.end(); + for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx) { GetObjectFile()->GetModule()->LogMessage( log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = " "{ bit_offset=%u, name='%s' }", - static_cast<void *>(clang_type.GetOpaqueQualType()), entry.first->getFieldIndex(), - static_cast<uint32_t>(entry.second), entry.first->getNameAsString().c_str()); + static_cast<void *>(clang_type.GetOpaqueQualType()), idx, + static_cast<uint32_t>(pos->second), pos->first->getNameAsString().c_str()); + } } - uint32_t idx = 0; - for (const auto &entry : layout_info.base_offsets) { - GetObjectFile()->GetModule()->LogMessage( - log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] = { " - "byte_offset=%u, name='%s' }", - clang_type.GetOpaqueQualType(), idx, (uint32_t)entry.second.getQuantity(), - entry.first->getNameAsString().c_str()); - ++idx; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos, + base_end = layout_info.base_offsets.end(); + for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; + ++base_pos, ++idx) + { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] " + "= { byte_offset=%u, name='%s' }", + clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(), + base_pos->first->getNameAsString().c_str()); + } } - - idx = 0; - for (const auto &entry : layout_info.vbase_offsets) { - GetObjectFile()->GetModule()->LogMessage( - log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) vbase[%u] = " - "{ byte_offset=%u, name='%s' }", - static_cast<void *>(clang_type.GetOpaqueQualType()), idx, - static_cast<uint32_t>(entry.second.getQuantity()), - entry.first->getNameAsString().c_str()); - ++idx; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos, + vbase_end = layout_info.vbase_offsets.end(); + for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; + ++vbase_pos, ++idx) + { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) " + "vbase[%u] = { byte_offset=%u, name='%s' }", + static_cast<void *>(clang_type.GetOpaqueQualType()), idx, + static_cast<uint32_t>(vbase_pos->second.getQuantity()), + vbase_pos->first->getNameAsString().c_str()); + } } } m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info)); @@ -7933,9 +7943,9 @@ SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton, bool SymbolFileDWARF::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &field_offsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &base_offsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &vbase_offsets) + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) { SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets); @@ -7943,9 +7953,9 @@ SymbolFileDWARF::LayoutRecordType(void *baton, const clang::RecordDecl *record_d bool SymbolFileDWARF::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &field_offsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &base_offsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &vbase_offsets) + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) { Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 4551d6ef56b..981e3551460 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -151,16 +151,15 @@ public: clang::DeclarationName Name, llvm::SmallVectorImpl <clang::NamedDecl *> *results); - static bool - LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &FieldOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &BaseOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &VirtualBaseOffsets); + static bool LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); bool LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &FieldOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &BaseOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &VirtualBaseOffsets); + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); struct LayoutInfo { @@ -174,9 +173,9 @@ public: } uint64_t bit_size; uint64_t alignment; - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> field_offsets; - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> base_offsets; - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> vbase_offsets; + llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets; }; //------------------------------------------------------------------ // PluginInterface protocol diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index eeb3ef8242a..9636028d0f5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1475,11 +1475,11 @@ SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInte } bool -SymbolFileDWARFDebugMap::LayoutRecordType( - void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &field_offsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &base_offsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &vbase_offsets) +SymbolFileDWARFDebugMap::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, + uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) { SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; SymbolFileDWARF *oso_dwarf; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index cecd6396784..d4400eb78e6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -103,11 +103,10 @@ public: static void CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *); - static bool - LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &FieldOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &BaseOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &VirtualBaseOffsets); + static bool LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); //------------------------------------------------------------------ // PluginInterface protocol diff --git a/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp b/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp index b8e78fe0c63..cd6972cce97 100644 --- a/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp +++ b/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp @@ -144,9 +144,9 @@ ClangExternalASTSourceCallbacks::CompleteType (ObjCInterfaceDecl *objc_decl) bool ClangExternalASTSourceCallbacks::layoutRecordType( const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, - std::vector<std::pair<const clang::FieldDecl *, uint64_t>> &FieldOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &BaseOffsets, - std::vector<std::pair<const clang::CXXRecordDecl *, clang::CharUnits>> &VirtualBaseOffsets) + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) { if (m_callback_layout_record_type) return m_callback_layout_record_type(m_callback_baton, diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py index c5f78ad82aa..aad75d46dcd 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py @@ -20,7 +20,7 @@ class LibcxxVBoolDataFormatterTestCase(TestBase): self.data_formatter_commands() @skipIfLinux # No standard locations for libc++ on Linux, so skip for now - @skipIfWindows # Windows doesn't have libcxx + @skipIfWindows # http://llvm.org/pr21800 @dwarf_test def test_with_dwarf_and_run_command(self): """Test data formatter commands.""" diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py b/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py index 28d0001b7a4..314b5b9a17a 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py @@ -22,6 +22,7 @@ class StdVBoolDataFormatterTestCase(TestBase): @expectedFailureFreeBSD("llvm.org/pr20548") # fails to build on lab.llvm.org buildbot @dwarf_test + @skipIfWindows # http://llvm.org/pr21800 @skipIfDarwin def test_with_dwarf_and_run_command(self): """Test data formatter commands.""" diff --git a/lldb/test/lang/c/bitfields/TestBitfields.py b/lldb/test/lang/c/bitfields/TestBitfields.py index 380246ddd6b..573d161ff75 100644 --- a/lldb/test/lang/c/bitfields/TestBitfields.py +++ b/lldb/test/lang/c/bitfields/TestBitfields.py @@ -26,6 +26,7 @@ class BitfieldsTestCase(TestBase): self.bitfields_variable_python() @dwarf_test + @unittest2.skipIf(sys.platform.startswith("win32"), "BitFields exhibit crashes in record layout on Windows (http://llvm.org/pr21800)") def test_with_dwarf_and_run_command(self): """Test 'frame variable ...' on a variable with bitfields.""" self.buildDwarf() @@ -33,6 +34,7 @@ class BitfieldsTestCase(TestBase): @python_api_test @dwarf_test + @unittest2.skipIf(sys.platform.startswith("win32"), "BitFields exhibit crashes in record layout on Windows (http://llvm.org/pr21800)") @expectedFailureGcc # GCC (4.6/4.7) generates incorrect code with unnamed bitfields. def test_with_dwarf_and_python_api(self): """Use Python APIs to inspect a bitfields variable.""" |