diff --git a/plugins/cpp/model/include/model/common.h b/plugins/cpp/model/include/model/common.h index 31fa1951c..e20dd2a49 100644 --- a/plugins/cpp/model/include/model/common.h +++ b/plugins/cpp/model/include/model/common.h @@ -23,7 +23,9 @@ enum Tag Static = 3, Implicit = 4, Global = 5, - Constant = 6 + Constant = 6, + TemplateSpecialization = 7, + TemplateInstantiation = 8 // all cases other than explicit specialization }; inline std::string visibilityToString(Visibility v_) diff --git a/plugins/cpp/parser/src/clangastvisitor.h b/plugins/cpp/parser/src/clangastvisitor.h index e07e8928e..58796fae3 100644 --- a/plugins/cpp/parser/src/clangastvisitor.h +++ b/plugins/cpp/parser/src/clangastvisitor.h @@ -675,6 +675,15 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor cppRecord->isAbstract = crd->isAbstract(); cppRecord->isPOD = crd->isPOD(); + if (crd->getTemplateInstantiationPattern()) + { + cppRecord->tags.insert( + crd->getTemplateSpecializationKind() == clang::TSK_ExplicitSpecialization + ? model::Tag::TemplateSpecialization + : model::Tag::TemplateInstantiation + ); + } + //--- CppInheritance ---// for (auto it = crd->bases_begin(); it != crd->bases_end(); ++it) diff --git a/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp b/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp index a68fc5249..dabbca02d 100644 --- a/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp +++ b/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp @@ -164,6 +164,13 @@ void CppMetricsParser::typeMcCabe() if (!typeFile || !cc::util::isRootedUnderAnyOf(_inputPaths, typeFile->path)) continue; + // Skip if its a template instantiation + const auto typeEntity = _ctx.db->query_one( + odb::query::astNodeId == type.id); + if (typeEntity && typeEntity->tags.find(model::Tag::TemplateInstantiation) + != typeEntity->tags.cend()) + continue; + mcValues[type.id] = 0; // Process its methods diff --git a/plugins/cpp_metrics/test/sources/parser/typemccabe.h b/plugins/cpp_metrics/test/sources/parser/typemccabe.h index 71e0b79f7..bfcc863d1 100644 --- a/plugins/cpp_metrics/test/sources/parser/typemccabe.h +++ b/plugins/cpp_metrics/test/sources/parser/typemccabe.h @@ -95,5 +95,19 @@ class ClassWithInnerClass { }; // 3 }; // 4 +template +class TemplateClass { + T value; +public: + T get() + { + return T(); + } // 1 + void set(T t) + { + value = t; + } // 1 +}; // 2 + #endif // TYPE_MCCABE__H diff --git a/plugins/cpp_metrics/test/sources/service/typemccabe.h b/plugins/cpp_metrics/test/sources/service/typemccabe.h index 71e0b79f7..bfcc863d1 100644 --- a/plugins/cpp_metrics/test/sources/service/typemccabe.h +++ b/plugins/cpp_metrics/test/sources/service/typemccabe.h @@ -95,5 +95,19 @@ class ClassWithInnerClass { }; // 3 }; // 4 +template +class TemplateClass { + T value; +public: + T get() + { + return T(); + } // 1 + void set(T t) + { + value = t; + } // 1 +}; // 2 + #endif // TYPE_MCCABE__H diff --git a/plugins/cpp_metrics/test/src/cppmetricsparsertest.cpp b/plugins/cpp_metrics/test/src/cppmetricsparsertest.cpp index b4ad0b072..6e0f07c8b 100644 --- a/plugins/cpp_metrics/test/src/cppmetricsparsertest.cpp +++ b/plugins/cpp_metrics/test/src/cppmetricsparsertest.cpp @@ -111,6 +111,7 @@ std::vector paramTypeMcCabe = { {"ClassMethodsInsideAndOutside", 8}, {"ClassWithInnerClass", 4}, {"ClassWithInnerClass::InnerClass", 3}, + {"TemplateClass", 2}, }; TEST_P(ParameterizedTypeMcCabeTest, TypeMcCabeTest) {