- fix: Project files that not in the project folder is not correctly handled in makefile.

- enhancement: Improve support for function pointer typedefs.
This commit is contained in:
Roy Qu 2023-03-01 11:29:30 +08:00
parent 00a7a770ed
commit e7013cff1a
6 changed files with 46 additions and 33 deletions

View File

@ -1,3 +1,8 @@
Red Panda C++ Version 2.16
- fix: Project files that not in the project folder is not correctly handled in makefile.
- enhancement: Improve support for function pointer typedefs.
Red Panda C++ Version 2.15 Red Panda C++ Version 2.15
- fix: Static class members is not correctly recognized as static. - fix: Static class members is not correctly recognized as static.

View File

@ -8,7 +8,7 @@ isEmpty(APP_NAME) {
} }
isEmpty(APP_VERSION) { isEmpty(APP_VERSION) {
APP_VERSION = 2.15 APP_VERSION = 2.16
} }
contains(QMAKE_HOST.arch, x86_64):{ contains(QMAKE_HOST.arch, x86_64):{

View File

@ -54,9 +54,9 @@ void ProjectCompiler::createStandardMakeFile()
file.write("$(BIN): $(OBJ)\n"); file.write("$(BIN): $(OBJ)\n");
if (!mOnlyCheckSyntax) { if (!mOnlyCheckSyntax) {
if (mProject->options().isCpp) { if (mProject->options().isCpp) {
writeln(file,"\t$(CPP) $(LINKOBJ) -o \"$(BIN)\" $(LIBS)"); writeln(file,"\t$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)");
} else } else
writeln(file,"\t$(CC) $(LINKOBJ) -o \"$(BIN)\" $(LIBS)"); writeln(file,"\t$(CC) $(LINKOBJ) -o $(BIN) $(LIBS)");
} }
writeMakeObjFilesRules(file); writeMakeObjFilesRules(file);
} }
@ -80,9 +80,9 @@ void ProjectCompiler::createDynamicMakeFile()
writeln(file,"$(BIN): $(LINKOBJ)"); writeln(file,"$(BIN): $(LINKOBJ)");
if (!mOnlyCheckSyntax) { if (!mOnlyCheckSyntax) {
if (mProject->options().isCpp) { if (mProject->options().isCpp) {
writeln(file, "\t$(CPP) -mdll $(LINKOBJ) -o \"$(BIN)\" $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)"); writeln(file, "\t$(CPP) -mdll $(LINKOBJ) -o $(BIN) $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)");
} else { } else {
writeln(file, "\t$(CC) -mdll $(LINKOBJ) -o \"$(BIN)\" $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)"); writeln(file, "\t$(CC) -mdll $(LINKOBJ) -o $(BIN) $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)");
} }
} }
writeMakeObjFilesRules(file); writeMakeObjFilesRules(file);
@ -126,7 +126,7 @@ void ProjectCompiler::newMakeFile(QFile& file)
if (mProject->options().usePrecompiledHeader if (mProject->options().usePrecompiledHeader
&& fileExists(mProject->options().precompiledHeader)) { && fileExists(mProject->options().precompiledHeader)) {
writeln(file, "$(PCH) : $(PCH_H)"); writeln(file, "$(PCH) : $(PCH_H)");
writeln(file, "\t$(CPP) -c \"$(PCH_H)\" -o \"$(PCH)\" $(CXXFLAGS)"); writeln(file, "\t$(CPP) -c $(PCH_H) -o $(PCH) $(CXXFLAGS)");
writeln(file); writeln(file);
} }
} }
@ -473,13 +473,13 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file)
writeln(file, "\t(CC) -c " + genMakePath1(shortFileName) + " $(CFLAGS) " + encodingStr); writeln(file, "\t(CC) -c " + genMakePath1(shortFileName) + " $(CFLAGS) " + encodingStr);
} else { } else {
if (unit->compileCpp()) if (unit->compileCpp())
writeln(file, "\t$(CPP) -c " + genMakePath1(shortFileName) + " -o \"" + objFileName2 + "\" $(CXXFLAGS) " + encodingStr); writeln(file, "\t$(CPP) -c " + genMakePath1(shortFileName) + " -o " + objFileName2 + " $(CXXFLAGS) " + encodingStr);
else else
writeln(file, "\t$(CC) -c " + genMakePath1(shortFileName) + " -o \"" + objFileName2 + "\" $(CFLAGS) " + encodingStr); writeln(file, "\t$(CC) -c " + genMakePath1(shortFileName) + " -o " + objFileName2 + " $(CFLAGS) " + encodingStr);
} }
} else if (fileType==FileType::GAS) { } else if (fileType==FileType::GAS) {
if (!mOnlyCheckSyntax) { if (!mOnlyCheckSyntax) {
writeln(file, "\t$(CC) -c " + genMakePath1(shortFileName) + " -o \"" + objFileName2 + "\" $(CFLAGS) " + encodingStr); writeln(file, "\t$(CC) -c " + genMakePath1(shortFileName) + " -o " + objFileName2 + " $(CFLAGS) " + encodingStr);
} }
} }
} }
@ -535,7 +535,7 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file)
} else { } else {
writeln(file); writeln(file);
writeln(file, objFileName2 + ": " + privResName2 + ' ' + resFiles); writeln(file, objFileName2 + ": " + privResName2 + ' ' + resFiles);
writeln(file, "\t$(WINDRES) -i " + privResName + windresArgs + " --input-format=rc -o \"" + objFileName + "\" -O coff $(WINDRESFLAGS)" writeln(file, "\t$(WINDRES) -i " + privResName + windresArgs + " --input-format=rc -o " + objFileName + " -O coff $(WINDRESFLAGS)"
+ ResIncludes); + ResIncludes);
} }
writeln(file); writeln(file);

