diff --git a/bin/app/data/src/test2/header.h b/bin/app/data/src/test2/header.h index efe15fc3..65d3600b 100644 --- a/bin/app/data/src/test2/header.h +++ b/bin/app/data/src/test2/header.h @@ -1,4 +1,4 @@ -template +template class TemplateTestClass { }; diff --git a/bin/test/data/log/test_log.txt b/bin/test/data/log/test_log.txt index 41b51725..2bfb2e81 100644 --- a/bin/test/data/log/test_log.txt +++ b/bin/test/data/log/test_log.txt @@ -1,25 +1,4 @@ ConfigManager.cpp ERROR: value path/to/nowhere is not present in config. -Token.cpp ERROR: Location Id was not referenced by this Token. -Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class -Edge.cpp ERROR: Nodes are not plain copies. -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Storage.cpp INFO: class: A -Storage.cpp INFO: method: A::A -Storage.cpp INFO: global usage: A::A -> A::count -Storage.cpp INFO: method: A::getCount -Storage.cpp INFO: global usage: A::getCount -> A::count -Storage.cpp INFO: method: A::process -Storage.cpp INFO: field: A::count -Storage.cpp INFO: class: B -Storage.cpp INFO: inheritance: B : A -Storage.cpp INFO: method: B::process -Storage.cpp INFO: type usage: B::process -> int -Storage.cpp INFO: function: main -Storage.cpp INFO: type usage: main -> B -Storage.cpp INFO: call: main -> B::B -Storage.cpp INFO: call: main -> A::getCount Storage.cpp INFO: class: A Storage.cpp INFO: method: A::A Storage.cpp INFO: global usage: A::A -> A::count @@ -52,6 +31,27 @@ SearchMatch.cpp INFO: 237 A::A ^^^^ +Storage.cpp INFO: class: A +Storage.cpp INFO: method: A::A +Storage.cpp INFO: global usage: A::A -> A::count +Storage.cpp INFO: method: A::getCount +Storage.cpp INFO: global usage: A::getCount -> A::count +Storage.cpp INFO: method: A::process +Storage.cpp INFO: field: A::count +Storage.cpp INFO: class: B +Storage.cpp INFO: inheritance: B : A +Storage.cpp INFO: method: B::process +Storage.cpp INFO: type usage: B::process -> int +Storage.cpp INFO: function: main +Storage.cpp INFO: type usage: main -> B +Storage.cpp INFO: call: main -> B::B +Storage.cpp INFO: call: main -> A::getCount +Token.cpp ERROR: Location Id was not referenced by this Token. +Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class +Edge.cpp ERROR: Nodes are not plain copies. +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined Settings.cpp WARNING: File for Settings not found. ConfigManager.cpp ERROR: value Bool is not present in config. ConfigManager.cpp ERROR: value Int is not present in config. @@ -67,6 +67,7 @@ ConfigManager.cpp ERROR: value Int is not present in config. ConfigManager.cpp ERROR: value Float is not present in config. ConfigManager.cpp ERROR: value String is not present in config. ConfigManager.cpp ERROR: value NewBool is not present in config. +Graph.cpp ERROR: Can't remove member edge, without removing the child node. Storage.cpp INFO: typedef: type -> int Storage.cpp INFO: class: Class Storage.cpp INFO: struct: Struct @@ -119,7 +120,6 @@ Storage.cpp INFO: call: main -> isTrue Storage.cpp INFO: function: isTrue Storage.cpp INFO: function: main Storage.cpp INFO: call: main -> isTrue -Graph.cpp ERROR: Can't remove member edge, without removing the child node. TextAccess.cpp WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 3 > 2 TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8 TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8 diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 69395184..f95feacd 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -496,6 +496,18 @@ Id Storage::onTemplateRecordArgumentTypeParsed( return 0; } +Id Storage::onTemplateDefaultArgumentTypeParsed( + const ParseTypeUsage& defaultArgumentType, const std::vector& templateArgumentTypeNameHierarchy) +{ + log("template default argument", utility::join(defaultArgumentType.dataType.getTypeNameHierarchy(), "::") + " -> " + utility::join(templateArgumentTypeNameHierarchy, "::"), defaultArgumentType.location); + Node* templateDefaultArgumentNode = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, defaultArgumentType.dataType.getTypeNameHierarchy()); + addTokenLocation(templateDefaultArgumentNode, defaultArgumentType.location); + Node* templateArgumentNode = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, templateArgumentTypeNameHierarchy); + Edge* edge = m_graph.createEdge(Edge::EDGE_TEMPLATE_DEFAULT_ARGUMENT_OF, templateDefaultArgumentNode, templateArgumentNode); + + return 0; +} + Id Storage::onTemplateRecordSpecializationParsed( const ParseLocation& location, const std::vector& specializedRecordNameHierarchy, const RecordType specializedRecordType, const std::vector& specializedFromNameHierarchy) diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 7314c202..bba74580 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -87,6 +87,8 @@ public: virtual Id onTemplateRecordArgumentTypeParsed( const ParseLocation& location, const std::vector& templateArgumentTypeNameHierarchy, const std::vector& templateRecordNameHierarchy); + virtual Id onTemplateDefaultArgumentTypeParsed( + const ParseTypeUsage& type, const std::vector& templateArgumentTypeNameHierarchy); virtual Id onTemplateRecordSpecializationParsed( const ParseLocation& location, const std::vector& specializedRecordNameHierarchy, diff --git a/src/lib/data/graph/Edge.h b/src/lib/data/graph/Edge.h index 35d017ed..be7850cf 100644 --- a/src/lib/data/graph/Edge.h +++ b/src/lib/data/graph/Edge.h @@ -17,20 +17,21 @@ public: typedef int EdgeTypeMask; enum EdgeType : EdgeTypeMask { - EDGE_MEMBER = 0x1, - EDGE_TYPE_OF = 0x2, - EDGE_RETURN_TYPE_OF = 0x4, - EDGE_PARAMETER_TYPE_OF = 0x8, - EDGE_TYPE_USAGE = 0x10, - EDGE_USAGE = 0x20, - EDGE_CALL = 0x40, - EDGE_INHERITANCE = 0x80, - EDGE_TYPEDEF_OF = 0x100, - EDGE_TEMPLATE_PARAMETER_OF = 0x200, - EDGE_TEMPLATE_ARGUMENT_OF = 0x400, - EDGE_TEMPLATE_SPECIALIZATION_OF = 0x800, + EDGE_MEMBER = 0x1, + EDGE_TYPE_OF = 0x2, + EDGE_RETURN_TYPE_OF = 0x4, + EDGE_PARAMETER_TYPE_OF = 0x8, + EDGE_TYPE_USAGE = 0x10, + EDGE_USAGE = 0x20, + EDGE_CALL = 0x40, + EDGE_INHERITANCE = 0x80, + EDGE_TYPEDEF_OF = 0x100, + EDGE_TEMPLATE_PARAMETER_OF = 0x200, + EDGE_TEMPLATE_ARGUMENT_OF = 0x400, + EDGE_TEMPLATE_DEFAULT_ARGUMENT_OF = 0x800, + EDGE_TEMPLATE_SPECIALIZATION_OF = 0x1000, - EDGE_AGGREGATION = 0x1000 + EDGE_AGGREGATION = 0x2000 }; Edge(EdgeType type, Node* from, Node* to); diff --git a/src/lib/data/parser/ParserClient.h b/src/lib/data/parser/ParserClient.h index 9a40a276..b52a7668 100644 --- a/src/lib/data/parser/ParserClient.h +++ b/src/lib/data/parser/ParserClient.h @@ -103,6 +103,8 @@ public: virtual Id onTemplateRecordArgumentTypeParsed( const ParseLocation& location, const std::vector& templateArgumentTypeNameHierarchy, const std::vector& templateRecordNameHierarchy) = 0; + virtual Id onTemplateDefaultArgumentTypeParsed( + const ParseTypeUsage& type, const std::vector& templateArgumentTypeNameHierarchy) = 0; virtual Id onTemplateRecordSpecializationParsed( const ParseLocation& location, const std::vector& specializedRecordNameHierarchy, const RecordType specializedRecordType, const std::vector& specializedFromNameHierarchy) = 0; diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index 6338ad92..8d01ac3a 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -266,7 +266,18 @@ bool ASTVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl* declaration) utility::getDeclNameHierarchy(declaration) ); } + return true; +} +bool ASTVisitor::VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl *declaration) +{ + if (declaration->hasDefaultArgument()) + { + m_client->onTemplateDefaultArgumentTypeParsed( + getParseTypeUsage(declaration->getDefaultArgumentInfo()->getTypeLoc(), declaration->getDefaultArgument()), + utility::getDeclNameHierarchy(declaration) + ); + } return true; } diff --git a/src/lib/data/parser/cxx/ASTVisitor.h b/src/lib/data/parser/cxx/ASTVisitor.h index 52e7a562..32b684e7 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.h +++ b/src/lib/data/parser/cxx/ASTVisitor.h @@ -36,6 +36,7 @@ public: virtual bool VisitEnumDecl(clang::EnumDecl* declaration); // enums virtual bool VisitEnumConstantDecl(clang::EnumConstantDecl* declaration); // enum fields + virtual bool VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl *declaration); virtual bool VisitClassTemplateDecl(clang::ClassTemplateDecl* declaration); virtual bool VisitClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* declaration); virtual bool VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *declaration); diff --git a/src/lib/data/parser/cxx/utilityCxx.cpp b/src/lib/data/parser/cxx/utilityCxx.cpp index b1ef2bf2..e07b6f35 100644 --- a/src/lib/data/parser/cxx/utilityCxx.cpp +++ b/src/lib/data/parser/cxx/utilityCxx.cpp @@ -121,7 +121,14 @@ namespace utility LOG_ERROR("unhandled declaration type"); } contextNameHierarchy = getContextNameHierarchy(declaration->getDeclContext()); - contextNameHierarchy.push_back(declName); + if (clang::isa(declaration)) + { + contextNameHierarchy.back() += "::" + declName; + } + else + { + contextNameHierarchy.push_back(declName); + } } return contextNameHierarchy; } diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index c2351e47..f2735de2 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -1445,6 +1445,19 @@ public: TS_ASSERT_EQUALS(client->methods[0], "private A::T A::foo() <4:4 4:6>"); } + void test_cxx_parser_finds_template_default_argument_type_of_template_class() + { + std::shared_ptr client = parseCode( + "template \n" + "class A\n" + "{\n" + "};\n" + ); + + TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 1); + TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes[0], "int -> A::T <1:24 1:26>"); + } + @@ -1725,6 +1738,15 @@ private: return 0; } + virtual Id onTemplateDefaultArgumentTypeParsed( + const ParseTypeUsage& defaultArgumentType, const std::vector& templateArgumentTypeNameHierarchy) + { + templateDefaultArgumentTypes.push_back( + addLocationSuffix(utility::join(defaultArgumentType.dataType.getTypeNameHierarchy(), "::") + " -> " + utility::join(templateArgumentTypeNameHierarchy, "::"), defaultArgumentType.location) + ); + return 0; + } + virtual Id onTemplateRecordSpecializationParsed( const ParseLocation& location, const std::vector& specializedRecordNameHierarchy, const RecordType specializedRecordType, const std::vector& specializedFromNameHierarchy) @@ -1774,6 +1796,7 @@ private: std::vector typeUses; // for types std::vector templateParameterTypes; std::vector templateArgumentTypes; + std::vector templateDefaultArgumentTypes; std::vector templateSpecializations; private: