1212#include " Compatibility.h"
1313
1414#include " clang/AST/Attrs.inc"
15+ #include " clang/AST/Comment.h"
1516#include " clang/AST/CXXInheritance.h"
1617#include " clang/AST/Decl.h"
1718#include " clang/AST/DeclAccessPair.h"
@@ -380,6 +381,11 @@ bool IsBuiltin(TCppType_t type) {
380381 return llvm::StringRef (Ty.getAsString ()).contains (" complex" );
381382}
382383
384+ bool IsTemplateClass (TCppScope_t handle) {
385+ auto * D = (clang::Decl*)handle;
386+ return llvm::isa_and_nonnull<clang::ClassTemplateDecl>(D);
387+ }
388+
383389bool IsTemplate (TCppScope_t handle) {
384390 auto * D = (clang::Decl*)handle;
385391 return llvm::isa_and_nonnull<clang::TemplateDecl>(D);
@@ -546,6 +552,15 @@ bool IsVariable(TCppScope_t scope) {
546552 return llvm::isa_and_nonnull<clang::VarDecl>(D);
547553}
548554
555+ std::string GetDocString (TCppScope_t scope) {
556+ auto *D = static_cast <Decl*>(scope);
557+ auto &AST = getASTContext (D);
558+ const clang::RawComment *Comment = AST.getRawCommentForAnyRedecl (D);
559+ if (!Comment)
560+ return " " ;
561+ return Comment->getFormattedText (AST.getSourceManager (), AST.getDiagnostics ());
562+ }
563+
549564std::string GetName (TCppType_t klass) {
550565 auto * D = (clang::NamedDecl*)klass;
551566
@@ -877,6 +892,98 @@ int64_t GetBaseClassOffset(TCppScope_t derived, TCppScope_t base) {
877892 return ComputeBaseOffset (getSema ().getASTContext (), DCXXRD, Paths.front ());
878893}
879894
895+ template <typename DeclType>
896+ static void GetNamespaceDecls (TCppScope_t ns,
897+ std::vector<TCppScope_t>& members) {
898+ if (!ns)
899+ return ;
900+
901+ auto * D = (clang::Decl*)ns;
902+ LOCK (getInterpInfo (D));
903+
904+ if (!D || !isa<NamespaceDecl>(D))
905+ return ;
906+
907+ auto * NSD = dyn_cast<NamespaceDecl>(D)->getMostRecentDecl ();
908+ while (NSD) {
909+ for (Decl* DI : NSD->decls ()) {
910+ if (auto * MD = dyn_cast<DeclType>(DI))
911+ members.push_back (MD);
912+ else if (auto * USD = dyn_cast<UsingShadowDecl>(DI)) {
913+ if (auto *MD = dyn_cast<DeclType>(USD->getTargetDecl ()))
914+ members.push_back (MD);
915+ }
916+ }
917+ NSD = NSD->getPreviousDecl ();
918+ }
919+ }
920+
921+ void GetDatamembersInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
922+ GetNamespaceDecls<VarDecl>(ns, members);
923+ }
924+
925+ void GetFunctionsInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
926+ GetNamespaceDecls<FunctionDecl>(ns, members);
927+ }
928+
929+ void GetClassInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
930+ GetNamespaceDecls<RecordDecl>(ns, members);
931+ }
932+
933+ void GetTemplatedClassInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
934+ GetNamespaceDecls<ClassTemplateDecl>(ns, members);
935+ }
936+
937+ void GetTemplatedFunctionsInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
938+ GetNamespaceDecls<FunctionTemplateDecl>(ns, members);
939+ }
940+
941+ template <typename DeclType>
942+ static void GetNamespaceDecls (TCppScope_t ns,
943+ std::vector<TCppScope_t>& members) {
944+ if (!ns)
945+ return ;
946+
947+ auto * D = (clang::Decl*)ns;
948+ LOCK (getInterpInfo (D));
949+
950+ if (!D || !isa<NamespaceDecl>(D))
951+ return ;
952+
953+ auto * NSD = dyn_cast<NamespaceDecl>(D)->getMostRecentDecl ();
954+ while (NSD) {
955+ for (Decl* DI : NSD->decls ()) {
956+ if (auto * MD = dyn_cast<DeclType>(DI))
957+ members.push_back (MD);
958+ else if (auto * USD = dyn_cast<UsingShadowDecl>(DI)) {
959+ if (auto *MD = dyn_cast<DeclType>(USD->getTargetDecl ()))
960+ members.push_back (MD);
961+ }
962+ }
963+ NSD = NSD->getPreviousDecl ();
964+ }
965+ }
966+
967+ void GetDatamembersInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
968+ GetNamespaceDecls<VarDecl>(ns, members);
969+ }
970+
971+ void GetFunctionsInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
972+ GetNamespaceDecls<FunctionDecl>(ns, members);
973+ }
974+
975+ void GetClassInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
976+ GetNamespaceDecls<RecordDecl>(ns, members);
977+ }
978+
979+ void GetTemplatedClassInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
980+ GetNamespaceDecls<ClassTemplateDecl>(ns, members);
981+ }
982+
983+ void GetTemplatedFunctionsInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
984+ GetNamespaceDecls<FunctionTemplateDecl>(ns, members);
985+ }
986+
880987template <typename DeclType>
881988static void GetClassDecls (TCppScope_t klass,
882989 std::vector<TCppFunction_t>& methods) {
@@ -888,6 +995,10 @@ static void GetClassDecls(TCppScope_t klass,
888995 if (auto * TD = dyn_cast<TypedefNameDecl>(D))
889996 D = GetScopeFromType (TD->getUnderlyingType ());
890997
998+ if (auto *CTD = llvm::dyn_cast_or_null<ClassTemplateDecl>(D)) {
999+ D = CTD->getTemplatedDecl ();
1000+ }
1001+
8911002 if (!D || !isa<CXXRecordDecl>(D))
8921003 return ;
8931004
@@ -1011,7 +1122,7 @@ TCppType_t GetFunctionReturnType(TCppFunction_t func) {
10111122 QualType Type = FD->getReturnType ();
10121123 if (Type->isUndeducedAutoType ()) {
10131124 bool needInstantiation = false ;
1014- if (IsTemplatedFunction (FD) && !FD->isDefined ())
1125+ if (IsTemplateInstantiationOrSpecialization (FD) && !FD->isDefined ())
10151126 needInstantiation = true ;
10161127 if (auto * MD = llvm::dyn_cast<clang::CXXMethodDecl>(FD)) {
10171128 if (IsTemplateSpecialization (MD->getParent ()))
@@ -1055,8 +1166,10 @@ TCppIndex_t GetFunctionRequiredArgs(TCppConstFunction_t func) {
10551166}
10561167
10571168TCppType_t GetFunctionArgType (TCppFunction_t func, TCppIndex_t iarg) {
1058- auto * D = (clang::Decl*)func;
1059-
1169+ auto * D = static_cast <clang::Decl*>(func);
1170+ if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
1171+ D = FTD->getTemplatedDecl ();
1172+ }
10601173 if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(D)) {
10611174 if (iarg < FD->getNumParams ()) {
10621175 auto * PVD = FD->getParamDecl (iarg);
@@ -1122,7 +1235,12 @@ bool IsFunctionDeleted(TCppConstFunction_t function) {
11221235
11231236bool IsTemplatedFunction (TCppFunction_t func) {
11241237 auto * D = (Decl*)func;
1125- return IsTemplatedFunction (D) || IsTemplateInstantiationOrSpecialization (D);
1238+ return IsTemplatedFunction (D) /* || IsTemplateInstantiationOrSpecialization(D)*/ ;
1239+ }
1240+
1241+ bool IsTemplateInstantiationOrSpecialization (TCppScope_t scope) {
1242+ auto *D = static_cast <Decl*>(scope);
1243+ return IsTemplateInstantiationOrSpecialization (D);
11261244}
11271245
11281246// FIXME: This lookup is broken, and should no longer be used in favour of
@@ -1334,6 +1452,9 @@ bool IsDestructor(TCppConstFunction_t method) {
13341452
13351453bool IsStaticMethod (TCppConstFunction_t method) {
13361454 const auto * D = static_cast <const Decl*>(method);
1455+ if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
1456+ D = FTD->getTemplatedDecl ();
1457+ }
13371458 if (auto * CXXMD = llvm::dyn_cast_or_null<CXXMethodDecl>(D)) {
13381459 return CXXMD->isStatic ();
13391460 }
@@ -1404,6 +1525,9 @@ bool IsVirtualMethod(TCppFunction_t method) {
14041525
14051526void GetDatamembers (TCppScope_t scope, std::vector<TCppScope_t>& datamembers) {
14061527 auto * D = (Decl*)scope;
1528+ if (auto *CTD = llvm::dyn_cast_or_null<ClassTemplateDecl>(D)) {
1529+ D = CTD->getTemplatedDecl ();
1530+ }
14071531
14081532 if (auto * CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
14091533 getSema ().ForceDeclarationOfImplicitMembers (CXXRD);
@@ -1497,7 +1621,7 @@ TCppType_t GetVariableType(TCppScope_t var) {
14971621 QualType QT = DD->getType ();
14981622
14991623 // Check if the type is a typedef type
1500- if (QT->isTypedefNameType ()) {
1624+ if (QT->isTypedefNameType () || QT-> getAs <clang::TemplateTypeParmType>() ) {
15011625 return QT.getAsOpaquePtr ();
15021626 }
15031627
@@ -1758,6 +1882,8 @@ TCppType_t GetCanonicalType(TCppType_t type) {
17581882 if (!type)
17591883 return 0 ;
17601884 QualType QT = QualType::getFromOpaquePtr (type);
1885+ if (QT->getAs <clang::TemplateTypeParmType>())
1886+ return type;
17611887 return QT.getCanonicalType ().getAsOpaquePtr ();
17621888}
17631889
@@ -3841,6 +3967,25 @@ bool IsConstMethod(TCppFunction_t method) {
38413967 return false ;
38423968}
38433969
3970+ TCppIndex_t GetTemplateNumArgs (TCppScope_t scope) {
3971+ auto *D = static_cast <Decl*>(scope);
3972+ if (auto *TD = llvm::dyn_cast<TemplateDecl>(D)) {
3973+ auto *TPL = TD->getTemplateParameters ();
3974+ return TPL->size ();
3975+ }
3976+ return -1 ;
3977+ }
3978+
3979+ std::string GetTemplateArgName (TCppScope_t scope, TCppIndex_t param_index) {
3980+ auto *D = static_cast <Decl*>(scope);
3981+ if (auto *TD = llvm::dyn_cast<TemplateDecl>(D)) {
3982+ auto *TPL = TD->getTemplateParameters ();
3983+ NamedDecl *ND = TPL->getParam (param_index);
3984+ return ND->getNameAsString ();
3985+ }
3986+ return " " ;
3987+ }
3988+
38443989std::string GetFunctionArgName (TCppFunction_t func, TCppIndex_t param_index) {
38453990 auto * D = (clang::Decl*)func;
38463991 clang::ParmVarDecl* PI = nullptr ;
0 commit comments