Commit d905b5bd authored by Anirudh Kaushik's avatar Anirudh Kaushik
Browse files

Revamp of path enumeration logic

parent 61065098
...@@ -252,8 +252,8 @@ vector < SusCFG * >Transition::returnCodeBlocks() ...@@ -252,8 +252,8 @@ vector < SusCFG * >Transition::returnCodeBlocks()
void Transition::dump(raw_ostream & os) void Transition::dump(raw_ostream & os)
{ {
os << "\n ####### Transition #######"; os << "\n ####### Transition #######";
os << "\n Initial State : " << _initialState-> os << "\n Initial State : " << _initialState->returnSusCFGBlock()->
returnSusCFGBlock()->getBlockID(); getBlockID();
os << "\n Final State : " << _finalState->returnSusCFGBlock()->getBlockID(); os << "\n Final State : " << _finalState->returnSusCFGBlock()->getBlockID();
os << "\n Transition Blocks : "; os << "\n Transition Blocks : ";
for (unsigned int i = 0; i < _codeBlockVector.size(); i++) { for (unsigned int i = 0; i < _codeBlockVector.size(); i++) {
...@@ -273,13 +273,17 @@ SuspensionAutomata::~SuspensionAutomata() ...@@ -273,13 +273,17 @@ SuspensionAutomata::~SuspensionAutomata()
{ {
} }
void bool SuspensionAutomata::initialize()
SuspensionAutomata::initialize()
{ {
const CFG::BuildOptions & b = CFG::BuildOptions(); const CFG::BuildOptions & b = CFG::BuildOptions();
_cfg = CFG::buildCFG(cast < Decl > (_d), _d->getBody(), _a, b); _cfg = CFG::buildCFG(cast < Decl > (_d), _d->getBody(), _a, b);
if (_cfg != NULL) {
return true;
}
return false;
} }
...@@ -356,10 +360,11 @@ void SuspensionAutomata::genSusCFG() ...@@ -356,10 +360,11 @@ void SuspensionAutomata::genSusCFG()
bool foundWait = false; bool foundWait = false;
vector < CFGBlock * >splitBlocksVector; vector < CFGBlock * >splitBlocksVector;
/*
_os << "==========================================================\n"; _os << "==========================================================\n";
_os << "Dump CFG Block\n"; _os << "Dump CFG Block\n";
b->dump(_cfg, LO, false); b->dump(_cfg, LO, false);
*/
unsigned int prevCFGBlockID; unsigned int prevCFGBlockID;
for (CFGBlock::const_iterator bit = b->begin(), bite = b->end(); for (CFGBlock::const_iterator bit = b->begin(), bite = b->end();
...@@ -541,166 +546,103 @@ void SuspensionAutomata::genSusCFG() ...@@ -541,166 +546,103 @@ void SuspensionAutomata::genSusCFG()
} }
/* vector<SusCFG*> SuspensionAutomata::modifDFS(SusCFG * block, State *initialState)
void SuspensionAutomata::genSauto()
{ {
typedef map<SusCFG*, vector<SusCFG*> > stateCommonBlocksMapType; deque < SusCFG * >traversedBlocks;
typedef pair<SusCFG*, vector<SusCFG*> > stateCommonBlocksPairType; vector < SusCFG * >visitedBlocks;
typedef map < SusCFG *, State * > susCFGBlockStateMapType; traversedBlocks.push_front(block);
typedef pair < SusCFG *, State * > susCFGBlockStatePairType;
deque < SusCFG * >stateQueue; vector < SusCFG * >transitionBlocks;
vector < SusCFG * >visitedStates; while (traversedBlocks.size() != 0) {
vector < SusCFG * >visitedWaitStates; SusCFG *currentBlock = traversedBlocks.front();
deque < SusCFG * >waitStates; //_os <<"\n ModifDFS current block : " <<currentBlock->getBlockID();
traversedBlocks.pop_front();
if (currentBlock->isWaitBlock()) {
float timeInNs;
string eventName;
susCFGVectorType susCFGVector = _susCFGVector; susCFGStateMapType::iterator stateFound =
susCFGStateMap.find(currentBlock);
State *finalState = stateFound->second;
susCFGBlockStateMapType susCFGBlockStateMap; if (isTimedWait(currentBlock->getWaitStmt())) {
stateCommonBlocksMapType stateCommonBlocksMap; finalState->setTimed();
waitStates.push_back(susCFGVector.at(0)); timeInNs = getTime(currentBlock->getWaitStmt());
while (!waitStates.empty()) { } else if (isEventWait(currentBlock->getWaitStmt())) {
stateQueue.clear();
visitedStates.clear();
vector < SusCFG * >tmpCodeBlocks;
State *initial;
State *finalState;
visitedWaitStates.push_back(waitStates.back());
if (waitStates.back()->getParentSusCFGBlock()) {
visitedWaitStates.push_back(waitStates.back()->getParentSusCFGBlock());
}
if (susCFGBlockStateMap.find(waitStates.back()) ==
susCFGBlockStateMap.end()) {
initial = new State(waitStates.back(), false, false, true, false);
susCFGBlockStateMap.insert(susCFGBlockStatePairType
(waitStates.back(), initial));
} else {
susCFGBlockStateMapType::iterator stateFound =
susCFGBlockStateMap.find(waitStates.back());
initial = stateFound->second;
}
vector < SusCFG * >succBlocks = waitStates.back()->getSuccBlocks();
for (unsigned int i = 0; i < succBlocks.size(); i++) {
stateQueue.push_front(succBlocks.at(i)); finalState->setEvent();
visitedStates.push_back(succBlocks.at(i)); eventName = getEvent(currentBlock->getWaitStmt());
} else if (isDeltaWait(currentBlock->getWaitStmt())) {
finalState->setDelta();
} else {
finalState->setInitial();
} }
while (!stateQueue.empty()) {
SusCFG *currentState = stateQueue.front();
stateQueue.pop_front();
if (currentState->isParentBlock()) { // has a wait statement
vector < SusCFG * >childListBlock = currentState->getChildBlockList();
SusCFG *finalWaitBlock;
State *initialTmp = initial;
for (unsigned int i = 0; i < childListBlock.size(); i++) {
if (childListBlock.at(i)->isWaitBlock()) {
bool isTimed = false;
bool isDelta = false;
bool isEvent = false;
bool isInitial = false;
float timeInNs;
string eventName;
if (isTimedWait(childListBlock.at(i)->getWaitStmt())){
isTimed = true;
timeInNs = getTime(childListBlock.at(i)->getWaitStmt());
}
else if (isEventWait(childListBlock.at(i)->getWaitStmt())){
isEvent = true;
eventName = getEvent(childListBlock.at(i)->getWaitStmt());
}
else if (isDeltaWait(childListBlock.at(i)->getWaitStmt()))
isDelta = true;
Transition *t = new Transition(); Transition *t = new Transition();
//State *finalState;
if (susCFGBlockStateMap.find(childListBlock.at(i))
== susCFGBlockStateMap.end()) {
finalState =
new State(childListBlock.at(i), isTimed,
isDelta, isInitial, isEvent);
susCFGBlockStateMap.insert
(susCFGBlockStatePairType(childListBlock.at(i), finalState));
} else {
susCFGBlockStateMapType::iterator stateFound =
susCFGBlockStateMap.find(childListBlock.at(i));
finalState = stateFound->second;
}
finalState->addEventName(eventName); finalState->addEventName(eventName);
finalState->addSimTime(timeInNs); finalState->addSimTime(timeInNs);
t->addInitialState(initialTmp); t->addInitialState(initialState);
t->addFinalState(finalState); t->addFinalState(finalState);
t->addCodeBlocks(tmpCodeBlocks); t->addCodeBlocks(transitionBlocks);
_transitionVector.push_back(t); _transitionVector.push_back(t);
tmpCodeBlocks.clear(); return transitionBlocks;
initialTmp = finalState;
finalWaitBlock = childListBlock.at(i);
//break; // this break statement will cause wait blocks in a sequence to be under detected....
} else { } else {
tmpCodeBlocks.push_back(childListBlock.at(i)); // When adding blocks to traversed blocks, check if the last node prior to the wait call has which branch discovered.
} // Also need to check terminator block or block 0
if (susCFGSuccIDMap.find(currentBlock) == susCFGSuccIDMap.end()) {
// currentBlock is not our concern yet, so insert the 0th successive block
//_os <<"\n Current Block : " <<currentBlock->getBlockID()<<" not of concern";
if (currentBlock->getSuccBlocks().at(0)->isParentBlock()) {
if (!isFound(visitedBlocks, currentBlock->getSuccBlocks().at(0)->getChildBlockList().at(0))) {
traversedBlocks.push_front(currentBlock->getSuccBlocks().at(0)->getChildBlockList().at(0));
} }
if (!isFound(visitedWaitStates, finalWaitBlock)) {
waitStates.push_front(finalWaitBlock);
} }
} else { else {
tmpCodeBlocks.push_back(currentState); if (!isFound(visitedBlocks, currentBlock->getSuccBlocks().at(0))) {
if (currentBlock->getSuccBlocks().at(0)->getBlockID() != 0) {
vector < SusCFG * >succCurrentBlocks = currentState->getSuccBlocks(); traversedBlocks.push_front(currentBlock->getSuccBlocks().at(0));
for (unsigned int i = 0; i < succCurrentBlocks.size(); i++) {
if (!isFound(visitedStates, succCurrentBlocks.at(i))) {
stateQueue.push_front(succCurrentBlocks.at(i));
visitedStates.push_back(succCurrentBlocks.at(i));
} }
} }
} }
} }
if (tmpCodeBlocks.size() != 0) { else {
if (stateCommonBlocksMap.find(finalState->returnSusCFGBlock()) != stateCommonBlocksMap.end()) { // currentBlock has a previous entry in the map, so take the other succesive block if it exists
stateCommonBlocksMapType::iterator stateFound = stateCommonBlocksMap.find(finalState->returnSusCFGBlock()); //_os <<"\n Current block : " <<currentBlock->getBlockID()<<" is of concern";
vector<SusCFG*> susCFGVec = stateFound->second; susCFGSuccIDMapType::iterator susCFGFound = susCFGSuccIDMap.find(currentBlock);
for (int i = 0; i<tmpCodeBlocks.size(); i++) { if (susCFGFound->second == currentBlock->getSuccBlocks().size() - 1) {
if (!isFound(susCFGVec, tmpCodeBlocks.at(i))) { // All the child branches of this node have been discovered. So, there is nothing to discover
susCFGVec.push_back(tmpCodeBlocks.at(i)); //_os <<"\n Current block : " <<currentBlock->getBlockID()<<" has all children accounted for";
break;
} }
else {
if (currentBlock->getSuccBlocks().at(susCFGFound->second + 1)->isParentBlock()) {
if (!isFound(visitedBlocks, currentBlock->getSuccBlocks().at(susCFGFound->second + 1)->getChildBlockList().at(0))) {
traversedBlocks.push_front(currentBlock->getSuccBlocks().at(susCFGFound->second + 1)->
getChildBlockList().at(0));
} }
stateCommonBlocksMap.erase(finalState->returnSusCFGBlock());
stateCommonBlocksMap.insert(stateCommonBlocksPairType(finalState->returnSusCFGBlock(), susCFGVec));
} }
else { else {
stateCommonBlocksMap.insert(stateCommonBlocksPairType(finalState->returnSusCFGBlock(), tmpCodeBlocks)); if (!isFound(visitedBlocks, currentBlock->getSuccBlocks().at(susCFGFound->second + 1))) {
if (currentBlock->getSuccBlocks().at(susCFGFound->second + 1)->getBlockID() != 0) {
traversedBlocks.push_front(currentBlock->getSuccBlocks().at(susCFGFound->second + 1));
}
} }
} }
waitStates.pop_back();
} }
for (int i = 0; i<_transitionVector.size(); i++) {
Transition *t = _transitionVector.at(i);
if (stateCommonBlocksMap.find(t->returnFinalState()->returnSusCFGBlock()) != stateCommonBlocksMap.end()) {
stateCommonBlocksMapType::iterator stateFound = stateCommonBlocksMap.find(t->returnFinalState()->returnSusCFGBlock());
vector<SusCFG*> remainingBlocks = stateFound->second;
t->addCodeBlocks(remainingBlocks);
} }
visitedBlocks.push_back(currentBlock);
transitionBlocks.push_back(currentBlock);
} }
}
return transitionBlocks;
} }
*/
void SuspensionAutomata::genSauto() void SuspensionAutomata::genSauto()
{ {
typedef pair < SusCFG *, State * >susCFGStatePairType;
typedef map < SusCFG *, State * >susCFGStateMapType;
susCFGStateMapType susCFGStateMap;
susCFGVectorType susCFGVector = _susCFGVector; susCFGVectorType susCFGVector = _susCFGVector;
susCFGVectorType waitBlocks; susCFGVectorType waitBlocks;
for (int i = 0; i < susCFGVector.size(); i++) { for (int i = 0; i < susCFGVector.size(); i++) {
...@@ -713,107 +655,97 @@ void SuspensionAutomata::genSauto() ...@@ -713,107 +655,97 @@ void SuspensionAutomata::genSauto()
susCFGStateMap.insert(susCFGStatePairType(susCFGVector.at(i), state)); susCFGStateMap.insert(susCFGStatePairType(susCFGVector.at(i), state));
} }
} }
for (int i = 0; i < waitBlocks.size(); i++) { for (int i = 0; i < waitBlocks.size(); i++) {
SusCFG *waitBlock = waitBlocks.at(i); SusCFG *waitBlock = waitBlocks.at(i);
deque < SusCFG * >susCodeBlocks; State *initial = new State(waitBlock, false, false, false, false); // create initial state
vector < SusCFG * >codeBlocks; // transtion code blocks distinct for a wait block
vector < SusCFG * >commonBlocks; // common code blocks for all destination wait calls
susCFGVectorType succBlocks = waitBlock->getSuccBlocks();
susCFGStateMapType::iterator stateFound =
susCFGStateMap.find(waitBlocks.at(i));
State *initialState = stateFound->second;
for (int j = 0; j < succBlocks.size(); j++) {
susCodeBlocks.push_back(succBlocks.at(j));
}
while (susCodeBlocks.size() != 0) {
SusCFG *currentBlock = susCodeBlocks.front();
susCodeBlocks.pop_front();
if (currentBlock->isWaitBlock()) {
float timeInNs;
string eventName;
susCFGStateMapType::iterator stateFound = //_os <<"\n Looking at Wait Block : " <<waitBlock->getBlockID();
susCFGStateMap.find(currentBlock);
State *finalState = stateFound->second;
if (isTimedWait(currentBlock->getWaitStmt())) { susCFGStateMapType::iterator stateFound =susCFGStateMap.find(waitBlocks.at(i));
finalState->setTimed(); State *initialState = stateFound->second;
timeInNs = getTime(currentBlock->getWaitStmt());
} else if (isEventWait(currentBlock->getWaitStmt())) {
finalState->setEvent(); vector<SusCFG*> backTrackCodeBlocks;
eventName = getEvent(currentBlock->getWaitStmt()); SusCFG* lastBlock;
} else if (isDeltaWait(currentBlock->getWaitStmt())) { susCFGSuccIDMap.clear(); // For each new initial state, start fresh...
finalState->setDelta(); // Left child.. do the same for the right child
} else { do {
finalState->setInitial(); SusCFG *initialInsertBlock;
if (waitBlock->getSuccBlocks().at(0)->isParentBlock()) {
initialInsertBlock = waitBlock->getSuccBlocks().at(0)->getChildBlockList().at(0);
} }
vector < SusCFG * >transitionBlocks;
transitionBlocks.insert(transitionBlocks.end(), commonBlocks.begin(),
commonBlocks.end());
transitionBlocks.insert(transitionBlocks.end(), codeBlocks.begin(),
codeBlocks.end());
codeBlocks.clear();
Transition *t = new Transition();
finalState->addEventName(eventName);
finalState->addSimTime(timeInNs);
t->addInitialState(initialState);
t->addFinalState(finalState);
t->addCodeBlocks(transitionBlocks);
_transitionVector.push_back(t);
break;
} else if (currentBlock->isParentBlock()) {
susCFGVectorType childBlockList = currentBlock->getChildBlockList();
for (int j = 0; j < childBlockList.size(); j++) {
if (childBlockList.at(j)->isWaitBlock()) {
float timeInNs;
string eventName;
susCFGStateMapType::iterator stateFound = else {
susCFGStateMap.find(childBlockList.at(j)); initialInsertBlock = waitBlock->getSuccBlocks().at(0);
State *finalState = stateFound->second; }
vector<SusCFG*> transitionCodeBlocks = modifDFS(initialInsertBlock, initial);
//_os <<"\n Transition Blocks : ";
backTrackCodeBlocks.clear();
for (int j = 0; j<transitionCodeBlocks.size(); j++) {
backTrackCodeBlocks.push_back(transitionCodeBlocks.at(j));
//_os <<" "<<transitionCodeBlocks.at(j)->getBlockID();;
}
int j;
for (j = backTrackCodeBlocks.size()-2; j >=0; j--) {
if (backTrackCodeBlocks.at(j)->getSuccBlocks().size() > 1) {
//_os <<"\n Block : " <<backTrackCodeBlocks.at(j)->getBlockID()<<" has more than one successor";
SusCFG* backBlock = backTrackCodeBlocks.at(j);
if (backBlock->getSuccBlocks().at(0)->isParentBlock()) {
if (backBlock->getSuccBlocks().at(0)->getChildBlockList().at(0) == backTrackCodeBlocks.at(j+1)) {
//_os <<"\n Block : " <<backBlock->getBlockID()<<" used the first successor";
susCFGSuccIDMap.insert(susCFGSuccIDPairType(backBlock, 0));
//_os <<"\n Map value : " <<susCFGSuccIDMap[backBlock];
break;
}
}
else if (backBlock->getSuccBlocks().at(1)->isParentBlock()) {
if (backBlock->getSuccBlocks().at(1)->getChildBlockList().at(0) == backTrackCodeBlocks.at(j+1)) {
//_os <<"\n Block : " <<backBlock->getBlockID()<<" used the second successor";
susCFGSuccIDMap.erase(backBlock);
susCFGSuccIDMap.insert(susCFGSuccIDPairType(backBlock, 1));
break;
}
}
if (isTimedWait(childBlockList.at(j)->getWaitStmt())) { else if (backBlock->getSuccBlocks().at(0) == backTrackCodeBlocks.at(j+1)) {
finalState->setTimed(); //_os <<"\n Block : " <<backBlock->getBlockID()<<" used the first successor";
timeInNs = getTime(childBlockList.at(j)->getWaitStmt()); susCFGSuccIDMap.insert(susCFGSuccIDPairType(backBlock, 0));
} else if (isEventWait(childBlockList.at(j)->getWaitStmt())) { break;
finalState->setEvent();
eventName = getEvent(childBlockList.at(j)->getWaitStmt());
} else if (isDeltaWait(childBlockList.at(j)->getWaitStmt())) {
finalState->setDelta();
} else {
finalState->setInitial();
} }
vector < SusCFG * >transitionBlocks; else if (backBlock->getSuccBlocks().at(1) == backTrackCodeBlocks.at(j+1)){
transitionBlocks.insert(transitionBlocks.end(), //_os <<"\n Block : " <<backBlock->getBlockID()<<" used the second successor";
commonBlocks.begin(), commonBlocks.end()); susCFGSuccIDMap.erase(backBlock);
transitionBlocks.insert(transitionBlocks.end(), codeBlocks.begin(), susCFGSuccIDMap.insert(susCFGSuccIDPairType(backBlock, 1));
codeBlocks.end());
codeBlocks.clear();
Transition *t = new Transition();
finalState->addEventName(eventName);
finalState->addSimTime(timeInNs);
t->addInitialState(initialState);
t->addFinalState(finalState);
t->addCodeBlocks(transitionBlocks);
_transitionVector.push_back(t);
break; break;
} else {
codeBlocks.push_back(childBlockList.at(j));
} }
} }
} else {
commonBlocks.push_back(currentBlock);
for (int j = 0; j < currentBlock->getSuccBlocks().size(); j++) {
susCodeBlocks.push_front(currentBlock->getSuccBlocks().at(j));
} }
//_os <<"\n J value : " <<j;
if (j == -1) {
if (susCFGSuccIDMap.find(backTrackCodeBlocks.back()) == susCFGSuccIDMap.end()) {
susCFGSuccIDMap.insert(susCFGSuccIDPairType(backTrackCodeBlocks.back(), 0));
}
else {
if (susCFGSuccIDMap[backTrackCodeBlocks.back()] == 0) {
susCFGSuccIDMap.erase(backTrackCodeBlocks.back());
susCFGSuccIDMap.insert(susCFGSuccIDPairType(backTrackCodeBlocks.back(), 1));
}
else {
} }
} }
} }
}
// delete the blocks from the back to j
if (backTrackCodeBlocks.size() != 0) {
backTrackCodeBlocks.pop_back();
}
}while(backTrackCodeBlocks.size() != 0);
}
}
// need a utility class and this should be a template function // need a utility class and this should be a template function
bool SuspensionAutomata::isFound(vector < SusCFG * >visitedState, bool SuspensionAutomata::isFound(vector < SusCFG * >visitedState,
SusCFG * block) SusCFG * block)
......
...@@ -113,15 +113,22 @@ namespace scpar { ...@@ -113,15 +113,22 @@ namespace scpar {
typedef vector < SusCFG * >susCFGVectorType; typedef vector < SusCFG * >susCFGVectorType;
typedef vector <Transition *> transitionVectorType; typedef vector <Transition *> transitionVectorType;
typedef pair<SusCFG*, int> susCFGSuccIDPairType;
typedef map<SusCFG*, int> susCFGSuccIDMapType;
typedef pair < SusCFG *, State * >susCFGStatePairType;
typedef map < SusCFG *, State * >susCFGStateMapType;
SuspensionAutomata(FindWait::waitListType, CXXMethodDecl *, ASTContext *, SuspensionAutomata(FindWait::waitListType, CXXMethodDecl *, ASTContext *,
raw_ostream &); raw_ostream &);
~SuspensionAutomata(); ~SuspensionAutomata();
bool isFound(vector < SusCFG * >, SusCFG *); bool isFound(vector < SusCFG * >, SusCFG *);
bool isFound(vector < Transition * >, Transition *); bool isFound(vector < Transition * >, Transition *);
void initialize(); bool initialize();
void genSusCFG(); void genSusCFG();
void genSauto(); void genSauto();
vector<SusCFG*> modifDFS(SusCFG*, State*);
bool isWaitCall(const CFGStmt * cs); bool isWaitCall(const CFGStmt * cs);
bool isTimedWait(Stmt * stmt); bool isTimedWait(Stmt * stmt);
bool isDeltaWait(Stmt * stmt); bool isDeltaWait(Stmt * stmt);
...@@ -139,12 +146,13 @@ namespace scpar { ...@@ -139,12 +146,13 @@ namespace scpar {
private: private:
CXXMethodDecl *_d; CXXMethodDecl *_d;
FindWait::waitListType _waitCalls; FindWait::waitListType _waitCalls;
susCFGSuccIDMapType susCFGSuccIDMap;
susCFGStateMapType susCFGStateMap;
CFG *_cfg; CFG *_cfg;
ASTContext *_a; ASTContext *_a;
raw_ostream & _os; raw_ostream & _os;
susCFGVectorType _susCFGVector; susCFGVectorType _susCFGVector;
transitionVectorType _transitionVector; transitionVectorType _transitionVector;
}; // End class SplitWaitBlocks }; // End class SplitWaitBlocks
} // End namespace scpar } // End namespace scpar
#endif #endif
...@@ -80,13 +80,18 @@ bool SystemCConsumer::fire() ...@@ -80,13 +80,18 @@ bool SystemCConsumer::fire()
FindNotify findNotify(ef->_entryMethodDecl, _os); FindNotify findNotify(ef->_entryMethodDecl, _os);
ef->addNotifys(findNotify); ef->addNotifys(findNotify);
SuspensionAutomata suspensionAutomata(findWaits.getWaitCalls(), ef->getEntryMethod(), &_context, llvm::errs()); SuspensionAutomata suspensionAutomata(findWaits.getWaitCalls(), ef->getEntryMethod(), &_context, llvm::errs());
suspensionAutomata.initialize(); if (suspensionAutomata.initialize()) {
suspensionAutomata.genSusCFG(); suspensionAutomata.genSusCFG();
suspensionAutomata.dumpSusCFG();
suspensionAutomata.genSauto(); suspensionAutomata.genSauto();
suspensionAutomata.dumpSauto();
ef->addSusCFGAuto(suspensionAutomata); ef->addSusCFGAuto(suspensionAutomata);
}
_entryFunctionContainerVector.push_back(ef); _entryFunctionContainerVector.push_back(ef);
} }
_systemcModel->addModuleDecl(md); _systemcModel->addModuleDecl(md);
......
...@@ -55,8 +55,7 @@ using namespace clang; ...@@ -55,8 +55,7 @@ using namespace clang;
namespace scpar namespace scpar
{ {
class SystemCConsumer:public ASTConsumer, class SystemCConsumer:public ASTConsumer, public RecursiveASTVisitor < SystemCConsumer >
public RecursiveASTVisitor < SystemCConsumer >
{ {