diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h index 94edd83be336b..dc1df9f27a6c4 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h @@ -172,7 +172,7 @@ class LVLocation : public LVObject { class LVLocationSymbol final : public LVLocation { // Location descriptors for the active range. - LVAutoOperations *Entries = nullptr; + std::unique_ptr Entries; void updateKind() override; @@ -180,7 +180,7 @@ class LVLocationSymbol final : public LVLocation { LVLocationSymbol() : LVLocation() {} LVLocationSymbol(const LVLocationSymbol &) = delete; LVLocationSymbol &operator=(const LVLocationSymbol &) = delete; - ~LVLocationSymbol() { delete Entries; }; + ~LVLocationSymbol() = default; void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset, uint64_t LocDescOffset) override; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h index a097372bccfd0..ca429d2c28932 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h @@ -74,21 +74,6 @@ using LVSymbolGetFunction = bool (LVSymbol::*)() const; using LVTypeSetFunction = void (LVType::*)(); using LVTypeGetFunction = bool (LVType::*)() const; -// The LVScope class represents a logical scope and uses vectors to store its -// children, which are pointers to other allocated logical elements (types, -// symbols, lines, scopes, ranges). On destruction, we have to traverse each -// vector and destroy its elements. The other case is LVSymbol. -// These definitions are intended to be used by the LVScope and LVSymbol -// to support automatic vector cleanup. -using LVAutoLines = LVAutoSmallVector; -using LVAutoLocations = LVAutoSmallVector; -using LVAutoOperations = LVAutoSmallVector; -using LVAutoScopes = LVAutoSmallVector; -using LVAutoSymbols = LVAutoSmallVector; -using LVAutoTypes = LVAutoSmallVector; - -// These definitions are intended to be used when the vector will be used -// just a container, with no automatic destruction. using LVElements = SmallVector; using LVLines = SmallVector; using LVLocations = SmallVector; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h index ed1807ce8bf8c..ff1a41cdf3e5c 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h @@ -54,6 +54,9 @@ class LVSplitContext final { raw_fd_ostream &os() { return OutputFile->os(); } }; +/// The logical reader owns of all the logical elements created during +/// the debug information parsing. For its creation it uses a specific +/// bump allocator for each type of logical element. class LVReader { LVBinaryType BinaryType; @@ -74,6 +77,50 @@ class LVReader { Error createSplitFolder(); bool OutputSplit = false; +// Define a specific bump allocator for the given KIND. +#define LV_OBJECT_ALLOCATOR(KIND) \ + llvm::SpecificBumpPtrAllocator Allocated##KIND; + + // Lines allocator. + LV_OBJECT_ALLOCATOR(Line) + LV_OBJECT_ALLOCATOR(LineDebug) + LV_OBJECT_ALLOCATOR(LineAssembler) + + // Locations allocator. + LV_OBJECT_ALLOCATOR(Location) + LV_OBJECT_ALLOCATOR(LocationSymbol) + + // Operations allocator. + LV_OBJECT_ALLOCATOR(Operation) + + // Scopes allocator. + LV_OBJECT_ALLOCATOR(Scope) + LV_OBJECT_ALLOCATOR(ScopeAggregate) + LV_OBJECT_ALLOCATOR(ScopeAlias) + LV_OBJECT_ALLOCATOR(ScopeArray) + LV_OBJECT_ALLOCATOR(ScopeCompileUnit) + LV_OBJECT_ALLOCATOR(ScopeEnumeration) + LV_OBJECT_ALLOCATOR(ScopeFormalPack) + LV_OBJECT_ALLOCATOR(ScopeFunction) + LV_OBJECT_ALLOCATOR(ScopeFunctionInlined) + LV_OBJECT_ALLOCATOR(ScopeFunctionType) + LV_OBJECT_ALLOCATOR(ScopeNamespace) + LV_OBJECT_ALLOCATOR(ScopeRoot) + LV_OBJECT_ALLOCATOR(ScopeTemplatePack) + + // Symbols allocator. + LV_OBJECT_ALLOCATOR(Symbol) + + // Types allocator. + LV_OBJECT_ALLOCATOR(Type) + LV_OBJECT_ALLOCATOR(TypeDefinition) + LV_OBJECT_ALLOCATOR(TypeEnumerator) + LV_OBJECT_ALLOCATOR(TypeImport) + LV_OBJECT_ALLOCATOR(TypeParam) + LV_OBJECT_ALLOCATOR(TypeSubrange) + +#undef LV_OBJECT_ALLOCATOR + protected: LVScopeRoot *Root = nullptr; std::string InputFilename; @@ -92,7 +139,7 @@ class LVReader { // Create the Scope Root. virtual Error createScopes() { - Root = new LVScopeRoot(); + Root = createScopeRoot(); Root->setName(getFilename()); if (options().getAttributeFormat()) Root->setFileFormatName(FileFormatName); @@ -129,9 +176,62 @@ class LVReader { OS(W.getOStream()) {} LVReader(const LVReader &) = delete; LVReader &operator=(const LVReader &) = delete; - virtual ~LVReader() { - if (Root) - delete Root; + virtual ~LVReader() = default; + +// Creates a logical object of the given KIND. The signature for the created +// functions looks like: +// ... +// LVScope *createScope() +// LVScopeRoot *creatScopeRoot() +// LVType *createType(); +// ... +#define LV_CREATE_OBJECT(KIND) \ + LV##KIND *create##KIND() { \ + return new (Allocated##KIND.Allocate()) LV##KIND(); \ + } + + // Lines creation. + LV_CREATE_OBJECT(Line) + LV_CREATE_OBJECT(LineDebug) + LV_CREATE_OBJECT(LineAssembler) + + // Locations creation. + LV_CREATE_OBJECT(Location) + LV_CREATE_OBJECT(LocationSymbol) + + // Scopes creation. + LV_CREATE_OBJECT(Scope) + LV_CREATE_OBJECT(ScopeAggregate) + LV_CREATE_OBJECT(ScopeAlias) + LV_CREATE_OBJECT(ScopeArray) + LV_CREATE_OBJECT(ScopeCompileUnit) + LV_CREATE_OBJECT(ScopeEnumeration) + LV_CREATE_OBJECT(ScopeFormalPack) + LV_CREATE_OBJECT(ScopeFunction) + LV_CREATE_OBJECT(ScopeFunctionInlined) + LV_CREATE_OBJECT(ScopeFunctionType) + LV_CREATE_OBJECT(ScopeNamespace) + LV_CREATE_OBJECT(ScopeRoot) + LV_CREATE_OBJECT(ScopeTemplatePack) + + // Symbols creation. + LV_CREATE_OBJECT(Symbol) + + // Types creation. + LV_CREATE_OBJECT(Type) + LV_CREATE_OBJECT(TypeDefinition) + LV_CREATE_OBJECT(TypeEnumerator) + LV_CREATE_OBJECT(TypeImport) + LV_CREATE_OBJECT(TypeParam) + LV_CREATE_OBJECT(TypeSubrange) + +#undef LV_CREATE_OBJECT + + // Operations creation. + LVOperation *createOperation(LVSmall OpCode, LVUnsigned Operand1, + LVUnsigned Operand2) { + return new (AllocatedOperation.Allocate()) + LVOperation(OpCode, Operand1, Operand2); } StringRef getFilename(LVObject *Object, size_t Index) const; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h index 8204163f34de6..4368e9334387b 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h @@ -63,12 +63,11 @@ using LVScopeKindSet = std::set; using LVScopeDispatch = std::map; using LVScopeRequest = std::vector; -using LVOffsetList = std::list; using LVOffsetElementMap = std::map; -using LVOffsetLinesMap = std::map; -using LVOffsetLocationsMap = std::map; +using LVOffsetLinesMap = std::map; +using LVOffsetLocationsMap = std::map; using LVOffsetSymbolMap = std::map; -using LVTagOffsetsMap = std::map; +using LVTagOffsetsMap = std::map; // Class to represent a DWARF Scope. class LVScope : public LVElement { @@ -100,7 +99,8 @@ class LVScope : public LVElement { // Calculate coverage factor. void calculateCoverage() { float CoveragePercentage = 0; - LVLocation::calculateCoverage(Ranges, CoverageFactor, CoveragePercentage); + LVLocation::calculateCoverage(Ranges.get(), CoverageFactor, + CoveragePercentage); } // Decide if the scope will be printed, using some conditions given by: @@ -117,11 +117,11 @@ class LVScope : public LVElement { protected: // Types, Symbols, Scopes, Lines, Locations in this scope. - LVAutoTypes *Types = nullptr; - LVAutoSymbols *Symbols = nullptr; - LVAutoScopes *Scopes = nullptr; - LVAutoLines *Lines = nullptr; - LVAutoLocations *Ranges = nullptr; + std::unique_ptr Types; + std::unique_ptr Symbols; + std::unique_ptr Scopes; + std::unique_ptr Lines; + std::unique_ptr Ranges; // Vector of elements (types, scopes and symbols). // It is the union of (*Types, *Symbols and *Scopes) to be used for @@ -129,7 +129,7 @@ class LVScope : public LVElement { // - Preserve the order the logical elements are read in. // - To have a single container with all the logical elements, when // the traversal does not require any specific element kind. - LVElements *Children = nullptr; + std::unique_ptr Children; // Resolve the template parameters/arguments relationship. void resolveTemplate(); @@ -150,7 +150,7 @@ class LVScope : public LVElement { } LVScope(const LVScope &) = delete; LVScope &operator=(const LVScope &) = delete; - virtual ~LVScope(); + virtual ~LVScope() = default; static bool classof(const LVElement *Element) { return Element->getSubclassID() == LVSubclassID::LV_SCOPE; @@ -202,12 +202,12 @@ class LVScope : public LVElement { const char *kind() const override; // Get the specific children. - const LVLines *getLines() const { return Lines; } - const LVLocations *getRanges() const { return Ranges; } - const LVScopes *getScopes() const { return Scopes; } - const LVSymbols *getSymbols() const { return Symbols; } - const LVTypes *getTypes() const { return Types; } - const LVElements *getChildren() const { return Children; } + const LVLines *getLines() const { return Lines.get(); } + const LVLocations *getRanges() const { return Ranges.get(); } + const LVScopes *getScopes() const { return Scopes.get(); } + const LVSymbols *getSymbols() const { return Symbols.get(); } + const LVTypes *getTypes() const { return Types.get(); } + const LVElements *getChildren() const { return Children.get(); } void addElement(LVElement *Element); void addElement(LVLine *Line); @@ -456,8 +456,8 @@ class LVScopeCompileUnit final : public LVScope { LVOffsetLocationsMap *Map) { LVOffset Offset = Element->getOffset(); addInvalidOffset(Offset, Element); - addItem( - Map, Offset, Location); + addItem(Map, Offset, + Location); } // Record scope sizes indexed by lexical level. @@ -489,12 +489,7 @@ class LVScopeCompileUnit final : public LVScope { } LVScopeCompileUnit(const LVScopeCompileUnit &) = delete; LVScopeCompileUnit &operator=(const LVScopeCompileUnit &) = delete; - ~LVScopeCompileUnit() { - deleteList(DebugTags); - deleteList(InvalidLocations); - deleteList(InvalidRanges); - deleteList(LinesZero); - } + ~LVScopeCompileUnit() = default; LVScope *getCompileUnitParent() const override { return static_cast(const_cast(this)); diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h index a2274ec1a62f7..d65ac641afbe5 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h @@ -31,25 +31,6 @@ namespace logicalview { // Returns the unique string pool instance. LVStringPool &getStringPool(); -template -using TypeIsValid = std::bool_constant::value>; - -// Utility class to help memory management and perform an automatic cleaning. -template -class LVAutoSmallVector : public SmallVector { - static_assert(TypeIsValid::value, "T must be a pointer type"); - -public: - using iterator = typename SmallVector::iterator; - LVAutoSmallVector() : SmallVector::SmallVector() {} - - ~LVAutoSmallVector() { - // Destroy the constructed elements in the vector. - for (auto *Item : *this) - delete Item; - } -}; - // Used to record specific characteristics about the objects. template class LVProperties { SmallBitVector Bits = SmallBitVector(static_cast(T::LastEntry) + 1); @@ -147,25 +128,10 @@ std::string formatAttributes(const StringRef First, Args... Others) { return Stream.str(); } -// Add an item to a map with second being a list. -template +// Add an item to a map with second being a small vector. +template void addItem(MapType *Map, KeyType Key, ValueType Value) { - ListType *List = nullptr; - typename MapType::const_iterator Iter = Map->find(Key); - if (Iter != Map->end()) - List = Iter->second; - else { - List = new ListType(); - Map->emplace(Key, List); - } - List->push_back(Value); -} - -// Delete the map contained list. -template void deleteList(MapType &Map) { - for (typename MapType::const_reference Entry : Map) - delete Entry.second; + (*Map)[Key].push_back(Value); } // Double map data structure. @@ -174,33 +140,26 @@ class LVDoubleMap { static_assert(std::is_pointer::value, "ValueType must be a pointer."); using LVSecondMapType = std::map; - using LVFirstMapType = std::map; + using LVFirstMapType = + std::map>; using LVAuxMapType = std::map; using LVValueTypes = std::vector; LVFirstMapType FirstMap; LVAuxMapType AuxMap; public: - LVDoubleMap() = default; - ~LVDoubleMap() { - for (auto &Entry : FirstMap) - delete Entry.second; - } - void add(FirstKeyType FirstKey, SecondKeyType SecondKey, ValueType Value) { - LVSecondMapType *SecondMap = nullptr; typename LVFirstMapType::iterator FirstIter = FirstMap.find(FirstKey); if (FirstIter == FirstMap.end()) { - SecondMap = new LVSecondMapType(); - FirstMap.emplace(FirstKey, SecondMap); + auto SecondMapSP = std::make_unique(); + SecondMapSP->emplace(SecondKey, Value); + FirstMap.emplace(FirstKey, std::move(SecondMapSP)); } else { - SecondMap = FirstIter->second; + LVSecondMapType *SecondMap = FirstIter->second.get(); + if (SecondMap->find(SecondKey) == SecondMap->end()) + SecondMap->emplace(SecondKey, Value); } - assert(SecondMap && "SecondMap is null."); - if (SecondMap && SecondMap->find(SecondKey) == SecondMap->end()) - SecondMap->emplace(SecondKey, Value); - typename LVAuxMapType::iterator AuxIter = AuxMap.find(SecondKey); if (AuxIter == AuxMap.end()) { AuxMap.emplace(SecondKey, FirstKey); @@ -212,8 +171,7 @@ class LVDoubleMap { if (FirstIter == FirstMap.end()) return nullptr; - LVSecondMapType *SecondMap = FirstIter->second; - return SecondMap; + return FirstIter->second.get(); } ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const { @@ -239,8 +197,8 @@ class LVDoubleMap { if (FirstMap.empty()) return Values; for (typename LVFirstMapType::const_reference FirstEntry : FirstMap) { - LVSecondMapType *SecondMap = FirstEntry.second; - for (typename LVSecondMapType::const_reference SecondEntry : *SecondMap) + LVSecondMapType &SecondMap = *FirstEntry.second; + for (typename LVSecondMapType::const_reference SecondEntry : SecondMap) Values.push_back(SecondEntry.second); } return Values; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h index b9628e3127849..4b2a910c88f1c 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h @@ -46,7 +46,7 @@ class LVSymbol final : public LVElement { // Reference to DW_AT_specification, DW_AT_abstract_origin attribute. LVSymbol *Reference = nullptr; - LVAutoLocations *Locations = nullptr; + std::unique_ptr Locations; LVLocation *CurrentLocation = nullptr; // Bitfields length. @@ -60,8 +60,8 @@ class LVSymbol final : public LVElement { float CoveragePercentage = 0; // Add a location gap into the location list. - LVAutoLocations::iterator addLocationGap(LVAutoLocations::iterator Pos, - LVAddress LowPC, LVAddress HighPC); + LVLocations::iterator addLocationGap(LVLocations::iterator Pos, + LVAddress LowPC, LVAddress HighPC); // Find the current symbol in the given 'Targets'. LVSymbol *findIn(const LVSymbols *Targets) const; @@ -73,7 +73,7 @@ class LVSymbol final : public LVElement { } LVSymbol(const LVSymbol &) = delete; LVSymbol &operator=(const LVSymbol &) = delete; - ~LVSymbol() { delete Locations; } + ~LVSymbol() = default; static bool classof(const LVElement *Element) { return Element->getSubclassID() == LVSubclassID::LV_SYMBOL; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h b/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h index 3030e9f24ed82..9f5e80747bf5e 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h @@ -27,7 +27,7 @@ namespace llvm { namespace logicalview { -using LVReaders = std::vector; +using LVReaders = std::vector>; using ArgVector = std::vector; using PdbOrObj = PointerUnion; @@ -45,7 +45,6 @@ class LVReaderHandler { LVReaders TheReaders; Error createReaders(); - void destroyReaders(); Error printReaders(); Error compareReaders(); @@ -72,20 +71,18 @@ class LVReaderHandler { } LVReaderHandler(const LVReaderHandler &) = delete; LVReaderHandler &operator=(const LVReaderHandler &) = delete; - ~LVReaderHandler() { destroyReaders(); } Error createReader(StringRef Filename, LVReaders &Readers) { return handleFile(Readers, Filename); } Error process(); - Expected createReader(StringRef Pathname) { + Expected> createReader(StringRef Pathname) { LVReaders Readers; if (Error Err = createReader(Pathname, Readers)) return std::move(Err); - return Readers[0]; + return std::move(Readers[0]); } - void deleteReader(LVReader *Reader) { delete Reader; } void print(raw_ostream &OS) const; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h index 8c3cce9286a33..4b2dc666733ee 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h @@ -89,7 +89,7 @@ class LVBinaryReader : public LVReader { // Scopes with ranges for current compile unit. It is used to find a line // giving its exact or closest address. To support comdat functions, all // addresses for the same section are recorded in the same map. - using LVSectionRanges = std::map; + using LVSectionRanges = std::map>; LVSectionRanges SectionRanges; // Image base and virtual address for Executable file. @@ -100,6 +100,8 @@ class LVBinaryReader : public LVReader { using LVSections = std::map; LVSections Sections; + std::vector> DiscoveredLines; + protected: // It contains the LVLineDebug elements representing the logical lines for // the current compile unit, created by parsing the debug line section. @@ -149,7 +151,7 @@ class LVBinaryReader : public LVReader { : LVReader(Filename, FileFormatName, W, BinaryType) {} LVBinaryReader(const LVBinaryReader &) = delete; LVBinaryReader &operator=(const LVBinaryReader &) = delete; - virtual ~LVBinaryReader(); + virtual ~LVBinaryReader() = default; void addToSymbolTable(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex = 0); diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp index 115b903c6c7f9..e11e56cd59760 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp @@ -579,8 +579,8 @@ void LVLocationSymbol::addObject(LVAddress LowPC, LVAddress HighPC, void LVLocationSymbol::addObject(LVSmall Opcode, LVUnsigned Operand1, LVUnsigned Operand2) { if (!Entries) - Entries = new LVAutoOperations(); - Entries->emplace_back(new LVOperation(Opcode, Operand1, Operand2)); + Entries = std::make_unique(); + Entries->push_back(getReader().createOperation(Opcode, Operand1, Operand2)); } // Based on the DWARF attribute, define the location kind. @@ -606,8 +606,7 @@ void LVLocation::setKind() { void LVLocationSymbol::updateKind() { // Update the location type for simple ones. if (Entries && Entries->size() == 1) { - LVOperation *Operation = Entries->front(); - if (dwarf::DW_OP_fbreg == Operation->getOpcode()) + if (dwarf::DW_OP_fbreg == Entries->front()->getOpcode()) setIsStackOffset(); } } diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp index fb503f3d3e7e2..2fc97ccb6690b 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp @@ -45,15 +45,6 @@ const char *const KindUnion = "Union"; //===----------------------------------------------------------------------===// // DWARF lexical block, such as: namespace, function, compile unit, module, etc. //===----------------------------------------------------------------------===// -LVScope::~LVScope() { - delete Types; - delete Symbols; - delete Scopes; - delete Lines; - delete Ranges; - delete Children; -} - // Return a string representation for the scope kind. const char *LVScope::kind() const { const char *Kind = KindUndefined; @@ -114,7 +105,7 @@ LVScopeDispatch LVScope::Dispatch = { void LVScope::addToChildren(LVElement *Element) { if (!Children) - Children = new LVElements(); + Children = std::make_unique(); Children->push_back(Element); } @@ -137,7 +128,7 @@ void LVScope::addElement(LVLine *Line) { assert(Line && "Invalid line."); assert(!Line->getParent() && "Line already inserted"); if (!Lines) - Lines = new LVAutoLines(); + Lines = std::make_unique(); // Add it to parent. Lines->push_back(Line); @@ -161,7 +152,7 @@ void LVScope::addObject(LVLocation *Location) { assert(Location && "Invalid location."); assert(!Location->getParent() && "Location already inserted"); if (!Ranges) - Ranges = new LVAutoLocations(); + Ranges = std::make_unique(); // Add it to parent. Location->setParent(this); @@ -176,7 +167,7 @@ void LVScope::addElement(LVScope *Scope) { assert(Scope && "Invalid scope."); assert(!Scope->getParent() && "Scope already inserted"); if (!Scopes) - Scopes = new LVAutoScopes(); + Scopes = std::make_unique(); // Add it to parent. Scopes->push_back(Scope); @@ -203,7 +194,7 @@ void LVScope::addElement(LVSymbol *Symbol) { assert(Symbol && "Invalid symbol."); assert(!Symbol->getParent() && "Symbol already inserted"); if (!Symbols) - Symbols = new LVAutoSymbols(); + Symbols = std::make_unique(); // Add it to parent. Symbols->push_back(Symbol); @@ -230,7 +221,7 @@ void LVScope::addElement(LVType *Type) { assert(Type && "Invalid type."); assert(!Type->getParent() && "Type already inserted"); if (!Types) - Types = new LVAutoTypes(); + Types = std::make_unique(); // Add it to parent. Types->push_back(Type); @@ -255,7 +246,7 @@ void LVScope::addElement(LVType *Type) { // Add a pair of ranges. void LVScope::addObject(LVAddress LowerAddress, LVAddress UpperAddress) { // Pack the ranges into a Location object. - LVLocation *Location = new LVLocation(); + LVLocation *Location = getReader().createLocation(); Location->setLowerAddress(LowerAddress); Location->setUpperAddress(UpperAddress); Location->setIsAddressRange(); @@ -341,7 +332,7 @@ void LVScope::addMissingElements(LVScope *Reference) { // information that is incorrect for the element to be inserted. // As the symbol being added does not exist in the debug section, // use its parent scope offset, to indicate its DIE location. - LVSymbol *Symbol = new LVSymbol(); + LVSymbol *Symbol = getReader().createSymbol(); addElement(Symbol); Symbol->setOffset(getOffset()); Symbol->setIsOptimized(); @@ -690,7 +681,7 @@ void LVScope::sort() { if (SortFunction) { std::function Sort = [&](LVScope *Parent, LVSortFunction SortFunction) { - auto Traverse = [&](auto *Set, LVSortFunction SortFunction) { + auto Traverse = [&](auto &Set, LVSortFunction SortFunction) { if (Set) std::stable_sort(Set->begin(), Set->end(), SortFunction); }; @@ -877,7 +868,7 @@ bool LVScope::equalNumberOfChildren(const LVScope *Scope) const { } void LVScope::markMissingParents(const LVScope *Target, bool TraverseChildren) { - auto SetCompareState = [&](auto *Container) { + auto SetCompareState = [&](auto &Container) { if (Container) for (auto *Entry : *Container) Entry->setIsInCompare(); @@ -1356,8 +1347,7 @@ void LVScopeCompileUnit::addedElement(LVType *Type) { // Record unsuported DWARF tags. void LVScopeCompileUnit::addDebugTag(dwarf::Tag Target, LVOffset Offset) { - addItem(&DebugTags, - Target, Offset); + addItem(&DebugTags, Target, Offset); } // Record elements with invalid offsets. @@ -1390,8 +1380,7 @@ void LVScopeCompileUnit::addLineZero(LVLine *Line) { LVScope *Scope = Line->getParentScope(); LVOffset Offset = Scope->getOffset(); addInvalidOffset(Offset, Scope); - addItem(&LinesZero, Offset, - Line); + addItem(&LinesZero, Offset, Line); } void LVScopeCompileUnit::printLocalNames(raw_ostream &OS, bool Full) const { @@ -1481,7 +1470,7 @@ void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const { PrintHeader(Header); for (LVOffsetLocationsMap::const_reference Entry : Map) { PrintElement(WarningOffsets, Entry.first); - for (const LVLocation *Location : *Entry.second) + for (const LVLocation *Location : Entry.second) OS << hexSquareString(Location->getOffset()) << " " << Location->getIntervalInfo() << "\n"; } @@ -1494,7 +1483,7 @@ void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const { OS << format("\n0x%02x", (unsigned)Entry.first) << ", " << dwarf::TagString(Entry.first) << "\n"; unsigned Count = 0; - for (const LVOffset &Offset : *Entry.second) + for (const LVOffset &Offset : Entry.second) PrintOffset(Count, Offset); OS << "\n"; } @@ -1519,7 +1508,7 @@ void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const { for (LVOffsetLinesMap::const_reference Entry : LinesZero) { PrintElement(WarningOffsets, Entry.first); unsigned Count = 0; - for (const LVLine *Line : *Entry.second) + for (const LVLine *Line : Entry.second) PrintOffset(Count, Line->getOffset()); OS << "\n"; } diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp index 82633fbc6b2e8..7e86a2f4c1b8a 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp @@ -66,10 +66,10 @@ void LVSymbol::addLocation(dwarf::Attribute Attr, LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset, uint64_t LocDescOffset, bool CallSiteLocation) { if (!Locations) - Locations = new LVAutoLocations(); + Locations = std::make_unique(); // Create the location entry. - CurrentLocation = new LVLocationSymbol(); + CurrentLocation = getReader().createLocationSymbol(); CurrentLocation->setParent(this); CurrentLocation->setAttr(Attr); if (CallSiteLocation) @@ -105,7 +105,7 @@ LVLocations::iterator LVSymbol::addLocationGap(LVLocations::iterator Pos, LVAddress LowPC, LVAddress HighPC) { // Create a location entry for the gap. - LVLocation *Gap = new LVLocationSymbol(); + LVLocation *Gap = getReader().createLocationSymbol(); Gap->setParent(this); Gap->setAttr(dwarf::DW_AT_location); Gap->addObject(LowPC, HighPC, @@ -190,7 +190,7 @@ void LVSymbol::getLocations(LVLocations &LocationList) const { // Calculate coverage factor. void LVSymbol::calculateCoverage() { - if (!LVLocation::calculateCoverage(Locations, CoverageFactor, + if (!LVLocation::calculateCoverage(Locations.get(), CoverageFactor, CoveragePercentage)) { LVScope *Parent = getParentScope(); if (Parent->getIsInlinedFunction()) { @@ -444,6 +444,6 @@ void LVSymbol::printExtra(raw_ostream &OS, bool Full) const { Reference->printReference(OS, Full, const_cast(this)); // Print location information. - LVLocation::print(Locations, OS, Full); + LVLocation::print(Locations.get(), OS, Full); } } diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp index 3d32c34ee02a3..de71e0904dbbc 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp @@ -253,16 +253,10 @@ void LVType::getParameters(const LVTypes *Types, LVTypes *TypesParam, if (!Type->getIsTemplateParam()) continue; if (options().getAttributeArgument()) { - LVScope *Scope = nullptr; if (Type->getIsKindType()) - Type = Type->getTypeAsType(); - else { - if (Type->getIsKindScope()) { - Scope = Type->getTypeAsScope(); - Type = nullptr; - } - } - Type ? TypesParam->push_back(Type) : ScopesParam->push_back(Scope); + TypesParam->push_back(Type->getTypeAsType()); + else if (Type->getIsKindScope()) + ScopesParam->push_back(Type->getTypeAsScope()); } else TypesParam->push_back(Type); } diff --git a/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp b/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp index 35dc30fd601fc..65633f2495f42 100644 --- a/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp +++ b/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp @@ -32,31 +32,26 @@ Error LVReaderHandler::process() { return Error::success(); } -void LVReaderHandler::destroyReaders() { - LLVM_DEBUG(dbgs() << "destroyReaders\n"); - for (const LVReader *Reader : TheReaders) - delete Reader; -} - Error LVReaderHandler::createReader(StringRef Filename, LVReaders &Readers, PdbOrObj &Input, StringRef FileFormatName, StringRef ExePath) { - auto CreateOneReader = [&]() -> LVReader * { + auto CreateOneReader = [&]() -> std::unique_ptr { if (Input.is()) { ObjectFile &Obj = *Input.get(); if (Obj.isELF() || Obj.isMachO()) - return new LVELFReader(Filename, FileFormatName, Obj, W); + return std::make_unique(Filename, FileFormatName, Obj, W); } return nullptr; }; - LVReader *Reader = CreateOneReader(); - if (!Reader) + std::unique_ptr ReaderObj = CreateOneReader(); + if (!ReaderObj) return createStringError(errc::invalid_argument, "unable to create reader for: '%s'", Filename.str().c_str()); - Readers.push_back(Reader); + LVReader *Reader = ReaderObj.get(); + Readers.emplace_back(std::move(ReaderObj)); return Reader->doLoad(); } @@ -158,7 +153,9 @@ Error LVReaderHandler::createReaders() { LVReaders Readers; if (Error Err = createReader(Object, Readers)) return Err; - TheReaders.insert(TheReaders.end(), Readers.begin(), Readers.end()); + TheReaders.insert(TheReaders.end(), + std::make_move_iterator(Readers.begin()), + std::make_move_iterator(Readers.end())); } return Error::success(); @@ -167,7 +164,7 @@ Error LVReaderHandler::createReaders() { Error LVReaderHandler::printReaders() { LLVM_DEBUG(dbgs() << "printReaders\n"); if (options().getPrintExecute()) - for (LVReader *Reader : TheReaders) + for (const std::unique_ptr &Reader : TheReaders) if (Error Err = Reader->doPrint()) return Err; @@ -182,7 +179,8 @@ Error LVReaderHandler::compareReaders() { size_t ViewPairs = ReadersCount / 2; LVCompare Compare(OS); for (size_t Pair = 0, Index = 0; Pair < ViewPairs; ++Pair) { - if (Error Err = Compare.execute(TheReaders[Index], TheReaders[Index + 1])) + if (Error Err = Compare.execute(TheReaders[Index].get(), + TheReaders[Index + 1].get())) return Err; Index += 2; } diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp index b654c624f57c0..1fb5c4a9d9105 100644 --- a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp @@ -297,29 +297,16 @@ void LVBinaryReader::addSectionRange(LVSectionIndex SectionIndex, } LVRange *LVBinaryReader::getSectionRanges(LVSectionIndex SectionIndex) { - LVRange *Range = nullptr; // Check if we already have a mapping for this section index. LVSectionRanges::iterator IterSection = SectionRanges.find(SectionIndex); - if (IterSection == SectionRanges.end()) { - Range = new LVRange(); - SectionRanges.emplace(SectionIndex, Range); - } else { - Range = IterSection->second; - } + if (IterSection == SectionRanges.end()) + IterSection = + SectionRanges.emplace(SectionIndex, std::make_unique()).first; + LVRange *Range = IterSection->second.get(); assert(Range && "Range is null."); return Range; } -LVBinaryReader::~LVBinaryReader() { - // Delete the lines created by 'createInstructions'. - std::vector AllInstructionLines = ScopeInstructions.find(); - for (LVLines *Entry : AllInstructionLines) - delete Entry; - // Delete the ranges created by 'getSectionRanges'. - for (LVSectionRanges::reference Entry : SectionRanges) - delete Entry.second; -} - Error LVBinaryReader::createInstructions(LVScope *Scope, LVSectionIndex SectionIndex, const LVNameInfo &NameInfo) { @@ -380,7 +367,9 @@ Error LVBinaryReader::createInstructions(LVScope *Scope, // Address for first instruction line. LVAddress FirstAddress = Address; - LVLines *Instructions = new LVLines(); + auto InstructionsSP = std::make_unique(); + LVLines &Instructions = *InstructionsSP; + DiscoveredLines.emplace_back(std::move(InstructionsSP)); while (Begin < End) { MCInst Instruction; @@ -422,10 +411,10 @@ Error LVBinaryReader::createInstructions(LVScope *Scope, // the 'processLines()' function will move each created logical line // to its enclosing logical scope, using the debug ranges information // and they will be released when its scope parent is deleted. - LVLineAssembler *Line = new LVLineAssembler(); + LVLineAssembler *Line = createLineAssembler(); Line->setAddress(Address); Line->setName(StringRef(Stream.str()).trim()); - Instructions->push_back(Line); + Instructions.push_back(Line); break; } } @@ -439,15 +428,15 @@ Error LVBinaryReader::createInstructions(LVScope *Scope, << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n" << "Address: " << hexValue(FirstAddress) << format(" - Collected instructions lines: %d\n", - Instructions->size()); - for (const LVLine *Line : *Instructions) + Instructions.size()); + for (const LVLine *Line : Instructions) dbgs() << format_decimal(++Index, 5) << ": " << hexValue(Line->getOffset()) << ", (" << Line->getName() << ")\n"; }); // The scope in the assembler names is linked to its own instructions. - ScopeInstructions.add(SectionIndex, Scope, Instructions); + ScopeInstructions.add(SectionIndex, Scope, &Instructions); AssemblerMappings.add(SectionIndex, FirstAddress, Scope); return Error::success(); diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp index 7746bc508b41a..882660348bd09 100644 --- a/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp @@ -57,182 +57,182 @@ LVElement *LVELFReader::createElement(dwarf::Tag Tag) { switch (Tag) { // Types. case dwarf::DW_TAG_base_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsBase(); if (options().getAttributeBase()) CurrentType->setIncludeInPrint(); return CurrentType; case dwarf::DW_TAG_const_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsConst(); CurrentType->setName("const"); return CurrentType; case dwarf::DW_TAG_enumerator: - CurrentType = new LVTypeEnumerator(); + CurrentType = createTypeEnumerator(); return CurrentType; case dwarf::DW_TAG_imported_declaration: - CurrentType = new LVTypeImport(); + CurrentType = createTypeImport(); CurrentType->setIsImportDeclaration(); return CurrentType; case dwarf::DW_TAG_imported_module: - CurrentType = new LVTypeImport(); + CurrentType = createTypeImport(); CurrentType->setIsImportModule(); return CurrentType; case dwarf::DW_TAG_pointer_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsPointer(); CurrentType->setName("*"); return CurrentType; case dwarf::DW_TAG_ptr_to_member_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsPointerMember(); CurrentType->setName("*"); return CurrentType; case dwarf::DW_TAG_reference_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsReference(); CurrentType->setName("&"); return CurrentType; case dwarf::DW_TAG_restrict_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsRestrict(); CurrentType->setName("restrict"); return CurrentType; case dwarf::DW_TAG_rvalue_reference_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsRvalueReference(); CurrentType->setName("&&"); return CurrentType; case dwarf::DW_TAG_subrange_type: - CurrentType = new LVTypeSubrange(); + CurrentType = createTypeSubrange(); return CurrentType; case dwarf::DW_TAG_template_value_parameter: - CurrentType = new LVTypeParam(); + CurrentType = createTypeParam(); CurrentType->setIsTemplateValueParam(); return CurrentType; case dwarf::DW_TAG_template_type_parameter: - CurrentType = new LVTypeParam(); + CurrentType = createTypeParam(); CurrentType->setIsTemplateTypeParam(); return CurrentType; case dwarf::DW_TAG_GNU_template_template_param: - CurrentType = new LVTypeParam(); + CurrentType = createTypeParam(); CurrentType->setIsTemplateTemplateParam(); return CurrentType; case dwarf::DW_TAG_typedef: - CurrentType = new LVTypeDefinition(); + CurrentType = createTypeDefinition(); return CurrentType; case dwarf::DW_TAG_unspecified_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsUnspecified(); return CurrentType; case dwarf::DW_TAG_volatile_type: - CurrentType = new LVType(); + CurrentType = createType(); CurrentType->setIsVolatile(); CurrentType->setName("volatile"); return CurrentType; // Symbols. case dwarf::DW_TAG_formal_parameter: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createSymbol(); CurrentSymbol->setIsParameter(); return CurrentSymbol; case dwarf::DW_TAG_unspecified_parameters: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createSymbol(); CurrentSymbol->setIsUnspecified(); CurrentSymbol->setName("..."); return CurrentSymbol; case dwarf::DW_TAG_member: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createSymbol(); CurrentSymbol->setIsMember(); return CurrentSymbol; case dwarf::DW_TAG_variable: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createSymbol(); CurrentSymbol->setIsVariable(); return CurrentSymbol; case dwarf::DW_TAG_inheritance: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createSymbol(); CurrentSymbol->setIsInheritance(); return CurrentSymbol; case dwarf::DW_TAG_call_site_parameter: case dwarf::DW_TAG_GNU_call_site_parameter: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createSymbol(); CurrentSymbol->setIsCallSiteParameter(); return CurrentSymbol; case dwarf::DW_TAG_constant: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createSymbol(); CurrentSymbol->setIsConstant(); return CurrentSymbol; // Scopes. case dwarf::DW_TAG_catch_block: - CurrentScope = new LVScope(); + CurrentScope = createScope(); CurrentScope->setIsCatchBlock(); return CurrentScope; case dwarf::DW_TAG_lexical_block: - CurrentScope = new LVScope(); + CurrentScope = createScope(); CurrentScope->setIsLexicalBlock(); return CurrentScope; case dwarf::DW_TAG_try_block: - CurrentScope = new LVScope(); + CurrentScope = createScope(); CurrentScope->setIsTryBlock(); return CurrentScope; case dwarf::DW_TAG_compile_unit: case dwarf::DW_TAG_skeleton_unit: - CurrentScope = new LVScopeCompileUnit(); + CurrentScope = createScopeCompileUnit(); CompileUnit = static_cast(CurrentScope); return CurrentScope; case dwarf::DW_TAG_inlined_subroutine: - CurrentScope = new LVScopeFunctionInlined(); + CurrentScope = createScopeFunctionInlined(); return CurrentScope; case dwarf::DW_TAG_namespace: - CurrentScope = new LVScopeNamespace(); + CurrentScope = createScopeNamespace(); return CurrentScope; case dwarf::DW_TAG_template_alias: - CurrentScope = new LVScopeAlias(); + CurrentScope = createScopeAlias(); return CurrentScope; case dwarf::DW_TAG_array_type: - CurrentScope = new LVScopeArray(); + CurrentScope = createScopeArray(); return CurrentScope; case dwarf::DW_TAG_call_site: case dwarf::DW_TAG_GNU_call_site: - CurrentScope = new LVScopeFunction(); + CurrentScope = createScopeFunction(); CurrentScope->setIsCallSite(); return CurrentScope; case dwarf::DW_TAG_entry_point: - CurrentScope = new LVScopeFunction(); + CurrentScope = createScopeFunction(); CurrentScope->setIsEntryPoint(); return CurrentScope; case dwarf::DW_TAG_subprogram: - CurrentScope = new LVScopeFunction(); + CurrentScope = createScopeFunction(); CurrentScope->setIsSubprogram(); return CurrentScope; case dwarf::DW_TAG_subroutine_type: - CurrentScope = new LVScopeFunctionType(); + CurrentScope = createScopeFunctionType(); return CurrentScope; case dwarf::DW_TAG_label: - CurrentScope = new LVScopeFunction(); + CurrentScope = createScopeFunction(); CurrentScope->setIsLabel(); return CurrentScope; case dwarf::DW_TAG_class_type: - CurrentScope = new LVScopeAggregate(); + CurrentScope = createScopeAggregate(); CurrentScope->setIsClass(); return CurrentScope; case dwarf::DW_TAG_structure_type: - CurrentScope = new LVScopeAggregate(); + CurrentScope = createScopeAggregate(); CurrentScope->setIsStructure(); return CurrentScope; case dwarf::DW_TAG_union_type: - CurrentScope = new LVScopeAggregate(); + CurrentScope = createScopeAggregate(); CurrentScope->setIsUnion(); return CurrentScope; case dwarf::DW_TAG_enumeration_type: - CurrentScope = new LVScopeEnumeration(); + CurrentScope = createScopeEnumeration(); return CurrentScope; case dwarf::DW_TAG_GNU_formal_parameter_pack: - CurrentScope = new LVScopeFormalPack(); + CurrentScope = createScopeFormalPack(); return CurrentScope; case dwarf::DW_TAG_GNU_template_parameter_pack: - CurrentScope = new LVScopeTemplatePack(); + CurrentScope = createScopeTemplatePack(); return CurrentScope; default: // Collect TAGs not implemented. @@ -733,7 +733,7 @@ void LVELFReader::createLineAndFileRecords( // the 'processLines()' function will move each created logical line // to its enclosing logical scope, using the debug ranges information // and they will be released when its scope parent is deleted. - LVLineDebug *Line = new LVLineDebug(); + LVLineDebug *Line = createLineDebug(); CULines.push_back(Line); Line->setAddress(Row.Address.Address); Line->setFilename( diff --git a/llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp b/llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp index 06da5ebbc995d..e9c1fbae4e0a7 100644 --- a/llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp +++ b/llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp @@ -26,9 +26,10 @@ namespace { //===----------------------------------------------------------------------===// // Basic Reader functionality. class ReaderTestCompare : public LVReader { - // Elements created but not added to any logical scope. They are - // deleted when the logical Reader is destroyed. - LVAutoSmallVector OrphanElements; +#define CREATE(VARIABLE, CREATE_FUNCTION, SET_FUNCTION) \ + VARIABLE = CREATE_FUNCTION(); \ + EXPECT_NE(VARIABLE, nullptr); \ + VARIABLE->SET_FUNCTION(); public: // Types. @@ -66,14 +67,6 @@ class ReaderTestCompare : public LVReader { protected: void add(LVScope *Parent, LVElement *Element); - template T *create(F Function) { - // 'Function' will update a specific kind of the logical element to - // have the ability of kind selection. - T *Element = new (std::nothrow) T(); - EXPECT_NE(Element, nullptr); - (Element->*Function)(); - return Element; - } void set(LVElement *Element, StringRef Name, LVOffset Offset, uint32_t LineNumber = 0, LVElement *Type = nullptr); @@ -116,54 +109,38 @@ void ReaderTestCompare::createElements() { ASSERT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(&LVType::setIsBase); - UnsignedType = create(&LVType::setIsBase); - GlobalType = create(&LVType::setIsBase); - LocalType = create(&LVType::setIsBase); - NestedType = create(&LVType::setIsBase); - EnumeratorOne = - create(&LVType::setIsEnumerator); - EnumeratorTwo = - create(&LVType::setIsEnumerator); - TypeDefinitionOne = - create(&LVType::setIsTypedef); - TypeDefinitionTwo = - create(&LVType::setIsTypedef); + CREATE(IntegerType, createType, setIsBase); + CREATE(UnsignedType, createType, setIsBase); + CREATE(GlobalType, createType, setIsBase); + CREATE(LocalType, createType, setIsBase); + CREATE(NestedType, createType, setIsBase); + CREATE(EnumeratorOne, createTypeEnumerator, setIsEnumerator); + CREATE(EnumeratorTwo, createTypeEnumerator, setIsEnumerator); + CREATE(TypeDefinitionOne, createTypeDefinition, setIsTypedef); + CREATE(TypeDefinitionTwo, createTypeDefinition, setIsTypedef); // Create the logical scopes. - NestedScope = - create(&LVScope::setIsLexicalBlock); - InnerScope = create(&LVScope::setIsLexicalBlock); - Aggregate = - create(&LVScope::setIsAggregate); - CompileUnit = create( - &LVScope::setIsCompileUnit); - Enumeration = create( - &LVScope::setIsEnumeration); - FunctionOne = - create(&LVScope::setIsFunction); - FunctionTwo = - create(&LVScope::setIsFunction); - Namespace = - create(&LVScope::setIsNamespace); + CREATE(NestedScope, createScope, setIsLexicalBlock); + CREATE(InnerScope, createScope, setIsLexicalBlock); + CREATE(Aggregate, createScopeAggregate, setIsAggregate); + CREATE(CompileUnit, createScopeCompileUnit, setIsCompileUnit); + CREATE(Enumeration, createScopeEnumeration, setIsEnumeration); + CREATE(FunctionOne, createScopeFunction, setIsFunction); + CREATE(FunctionTwo, createScopeFunction, setIsFunction); + CREATE(Namespace, createScopeNamespace, setIsNamespace); // Create the logical symbols. - GlobalVariable = - create(&LVSymbol::setIsVariable); - LocalVariable = - create(&LVSymbol::setIsVariable); - ClassMember = create(&LVSymbol::setIsMember); - NestedVariable = - create(&LVSymbol::setIsVariable); - ParameterOne = - create(&LVSymbol::setIsParameter); - ParameterTwo = - create(&LVSymbol::setIsParameter); + CREATE(GlobalVariable, createSymbol, setIsVariable); + CREATE(LocalVariable, createSymbol, setIsVariable); + CREATE(ClassMember, createSymbol, setIsMember); + CREATE(NestedVariable, createSymbol, setIsVariable); + CREATE(ParameterOne, createSymbol, setIsParameter); + CREATE(ParameterTwo, createSymbol, setIsParameter); // Create the logical lines. - LineOne = create(&LVLine::setIsLineDebug); - LineTwo = create(&LVLine::setIsLineDebug); - LineThree = create(&LVLine::setIsLineDebug); + CREATE(LineOne, createLine, setIsLineDebug); + CREATE(LineTwo, createLine, setIsLineDebug); + CREATE(LineThree, createLine, setIsLineDebug); } // Reference Reader: Target Reader: @@ -203,8 +180,6 @@ void ReaderTestCompare::addElements(bool IsReference, bool IsTarget) { auto Insert = [&](bool Insert, auto *Parent, auto *Child) { if (Insert) add(Parent, Child); - else - OrphanElements.push_back(Child); }; setCompileUnit(CompileUnit); diff --git a/llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp index 8af3050a4273f..f6db28afef20f 100644 --- a/llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp +++ b/llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp @@ -47,15 +47,16 @@ LVScopeCompileUnit *getFirstCompileUnit(LVScopeRoot *Root) { } // Helper function to create a reader. -LVReader *createReader(LVReaderHandler &ReaderHandler, - SmallString<128> &InputsDir, StringRef Filename) { +std::unique_ptr createReader(LVReaderHandler &ReaderHandler, + SmallString<128> &InputsDir, + StringRef Filename) { SmallString<128> ObjectName(InputsDir); llvm::sys::path::append(ObjectName, Filename); - Expected ReaderOrErr = + Expected> ReaderOrErr = ReaderHandler.createReader(std::string(ObjectName)); EXPECT_THAT_EXPECTED(ReaderOrErr, Succeeded()); - LVReader *Reader = *ReaderOrErr; + std::unique_ptr Reader = std::move(*ReaderOrErr); EXPECT_NE(Reader, nullptr); return Reader; } @@ -260,9 +261,9 @@ void elementProperties(SmallString<128> &InputsDir) { LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); // Check logical elements properties. - LVReader *Reader = createReader(ReaderHandler, InputsDir, DwarfClang); - checkElementProperties(Reader); - ReaderHandler.deleteReader(Reader); + std::unique_ptr Reader = + createReader(ReaderHandler, InputsDir, DwarfClang); + checkElementProperties(Reader.get()); } // Logical elements selection. @@ -291,9 +292,9 @@ void elementSelection(SmallString<128> &InputsDir) { LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); // Check logical elements selection. - LVReader *Reader = createReader(ReaderHandler, InputsDir, DwarfGcc); - checkElementSelection(Reader); - ReaderHandler.deleteReader(Reader); + std::unique_ptr Reader = + createReader(ReaderHandler, InputsDir, DwarfGcc); + checkElementSelection(Reader.get()); } // Compare logical elements. @@ -315,11 +316,11 @@ void compareElements(SmallString<128> &InputsDir) { LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); // Check logical comparison. - LVReader *Reference = createReader(ReaderHandler, InputsDir, DwarfClang); - LVReader *Target = createReader(ReaderHandler, InputsDir, DwarfGcc); - checkElementComparison(Reference, Target); - ReaderHandler.deleteReader(Reference); - ReaderHandler.deleteReader(Target); + std::unique_ptr Reference = + createReader(ReaderHandler, InputsDir, DwarfClang); + std::unique_ptr Target = + createReader(ReaderHandler, InputsDir, DwarfGcc); + checkElementComparison(Reference.get(), Target.get()); } TEST(LogicalViewTest, ELFReader) { diff --git a/llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp b/llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp index 1163fabf84fb5..86949714afae4 100644 --- a/llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp +++ b/llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp @@ -24,17 +24,12 @@ namespace { class ReaderTest : public LVReader { protected: + void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine); void add(LVScope *Parent, LVElement *Element); - template T *create() { - T *Element = new (std::nothrow) T(); - EXPECT_NE(Element, nullptr); - return Element; - } void set(LVElement *Element, StringRef Name, LVOffset Offset, uint32_t LineNumber = 0, LVElement *Type = nullptr); void set(LVLocation *Location, LVLine *LowerLine, LVLine *UpperLine, LVAddress LowerAddress, LVAddress UpperAddress); - void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine); public: ReaderTest(ScopedPrinter &W) : LVReader("", "", W) { setInstance(this); } @@ -84,6 +79,10 @@ void ReaderTest::add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine) { } class ReaderTestLocations : public ReaderTest { +#define CREATE(VARIABLE, CREATE_FUNCTION) \ + VARIABLE = CREATE_FUNCTION(); \ + EXPECT_NE(VARIABLE, nullptr); + // Types. LVType *IntegerType = nullptr; @@ -129,33 +128,33 @@ void ReaderTestLocations::createElements() { EXPECT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(); + CREATE(IntegerType, createType); // Create the logical scopes. - NestedScope = create(); - CompileUnit = create(); - Function = create(); + CREATE(NestedScope, createScope); + CREATE(CompileUnit, createScopeCompileUnit); + CREATE(Function, createScopeFunction); // Create the logical symbols. - LocalVariable = create(); - NestedVariable = create(); - Parameter = create(); + CREATE(LocalVariable, createSymbol); + CREATE(NestedVariable, createSymbol); + CREATE(Parameter, createSymbol); // Create the logical lines. - LineOne = create(); - LineTwo = create(); - LineThree = create(); - LineFour = create(); - LineFive = create(); - LineSix = create(); + CREATE(LineOne, createLine); + CREATE(LineTwo, createLine); + CREATE(LineThree, createLine); + CREATE(LineFour, createLine); + CREATE(LineFive, createLine); + CREATE(LineSix, createLine); // Create the logical locations. - LocationOne = create(); - LocationTwo = create(); - LocationThree = create(); - LocationFour = create(); - LocationFive = create(); - LocationSix = create(); + CREATE(LocationOne, createLocation); + CREATE(LocationTwo, createLocation); + CREATE(LocationThree, createLocation); + CREATE(LocationFour, createLocation); + CREATE(LocationFive, createLocation); + CREATE(LocationSix, createLocation); } // Create the logical view adding the created logical elements. @@ -369,30 +368,46 @@ void ReaderTestCoverage::createElements() { EXPECT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(); + IntegerType = createType(); + EXPECT_NE(IntegerType, nullptr); // Create the logical scopes. - CompileUnit = create(); - Function = create(); - InlinedFunction = create(); + CompileUnit = createScopeCompileUnit(); + EXPECT_NE(CompileUnit, nullptr); + Function = createScopeFunction(); + EXPECT_NE(Function, nullptr); + InlinedFunction = createScopeFunctionInlined(); + EXPECT_NE(InlinedFunction, nullptr); // Create the logical symbols. - Variable = create(); - Parameter = create(); + Variable = createSymbol(); + EXPECT_NE(Variable, nullptr); + Parameter = createSymbol(); + EXPECT_NE(Parameter, nullptr); // Create the logical lines. - LineOne = create(); - LineTwo = create(); - LineThree = create(); - LineFour = create(); - LineFive = create(); - LineSix = create(); + LineOne = createLine(); + EXPECT_NE(LineOne, nullptr); + LineTwo = createLine(); + EXPECT_NE(LineTwo, nullptr); + LineThree = createLine(); + EXPECT_NE(LineThree, nullptr); + LineFour = createLine(); + EXPECT_NE(LineFour, nullptr); + LineFive = createLine(); + EXPECT_NE(LineFive, nullptr); + LineSix = createLine(); + EXPECT_NE(LineSix, nullptr); // Create the logical locations. - LocationOne = create(); - LocationTwo = create(); - LocationFive = create(); - LocationSix = create(); + LocationOne = createLocation(); + EXPECT_NE(LocationOne, nullptr); + LocationTwo = createLocation(); + EXPECT_NE(LocationTwo, nullptr); + LocationFive = createLocation(); + EXPECT_NE(LocationFive, nullptr); + LocationSix = createLocation(); + EXPECT_NE(LocationSix, nullptr); } // Create the logical view adding the created logical elements. diff --git a/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp b/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp index b19029fd1239a..8aa856ad30397 100644 --- a/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp +++ b/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp @@ -23,6 +23,10 @@ using namespace llvm::logicalview; namespace { class ReaderTestElements : public LVReader { +#define CREATE(VARIABLE, CREATE_FUNCTION) \ + VARIABLE = CREATE_FUNCTION(); \ + EXPECT_NE(VARIABLE, nullptr); + // Types. LVType *IntegerType = nullptr; LVType *UnsignedType = nullptr; @@ -60,11 +64,6 @@ class ReaderTestElements : public LVReader { protected: void add(LVScope *Parent, LVElement *Element); - template T *create() { - T *Element = new (std::nothrow) T(); - EXPECT_NE(Element, nullptr); - return Element; - } void set(LVElement *Element, StringRef Name, LVOffset Offset, uint32_t LineNumber = 0, LVElement *Type = nullptr); @@ -111,40 +110,40 @@ void ReaderTestElements::createElements() { ASSERT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(); - UnsignedType = create(); - GlobalType = create(); - LocalType = create(); - NestedType = create(); - EnumeratorOne = create(); - EnumeratorTwo = create(); - TypeDefinitionOne = create(); - TypeDefinitionTwo = create(); - TypeSubrange = create(); - TypeParam = create(); - TypeImport = create(); + CREATE(IntegerType, createType); + CREATE(UnsignedType, createType); + CREATE(GlobalType, createType); + CREATE(LocalType, createType); + CREATE(NestedType, createType); + CREATE(EnumeratorOne, createTypeEnumerator); + CREATE(EnumeratorTwo, createTypeEnumerator); + CREATE(TypeDefinitionOne, createTypeDefinition); + CREATE(TypeDefinitionTwo, createTypeDefinition); + CREATE(TypeSubrange, createTypeSubrange); + CREATE(TypeParam, createTypeParam); + CREATE(TypeImport, createTypeImport); // Create the logical scopes. - NestedScope = create(); - Aggregate = create(); - Array = create(); - CompileUnit = create(); - Enumeration = create(); - Function = create(); - ClassFunction = create(); - InlinedFunction = create(); - Namespace = create(); + CREATE(NestedScope, createScope); + CREATE(Aggregate, createScopeAggregate); + CREATE(Array, createScopeArray); + CREATE(CompileUnit, createScopeCompileUnit); + CREATE(Enumeration, createScopeEnumeration); + CREATE(Function, createScopeFunction); + CREATE(ClassFunction, createScopeFunction); + CREATE(InlinedFunction, createScopeFunctionInlined); + CREATE(Namespace, createScopeNamespace); // Create the logical symbols. - GlobalVariable = create(); - LocalVariable = create(); - ClassMember = create(); - NestedVariable = create(); - Parameter = create(); + CREATE(GlobalVariable, createSymbol); + CREATE(LocalVariable, createSymbol); + CREATE(ClassMember, createSymbol); + CREATE(NestedVariable, createSymbol); + CREATE(Parameter, createSymbol); // Create the logical lines. - LocalLine = create(); - NestedLine = create(); + CREATE(LocalLine, createLine); + CREATE(NestedLine, createLine); } // Create the logical view adding the created logical elements. diff --git a/llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp b/llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp index d590942eed4d7..70835ce05507c 100644 --- a/llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp +++ b/llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp @@ -23,6 +23,11 @@ using namespace llvm::logicalview; namespace { class ReaderTestSelection : public LVReader { +#define CREATE(VARIABLE, CREATE_FUNCTION, SET_FUNCTION) \ + VARIABLE = CREATE_FUNCTION(); \ + EXPECT_NE(VARIABLE, nullptr); \ + VARIABLE->SET_FUNCTION(); + // Types. LVType *IntegerType = nullptr; @@ -47,14 +52,6 @@ class ReaderTestSelection : public LVReader { protected: void add(LVScope *Parent, LVElement *Element); - template T *create(F Function) { - // 'Function' will update a specific kind of the logical element to - // have the ability of kind selection. - T *Element = new (std::nothrow) T(); - EXPECT_NE(Element, nullptr); - (Element->*Function)(); - return Element; - } void set(LVElement *Element, StringRef Name, LVOffset Offset, uint32_t LineNumber = 0, LVElement *Type = nullptr); @@ -104,34 +101,27 @@ void ReaderTestSelection::createElements() { EXPECT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(&LVType::setIsBase); + CREATE(IntegerType, createType, setIsBase); // Create the logical scopes. - CompileUnit = create( - &LVScope::setIsCompileUnit); - Function = - create(&LVScope::setIsFunction); - NestedScope = - create(&LVScope::setIsLexicalBlock); - Namespace = - create(&LVScope::setIsNamespace); - Aggregate = - create(&LVScope::setIsAggregate); + CREATE(CompileUnit, createScopeCompileUnit, setIsCompileUnit); + CREATE(Function, createScopeFunction, setIsFunction); + CREATE(NestedScope, createScope, setIsLexicalBlock); + CREATE(Namespace, createScopeNamespace, setIsNamespace); + CREATE(Aggregate, createScopeAggregate, setIsAggregate); // Create the logical symbols. - ClassMember = create(&LVSymbol::setIsMember); - LocalVariable = - create(&LVSymbol::setIsVariable); - NestedVariable = - create(&LVSymbol::setIsVariable); - Parameter = create(&LVSymbol::setIsParameter); + CREATE(ClassMember, createSymbol, setIsMember); + CREATE(LocalVariable, createSymbol, setIsVariable); + CREATE(NestedVariable, createSymbol, setIsVariable); + CREATE(Parameter, createSymbol, setIsParameter); // Create the logical lines. - LineOne = create(&LVLine::setIsLineDebug); - LineTwo = create(&LVLine::setIsBasicBlock); - LineThree = create(&LVLine::setIsNewStatement); - LineFour = create(&LVLine::setIsPrologueEnd); - LineFive = create(&LVLine::setIsLineAssembler); + CREATE(LineOne, createLine, setIsLineDebug); + CREATE(LineTwo, createLine, setIsBasicBlock); + CREATE(LineThree, createLine, setIsNewStatement); + CREATE(LineFour, createLine, setIsPrologueEnd); + CREATE(LineFive, createLine, setIsLineAssembler); } // Create the logical view adding the created logical elements. diff --git a/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp b/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp index e2444e36a6887..36c6e16a78dfa 100644 --- a/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp +++ b/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp @@ -22,7 +22,10 @@ using namespace llvm::logicalview; namespace { -class MyLocation; +class MyLocation : public LVLocation { +public: + bool validateRanges(); +}; // This code emulates the work done by the Readers when processing the // binary files and the creation of the AddressToLine mapping is done @@ -59,6 +62,14 @@ LVLine *MyAddressToLine::lineUpperBound(LVAddress Address) { MyAddressToLine AddressToLine; class ReaderTestWarningInternal : public LVReader { +#define CREATE(VARIABLE, CREATE_FUNCTION) \ + VARIABLE = CREATE_FUNCTION(); \ + EXPECT_NE(VARIABLE, nullptr); + +#define CREATE_CUSTOM(VARIABLE, CREATE_FUNCTION) \ + VARIABLE = CREATE_FUNCTION(); \ + EXPECT_NE(VARIABLE, nullptr); + // Types. LVType *IntegerType = nullptr; @@ -87,18 +98,19 @@ class ReaderTestWarningInternal : public LVReader { MyLocation *LocationFive = nullptr; MyLocation *LocationSix = nullptr; + llvm::SpecificBumpPtrAllocator AllocatedLocations; + protected: - void add(LVScope *Parent, LVElement *Element); - template T *create() { - T *Element = new (std::nothrow) T(); - EXPECT_NE(Element, nullptr); - return Element; + MyLocation *createCustomLocation() { + return new (AllocatedLocations.Allocate()) MyLocation(); } + + void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine); + void add(LVScope *Parent, LVElement *Element); void set(LVElement *Element, StringRef Name, LVOffset Offset, uint32_t LineNumber = 0, LVElement *Type = nullptr); void set(MyLocation *Location, LVLine *LowerLine, LVLine *UpperLine, LVAddress LowerAddress, LVAddress UpperAddress); - void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine); public: ReaderTestWarningInternal(ScopedPrinter &W) : LVReader("", "", W) { @@ -115,11 +127,6 @@ class ReaderTestWarningInternal : public LVReader { void checkWarnings(); }; -class MyLocation : public LVLocation { -public: - bool validateRanges(); -}; - bool MyLocation::validateRanges() { // Traverse the locations and validate them against the address to line // mapping in the current compile unit. Record those invalid ranges. @@ -213,33 +220,33 @@ void ReaderTestWarningInternal::createElements() { EXPECT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(); + CREATE(IntegerType, createType); // Create the logical scopes. - NestedScope = create(); - CompileUnit = create(); - Function = create(); + CREATE(NestedScope, createScope); + CREATE(CompileUnit, createScopeCompileUnit); + CREATE(Function, createScopeFunction); // Create the logical symbols. - LocalVariable = create(); - NestedVariable = create(); - Parameter = create(); + CREATE(LocalVariable, createSymbol); + CREATE(NestedVariable, createSymbol); + CREATE(Parameter, createSymbol); // Create the logical lines. - LineOne = create(); - LineTwo = create(); - LineThree = create(); - LineFour = create(); - LineFive = create(); - LineSix = create(); + CREATE(LineOne, createLine); + CREATE(LineTwo, createLine); + CREATE(LineThree, createLine); + CREATE(LineFour, createLine); + CREATE(LineFive, createLine); + CREATE(LineSix, createLine); // Create the logical locations. - LocationOne = create(); - LocationTwo = create(); - LocationThree = create(); - LocationFour = create(); - LocationFive = create(); - LocationSix = create(); + CREATE_CUSTOM(LocationOne, createCustomLocation); + CREATE_CUSTOM(LocationTwo, createCustomLocation); + CREATE_CUSTOM(LocationThree, createCustomLocation); + CREATE_CUSTOM(LocationFour, createCustomLocation); + CREATE_CUSTOM(LocationFive, createCustomLocation); + CREATE_CUSTOM(LocationSix, createCustomLocation); } // Create the logical view adding the created logical elements. @@ -450,7 +457,7 @@ void ReaderTestWarningInternal::checkWarnings() { LVOffsetLinesMap::iterator IterZero = LinesZero.begin(); EXPECT_EQ(IterZero->first, Function->getOffset()); - LVLines *Lines = IterZero->second; + LVLines *Lines = &IterZero->second; EXPECT_NE(Lines, nullptr); ASSERT_EQ(Lines->size(), 1u); LVLine *Line = *(Lines->begin()); @@ -459,7 +466,7 @@ void ReaderTestWarningInternal::checkWarnings() { ++IterZero; EXPECT_EQ(IterZero->first, NestedScope->getOffset()); - Lines = IterZero->second; + Lines = &IterZero->second; EXPECT_NE(Lines, nullptr); ASSERT_EQ(Lines->size(), 1u); Line = *(Lines->begin()); @@ -487,7 +494,7 @@ void ReaderTestWarningInternal::checkWarnings() { LVOffsetLocationsMap::iterator IterRange = InvalidRanges.begin(); EXPECT_EQ(IterRange->first, Function->getOffset()); - LVLocations *Locations = IterRange->second; + LVLocations *Locations = &IterRange->second; EXPECT_NE(Locations, nullptr); ASSERT_EQ(Locations->size(), 1u); LVLocation *Location = *(Locations->begin()); @@ -501,7 +508,7 @@ void ReaderTestWarningInternal::checkWarnings() { LVOffsetLocationsMap::iterator IterLocations = InvalidLocations.begin(); EXPECT_EQ(IterLocations->first, NestedVariable->getOffset()); - Locations = IterLocations->second; + Locations = &IterLocations->second; EXPECT_NE(Locations, nullptr); ASSERT_EQ(Locations->size(), 1u); Location = *(Locations->begin());