/*
* 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 .
*/
#include "analysis/function.h"
#include "command.h"
#include "logger.h"
#include "analysis/analysis.h"
#include "analysis/walkitem.h"
#include "nodes/decl/function_decl.h"
#include "nodes/list/tree_list.h"
#include
#include "localconsts.h"
namespace Analysis
{
// put arg types into arr
void getFunctionArgTypes(FunctionDeclNode *node,
std::vector &arr)
{
// function not have type
if (!node->functionType)
return;
// walk in TREE_LIST and get value nodes
FOR_TREE_LIST2(list, node->functionType->argTypes)
{
arr.push_back(static_cast(list->value));
}
}
// find in TREE_LIST purpose with given label and get value
TreeListNode *findTreeListPurposeValue(TreeListNode *list,
const std::string &name)
{
FOR_TREE_LIST(list)
{
if (list->purpose && list->purpose->label == name)
{
return static_cast(list->value);
}
}
return nullptr;
}
void getFunctionParamsNonNullAttributes(FunctionDeclNode *node,
std::set &arr)
{
// function not have type
if (!node->functionType)
return;
TreeListNode *list = findTreeListPurposeValue(
static_cast(node->functionType->attribute),
"nonnull");
// no attribute nonnull
if (!list)
return;
// get all labels from TREE_LIST and convert to int.
// tree based on constants for attribute nonnull
FOR_TREE_LIST(list)
{
if (list->value)
{
arr.insert(atoi(list->value->label.c_str()));
}
}
}
WalkItem analyseFunction(FunctionDeclNode *node, WalkItem wi)
{
// ignore external functions
if (node->isExternal)
{
wi.stopWalking = true;
return wi;
}
std::vector types;
std::set nonNull;
WalkItem wi2 = wi;
getFunctionArgTypes(node, types);
getFunctionParamsNonNullAttributes(node, nonNull);
// here need check is variables already present in wi2.checkNullVars
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];
if (type->nodeType != POINTER_TYPE)
continue;
const ParmDeclNode *const name = node->args[f];
if (nonNull.find(f + 1) == nonNull.end())
{
if (command == Command::FindArgs)
{
Log::log("%s %s, ",
type->nodeTypeName.c_str(),
name->label.c_str());
}
wi2.checkNullVars.insert(name->label);
}
}
if (command == Command::FindArgs)
Log::log("\n");
if (!wi2.checkNullVars.empty())
{
walkTree(node->code, wi2);
}
wi.stopWalking = true;
return wi;
}
}