moved
This commit is contained in:
1056
Sapfor/_src/VerificationCode/CorrectVarDecl.cpp
Normal file
1056
Sapfor/_src/VerificationCode/CorrectVarDecl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
114
Sapfor/_src/VerificationCode/IncludeChecker.cpp
Normal file
114
Sapfor/_src/VerificationCode/IncludeChecker.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "dvm.h"
|
||||
#include "verifications.h"
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Distribution/DvmhDirective.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::set;
|
||||
using std::pair;
|
||||
|
||||
static bool check(SgStatement* st, const string& fileName, const int lastLine, vector<Messages>& currMessages)
|
||||
{
|
||||
if (isSgExecutableStatement(st) && !isSPF_stat(st) && !isDVM_stat(st))
|
||||
{
|
||||
if (st->fileName() != fileName)
|
||||
{
|
||||
__spf_print(1, " ERROR: include '%s' at line %d has executable operators\n", st->fileName(), lastLine);
|
||||
|
||||
wstring currE, currR;
|
||||
__spf_printToLongBuf(currE, L"Include '%s' has executable operators", to_wstring(st->fileName()).c_str());
|
||||
__spf_printToLongBuf(currR, R52, to_wstring(st->fileName()).c_str());
|
||||
|
||||
currMessages.push_back(Messages(ERROR, lastLine, currR, currE, 1019));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncludeChecker(SgFile *file, const string &fileName, vector<Messages> &currMessages)
|
||||
{
|
||||
int funcNum = file->numberOfFunctions();
|
||||
bool checkOK = true;
|
||||
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement *st = file->functions(i);
|
||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
||||
int lastLine = 1;
|
||||
while (st != lastNode)
|
||||
{
|
||||
if (st == NULL)
|
||||
{
|
||||
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
|
||||
if (st->fileName() == fileName)
|
||||
{
|
||||
lastLine = st->lineNumber();
|
||||
auto next = st->lexNext();
|
||||
if (next && next->comments() && next->fileName() != fileName)
|
||||
{
|
||||
string comm(next->comments());
|
||||
int countLines = 0;
|
||||
for (auto& elem : comm)
|
||||
if (elem == '\n')
|
||||
++countLines;
|
||||
lastLine += countLines;
|
||||
}
|
||||
lastLine++;
|
||||
}
|
||||
|
||||
auto res = check(st, fileName, lastLine, currMessages);
|
||||
checkOK = checkOK && res;
|
||||
st = st->lexNext();
|
||||
}
|
||||
}
|
||||
|
||||
vector<SgStatement*> modules;
|
||||
findModulesInFile(file, modules);
|
||||
|
||||
for (auto& module : modules)
|
||||
{
|
||||
SgStatement* st = module;
|
||||
SgStatement* lastNode = module->lastNodeOfStmt();
|
||||
|
||||
if (st->fileName() != fileName)
|
||||
continue;
|
||||
|
||||
int lastLine = 1;
|
||||
while (st != lastNode)
|
||||
{
|
||||
if (st->fileName() == fileName)
|
||||
lastLine = st->lineNumber();
|
||||
else
|
||||
{
|
||||
auto res = check(st, fileName, lastLine, currMessages);
|
||||
checkOK = checkOK && res;
|
||||
}
|
||||
|
||||
if (st->variant() == FUNC_HEDR || st->variant() == PROC_HEDR)
|
||||
st = st->lastNodeOfStmt();
|
||||
|
||||
st = st->lexNext();
|
||||
}
|
||||
}
|
||||
return checkOK;
|
||||
}
|
||||
651
Sapfor/_src/VerificationCode/StructureChecker.cpp
Normal file
651
Sapfor/_src/VerificationCode/StructureChecker.cpp
Normal file
@@ -0,0 +1,651 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "dvm.h"
|
||||
#include "verifications.h"
|
||||
|
||||
#include "../ParallelizationRegions/ParRegions.h"
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/errors.h"
|
||||
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::make_pair;
|
||||
using std::set;
|
||||
|
||||
bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
|
||||
{
|
||||
int funcNum = file->numberOfFunctions();
|
||||
bool checkOK = true;
|
||||
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement *st = file->functions(i);
|
||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
||||
|
||||
while (st != lastNode)
|
||||
{
|
||||
if (st == NULL)
|
||||
{
|
||||
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
|
||||
if (st->variant() == FOR_NODE)
|
||||
{
|
||||
SgForStmt *currSt = (SgForStmt*)st;
|
||||
if (currSt->isEnddoLoop() == 0)
|
||||
{
|
||||
__spf_print(1, " ERROR: Loop on line %d does not have END DO\n", st->lineNumber());
|
||||
currMessages.push_back(Messages(ERROR, st->lineNumber(), R51, L"This loop does not have END DO format", 1018));
|
||||
checkOK = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (st->variant() == FORALL_NODE || st->variant() == FORALL_STAT ||
|
||||
st->variant() == WHERE_BLOCK_STMT || st->variant() == WHERE_NODE)
|
||||
{
|
||||
__spf_print(1, " ERROR: Loop on line %d does not have END DO\n", st->lineNumber());
|
||||
currMessages.push_back(Messages(ERROR, st->lineNumber(), R50, L"This loop does not have END DO format", 1018));
|
||||
checkOK = false;
|
||||
}
|
||||
|
||||
if (st->variant() == WHILE_NODE)
|
||||
{
|
||||
auto last = st->lastNodeOfStmt();
|
||||
auto str = string(last->unparse());
|
||||
convertToLower(str);
|
||||
if (last->variant() != CONTROL_END || str.find("enddo") == string::npos)
|
||||
{
|
||||
__spf_print(1, " ERROR: Loop on line %d does not have END DO\n", st->lineNumber());
|
||||
currMessages.push_back(Messages(ERROR, st->lineNumber(), R50, L"This loop does not have END DO format", 1018));
|
||||
checkOK = false;
|
||||
}
|
||||
}
|
||||
|
||||
st = st->lexNext();
|
||||
}
|
||||
}
|
||||
return checkOK;
|
||||
}
|
||||
|
||||
bool DvmDirectiveChecker(SgFile *file, map<string, vector<int>> &errors, const int keepDvmDirectives, const int ignoreDvmChecker)
|
||||
{
|
||||
if (keepDvmDirectives != 0)
|
||||
return true;
|
||||
|
||||
int funcNum = file->numberOfFunctions();
|
||||
bool checkOK = true;
|
||||
__spf_print(1, " ignoreDvmChecker = %d\n", ignoreDvmChecker);
|
||||
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement *st = file->functions(i);
|
||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
||||
|
||||
for ( ; st != lastNode; st = st->lexNext())
|
||||
{
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
|
||||
if (isDVM_stat(st) && (st->variant() != DVM_INTERVAL_DIR && st->variant() != DVM_ENDINTERVAL_DIR))
|
||||
{
|
||||
errors[st->fileName()].push_back(st->lineNumber());
|
||||
checkOK = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return checkOK;
|
||||
}
|
||||
|
||||
bool EquivalenceChecker(SgFile *file, const string &fileName, const vector<ParallelRegion*> ®ions, map<string, vector<Messages>> &currMessages)
|
||||
{
|
||||
int funcNum = file->numberOfFunctions();
|
||||
bool checkOK = true;
|
||||
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement *st = file->functions(i);
|
||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
||||
int lastLine = 1;
|
||||
|
||||
while (st != lastNode)
|
||||
{
|
||||
lastLine = st->lineNumber();
|
||||
if (st == NULL)
|
||||
{
|
||||
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (st->variant() == EQUI_STAT)
|
||||
{
|
||||
auto eqList = isSgNestedVarListDeclStmt(st);
|
||||
if (eqList == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
bool needToReport = false;
|
||||
bool checkTmp = true;
|
||||
//TODO: need to check variables in region
|
||||
if (getRegionByLine(regions, st->fileName(), lastLine))
|
||||
{
|
||||
checkTmp = false;
|
||||
needToReport = true;
|
||||
}
|
||||
else
|
||||
needToReport = true;
|
||||
|
||||
bool onlyVars = true;
|
||||
for (int z = 0; z < eqList->numberOfLists(); ++z)
|
||||
{
|
||||
auto list = eqList->list(z);
|
||||
while (list)
|
||||
{
|
||||
SgSymbol* symb = list->lhs()->symbol();
|
||||
checkNull(symb, convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
if (isArrayRef(list->lhs()) ||
|
||||
symb->type() && symb->type()->variant() == T_ARRAY)
|
||||
{
|
||||
SgStatement* decl = declaratedInStmt(symb);
|
||||
DIST::Array* array = getArrayFromDeclarated(decl, symb->identifier());
|
||||
|
||||
if (array && !array->IsNotDistribute())
|
||||
onlyVars = false;
|
||||
}
|
||||
list = list->rhs();
|
||||
}
|
||||
}
|
||||
|
||||
if (onlyVars)
|
||||
{
|
||||
needToReport = false;
|
||||
checkTmp = true;
|
||||
}
|
||||
|
||||
checkOK &= checkTmp;
|
||||
if (needToReport)
|
||||
{
|
||||
__spf_print(1, "The equivalence operator is not supported yet at line %d of file %s\n", st->lineNumber(), st->fileName());
|
||||
currMessages[st->fileName()].push_back(Messages(checkOK ? WARR : ERROR, st->lineNumber(), R70, L"An equivalence operator is not supported yet", 1038));
|
||||
}
|
||||
}
|
||||
|
||||
if (st->variant() == PAUSE_NODE)
|
||||
{
|
||||
checkOK &= false;
|
||||
__spf_print(1, "The PAUSE operator is not supported yet at line %d of file %s\n", st->lineNumber(), st->fileName());
|
||||
currMessages[st->fileName()].push_back(Messages(ERROR, st->lineNumber(), R69, L"An PAUSE operator is deprecated to parallel", 1038));
|
||||
}
|
||||
st = st->lexNext();
|
||||
}
|
||||
}
|
||||
return checkOK;
|
||||
}
|
||||
|
||||
bool CommonBlockChecker(SgFile *file, const string &fileName, const map<string, CommonBlock*> &commonBlocks, map<string, vector<Messages>> &messages)
|
||||
{
|
||||
bool checkOK = true;
|
||||
|
||||
for (auto& block : commonBlocks)
|
||||
{
|
||||
auto vars = block.second->getVariables();
|
||||
|
||||
for (int i = 0; i < vars.size(); i++)
|
||||
{
|
||||
int pos = vars[i]->getPosition();
|
||||
varType type = vars[i]->getType();
|
||||
|
||||
//only this file
|
||||
bool needToSkip = true;
|
||||
const CommonVariableUse *currUse = NULL;
|
||||
for (auto &elem : vars[i]->getAllUse())
|
||||
{
|
||||
if (elem.getFile() == file)
|
||||
{
|
||||
needToSkip = false;
|
||||
currUse = &elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (needToSkip)
|
||||
continue;
|
||||
|
||||
for (int j = i + 1; j < vars.size(); j++)
|
||||
{
|
||||
bool needToReport = false;
|
||||
auto typeMessage = NOTE;
|
||||
|
||||
if ((vars[j]->getPosition() == pos) &&
|
||||
((vars[j]->getType() == ARRAY && type != ARRAY) || (vars[j]->getType() != ARRAY && type == ARRAY)))
|
||||
{
|
||||
DIST::Array *array = NULL;
|
||||
if (vars[j]->getType() == ARRAY)
|
||||
array = getArrayFromDeclarated(vars[j]->getDeclarated(), vars[j]->getName());
|
||||
else
|
||||
array = getArrayFromDeclarated(vars[i]->getDeclarated(), vars[i]->getName());
|
||||
|
||||
if (array == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
if (array->IsNotDistribute())
|
||||
typeMessage = WARR;
|
||||
else
|
||||
{
|
||||
checkOK = false;
|
||||
typeMessage = ERROR;
|
||||
}
|
||||
needToReport = true;
|
||||
}
|
||||
else if (vars[j]->getPosition() == pos && vars[j]->getType() != type)
|
||||
{
|
||||
typeMessage = WARR;
|
||||
needToReport = true;
|
||||
}
|
||||
|
||||
if (needToReport)
|
||||
{
|
||||
wstring messageE, messageR;
|
||||
__spf_printToLongBuf(messageE, L"Variables '%s' and '%s' in one storage association (common block '%s') have different types (files - %s:%d and %s:%d)",
|
||||
to_wstring(vars[i]->getName()).c_str(), to_wstring(vars[j]->getName()).c_str(), to_wstring(block.first).c_str(),
|
||||
to_wstring(vars[i]->getDeclarated()->fileName()).c_str(), vars[i]->getDeclarated()->lineNumber(),
|
||||
to_wstring(vars[j]->getDeclarated()->fileName()).c_str(), vars[j]->getDeclarated()->lineNumber());
|
||||
|
||||
__spf_printToLongBuf(messageR, R71,
|
||||
to_wstring(vars[i]->getName()).c_str(), to_wstring(vars[j]->getName()).c_str(), to_wstring(block.first).c_str(),
|
||||
to_wstring(vars[i]->getDeclarated()->fileName()).c_str(), vars[i]->getDeclarated()->lineNumber(),
|
||||
to_wstring(vars[j]->getDeclarated()->fileName()).c_str(), vars[j]->getDeclarated()->lineNumber());
|
||||
|
||||
messages[vars[i]->getDeclarated()->fileName()].push_back(Messages(typeMessage, vars[i]->getDeclarated()->lineNumber(), messageR, messageE, 1039));
|
||||
messages[vars[j]->getDeclarated()->fileName()].push_back(Messages(typeMessage, vars[j]->getDeclarated()->lineNumber(), messageR, messageE, 1039));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return checkOK;
|
||||
}
|
||||
|
||||
bool FunctionsChecker(SgFile *file, map<string, pair<string, int>> &funcNames, map<string, vector<Messages>> &currMessages)
|
||||
{
|
||||
int funcNum = file->numberOfFunctions();
|
||||
bool checkOK = true;
|
||||
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement *st = file->functions(i);
|
||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
||||
|
||||
if (st->controlParent()->variant() == GLOBAL)
|
||||
{
|
||||
string funcName = st->symbol()->identifier();
|
||||
auto it = funcNames.find(funcName);
|
||||
if (it == funcNames.end())
|
||||
funcNames[funcName] = make_pair(file->filename(), st->lineNumber());
|
||||
else
|
||||
{
|
||||
__spf_print(1, "the same function name in different places was found: func %s, places %s:%d and %s:%d\n",
|
||||
it->first.c_str(), it->second.first.c_str(), it->second.second, file->filename(), st->lineNumber());
|
||||
|
||||
wstring messageE, messageR;
|
||||
__spf_printToLongBuf(messageE, L"Function '%s' was declared in more than one place: '%s':%d and '%s':%d",
|
||||
to_wstring(funcName).c_str(), to_wstring(it->second.first).c_str(),
|
||||
it->second.second, to_wstring(file->filename()).c_str(), st->lineNumber());
|
||||
|
||||
__spf_printToLongBuf(messageR, R92,
|
||||
to_wstring(funcName).c_str(), to_wstring(it->second.first).c_str(),
|
||||
it->second.second, to_wstring(file->filename()).c_str(), st->lineNumber());
|
||||
|
||||
currMessages[st->fileName()].push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1048));
|
||||
currMessages[it->second.first].push_back(Messages(ERROR, it->second.second, messageR, messageE, 1048));
|
||||
|
||||
checkOK = false;
|
||||
}
|
||||
|
||||
if (isIntrinsicFunctionName(funcName.c_str()))
|
||||
{
|
||||
__spf_print(1, "the same function name in different places was found: func %s, places %s:%d and %s:%d\n",
|
||||
funcName.c_str(), file->filename(), st->lineNumber(), "intrinsic", 0);
|
||||
|
||||
wstring messageE, messageR;
|
||||
__spf_printToLongBuf(messageE, L"Function '%s' was declared in more than one place: '%s':%d and '%s':%d",
|
||||
to_wstring(funcName).c_str(), to_wstring(file->filename()).c_str(), st->lineNumber(), to_wstring("intrinsic").c_str(), 0);
|
||||
|
||||
__spf_printToLongBuf(messageR, R92,
|
||||
to_wstring(funcName).c_str(), to_wstring(file->filename()).c_str(), st->lineNumber(), to_wstring("intrinsic").c_str(), 0);
|
||||
|
||||
currMessages[st->fileName()].push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1048));
|
||||
|
||||
checkOK = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return checkOK;
|
||||
}
|
||||
|
||||
void fillFunctionInfo(SgFile* file, map<string, vector<Function>>& funcInfo)
|
||||
{
|
||||
const int funcNum = file->numberOfFunctions();
|
||||
const string fileName = file->filename();
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement* st = file->functions(i);
|
||||
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||
|
||||
if (st->fileName() != fileName)
|
||||
continue;
|
||||
|
||||
Function newFunc;
|
||||
newFunc.name = st->symbol()->identifier();
|
||||
newFunc.line = st->lineNumber();
|
||||
newFunc.file = file->filename();
|
||||
newFunc.point = st;
|
||||
if (isSgProgHedrStmt(st) == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
newFunc.parametersCount = ((SgProgHedrStmt*)st)->numberOfParameters();
|
||||
|
||||
auto cp = st->controlParent();
|
||||
if (cp->variant() == GLOBAL)
|
||||
newFunc.type = 1;
|
||||
else if (cp->variant() == MODULE_STMT)
|
||||
{
|
||||
if (string(cp->fileName()) != file->filename())
|
||||
continue; // add module functions only once
|
||||
newFunc.type = 0;
|
||||
newFunc.parentName = cp->symbol()->identifier();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto cpcp = cp->controlParent();
|
||||
if (cpcp->variant() == GLOBAL)
|
||||
{
|
||||
newFunc.type = 2;
|
||||
newFunc.parentName = cp->symbol()->identifier();
|
||||
}
|
||||
else
|
||||
{
|
||||
newFunc.type = 3;
|
||||
newFunc.parentName = cp->symbol()->identifier();
|
||||
newFunc.globalName = cpcp->symbol()->identifier();
|
||||
}
|
||||
}
|
||||
funcInfo[newFunc.name].push_back(newFunc);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: for the same parameters count
|
||||
// add support of optilnal parameters
|
||||
static SgSymbol* resolveName(SgFile* file, SgStatement* context, SgExpression* parameters, const vector<Function>& functions, const string& name)
|
||||
{
|
||||
SgSymbol* corrected = NULL;
|
||||
|
||||
int parCount = 0;
|
||||
while (parameters)
|
||||
{
|
||||
parCount++;
|
||||
parameters = parameters->rhs();
|
||||
}
|
||||
|
||||
auto cp = getFuncStat(context, { MODULE_STMT } );
|
||||
auto cpcp = cp->controlParent();
|
||||
auto globalP = cpcp->controlParent();
|
||||
|
||||
const string cpName = cp->symbol()->identifier();
|
||||
const string cpcpName = (cpcp->variant() == GLOBAL) ? "" : cpcp->symbol()->identifier();
|
||||
const string global = globalP ? ((globalP->variant() != GLOBAL) ? globalP->symbol()->identifier() : "") : "";
|
||||
|
||||
//try to resolve by parameters count
|
||||
vector<Function> firstStep, candidates;
|
||||
|
||||
for (auto& func : functions)
|
||||
if (func.parametersCount == parCount)
|
||||
firstStep.push_back(func);
|
||||
|
||||
if (firstStep.size() != 1)
|
||||
{
|
||||
for (auto& func : firstStep)
|
||||
{
|
||||
if (func.type == 3)
|
||||
{
|
||||
if (func.parentName == cpName && func.globalName == cpcpName ||
|
||||
func.parentName == cpcpName && func.globalName == global)
|
||||
{
|
||||
candidates.push_back(func);
|
||||
}
|
||||
}
|
||||
else if (func.type == 0)
|
||||
{
|
||||
if (func.parentName == cpcpName)
|
||||
candidates.push_back(func);
|
||||
}
|
||||
else if (func.type == 2)
|
||||
{
|
||||
if (func.parentName == cpName || func.parentName == cpcpName) // contains
|
||||
candidates.push_back(func);
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO:
|
||||
candidates.push_back(func);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
candidates = firstStep;
|
||||
|
||||
if (candidates.size() == 0)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
//TODO: added candidate filtration by context
|
||||
|
||||
if (candidates.size() == 1)
|
||||
{
|
||||
Function target = candidates[0];
|
||||
auto itF = target.resolved.find(file);
|
||||
|
||||
if (itF != target.resolved.end())
|
||||
corrected = itF->second;
|
||||
else
|
||||
{
|
||||
if (target.type == 1 || target.type == 2) // global or internal
|
||||
{
|
||||
if (target.file == file->filename())
|
||||
{
|
||||
corrected = target.point->symbol();
|
||||
target.resolved[file] = corrected;
|
||||
}
|
||||
/*else //TODO: create needed symbol?
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);*/
|
||||
}
|
||||
else if (target.type == 0) // module
|
||||
{
|
||||
if (target.file == file->filename())
|
||||
{
|
||||
corrected = target.point->symbol();
|
||||
target.resolved[file] = corrected;
|
||||
}
|
||||
else
|
||||
;//TODO: find module symbol clone in current file
|
||||
}
|
||||
}
|
||||
}
|
||||
else // TODO
|
||||
{
|
||||
__spf_print(1, "can not resolve of CALL '%s' function, candidates count %d, file %s and line %d\n", name.c_str(), functions.size(), current_file->filename(), context->lineNumber());
|
||||
for (auto& func : functions)
|
||||
__spf_print(1, " --> from file file %s and line %d, parameter count - %d\n", func.file.c_str(), func.line, func.parametersCount);
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
|
||||
return corrected;
|
||||
}
|
||||
|
||||
static void resolveFunctionCalls(SgFile* file, SgStatement* context, SgExpression* ex, const set<string>& toResolve, const map<string, vector<Function>>& funcInfo)
|
||||
{
|
||||
if (ex)
|
||||
{
|
||||
if (ex->variant() == FUNC_CALL)
|
||||
{
|
||||
string name = ex->symbol()->identifier();
|
||||
if (toResolve.find(name) != toResolve.end())
|
||||
{
|
||||
auto newS = resolveName(file, context, ex->lhs(), funcInfo.at(name), name);
|
||||
if (newS && ex->symbol()->id() != newS->id())
|
||||
ex->setSymbol(*newS);
|
||||
}
|
||||
}
|
||||
|
||||
resolveFunctionCalls(file, context, ex->lhs(), toResolve, funcInfo);
|
||||
resolveFunctionCalls(file, context, ex->rhs(), toResolve, funcInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void resolveFunctionCalls(SgFile* file, const set<string>& toResolve, const map<string, vector<Function>>& funcInfo)
|
||||
{
|
||||
if (toResolve.size() == 0)
|
||||
return;
|
||||
|
||||
int funcNum = file->numberOfFunctions();
|
||||
for (int z = 0; z < funcNum; ++z)
|
||||
{
|
||||
SgStatement* st = file->functions(z);
|
||||
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||
|
||||
while (st != lastNode)
|
||||
{
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
|
||||
if (st->variant() == PROC_STAT)
|
||||
{
|
||||
string name = st->symbol()->identifier();
|
||||
if (toResolve.find(name) != toResolve.end())
|
||||
{
|
||||
auto newS = resolveName(file, st, st->expr(0), funcInfo.at(name), name);
|
||||
if (newS && st->symbol()->id() != newS->id())
|
||||
st->setSymbol(*newS);
|
||||
}
|
||||
}
|
||||
|
||||
for (int z = 0; z < 3; ++z)
|
||||
resolveFunctionCalls(file, st, st->expr(z), toResolve, funcInfo);
|
||||
st = st->lexNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OperatorChecker(SgFile* file, map<string, vector<Messages>>& currMessages)
|
||||
{
|
||||
bool checkOK = true;
|
||||
set<int> usedLines;
|
||||
|
||||
SgStatement* st = file->firstStatement();
|
||||
string currF = file->filename();
|
||||
|
||||
const set<int> cpOnSameLine = { ARITHIF_NODE, LOGIF_NODE, GOTO_NODE , IF_NODE, FORALL_STAT };
|
||||
while (st)
|
||||
{
|
||||
int line = st->lineNumber();
|
||||
if (line > 0 && st->variant() == PROG_HEDR && st->symbol()->identifier() == string("_MAIN"))
|
||||
; // skip
|
||||
else if (line > 0 && st->fileName() == currF)
|
||||
{
|
||||
int var = st->controlParent()->variant();
|
||||
bool cpWasAdded = cpOnSameLine.find(var) != cpOnSameLine.end() && (usedLines.find(line) != usedLines.end());
|
||||
|
||||
if (usedLines.find(line) != usedLines.end() && !cpWasAdded)
|
||||
{
|
||||
|
||||
wstring messageE, messageR;
|
||||
__spf_printToLongBuf(messageE, L"More than one operator found on a line, try to run Code correction pass");
|
||||
__spf_printToLongBuf(messageR, R179);
|
||||
|
||||
currMessages[st->fileName()].push_back(Messages(ERROR, line, messageR, messageE, 1027));
|
||||
checkOK = false;
|
||||
}
|
||||
usedLines.insert(line);
|
||||
}
|
||||
st = st->lexNext();
|
||||
}
|
||||
return checkOK;
|
||||
}
|
||||
|
||||
bool checkAndMoveFormatOperators(SgFile* file, vector<Messages>& currMessages, bool withError)
|
||||
{
|
||||
bool checkOK = true;
|
||||
|
||||
const int funcNum = file->numberOfFunctions();
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement* st = file->functions(i);
|
||||
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||
|
||||
vector<SgStatement*> toMove;
|
||||
while (st != lastNode)
|
||||
{
|
||||
if (st == NULL)
|
||||
{
|
||||
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
|
||||
if (isSgExecutableStatement(st) && !isDVM_stat(st) && !isSPF_stat(st))
|
||||
break;
|
||||
|
||||
if (st->variant() == FORMAT_STAT)
|
||||
{
|
||||
if (withError)
|
||||
{
|
||||
toMove.push_back(st);
|
||||
st = st->lexNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
SgStatement* needed = st;
|
||||
st = st->lexNext();
|
||||
toMove.push_back(needed->extractStmt());
|
||||
}
|
||||
}
|
||||
else
|
||||
st = st->lexNext();
|
||||
}
|
||||
|
||||
if (toMove.size() > 0)
|
||||
{
|
||||
if (!withError)
|
||||
{
|
||||
for (auto& format : toMove)
|
||||
lastNode->insertStmtBefore(*format, *lastNode->controlParent());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& format : toMove)
|
||||
{
|
||||
wstring messageE, messageR;
|
||||
__spf_printToLongBuf(messageE, L"FORMAT operators cannot be placed in the declaration scope in the SAPFOR, try to run Code correction pass");
|
||||
__spf_printToLongBuf(messageR, R183);
|
||||
|
||||
currMessages.push_back(Messages(ERROR, format->lineNumber(), messageR, messageE, 1060));
|
||||
}
|
||||
checkOK = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return checkOK;
|
||||
}
|
||||
42
Sapfor/_src/VerificationCode/VerifySageStructures.cpp
Normal file
42
Sapfor/_src/VerificationCode/VerifySageStructures.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "dvm.h"
|
||||
#include "verifications.h"
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/errors.h"
|
||||
|
||||
int VerifyFile(SgFile *file)
|
||||
{
|
||||
int funcNum = file->numberOfFunctions();
|
||||
|
||||
int isError = 0;
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement *st = file->functions(i);
|
||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
||||
|
||||
while (st != lastNode)
|
||||
{
|
||||
if (st == NULL)
|
||||
{
|
||||
__spf_print(1, "Found errors in Sage structures in file %s, -1\n", file->filename());
|
||||
isError = -1;
|
||||
break;
|
||||
}
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
st = st->lexNext();
|
||||
}
|
||||
|
||||
if (isError != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return isError;
|
||||
}
|
||||
53
Sapfor/_src/VerificationCode/verifications.h
Normal file
53
Sapfor/_src/VerificationCode/verifications.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "dvm.h"
|
||||
#include "../Utils/errors.h"
|
||||
|
||||
#include "../ParallelizationRegions/ParRegions.h"
|
||||
#include "../ParallelizationRegions/ParRegions_func.h"
|
||||
#include "../Utils/CommonBlock.h"
|
||||
|
||||
struct Function
|
||||
{
|
||||
std::string name;
|
||||
std::string file;
|
||||
int line;
|
||||
SgStatement* point = NULL;
|
||||
int parametersCount;
|
||||
|
||||
int type; // 0 - module, 1 - global, 2 - internal, 3 - internal in module
|
||||
std::string parentName;
|
||||
std::string globalName;
|
||||
|
||||
std::map<SgFile*, SgSymbol*> resolved;
|
||||
};
|
||||
|
||||
bool EquivalenceChecker(SgFile *file, const std::string &fileName, const std::vector<ParallelRegion*> ®ions, std::map<std::string, std::vector<Messages>> &currM);
|
||||
bool CommonBlockChecker(SgFile *file, const std::string &fileName, const std::map<std::string, CommonBlock*> &commonBlocks, std::map<std::string, std::vector<Messages>> &messages);
|
||||
bool EndDoLoopChecker(SgFile *file, std::vector<Messages> &currM);
|
||||
bool IncludeChecker(SgFile *file, const std::string &fileName, std::vector<Messages> &currM);
|
||||
void VarDeclCorrecter(SgFile *file);
|
||||
bool DvmDirectiveChecker(SgFile *file, std::map<std::string, std::vector<int>> &errors, const int, const int);
|
||||
bool FunctionsChecker(SgFile *file, std::map<std::string, std::pair<std::string, int>> &funcNames, std::map<std::string, std::vector<Messages>> &currMessages);
|
||||
bool OperatorChecker(SgFile* file, std::map<std::string, std::vector<Messages>>& currMessages);
|
||||
void fillFunctionInfo(SgFile* file, std::map<std::string, std::vector<Function>>& funcInfo);
|
||||
void resolveFunctionCalls(SgFile* file, const std::set<std::string>& toResolve, const std::map<std::string, std::vector<Function>>& funcInfo);
|
||||
bool checkAndMoveFormatOperators(SgFile* file, std::vector<Messages> &currMessage, bool withError = true);
|
||||
|
||||
int VerifyFile(SgFile *file);
|
||||
void correctModuleProcNames(SgFile *file, const std::set<std::string>& globalF);
|
||||
void correctModuleSymbols(SgFile *file);
|
||||
void replaceStructuresToSimpleTypes(SgFile* file);
|
||||
void restoreCorrectedModuleProcNames(SgFile *file);
|
||||
bool checkArgumentsDeclaration(SgProject *project, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, const std::vector<ParallelRegion*> ®ions, std::map<std::string, std::vector<Messages>> &SPF_messages);
|
||||
|
||||
void replaceDerivedAssigns(SgFile *file, SgStatement *stToCopy, SgStatement *insertB, const std::map<std::string, SgStatement*> &derivedTypesDecl);
|
||||
bool isDerivedAssign(SgStatement *st);
|
||||
std::map<std::string, SgStatement*> createDerivedTypeDeclMap(SgStatement *forS);
|
||||
void removeExecutableFromModuleDeclaration(SgFile* current, const std::set<std::string>& filesInProj, std::vector<SgStatement*>& hiddenData);
|
||||
bool needToReplaceInterfaceName(SgStatement* interf);
|
||||
|
||||
std::string getOrigName(const std::string& file, const std::string& s);
|
||||
Reference in New Issue
Block a user