================ @@ -32,6 +33,183 @@ populateParentNamespaces(llvm::SmallVector<Reference, 4> &Namespaces, static void populateMemberTypeInfo(MemberTypeInfo &I, const FieldDecl *D); +void getTemplateParameters(const TemplateParameterList *TemplateParams, + llvm::raw_ostream &Stream) { + Stream << "template <"; + + for (unsigned i = 0; i < TemplateParams->size(); ++i) { + if (i > 0) { + Stream << ", "; + } + + const NamedDecl *Param = TemplateParams->getParam(i); + if (const auto *TTP = llvm::dyn_cast<TemplateTypeParmDecl>(Param)) { + if (TTP->wasDeclaredWithTypename()) { + Stream << "typename"; + } else { + Stream << "class"; + } + if (TTP->isParameterPack()) { + Stream << "..."; + } + Stream << " " << TTP->getNameAsString(); + } else if (const auto *NTTP = llvm::dyn_cast<NonTypeTemplateParmDecl>(Param)) { + NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy()); + if (NTTP->isParameterPack()) { + Stream << "..."; + } + Stream << " " << NTTP->getNameAsString(); + } else if (const auto *TTPD = llvm::dyn_cast<TemplateTemplateParmDecl>(Param)) { + Stream << "template <"; + getTemplateParameters(TTPD->getTemplateParameters(), Stream); + Stream << "> class " << TTPD->getNameAsString(); + } + } + + Stream << "> "; +} + +// Extract the full function prototype from a FunctionDecl including +// Full Decl +llvm::SmallString<256> getFunctionPrototype(const FunctionDecl *FuncDecl) { + llvm::SmallString<256> Result; + llvm::raw_svector_ostream Stream(Result); + const ASTContext& Ctx = FuncDecl->getASTContext(); + const auto *Method = llvm::dyn_cast<CXXMethodDecl>(FuncDecl); + // If it's a templated function, handle the template parameters + if (const auto *TmplDecl = FuncDecl->getDescribedTemplate()) { + getTemplateParameters(TmplDecl->getTemplateParameters(), Stream); + } + // If it's a virtual method + if (Method) { + if (Method->isVirtual()) + { + Stream << "virtual "; + } + } + // Print return type + FuncDecl->getReturnType().print(Stream, Ctx.getPrintingPolicy()); + + // Print function name + Stream << " " << FuncDecl->getNameAsString() << "("; + + // Print parameter list with types, names, and default values + for (unsigned I = 0; I < FuncDecl->getNumParams(); ++I) { + if (I > 0) { + Stream << ", "; + } + const ParmVarDecl *ParamDecl = FuncDecl->getParamDecl(I); + QualType ParamType = ParamDecl->getType(); + ParamType.print(Stream, Ctx.getPrintingPolicy()); + + // Print parameter name if it has one + if (!ParamDecl->getName().empty()) { + Stream << " " << ParamDecl->getNameAsString(); + } + + // Print default argument if it exists + if (ParamDecl->hasDefaultArg()) { + const Expr *DefaultArg = ParamDecl->getDefaultArg(); + if (DefaultArg) { + Stream << " = "; + DefaultArg->printPretty(Stream, nullptr, Ctx.getPrintingPolicy()); + } ---------------- ilovepi wrote:
DefaultArg only gets used in the conditional. you can use ``` if(const Expr* DefaultArg = ...){ ... } ``` https://github.com/llvm/llvm-project/pull/133161 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits