cfagraph.cpp
No OneTemporary

File Metadata

Created
Sun, Sep 13, 3:26 PM

cfagraph.cpp

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* File: CFAGraph.cpp
* Author: pgess <v.melnychenko@xreate.org>
*
* Created on June 27, 2016, 2:09 PM
*/
/**
* \file cfagraph.h
* \brief Control Flow Analysis(CFA) graph representation
*/
#include "analysis/cfagraph.h"
#include "analysis/utils.h"
using namespace xreate::cfa;
using namespace std;
void
CFAGraph::print(std::ostringstream& output) const {
const std::string& atomBindingScope = Config::get("transcend.bindings.scope");
output << endl << "%\t\tStatic analysis: CFA" << endl;
output << __outputPrecomputed.str();
//declare scopes
boost::format formatScope("scope(0..%1%).");
output << formatScope % (__transcend->getScopesCount() - 1) << std::endl;
//show context rules:
for (auto rule : this->__contextRules) {
output << ContextRule(rule.second).compile(rule.first) << std::endl;
};
//parent connections
//TOTEST CFG parent function
boost::format formatFunctionParent("cfa_parent(%1%, function(\"%2%\")).");
for (const auto &relation : this->__parentFnRelation) {
const string& function = this->__fnNodes.left.at(relation.right);
output << formatFunctionParent % relation.left % function << endl;
}
//TOTEST CFG parent scope
boost::format formatScopeParent("cfa_parent(%1%, scope(%2%)).");
for (const auto &relation : this->__parentScopeRelation) {
output << formatScopeParent % relation.first % relation.second << endl;
}
//call connections
boost::format formatCall("cfa_call(%1%, \"%2%\").");
for (const auto &relation : this->__callRelations) {
const ScopePacked scopeFrom = relation.left;
const string& functionTo = this->__fnNodes.left.at(relation.right);
output << formatCall % (scopeFrom) % (functionTo) << endl;
}
//function specializations description
boost::format formatSpecializations("cfa_function_specializations(\"%1%\", %2%).");
const list<ManagedFnPtr>& functions = __transcend->ast->getAllFunctions();
for (auto f : functions) {
if (f->guard.isValid()) {
list<string> guardRaw = xreate::analysis::compile(f->guard);
assert(guardRaw.size() == 1);
output << formatSpecializations % (f->getName()) % (guardRaw.front()) << endl;
}
}
}
void
CFAGraph::addFunctionAnnotations(const std::string& fn, const std::map<std::string, Expression>& tags) {
unsigned int fid = registerNodeFunction(fn);
for (auto& tag : tags) {
__fnTags.emplace(fid, tag.second);
}
}
void
CFAGraph::addScopeAnnotations(const ScopePacked& scope, const std::vector<Expression>& tags) {
for (Expression tag : tags) {
__scopeTags.emplace(scope, tag);
}
}
void
CFAGraph::addContextRules(const ScopePacked& scope, const std::vector<Expression>& rules) {
for (Expression rule : rules) {
__contextRules.emplace(scope, rule);
}
}
void
CFAGraph::addCallConnection(const ScopePacked& callerScope, const std::string& calleeFn) {
unsigned int idFuncTo = registerNodeFunction(calleeFn);
__callRelations.insert(CALL_RELATIONS::value_type(callerScope, idFuncTo));
}
void
CFAGraph::addParentConnection(const ScopePacked& scopeEntry, const std::string& fnParent) {
__parentFnRelation.insert(PARENT_FUNCTION_RELATIONS::value_type(scopeEntry, registerNodeFunction(fnParent)));
}
void
CFAGraph::addParentConnection(const ScopePacked& scopeChild, const ScopePacked& scopeParent) {
__parentScopeRelation.emplace(scopeChild, scopeParent);
}
unsigned int
CFAGraph::registerNodeFunction(const std::string& fname) {
auto pos = __fnNodes.left.insert(make_pair(__fnNodes.size(), fname));
return pos.first->first;
}
void
CFAGraph::addScope(CodeScope* scope) {
boost::format formatScopeBinding("ast_scope_binding(%1%, %2%, \"%3%\").");
ScopePacked scopeId = __transcend->pack(scope);
__scopesCount = max(scopeId + 1, __scopesCount);
for (int id = 0, size = scope->__bindings.size(); id < size; ++id) {
__outputPrecomputed << formatScopeBinding
% scopeId
% id
% scope->__bindings.at(id)
<< endl;
}
}

Event Timeline