summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.files6
-rw-r--r--src/analysis/analysis.cpp52
-rw-r--r--src/analysis/analysis.h34
-rw-r--r--src/analysis/function.cpp129
-rw-r--r--src/analysis/function.h40
-rw-r--r--src/logger.cpp13
-rw-r--r--src/logger.h3
-rw-r--r--src/nodes/base/node.h6
-rw-r--r--src/parsers/generic.cpp7
-rw-r--r--src/parsers/list/tree_list.cpp2
-rw-r--r--src/plugin.cpp8
11 files changed, 291 insertions, 9 deletions
diff --git a/src/Makefile.files b/src/Makefile.files
index 3fcc67a..b338808 100644
--- a/src/Makefile.files
+++ b/src/Makefile.files
@@ -1,4 +1,8 @@
-SRC = nodes/base/cst.h \
+SRC = analysis/analysis.cpp \
+ analysis/analysis.h \
+ analysis/function.cpp \
+ analysis/function.h \
+ nodes/base/cst.h \
nodes/base/decl.h \
nodes/base/expr.h \
nodes/base/node.h \
diff --git a/src/analysis/analysis.cpp b/src/analysis/analysis.cpp
new file mode 100644
index 0000000..fa1672c
--- /dev/null
+++ b/src/analysis/analysis.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Andrei Karas
+ *
+ * This file is part of AstDumper.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "analysis/analysis.h"
+
+#include "command.h"
+
+#include "analysis/function.h"
+
+#include "nodes/decl/function_decl.h"
+
+#include "localconsts.h"
+
+namespace Analysis
+{
+
+void walkTree(Node *node)
+{
+ analyseNode(node);
+
+ FOR_EACH (std::vector<Node*>::iterator, it, node->childs)
+ {
+ walkTree(*it);
+ }
+}
+
+void analyseNode(Node *node)
+{
+ // searching function declaration
+ if (node->nodeType == FUNCTION_DECL)
+ {
+ analyseFunction(static_cast<FunctionDeclNode*>(node));
+ }
+}
+
+}
diff --git a/src/analysis/analysis.h b/src/analysis/analysis.h
new file mode 100644
index 0000000..64ecffd
--- /dev/null
+++ b/src/analysis/analysis.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Andrei Karas
+ *
+ * This file is part of AstDumper.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ANALYSIS_ANALYSIS_H
+#define ANALYSIS_ANALYSIS_H
+
+#include "includes.h"
+
+struct Node;
+
+namespace Analysis
+{
+ void walkTree(Node *node);
+
+ void analyseNode(Node *node);
+}
+
+#endif // ANALYSIS_ANALYSIS_H
diff --git a/src/analysis/function.cpp b/src/analysis/function.cpp
new file mode 100644
index 0000000..21d81ef
--- /dev/null
+++ b/src/analysis/function.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 Andrei Karas
+ *
+ * This file is part of AstDumper.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "analysis/function.h"
+
+#include "command.h"
+#include "logger.h"
+
+#include "nodes/decl/function_decl.h"
+
+#include "nodes/list/tree_list.h"
+
+#include <set>
+
+#include "localconsts.h"
+
+namespace Analysis
+{
+
+// walking TREE_LIST and getting all types
+void getTypesFromTreeList(TreeListNode *list,
+ std::vector<TypeNode*> &arr)
+{
+ while (list)
+ {
+ arr.push_back(static_cast<TypeNode*>(list->value));
+ list = static_cast<TreeListNode*>(list->chain);
+ }
+}
+
+// put arg types into arr
+void getFunctionArgTypes(FunctionDeclNode *node,
+ std::vector<TypeNode*> &arr)
+{
+ // function not have type
+ if (!node->functionType)
+ return;
+ getTypesFromTreeList(node->functionType->argTypes, arr);
+}
+
+TreeListNode *findTreeListPurposeValue(TreeListNode *list,
+ const std::string &name)
+{
+ while (list)
+ {
+ if (list->purpose->label == name)
+ {
+ return static_cast<TreeListNode*>(list->value);
+ }
+ list = static_cast<TreeListNode*>(list->chain);
+ }
+ return nullptr;
+}
+
+void getFunctionParamsNonNullAttributes(FunctionDeclNode *node,
+ std::set<int> &arr)
+{
+ // function not have type
+ if (!node->functionType)
+ return;
+ TreeListNode *list = findTreeListPurposeValue(
+ static_cast<TreeListNode*>(node->functionType->attribute),
+ "nonnull");
+ // no attribute nonnull
+ if (!list)
+ return;
+ while (list)
+ {
+ if (list->value)
+ {
+ arr.insert(atoi(list->value->label.c_str()));
+ }
+ list = static_cast<TreeListNode*>(list->chain);
+ }
+}
+
+void analyseFunction(FunctionDeclNode *node)
+{
+ // ignore external functions
+ if (node->isExternal)
+ return;
+
+ std::vector<TypeNode*> types;
+ std::set<int> nonNull;
+
+ getFunctionArgTypes(node, types);
+ getFunctionParamsNonNullAttributes(node, nonNull);
+ if (command == Command::FindArgs)
+ {
+ Log::log("%s: ", node->label.c_str());
+ const int sz = node->args.size();
+ for (int f = 0; f < sz; f ++)
+ {
+ const TypeNode *const type = types[f];
+ const ParmDeclNode *const name = node->args[f];
+ if (nonNull.find(f + 1) != nonNull.end())
+ {
+ Log::log("%s %s nonnull, ",
+ type->nodeTypeName.c_str(),
+ name->label.c_str());
+ }
+ else
+ {
+ Log::log("%s %s, ",
+ type->nodeTypeName.c_str(),
+ name->label.c_str());
+ }
+ }
+ Log::log("\n");
+ }
+}
+
+}
diff --git a/src/analysis/function.h b/src/analysis/function.h
new file mode 100644
index 0000000..04e3e01
--- /dev/null
+++ b/src/analysis/function.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 Andrei Karas
+ *
+ * This file is part of AstDumper.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ANALYSIS_FUNCTION_H
+#define ANALYSIS_FUNCTION_H
+
+#include "includes.h"
+
+struct FunctionDeclNode;
+struct TreeListNode;
+struct TypeNode;
+
+namespace Analysis
+{
+ void analyseFunction(FunctionDeclNode *node);
+
+ void getFunctionArgTypes(FunctionDeclNode *node,
+ std::vector<TypeNode*> &arr);
+
+ void getTypesFromTreeList(TreeListNode *list,
+ std::vector<TypeNode*> &arr);
+}
+
+#endif // ANALYSIS_FUNCTION_H
diff --git a/src/logger.cpp b/src/logger.cpp
index 13df3ed..34fb90c 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -78,6 +78,15 @@ void error(const char *const text,
va_end(ap);
}
+void log(const char *const text,
+ ...)
+{
+ va_list ap;
+ va_start(ap, text);
+ vfprintf(stderr, text, ap);
+ va_end(ap);
+}
+
void dumpInt(const Node *const node,
const char *const text,
const int val)
@@ -124,7 +133,7 @@ void dump(const Node *const node)
fprintf(stderr,
"%d %s %s\n",
node->indent,
- node->nodeType.c_str(),
+ node->nodeTypeName.c_str(),
node->file.c_str());
return;
}
@@ -138,7 +147,7 @@ void dump(const Node *const node)
return;
}
fprintf(stderr, "%s", node->getIndent().c_str());
- fprintf(stderr, "%s", node->nodeType.c_str());
+ fprintf(stderr, "%s", node->nodeTypeName.c_str());
if (!node->label.empty())
fprintf(stderr, " %s", node->label.c_str());
if (!node->file.empty())
diff --git a/src/logger.h b/src/logger.h
index 76ebddf..771d1f8 100644
--- a/src/logger.h
+++ b/src/logger.h
@@ -37,6 +37,9 @@ namespace Log
void error(const char *const text,
...);
+ void log(const char *const text,
+ ...);
+
void dumpInt(const Node *const node,
const char *const text,
const int val);
diff --git a/src/nodes/base/node.h b/src/nodes/base/node.h
index d6b42ad..d29cb5a 100644
--- a/src/nodes/base/node.h
+++ b/src/nodes/base/node.h
@@ -30,12 +30,13 @@ struct Node
{
Node() :
parent(nullptr),
- nodeType(),
+ nodeTypeName(),
label(),
file(),
tag(),
childs(),
gccNode(nullptr),
+ nodeType(ERROR_MARK),
line(-1),
column(-1),
treeNumber(0),
@@ -59,12 +60,13 @@ struct Node
}
Node *parent;
- std::string nodeType;
+ std::string nodeTypeName;
std::string label;
std::string file;
std::string tag;
std::vector<Node*> childs;
tree gccNode;
+ tree_code nodeType;
int line;
int column;
int treeNumber;
diff --git a/src/parsers/generic.cpp b/src/parsers/generic.cpp
index a7195a4..a749fad 100644
--- a/src/parsers/generic.cpp
+++ b/src/parsers/generic.cpp
@@ -102,14 +102,14 @@ Node *createParseNode(Node *parent,
Log::dump(node,
"Wrong node type. Want %s but get %s",
get_tree_code_name(wantType),
- node->nodeType.c_str());
+ node->nodeTypeName.c_str());
}
else
{
Log::dump(node,
"Wrong node type. Want %s but get %s - %s",
get_tree_code_name(wantType),
- node->nodeType.c_str(),
+ node->nodeTypeName.c_str(),
tag.c_str());
}
if (!parent)
@@ -163,7 +163,8 @@ void fillType(Node *node)
}
node->treeNumber = static_cast<int>(TREE_CODE(node->gccNode));
- node->nodeType = get_tree_code_name(TREE_CODE(node->gccNode));
+ node->nodeType = TREE_CODE(node->gccNode);
+ node->nodeTypeName = get_tree_code_name(TREE_CODE(node->gccNode));
// Log::dump(node);
}
diff --git a/src/parsers/list/tree_list.cpp b/src/parsers/list/tree_list.cpp
index 2b48899..bcc16ef 100644
--- a/src/parsers/list/tree_list.cpp
+++ b/src/parsers/list/tree_list.cpp
@@ -52,7 +52,7 @@ void parseTreeListNode(TreeListNode *node)
node->chain = createParseNode(
node,
TREE_CHAIN(node->gccNode),
- node->tag);
+ "chain");
/* look like infinite loop
FOR_CHAIN(node->gccNode, it, TREE_CHAIN, TREE_CHAIN)
diff --git a/src/plugin.cpp b/src/plugin.cpp
index 7499a54..ffd86f9 100644
--- a/src/plugin.cpp
+++ b/src/plugin.cpp
@@ -25,6 +25,8 @@
#include "command.h"
+#include "analysis/analysis.h"
+
#include "parsers/generic.h"
#include "localconsts.h"
@@ -39,6 +41,8 @@ static void pre_generic(void *gcc_data,
void *user_data A_UNUSED)
{
Node *node = Generic::parseNodes((tree)gcc_data);
+ if (command == Command::FindArgs)
+ Analysis::walkTree(node);
Generic::cleanAllNodes(node);
}
@@ -73,6 +77,10 @@ int plugin_init (struct plugin_name_args *plugin_info,
{
command = Command::DumpUnsupported;
}
+ else if (cmd == "findargs")
+ {
+ command = Command::FindArgs;
+ }
else
{
error("Plugin %s. Unknown command: %s",