- fix: Processing for #if/#elif/#else is not correct.
This commit is contained in:
parent
02a0ed049b
commit
14ba74e705
1
NEWS.md
1
NEWS.md
|
@ -8,6 +8,7 @@ Red Panda C++ Version 2.25
|
|||
- enhancement: Option "Enable ANSI escape sequences Support" in Settings -> Executor
|
||||
- change: Use freetype as the fontengine in windows ( from cyano.CN )
|
||||
- fix: Custom compile options is not used when retrieve macros defined by the compiler.
|
||||
- fix: Processing for #if/#elif/#else is not correct.
|
||||
|
||||
Red Panda C++ Version 2.24
|
||||
|
||||
|
|
|
@ -347,12 +347,12 @@ void CppPreprocessor::handleBranch(const QString &line)
|
|||
// return;
|
||||
// }
|
||||
// }
|
||||
if (!getCurrentBranch()) {
|
||||
setCurrentBranch(false);
|
||||
if (getCurrentBranch()!=BranchResult::isTrue) {
|
||||
setCurrentBranch(BranchResult::parentIsFalse);
|
||||
} else {
|
||||
constexpr int IFDEF_LEN = 5; //length of ifdef;
|
||||
QString name = line.mid(IFDEF_LEN).trimmed();
|
||||
setCurrentBranch( getDefine(name)!=nullptr );
|
||||
setCurrentBranch( getDefine(name)!=nullptr?(BranchResult::isTrue):(BranchResult::isFalse) );
|
||||
|
||||
}
|
||||
} else if (line.startsWith("ifndef")) {
|
||||
|
@ -363,12 +363,12 @@ void CppPreprocessor::handleBranch(const QString &line)
|
|||
// return;
|
||||
// }
|
||||
// }
|
||||
if (!getCurrentBranch()) {
|
||||
setCurrentBranch(false);
|
||||
if (getCurrentBranch()!=BranchResult::isTrue) {
|
||||
setCurrentBranch(BranchResult::parentIsFalse);
|
||||
} else {
|
||||
constexpr int IFNDEF_LEN = 6; //length of ifndef;
|
||||
QString name = line.mid(IFNDEF_LEN).trimmed();
|
||||
setCurrentBranch( getDefine(name)==nullptr );
|
||||
setCurrentBranch( getDefine(name)==nullptr?(BranchResult::isTrue):(BranchResult::isFalse) );
|
||||
}
|
||||
} else if (line.startsWith("if")) {
|
||||
// // if a branch that is not at our level is false, current branch is false too;
|
||||
|
@ -378,29 +378,30 @@ void CppPreprocessor::handleBranch(const QString &line)
|
|||
// return;
|
||||
// }
|
||||
// }
|
||||
if (!getCurrentBranch()) {// we are already inside an if that is NOT being taken
|
||||
setCurrentBranch(false);// so don't take this one either
|
||||
if (getCurrentBranch()!=BranchResult::isTrue) {// we are already inside an if that is NOT being taken
|
||||
setCurrentBranch(BranchResult::parentIsFalse);// so don't take this one either
|
||||
} else {
|
||||
constexpr int IF_LEN = 2; //length of if;
|
||||
QString ifLine = line.mid(IF_LEN).trimmed();
|
||||
|
||||
bool testResult = evaluateIf(ifLine);
|
||||
setCurrentBranch(testResult);
|
||||
setCurrentBranch(testResult?(BranchResult::isTrue):(BranchResult::isFalse));
|
||||
}
|
||||
} else if (line.startsWith("else")) {
|
||||
bool oldResult = getCurrentBranch(); // take either if or else
|
||||
BranchResult oldResult = getCurrentBranch(); // take either if or else
|
||||
removeCurrentBranch();
|
||||
setCurrentBranch(!oldResult);
|
||||
setCurrentBranch(calcElseBranchResult(oldResult));
|
||||
} else if (line.startsWith("elif")) {
|
||||
bool oldResult = getCurrentBranch(); // take either if or else
|
||||
BranchResult oldResult = getCurrentBranch(); // take either if or else
|
||||
removeCurrentBranch();
|
||||
if (oldResult) { // don't take this one, if previous has been taken
|
||||
setCurrentBranch(false);
|
||||
} else {
|
||||
BranchResult elseResult = calcElseBranchResult(oldResult);
|
||||
if (elseResult == BranchResult::isTrue) { // don't take this one, if previous has been taken
|
||||
constexpr int ELIF_LEN = 4; //length of if;
|
||||
QString ifLine = line.mid(ELIF_LEN).trimmed();
|
||||
bool testResult = evaluateIf(ifLine);
|
||||
setCurrentBranch(testResult);
|
||||
setCurrentBranch(testResult?(BranchResult::isTrue):(BranchResult::isFalse));
|
||||
} else {
|
||||
setCurrentBranch(elseResult);
|
||||
}
|
||||
} else if (line.startsWith("endif")) {
|
||||
removeCurrentBranch();
|
||||
|
@ -409,7 +410,7 @@ void CppPreprocessor::handleBranch(const QString &line)
|
|||
|
||||
void CppPreprocessor::handleDefine(const QString &line)
|
||||
{
|
||||
if (getCurrentBranch()) {
|
||||
if (getCurrentBranch() == BranchResult::isTrue) {
|
||||
addDefineByLine(line, false);
|
||||
mResult[mPreProcIndex] = '#' + line; // add define to result file so the parser can handle it
|
||||
}
|
||||
|
@ -417,7 +418,7 @@ void CppPreprocessor::handleDefine(const QString &line)
|
|||
|
||||
void CppPreprocessor::handleInclude(const QString &line, bool fromNext)
|
||||
{
|
||||
if (!getCurrentBranch()) // we're skipping due to a branch failure
|
||||
if (getCurrentBranch()!=BranchResult::isTrue) // we're skipping due to a branch failure
|
||||
return;
|
||||
|
||||
PParsedFile file = mIncludes.back();
|
||||
|
@ -902,6 +903,17 @@ void CppPreprocessor::closeInclude()
|
|||
.arg(parsedFile->index+1));
|
||||
}
|
||||
|
||||
CppPreprocessor::BranchResult CppPreprocessor::calcElseBranchResult(BranchResult oldResult)
|
||||
{
|
||||
switch(oldResult) {
|
||||
case BranchResult::isTrue: return BranchResult::isFalse_but_trued;
|
||||
case BranchResult::isFalse: return BranchResult::isTrue;
|
||||
case BranchResult::isFalse_but_trued: return BranchResult::isFalse_but_trued;
|
||||
case BranchResult::parentIsFalse: return BranchResult::parentIsFalse;
|
||||
}
|
||||
Q_ASSERT( false ); //We should fail here.
|
||||
}
|
||||
|
||||
void CppPreprocessor::addDefinesInFile(const QString &fileName)
|
||||
{
|
||||
if (mProcessed.contains(fileName))
|
||||
|
@ -1200,7 +1212,7 @@ void CppPreprocessor::skipToPreprocessor()
|
|||
int bufferCount = mBuffer.count();
|
||||
// Increment until a line begins with a #
|
||||
while ((mIndex < bufferCount) && !mBuffer[mIndex].startsWith('#')) {
|
||||
if (getCurrentBranch()) { // if not skipping, expand current macros
|
||||
if (getCurrentBranch()==BranchResult::isTrue) { // if not skipping, expand current macros
|
||||
int startIndex = mIndex;
|
||||
QString expanded = expandMacros();
|
||||
mResult.append(expanded);
|
||||
|
|
|
@ -104,6 +104,14 @@ public:
|
|||
static QList<PDefineArgToken> tokenizeValue(const QString& value);
|
||||
|
||||
private:
|
||||
|
||||
enum class BranchResult {
|
||||
isTrue, /* This branch is true */
|
||||
isFalse_but_trued, /* This branch is false, but a previous branch is true */
|
||||
isFalse, /* This branch and all previous branches is false */
|
||||
parentIsFalse
|
||||
};
|
||||
|
||||
void preprocessBuffer();
|
||||
void skipToEndOfPreprocessor();
|
||||
void skipToPreprocessor();
|
||||
|
@ -130,27 +138,32 @@ private:
|
|||
void closeInclude();
|
||||
|
||||
// branch stuff
|
||||
bool getCurrentBranch(){
|
||||
BranchResult getCurrentBranch(){
|
||||
if (!mBranchResults.isEmpty())
|
||||
return mBranchResults.last();
|
||||
else
|
||||
return true;
|
||||
return BranchResult::isTrue;
|
||||
}
|
||||
void setCurrentBranch(bool value){
|
||||
if (value!=getCurrentBranch()) {
|
||||
mCurrentIncludes->branches.insert(mIndex+1,value);
|
||||
BranchResult calcElseBranchResult(BranchResult oldResult);
|
||||
bool sameResultWithCurrentBranch(BranchResult value) {
|
||||
return (getCurrentBranch()==BranchResult::isTrue && value == BranchResult::isTrue)
|
||||
|| (getCurrentBranch()!=BranchResult::isTrue && value != BranchResult::isTrue);
|
||||
}
|
||||
void setCurrentBranch(BranchResult value){
|
||||
if (!sameResultWithCurrentBranch(value)) {
|
||||
mCurrentIncludes->branches.insert(mIndex+1,value==BranchResult::isTrue);
|
||||
}
|
||||
mBranchResults.append(value);
|
||||
}
|
||||
void removeCurrentBranch(){
|
||||
bool result = getCurrentBranch();
|
||||
BranchResult value = getCurrentBranch();
|
||||
if (mBranchResults.size()>0) {
|
||||
mBranchResults.pop_back();
|
||||
}
|
||||
if (getCurrentBranch()!=result) {
|
||||
mCurrentIncludes->branches.insert(mIndex,getCurrentBranch());
|
||||
if (!sameResultWithCurrentBranch(value)) {
|
||||
mCurrentIncludes->branches.insert(mIndex,getCurrentBranch()==BranchResult::isTrue);
|
||||
}
|
||||
};
|
||||
}
|
||||
// include stuff
|
||||
PFileIncludes getFileIncludesEntry(const QString& fileName){
|
||||
return mIncludesList.value(fileName,PFileIncludes());
|
||||
|
@ -227,7 +240,6 @@ static bool isNumberChar(const QChar& ch);
|
|||
|
||||
int evaluateExpression(QString line);
|
||||
private:
|
||||
|
||||
//temporary data when preprocessing single file
|
||||
int mIndex; // points to current file buffer.
|
||||
QString mFileName;
|
||||
|
@ -236,7 +248,7 @@ private:
|
|||
PFileIncludes mCurrentIncludes;
|
||||
int mPreProcIndex;
|
||||
QList<PParsedFile> mIncludes; // stack of files we've stepped into. last one is current file, first one is source file
|
||||
QList<bool> mBranchResults;// stack of branch results (boolean). last one is current branch, first one is outermost branch
|
||||
QList<BranchResult> mBranchResults;// stack of branch results (boolean). last one is current branch, first one is outermost branch
|
||||
DefineMap mDefines; // working set, editable
|
||||
QSet<QString> mProcessed; // dictionary to save filename already processed
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ struct Statement {
|
|||
// definiton line/filename is valid
|
||||
bool hasDefinition() {
|
||||
return properties.testFlag(StatementProperty::spHasDefinition);
|
||||
};
|
||||
}
|
||||
void setHasDefinition(bool on) {
|
||||
properties.setFlag(StatementProperty::spHasDefinition,on);
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ struct Statement {
|
|||
// statement in system header (#include <>)
|
||||
bool inSystemHeader() {
|
||||
return properties.testFlag(StatementProperty::spInSystemHeader);
|
||||
};
|
||||
}
|
||||
void setInSystemHeader(bool on) {
|
||||
properties.setFlag(StatementProperty::spInSystemHeader, on);
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ struct Statement {
|
|||
}
|
||||
bool isInherited() {
|
||||
return properties.testFlag(StatementProperty::spInherited);
|
||||
}; // inherted member;
|
||||
} // inherted member;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -439,13 +439,11 @@ PStatement ClassBrowserModel::createDummy(const PStatement& statement)
|
|||
|
||||
ClassBrowserNode* ClassBrowserModel::getParentNode(const PStatement &parentStatement, int depth)
|
||||
{
|
||||
if (depth>10)
|
||||
return nullptr;
|
||||
if (!parentStatement)
|
||||
return mRoot;
|
||||
if (!isScopeStatement(parentStatement)) {
|
||||
return mRoot;
|
||||
}
|
||||
Q_ASSERT(depth<=10);
|
||||
if (depth>10) return mRoot;
|
||||
if (!parentStatement) return mRoot;
|
||||
if (!isScopeStatement(parentStatement)) return mRoot;
|
||||
|
||||
PClassBrowserNode parentNode = mScopeNodes.value(parentStatement->fullName,PClassBrowserNode());
|
||||
if (!parentNode) {
|
||||
PStatement dummyParent = createDummy(parentStatement);
|
||||
|
|
Loading…
Reference in New Issue