Index: llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h +++ llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h @@ -172,7 +172,8 @@ class LVLocationSymbol final : public LVLocation { // Location descriptors for the active range. - LVAutoOperations *Entries = nullptr; + using LVOperationSet = SmallVector, 8>; + std::unique_ptr Entries; void updateKind() override; @@ -180,7 +181,7 @@ 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; Index: llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h +++ llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h @@ -74,21 +74,6 @@ 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; Index: llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h +++ llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h @@ -74,6 +74,9 @@ Error createSplitFolder(); bool OutputSplit = false; + // Allocated logical elements. + SmallVector> AllocatedObjects; + protected: LVScopeRoot *Root = nullptr; std::string InputFilename; @@ -92,7 +95,7 @@ // Create the Scope Root. virtual Error createScopes() { - Root = new LVScopeRoot(); + Root = createObject(); Root->setName(getFilename()); if (options().getAttributeFormat()) Root->setFileFormatName(FileFormatName); @@ -129,9 +132,14 @@ 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 and records it in the Reader. + template ObjectType *createObject() { + std::unique_ptr ObjectSP = std::make_unique(); + LVObject *Object = ObjectSP.get(); + AllocatedObjects.emplace_back(std::move(ObjectSP)); + return (ObjectType *)Object; } StringRef getFilename(LVObject *Object, size_t Index) const; Index: llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h +++ llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h @@ -63,12 +63,11 @@ 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 @@ // 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 @@ 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 @@ // - 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 @@ } 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 @@ 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); @@ -459,8 +459,8 @@ LVOffsetLocationsMap *Map) { LVOffset Offset = Element->getOffset(); addInvalidOffset(Offset, Element); - addItem( - Map, Offset, Location); + addItem(Map, Offset, + Location); } // Record scope sizes indexed by lexical level. @@ -492,12 +492,7 @@ } 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)); Index: llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h +++ llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h @@ -27,25 +27,6 @@ namespace llvm { namespace logicalview { -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; - } -}; - using LVStringRefs = std::vector; using LVLexicalComponent = std::tuple; using LVLexicalIndex = @@ -148,25 +129,10 @@ 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. @@ -175,33 +141,29 @@ 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); + std::unique_ptr SecondMapSP = + std::make_unique(); + SecondMap = SecondMapSP.get(); + SecondMap->emplace(SecondKey, Value); + FirstMap.emplace(FirstKey, std::move(SecondMapSP)); } else { - SecondMap = FirstIter->second; + 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); @@ -213,8 +175,7 @@ if (FirstIter == FirstMap.end()) return nullptr; - LVSecondMapType *SecondMap = FirstIter->second; - return SecondMap; + return FirstIter->second.get(); } ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const { @@ -240,8 +201,8 @@ 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; Index: llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h +++ llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h @@ -46,7 +46,7 @@ // 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 @@ 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 @@ } 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; Index: llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h +++ 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 @@ LVReaders TheReaders; Error createReaders(); - void destroyReaders(); Error printReaders(); Error compareReaders(); @@ -74,20 +73,18 @@ } 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 Err; + return std::move(Readers[0]); } - void deleteReader(LVReader *Reader) { delete Reader; } void print(raw_ostream &OS) const; Index: llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h +++ llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h @@ -73,7 +73,7 @@ // It contains the LVLineDebug elements representing the inlined logical // lines for the current compile unit, created by parsing the CodeView // S_INLINESITE symbol annotation data. - using LVInlineeLine = std::map; + using LVInlineeLine = std::map>; LVInlineeLine CUInlineeLines; // Instruction lines for a logical scope. These instructions are fetched @@ -96,7 +96,7 @@ // 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. @@ -107,6 +107,8 @@ 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. @@ -158,12 +160,10 @@ : LVReader(Filename, FileFormatName, W, BinaryType) {} LVBinaryReader(const LVBinaryReader &) = delete; LVBinaryReader &operator=(const LVBinaryReader &) = delete; - virtual ~LVBinaryReader(); + virtual ~LVBinaryReader() = default; void addInlineeLines(LVScope *Scope, LVLines &Lines) { - LVLines *InlineeLines = new LVLines(); - *InlineeLines = std::move(Lines); - CUInlineeLines.emplace(Scope, InlineeLines); + CUInlineeLines.emplace(Scope, std::make_unique(std::move(Lines))); } // Convert Segment::Offset pair to absolute address. Index: llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h =================================================================== --- llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h +++ llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h @@ -239,7 +239,7 @@ std::shared_ptr TypeServer = nullptr; std::shared_ptr PrecompHeader = nullptr; - LVShared *Shared; + std::shared_ptr Shared; // Object files have only one type stream that contains both types and ids. // Precompiled header objects don't contain an IPI stream. Use the TPI. @@ -283,7 +283,6 @@ public: LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W, llvm::pdb::InputFile &Input); - ~LVLogicalVisitor(); // Current elements during the processing of a RecordType or RecordSymbol. // They are shared with the SymbolVisitor. @@ -348,7 +347,7 @@ LVElement *getElement(uint32_t StreamIdx, TypeIndex TI, LVScope *Parent = nullptr); - LVShared *getShared() { return Shared; } + LVShared *getShared() { return Shared.get(); } LVScope *getReaderScope() const { return ReaderScope; } Index: llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp +++ llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp @@ -579,8 +579,8 @@ 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(std::make_unique(Opcode, Operand1, Operand2)); } // Based on the DWARF attribute, define the location kind. @@ -606,15 +606,14 @@ 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(); } } void LVLocationSymbol::printRawExtra(raw_ostream &OS, bool Full) const { if (Entries) - for (const LVOperation *Operation : *Entries) + for (const std::unique_ptr &Operation : *Entries) Operation->print(OS, Full); } @@ -661,7 +660,7 @@ bool CodeViewLocation = getParentSymbol()->getHasCodeViewLocation(); std::stringstream Stream; std::string Leading = ""; - for (LVOperation *Operation : *Entries) { + for (std::unique_ptr &Operation : *Entries) { Stream << Leading << (CodeViewLocation ? Operation->getOperandsCodeViewInfo() : Operation->getOperandsDWARFInfo()); Index: llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp +++ llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp @@ -45,15 +45,6 @@ //===----------------------------------------------------------------------===// // 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 @@ void LVScope::addToChildren(LVElement *Element) { if (!Children) - Children = new LVElements(); + Children = std::make_unique(); Children->push_back(Element); } @@ -137,7 +128,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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().createObject(); Location->setLowerAddress(LowerAddress); Location->setUpperAddress(UpperAddress); Location->setIsAddressRange(); @@ -341,7 +332,7 @@ // 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().createObject(); addElement(Symbol); Symbol->setOffset(getOffset()); Symbol->setIsOptimized(); @@ -698,11 +689,11 @@ if (Set) std::stable_sort(Set->begin(), Set->end(), SortFunction); }; - Traverse(Parent->Types, SortFunction); - Traverse(Parent->Symbols, SortFunction); - Traverse(Parent->Scopes, SortFunction); - Traverse(Parent->Ranges, compareRange); - Traverse(Parent->Children, SortFunction); + Traverse(Parent->Types.get(), SortFunction); + Traverse(Parent->Symbols.get(), SortFunction); + Traverse(Parent->Scopes.get(), SortFunction); + Traverse(Parent->Ranges.get(), compareRange); + Traverse(Parent->Children.get(), SortFunction); if (Parent->Scopes) for (LVScope *Scope : *Parent->Scopes) @@ -886,10 +877,10 @@ for (auto *Entry : *Container) Entry->setIsInCompare(); }; - SetCompareState(Types); - SetCompareState(Symbols); - SetCompareState(Lines); - SetCompareState(Scopes); + SetCompareState(Types.get()); + SetCompareState(Symbols.get()); + SetCompareState(Lines.get()); + SetCompareState(Scopes.get()); // At this point, we are ready to start comparing the current scope, once // the compare bits have been set. @@ -1360,8 +1351,7 @@ // 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. @@ -1394,8 +1384,7 @@ 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 { @@ -1485,7 +1474,7 @@ 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"; } @@ -1498,7 +1487,7 @@ 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"; } @@ -1523,7 +1512,7 @@ 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"; } Index: llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp +++ llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp @@ -66,10 +66,10 @@ 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().createObject(); CurrentLocation->setParent(this); CurrentLocation->setAttr(Attr); if (CallSiteLocation) @@ -105,7 +105,7 @@ LVAddress LowPC, LVAddress HighPC) { // Create a location entry for the gap. - LVLocation *Gap = new LVLocationSymbol(); + LVLocation *Gap = getReader().createObject(); Gap->setParent(this); Gap->setAttr(dwarf::DW_AT_location); Gap->addObject(LowPC, HighPC, @@ -190,7 +190,7 @@ // 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 @@ Reference->printReference(OS, Full, const_cast(this)); // Print location information. - LVLocation::print(Locations, OS, Full); + LVLocation::print(Locations.get(), OS, Full); } } Index: llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp +++ llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp @@ -37,40 +37,36 @@ 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.isCOFF()) { COFFObjectFile *COFF = cast(&Obj); - return new LVCodeViewReader(Filename, FileFormatName, *COFF, W, - ExePath); + return std::make_unique(Filename, FileFormatName, + *COFF, W, ExePath); } if (Obj.isELF() || Obj.isMachO()) - return new LVELFReader(Filename, FileFormatName, Obj, W); + return std::make_unique(Filename, FileFormatName, Obj, W); } if (Input.is()) { PDBFile &Pdb = *Input.get(); - return new LVCodeViewReader(Filename, FileFormatName, Pdb, W, ExePath); + return std::make_unique(Filename, FileFormatName, Pdb, + W, ExePath); } 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(); } @@ -283,7 +279,9 @@ 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(); @@ -292,7 +290,7 @@ 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; @@ -307,7 +305,8 @@ 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; } Index: llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp +++ llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp @@ -352,29 +352,16 @@ } 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) { @@ -435,7 +422,9 @@ // Address for first instruction line. LVAddress FirstAddress = Address; - LVLines *Instructions = new LVLines(); + std::unique_ptr InstructionsSP = std::make_unique(); + LVLines *Instructions = InstructionsSP.get(); + DiscoveredLines.emplace_back(std::move(InstructionsSP)); while (Begin < End) { MCInst Instruction; @@ -476,7 +465,7 @@ // 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 = createObject(); Line->setAddress(Address); Line->setName(StringRef(Stream.str()).trim()); Instructions->push_back(Line); @@ -891,7 +880,8 @@ LVScope *Scope = InlineeIter->first; addToSymbolTable(Scope->getLinkageName(), Scope, SectionIndex); - LVLines *InlineeLines = InlineeIter->second; + // TODO: Convert this into a reference. + LVLines *InlineeLines = InlineeIter->second.get(); LLVM_DEBUG({ dbgs() << "Inlined lines for: " << Scope->getName() << "\n"; for (const LVLine *Line : *InlineeLines) @@ -931,7 +921,6 @@ // creates an unique set of lines. Remove only the created container. CUInlineeLines.erase(InlineeIter); InlineeLines->clear(); - delete InlineeLines; } LLVM_DEBUG({ dbgs() << "Merged Inlined lines for: " << Function->getName() << "\n"; Index: llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp +++ llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp @@ -308,7 +308,7 @@ // 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 *LineDebug = new LVLineDebug(); + LVLineDebug *LineDebug = createObject(); CULines.push_back(LineDebug); LVAddress Address = linearAddress(Segment, Begin + Line.Offset); LineDebug->setAddress(Address + Addendum); Index: llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp +++ llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp @@ -450,7 +450,7 @@ if (!Namespace) { // We have identified namespaces that are generated by MSVC. Mark them // as 'system' so they will be excluded from the logical view. - Namespace = new LVScopeNamespace(); + Namespace = Shared->Reader->createObject(); Namespace->setTag(dwarf::DW_TAG_namespace); Namespace->setName(Component); Parent->addElement(Namespace); @@ -1386,7 +1386,7 @@ LLVM_DEBUG({ printTypeIndex("Inlinee", InlineSite.Inlinee); }); if (LVScope *InlinedFunction = LogicalVisitor->CurrentScope) { - LVScope *AbstractFunction = new LVScopeFunction(); + LVScope *AbstractFunction = Reader->createObject(); AbstractFunction->setIsSubprogram(); AbstractFunction->setTag(dwarf::DW_TAG_subprogram); AbstractFunction->setInlineCode(dwarf::DW_INL_inlined); @@ -1699,9 +1699,8 @@ : Reader(Reader), W(W), Input(Input) { // The LogicalVisitor connects the CodeViewReader with the visitors that // traverse the types, symbols, etc. Do any initialization that is needed. - Shared = new LVShared(Reader, this); + Shared = std::make_shared(Reader, this); } -LVLogicalVisitor::~LVLogicalVisitor() { delete Shared; } void LVLogicalVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI, uint32_t StreamIdx) { @@ -1809,7 +1808,7 @@ // create a DW_TAG_subrange_type, with dimension size. // The subrange type can be: unsigned __int32 or unsigned __int64. auto AddSubrangeType = [&](ArrayRecord &AR) { - LVType *Subrange = new LVTypeSubrange(); + LVType *Subrange = Reader->createObject(); Subrange->setTag(dwarf::DW_TAG_subrange_type); Subrange->setType(getElement(StreamTPI, AR.getIndexType())); Subrange->setCount(AR.getSize()); @@ -2266,7 +2265,7 @@ } if (Mods & uint16_t(ModifierOptions::Volatile)) { if (SeenModifier) { - LVType *Volatile = new LVType(); + LVType *Volatile = Reader->createObject(); Volatile->setIsModifier(); LastLink->setType(Volatile); LastLink = Volatile; @@ -2278,7 +2277,7 @@ } if (Mods & uint16_t(ModifierOptions::Unaligned)) { if (SeenModifier) { - LVType *Unaligned = new LVType(); + LVType *Unaligned = Reader->createObject(); Unaligned->setIsModifier(); LastLink->setType(Unaligned); LastLink = Unaligned; @@ -2338,7 +2337,7 @@ if (Ptr.isRestrict()) { SeenModifier = true; - LVType *Restrict = new LVType(); + LVType *Restrict = Reader->createObject(); Restrict->setTag(dwarf::DW_TAG_restrict_type); Restrict->setIsRestrict(); Restrict->setName("restrict"); @@ -2348,7 +2347,7 @@ } if (Mode == PointerMode::LValueReference) { if (SeenModifier) { - LVType *LReference = new LVType(); + LVType *LReference = Reader->createObject(); LReference->setIsModifier(); LastLink->setType(LReference); LastLink = LReference; @@ -2360,7 +2359,7 @@ } if (Mode == PointerMode::RValueReference) { if (SeenModifier) { - LVType *RReference = new LVType(); + LVType *RReference = Reader->createObject(); RReference->setIsModifier(); LastLink->setType(RReference); LastLink = RReference; @@ -2949,7 +2948,7 @@ CurrentType = nullptr; if (Kind < TypeIndex::FirstNonSimpleIndex) { - CurrentType = new LVType(); + CurrentType = Reader->createObject(); CurrentType->setIsBase(); CurrentType->setTag(dwarf::DW_TAG_base_type); if (options().getAttributeBase()) @@ -2960,15 +2959,15 @@ switch (Kind) { // Types. case TypeLeafKind::LF_ENUMERATE: - CurrentType = new LVTypeEnumerator(); + CurrentType = Reader->createObject(); CurrentType->setTag(dwarf::DW_TAG_enumerator); return CurrentType; case TypeLeafKind::LF_MODIFIER: - CurrentType = new LVType(); + CurrentType = Reader->createObject(); CurrentType->setIsModifier(); return CurrentType; case TypeLeafKind::LF_POINTER: - CurrentType = new LVType(); + CurrentType = Reader->createObject(); CurrentType->setIsPointer(); CurrentType->setName("*"); CurrentType->setTag(dwarf::DW_TAG_pointer_type); @@ -2978,45 +2977,45 @@ case TypeLeafKind::LF_BCLASS: case TypeLeafKind::LF_IVBCLASS: case TypeLeafKind::LF_VBCLASS: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = Reader->createObject(); CurrentSymbol->setTag(dwarf::DW_TAG_inheritance); CurrentSymbol->setIsInheritance(); return CurrentSymbol; case TypeLeafKind::LF_MEMBER: case TypeLeafKind::LF_STMEMBER: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = Reader->createObject(); CurrentSymbol->setIsMember(); CurrentSymbol->setTag(dwarf::DW_TAG_member); return CurrentSymbol; // Scopes. case TypeLeafKind::LF_ARRAY: - CurrentScope = new LVScopeArray(); + CurrentScope = Reader->createObject(); CurrentScope->setTag(dwarf::DW_TAG_array_type); return CurrentScope; case TypeLeafKind::LF_CLASS: - CurrentScope = new LVScopeAggregate(); + CurrentScope = Reader->createObject(); CurrentScope->setTag(dwarf::DW_TAG_class_type); CurrentScope->setIsClass(); return CurrentScope; case TypeLeafKind::LF_ENUM: - CurrentScope = new LVScopeEnumeration(); + CurrentScope = Reader->createObject(); CurrentScope->setTag(dwarf::DW_TAG_enumeration_type); return CurrentScope; case TypeLeafKind::LF_METHOD: case TypeLeafKind::LF_ONEMETHOD: case TypeLeafKind::LF_PROCEDURE: - CurrentScope = new LVScopeFunction(); + CurrentScope = Reader->createObject(); CurrentScope->setIsSubprogram(); CurrentScope->setTag(dwarf::DW_TAG_subprogram); return CurrentScope; case TypeLeafKind::LF_STRUCTURE: - CurrentScope = new LVScopeAggregate(); + CurrentScope = Reader->createObject(); CurrentScope->setIsStructure(); CurrentScope->setTag(dwarf::DW_TAG_structure_type); return CurrentScope; case TypeLeafKind::LF_UNION: - CurrentScope = new LVScopeAggregate(); + CurrentScope = Reader->createObject(); CurrentScope->setIsUnion(); CurrentScope->setTag(dwarf::DW_TAG_union_type); return CurrentScope; @@ -3035,13 +3034,13 @@ switch (Kind) { // Types. case SymbolKind::S_UDT: - CurrentType = new LVTypeDefinition(); + CurrentType = Reader->createObject(); CurrentType->setTag(dwarf::DW_TAG_typedef); return CurrentType; // Symbols. case SymbolKind::S_CONSTANT: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = Reader->createObject(); CurrentSymbol->setIsConstant(); CurrentSymbol->setTag(dwarf::DW_TAG_constant); return CurrentSymbol; @@ -3054,26 +3053,26 @@ // During the symbol traversal more information is available to // determine if the symbol is a parameter or a variable. At this // stage mark it as variable. - CurrentSymbol = new LVSymbol(); + CurrentSymbol = Reader->createObject(); CurrentSymbol->setIsVariable(); CurrentSymbol->setTag(dwarf::DW_TAG_variable); return CurrentSymbol; // Scopes. case SymbolKind::S_BLOCK32: - CurrentScope = new LVScope(); + CurrentScope = Reader->createObject(); CurrentScope->setIsLexicalBlock(); CurrentScope->setTag(dwarf::DW_TAG_lexical_block); return CurrentScope; case SymbolKind::S_COMPILE2: case SymbolKind::S_COMPILE3: - CurrentScope = new LVScopeCompileUnit(); + CurrentScope = Reader->createObject(); CurrentScope->setTag(dwarf::DW_TAG_compile_unit); Reader->setCompileUnit(static_cast(CurrentScope)); return CurrentScope; case SymbolKind::S_INLINESITE: case SymbolKind::S_INLINESITE2: - CurrentScope = new LVScopeFunctionInlined(); + CurrentScope = Reader->createObject(); CurrentScope->setIsInlinedFunction(); CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine); return CurrentScope; @@ -3083,7 +3082,7 @@ case SymbolKind::S_GPROC32_ID: case SymbolKind::S_SEPCODE: case SymbolKind::S_THUNK32: - CurrentScope = new LVScopeFunction(); + CurrentScope = Reader->createObject(); CurrentScope->setIsSubprogram(); CurrentScope->setTag(dwarf::DW_TAG_subprogram); return CurrentScope; @@ -3158,7 +3157,7 @@ LVSymbol *LVLogicalVisitor::createParameter(LVElement *Element, StringRef Name, LVScope *Parent) { - LVSymbol *Parameter = new LVSymbol(); + LVSymbol *Parameter = Reader->createObject(); Parent->addElement(Parameter); Parameter->setIsParameter(); Parameter->setTag(dwarf::DW_TAG_formal_parameter); @@ -3456,7 +3455,7 @@ LVLines InlineeLines; auto CreateLine = [&]() { // Create the logical line record. - LVLineDebug *Line = new LVLineDebug(); + LVLineDebug *Line = Reader->createObject(); Line->setAddress(CodeOffset); Line->setLineNumber(LineOffset); // TODO: This part needs additional work in order to set properly the Index: llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp +++ llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp @@ -57,182 +57,182 @@ switch (Tag) { // Types. case dwarf::DW_TAG_base_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsBase(); if (options().getAttributeBase()) CurrentType->setIncludeInPrint(); return CurrentType; case dwarf::DW_TAG_const_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsConst(); CurrentType->setName("const"); return CurrentType; case dwarf::DW_TAG_enumerator: - CurrentType = new LVTypeEnumerator(); + CurrentType = createObject(); return CurrentType; case dwarf::DW_TAG_imported_declaration: - CurrentType = new LVTypeImport(); + CurrentType = createObject(); CurrentType->setIsImportDeclaration(); return CurrentType; case dwarf::DW_TAG_imported_module: - CurrentType = new LVTypeImport(); + CurrentType = createObject(); CurrentType->setIsImportModule(); return CurrentType; case dwarf::DW_TAG_pointer_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsPointer(); CurrentType->setName("*"); return CurrentType; case dwarf::DW_TAG_ptr_to_member_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsPointerMember(); CurrentType->setName("*"); return CurrentType; case dwarf::DW_TAG_reference_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsReference(); CurrentType->setName("&"); return CurrentType; case dwarf::DW_TAG_restrict_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsRestrict(); CurrentType->setName("restrict"); return CurrentType; case dwarf::DW_TAG_rvalue_reference_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsRvalueReference(); CurrentType->setName("&&"); return CurrentType; case dwarf::DW_TAG_subrange_type: - CurrentType = new LVTypeSubrange(); + CurrentType = createObject(); return CurrentType; case dwarf::DW_TAG_template_value_parameter: - CurrentType = new LVTypeParam(); + CurrentType = createObject(); CurrentType->setIsTemplateValueParam(); return CurrentType; case dwarf::DW_TAG_template_type_parameter: - CurrentType = new LVTypeParam(); + CurrentType = createObject(); CurrentType->setIsTemplateTypeParam(); return CurrentType; case dwarf::DW_TAG_GNU_template_template_param: - CurrentType = new LVTypeParam(); + CurrentType = createObject(); CurrentType->setIsTemplateTemplateParam(); return CurrentType; case dwarf::DW_TAG_typedef: - CurrentType = new LVTypeDefinition(); + CurrentType = createObject(); return CurrentType; case dwarf::DW_TAG_unspecified_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsUnspecified(); return CurrentType; case dwarf::DW_TAG_volatile_type: - CurrentType = new LVType(); + CurrentType = createObject(); CurrentType->setIsVolatile(); CurrentType->setName("volatile"); return CurrentType; // Symbols. case dwarf::DW_TAG_formal_parameter: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createObject(); CurrentSymbol->setIsParameter(); return CurrentSymbol; case dwarf::DW_TAG_unspecified_parameters: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createObject(); CurrentSymbol->setIsUnspecified(); CurrentSymbol->setName("..."); return CurrentSymbol; case dwarf::DW_TAG_member: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createObject(); CurrentSymbol->setIsMember(); return CurrentSymbol; case dwarf::DW_TAG_variable: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createObject(); CurrentSymbol->setIsVariable(); return CurrentSymbol; case dwarf::DW_TAG_inheritance: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createObject(); CurrentSymbol->setIsInheritance(); return CurrentSymbol; case dwarf::DW_TAG_call_site_parameter: case dwarf::DW_TAG_GNU_call_site_parameter: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createObject(); CurrentSymbol->setIsCallSiteParameter(); return CurrentSymbol; case dwarf::DW_TAG_constant: - CurrentSymbol = new LVSymbol(); + CurrentSymbol = createObject(); CurrentSymbol->setIsConstant(); return CurrentSymbol; // Scopes. case dwarf::DW_TAG_catch_block: - CurrentScope = new LVScope(); + CurrentScope = createObject(); CurrentScope->setIsCatchBlock(); return CurrentScope; case dwarf::DW_TAG_lexical_block: - CurrentScope = new LVScope(); + CurrentScope = createObject(); CurrentScope->setIsLexicalBlock(); return CurrentScope; case dwarf::DW_TAG_try_block: - CurrentScope = new LVScope(); + CurrentScope = createObject(); CurrentScope->setIsTryBlock(); return CurrentScope; case dwarf::DW_TAG_compile_unit: case dwarf::DW_TAG_skeleton_unit: - CurrentScope = new LVScopeCompileUnit(); + CurrentScope = createObject(); CompileUnit = static_cast(CurrentScope); return CurrentScope; case dwarf::DW_TAG_inlined_subroutine: - CurrentScope = new LVScopeFunctionInlined(); + CurrentScope = createObject(); return CurrentScope; case dwarf::DW_TAG_namespace: - CurrentScope = new LVScopeNamespace(); + CurrentScope = createObject(); return CurrentScope; case dwarf::DW_TAG_template_alias: - CurrentScope = new LVScopeAlias(); + CurrentScope = createObject(); return CurrentScope; case dwarf::DW_TAG_array_type: - CurrentScope = new LVScopeArray(); + CurrentScope = createObject(); return CurrentScope; case dwarf::DW_TAG_call_site: case dwarf::DW_TAG_GNU_call_site: - CurrentScope = new LVScopeFunction(); + CurrentScope = createObject(); CurrentScope->setIsCallSite(); return CurrentScope; case dwarf::DW_TAG_entry_point: - CurrentScope = new LVScopeFunction(); + CurrentScope = createObject(); CurrentScope->setIsEntryPoint(); return CurrentScope; case dwarf::DW_TAG_subprogram: - CurrentScope = new LVScopeFunction(); + CurrentScope = createObject(); CurrentScope->setIsSubprogram(); return CurrentScope; case dwarf::DW_TAG_subroutine_type: - CurrentScope = new LVScopeFunctionType(); + CurrentScope = createObject(); return CurrentScope; case dwarf::DW_TAG_label: - CurrentScope = new LVScopeFunction(); + CurrentScope = createObject(); CurrentScope->setIsLabel(); return CurrentScope; case dwarf::DW_TAG_class_type: - CurrentScope = new LVScopeAggregate(); + CurrentScope = createObject(); CurrentScope->setIsClass(); return CurrentScope; case dwarf::DW_TAG_structure_type: - CurrentScope = new LVScopeAggregate(); + CurrentScope = createObject(); CurrentScope->setIsStructure(); return CurrentScope; case dwarf::DW_TAG_union_type: - CurrentScope = new LVScopeAggregate(); + CurrentScope = createObject(); CurrentScope->setIsUnion(); return CurrentScope; case dwarf::DW_TAG_enumeration_type: - CurrentScope = new LVScopeEnumeration(); + CurrentScope = createObject(); return CurrentScope; case dwarf::DW_TAG_GNU_formal_parameter_pack: - CurrentScope = new LVScopeFormalPack(); + CurrentScope = createObject(); return CurrentScope; case dwarf::DW_TAG_GNU_template_parameter_pack: - CurrentScope = new LVScopeTemplatePack(); + CurrentScope = createObject(); return CurrentScope; default: // Collect TAGs not implemented. @@ -733,7 +733,7 @@ // 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 = createObject(); CULines.push_back(Line); Line->setAddress(Row.Address.Address); Line->setFilename( Index: llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp @@ -47,15 +47,16 @@ } // 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; } @@ -359,17 +360,21 @@ LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); // Check logical elements properties. - LVReader *Reader = createReader(ReaderHandler, InputsDir, CodeViewClang); - checkElementPropertiesClangCodeview(Reader); - ReaderHandler.deleteReader(Reader); - - Reader = createReader(ReaderHandler, InputsDir, CodeViewMsvc); - checkElementPropertiesMsvcCodeview(Reader); - ReaderHandler.deleteReader(Reader); - - Reader = createReader(ReaderHandler, InputsDir, CodeViewPdbMsvc); - checkElementPropertiesMsvcCodeviewPdb(Reader); - ReaderHandler.deleteReader(Reader); + { + std::unique_ptr Reader = + createReader(ReaderHandler, InputsDir, CodeViewClang); + checkElementPropertiesClangCodeview(Reader.get()); + } + { + std::unique_ptr Reader = + createReader(ReaderHandler, InputsDir, CodeViewMsvc); + checkElementPropertiesMsvcCodeview(Reader.get()); + } + { + std::unique_ptr Reader = + createReader(ReaderHandler, InputsDir, CodeViewPdbMsvc); + checkElementPropertiesMsvcCodeviewPdb(Reader.get()); + } } // Logical elements selection. @@ -398,35 +403,39 @@ LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); // Check logical elements selection. - std::vector DataClang = { - {"* const int", &LVElement::getIsType}, - {"CONSTANT", &LVElement::getIsSymbol}, - {"INTEGER", &LVElement::getIsType}, - {"INTPTR", &LVElement::getIsType}, - {"ParamPtr", &LVElement::getIsSymbol}, - {"const int", &LVElement::getIsType}, - {"foo", &LVElement::getIsScope}, - {"foo::?", &LVElement::getIsScope}, - {"int", &LVElement::getIsType}, - {"movl", &LVElement::getIsLine}, - {"movl", &LVElement::getIsLine}}; - LVReader *Reader = createReader(ReaderHandler, InputsDir, CodeViewClang); - checkElementSelection(Reader, DataClang, DataClang.size()); - ReaderHandler.deleteReader(Reader); - - std::vector DataMsvc = {{"* const int", &LVElement::getIsType}, - {"CONSTANT", &LVElement::getIsSymbol}, - {"INTEGER", &LVElement::getIsType}, - {"INTPTR", &LVElement::getIsType}, - {"ParamPtr", &LVElement::getIsSymbol}, - {"const int", &LVElement::getIsType}, - {"foo", &LVElement::getIsScope}, - {"foo::?", &LVElement::getIsScope}, - {"int", &LVElement::getIsType}, - {"movl", &LVElement::getIsLine}}; - Reader = createReader(ReaderHandler, InputsDir, CodeViewMsvc); - checkElementSelection(Reader, DataMsvc, DataMsvc.size()); - ReaderHandler.deleteReader(Reader); + { + std::vector DataClang = { + {"* const int", &LVElement::getIsType}, + {"CONSTANT", &LVElement::getIsSymbol}, + {"INTEGER", &LVElement::getIsType}, + {"INTPTR", &LVElement::getIsType}, + {"ParamPtr", &LVElement::getIsSymbol}, + {"const int", &LVElement::getIsType}, + {"foo", &LVElement::getIsScope}, + {"foo::?", &LVElement::getIsScope}, + {"int", &LVElement::getIsType}, + {"movl", &LVElement::getIsLine}, + {"movl", &LVElement::getIsLine}}; + std::unique_ptr Reader = + createReader(ReaderHandler, InputsDir, CodeViewClang); + checkElementSelection(Reader.get(), DataClang, DataClang.size()); + } + { + std::vector DataMsvc = { + {"* const int", &LVElement::getIsType}, + {"CONSTANT", &LVElement::getIsSymbol}, + {"INTEGER", &LVElement::getIsType}, + {"INTPTR", &LVElement::getIsType}, + {"ParamPtr", &LVElement::getIsSymbol}, + {"const int", &LVElement::getIsType}, + {"foo", &LVElement::getIsScope}, + {"foo::?", &LVElement::getIsScope}, + {"int", &LVElement::getIsType}, + {"movl", &LVElement::getIsLine}}; + std::unique_ptr Reader = + createReader(ReaderHandler, InputsDir, CodeViewMsvc); + checkElementSelection(Reader.get(), DataMsvc, DataMsvc.size()); + } } // Compare logical elements. @@ -448,11 +457,11 @@ LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); // Check logical comparison. - LVReader *Reference = createReader(ReaderHandler, InputsDir, CodeViewClang); - LVReader *Target = createReader(ReaderHandler, InputsDir, CodeViewMsvc); - checkElementComparison(Reference, Target); - ReaderHandler.deleteReader(Reference); - ReaderHandler.deleteReader(Target); + std::unique_ptr Reference = + createReader(ReaderHandler, InputsDir, CodeViewClang); + std::unique_ptr Target = + createReader(ReaderHandler, InputsDir, CodeViewMsvc); + checkElementComparison(Reference.get(), Target.get()); } TEST(LogicalViewTest, CodeViewReader) { Index: llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp @@ -26,10 +26,6 @@ //===----------------------------------------------------------------------===// // 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; - public: // Types. LVType *IntegerType = nullptr; @@ -69,7 +65,7 @@ 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(); + T *Element = createObject(); EXPECT_NE(Element, nullptr); (Element->*Function)(); return Element; @@ -203,8 +199,6 @@ auto Insert = [&](bool Insert, auto *Parent, auto *Child) { if (Insert) add(Parent, Child); - else - OrphanElements.push_back(Child); }; setCompileUnit(CompileUnit); Index: llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp @@ -47,15 +47,16 @@ } // 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 @@ 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 @@ 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 @@ 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) { Index: llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp @@ -26,7 +26,7 @@ protected: void add(LVScope *Parent, LVElement *Element); template T *create() { - T *Element = new (std::nothrow) T(); + T *Element = createObject(); EXPECT_NE(Element, nullptr); return Element; } Index: llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp @@ -61,7 +61,7 @@ protected: void add(LVScope *Parent, LVElement *Element); template T *create() { - T *Element = new (std::nothrow) T(); + T *Element = createObject(); EXPECT_NE(Element, nullptr); return Element; } Index: llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp @@ -50,7 +50,7 @@ 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(); + T *Element = createObject(); EXPECT_NE(Element, nullptr); (Element->*Function)(); return Element; Index: llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp @@ -90,7 +90,7 @@ protected: void add(LVScope *Parent, LVElement *Element); template T *create() { - T *Element = new (std::nothrow) T(); + T *Element = createObject(); EXPECT_NE(Element, nullptr); return Element; } @@ -450,7 +450,7 @@ 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 +459,7 @@ ++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 +487,7 @@ 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 +501,7 @@ 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());