================
@@ -1040,5 +1038,86 @@ bool isExpandedFromParameterPack(const ParmVarDecl *D) {
   return getUnderlyingPackType(D) != nullptr;
 }
 
+bool isLikelyForwardingFunction(const FunctionTemplateDecl *FT) {
+  const auto *FD = FT->getTemplatedDecl();
+  const auto NumParams = FD->getNumParams();
+  // Check whether its last parameter is a parameter pack...
+  if (NumParams > 0) {
+    const auto *LastParam = FD->getParamDecl(NumParams - 1);
+    if (const auto *PET = dyn_cast<PackExpansionType>(LastParam->getType())) {
+      // ... of the type T&&... or T...
+      const auto BaseType = PET->getPattern().getNonReferenceType();
+      if (const auto *TTPT =
+              dyn_cast<TemplateTypeParmType>(BaseType.getTypePtr())) {
+        // ... whose template parameter comes from the function directly
+        if (FT->getTemplateParameters()->getDepth() == TTPT->getDepth()) {
+          return true;
+        }
+      }
+    }
+  }
+  return false;
+}
+
+class ForwardingToConstructorVisitor
+    : public RecursiveASTVisitor<ForwardingToConstructorVisitor> {
+public:
+  struct SeenFunctions {
+    unsigned int DepthLeft;
+    SeenFunctions *Prev;
+    const FunctionDecl *Current;
+
+    bool seenFunction(const FunctionDecl *FD) {
+      if (Current == FD)
+        return true;
+      if (Prev == nullptr)
+        return false;
+      return Prev->seenFunction(FD);
+    }
+  };
+
+  ForwardingToConstructorVisitor(SeenFunctions SF,
+                                 SmallVector<CXXConstructorDecl *, 1> &Output)
+      : SF(std::move(SF)), Constructors(Output) {}
+
+  bool VisitCallExpr(CallExpr *E) {
+    if (SF.DepthLeft == 0)
+      return true;
+    if (auto *FD = E->getDirectCallee()) {
+      // Check if we already visited this function to prevent endless recursion
+      if (SF.seenFunction(FD))
+        return true;
+      if (auto *PT = FD->getPrimaryTemplate();
+          PT && isLikelyForwardingFunction(PT)) {
+        SeenFunctions Next{SF.DepthLeft - 1, &SF, FD};
+        ForwardingToConstructorVisitor Visitor{std::move(Next), Constructors};
+        Visitor.TraverseStmt(FD->getBody());
+      }
+    }
+    return true;
+  }
+
+  bool VisitCXXNewExpr(CXXNewExpr *E) {
+    if (auto *CE = E->getConstructExpr())
+      if (auto *Callee = CE->getConstructor())
+        Constructors.push_back(Callee);
+    return true;
+  }
+
+  // List of function stack
----------------
HighCommander4 wrote:

``// Stack of seen functions``?

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

Reply via email to