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 ();
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,51 @@ 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+
903+ if (!D || !isa<NamespaceDecl>(D))
904+ return ;
905+
906+ auto * NSD = dyn_cast<NamespaceDecl>(D)->getMostRecentDecl ();
907+ while (NSD) {
908+ for (Decl* DI : NSD->decls ()) {
909+ if (auto * MD = dyn_cast<DeclType>(DI))
910+ members.push_back (MD);
911+ else if (auto * USD = dyn_cast<UsingShadowDecl>(DI)) {
912+ if (auto *MD = dyn_cast<DeclType>(USD->getTargetDecl ()))
913+ members.push_back (MD);
914+ }
915+ }
916+ NSD = NSD->getPreviousDecl ();
917+ }
918+ }
919+
920+ void GetDatamembersInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
921+ GetNamespaceDecls<VarDecl>(ns, members);
922+ }
923+
924+ void GetFunctionsInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
925+ GetNamespaceDecls<FunctionDecl>(ns, members);
926+ }
927+
928+ void GetClassInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
929+ GetNamespaceDecls<RecordDecl>(ns, members);
930+ }
931+
932+ void GetTemplatedClassInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
933+ GetNamespaceDecls<ClassTemplateDecl>(ns, members);
934+ }
935+
936+ void GetTemplatedFunctionsInNamespace (TCppScope_t ns, std::vector<TCppScope_t>& members) {
937+ GetNamespaceDecls<FunctionTemplateDecl>(ns, members);
938+ }
939+
880940template <typename DeclType>
881941static void GetClassDecls (TCppScope_t klass,
882942 std::vector<TCppFunction_t>& methods) {
@@ -888,6 +948,10 @@ static void GetClassDecls(TCppScope_t klass,
888948 if (auto * TD = dyn_cast<TypedefNameDecl>(D))
889949 D = GetScopeFromType (TD->getUnderlyingType ());
890950
951+ if (auto *CTD = llvm::dyn_cast_or_null<ClassTemplateDecl>(D)) {
952+ D = CTD->getTemplatedDecl ();
953+ }
954+
891955 if (!D || !isa<CXXRecordDecl>(D))
892956 return ;
893957
@@ -1011,7 +1075,7 @@ TCppType_t GetFunctionReturnType(TCppFunction_t func) {
10111075 QualType Type = FD->getReturnType ();
10121076 if (Type->isUndeducedAutoType ()) {
10131077 bool needInstantiation = false ;
1014- if (IsTemplatedFunction (FD) && !FD->isDefined ())
1078+ if (IsTemplateInstantiationOrSpecialization (FD) && !FD->isDefined ())
10151079 needInstantiation = true ;
10161080 if (auto * MD = llvm::dyn_cast<clang::CXXMethodDecl>(FD)) {
10171081 if (IsTemplateSpecialization (MD->getParent ()))
@@ -1055,8 +1119,10 @@ TCppIndex_t GetFunctionRequiredArgs(TCppConstFunction_t func) {
10551119}
10561120
10571121TCppType_t GetFunctionArgType (TCppFunction_t func, TCppIndex_t iarg) {
1058- auto * D = (clang::Decl*)func;
1059-
1122+ auto * D = static_cast <clang::Decl*>(func);
1123+ if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
1124+ D = FTD->getTemplatedDecl ();
1125+ }
10601126 if (auto * FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(D)) {
10611127 if (iarg < FD->getNumParams ()) {
10621128 auto * PVD = FD->getParamDecl (iarg);
@@ -1122,7 +1188,12 @@ bool IsFunctionDeleted(TCppConstFunction_t function) {
11221188
11231189bool IsTemplatedFunction (TCppFunction_t func) {
11241190 auto * D = (Decl*)func;
1125- return IsTemplatedFunction (D) || IsTemplateInstantiationOrSpecialization (D);
1191+ return IsTemplatedFunction (D) /* || IsTemplateInstantiationOrSpecialization(D)*/ ;
1192+ }
1193+
1194+ bool IsTemplateInstantiationOrSpecialization (TCppScope_t scope) {
1195+ auto *D = static_cast <Decl*>(scope);
1196+ return IsTemplateInstantiationOrSpecialization (D);
11261197}
11271198
11281199// FIXME: This lookup is broken, and should no longer be used in favour of
@@ -1334,6 +1405,9 @@ bool IsDestructor(TCppConstFunction_t method) {
13341405
13351406bool IsStaticMethod (TCppConstFunction_t method) {
13361407 const auto * D = static_cast <const Decl*>(method);
1408+ if (auto *FTD = llvm::dyn_cast_or_null<FunctionTemplateDecl>(D)) {
1409+ D = FTD->getTemplatedDecl ();
1410+ }
13371411 if (auto * CXXMD = llvm::dyn_cast_or_null<CXXMethodDecl>(D)) {
13381412 return CXXMD->isStatic ();
13391413 }
@@ -1404,6 +1478,9 @@ bool IsVirtualMethod(TCppFunction_t method) {
14041478
14051479void GetDatamembers (TCppScope_t scope, std::vector<TCppScope_t>& datamembers) {
14061480 auto * D = (Decl*)scope;
1481+ if (auto *CTD = llvm::dyn_cast_or_null<ClassTemplateDecl>(D)) {
1482+ D = CTD->getTemplatedDecl ();
1483+ }
14071484
14081485 if (auto * CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
14091486 getSema ().ForceDeclarationOfImplicitMembers (CXXRD);
@@ -1497,7 +1574,7 @@ TCppType_t GetVariableType(TCppScope_t var) {
14971574 QualType QT = DD->getType ();
14981575
14991576 // Check if the type is a typedef type
1500- if (QT->isTypedefNameType ()) {
1577+ if (QT->isTypedefNameType () || QT-> getAs <clang::TemplateTypeParmType>() ) {
15011578 return QT.getAsOpaquePtr ();
15021579 }
15031580
@@ -1758,6 +1835,8 @@ TCppType_t GetCanonicalType(TCppType_t type) {
17581835 if (!type)
17591836 return 0 ;
17601837 QualType QT = QualType::getFromOpaquePtr (type);
1838+ if (QT->getAs <clang::TemplateTypeParmType>())
1839+ return type;
17611840 return QT.getCanonicalType ().getAsOpaquePtr ();
17621841}
17631842
@@ -3841,6 +3920,25 @@ bool IsConstMethod(TCppFunction_t method) {
38413920 return false ;
38423921}
38433922
3923+ TCppIndex_t GetTemplateNumArgs (TCppScope_t scope) {
3924+ auto *D = static_cast <Decl*>(scope);
3925+ if (auto *TD = llvm::dyn_cast<TemplateDecl>(D)) {
3926+ auto *TPL = TD->getTemplateParameters ();
3927+ return TPL->size ();
3928+ }
3929+ return -1 ;
3930+ }
3931+
3932+ std::string GetTemplateArgName (TCppScope_t scope, TCppIndex_t param_index) {
3933+ auto *D = static_cast <Decl*>(scope);
3934+ if (auto *TD = llvm::dyn_cast<TemplateDecl>(D)) {
3935+ auto *TPL = TD->getTemplateParameters ();
3936+ NamedDecl *ND = TPL->getParam (param_index);
3937+ return ND->getNameAsString ();
3938+ }
3939+ return " " ;
3940+ }
3941+
38443942std::string GetFunctionArgName (TCppFunction_t func, TCppIndex_t param_index) {
38453943 auto * D = (clang::Decl*)func;
38463944 clang::ParmVarDecl* PI = nullptr ;
0 commit comments