data: template arguments default parameters

* implemented parsing of template argument default parameters.
* added tests for default arguments of template parameters.

fortune cookie message = If you continually give, you will continually have.
This commit is contained in:
malte_langkabel
2015-02-03 16:22:48 +01:00
parent 799f324463
commit bdcca6dbad
10 changed files with 96 additions and 37 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
template <typename T, typename U>
template <typename T = int, typename U = int>
class TemplateTestClass
{
};
+22 -22
View File
@@ -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 <input.cc 1:7 1:7>
Storage.cpp INFO: method: A::A <input.cc 4:2 4:2>
Storage.cpp INFO: global usage: A::A -> A::count <input.cc 5:3 5:7>
Storage.cpp INFO: method: A::getCount <input.cc 8:13 8:20>
Storage.cpp INFO: global usage: A::getCount -> A::count <input.cc 10:10 10:14>
Storage.cpp INFO: method: A::process <input.cc 14:15 14:21>
Storage.cpp INFO: field: A::count <input.cc 17:13 17:17>
Storage.cpp INFO: class: B <input.cc 20:7 20:7>
Storage.cpp INFO: inheritance: B : A <input.cc 21:4 21:11>
Storage.cpp INFO: method: B::process <input.cc 24:15 24:21>
Storage.cpp INFO: type usage: B::process -> int <input.cc 26:3 26:5>
Storage.cpp INFO: function: main <input.cc 30:5 30:8>
Storage.cpp INFO: type usage: main -> B <input.cc 32:2 32:2>
Storage.cpp INFO: call: main -> B::B <input.cc 32:4 32:4>
Storage.cpp INFO: call: main -> A::getCount <input.cc 34:9 34:21>
Storage.cpp INFO: class: A <input.cc 1:7 1:7>
Storage.cpp INFO: method: A::A <input.cc 4:2 4:2>
Storage.cpp INFO: global usage: A::A -> A::count <input.cc 5:3 5:7>
@@ -52,6 +31,27 @@ SearchMatch.cpp INFO:
237 A::A
^^^^
Storage.cpp INFO: class: A <input.cc 1:7 1:7>
Storage.cpp INFO: method: A::A <input.cc 4:2 4:2>
Storage.cpp INFO: global usage: A::A -> A::count <input.cc 5:3 5:7>
Storage.cpp INFO: method: A::getCount <input.cc 8:13 8:20>
Storage.cpp INFO: global usage: A::getCount -> A::count <input.cc 10:10 10:14>
Storage.cpp INFO: method: A::process <input.cc 14:15 14:21>
Storage.cpp INFO: field: A::count <input.cc 17:13 17:17>
Storage.cpp INFO: class: B <input.cc 20:7 20:7>
Storage.cpp INFO: inheritance: B : A <input.cc 21:4 21:11>
Storage.cpp INFO: method: B::process <input.cc 24:15 24:21>
Storage.cpp INFO: type usage: B::process -> int <input.cc 26:3 26:5>
Storage.cpp INFO: function: main <input.cc 30:5 30:8>
Storage.cpp INFO: type usage: main -> B <input.cc 32:2 32:2>
Storage.cpp INFO: call: main -> B::B <input.cc 32:4 32:4>
Storage.cpp INFO: call: main -> A::getCount <input.cc 34:9 34:21>
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 <file.cpp 1:1 1:1>
Storage.cpp INFO: class: Class <file.cpp 1:1 1:1>
Storage.cpp INFO: struct: Struct <file.cpp 1:1 1:1>
@@ -119,7 +120,6 @@ Storage.cpp INFO: call: main -> isTrue <file.cpp 1:0 1:0>
Storage.cpp INFO: function: isTrue <file.h 1:0 1:0>
Storage.cpp INFO: function: main <file.cpp 1:0 1:0>
Storage.cpp INFO: call: main -> isTrue <file.cpp 1:0 1:0>
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
+12
View File
@@ -496,6 +496,18 @@ Id Storage::onTemplateRecordArgumentTypeParsed(
return 0;
}
Id Storage::onTemplateDefaultArgumentTypeParsed(
const ParseTypeUsage& defaultArgumentType, const std::vector<std::string>& 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<std::string>& specializedRecordNameHierarchy,
const RecordType specializedRecordType, const std::vector<std::string>& specializedFromNameHierarchy)
+2
View File
@@ -87,6 +87,8 @@ public:
virtual Id onTemplateRecordArgumentTypeParsed(
const ParseLocation& location, const std::vector<std::string>& templateArgumentTypeNameHierarchy,
const std::vector<std::string>& templateRecordNameHierarchy);
virtual Id onTemplateDefaultArgumentTypeParsed(
const ParseTypeUsage& type, const std::vector<std::string>& templateArgumentTypeNameHierarchy);
virtual Id onTemplateRecordSpecializationParsed(
const ParseLocation& location, const std::vector<std::string>& specializedRecordNameHierarchy,
+14 -13
View File
@@ -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);
+2
View File
@@ -103,6 +103,8 @@ public:
virtual Id onTemplateRecordArgumentTypeParsed(
const ParseLocation& location, const std::vector<std::string>& templateArgumentTypeNameHierarchy,
const std::vector<std::string>& templateRecordNameHierarchy) = 0;
virtual Id onTemplateDefaultArgumentTypeParsed(
const ParseTypeUsage& type, const std::vector<std::string>& templateArgumentTypeNameHierarchy) = 0;
virtual Id onTemplateRecordSpecializationParsed(
const ParseLocation& location, const std::vector<std::string>& specializedRecordNameHierarchy,
const RecordType specializedRecordType, const std::vector<std::string>& specializedFromNameHierarchy) = 0;
+11
View File
@@ -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;
}
+1
View File
@@ -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);
+8 -1
View File
@@ -121,7 +121,14 @@ namespace utility
LOG_ERROR("unhandled declaration type");
}
contextNameHierarchy = getContextNameHierarchy(declaration->getDeclContext());
contextNameHierarchy.push_back(declName);
if (clang::isa<clang::TemplateTypeParmDecl>(declaration))
{
contextNameHierarchy.back() += "::" + declName;
}
else
{
contextNameHierarchy.push_back(declName);
}
}
return contextNameHierarchy;
}
+23
View File
@@ -1445,6 +1445,19 @@ public:
TS_ASSERT_EQUALS(client->methods[0], "private A<T>::T A<T>::foo() <4:4 4:6>");
}
void test_cxx_parser_finds_template_default_argument_type_of_template_class()
{
std::shared_ptr<TestParserClient> client = parseCode(
"template <typename T = int>\n"
"class A\n"
"{\n"
"};\n"
);
TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 1);
TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes[0], "int -> A<T>::T <1:24 1:26>");
}
@@ -1725,6 +1738,15 @@ private:
return 0;
}
virtual Id onTemplateDefaultArgumentTypeParsed(
const ParseTypeUsage& defaultArgumentType, const std::vector<std::string>& 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<std::string>& specializedRecordNameHierarchy,
const RecordType specializedRecordType, const std::vector<std::string>& specializedFromNameHierarchy)
@@ -1774,6 +1796,7 @@ private:
std::vector<std::string> typeUses; // for types
std::vector<std::string> templateParameterTypes;
std::vector<std::string> templateArgumentTypes;
std::vector<std::string> templateDefaultArgumentTypes;
std::vector<std::string> templateSpecializations;
private: