[llvm] 7fbcc24 - [llvm-debuginfo-analyzer] (08a/09) - Memory Management

Carlos Alberto Enciso via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 16 02:31:59 PST 2023


Author: Carlos Alberto Enciso
Date: 2023-02-16T10:15:19Z
New Revision: 7fbcc24409efdb37cec79ad461ef383f6ffc5ef2

URL: https://github.com/llvm/llvm-project/commit/7fbcc24409efdb37cec79ad461ef383f6ffc5ef2
DIFF: https://github.com/llvm/llvm-project/commit/7fbcc24409efdb37cec79ad461ef383f6ffc5ef2.diff

LOG: [llvm-debuginfo-analyzer] (08a/09) - Memory Management

llvm-debuginfo-analyzer is a command line tool that processes debug
info contained in a binary file and produces a debug information
format agnostic “Logical View”, which is a high-level semantic
representation of the debug info, independent of the low-level
format.

The code has been divided into the following patches:

1) Interval tree
2) Driver and documentation
3) Logical elements
4) Locations and ranges
5) Select elements
6) Warning and internal options
7) Compare elements
8) ELF Reader
8a) Memory Management
9) CodeView Reader

Full details:

https://discourse.llvm.org/t/llvm-dev-rfc-llvm-dva-debug-information-visual-analyzer/62570

This patch:

This is a high level summary of the changes in this patch.

Memory Management
- Use Bump allocators for memory management.

As the logical elements are only allocated in one pass (debuginfo
parsing) and they are never manipulated/created/destroyed later,
use the SpecificBumpPtrAllocator for the memory management.

Reviewed By: dblaikie, Orlando

Differential Revision: https://reviews.llvm.org/D137933

Added: 
    

Modified: 
    llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
    llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
    llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
    llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
    llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
    llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
    llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h
    llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
    llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp
    llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
    llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp
    llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
    llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp
    llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
    llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp
    llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp
    llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp
    llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp
    llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp
    llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp
    llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
index 94edd83be336b..dc1df9f27a6c4 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
@@ -172,7 +172,7 @@ class LVLocation : public LVObject {
 
 class LVLocationSymbol final : public LVLocation {
   // Location descriptors for the active range.
-  LVAutoOperations *Entries = nullptr;
+  std::unique_ptr<LVOperations> Entries;
 
   void updateKind() override;
 
@@ -180,7 +180,7 @@ class LVLocationSymbol final : public LVLocation {
   LVLocationSymbol() : LVLocation() {}
   LVLocationSymbol(const LVLocationSymbol &) = delete;
   LVLocationSymbol &operator=(const LVLocationSymbol &) = delete;
-  ~LVLocationSymbol() { delete Entries; };
+  ~LVLocationSymbol() = default;
 
   void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset,
                  uint64_t LocDescOffset) override;

diff  --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
index a097372bccfd0..ca429d2c28932 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
@@ -74,21 +74,6 @@ using LVSymbolGetFunction = bool (LVSymbol::*)() const;
 using LVTypeSetFunction = void (LVType::*)();
 using LVTypeGetFunction = bool (LVType::*)() const;
 
-// The LVScope class represents a logical scope and uses vectors to store its
-// children, which are pointers to other allocated logical elements (types,
-// symbols, lines, scopes, ranges). On destruction, we have to traverse each
-// vector and destroy its elements. The other case is LVSymbol.
-// These definitions are intended to be used by the LVScope and LVSymbol
-// to support automatic vector cleanup.
-using LVAutoLines = LVAutoSmallVector<LVLine *>;
-using LVAutoLocations = LVAutoSmallVector<LVLocation *>;
-using LVAutoOperations = LVAutoSmallVector<LVOperation *, 8>;
-using LVAutoScopes = LVAutoSmallVector<LVScope *>;
-using LVAutoSymbols = LVAutoSmallVector<LVSymbol *>;
-using LVAutoTypes = LVAutoSmallVector<LVType *>;
-
-// These definitions are intended to be used when the vector will be used
-// just a container, with no automatic destruction.
 using LVElements = SmallVector<LVElement *, 8>;
 using LVLines = SmallVector<LVLine *, 8>;
 using LVLocations = SmallVector<LVLocation *, 8>;

diff  --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
index ed1807ce8bf8c..ff1a41cdf3e5c 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
@@ -54,6 +54,9 @@ class LVSplitContext final {
   raw_fd_ostream &os() { return OutputFile->os(); }
 };
 
+/// The logical reader owns of all the logical elements created during
+/// the debug information parsing. For its creation it uses a specific
+///  bump allocator for each type of logical element.
 class LVReader {
   LVBinaryType BinaryType;
 
@@ -74,6 +77,50 @@ class LVReader {
   Error createSplitFolder();
   bool OutputSplit = false;
 
+// Define a specific bump allocator for the given KIND.
+#define LV_OBJECT_ALLOCATOR(KIND)                                              \
+  llvm::SpecificBumpPtrAllocator<LV##KIND> Allocated##KIND;
+
+  // Lines allocator.
+  LV_OBJECT_ALLOCATOR(Line)
+  LV_OBJECT_ALLOCATOR(LineDebug)
+  LV_OBJECT_ALLOCATOR(LineAssembler)
+
+  // Locations allocator.
+  LV_OBJECT_ALLOCATOR(Location)
+  LV_OBJECT_ALLOCATOR(LocationSymbol)
+
+  // Operations allocator.
+  LV_OBJECT_ALLOCATOR(Operation)
+
+  // Scopes allocator.
+  LV_OBJECT_ALLOCATOR(Scope)
+  LV_OBJECT_ALLOCATOR(ScopeAggregate)
+  LV_OBJECT_ALLOCATOR(ScopeAlias)
+  LV_OBJECT_ALLOCATOR(ScopeArray)
+  LV_OBJECT_ALLOCATOR(ScopeCompileUnit)
+  LV_OBJECT_ALLOCATOR(ScopeEnumeration)
+  LV_OBJECT_ALLOCATOR(ScopeFormalPack)
+  LV_OBJECT_ALLOCATOR(ScopeFunction)
+  LV_OBJECT_ALLOCATOR(ScopeFunctionInlined)
+  LV_OBJECT_ALLOCATOR(ScopeFunctionType)
+  LV_OBJECT_ALLOCATOR(ScopeNamespace)
+  LV_OBJECT_ALLOCATOR(ScopeRoot)
+  LV_OBJECT_ALLOCATOR(ScopeTemplatePack)
+
+  // Symbols allocator.
+  LV_OBJECT_ALLOCATOR(Symbol)
+
+  // Types allocator.
+  LV_OBJECT_ALLOCATOR(Type)
+  LV_OBJECT_ALLOCATOR(TypeDefinition)
+  LV_OBJECT_ALLOCATOR(TypeEnumerator)
+  LV_OBJECT_ALLOCATOR(TypeImport)
+  LV_OBJECT_ALLOCATOR(TypeParam)
+  LV_OBJECT_ALLOCATOR(TypeSubrange)
+
+#undef LV_OBJECT_ALLOCATOR
+
 protected:
   LVScopeRoot *Root = nullptr;
   std::string InputFilename;
@@ -92,7 +139,7 @@ class LVReader {
 
   // Create the Scope Root.
   virtual Error createScopes() {
-    Root = new LVScopeRoot();
+    Root = createScopeRoot();
     Root->setName(getFilename());
     if (options().getAttributeFormat())
       Root->setFileFormatName(FileFormatName);
@@ -129,9 +176,62 @@ class LVReader {
         OS(W.getOStream()) {}
   LVReader(const LVReader &) = delete;
   LVReader &operator=(const LVReader &) = delete;
-  virtual ~LVReader() {
-    if (Root)
-      delete Root;
+  virtual ~LVReader() = default;
+
+// Creates a logical object of the given KIND. The signature for the created
+// functions looks like:
+//   ...
+//   LVScope *createScope()
+//   LVScopeRoot *creatScopeRoot()
+//   LVType *createType();
+//   ...
+#define LV_CREATE_OBJECT(KIND)                                                 \
+  LV##KIND *create##KIND() {                                                   \
+    return new (Allocated##KIND.Allocate()) LV##KIND();                        \
+  }
+
+  // Lines creation.
+  LV_CREATE_OBJECT(Line)
+  LV_CREATE_OBJECT(LineDebug)
+  LV_CREATE_OBJECT(LineAssembler)
+
+  // Locations creation.
+  LV_CREATE_OBJECT(Location)
+  LV_CREATE_OBJECT(LocationSymbol)
+
+  // Scopes creation.
+  LV_CREATE_OBJECT(Scope)
+  LV_CREATE_OBJECT(ScopeAggregate)
+  LV_CREATE_OBJECT(ScopeAlias)
+  LV_CREATE_OBJECT(ScopeArray)
+  LV_CREATE_OBJECT(ScopeCompileUnit)
+  LV_CREATE_OBJECT(ScopeEnumeration)
+  LV_CREATE_OBJECT(ScopeFormalPack)
+  LV_CREATE_OBJECT(ScopeFunction)
+  LV_CREATE_OBJECT(ScopeFunctionInlined)
+  LV_CREATE_OBJECT(ScopeFunctionType)
+  LV_CREATE_OBJECT(ScopeNamespace)
+  LV_CREATE_OBJECT(ScopeRoot)
+  LV_CREATE_OBJECT(ScopeTemplatePack)
+
+  // Symbols creation.
+  LV_CREATE_OBJECT(Symbol)
+
+  // Types creation.
+  LV_CREATE_OBJECT(Type)
+  LV_CREATE_OBJECT(TypeDefinition)
+  LV_CREATE_OBJECT(TypeEnumerator)
+  LV_CREATE_OBJECT(TypeImport)
+  LV_CREATE_OBJECT(TypeParam)
+  LV_CREATE_OBJECT(TypeSubrange)
+
+#undef LV_CREATE_OBJECT
+
+  // Operations creation.
+  LVOperation *createOperation(LVSmall OpCode, LVUnsigned Operand1,
+                               LVUnsigned Operand2) {
+    return new (AllocatedOperation.Allocate())
+        LVOperation(OpCode, Operand1, Operand2);
   }
 
   StringRef getFilename(LVObject *Object, size_t Index) const;

diff  --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index 8204163f34de6..4368e9334387b 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -63,12 +63,11 @@ using LVScopeKindSet = std::set<LVScopeKind>;
 using LVScopeDispatch = std::map<LVScopeKind, LVScopeGetFunction>;
 using LVScopeRequest = std::vector<LVScopeGetFunction>;
 
-using LVOffsetList = std::list<LVOffset>;
 using LVOffsetElementMap = std::map<LVOffset, LVElement *>;
-using LVOffsetLinesMap = std::map<LVOffset, LVLines *>;
-using LVOffsetLocationsMap = std::map<LVOffset, LVLocations *>;
+using LVOffsetLinesMap = std::map<LVOffset, LVLines>;
+using LVOffsetLocationsMap = std::map<LVOffset, LVLocations>;
 using LVOffsetSymbolMap = std::map<LVOffset, LVSymbol *>;
-using LVTagOffsetsMap = std::map<dwarf::Tag, LVOffsetList *>;
+using LVTagOffsetsMap = std::map<dwarf::Tag, LVOffsets>;
 
 // Class to represent a DWARF Scope.
 class LVScope : public LVElement {
@@ -100,7 +99,8 @@ class LVScope : public LVElement {
   // Calculate coverage factor.
   void calculateCoverage() {
     float CoveragePercentage = 0;
-    LVLocation::calculateCoverage(Ranges, CoverageFactor, CoveragePercentage);
+    LVLocation::calculateCoverage(Ranges.get(), CoverageFactor,
+                                  CoveragePercentage);
   }
 
   // Decide if the scope will be printed, using some conditions given by:
@@ -117,11 +117,11 @@ class LVScope : public LVElement {
 
 protected:
   // Types, Symbols, Scopes, Lines, Locations in this scope.
-  LVAutoTypes *Types = nullptr;
-  LVAutoSymbols *Symbols = nullptr;
-  LVAutoScopes *Scopes = nullptr;
-  LVAutoLines *Lines = nullptr;
-  LVAutoLocations *Ranges = nullptr;
+  std::unique_ptr<LVTypes> Types;
+  std::unique_ptr<LVSymbols> Symbols;
+  std::unique_ptr<LVScopes> Scopes;
+  std::unique_ptr<LVLines> Lines;
+  std::unique_ptr<LVLocations> Ranges;
 
   // Vector of elements (types, scopes and symbols).
   // It is the union of (*Types, *Symbols and *Scopes) to be used for
@@ -129,7 +129,7 @@ class LVScope : public LVElement {
   // - Preserve the order the logical elements are read in.
   // - To have a single container with all the logical elements, when
   //   the traversal does not require any specific element kind.
-  LVElements *Children = nullptr;
+  std::unique_ptr<LVElements> Children;
 
   // Resolve the template parameters/arguments relationship.
   void resolveTemplate();
@@ -150,7 +150,7 @@ class LVScope : public LVElement {
   }
   LVScope(const LVScope &) = delete;
   LVScope &operator=(const LVScope &) = delete;
-  virtual ~LVScope();
+  virtual ~LVScope() = default;
 
   static bool classof(const LVElement *Element) {
     return Element->getSubclassID() == LVSubclassID::LV_SCOPE;
@@ -202,12 +202,12 @@ class LVScope : public LVElement {
   const char *kind() const override;
 
   // Get the specific children.
-  const LVLines *getLines() const { return Lines; }
-  const LVLocations *getRanges() const { return Ranges; }
-  const LVScopes *getScopes() const { return Scopes; }
-  const LVSymbols *getSymbols() const { return Symbols; }
-  const LVTypes *getTypes() const { return Types; }
-  const LVElements *getChildren() const { return Children; }
+  const LVLines *getLines() const { return Lines.get(); }
+  const LVLocations *getRanges() const { return Ranges.get(); }
+  const LVScopes *getScopes() const { return Scopes.get(); }
+  const LVSymbols *getSymbols() const { return Symbols.get(); }
+  const LVTypes *getTypes() const { return Types.get(); }
+  const LVElements *getChildren() const { return Children.get(); }
 
   void addElement(LVElement *Element);
   void addElement(LVLine *Line);
@@ -456,8 +456,8 @@ class LVScopeCompileUnit final : public LVScope {
                                  LVOffsetLocationsMap *Map) {
     LVOffset Offset = Element->getOffset();
     addInvalidOffset(Offset, Element);
-    addItem<LVOffsetLocationsMap, LVLocations, LVOffset, LVLocation *>(
-        Map, Offset, Location);
+    addItem<LVOffsetLocationsMap, LVOffset, LVLocation *>(Map, Offset,
+                                                          Location);
   }
 
   // Record scope sizes indexed by lexical level.
@@ -489,12 +489,7 @@ class LVScopeCompileUnit final : public LVScope {
   }
   LVScopeCompileUnit(const LVScopeCompileUnit &) = delete;
   LVScopeCompileUnit &operator=(const LVScopeCompileUnit &) = delete;
-  ~LVScopeCompileUnit() {
-    deleteList<LVTagOffsetsMap>(DebugTags);
-    deleteList<LVOffsetLocationsMap>(InvalidLocations);
-    deleteList<LVOffsetLocationsMap>(InvalidRanges);
-    deleteList<LVOffsetLinesMap>(LinesZero);
-  }
+  ~LVScopeCompileUnit() = default;
 
   LVScope *getCompileUnitParent() const override {
     return static_cast<LVScope *>(const_cast<LVScopeCompileUnit *>(this));

diff  --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
index a2274ec1a62f7..d65ac641afbe5 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h
@@ -31,25 +31,6 @@ namespace logicalview {
 // Returns the unique string pool instance.
 LVStringPool &getStringPool();
 
-template <typename T>
-using TypeIsValid = std::bool_constant<std::is_pointer<T>::value>;
-
-// Utility class to help memory management and perform an automatic cleaning.
-template <typename T, unsigned N = 8>
-class LVAutoSmallVector : public SmallVector<T, N> {
-  static_assert(TypeIsValid<T>::value, "T must be a pointer type");
-
-public:
-  using iterator = typename SmallVector<T, N>::iterator;
-  LVAutoSmallVector() : SmallVector<T, N>::SmallVector() {}
-
-  ~LVAutoSmallVector() {
-    // Destroy the constructed elements in the vector.
-    for (auto *Item : *this)
-      delete Item;
-  }
-};
-
 // Used to record specific characteristics about the objects.
 template <typename T> class LVProperties {
   SmallBitVector Bits = SmallBitVector(static_cast<unsigned>(T::LastEntry) + 1);
@@ -147,25 +128,10 @@ std::string formatAttributes(const StringRef First, Args... Others) {
   return Stream.str();
 }
 
-// Add an item to a map with second being a list.
-template <typename MapType, typename ListType, typename KeyType,
-          typename ValueType>
+// Add an item to a map with second being a small vector.
+template <typename MapType, typename KeyType, typename ValueType>
 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 <typename MapType> void deleteList(MapType &Map) {
-  for (typename MapType::const_reference Entry : Map)
-    delete Entry.second;
+  (*Map)[Key].push_back(Value);
 }
 
 // Double map data structure.
@@ -174,33 +140,26 @@ class LVDoubleMap {
   static_assert(std::is_pointer<ValueType>::value,
                 "ValueType must be a pointer.");
   using LVSecondMapType = std::map<SecondKeyType, ValueType>;
-  using LVFirstMapType = std::map<FirstKeyType, LVSecondMapType *>;
+  using LVFirstMapType =
+      std::map<FirstKeyType, std::unique_ptr<LVSecondMapType>>;
   using LVAuxMapType = std::map<SecondKeyType, FirstKeyType>;
   using LVValueTypes = std::vector<ValueType>;
   LVFirstMapType FirstMap;
   LVAuxMapType AuxMap;
 
 public:
-  LVDoubleMap() = default;
-  ~LVDoubleMap() {
-    for (auto &Entry : FirstMap)
-      delete Entry.second;
-  }
-
   void add(FirstKeyType FirstKey, SecondKeyType SecondKey, ValueType Value) {
-    LVSecondMapType *SecondMap = nullptr;
     typename LVFirstMapType::iterator FirstIter = FirstMap.find(FirstKey);
     if (FirstIter == FirstMap.end()) {
-      SecondMap = new LVSecondMapType();
-      FirstMap.emplace(FirstKey, SecondMap);
+      auto SecondMapSP = std::make_unique<LVSecondMapType>();
+      SecondMapSP->emplace(SecondKey, Value);
+      FirstMap.emplace(FirstKey, std::move(SecondMapSP));
     } else {
-      SecondMap = FirstIter->second;
+      LVSecondMapType *SecondMap = FirstIter->second.get();
+      if (SecondMap->find(SecondKey) == SecondMap->end())
+        SecondMap->emplace(SecondKey, Value);
     }
 
-    assert(SecondMap && "SecondMap is null.");
-    if (SecondMap && SecondMap->find(SecondKey) == SecondMap->end())
-      SecondMap->emplace(SecondKey, Value);
-
     typename LVAuxMapType::iterator AuxIter = AuxMap.find(SecondKey);
     if (AuxIter == AuxMap.end()) {
       AuxMap.emplace(SecondKey, FirstKey);
@@ -212,8 +171,7 @@ class LVDoubleMap {
     if (FirstIter == FirstMap.end())
       return nullptr;
 
-    LVSecondMapType *SecondMap = FirstIter->second;
-    return SecondMap;
+    return FirstIter->second.get();
   }
 
   ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const {
@@ -239,8 +197,8 @@ class LVDoubleMap {
     if (FirstMap.empty())
       return Values;
     for (typename LVFirstMapType::const_reference FirstEntry : FirstMap) {
-      LVSecondMapType *SecondMap = FirstEntry.second;
-      for (typename LVSecondMapType::const_reference SecondEntry : *SecondMap)
+      LVSecondMapType &SecondMap = *FirstEntry.second;
+      for (typename LVSecondMapType::const_reference SecondEntry : SecondMap)
         Values.push_back(SecondEntry.second);
     }
     return Values;

diff  --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
index b9628e3127849..4b2a910c88f1c 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
@@ -46,7 +46,7 @@ class LVSymbol final : public LVElement {
 
   // Reference to DW_AT_specification, DW_AT_abstract_origin attribute.
   LVSymbol *Reference = nullptr;
-  LVAutoLocations *Locations = nullptr;
+  std::unique_ptr<LVLocations> Locations;
   LVLocation *CurrentLocation = nullptr;
 
   // Bitfields length.
@@ -60,8 +60,8 @@ class LVSymbol final : public LVElement {
   float CoveragePercentage = 0;
 
   // Add a location gap into the location list.
-  LVAutoLocations::iterator addLocationGap(LVAutoLocations::iterator Pos,
-                                           LVAddress LowPC, LVAddress HighPC);
+  LVLocations::iterator addLocationGap(LVLocations::iterator Pos,
+                                       LVAddress LowPC, LVAddress HighPC);
 
   // Find the current symbol in the given 'Targets'.
   LVSymbol *findIn(const LVSymbols *Targets) const;
@@ -73,7 +73,7 @@ class LVSymbol final : public LVElement {
   }
   LVSymbol(const LVSymbol &) = delete;
   LVSymbol &operator=(const LVSymbol &) = delete;
-  ~LVSymbol() { delete Locations; }
+  ~LVSymbol() = default;
 
   static bool classof(const LVElement *Element) {
     return Element->getSubclassID() == LVSubclassID::LV_SYMBOL;

diff  --git a/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h b/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h
index 3030e9f24ed82..9f5e80747bf5e 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h
@@ -27,7 +27,7 @@
 namespace llvm {
 namespace logicalview {
 
-using LVReaders = std::vector<LVReader *>;
+using LVReaders = std::vector<std::unique_ptr<LVReader>>;
 using ArgVector = std::vector<std::string>;
 using PdbOrObj = PointerUnion<object::ObjectFile *, pdb::PDBFile *>;
 
@@ -45,7 +45,6 @@ class LVReaderHandler {
   LVReaders TheReaders;
 
   Error createReaders();
-  void destroyReaders();
   Error printReaders();
   Error compareReaders();
 
@@ -72,20 +71,18 @@ class LVReaderHandler {
   }
   LVReaderHandler(const LVReaderHandler &) = delete;
   LVReaderHandler &operator=(const LVReaderHandler &) = delete;
-  ~LVReaderHandler() { destroyReaders(); }
 
   Error createReader(StringRef Filename, LVReaders &Readers) {
     return handleFile(Readers, Filename);
   }
   Error process();
 
-  Expected<LVReader *> createReader(StringRef Pathname) {
+  Expected<std::unique_ptr<LVReader>> createReader(StringRef Pathname) {
     LVReaders Readers;
     if (Error Err = createReader(Pathname, Readers))
       return std::move(Err);
-    return Readers[0];
+    return std::move(Readers[0]);
   }
-  void deleteReader(LVReader *Reader) { delete Reader; }
 
   void print(raw_ostream &OS) const;
 

diff  --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
index 8c3cce9286a33..4b2dc666733ee 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h
@@ -89,7 +89,7 @@ class LVBinaryReader : public LVReader {
   // Scopes with ranges for current compile unit. It is used to find a line
   // giving its exact or closest address. To support comdat functions, all
   // addresses for the same section are recorded in the same map.
-  using LVSectionRanges = std::map<LVSectionIndex, LVRange *>;
+  using LVSectionRanges = std::map<LVSectionIndex, std::unique_ptr<LVRange>>;
   LVSectionRanges SectionRanges;
 
   // Image base and virtual address for Executable file.
@@ -100,6 +100,8 @@ class LVBinaryReader : public LVReader {
   using LVSections = std::map<LVSectionIndex, object::SectionRef>;
   LVSections Sections;
 
+  std::vector<std::unique_ptr<LVLines>> DiscoveredLines;
+
 protected:
   // It contains the LVLineDebug elements representing the logical lines for
   // the current compile unit, created by parsing the debug line section.
@@ -149,7 +151,7 @@ class LVBinaryReader : public LVReader {
       : LVReader(Filename, FileFormatName, W, BinaryType) {}
   LVBinaryReader(const LVBinaryReader &) = delete;
   LVBinaryReader &operator=(const LVBinaryReader &) = delete;
-  virtual ~LVBinaryReader();
+  virtual ~LVBinaryReader() = default;
 
   void addToSymbolTable(StringRef Name, LVScope *Function,
                         LVSectionIndex SectionIndex = 0);

diff  --git a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp
index 115b903c6c7f9..e11e56cd59760 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp
@@ -579,8 +579,8 @@ void LVLocationSymbol::addObject(LVAddress LowPC, LVAddress HighPC,
 void LVLocationSymbol::addObject(LVSmall Opcode, LVUnsigned Operand1,
                                  LVUnsigned Operand2) {
   if (!Entries)
-    Entries = new LVAutoOperations();
-  Entries->emplace_back(new LVOperation(Opcode, Operand1, Operand2));
+    Entries = std::make_unique<LVOperations>();
+  Entries->push_back(getReader().createOperation(Opcode, Operand1, Operand2));
 }
 
 // Based on the DWARF attribute, define the location kind.
@@ -606,8 +606,7 @@ void LVLocation::setKind() {
 void LVLocationSymbol::updateKind() {
   // Update the location type for simple ones.
   if (Entries && Entries->size() == 1) {
-    LVOperation *Operation = Entries->front();
-    if (dwarf::DW_OP_fbreg == Operation->getOpcode())
+    if (dwarf::DW_OP_fbreg == Entries->front()->getOpcode())
       setIsStackOffset();
   }
 }

diff  --git a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
index fb503f3d3e7e2..2fc97ccb6690b 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
@@ -45,15 +45,6 @@ const char *const KindUnion = "Union";
 //===----------------------------------------------------------------------===//
 // DWARF lexical block, such as: namespace, function, compile unit, module, etc.
 //===----------------------------------------------------------------------===//
-LVScope::~LVScope() {
-  delete Types;
-  delete Symbols;
-  delete Scopes;
-  delete Lines;
-  delete Ranges;
-  delete Children;
-}
-
 // Return a string representation for the scope kind.
 const char *LVScope::kind() const {
   const char *Kind = KindUndefined;
@@ -114,7 +105,7 @@ LVScopeDispatch LVScope::Dispatch = {
 
 void LVScope::addToChildren(LVElement *Element) {
   if (!Children)
-    Children = new LVElements();
+    Children = std::make_unique<LVElements>();
   Children->push_back(Element);
 }
 
@@ -137,7 +128,7 @@ void LVScope::addElement(LVLine *Line) {
   assert(Line && "Invalid line.");
   assert(!Line->getParent() && "Line already inserted");
   if (!Lines)
-    Lines = new LVAutoLines();
+    Lines = std::make_unique<LVLines>();
 
   // Add it to parent.
   Lines->push_back(Line);
@@ -161,7 +152,7 @@ void LVScope::addObject(LVLocation *Location) {
   assert(Location && "Invalid location.");
   assert(!Location->getParent() && "Location already inserted");
   if (!Ranges)
-    Ranges = new LVAutoLocations();
+    Ranges = std::make_unique<LVLocations>();
 
   // Add it to parent.
   Location->setParent(this);
@@ -176,7 +167,7 @@ void LVScope::addElement(LVScope *Scope) {
   assert(Scope && "Invalid scope.");
   assert(!Scope->getParent() && "Scope already inserted");
   if (!Scopes)
-    Scopes = new LVAutoScopes();
+    Scopes = std::make_unique<LVScopes>();
 
   // Add it to parent.
   Scopes->push_back(Scope);
@@ -203,7 +194,7 @@ void LVScope::addElement(LVSymbol *Symbol) {
   assert(Symbol && "Invalid symbol.");
   assert(!Symbol->getParent() && "Symbol already inserted");
   if (!Symbols)
-    Symbols = new LVAutoSymbols();
+    Symbols = std::make_unique<LVSymbols>();
 
   // Add it to parent.
   Symbols->push_back(Symbol);
@@ -230,7 +221,7 @@ void LVScope::addElement(LVType *Type) {
   assert(Type && "Invalid type.");
   assert(!Type->getParent() && "Type already inserted");
   if (!Types)
-    Types = new LVAutoTypes();
+    Types = std::make_unique<LVTypes>();
 
   // Add it to parent.
   Types->push_back(Type);
@@ -255,7 +246,7 @@ void LVScope::addElement(LVType *Type) {
 // Add a pair of ranges.
 void LVScope::addObject(LVAddress LowerAddress, LVAddress UpperAddress) {
   // Pack the ranges into a Location object.
-  LVLocation *Location = new LVLocation();
+  LVLocation *Location = getReader().createLocation();
   Location->setLowerAddress(LowerAddress);
   Location->setUpperAddress(UpperAddress);
   Location->setIsAddressRange();
@@ -341,7 +332,7 @@ void LVScope::addMissingElements(LVScope *Reference) {
       // information that is incorrect for the element to be inserted.
       // As the symbol being added does not exist in the debug section,
       // use its parent scope offset, to indicate its DIE location.
-      LVSymbol *Symbol = new LVSymbol();
+      LVSymbol *Symbol = getReader().createSymbol();
       addElement(Symbol);
       Symbol->setOffset(getOffset());
       Symbol->setIsOptimized();
@@ -690,7 +681,7 @@ void LVScope::sort() {
   if (SortFunction) {
     std::function<void(LVScope * Parent, LVSortFunction SortFunction)> Sort =
         [&](LVScope *Parent, LVSortFunction SortFunction) {
-          auto Traverse = [&](auto *Set, LVSortFunction SortFunction) {
+          auto Traverse = [&](auto &Set, LVSortFunction SortFunction) {
             if (Set)
               std::stable_sort(Set->begin(), Set->end(), SortFunction);
           };
@@ -877,7 +868,7 @@ bool LVScope::equalNumberOfChildren(const LVScope *Scope) const {
 }
 
 void LVScope::markMissingParents(const LVScope *Target, bool TraverseChildren) {
-  auto SetCompareState = [&](auto *Container) {
+  auto SetCompareState = [&](auto &Container) {
     if (Container)
       for (auto *Entry : *Container)
         Entry->setIsInCompare();
@@ -1356,8 +1347,7 @@ void LVScopeCompileUnit::addedElement(LVType *Type) {
 
 // Record unsuported DWARF tags.
 void LVScopeCompileUnit::addDebugTag(dwarf::Tag Target, LVOffset Offset) {
-  addItem<LVTagOffsetsMap, LVOffsetList, dwarf::Tag, LVOffset>(&DebugTags,
-                                                               Target, Offset);
+  addItem<LVTagOffsetsMap, dwarf::Tag, LVOffset>(&DebugTags, Target, Offset);
 }
 
 // Record elements with invalid offsets.
@@ -1390,8 +1380,7 @@ void LVScopeCompileUnit::addLineZero(LVLine *Line) {
   LVScope *Scope = Line->getParentScope();
   LVOffset Offset = Scope->getOffset();
   addInvalidOffset(Offset, Scope);
-  addItem<LVOffsetLinesMap, LVLines, LVOffset, LVLine *>(&LinesZero, Offset,
-                                                         Line);
+  addItem<LVOffsetLinesMap, LVOffset, LVLine *>(&LinesZero, Offset, Line);
 }
 
 void LVScopeCompileUnit::printLocalNames(raw_ostream &OS, bool Full) const {
@@ -1481,7 +1470,7 @@ void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const {
     PrintHeader(Header);
     for (LVOffsetLocationsMap::const_reference Entry : Map) {
       PrintElement(WarningOffsets, Entry.first);
-      for (const LVLocation *Location : *Entry.second)
+      for (const LVLocation *Location : Entry.second)
         OS << hexSquareString(Location->getOffset()) << " "
            << Location->getIntervalInfo() << "\n";
     }
@@ -1494,7 +1483,7 @@ void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const {
       OS << format("\n0x%02x", (unsigned)Entry.first) << ", "
          << dwarf::TagString(Entry.first) << "\n";
       unsigned Count = 0;
-      for (const LVOffset &Offset : *Entry.second)
+      for (const LVOffset &Offset : Entry.second)
         PrintOffset(Count, Offset);
       OS << "\n";
     }
@@ -1519,7 +1508,7 @@ void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const {
     for (LVOffsetLinesMap::const_reference Entry : LinesZero) {
       PrintElement(WarningOffsets, Entry.first);
       unsigned Count = 0;
-      for (const LVLine *Line : *Entry.second)
+      for (const LVLine *Line : Entry.second)
         PrintOffset(Count, Line->getOffset());
       OS << "\n";
     }

diff  --git a/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp
index 82633fbc6b2e8..7e86a2f4c1b8a 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp
@@ -66,10 +66,10 @@ void LVSymbol::addLocation(dwarf::Attribute Attr, LVAddress LowPC,
                            LVAddress HighPC, LVUnsigned SectionOffset,
                            uint64_t LocDescOffset, bool CallSiteLocation) {
   if (!Locations)
-    Locations = new LVAutoLocations();
+    Locations = std::make_unique<LVLocations>();
 
   // Create the location entry.
-  CurrentLocation = new LVLocationSymbol();
+  CurrentLocation = getReader().createLocationSymbol();
   CurrentLocation->setParent(this);
   CurrentLocation->setAttr(Attr);
   if (CallSiteLocation)
@@ -105,7 +105,7 @@ LVLocations::iterator LVSymbol::addLocationGap(LVLocations::iterator Pos,
                                                LVAddress LowPC,
                                                LVAddress HighPC) {
   // Create a location entry for the gap.
-  LVLocation *Gap = new LVLocationSymbol();
+  LVLocation *Gap = getReader().createLocationSymbol();
   Gap->setParent(this);
   Gap->setAttr(dwarf::DW_AT_location);
   Gap->addObject(LowPC, HighPC,
@@ -190,7 +190,7 @@ void LVSymbol::getLocations(LVLocations &LocationList) const {
 
 // Calculate coverage factor.
 void LVSymbol::calculateCoverage() {
-  if (!LVLocation::calculateCoverage(Locations, CoverageFactor,
+  if (!LVLocation::calculateCoverage(Locations.get(), CoverageFactor,
                                      CoveragePercentage)) {
     LVScope *Parent = getParentScope();
     if (Parent->getIsInlinedFunction()) {
@@ -444,6 +444,6 @@ void LVSymbol::printExtra(raw_ostream &OS, bool Full) const {
       Reference->printReference(OS, Full, const_cast<LVSymbol *>(this));
 
     // Print location information.
-    LVLocation::print(Locations, OS, Full);
+    LVLocation::print(Locations.get(), OS, Full);
   }
 }

diff  --git a/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
index 3d32c34ee02a3..de71e0904dbbc 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
@@ -253,16 +253,10 @@ void LVType::getParameters(const LVTypes *Types, LVTypes *TypesParam,
     if (!Type->getIsTemplateParam())
       continue;
     if (options().getAttributeArgument()) {
-      LVScope *Scope = nullptr;
       if (Type->getIsKindType())
-        Type = Type->getTypeAsType();
-      else {
-        if (Type->getIsKindScope()) {
-          Scope = Type->getTypeAsScope();
-          Type = nullptr;
-        }
-      }
-      Type ? TypesParam->push_back(Type) : ScopesParam->push_back(Scope);
+        TypesParam->push_back(Type->getTypeAsType());
+      else if (Type->getIsKindScope())
+        ScopesParam->push_back(Type->getTypeAsScope());
     } else
       TypesParam->push_back(Type);
   }

diff  --git a/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp b/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp
index 35dc30fd601fc..65633f2495f42 100644
--- a/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp
@@ -32,31 +32,26 @@ Error LVReaderHandler::process() {
   return Error::success();
 }
 
-void LVReaderHandler::destroyReaders() {
-  LLVM_DEBUG(dbgs() << "destroyReaders\n");
-  for (const LVReader *Reader : TheReaders)
-    delete Reader;
-}
-
 Error LVReaderHandler::createReader(StringRef Filename, LVReaders &Readers,
                                     PdbOrObj &Input, StringRef FileFormatName,
                                     StringRef ExePath) {
-  auto CreateOneReader = [&]() -> LVReader * {
+  auto CreateOneReader = [&]() -> std::unique_ptr<LVReader> {
     if (Input.is<ObjectFile *>()) {
       ObjectFile &Obj = *Input.get<ObjectFile *>();
       if (Obj.isELF() || Obj.isMachO())
-        return new LVELFReader(Filename, FileFormatName, Obj, W);
+        return std::make_unique<LVELFReader>(Filename, FileFormatName, Obj, W);
     }
     return nullptr;
   };
 
-  LVReader *Reader = CreateOneReader();
-  if (!Reader)
+  std::unique_ptr<LVReader> ReaderObj = CreateOneReader();
+  if (!ReaderObj)
     return createStringError(errc::invalid_argument,
                              "unable to create reader for: '%s'",
                              Filename.str().c_str());
 
-  Readers.push_back(Reader);
+  LVReader *Reader = ReaderObj.get();
+  Readers.emplace_back(std::move(ReaderObj));
   return Reader->doLoad();
 }
 
@@ -158,7 +153,9 @@ Error LVReaderHandler::createReaders() {
     LVReaders Readers;
     if (Error Err = createReader(Object, Readers))
       return Err;
-    TheReaders.insert(TheReaders.end(), Readers.begin(), Readers.end());
+    TheReaders.insert(TheReaders.end(),
+                      std::make_move_iterator(Readers.begin()),
+                      std::make_move_iterator(Readers.end()));
   }
 
   return Error::success();
@@ -167,7 +164,7 @@ Error LVReaderHandler::createReaders() {
 Error LVReaderHandler::printReaders() {
   LLVM_DEBUG(dbgs() << "printReaders\n");
   if (options().getPrintExecute())
-    for (LVReader *Reader : TheReaders)
+    for (const std::unique_ptr<LVReader> &Reader : TheReaders)
       if (Error Err = Reader->doPrint())
         return Err;
 
@@ -182,7 +179,8 @@ Error LVReaderHandler::compareReaders() {
     size_t ViewPairs = ReadersCount / 2;
     LVCompare Compare(OS);
     for (size_t Pair = 0, Index = 0; Pair < ViewPairs; ++Pair) {
-      if (Error Err = Compare.execute(TheReaders[Index], TheReaders[Index + 1]))
+      if (Error Err = Compare.execute(TheReaders[Index].get(),
+                                      TheReaders[Index + 1].get()))
         return Err;
       Index += 2;
     }

diff  --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
index b654c624f57c0..1fb5c4a9d9105 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
@@ -297,29 +297,16 @@ void LVBinaryReader::addSectionRange(LVSectionIndex SectionIndex,
 }
 
 LVRange *LVBinaryReader::getSectionRanges(LVSectionIndex SectionIndex) {
-  LVRange *Range = nullptr;
   // Check if we already have a mapping for this section index.
   LVSectionRanges::iterator IterSection = SectionRanges.find(SectionIndex);
-  if (IterSection == SectionRanges.end()) {
-    Range = new LVRange();
-    SectionRanges.emplace(SectionIndex, Range);
-  } else {
-    Range = IterSection->second;
-  }
+  if (IterSection == SectionRanges.end())
+    IterSection =
+        SectionRanges.emplace(SectionIndex, std::make_unique<LVRange>()).first;
+  LVRange *Range = IterSection->second.get();
   assert(Range && "Range is null.");
   return Range;
 }
 
-LVBinaryReader::~LVBinaryReader() {
-  // Delete the lines created by 'createInstructions'.
-  std::vector<LVLines *> AllInstructionLines = ScopeInstructions.find();
-  for (LVLines *Entry : AllInstructionLines)
-    delete Entry;
-  // Delete the ranges created by 'getSectionRanges'.
-  for (LVSectionRanges::reference Entry : SectionRanges)
-    delete Entry.second;
-}
-
 Error LVBinaryReader::createInstructions(LVScope *Scope,
                                          LVSectionIndex SectionIndex,
                                          const LVNameInfo &NameInfo) {
@@ -380,7 +367,9 @@ Error LVBinaryReader::createInstructions(LVScope *Scope,
 
   // Address for first instruction line.
   LVAddress FirstAddress = Address;
-  LVLines *Instructions = new LVLines();
+  auto InstructionsSP = std::make_unique<LVLines>();
+  LVLines &Instructions = *InstructionsSP;
+  DiscoveredLines.emplace_back(std::move(InstructionsSP));
 
   while (Begin < End) {
     MCInst Instruction;
@@ -422,10 +411,10 @@ Error LVBinaryReader::createInstructions(LVScope *Scope,
       // the 'processLines()' function will move each created logical line
       // to its enclosing logical scope, using the debug ranges information
       // and they will be released when its scope parent is deleted.
-      LVLineAssembler *Line = new LVLineAssembler();
+      LVLineAssembler *Line = createLineAssembler();
       Line->setAddress(Address);
       Line->setName(StringRef(Stream.str()).trim());
-      Instructions->push_back(Line);
+      Instructions.push_back(Line);
       break;
     }
     }
@@ -439,15 +428,15 @@ Error LVBinaryReader::createInstructions(LVScope *Scope,
            << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"
            << "Address: " << hexValue(FirstAddress)
            << format(" - Collected instructions lines: %d\n",
-                     Instructions->size());
-    for (const LVLine *Line : *Instructions)
+                     Instructions.size());
+    for (const LVLine *Line : Instructions)
       dbgs() << format_decimal(++Index, 5) << ": "
              << hexValue(Line->getOffset()) << ", (" << Line->getName()
              << ")\n";
   });
 
   // The scope in the assembler names is linked to its own instructions.
-  ScopeInstructions.add(SectionIndex, Scope, Instructions);
+  ScopeInstructions.add(SectionIndex, Scope, &Instructions);
   AssemblerMappings.add(SectionIndex, FirstAddress, Scope);
 
   return Error::success();

diff  --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp
index 7746bc508b41a..882660348bd09 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVELFReader.cpp
@@ -57,182 +57,182 @@ LVElement *LVELFReader::createElement(dwarf::Tag Tag) {
   switch (Tag) {
   // Types.
   case dwarf::DW_TAG_base_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsBase();
     if (options().getAttributeBase())
       CurrentType->setIncludeInPrint();
     return CurrentType;
   case dwarf::DW_TAG_const_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsConst();
     CurrentType->setName("const");
     return CurrentType;
   case dwarf::DW_TAG_enumerator:
-    CurrentType = new LVTypeEnumerator();
+    CurrentType = createTypeEnumerator();
     return CurrentType;
   case dwarf::DW_TAG_imported_declaration:
-    CurrentType = new LVTypeImport();
+    CurrentType = createTypeImport();
     CurrentType->setIsImportDeclaration();
     return CurrentType;
   case dwarf::DW_TAG_imported_module:
-    CurrentType = new LVTypeImport();
+    CurrentType = createTypeImport();
     CurrentType->setIsImportModule();
     return CurrentType;
   case dwarf::DW_TAG_pointer_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsPointer();
     CurrentType->setName("*");
     return CurrentType;
   case dwarf::DW_TAG_ptr_to_member_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsPointerMember();
     CurrentType->setName("*");
     return CurrentType;
   case dwarf::DW_TAG_reference_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsReference();
     CurrentType->setName("&");
     return CurrentType;
   case dwarf::DW_TAG_restrict_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsRestrict();
     CurrentType->setName("restrict");
     return CurrentType;
   case dwarf::DW_TAG_rvalue_reference_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsRvalueReference();
     CurrentType->setName("&&");
     return CurrentType;
   case dwarf::DW_TAG_subrange_type:
-    CurrentType = new LVTypeSubrange();
+    CurrentType = createTypeSubrange();
     return CurrentType;
   case dwarf::DW_TAG_template_value_parameter:
-    CurrentType = new LVTypeParam();
+    CurrentType = createTypeParam();
     CurrentType->setIsTemplateValueParam();
     return CurrentType;
   case dwarf::DW_TAG_template_type_parameter:
-    CurrentType = new LVTypeParam();
+    CurrentType = createTypeParam();
     CurrentType->setIsTemplateTypeParam();
     return CurrentType;
   case dwarf::DW_TAG_GNU_template_template_param:
-    CurrentType = new LVTypeParam();
+    CurrentType = createTypeParam();
     CurrentType->setIsTemplateTemplateParam();
     return CurrentType;
   case dwarf::DW_TAG_typedef:
-    CurrentType = new LVTypeDefinition();
+    CurrentType = createTypeDefinition();
     return CurrentType;
   case dwarf::DW_TAG_unspecified_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsUnspecified();
     return CurrentType;
   case dwarf::DW_TAG_volatile_type:
-    CurrentType = new LVType();
+    CurrentType = createType();
     CurrentType->setIsVolatile();
     CurrentType->setName("volatile");
     return CurrentType;
 
   // Symbols.
   case dwarf::DW_TAG_formal_parameter:
-    CurrentSymbol = new LVSymbol();
+    CurrentSymbol = createSymbol();
     CurrentSymbol->setIsParameter();
     return CurrentSymbol;
   case dwarf::DW_TAG_unspecified_parameters:
-    CurrentSymbol = new LVSymbol();
+    CurrentSymbol = createSymbol();
     CurrentSymbol->setIsUnspecified();
     CurrentSymbol->setName("...");
     return CurrentSymbol;
   case dwarf::DW_TAG_member:
-    CurrentSymbol = new LVSymbol();
+    CurrentSymbol = createSymbol();
     CurrentSymbol->setIsMember();
     return CurrentSymbol;
   case dwarf::DW_TAG_variable:
-    CurrentSymbol = new LVSymbol();
+    CurrentSymbol = createSymbol();
     CurrentSymbol->setIsVariable();
     return CurrentSymbol;
   case dwarf::DW_TAG_inheritance:
-    CurrentSymbol = new LVSymbol();
+    CurrentSymbol = createSymbol();
     CurrentSymbol->setIsInheritance();
     return CurrentSymbol;
   case dwarf::DW_TAG_call_site_parameter:
   case dwarf::DW_TAG_GNU_call_site_parameter:
-    CurrentSymbol = new LVSymbol();
+    CurrentSymbol = createSymbol();
     CurrentSymbol->setIsCallSiteParameter();
     return CurrentSymbol;
   case dwarf::DW_TAG_constant:
-    CurrentSymbol = new LVSymbol();
+    CurrentSymbol = createSymbol();
     CurrentSymbol->setIsConstant();
     return CurrentSymbol;
 
   // Scopes.
   case dwarf::DW_TAG_catch_block:
-    CurrentScope = new LVScope();
+    CurrentScope = createScope();
     CurrentScope->setIsCatchBlock();
     return CurrentScope;
   case dwarf::DW_TAG_lexical_block:
-    CurrentScope = new LVScope();
+    CurrentScope = createScope();
     CurrentScope->setIsLexicalBlock();
     return CurrentScope;
   case dwarf::DW_TAG_try_block:
-    CurrentScope = new LVScope();
+    CurrentScope = createScope();
     CurrentScope->setIsTryBlock();
     return CurrentScope;
   case dwarf::DW_TAG_compile_unit:
   case dwarf::DW_TAG_skeleton_unit:
-    CurrentScope = new LVScopeCompileUnit();
+    CurrentScope = createScopeCompileUnit();
     CompileUnit = static_cast<LVScopeCompileUnit *>(CurrentScope);
     return CurrentScope;
   case dwarf::DW_TAG_inlined_subroutine:
-    CurrentScope = new LVScopeFunctionInlined();
+    CurrentScope = createScopeFunctionInlined();
     return CurrentScope;
   case dwarf::DW_TAG_namespace:
-    CurrentScope = new LVScopeNamespace();
+    CurrentScope = createScopeNamespace();
     return CurrentScope;
   case dwarf::DW_TAG_template_alias:
-    CurrentScope = new LVScopeAlias();
+    CurrentScope = createScopeAlias();
     return CurrentScope;
   case dwarf::DW_TAG_array_type:
-    CurrentScope = new LVScopeArray();
+    CurrentScope = createScopeArray();
     return CurrentScope;
   case dwarf::DW_TAG_call_site:
   case dwarf::DW_TAG_GNU_call_site:
-    CurrentScope = new LVScopeFunction();
+    CurrentScope = createScopeFunction();
     CurrentScope->setIsCallSite();
     return CurrentScope;
   case dwarf::DW_TAG_entry_point:
-    CurrentScope = new LVScopeFunction();
+    CurrentScope = createScopeFunction();
     CurrentScope->setIsEntryPoint();
     return CurrentScope;
   case dwarf::DW_TAG_subprogram:
-    CurrentScope = new LVScopeFunction();
+    CurrentScope = createScopeFunction();
     CurrentScope->setIsSubprogram();
     return CurrentScope;
   case dwarf::DW_TAG_subroutine_type:
-    CurrentScope = new LVScopeFunctionType();
+    CurrentScope = createScopeFunctionType();
     return CurrentScope;
   case dwarf::DW_TAG_label:
-    CurrentScope = new LVScopeFunction();
+    CurrentScope = createScopeFunction();
     CurrentScope->setIsLabel();
     return CurrentScope;
   case dwarf::DW_TAG_class_type:
-    CurrentScope = new LVScopeAggregate();
+    CurrentScope = createScopeAggregate();
     CurrentScope->setIsClass();
     return CurrentScope;
   case dwarf::DW_TAG_structure_type:
-    CurrentScope = new LVScopeAggregate();
+    CurrentScope = createScopeAggregate();
     CurrentScope->setIsStructure();
     return CurrentScope;
   case dwarf::DW_TAG_union_type:
-    CurrentScope = new LVScopeAggregate();
+    CurrentScope = createScopeAggregate();
     CurrentScope->setIsUnion();
     return CurrentScope;
   case dwarf::DW_TAG_enumeration_type:
-    CurrentScope = new LVScopeEnumeration();
+    CurrentScope = createScopeEnumeration();
     return CurrentScope;
   case dwarf::DW_TAG_GNU_formal_parameter_pack:
-    CurrentScope = new LVScopeFormalPack();
+    CurrentScope = createScopeFormalPack();
     return CurrentScope;
   case dwarf::DW_TAG_GNU_template_parameter_pack:
-    CurrentScope = new LVScopeTemplatePack();
+    CurrentScope = createScopeTemplatePack();
     return CurrentScope;
   default:
     // Collect TAGs not implemented.
@@ -733,7 +733,7 @@ void LVELFReader::createLineAndFileRecords(
       // the 'processLines()' function will move each created logical line
       // to its enclosing logical scope, using the debug ranges information
       // and they will be released when its scope parent is deleted.
-      LVLineDebug *Line = new LVLineDebug();
+      LVLineDebug *Line = createLineDebug();
       CULines.push_back(Line);
       Line->setAddress(Row.Address.Address);
       Line->setFilename(

diff  --git a/llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp b/llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp
index 06da5ebbc995d..e9c1fbae4e0a7 100644
--- a/llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp
@@ -26,9 +26,10 @@ namespace {
 //===----------------------------------------------------------------------===//
 // Basic Reader functionality.
 class ReaderTestCompare : public LVReader {
-  // Elements created but not added to any logical scope. They are
-  // deleted when the logical Reader is destroyed.
-  LVAutoSmallVector<LVElement *> OrphanElements;
+#define CREATE(VARIABLE, CREATE_FUNCTION, SET_FUNCTION)                        \
+  VARIABLE = CREATE_FUNCTION();                                                \
+  EXPECT_NE(VARIABLE, nullptr);                                                \
+  VARIABLE->SET_FUNCTION();
 
 public:
   // Types.
@@ -66,14 +67,6 @@ class ReaderTestCompare : public LVReader {
 
 protected:
   void add(LVScope *Parent, LVElement *Element);
-  template <typename T, typename F> T *create(F Function) {
-    // 'Function' will update a specific kind of the logical element to
-    // have the ability of kind selection.
-    T *Element = new (std::nothrow) T();
-    EXPECT_NE(Element, nullptr);
-    (Element->*Function)();
-    return Element;
-  }
   void set(LVElement *Element, StringRef Name, LVOffset Offset,
            uint32_t LineNumber = 0, LVElement *Type = nullptr);
 
@@ -116,54 +109,38 @@ void ReaderTestCompare::createElements() {
   ASSERT_NE(Root, nullptr);
 
   // Create the logical types.
-  IntegerType = create<LVType, LVTypeSetFunction>(&LVType::setIsBase);
-  UnsignedType = create<LVType, LVTypeSetFunction>(&LVType::setIsBase);
-  GlobalType = create<LVType, LVTypeSetFunction>(&LVType::setIsBase);
-  LocalType = create<LVType, LVTypeSetFunction>(&LVType::setIsBase);
-  NestedType = create<LVType, LVTypeSetFunction>(&LVType::setIsBase);
-  EnumeratorOne =
-      create<LVTypeEnumerator, LVTypeSetFunction>(&LVType::setIsEnumerator);
-  EnumeratorTwo =
-      create<LVTypeEnumerator, LVTypeSetFunction>(&LVType::setIsEnumerator);
-  TypeDefinitionOne =
-      create<LVTypeDefinition, LVTypeSetFunction>(&LVType::setIsTypedef);
-  TypeDefinitionTwo =
-      create<LVTypeDefinition, LVTypeSetFunction>(&LVType::setIsTypedef);
+  CREATE(IntegerType, createType, setIsBase);
+  CREATE(UnsignedType, createType, setIsBase);
+  CREATE(GlobalType, createType, setIsBase);
+  CREATE(LocalType, createType, setIsBase);
+  CREATE(NestedType, createType, setIsBase);
+  CREATE(EnumeratorOne, createTypeEnumerator, setIsEnumerator);
+  CREATE(EnumeratorTwo, createTypeEnumerator, setIsEnumerator);
+  CREATE(TypeDefinitionOne, createTypeDefinition, setIsTypedef);
+  CREATE(TypeDefinitionTwo, createTypeDefinition, setIsTypedef);
 
   // Create the logical scopes.
-  NestedScope =
-      create<LVScope, LVScopeSetFunction>(&LVScope::setIsLexicalBlock);
-  InnerScope = create<LVScope, LVScopeSetFunction>(&LVScope::setIsLexicalBlock);
-  Aggregate =
-      create<LVScopeAggregate, LVScopeSetFunction>(&LVScope::setIsAggregate);
-  CompileUnit = create<LVScopeCompileUnit, LVScopeSetFunction>(
-      &LVScope::setIsCompileUnit);
-  Enumeration = create<LVScopeEnumeration, LVScopeSetFunction>(
-      &LVScope::setIsEnumeration);
-  FunctionOne =
-      create<LVScopeFunction, LVScopeSetFunction>(&LVScope::setIsFunction);
-  FunctionTwo =
-      create<LVScopeFunction, LVScopeSetFunction>(&LVScope::setIsFunction);
-  Namespace =
-      create<LVScopeNamespace, LVScopeSetFunction>(&LVScope::setIsNamespace);
+  CREATE(NestedScope, createScope, setIsLexicalBlock);
+  CREATE(InnerScope, createScope, setIsLexicalBlock);
+  CREATE(Aggregate, createScopeAggregate, setIsAggregate);
+  CREATE(CompileUnit, createScopeCompileUnit, setIsCompileUnit);
+  CREATE(Enumeration, createScopeEnumeration, setIsEnumeration);
+  CREATE(FunctionOne, createScopeFunction, setIsFunction);
+  CREATE(FunctionTwo, createScopeFunction, setIsFunction);
+  CREATE(Namespace, createScopeNamespace, setIsNamespace);
 
   // Create the logical symbols.
-  GlobalVariable =
-      create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsVariable);
-  LocalVariable =
-      create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsVariable);
-  ClassMember = create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsMember);
-  NestedVariable =
-      create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsVariable);
-  ParameterOne =
-      create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsParameter);
-  ParameterTwo =
-      create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsParameter);
+  CREATE(GlobalVariable, createSymbol, setIsVariable);
+  CREATE(LocalVariable, createSymbol, setIsVariable);
+  CREATE(ClassMember, createSymbol, setIsMember);
+  CREATE(NestedVariable, createSymbol, setIsVariable);
+  CREATE(ParameterOne, createSymbol, setIsParameter);
+  CREATE(ParameterTwo, createSymbol, setIsParameter);
 
   // Create the logical lines.
-  LineOne = create<LVLine, LVLineSetFunction>(&LVLine::setIsLineDebug);
-  LineTwo = create<LVLine, LVLineSetFunction>(&LVLine::setIsLineDebug);
-  LineThree = create<LVLine, LVLineSetFunction>(&LVLine::setIsLineDebug);
+  CREATE(LineOne, createLine, setIsLineDebug);
+  CREATE(LineTwo, createLine, setIsLineDebug);
+  CREATE(LineThree, createLine, setIsLineDebug);
 }
 
 // Reference Reader:              Target Reader:
@@ -203,8 +180,6 @@ void ReaderTestCompare::addElements(bool IsReference, bool IsTarget) {
   auto Insert = [&](bool Insert, auto *Parent, auto *Child) {
     if (Insert)
       add(Parent, Child);
-    else
-      OrphanElements.push_back(Child);
   };
 
   setCompileUnit(CompileUnit);

diff  --git a/llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp
index 8af3050a4273f..f6db28afef20f 100644
--- a/llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/ELFReaderTest.cpp
@@ -47,15 +47,16 @@ LVScopeCompileUnit *getFirstCompileUnit(LVScopeRoot *Root) {
 }
 
 // Helper function to create a reader.
-LVReader *createReader(LVReaderHandler &ReaderHandler,
-                       SmallString<128> &InputsDir, StringRef Filename) {
+std::unique_ptr<LVReader> createReader(LVReaderHandler &ReaderHandler,
+                                       SmallString<128> &InputsDir,
+                                       StringRef Filename) {
   SmallString<128> ObjectName(InputsDir);
   llvm::sys::path::append(ObjectName, Filename);
 
-  Expected<LVReader *> ReaderOrErr =
+  Expected<std::unique_ptr<LVReader>> ReaderOrErr =
       ReaderHandler.createReader(std::string(ObjectName));
   EXPECT_THAT_EXPECTED(ReaderOrErr, Succeeded());
-  LVReader *Reader = *ReaderOrErr;
+  std::unique_ptr<LVReader> Reader = std::move(*ReaderOrErr);
   EXPECT_NE(Reader, nullptr);
   return Reader;
 }
@@ -260,9 +261,9 @@ void elementProperties(SmallString<128> &InputsDir) {
   LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);
 
   // Check logical elements properties.
-  LVReader *Reader = createReader(ReaderHandler, InputsDir, DwarfClang);
-  checkElementProperties(Reader);
-  ReaderHandler.deleteReader(Reader);
+  std::unique_ptr<LVReader> Reader =
+      createReader(ReaderHandler, InputsDir, DwarfClang);
+  checkElementProperties(Reader.get());
 }
 
 // Logical elements selection.
@@ -291,9 +292,9 @@ void elementSelection(SmallString<128> &InputsDir) {
   LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);
 
   // Check logical elements selection.
-  LVReader *Reader = createReader(ReaderHandler, InputsDir, DwarfGcc);
-  checkElementSelection(Reader);
-  ReaderHandler.deleteReader(Reader);
+  std::unique_ptr<LVReader> Reader =
+      createReader(ReaderHandler, InputsDir, DwarfGcc);
+  checkElementSelection(Reader.get());
 }
 
 // Compare logical elements.
@@ -315,11 +316,11 @@ void compareElements(SmallString<128> &InputsDir) {
   LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);
 
   // Check logical comparison.
-  LVReader *Reference = createReader(ReaderHandler, InputsDir, DwarfClang);
-  LVReader *Target = createReader(ReaderHandler, InputsDir, DwarfGcc);
-  checkElementComparison(Reference, Target);
-  ReaderHandler.deleteReader(Reference);
-  ReaderHandler.deleteReader(Target);
+  std::unique_ptr<LVReader> Reference =
+      createReader(ReaderHandler, InputsDir, DwarfClang);
+  std::unique_ptr<LVReader> Target =
+      createReader(ReaderHandler, InputsDir, DwarfGcc);
+  checkElementComparison(Reference.get(), Target.get());
 }
 
 TEST(LogicalViewTest, ELFReader) {

diff  --git a/llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp b/llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp
index 1163fabf84fb5..86949714afae4 100644
--- a/llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/LocationRangesTest.cpp
@@ -24,17 +24,12 @@ namespace {
 
 class ReaderTest : public LVReader {
 protected:
+  void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine);
   void add(LVScope *Parent, LVElement *Element);
-  template <typename T> T *create() {
-    T *Element = new (std::nothrow) T();
-    EXPECT_NE(Element, nullptr);
-    return Element;
-  }
   void set(LVElement *Element, StringRef Name, LVOffset Offset,
            uint32_t LineNumber = 0, LVElement *Type = nullptr);
   void set(LVLocation *Location, LVLine *LowerLine, LVLine *UpperLine,
            LVAddress LowerAddress, LVAddress UpperAddress);
-  void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine);
 
 public:
   ReaderTest(ScopedPrinter &W) : LVReader("", "", W) { setInstance(this); }
@@ -84,6 +79,10 @@ void ReaderTest::add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine) {
 }
 
 class ReaderTestLocations : public ReaderTest {
+#define CREATE(VARIABLE, CREATE_FUNCTION)                                      \
+  VARIABLE = CREATE_FUNCTION();                                                \
+  EXPECT_NE(VARIABLE, nullptr);
+
   // Types.
   LVType *IntegerType = nullptr;
 
@@ -129,33 +128,33 @@ void ReaderTestLocations::createElements() {
   EXPECT_NE(Root, nullptr);
 
   // Create the logical types.
-  IntegerType = create<LVType>();
+  CREATE(IntegerType, createType);
 
   // Create the logical scopes.
-  NestedScope = create<LVScope>();
-  CompileUnit = create<LVScopeCompileUnit>();
-  Function = create<LVScopeFunction>();
+  CREATE(NestedScope, createScope);
+  CREATE(CompileUnit, createScopeCompileUnit);
+  CREATE(Function, createScopeFunction);
 
   // Create the logical symbols.
-  LocalVariable = create<LVSymbol>();
-  NestedVariable = create<LVSymbol>();
-  Parameter = create<LVSymbol>();
+  CREATE(LocalVariable, createSymbol);
+  CREATE(NestedVariable, createSymbol);
+  CREATE(Parameter, createSymbol);
 
   // Create the logical lines.
-  LineOne = create<LVLine>();
-  LineTwo = create<LVLine>();
-  LineThree = create<LVLine>();
-  LineFour = create<LVLine>();
-  LineFive = create<LVLine>();
-  LineSix = create<LVLine>();
+  CREATE(LineOne, createLine);
+  CREATE(LineTwo, createLine);
+  CREATE(LineThree, createLine);
+  CREATE(LineFour, createLine);
+  CREATE(LineFive, createLine);
+  CREATE(LineSix, createLine);
 
   // Create the logical locations.
-  LocationOne = create<LVLocation>();
-  LocationTwo = create<LVLocation>();
-  LocationThree = create<LVLocation>();
-  LocationFour = create<LVLocation>();
-  LocationFive = create<LVLocation>();
-  LocationSix = create<LVLocation>();
+  CREATE(LocationOne, createLocation);
+  CREATE(LocationTwo, createLocation);
+  CREATE(LocationThree, createLocation);
+  CREATE(LocationFour, createLocation);
+  CREATE(LocationFive, createLocation);
+  CREATE(LocationSix, createLocation);
 }
 
 // Create the logical view adding the created logical elements.
@@ -369,30 +368,46 @@ void ReaderTestCoverage::createElements() {
   EXPECT_NE(Root, nullptr);
 
   // Create the logical types.
-  IntegerType = create<LVType>();
+  IntegerType = createType();
+  EXPECT_NE(IntegerType, nullptr);
 
   // Create the logical scopes.
-  CompileUnit = create<LVScopeCompileUnit>();
-  Function = create<LVScopeFunction>();
-  InlinedFunction = create<LVScopeFunctionInlined>();
+  CompileUnit = createScopeCompileUnit();
+  EXPECT_NE(CompileUnit, nullptr);
+  Function = createScopeFunction();
+  EXPECT_NE(Function, nullptr);
+  InlinedFunction = createScopeFunctionInlined();
+  EXPECT_NE(InlinedFunction, nullptr);
 
   // Create the logical symbols.
-  Variable = create<LVSymbol>();
-  Parameter = create<LVSymbol>();
+  Variable = createSymbol();
+  EXPECT_NE(Variable, nullptr);
+  Parameter = createSymbol();
+  EXPECT_NE(Parameter, nullptr);
 
   // Create the logical lines.
-  LineOne = create<LVLine>();
-  LineTwo = create<LVLine>();
-  LineThree = create<LVLine>();
-  LineFour = create<LVLine>();
-  LineFive = create<LVLine>();
-  LineSix = create<LVLine>();
+  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<LVLocation>();
-  LocationTwo = create<LVLocation>();
-  LocationFive = create<LVLocation>();
-  LocationSix = create<LVLocation>();
+  LocationOne = createLocation();
+  EXPECT_NE(LocationOne, nullptr);
+  LocationTwo = createLocation();
+  EXPECT_NE(LocationTwo, nullptr);
+  LocationFive = createLocation();
+  EXPECT_NE(LocationFive, nullptr);
+  LocationSix = createLocation();
+  EXPECT_NE(LocationSix, nullptr);
 }
 
 // Create the logical view adding the created logical elements.

diff  --git a/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp b/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp
index b19029fd1239a..8aa856ad30397 100644
--- a/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp
@@ -23,6 +23,10 @@ using namespace llvm::logicalview;
 namespace {
 
 class ReaderTestElements : public LVReader {
+#define CREATE(VARIABLE, CREATE_FUNCTION)                                      \
+  VARIABLE = CREATE_FUNCTION();                                                \
+  EXPECT_NE(VARIABLE, nullptr);
+
   // Types.
   LVType *IntegerType = nullptr;
   LVType *UnsignedType = nullptr;
@@ -60,11 +64,6 @@ class ReaderTestElements : public LVReader {
 
 protected:
   void add(LVScope *Parent, LVElement *Element);
-  template <typename T> T *create() {
-    T *Element = new (std::nothrow) T();
-    EXPECT_NE(Element, nullptr);
-    return Element;
-  }
   void set(LVElement *Element, StringRef Name, LVOffset Offset,
            uint32_t LineNumber = 0, LVElement *Type = nullptr);
 
@@ -111,40 +110,40 @@ void ReaderTestElements::createElements() {
   ASSERT_NE(Root, nullptr);
 
   // Create the logical types.
-  IntegerType = create<LVType>();
-  UnsignedType = create<LVType>();
-  GlobalType = create<LVType>();
-  LocalType = create<LVType>();
-  NestedType = create<LVType>();
-  EnumeratorOne = create<LVTypeEnumerator>();
-  EnumeratorTwo = create<LVTypeEnumerator>();
-  TypeDefinitionOne = create<LVTypeDefinition>();
-  TypeDefinitionTwo = create<LVTypeDefinition>();
-  TypeSubrange = create<LVTypeSubrange>();
-  TypeParam = create<LVTypeParam>();
-  TypeImport = create<LVTypeImport>();
+  CREATE(IntegerType, createType);
+  CREATE(UnsignedType, createType);
+  CREATE(GlobalType, createType);
+  CREATE(LocalType, createType);
+  CREATE(NestedType, createType);
+  CREATE(EnumeratorOne, createTypeEnumerator);
+  CREATE(EnumeratorTwo, createTypeEnumerator);
+  CREATE(TypeDefinitionOne, createTypeDefinition);
+  CREATE(TypeDefinitionTwo, createTypeDefinition);
+  CREATE(TypeSubrange, createTypeSubrange);
+  CREATE(TypeParam, createTypeParam);
+  CREATE(TypeImport, createTypeImport);
 
   // Create the logical scopes.
-  NestedScope = create<LVScope>();
-  Aggregate = create<LVScopeAggregate>();
-  Array = create<LVScopeArray>();
-  CompileUnit = create<LVScopeCompileUnit>();
-  Enumeration = create<LVScopeEnumeration>();
-  Function = create<LVScopeFunction>();
-  ClassFunction = create<LVScopeFunction>();
-  InlinedFunction = create<LVScopeFunctionInlined>();
-  Namespace = create<LVScopeNamespace>();
+  CREATE(NestedScope, createScope);
+  CREATE(Aggregate, createScopeAggregate);
+  CREATE(Array, createScopeArray);
+  CREATE(CompileUnit, createScopeCompileUnit);
+  CREATE(Enumeration, createScopeEnumeration);
+  CREATE(Function, createScopeFunction);
+  CREATE(ClassFunction, createScopeFunction);
+  CREATE(InlinedFunction, createScopeFunctionInlined);
+  CREATE(Namespace, createScopeNamespace);
 
   // Create the logical symbols.
-  GlobalVariable = create<LVSymbol>();
-  LocalVariable = create<LVSymbol>();
-  ClassMember = create<LVSymbol>();
-  NestedVariable = create<LVSymbol>();
-  Parameter = create<LVSymbol>();
+  CREATE(GlobalVariable, createSymbol);
+  CREATE(LocalVariable, createSymbol);
+  CREATE(ClassMember, createSymbol);
+  CREATE(NestedVariable, createSymbol);
+  CREATE(Parameter, createSymbol);
 
   // Create the logical lines.
-  LocalLine = create<LVLine>();
-  NestedLine = create<LVLine>();
+  CREATE(LocalLine, createLine);
+  CREATE(NestedLine, createLine);
 }
 
 // Create the logical view adding the created logical elements.

diff  --git a/llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp b/llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp
index d590942eed4d7..70835ce05507c 100644
--- a/llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/SelectElementsTest.cpp
@@ -23,6 +23,11 @@ using namespace llvm::logicalview;
 namespace {
 
 class ReaderTestSelection : public LVReader {
+#define CREATE(VARIABLE, CREATE_FUNCTION, SET_FUNCTION)                        \
+  VARIABLE = CREATE_FUNCTION();                                                \
+  EXPECT_NE(VARIABLE, nullptr);                                                \
+  VARIABLE->SET_FUNCTION();
+
   // Types.
   LVType *IntegerType = nullptr;
 
@@ -47,14 +52,6 @@ class ReaderTestSelection : public LVReader {
 
 protected:
   void add(LVScope *Parent, LVElement *Element);
-  template <typename T, typename F> T *create(F Function) {
-    // 'Function' will update a specific kind of the logical element to
-    // have the ability of kind selection.
-    T *Element = new (std::nothrow) T();
-    EXPECT_NE(Element, nullptr);
-    (Element->*Function)();
-    return Element;
-  }
   void set(LVElement *Element, StringRef Name, LVOffset Offset,
            uint32_t LineNumber = 0, LVElement *Type = nullptr);
 
@@ -104,34 +101,27 @@ void ReaderTestSelection::createElements() {
   EXPECT_NE(Root, nullptr);
 
   // Create the logical types.
-  IntegerType = create<LVType, LVTypeSetFunction>(&LVType::setIsBase);
+  CREATE(IntegerType, createType, setIsBase);
 
   // Create the logical scopes.
-  CompileUnit = create<LVScopeCompileUnit, LVScopeSetFunction>(
-      &LVScope::setIsCompileUnit);
-  Function =
-      create<LVScopeFunction, LVScopeSetFunction>(&LVScope::setIsFunction);
-  NestedScope =
-      create<LVScope, LVScopeSetFunction>(&LVScope::setIsLexicalBlock);
-  Namespace =
-      create<LVScopeNamespace, LVScopeSetFunction>(&LVScope::setIsNamespace);
-  Aggregate =
-      create<LVScopeAggregate, LVScopeSetFunction>(&LVScope::setIsAggregate);
+  CREATE(CompileUnit, createScopeCompileUnit, setIsCompileUnit);
+  CREATE(Function, createScopeFunction, setIsFunction);
+  CREATE(NestedScope, createScope, setIsLexicalBlock);
+  CREATE(Namespace, createScopeNamespace, setIsNamespace);
+  CREATE(Aggregate, createScopeAggregate, setIsAggregate);
 
   // Create the logical symbols.
-  ClassMember = create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsMember);
-  LocalVariable =
-      create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsVariable);
-  NestedVariable =
-      create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsVariable);
-  Parameter = create<LVSymbol, LVSymbolSetFunction>(&LVSymbol::setIsParameter);
+  CREATE(ClassMember, createSymbol, setIsMember);
+  CREATE(LocalVariable, createSymbol, setIsVariable);
+  CREATE(NestedVariable, createSymbol, setIsVariable);
+  CREATE(Parameter, createSymbol, setIsParameter);
 
   // Create the logical lines.
-  LineOne = create<LVLine, LVLineSetFunction>(&LVLine::setIsLineDebug);
-  LineTwo = create<LVLine, LVLineSetFunction>(&LVLine::setIsBasicBlock);
-  LineThree = create<LVLine, LVLineSetFunction>(&LVLine::setIsNewStatement);
-  LineFour = create<LVLine, LVLineSetFunction>(&LVLine::setIsPrologueEnd);
-  LineFive = create<LVLine, LVLineSetFunction>(&LVLine::setIsLineAssembler);
+  CREATE(LineOne, createLine, setIsLineDebug);
+  CREATE(LineTwo, createLine, setIsBasicBlock);
+  CREATE(LineThree, createLine, setIsNewStatement);
+  CREATE(LineFour, createLine, setIsPrologueEnd);
+  CREATE(LineFive, createLine, setIsLineAssembler);
 }
 
 // Create the logical view adding the created logical elements.

diff  --git a/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp b/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp
index e2444e36a6887..36c6e16a78dfa 100644
--- a/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp
@@ -22,7 +22,10 @@ using namespace llvm::logicalview;
 
 namespace {
 
-class MyLocation;
+class MyLocation : public LVLocation {
+public:
+  bool validateRanges();
+};
 
 // This code emulates the work done by the Readers when processing the
 // binary files and the creation of the AddressToLine mapping is done
@@ -59,6 +62,14 @@ LVLine *MyAddressToLine::lineUpperBound(LVAddress Address) {
 MyAddressToLine AddressToLine;
 
 class ReaderTestWarningInternal : public LVReader {
+#define CREATE(VARIABLE, CREATE_FUNCTION)                                      \
+  VARIABLE = CREATE_FUNCTION();                                                \
+  EXPECT_NE(VARIABLE, nullptr);
+
+#define CREATE_CUSTOM(VARIABLE, CREATE_FUNCTION)                               \
+  VARIABLE = CREATE_FUNCTION();                                                \
+  EXPECT_NE(VARIABLE, nullptr);
+
   // Types.
   LVType *IntegerType = nullptr;
 
@@ -87,18 +98,19 @@ class ReaderTestWarningInternal : public LVReader {
   MyLocation *LocationFive = nullptr;
   MyLocation *LocationSix = nullptr;
 
+  llvm::SpecificBumpPtrAllocator<MyLocation> AllocatedLocations;
+
 protected:
-  void add(LVScope *Parent, LVElement *Element);
-  template <typename T> T *create() {
-    T *Element = new (std::nothrow) T();
-    EXPECT_NE(Element, nullptr);
-    return Element;
+  MyLocation *createCustomLocation() {
+    return new (AllocatedLocations.Allocate()) MyLocation();
   }
+
+  void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine);
+  void add(LVScope *Parent, LVElement *Element);
   void set(LVElement *Element, StringRef Name, LVOffset Offset,
            uint32_t LineNumber = 0, LVElement *Type = nullptr);
   void set(MyLocation *Location, LVLine *LowerLine, LVLine *UpperLine,
            LVAddress LowerAddress, LVAddress UpperAddress);
-  void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine);
 
 public:
   ReaderTestWarningInternal(ScopedPrinter &W) : LVReader("", "", W) {
@@ -115,11 +127,6 @@ class ReaderTestWarningInternal : public LVReader {
   void checkWarnings();
 };
 
-class MyLocation : public LVLocation {
-public:
-  bool validateRanges();
-};
-
 bool MyLocation::validateRanges() {
   // Traverse the locations and validate them against the address to line
   // mapping in the current compile unit. Record those invalid ranges.
@@ -213,33 +220,33 @@ void ReaderTestWarningInternal::createElements() {
   EXPECT_NE(Root, nullptr);
 
   // Create the logical types.
-  IntegerType = create<LVType>();
+  CREATE(IntegerType, createType);
 
   // Create the logical scopes.
-  NestedScope = create<LVScope>();
-  CompileUnit = create<LVScopeCompileUnit>();
-  Function = create<LVScopeFunction>();
+  CREATE(NestedScope, createScope);
+  CREATE(CompileUnit, createScopeCompileUnit);
+  CREATE(Function, createScopeFunction);
 
   // Create the logical symbols.
-  LocalVariable = create<LVSymbol>();
-  NestedVariable = create<LVSymbol>();
-  Parameter = create<LVSymbol>();
+  CREATE(LocalVariable, createSymbol);
+  CREATE(NestedVariable, createSymbol);
+  CREATE(Parameter, createSymbol);
 
   // Create the logical lines.
-  LineOne = create<LVLine>();
-  LineTwo = create<LVLine>();
-  LineThree = create<LVLine>();
-  LineFour = create<LVLine>();
-  LineFive = create<LVLine>();
-  LineSix = create<LVLine>();
+  CREATE(LineOne, createLine);
+  CREATE(LineTwo, createLine);
+  CREATE(LineThree, createLine);
+  CREATE(LineFour, createLine);
+  CREATE(LineFive, createLine);
+  CREATE(LineSix, createLine);
 
   // Create the logical locations.
-  LocationOne = create<MyLocation>();
-  LocationTwo = create<MyLocation>();
-  LocationThree = create<MyLocation>();
-  LocationFour = create<MyLocation>();
-  LocationFive = create<MyLocation>();
-  LocationSix = create<MyLocation>();
+  CREATE_CUSTOM(LocationOne, createCustomLocation);
+  CREATE_CUSTOM(LocationTwo, createCustomLocation);
+  CREATE_CUSTOM(LocationThree, createCustomLocation);
+  CREATE_CUSTOM(LocationFour, createCustomLocation);
+  CREATE_CUSTOM(LocationFive, createCustomLocation);
+  CREATE_CUSTOM(LocationSix, createCustomLocation);
 }
 
 // Create the logical view adding the created logical elements.
@@ -450,7 +457,7 @@ void ReaderTestWarningInternal::checkWarnings() {
 
   LVOffsetLinesMap::iterator IterZero = LinesZero.begin();
   EXPECT_EQ(IterZero->first, Function->getOffset());
-  LVLines *Lines = IterZero->second;
+  LVLines *Lines = &IterZero->second;
   EXPECT_NE(Lines, nullptr);
   ASSERT_EQ(Lines->size(), 1u);
   LVLine *Line = *(Lines->begin());
@@ -459,7 +466,7 @@ void ReaderTestWarningInternal::checkWarnings() {
 
   ++IterZero;
   EXPECT_EQ(IterZero->first, NestedScope->getOffset());
-  Lines = IterZero->second;
+  Lines = &IterZero->second;
   EXPECT_NE(Lines, nullptr);
   ASSERT_EQ(Lines->size(), 1u);
   Line = *(Lines->begin());
@@ -487,7 +494,7 @@ void ReaderTestWarningInternal::checkWarnings() {
 
   LVOffsetLocationsMap::iterator IterRange = InvalidRanges.begin();
   EXPECT_EQ(IterRange->first, Function->getOffset());
-  LVLocations *Locations = IterRange->second;
+  LVLocations *Locations = &IterRange->second;
   EXPECT_NE(Locations, nullptr);
   ASSERT_EQ(Locations->size(), 1u);
   LVLocation *Location = *(Locations->begin());
@@ -501,7 +508,7 @@ void ReaderTestWarningInternal::checkWarnings() {
 
   LVOffsetLocationsMap::iterator IterLocations = InvalidLocations.begin();
   EXPECT_EQ(IterLocations->first, NestedVariable->getOffset());
-  Locations = IterLocations->second;
+  Locations = &IterLocations->second;
   EXPECT_NE(Locations, nullptr);
   ASSERT_EQ(Locations->size(), 1u);
   Location = *(Locations->begin());


        


More information about the llvm-commits mailing list