Merge pull request 'private_remoing: add loop alignment check and fix messages' (#44) from private_removing into master
This commit was merged in pull request #44.
This commit is contained in:
@@ -25,6 +25,21 @@ struct RegularExpr {
|
|||||||
string var;
|
string var;
|
||||||
|
|
||||||
RegularExpr(): coefA(0), coefB(0), var("") {}
|
RegularExpr(): coefA(0), coefB(0), var("") {}
|
||||||
|
|
||||||
|
string toString() const
|
||||||
|
{
|
||||||
|
string result = var;
|
||||||
|
|
||||||
|
if (coefA != 1)
|
||||||
|
result = std::to_string(coefA) + "*" + var;
|
||||||
|
|
||||||
|
if (coefB > 0)
|
||||||
|
result += " + " + std::to_string(coefB);
|
||||||
|
else if (coefB < 0)
|
||||||
|
result += " - " + std::to_string((-1) * coefB);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool operator==(const RegularExpr& left, const RegularExpr& right)
|
static bool operator==(const RegularExpr& left, const RegularExpr& right)
|
||||||
@@ -52,13 +67,38 @@ struct ArraySubscript {
|
|||||||
RegularExpr regExprStart;
|
RegularExpr regExprStart;
|
||||||
RegularExpr regExprEnd;
|
RegularExpr regExprEnd;
|
||||||
|
|
||||||
ArraySubscript() {
|
ArraySubscript()
|
||||||
|
{
|
||||||
isFixed = false;
|
isFixed = false;
|
||||||
value = 0;
|
value = 0;
|
||||||
isRegIndex = false;
|
isRegIndex = false;
|
||||||
regExprStart = RegularExpr{};
|
regExprStart = RegularExpr{};
|
||||||
regExprEnd = RegularExpr{};
|
regExprEnd = RegularExpr{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string toStringStart() const
|
||||||
|
{
|
||||||
|
if (isFixed)
|
||||||
|
return std::to_string(value);
|
||||||
|
|
||||||
|
return regExprStart.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
string toStringEnd() const
|
||||||
|
{
|
||||||
|
if (isFixed)
|
||||||
|
return std::to_string(value);
|
||||||
|
|
||||||
|
return regExprEnd.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
string toString() const
|
||||||
|
{
|
||||||
|
if (regExprStart == regExprEnd)
|
||||||
|
return this->toStringStart();
|
||||||
|
|
||||||
|
return this->toStringStart() + ":" + this->toStringEnd();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// DefUseStmtsPair represents pair of DEF and USE statements for private variable
|
// DefUseStmtsPair represents pair of DEF and USE statements for private variable
|
||||||
@@ -337,15 +377,17 @@ static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, vec
|
|||||||
* Block of creating messages functions: *
|
* Block of creating messages functions: *
|
||||||
* ************************************* */
|
* ************************************* */
|
||||||
|
|
||||||
static void addMessageRemoveLoop(vector<Messages>& messages, int loopLineNum)
|
static void addMessageVarNotAlignedWithLoop(vector<Messages>& messages, string varName, int loopLineNum)
|
||||||
{
|
{
|
||||||
__spf_print(1, "NOTE: loop on line %d was removed\n", loopLineNum);
|
__spf_print(1, "WARR: cannot remove private var '%s' - its references have different alignment with the loop %d\n",
|
||||||
|
varName.c_str(), loopLineNum);
|
||||||
|
|
||||||
wstring messageE, messageR;
|
wstring messageE, messageR;
|
||||||
__spf_printToLongBuf(messageE, L"Loop on line %d was removed", loopLineNum);
|
__spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - its references have different alignment with the loop",
|
||||||
__spf_printToLongBuf(messageR, R198, loopLineNum);
|
to_wstring(varName).c_str());
|
||||||
|
__spf_printToLongBuf(messageR, R198, to_wstring(varName).c_str());
|
||||||
|
|
||||||
messages.push_back(Messages(typeMessage::NOTE, loopLineNum, messageR, messageE, 2024));
|
messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2024));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addMessageRemovePrivateVar(vector<Messages>& messages, string varName, int loopLineNum)
|
static void addMessageRemovePrivateVar(vector<Messages>& messages, string varName, int loopLineNum)
|
||||||
@@ -385,19 +427,19 @@ static void addMessageCannotFindRD(vector<Messages>& messages, string varName, i
|
|||||||
messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2021));
|
messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2021));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: unused:
|
static void addMessagePossibleDifferentAssumption(vector<Messages>& messages, string varName,
|
||||||
//static void addMessageMoreThanOneRD(vector<Messages>& messages, string varName, int loopLineNum)
|
string ref1, string ref2, int loopLineNum)
|
||||||
//{
|
{
|
||||||
// __spf_print(1, "WARR: cannot remove private var '%s' - more than one definition reaches the statement in line %d\n",
|
__spf_print(1, "WARR: removing of private var '%s' was made with assumption that references '%s' and '%s' are different in line %d\n",
|
||||||
// varName.c_str(), loopLineNum);
|
varName.c_str(), ref1.c_str(), ref2.c_str(), loopLineNum);
|
||||||
//
|
|
||||||
// wstring messageE, messageR;
|
wstring messageE, messageR;
|
||||||
// __spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - more than one definition reaches the statement",
|
__spf_printToLongBuf(messageE, L"Removing of private var '%s' was made with assumption that references '%s' and '%s' are different",
|
||||||
// to_wstring(varName).c_str());
|
to_wstring(varName).c_str(), to_wstring(ref1).c_str(), to_wstring(ref2).c_str());
|
||||||
// __spf_printToLongBuf(messageR, R193, to_wstring(varName).c_str());
|
__spf_printToLongBuf(messageR, R192, to_wstring(varName).c_str(), to_wstring(ref1).c_str(), to_wstring(ref2).c_str());
|
||||||
//
|
|
||||||
// messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2020));
|
messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2019));
|
||||||
//}
|
}
|
||||||
|
|
||||||
static void addMessageRecursiveDependency(vector<Messages>& messages, string varName, int lineNum)
|
static void addMessageRecursiveDependency(vector<Messages>& messages, string varName, int lineNum)
|
||||||
{
|
{
|
||||||
@@ -963,6 +1005,126 @@ static vector<int> getShortFixedSubscriptsVector(Context* ctx, SgArrayRefExp* ar
|
|||||||
return getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime, iterationVars);
|
return getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime, iterationVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getLoopsInfo return vector of pair (string, int) - doName and level for each loop
|
||||||
|
// from stmt up to outerLoop (not only closely nested). Loop levels start from 1
|
||||||
|
static void getLoopsInfo(SgStatement* stmt, SgStatement* outerLoop,
|
||||||
|
vector<pair<string, int>>& loopsInfo)
|
||||||
|
{
|
||||||
|
if (stmt == nullptr)
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
|
if (stmt->variant() == FOR_NODE)
|
||||||
|
{
|
||||||
|
string doName = ((SgForStmt*)stmt)->doName()->identifier();
|
||||||
|
loopsInfo.push_back(make_pair(doName, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stmt == outerLoop)
|
||||||
|
{
|
||||||
|
int levelsNum = loopsInfo.size();
|
||||||
|
for (int i = 0; i < levelsNum; ++i)
|
||||||
|
loopsInfo[i].second = levelsNum - i;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLoopsInfo(stmt->controlParent(), outerLoop, loopsInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkLoopAlignmentMatching checks if all array references in loop has the same alignment
|
||||||
|
// with nested loops
|
||||||
|
static bool checkLoopAlignmentMatching(Context* ctx)
|
||||||
|
{
|
||||||
|
// Loop alignment is a pair of loop alignment vector
|
||||||
|
// and a number of nested loops for current statement context (not only closely nested).
|
||||||
|
// Loop alignment vector is a vector of ctx->dimensionsNum length of loop levels
|
||||||
|
// or -1, if dimension is not aligned with any loop.
|
||||||
|
// Dimension is aligned with loop, if subscript expression has iteration var of this loop
|
||||||
|
// (and only of this loop).
|
||||||
|
set<pair<vector<int>, int>> loopAlignmentSet;
|
||||||
|
|
||||||
|
for (SgStatement* st = ctx->loopStmt; st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
||||||
|
{
|
||||||
|
vector<SgArrayRefExp*> arrayRefs = getDirectArrayRefsFromSingleStmt(st, ctx->arraySymbol);
|
||||||
|
if (arrayRefs.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vector<pair<string, int>> loopsInfoVector;
|
||||||
|
getLoopsInfo(st, ctx->loopStmt, loopsInfoVector);
|
||||||
|
|
||||||
|
for (SgArrayRefExp* arrayRef : arrayRefs)
|
||||||
|
{
|
||||||
|
vector<int> arrayRefLoopAlignment;
|
||||||
|
for (int i = 0; i < ctx->dimensionsNum; ++i)
|
||||||
|
{
|
||||||
|
bool foundIterationVar = false;
|
||||||
|
|
||||||
|
set<string> vars;
|
||||||
|
getVariables(arrayRef->subscript(i), vars, { VAR_REF });
|
||||||
|
for (string var : vars)
|
||||||
|
{
|
||||||
|
for (auto& loopInfo : loopsInfoVector)
|
||||||
|
{
|
||||||
|
if (loopInfo.first != var)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// There are two iteration vars in subscript expression
|
||||||
|
// or one var is iteration var for more than one loop:
|
||||||
|
if (foundIterationVar)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foundIterationVar = true;
|
||||||
|
arrayRefLoopAlignment.push_back(loopInfo.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundIterationVar)
|
||||||
|
arrayRefLoopAlignment.push_back(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
loopAlignmentSet.insert(make_pair(arrayRefLoopAlignment, loopsInfoVector.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all loop alignments has similar alignment diff.
|
||||||
|
// Alignment diff is a difference between the number of nested loops (size of loopInfoVector)
|
||||||
|
// and the number of aligned dimensions (alignment counter).
|
||||||
|
int alignmentDiff = -1;
|
||||||
|
for (auto& loopAlignment : loopAlignmentSet)
|
||||||
|
{
|
||||||
|
int currentAlignmentCounter = ctx->dimensionsNum;
|
||||||
|
for (int i = 0; i < ctx->dimensionsNum; ++i)
|
||||||
|
if (loopAlignment.first[i] == -1) // if dimension is not aligned
|
||||||
|
currentAlignmentCounter--;
|
||||||
|
|
||||||
|
int currentAlignmentDiff = loopAlignment.second - currentAlignmentCounter;
|
||||||
|
if (alignmentDiff == -1)
|
||||||
|
alignmentDiff = currentAlignmentDiff;
|
||||||
|
else if (alignmentDiff != currentAlignmentDiff)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there are any different loop alignments.
|
||||||
|
// Two loop alignments are different if they have different loop level alignments
|
||||||
|
// in the same dimension. The case when one of two different loop level is -1
|
||||||
|
// (there is no loop alignment) is not a problem
|
||||||
|
for (int i = 0; i < ctx->dimensionsNum; ++i)
|
||||||
|
{
|
||||||
|
int currentLoopLevel = -1;
|
||||||
|
for (auto& loopAlignment : loopAlignmentSet)
|
||||||
|
{
|
||||||
|
if (loopAlignment.first[i] != -1) // if loop alignment is not empty
|
||||||
|
{
|
||||||
|
if (currentLoopLevel == -1)
|
||||||
|
currentLoopLevel = loopAlignment.first[i];
|
||||||
|
else if (currentLoopLevel != loopAlignment.first[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
|
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
|
||||||
static bool checkFixedDimensionsMaskMatching(Context* ctx)
|
static bool checkFixedDimensionsMaskMatching(Context* ctx)
|
||||||
@@ -1848,9 +2010,8 @@ static bool fixedSubscriptLess(const ArraySubscript& left, const ArraySubscript&
|
|||||||
|
|
||||||
// fixedSubscriptLess checks if left and right FixedSubscripts are different,
|
// fixedSubscriptLess checks if left and right FixedSubscripts are different,
|
||||||
// using empirical methods
|
// using empirical methods
|
||||||
static bool possibleDifferent(ArraySubscript left, ArraySubscript right)
|
static bool arePossibleDifferent(ArraySubscript left, ArraySubscript right)
|
||||||
{
|
{
|
||||||
// TODO: add warning?
|
|
||||||
if (left.isFixed && right.isRegIndex && right.regExprStart == right.regExprEnd) {
|
if (left.isFixed && right.isRegIndex && right.regExprStart == right.regExprEnd) {
|
||||||
return true; // in general, this is not true
|
return true; // in general, this is not true
|
||||||
}
|
}
|
||||||
@@ -1858,9 +2019,9 @@ static bool possibleDifferent(ArraySubscript left, ArraySubscript right)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// isDifferentRefs checks if exp (var reference) is different from var. Refs are different
|
// areDifferentRefs checks if exp (var reference) is different from var
|
||||||
// if they has at least one different fixed subscript: arr(i, 1) is different from arr(j, 2)
|
static bool areDifferentRefs(Context* ctx, SgExpression* exp, const pair<string, vector<ArraySubscript>>& var,
|
||||||
static bool isDifferentRefs(SgExpression* exp, const pair<string, vector<ArraySubscript>>& var, SgStatement* stmt)
|
SgStatement* stmt)
|
||||||
{
|
{
|
||||||
if (exp->symbol()->identifier() != var.first)
|
if (exp->symbol()->identifier() != var.first)
|
||||||
return true;
|
return true;
|
||||||
@@ -1876,11 +2037,26 @@ static bool isDifferentRefs(SgExpression* exp, const pair<string, vector<ArraySu
|
|||||||
for (int i = 0; i < leftVec.size(); i++)
|
for (int i = 0; i < leftVec.size(); i++)
|
||||||
{
|
{
|
||||||
if (fixedSubscriptLess(leftVec[i], var.second[i])
|
if (fixedSubscriptLess(leftVec[i], var.second[i])
|
||||||
|| fixedSubscriptLess(var.second[i], leftVec[i])
|
|| fixedSubscriptLess(var.second[i], leftVec[i]))
|
||||||
|| possibleDifferent(leftVec[i], var.second[i]))
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (arePossibleDifferent(leftVec[i], var.second[i]))
|
||||||
|
{
|
||||||
|
string varRefStr = var.first + "(";
|
||||||
|
for (int i = 0; i < var.second.size(); ++i)
|
||||||
|
{
|
||||||
|
varRefStr += var.second[i].toString();
|
||||||
|
if (i != var.second.size() - 1)
|
||||||
|
varRefStr += ",";
|
||||||
|
}
|
||||||
|
varRefStr += ")";
|
||||||
|
|
||||||
|
addMessagePossibleDifferentAssumption(ctx->messages, ctx->arraySymbol->identifier(),
|
||||||
|
exp->sunparse(), varRefStr, stmt->lineNumber());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1972,7 +2148,7 @@ static bool checkDefUsePair(Context* ctx, const DefUseStmtsPair& defUse, const C
|
|||||||
auto useLoopStmt = getScopeLoopStmt(defUse.second);
|
auto useLoopStmt = getScopeLoopStmt(defUse.second);
|
||||||
|
|
||||||
LoopGraph* loop = ctx->loop;
|
LoopGraph* loop = ctx->loop;
|
||||||
while (loop->perfectLoop != 1) // (what is it? - TODO: may be remove it)
|
while (loop->perfectLoop != 1)
|
||||||
loop = loop->children[0];
|
loop = loop->children[0];
|
||||||
|
|
||||||
LoopGraph* defLoop = findLoop(loop, defLoopStmt);
|
LoopGraph* defLoop = findLoop(loop, defLoopStmt);
|
||||||
@@ -2022,7 +2198,7 @@ static bool checkDefUsePair(Context* ctx, const DefUseStmtsPair& defUse, const C
|
|||||||
{
|
{
|
||||||
if (st == defUse.second)
|
if (st == defUse.second)
|
||||||
continue;
|
continue;
|
||||||
if (st->variant() == ASSIGN_STAT && !isDifferentRefs(st->expr(0), var, st))
|
if (st->variant() == ASSIGN_STAT && !areDifferentRefs(ctx, st->expr(0), var, st))
|
||||||
{
|
{
|
||||||
addMessageDependOnNonInvariant(ctx->messages, arrayName,
|
addMessageDependOnNonInvariant(ctx->messages, arrayName,
|
||||||
var.first, defUse.first->lineNumber());
|
var.first, defUse.first->lineNumber());
|
||||||
@@ -2179,6 +2355,13 @@ void removePrivatesAnalysis(string filename,
|
|||||||
if (context.explicitArrayRefs.empty())
|
if (context.explicitArrayRefs.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!checkLoopAlignmentMatching(&context))
|
||||||
|
{
|
||||||
|
addMessageVarNotAlignedWithLoop(messages, context.arraySymbol->identifier(),
|
||||||
|
context.loop->lineNum);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
context.fixedDimensionsMask = getFixedDimensionsMask(&context);
|
context.fixedDimensionsMask = getFixedDimensionsMask(&context);
|
||||||
|
|
||||||
if (!context.fixedDimensionsMask.empty() &&
|
if (!context.fixedDimensionsMask.empty() &&
|
||||||
@@ -2194,10 +2377,16 @@ void removePrivatesAnalysis(string filename,
|
|||||||
removePrivateAnalyze(&context);
|
removePrivateAnalyze(&context);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(), context.loop->lineNum);
|
{
|
||||||
|
addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(),
|
||||||
|
context.loop->lineNum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (LoopGraph* loop : loopGraphs)
|
for (LoopGraph* loop : loopGraphs)
|
||||||
removePrivatesAnalysis(filename, loop->children, messages, usersDirectives, commonBlocks, allFuncInfo);
|
{
|
||||||
|
removePrivatesAnalysis(filename, loop->children, messages,
|
||||||
|
usersDirectives, commonBlocks, allFuncInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,12 +95,12 @@ enum typeMessage { WARR, ERROR, NOTE };
|
|||||||
// 16 "cannot remove private var '%s' - it doesn't match any fixed dimensions mask"
|
// 16 "cannot remove private var '%s' - it doesn't match any fixed dimensions mask"
|
||||||
// 17 cannot remove private var '%s' - it has recursive dependency or it depends on non-invariant var '%s'
|
// 17 cannot remove private var '%s' - it has recursive dependency or it depends on non-invariant var '%s'
|
||||||
// 18 "private variable '%s' was removed" or "private variable '%s' was partially removed"
|
// 18 "private variable '%s' was removed" or "private variable '%s' was partially removed"
|
||||||
// 19 "cannot remove private var '%s' - it doesn't have any fixed dimensions"
|
// 19 "Removing of private var '%s' was made with assumption that references '%s' and '%s' are different"
|
||||||
// 20 "cannot remove private var '%s' - more than one definition reaches the statement"
|
// 20 "cannot remove private var '%s' - more than one definition reaches the statement"
|
||||||
// 21 "cannot remove private var '%s' - cannot find reaching definition for the statement"
|
// 21 "cannot remove private var '%s' - cannot find reaching definition for the statement"
|
||||||
// 22 "cannot transform ..."
|
// 22 "cannot transform ..."
|
||||||
// 23 "cannot transform ..."
|
// 23 "cannot transform ..."
|
||||||
// 24 "loop on line %d was removed"
|
// 24 "Cannot remove private var '%s' - its references have different alignment with the loop"
|
||||||
// 25 "Cannot remove private var '%s' - it is used in the call of function '%s'"
|
// 25 "Cannot remove private var '%s' - it is used in the call of function '%s'"
|
||||||
|
|
||||||
// 30xx PARALLEL GROUP
|
// 30xx PARALLEL GROUP
|
||||||
@@ -521,9 +521,9 @@ static const wchar_t *R190 = L"R190:%s#%s";
|
|||||||
static const wchar_t *R191 = L"R191:%s";
|
static const wchar_t *R191 = L"R191:%s";
|
||||||
static const wchar_t *R201 = L"R201:%s";
|
static const wchar_t *R201 = L"R201:%s";
|
||||||
//2019
|
//2019
|
||||||
static const wchar_t *R192 = L"R192:%s";
|
static const wchar_t *R192 = L"R192:%s#%s#%s";
|
||||||
//2020
|
//2020
|
||||||
static const wchar_t *R193 = L"R193:%s";
|
// static const wchar_t *R193 = L"R193:%s";
|
||||||
//2021
|
//2021
|
||||||
static const wchar_t *R194 = L"R194:%s";
|
static const wchar_t *R194 = L"R194:%s";
|
||||||
//2022
|
//2022
|
||||||
@@ -531,7 +531,7 @@ static const wchar_t *R196 = L"R196:";
|
|||||||
//2023
|
//2023
|
||||||
static const wchar_t *R197 = L"R197:";
|
static const wchar_t *R197 = L"R197:";
|
||||||
//2024
|
//2024
|
||||||
static const wchar_t *R198 = L"R198:%d";
|
static const wchar_t *R198 = L"R198:%s";
|
||||||
//2025
|
//2025
|
||||||
static const wchar_t *R203 = L"R203:%s#%s";
|
static const wchar_t *R203 = L"R203:%s#%s";
|
||||||
|
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ R190 = "Нельзя удалить приватную переменную '%s'
|
|||||||
R191 = "Приватная переменная '%s' была удалена"
|
R191 = "Приватная переменная '%s' была удалена"
|
||||||
R201 = "Приватная переменная '%s' была частично удалена"
|
R201 = "Приватная переменная '%s' была частично удалена"
|
||||||
//2019
|
//2019
|
||||||
R192 = "Нельзя удалить приватную переменную '%s' - она не имеет фиксированных измерений"
|
R192 = "Удаление приватной переменной '%s' было выполнено в предположении, что выражения '%s' и '%s' различны"
|
||||||
//2020
|
//2020
|
||||||
R193 = "Нельзя удалить приватную переменную '%s' - более одного определения достигают оператора"
|
R193 = "Нельзя удалить приватную переменную '%s' - более одного определения достигают оператора"
|
||||||
//2021
|
//2021
|
||||||
@@ -241,7 +241,7 @@ R196 = "Невозможно выполнить преобразование ц
|
|||||||
//2023
|
//2023
|
||||||
R197 = "Преобразование не может быть выполнено - не произошло никаких изменений в коде"
|
R197 = "Преобразование не может быть выполнено - не произошло никаких изменений в коде"
|
||||||
//2024
|
//2024
|
||||||
R198 = "Цикл на строке %d был удалён"
|
R198 = "Нельзя удалить приватную переменную '%s' - обращения к ней имеют разное выравнивание с циклом"
|
||||||
//2025
|
//2025
|
||||||
R203 = "Нельзя удалить приватную переменную '%s' - она используется в вызове функции %s"
|
R203 = "Нельзя удалить приватную переменную '%s' - она используется в вызове функции %s"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user