data: fixed crash when parsing initialization of global variable

handled visiting of global variable usage in initialization of another global variable.
This commit is contained in:
malte_langkabel
2015-02-09 11:20:01 +01:00
parent af1462f955
commit 4da51180ca
9 changed files with 82 additions and 23 deletions
+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
+14
View File
@@ -412,6 +412,20 @@ Id Storage::onGlobalVariableUsageParsed( // or static variable used
return onVariableUsageParsed("global usage", location, user, usedNameHierarchy);
}
Id Storage::onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseVariable& user, const std::vector<std::string>& usedNameHierarchy)
{
log("global usage", user.getFullName() + " -> " + utility::join(usedNameHierarchy, "::"), location);
Node* userNode = addNodeHierarchy(Node::NODE_UNDEFINED_VARIABLE, user.nameHierarchy);
Node* usedNode = addNodeHierarchy(Node::NODE_UNDEFINED_VARIABLE, usedNameHierarchy);
Edge* edge = m_graph.createEdge(Edge::EDGE_USAGE, userNode, usedNode);
addTokenLocation(edge, location);
return edge->getId();
}
Id Storage::onEnumFieldUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy
){
+2
View File
@@ -74,6 +74,8 @@ public:
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy);
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy);
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseVariable& user, const std::vector<std::string>& usedNameHierarchy);
virtual Id onEnumFieldUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy);
virtual Id onEnumFieldUsageParsed(
+2
View File
@@ -90,6 +90,8 @@ public:
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy) = 0;
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy) = 0;
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseVariable& user, const std::vector<std::string>& usedNameHierarchy) = 0;
virtual Id onEnumFieldUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy) = 0;
virtual Id onEnumFieldUsageParsed(
+8 -1
View File
@@ -89,7 +89,14 @@ void ASTBodyVisitor::VisitDeclRefExpr(clang::make_ptr<clang::DeclRefExpr>::type
{
if (expr->getDecl()->getKind() == clang::Decl::Var && expr->getDecl()->isDefinedOutsideFunctionOrMethod())
{
m_client->VisitGlobalVariableExprInDeclBody(m_functionDecl, expr);
if (m_functionDecl)
{
m_client->VisitGlobalVariableExprInDeclBody(m_functionDecl, expr);
}
else
{
m_client->VisitGlobalVariableExprInDeclBody(m_varDecl, expr);
}
}
else if (expr->getDecl()->getKind() == clang::Decl::EnumConstant)
{
@@ -19,6 +19,7 @@ public:
virtual void VisitCXXNewExprInDeclBody(clang::VarDecl* decl, clang::CXXNewExpr* expr) = 0;
virtual void VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr) = 0;
virtual void VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0;
virtual void VisitGlobalVariableExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr) = 0;
virtual void VisitEnumExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr) = 0;
virtual void VisitEnumExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr) = 0;
virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl) = 0;
+14
View File
@@ -554,6 +554,20 @@ void ASTVisitor::VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, cl
);
}
void ASTVisitor::VisitGlobalVariableExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr)
{
ParseLocation parseLocation = getParseLocation(expr->getSourceRange());
const std::string exprName = expr->getNameInfo().getAsString();
parseLocation.endColumnNumber += exprName.size() - 1;
m_client->onGlobalVariableUsageParsed(
parseLocation,
getParseVariable(decl),
utility::getDeclNameHierarchy(expr->getDecl())
);
}
void ASTVisitor::VisitEnumExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr)
{
ParseLocation parseLocation = getParseLocation(expr->getSourceRange());
+1
View File
@@ -50,6 +50,7 @@ public:
virtual void VisitCXXNewExprInDeclBody(clang::VarDecl* decl, clang::CXXNewExpr* expr); // type use of new operator in global space
virtual void VisitMemberExprInDeclBody(clang::FunctionDecl* decl, clang::MemberExpr* expr); // field usages
virtual void VisitGlobalVariableExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // global variable usage
virtual void VisitGlobalVariableExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr); // global variable usage
virtual void VisitEnumExprInDeclBody(clang::FunctionDecl* decl, clang::DeclRefExpr* expr); // enum field usage
virtual void VisitEnumExprInDeclBody(clang::VarDecl* decl, clang::DeclRefExpr* expr); // enum field usage in global variable
virtual void VisitVarDeclInDeclBody(clang::FunctionDecl* decl, clang::VarDecl* varDecl); // type usages
+18
View File
@@ -875,6 +875,17 @@ public:
TS_ASSERT_EQUALS(client->usages[0], "int main() -> bar <5:2 5:4>");
}
void test_cxx_parser_finds_usage_of_global_variable_in_global_variable_initialization()
{
std::shared_ptr<TestParserClient> client = parseCode(
"int a = 0;\n"
"int b[] = {a};\n"
);
TS_ASSERT_EQUALS(client->usages.size(), 1);
TS_ASSERT_EQUALS(client->usages[0], "int [] b -> a <2:12 2:12>");
}
void test_cxx_parser_finds_usage_of_global_variable_in_method()
{
std::shared_ptr<TestParserClient> client = parseCode(
@@ -1692,6 +1703,13 @@ private:
return 0;
}
virtual Id onGlobalVariableUsageParsed(
const ParseLocation& location, const ParseVariable& user, const std::vector<std::string>& usedNameHierarchy)
{
usages.push_back(addLocationSuffix(variableStr(user) + " -> " + utility::join(usedNameHierarchy, "::"), location));
return 0;
}
virtual Id onEnumFieldUsageParsed(
const ParseLocation& location, const ParseFunction& user, const std::vector<std::string>& usedNameHierarchy)
{