================
@@ -2556,35 +2556,59 @@ class DISubprogram : public DILocalScope {
 
   /// For the given retained node of DISubprogram, applies one of the
   /// given functions depending on the type of the node.
-  template <typename T, typename FuncLVT, typename FuncLabelT,
-            typename FuncImportedEntityT, typename FuncUnknownT>
-  static T
-  visitRetainedNode(const Metadata *N, FuncLVT &&FuncLV, FuncLabelT 
&&FuncLabel,
-                    FuncImportedEntityT &&FuncIE, FuncUnknownT &&FuncUnknown) {
-    if (const auto *LV = dyn_cast<DILocalVariable>(N))
+  template <typename T, typename MetadataT, typename FuncLVT,
+            typename FuncLabelT, typename FuncImportedEntityT,
+            typename FuncTypeT, typename FuncUnknownT>
+  static T visitRetainedNode(MetadataT *N, FuncLVT &&FuncLV,
+                             FuncLabelT &&FuncLabel,
+                             FuncImportedEntityT &&FuncIE, FuncTypeT 
&&FuncType,
+                             FuncUnknownT &&FuncUnknown) {
+    static_assert(std::is_base_of_v<Metadata, MetadataT>,
+                  "N must point to Metadata or const Metadata");
+
+    if (auto *LV = dyn_cast<DILocalVariable>(N))
       return FuncLV(LV);
-    if (const auto *L = dyn_cast<DILabel>(N))
+    if (auto *L = dyn_cast<DILabel>(N))
       return FuncLabel(L);
-    if (const auto *IE = dyn_cast<DIImportedEntity>(N))
+    if (auto *IE = dyn_cast<DIImportedEntity>(N))
       return FuncIE(IE);
+    if (auto *Ty = dyn_cast<DIType>(N))
+      return FuncType(Ty);
     return FuncUnknown(N);
   }
 
   /// Returns the scope of subprogram's retainedNodes.
   static const DILocalScope *getRetainedNodeScope(const MDNode *N);
+  static DILocalScope *getRetainedNodeScope(MDNode *N);
   // For use in Verifier.
   static const DIScope *getRawRetainedNodeScope(const MDNode *N);
+  static DIScope *getRawRetainedNodeScope(MDNode *N);
 
   /// For each retained node, applies one of the given functions depending
   /// on the type of a node.
-  template <typename FuncLVT, typename FuncLabelT, typename 
FuncImportedEntityT>
+  template <typename FuncLVT, typename FuncLabelT, typename 
FuncImportedEntityT,
+            typename FuncTypeT>
   void forEachRetainedNode(FuncLVT &&FuncLV, FuncLabelT &&FuncLabel,
-                           FuncImportedEntityT &&FuncIE) const {
+                           FuncImportedEntityT &&FuncIE, FuncTypeT &&FuncType) 
{
     for (MDNode *N : getRetainedNodes())
-      visitRetainedNode<void>(N, FuncLV, FuncLabel, FuncIE,
-                              [](const Metadata *N) {
-                                llvm_unreachable("Unexpected retained node!");
-                              });
+      visitRetainedNode<void>(
+          N, FuncLV, FuncLabel, FuncIE, FuncType,
+          [](auto *N) { llvm_unreachable("Unexpected retained node!"); });
+  }
+
+  /// Remove types that do not belong to the subprogram's scope from
+  /// retainedNodes list.
+  void cleanupRetainedNodes();
+
+  /// When DebugTypeODRUniquing is enabled, after multiple modules are loaded,
+  /// some subprograms (that are from different compilation units, usually)
+  /// may have references to the same local type in their retainedNodes lists.
+  ///
----------------
adrian-prantl wrote:

For someone reading the API documentation it would help to answer the following 
questions in this document:
- why may two subprograms refer to the same local type?
- why is that a problem?
- what exactly does the "cleanup" look like?
- does the cleanup degrade the debug info quality/accuracy in any way?

https://github.com/llvm/llvm-project/pull/165032
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to