View File

@ -2479,17 +2479,13 @@ void CppParser::handleLambda(int index, int endIndex)
i++; i++;
} else if (mTokenizer[i]->text==';') { } else if (mTokenizer[i]->text==';') {
break; break;
} else if (isWordChar(mTokenizer[i]->text[0])) { } else if (isIdentChar(mTokenizer[i]->text[0])) {
QString cmd=mTokenizer[i]->text; QString cmd=mTokenizer[i]->text;
while (cmd.startsWith('*')) {
cmd=cmd.mid(1);
}
if (cmd=="const") { if (cmd=="const") {
tempType="const"; tempType="const";
} else { } else {
QString suffix; QString suffix;
QString args; QString args;
cmd=mTokenizer[i]->text;
parseCommandTypeAndArgs(cmd,suffix,args); parseCommandTypeAndArgs(cmd,suffix,args);
if (!cmd.isEmpty()) { if (!cmd.isEmpty()) {
addChildStatement( addChildStatement(
@ -2872,7 +2868,6 @@ void CppParser::handleOtherTypedefs()
break; break;
} else if (mTokenizer[mIndex]->text == '(') { } else if (mTokenizer[mIndex]->text == '(') {
int paramStart=mTokenizer[mIndex]->matchIndex+1; int paramStart=mTokenizer[mIndex]->matchIndex+1;
QString newType = mTokenizer[mIndex+1]->text;
if (paramStart>=mTokenizer.tokenCount() if (paramStart>=mTokenizer.tokenCount()
|| mTokenizer[paramStart]->text!='(') { || mTokenizer[paramStart]->text!='(') {
//not valid function pointer (no args) //not valid function pointer (no args)
@ -2880,8 +2875,7 @@ void CppParser::handleOtherTypedefs()
mIndex=indexOfNextSemicolon(paramStart)+1; mIndex=indexOfNextSemicolon(paramStart)+1;
return; return;
} }
if (newType.startsWith('*')) QString newType = findFunctionPointerName(mIndex);
newType = newType.mid(1);
if (!newType.isEmpty()) { if (!newType.isEmpty()) {
addStatement( addStatement(
getCurrentScope(), getCurrentScope(),
@ -3608,17 +3602,16 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
} }
} else if (mTokenizer[mIndex]->text==';') { } else if (mTokenizer[mIndex]->text==';') {
break; break;
} else if (isWordChar(mTokenizer[mIndex]->text[0])) { } else if (isIdentChar(mTokenizer[mIndex]->text[0])) {
QString cmd=mTokenizer[mIndex]->text; QString cmd=mTokenizer[mIndex]->text;
if (mIndex+1< mTokenizer.tokenCount() && mTokenizer[mIndex+1]->text=='(' if (mIndex+1< mTokenizer.tokenCount() && mTokenizer[mIndex+1]->text=='('
&& mTokenizer[mIndex+1]->matchIndex+1<mTokenizer.tokenCount() && mTokenizer[mIndex+1]->matchIndex+1<mTokenizer.tokenCount()
&& mTokenizer[mTokenizer[mIndex+1]->matchIndex+1]->text=='(') { && mTokenizer[mTokenizer[mIndex+1]->matchIndex+1]->text=='(') {
//function pointer //function pointer
cmd = mTokenizer[mIndex+2]->text;
cmd = findFunctionPointerName(mIndex+1);
int argStart=mTokenizer[mIndex+1]->matchIndex+1; int argStart=mTokenizer[mIndex+1]->matchIndex+1;
int argEnd=mTokenizer[argStart]->matchIndex; int argEnd=mTokenizer[argStart]->matchIndex;
if (cmd.startsWith("*"))
cmd = cmd.mid(1);
if (!cmd.isEmpty()) { if (!cmd.isEmpty()) {
QString type=lastType; QString type=lastType;
@ -3645,9 +3638,6 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
mIndex=indexOfNextSemicolonOrLeftBrace(argEnd+1); mIndex=indexOfNextSemicolonOrLeftBrace(argEnd+1);
} else { } else {
//normal var //normal var
while (cmd.startsWith('*')) {
cmd=cmd.mid(1);
}
if (cmd=="const") { if (cmd=="const") {
tempType=mTokenizer[mIndex]->text; tempType=mTokenizer[mIndex]->text;
} else { } else {
@ -4890,6 +4880,20 @@ void CppParser::doSkipInExpression(const QStringList &expression, int &pos, cons
} }
} }
QString CppParser::findFunctionPointerName(int startIdx)
{
Q_ASSERT(mTokenizer[startIdx]->text=="(");
int i=startIdx+1;
int endIdx = mTokenizer[startIdx]->matchIndex;
while (i<endIdx) {
if (isIdentChar(mTokenizer[i]->text[0])) {
return mTokenizer[i]->text;
}
i++;
}
return QString();
}
PStatement CppParser::doParseEvalTypeInfo( PStatement CppParser::doParseEvalTypeInfo(
const QString &fileName, const QString &fileName,
const PStatement &scope, const PStatement &scope,
@ -5076,9 +5080,7 @@ void CppParser::scanMethodArgs(const PStatement& functionStatement, int argStart
//function pointer //function pointer
int argStart=mTokenizer[i]->matchIndex+1; int argStart=mTokenizer[i]->matchIndex+1;
int argEnd=mTokenizer[argStart]->matchIndex; int argEnd=mTokenizer[argStart]->matchIndex;
QString cmd=mTokenizer[i+1]->text; QString cmd=findFunctionPointerName(i);
if (cmd.startsWith('*'))
cmd=cmd.mid(1);
QString args=mergeArgs(argStart,argEnd); QString args=mergeArgs(argStart,argEnd);
if (!cmd.isEmpty()) { if (!cmd.isEmpty()) {
addStatement( addStatement(
@ -5642,10 +5644,15 @@ QString CppParser::mergeArgs(int startIndex, int endIndex)
void CppParser::parseCommandTypeAndArgs(QString &command, QString &typeSuffix, QString &args) void CppParser::parseCommandTypeAndArgs(QString &command, QString &typeSuffix, QString &args)
{ {
typeSuffix=""; int prefix=0;
while (command.startsWith('*') || command.startsWith('&')) { while (prefix<command.length() && (command[prefix]=='*' || command[prefix]=='&')) {
typeSuffix=command.front(); prefix++;
command=command.mid(1); }
if (prefix>0) {
typeSuffix=command.left(prefix);
command=command.mid(prefix);
} else {
typeSuffix="";
} }
int pos=command.indexOf('['); int pos=command.indexOf('[');
if (pos>=0) { if (pos>=0) {

View File

@ -340,6 +340,7 @@ private:
PEvalStatement doCreateEvalLiteral(const QString& type); PEvalStatement doCreateEvalLiteral(const QString& type);
void doSkipInExpression(const QStringList& expression, int&pos, const QString& startSymbol, const QString& endSymbol); void doSkipInExpression(const QStringList& expression, int&pos, const QString& startSymbol, const QString& endSymbol);
QString findFunctionPointerName(int startIdx);
bool isIdentifier(const QString& token) const { bool isIdentifier(const QString& token) const {
return (!token.isEmpty() && isIdentChar(token.front()) return (!token.isEmpty() && isIdentChar(token.front())
&& !token.contains('\"')); && !token.contains('\"'));

View File

@ -14,7 +14,7 @@ qsynedit.subdir = libs/qsynedit
APP_NAME = RedPandaCPP APP_NAME = RedPandaCPP
APP_VERSION = 2.15 APP_VERSION = 2.16
# Add the dependencies so that the RedPandaIDE project can add the depended programs # Add the dependencies so that the RedPandaIDE project can add the depended programs
# into the main app bundle # into the main app bundle