cfgpass.cpp
No OneTemporary

File Metadata

Created
Wed, Jul 8, 5:45 AM

cfgpass.cpp

#include "cfgpass.h"
#include <QString>
using namespace std;
using namespace xreate;
CFGPass::CFGPass(ClaspLayer* claspLayer)
: clasp(claspLayer)
{
}
void
CFGPass::process(const Expression& entity,const Context& context)
{
switch(entity.__state)
{
case Expression::COMPOUND:
{
switch (entity.__op){
// First of all process all parameters
case Operator::CALL : case Operator::LIST: case Operator::LOOP:
for (const Expression& op: entity.operands)
{
process(op, context);
}
}
// this is what we are looking for
if (entity.__op == Operator::CALL)
{
const std::string& calleeName = entity.__valueS;
assert(clasp->ast->__indexFunctions.count(calleeName));
FID calleeId = clasp->ast->__indexFunctions.at(calleeName);
__graph.addLink(context.id, calleeId);
break;
}
if (entity.__op == Operator::LOOP)
{
assert(entity.blocks.size());
process(&(entity.blocks[0]), context);
}
break;
}
case Expression::IDENT:
const std::string& name = entity.__valueS;
//search in current scope:
if (context.scope->__vartable.count(name))
{
VID ident = context.scope->__vartable.at(name);
// if ident is scope arg then do nothing
if (! context.scope->__declarations.count(ident))
{
break;
}
// if ident declared within current scope,
const Expression& decl = context.scope->__declarations.at(ident);
process(decl, context);
}
//search in parent scope
if (context.scope->__parent)
{
Context context2 = context;
context2.scope = context.scope->__parent;
process(entity, context2);
};
}
}
void CFGPass:: process(const CodeScope* scope, Context context)
{
context.scope = scope;
process(scope->__body, context);
}
void
CFGPass::run()
{
__graph = CFGraph();
cout << "CFGPass::run" << endl;
for(FID f=0, fcount= clasp->ast->getFunctionsCount(); f<fcount; ++f)
{
const Function& func = clasp->ast->getFunctionById(f);
__graph.addNode(f, string(func.getName()));
Context context{f, nullptr};
process(&func.getEntryScope(), context);
};
clasp->addCFGData(std::move(__graph));
}

Event Timeline