@@ -719,39 +719,46 @@ namespace Cpp {
719719 return ComputeBaseOffset (getSema ().getASTContext (), DCXXRD, Paths.front ());
720720 }
721721
722- // FIXME: We should make the std::vector<TCppFunction_t> an out parameter to
723- // avoid copies.
724- std::vector<TCppFunction_t> GetClassMethods (TCppScope_t klass)
725- {
726-
722+ template <typename DeclType>
723+ static void GetClassDecls (TCppScope_t klass,
724+ std::vector<TCppFunction_t>& methods) {
727725 if (!klass)
728- return {} ;
726+ return ;
729727
730- auto * D = (clang::Decl *) klass;
728+ auto * D = (clang::Decl*) klass;
731729
732- if (auto * TD = dyn_cast<TypedefNameDecl>(D))
730+ if (auto * TD = dyn_cast<TypedefNameDecl>(D))
733731 D = GetScopeFromType (TD->getUnderlyingType ());
734732
735- std::vector<TCppFunction_t> methods;
736- if (auto *CXXRD = dyn_cast_or_null<CXXRecordDecl>(D)) {
737- getSema ().ForceDeclarationOfImplicitMembers (CXXRD);
738- for (Decl* DI : CXXRD->decls ()) {
739- if (auto * MD = dyn_cast<CXXMethodDecl>(DI))
733+ if (!D || !isa<CXXRecordDecl>(D))
734+ return ;
735+
736+ auto * CXXRD = dyn_cast<CXXRecordDecl>(D);
737+ getSema ().ForceDeclarationOfImplicitMembers (CXXRD);
738+ for (Decl* DI : CXXRD->decls ()) {
739+ if (auto * MD = dyn_cast<DeclType>(DI))
740+ methods.push_back (MD);
741+ else if (auto * USD = dyn_cast<UsingShadowDecl>(DI))
742+ if (auto * MD = dyn_cast<DeclType>(USD->getTargetDecl ()))
740743 methods.push_back (MD);
741- else if (auto * USD = dyn_cast<UsingShadowDecl>(DI))
742- if (auto * MD = dyn_cast<CXXMethodDecl>(USD->getTargetDecl ()))
743- methods.push_back (MD);
744- }
745744 }
746- return methods;
745+ }
746+
747+ void GetClassMethods (TCppScope_t klass,
748+ std::vector<TCppFunction_t>& methods) {
749+ GetClassDecls<CXXMethodDecl>(klass, methods);
750+ }
751+
752+ void GetFunctionTemplatedDecls (TCppScope_t klass,
753+ std::vector<TCppFunction_t>& methods) {
754+ GetClassDecls<FunctionTemplateDecl>(klass, methods);
747755 }
748756
749757 bool HasDefaultConstructor (TCppScope_t scope) {
750758 auto *D = (clang::Decl *) scope;
751759
752- if (auto * CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
760+ if (auto * CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D))
753761 return CXXRD->hasDefaultConstructor ();
754- }
755762
756763 return false ;
757764 }
@@ -818,21 +825,19 @@ namespace Cpp {
818825 TCppType_t GetFunctionReturnType (TCppFunction_t func)
819826 {
820827 auto *D = (clang::Decl *) func;
821- if (auto *FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(D)) {
822- return FD->getReturnType ().getAsOpaquePtr ();
823- }
828+ if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(D))
829+ return FD->getReturnType ().getAsOpaquePtr ();
824830
825- if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D)) {
826- return (FD->getTemplatedDecl ())->getReturnType ().getAsOpaquePtr ();
827- }
831+ if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D))
832+ return (FD->getTemplatedDecl ())->getReturnType ().getAsOpaquePtr ();
828833
829834 return 0 ;
830835 }
831836
832837 TCppIndex_t GetFunctionNumArgs (TCppFunction_t func)
833838 {
834839 auto *D = (clang::Decl *) func;
835- if (auto * FD = llvm::dyn_cast_or_null<FunctionDecl>(D))
840+ if (auto * FD = llvm::dyn_cast_or_null<FunctionDecl>(D))
836841 return FD->getNumParams ();
837842
838843 if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D))
@@ -844,9 +849,8 @@ namespace Cpp {
844849 TCppIndex_t GetFunctionRequiredArgs (TCppConstFunction_t func)
845850 {
846851 auto *D = (const clang::Decl *) func;
847- if (auto * FD = llvm::dyn_cast_or_null<FunctionDecl> (D)) {
852+ if (auto * FD = llvm::dyn_cast_or_null<FunctionDecl>(D))
848853 return FD->getMinRequiredArguments ();
849- }
850854
851855 if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D))
852856 return (FD->getTemplatedDecl ())->getMinRequiredArguments ();
@@ -868,8 +872,7 @@ namespace Cpp {
868872 return 0 ;
869873 }
870874
871- std::string GetFunctionSignature (TCppFunction_t func)
872- {
875+ std::string GetFunctionSignature (TCppFunction_t func) {
873876 if (!func)
874877 return " <unknown>" ;
875878
@@ -886,6 +889,7 @@ namespace Cpp {
886889 SS.flush ();
887890 return Signature;
888891 }
892+
889893 return " <unknown>" ;
890894 }
891895
@@ -925,7 +929,7 @@ namespace Cpp {
925929 {
926930 DeclContext *Within = 0 ;
927931 if (parent) {
928- auto * D = (Decl *)parent;
932+ auto * D = (Decl*)parent;
929933 Within = llvm::dyn_cast<DeclContext>(D);
930934 }
931935
@@ -941,6 +945,72 @@ namespace Cpp {
941945 return true ;
942946 }
943947
948+ void GetClassTemplatedMethods (const std::string& name, TCppScope_t parent,
949+ std::vector<TCppFunction_t>& funcs) {
950+
951+ auto * D = (Decl*)parent;
952+
953+ if (!parent || name.empty ())
954+ return ;
955+
956+ D = GetUnderlyingScope (D);
957+
958+ llvm::StringRef Name (name);
959+ auto & S = getSema ();
960+ DeclarationName DName = &getASTContext ().Idents .get (name);
961+ clang::LookupResult R (S, DName, SourceLocation (), Sema::LookupOrdinaryName,
962+ Sema::ForVisibleRedeclaration);
963+
964+ Cpp_utils::Lookup::Named (&S, R, Decl::castToDeclContext (D));
965+
966+ if (R.empty ())
967+ return ;
968+
969+ R.resolveKind ();
970+
971+ for (auto * Found : R)
972+ if (llvm::isa<FunctionTemplateDecl>(Found))
973+ funcs.push_back (Found);
974+ }
975+
976+ TCppFunction_t
977+ BestTemplateFunctionMatch (const std::vector<TCppFunction_t>& candidates,
978+ const std::vector<TemplateArgInfo>& explicit_types,
979+ const std::vector<TemplateArgInfo>& arg_types) {
980+
981+ for (const auto & candidate : candidates) {
982+ auto * TFD = (FunctionTemplateDecl*)candidate;
983+ clang::TemplateParameterList* tpl = TFD->getTemplateParameters ();
984+
985+ // template parameter size does not match
986+ if (tpl->size () < explicit_types.size ())
987+ continue ;
988+
989+ // right now uninstantiated functions give template typenames instead of
990+ // actual types. We make this match solely based on count
991+
992+ const FunctionDecl* func = TFD->getTemplatedDecl ();
993+ if (func->getNumParams () != arg_types.size ())
994+ continue ;
995+
996+ // FIXME : first score based on the type similarity before forcing
997+ // instantiation try instantiating
998+ TCppFunction_t instantiated =
999+ InstantiateTemplate (candidate, arg_types.data (), arg_types.size ());
1000+ if (instantiated)
1001+ return instantiated;
1002+
1003+ // Force the instantiation with template params in case of no args
1004+ // maybe steer instantiation better with arg set returned from
1005+ // TemplateProxy?
1006+ instantiated = InstantiateTemplate (candidate, explicit_types.data (),
1007+ explicit_types.size ());
1008+ if (instantiated)
1009+ return instantiated;
1010+ }
1011+ return nullptr ;
1012+ }
1013+
9441014 // Gets the AccessSpecifier of the function and checks if it is equal to
9451015 // the provided AccessSpecifier.
9461016 bool CheckMethodAccess (TCppFunction_t method, AccessSpecifier AS)
@@ -2836,7 +2906,7 @@ namespace Cpp {
28362906 }
28372907
28382908 TCppScope_t InstantiateTemplate (TCppScope_t tmpl,
2839- TemplateArgInfo* template_args,
2909+ const TemplateArgInfo* template_args,
28402910 size_t template_args_size) {
28412911 ASTContext &C = getASTContext ();
28422912
0 commit comments