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,48 @@ Error createSplitFolder(); bool OutputSplit = false; +// 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. +// Define a specific bump allocator for the given KIND. +#define OBJECT_ALLOCATOR(KIND) \ + llvm::SpecificBumpPtrAllocator Allocated##KIND; + + // Lines allocator. + OBJECT_ALLOCATOR(Line) + OBJECT_ALLOCATOR(LineDebug) + OBJECT_ALLOCATOR(LineAssembler) + + // Locations allocator. + OBJECT_ALLOCATOR(Location) + OBJECT_ALLOCATOR(LocationSymbol) + + // Scopes allocator. + OBJECT_ALLOCATOR(Scope) + OBJECT_ALLOCATOR(ScopeAggregate) + OBJECT_ALLOCATOR(ScopeAlias) + OBJECT_ALLOCATOR(ScopeArray) + OBJECT_ALLOCATOR(ScopeCompileUnit) + OBJECT_ALLOCATOR(ScopeEnumeration) + OBJECT_ALLOCATOR(ScopeFormalPack) + OBJECT_ALLOCATOR(ScopeFunction) + OBJECT_ALLOCATOR(ScopeFunctionInlined) + OBJECT_ALLOCATOR(ScopeFunctionType) + OBJECT_ALLOCATOR(ScopeNamespace) + OBJECT_ALLOCATOR(ScopeRoot) + OBJECT_ALLOCATOR(ScopeTemplatePack) + + // Symbols allocator. + OBJECT_ALLOCATOR(Symbol) + + // Types allocator. + OBJECT_ALLOCATOR(Type) + OBJECT_ALLOCATOR(TypeDefinition) + OBJECT_ALLOCATOR(TypeEnumerator) + OBJECT_ALLOCATOR(TypeImport) + OBJECT_ALLOCATOR(TypeParam) + OBJECT_ALLOCATOR(TypeSubrange) + protected: LVScopeRoot *Root = nullptr; std::string InputFilename; @@ -92,7 +134,7 @@ // Create the Scope Root. virtual Error createScopes() { - Root = new LVScopeRoot(); + Root = createScopeRoot(); Root->setName(getFilename()); if (options().getAttributeFormat()) Root->setFileFormatName(FileFormatName); @@ -129,11 +171,55 @@ 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 CREATE_OBJECT(KIND) \ + LV##KIND *create##KIND() { \ + return new (Allocated##KIND.Allocate()) LV##KIND(); \ } + // Lines creation. + CREATE_OBJECT(Line) + CREATE_OBJECT(LineDebug) + CREATE_OBJECT(LineAssembler) + + // Locations creation. + CREATE_OBJECT(Location) + CREATE_OBJECT(LocationSymbol) + + // Scopes creation. + CREATE_OBJECT(Scope) + CREATE_OBJECT(ScopeAggregate) + CREATE_OBJECT(ScopeAlias) + CREATE_OBJECT(ScopeArray) + CREATE_OBJECT(ScopeCompileUnit) + CREATE_OBJECT(ScopeEnumeration) + CREATE_OBJECT(ScopeFormalPack) + CREATE_OBJECT(ScopeFunction) + CREATE_OBJECT(ScopeFunctionInlined) + CREATE_OBJECT(ScopeFunctionType) + CREATE_OBJECT(ScopeNamespace) + CREATE_OBJECT(ScopeRoot) + CREATE_OBJECT(ScopeTemplatePack) + + // Symbols creation. + CREATE_OBJECT(Symbol) + + // Types creation. + CREATE_OBJECT(Type) + CREATE_OBJECT(TypeDefinition) + CREATE_OBJECT(TypeEnumerator) + CREATE_OBJECT(TypeImport) + CREATE_OBJECT(TypeParam) + CREATE_OBJECT(TypeSubrange) + StringRef getFilename(LVObject *Object, size_t Index) const; StringRef getFilename() const { return InputFilename; } void setFilename(std::string Name) { InputFilename = std::move(Name); } 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); @@ -456,8 +456,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. @@ -489,12 +489,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; - } -}; - // Used to record specific characteristics about the objects. template class LVProperties { SmallBitVector Bits = SmallBitVector(static_cast(T::LastEntry) + 1); @@ -143,25 +124,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. @@ -170,33 +136,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); @@ -208,8 +170,7 @@ if (FirstIter == FirstMap.end()) return nullptr; - LVSecondMapType *SecondMap = FirstIter->second; - return SecondMap; + return FirstIter->second.get(); } ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const { @@ -235,8 +196,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(); @@ -72,20 +71,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 @@ -89,7 +89,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. @@ -100,6 +100,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. @@ -149,7 +151,7 @@ : 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); 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().createLocation(); 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().createSymbol(); addElement(Symbol); Symbol->setOffset(getOffset()); Symbol->setIsOptimized(); @@ -694,11 +685,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) @@ -882,10 +873,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. @@ -1356,8 +1347,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. @@ -1390,8 +1380,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 { @@ -1481,7 +1470,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"; } @@ -1494,7 +1483,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"; } @@ -1519,7 +1508,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().createLocationSymbol(); 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().createLocationSymbol(); 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/Core/LVType.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp +++ llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp @@ -253,18 +253,16 @@ if (!Type->getIsTemplateParam()) continue; if (options().getAttributeArgument()) { - LVScope *Scope = nullptr; - if (Type->getIsKindType()) - Type = Type->getTypeAsType(); - else { + if (Type->getIsKindType()) { + TypesParam->push_back(Type->getTypeAsType()); + } else { if (Type->getIsKindScope()) { - Scope = Type->getTypeAsScope(); - Type = nullptr; + ScopesParam->push_back(Type->getTypeAsScope()); } } - Type ? TypesParam->push_back(Type) : ScopesParam->push_back(Scope); - } else + } else { TypesParam->push_back(Type); + } } } Index: llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp =================================================================== --- llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp +++ llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp @@ -32,31 +32,26 @@ 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 @@ 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::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 @@ 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 @@ -297,29 +297,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) { @@ -380,7 +367,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; @@ -422,7 +411,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 = createLineAssembler(); Line->setAddress(Address); Line->setName(StringRef(Stream.str()).trim()); Instructions->push_back(Line); 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 = 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 @@ // 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( 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; @@ -66,14 +62,6 @@ 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 +104,112 @@ 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); + IntegerType = createType(); + EXPECT_NE(IntegerType, nullptr); + IntegerType->setIsBase(); + + UnsignedType = createType(); + EXPECT_NE(UnsignedType, nullptr); + UnsignedType->setIsBase(); + + GlobalType = createType(); + EXPECT_NE(GlobalType, nullptr); + GlobalType->setIsBase(); + + LocalType = createType(); + EXPECT_NE(LocalType, nullptr); + LocalType->setIsBase(); + + NestedType = createType(); + EXPECT_NE(NestedType, nullptr); + NestedType->setIsBase(); + + EnumeratorOne = createTypeEnumerator(); + EXPECT_NE(EnumeratorOne, nullptr); + EnumeratorOne->setIsEnumerator(); + + EnumeratorTwo = createTypeEnumerator(); + EXPECT_NE(EnumeratorTwo, nullptr); + EnumeratorTwo->setIsEnumerator(); + + TypeDefinitionOne = createTypeDefinition(); + EXPECT_NE(TypeDefinitionOne, nullptr); + TypeDefinitionOne->setIsTypedef(); + + TypeDefinitionTwo = createTypeDefinition(); + EXPECT_NE(TypeDefinitionTwo, nullptr); + TypeDefinitionTwo->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); + NestedScope = createScope(); + EXPECT_NE(NestedScope, nullptr); + NestedScope->setIsLexicalBlock(); + + InnerScope = createScope(); + EXPECT_NE(InnerScope, nullptr); + InnerScope->setIsLexicalBlock(); + + Aggregate = createScopeAggregate(); + EXPECT_NE(Aggregate, nullptr); + Aggregate->setIsAggregate(); + + CompileUnit = createScopeCompileUnit(); + EXPECT_NE(CompileUnit, nullptr); + CompileUnit->setIsCompileUnit(); + + Enumeration = createScopeEnumeration(); + EXPECT_NE(Enumeration, nullptr); + Enumeration->setIsEnumeration(); + + FunctionOne = createScopeFunction(); + EXPECT_NE(FunctionOne, nullptr); + FunctionOne->setIsFunction(); + + FunctionTwo = createScopeFunction(); + EXPECT_NE(FunctionTwo, nullptr); + FunctionTwo->setIsFunction(); + + Namespace = createScopeNamespace(); + EXPECT_NE(Namespace, nullptr); + Namespace->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); + GlobalVariable = createSymbol(); + EXPECT_NE(GlobalVariable, nullptr); + GlobalVariable->setIsVariable(); + + LocalVariable = createSymbol(); + EXPECT_NE(LocalVariable, nullptr); + LocalVariable->setIsVariable(); + + ClassMember = createSymbol(); + EXPECT_NE(ClassMember, nullptr); + ClassMember->setIsMember(); + + NestedVariable = createSymbol(); + EXPECT_NE(NestedVariable, nullptr); + NestedVariable->setIsVariable(); + + ParameterOne = createSymbol(); + EXPECT_NE(ParameterOne, nullptr); + ParameterOne->setIsParameter(); + + ParameterTwo = createSymbol(); + EXPECT_NE(ParameterTwo, nullptr); + ParameterTwo->setIsParameter(); // Create the logical lines. - LineOne = create(&LVLine::setIsLineDebug); - LineTwo = create(&LVLine::setIsLineDebug); - LineThree = create(&LVLine::setIsLineDebug); + LineOne = createLine(); + EXPECT_NE(LineOne, nullptr); + LineOne->setIsLineDebug(); + + LineTwo = createLine(); + EXPECT_NE(LineTwo, nullptr); + LineTwo->setIsLineDebug(); + + LineThree = createLine(); + EXPECT_NE(LineThree, nullptr); + LineThree->setIsLineDebug(); } // Reference Reader: Target Reader: @@ -203,8 +249,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 @@ -24,17 +24,12 @@ 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); } @@ -129,33 +124,52 @@ EXPECT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(); + IntegerType = createType(); + EXPECT_NE(IntegerType, nullptr); // Create the logical scopes. - NestedScope = create(); - CompileUnit = create(); - Function = create(); + NestedScope = createScope(); + EXPECT_NE(NestedScope, nullptr); + CompileUnit = createScopeCompileUnit(); + EXPECT_NE(CompileUnit, nullptr); + Function = createScopeFunction(); + EXPECT_NE(Function, nullptr); // Create the logical symbols. - LocalVariable = create(); - NestedVariable = create(); - Parameter = create(); + LocalVariable = createSymbol(); + EXPECT_NE(LocalVariable, nullptr); + NestedVariable = createSymbol(); + EXPECT_NE(NestedVariable, 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(); - LocationThree = create(); - LocationFour = create(); - LocationFive = create(); - LocationSix = create(); + LocationOne = createLocation(); + EXPECT_NE(LocationOne, nullptr); + LocationTwo = createLocation(); + EXPECT_NE(LocationTwo, nullptr); + LocationThree = createLocation(); + EXPECT_NE(LocationThree, nullptr); + LocationFour = createLocation(); + EXPECT_NE(LocationFour, nullptr); + LocationFive = createLocation(); + EXPECT_NE(LocationFive, nullptr); + LocationSix = createLocation(); + EXPECT_NE(LocationSix, nullptr); } // Create the logical view adding the created logical elements. @@ -369,30 +383,46 @@ 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. Index: llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp @@ -60,11 +60,6 @@ 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 +106,68 @@ 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(); + IntegerType = createType(); + EXPECT_NE(IntegerType, nullptr); + UnsignedType = createType(); + EXPECT_NE(UnsignedType, nullptr); + GlobalType = createType(); + EXPECT_NE(GlobalType, nullptr); + LocalType = createType(); + EXPECT_NE(LocalType, nullptr); + NestedType = createType(); + EXPECT_NE(NestedType, nullptr); + EnumeratorOne = createTypeEnumerator(); + EXPECT_NE(EnumeratorOne, nullptr); + EnumeratorTwo = createTypeEnumerator(); + EXPECT_NE(EnumeratorTwo, nullptr); + TypeDefinitionOne = createTypeDefinition(); + EXPECT_NE(TypeDefinitionOne, nullptr); + TypeDefinitionTwo = createTypeDefinition(); + EXPECT_NE(TypeDefinitionTwo, nullptr); + TypeSubrange = createTypeSubrange(); + EXPECT_NE(TypeSubrange, nullptr); + TypeParam = createTypeParam(); + EXPECT_NE(TypeParam, nullptr); + TypeImport = createTypeImport(); + EXPECT_NE(TypeImport, nullptr); // Create the logical scopes. - NestedScope = create(); - Aggregate = create(); - Array = create(); - CompileUnit = create(); - Enumeration = create(); - Function = create(); - ClassFunction = create(); - InlinedFunction = create(); - Namespace = create(); + NestedScope = createScope(); + EXPECT_NE(NestedScope, nullptr); + Aggregate = createScopeAggregate(); + EXPECT_NE(Aggregate, nullptr); + Array = createScopeArray(); + EXPECT_NE(Array, nullptr); + CompileUnit = createScopeCompileUnit(); + EXPECT_NE(CompileUnit, nullptr); + Enumeration = createScopeEnumeration(); + EXPECT_NE(Enumeration, nullptr); + Function = createScopeFunction(); + EXPECT_NE(Function, nullptr); + ClassFunction = createScopeFunction(); + EXPECT_NE(ClassFunction, nullptr); + InlinedFunction = createScopeFunctionInlined(); + EXPECT_NE(InlinedFunction, nullptr); + Namespace = createScopeNamespace(); + EXPECT_NE(Namespace, nullptr); // Create the logical symbols. - GlobalVariable = create(); - LocalVariable = create(); - ClassMember = create(); - NestedVariable = create(); - Parameter = create(); + GlobalVariable = createSymbol(); + EXPECT_NE(GlobalVariable, nullptr); + LocalVariable = createSymbol(); + EXPECT_NE(LocalVariable, nullptr); + ClassMember = createSymbol(); + EXPECT_NE(ClassMember, nullptr); + NestedVariable = createSymbol(); + EXPECT_NE(NestedVariable, nullptr); + Parameter = createSymbol(); + EXPECT_NE(Parameter, nullptr); // Create the logical lines. - LocalLine = create(); - NestedLine = create(); + LocalLine = createLine(); + EXPECT_NE(LocalLine, nullptr); + NestedLine = createLine(); + EXPECT_NE(NestedLine, nullptr); } // Create the logical view adding the created logical elements. Index: llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp @@ -47,14 +47,6 @@ 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 +96,68 @@ EXPECT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(&LVType::setIsBase); + IntegerType = createType(); + EXPECT_NE(IntegerType, nullptr); + IntegerType->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); + CompileUnit = createScopeCompileUnit(); + EXPECT_NE(CompileUnit, nullptr); + CompileUnit->setIsCompileUnit(); + + Function = createScopeFunction(); + EXPECT_NE(Function, nullptr); + Function->setIsFunction(); + + NestedScope = createScope(); + EXPECT_NE(NestedScope, nullptr); + NestedScope->setIsLexicalBlock(); + + Namespace = createScopeNamespace(); + EXPECT_NE(Namespace, nullptr); + Namespace->setIsNamespace(); + + Aggregate = createScopeAggregate(); + EXPECT_NE(Aggregate, nullptr); + Aggregate->setIsAggregate(); // Create the logical symbols. - ClassMember = create(&LVSymbol::setIsMember); - LocalVariable = - create(&LVSymbol::setIsVariable); - NestedVariable = - create(&LVSymbol::setIsVariable); - Parameter = create(&LVSymbol::setIsParameter); + ClassMember = createSymbol(); + EXPECT_NE(ClassMember, nullptr); + ClassMember->setIsMember(); + + LocalVariable = createSymbol(); + EXPECT_NE(LocalVariable, nullptr); + LocalVariable->setIsVariable(); + + NestedVariable = createSymbol(); + EXPECT_NE(NestedVariable, nullptr); + NestedVariable->setIsVariable(); + + Parameter = createSymbol(); + EXPECT_NE(Parameter, nullptr); + Parameter->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); + LineOne = createLine(); + EXPECT_NE(LineOne, nullptr); + LineOne->setIsLineDebug(); + + LineTwo = createLine(); + EXPECT_NE(LineTwo, nullptr); + LineTwo->setIsBasicBlock(); + + LineThree = createLine(); + EXPECT_NE(LineThree, nullptr); + LineThree->setIsNewStatement(); + + LineFour = createLine(); + EXPECT_NE(LineFour, nullptr); + LineFour->setIsPrologueEnd(); + + LineFive = createLine(); + EXPECT_NE(LineFive, nullptr); + LineFive->setIsLineAssembler(); } // Create the logical view adding the created logical elements. Index: llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp =================================================================== --- llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp +++ llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp @@ -22,7 +22,10 @@ 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 @@ -87,18 +90,24 @@ MyLocation *LocationFive = nullptr; MyLocation *LocationSix = nullptr; +#define CUSTOM_ALLOCATOR(KIND) \ + llvm::SpecificBumpPtrAllocator Allocated##KIND; + + CUSTOM_ALLOCATOR(Location) + protected: - void add(LVScope *Parent, LVElement *Element); - template T *create() { - T *Element = new (std::nothrow) T(); - EXPECT_NE(Element, nullptr); - return Element; +#define CREATE_CUSTOM(KIND) \ + My##KIND *createCustom##KIND() { \ + return new (Allocated##KIND.Allocate()) My##KIND(); \ } + CREATE_CUSTOM(Location) + + 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 +124,6 @@ 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 +217,52 @@ EXPECT_NE(Root, nullptr); // Create the logical types. - IntegerType = create(); + IntegerType = createType(); + EXPECT_NE(IntegerType, nullptr); // Create the logical scopes. - NestedScope = create(); - CompileUnit = create(); - Function = create(); + NestedScope = createScope(); + EXPECT_NE(NestedScope, nullptr); + CompileUnit = createScopeCompileUnit(); + EXPECT_NE(CompileUnit, nullptr); + Function = createScopeFunction(); + EXPECT_NE(Function, nullptr); // Create the logical symbols. - LocalVariable = create(); - NestedVariable = create(); - Parameter = create(); + LocalVariable = createSymbol(); + EXPECT_NE(LocalVariable, nullptr); + NestedVariable = createSymbol(); + EXPECT_NE(NestedVariable, 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(); - LocationThree = create(); - LocationFour = create(); - LocationFive = create(); - LocationSix = create(); + LocationOne = createCustomLocation(); + EXPECT_NE(LocationOne, nullptr); + LocationTwo = createCustomLocation(); + EXPECT_NE(LocationTwo, nullptr); + LocationThree = createCustomLocation(); + EXPECT_NE(LocationThree, nullptr); + LocationFour = createCustomLocation(); + EXPECT_NE(LocationFour, nullptr); + LocationFive = createCustomLocation(); + EXPECT_NE(LocationFive, nullptr); + LocationSix = createCustomLocation(); + EXPECT_NE(LocationSix, nullptr); } // Create the logical view adding the created logical elements. @@ -450,7 +473,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 +482,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 +510,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 +524,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());