@@ -719,39 +719,46 @@ namespace Cpp {
719
719
return ComputeBaseOffset (getSema ().getASTContext (), DCXXRD, Paths.front ());
720
720
}
721
721
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) {
727
725
if (!klass)
728
- return {} ;
726
+ return ;
729
727
730
- auto * D = (clang::Decl *) klass;
728
+ auto * D = (clang::Decl*) klass;
731
729
732
- if (auto * TD = dyn_cast<TypedefNameDecl>(D))
730
+ if (auto * TD = dyn_cast<TypedefNameDecl>(D))
733
731
D = GetScopeFromType (TD->getUnderlyingType ());
734
732
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 ()))
740
743
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
- }
745
744
}
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);
747
755
}
748
756
749
757
bool HasDefaultConstructor (TCppScope_t scope) {
750
758
auto *D = (clang::Decl *) scope;
751
759
752
- if (auto * CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
760
+ if (auto * CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D))
753
761
return CXXRD->hasDefaultConstructor ();
754
- }
755
762
756
763
return false ;
757
764
}
@@ -818,21 +825,19 @@ namespace Cpp {
818
825
TCppType_t GetFunctionReturnType (TCppFunction_t func)
819
826
{
820
827
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 ();
824
830
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 ();
828
833
829
834
return 0 ;
830
835
}
831
836
832
837
TCppIndex_t GetFunctionNumArgs (TCppFunction_t func)
833
838
{
834
839
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))
836
841
return FD->getNumParams ();
837
842
838
843
if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D))
@@ -844,9 +849,8 @@ namespace Cpp {
844
849
TCppIndex_t GetFunctionRequiredArgs (TCppConstFunction_t func)
845
850
{
846
851
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))
848
853
return FD->getMinRequiredArguments ();
849
- }
850
854
851
855
if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(D))
852
856
return (FD->getTemplatedDecl ())->getMinRequiredArguments ();
@@ -868,8 +872,7 @@ namespace Cpp {
868
872
return 0 ;
869
873
}
870
874
871
- std::string GetFunctionSignature (TCppFunction_t func)
872
- {
875
+ std::string GetFunctionSignature (TCppFunction_t func) {
873
876
if (!func)
874
877
return " <unknown>" ;
875
878
@@ -886,6 +889,7 @@ namespace Cpp {
886
889
SS.flush ();
887
890
return Signature;
888
891
}
892
+
889
893
return " <unknown>" ;
890
894
}
891
895
@@ -925,7 +929,7 @@ namespace Cpp {
925
929
{
926
930
DeclContext *Within = 0 ;
927
931
if (parent) {
928
- auto * D = (Decl *)parent;
932
+ auto * D = (Decl*)parent;
929
933
Within = llvm::dyn_cast<DeclContext>(D);
930
934
}
931
935
@@ -941,6 +945,72 @@ namespace Cpp {
941
945
return true ;
942
946
}
943
947
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
+
944
1014
// Gets the AccessSpecifier of the function and checks if it is equal to
945
1015
// the provided AccessSpecifier.
946
1016
bool CheckMethodAccess (TCppFunction_t method, AccessSpecifier AS)
@@ -2836,7 +2906,7 @@ namespace Cpp {
2836
2906
}
2837
2907
2838
2908
TCppScope_t InstantiateTemplate (TCppScope_t tmpl,
2839
- TemplateArgInfo* template_args,
2909
+ const TemplateArgInfo* template_args,
2840
2910
size_t template_args_size) {
2841
2911
ASTContext &C = getASTContext ();
2842
2912
0 commit comments