- 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
- fix: Static class members is not correctly recognized as static.

View File

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

View File

@ -54,9 +54,9 @@ void ProjectCompiler::createStandardMakeFile()
file.write("$(BIN): $(OBJ)\n");
if (!mOnlyCheckSyntax) {
if (mProject->options().isCpp) {
writeln(file,"\t$(CPP) $(LINKOBJ) -o \"$(BIN)\" $(LIBS)");
writeln(file,"\t$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)");
} else
writeln(file,"\t$(CC) $(LINKOBJ) -o \"$(BIN)\" $(LIBS)");
writeln(file,"\t$(CC) $(LINKOBJ) -o $(BIN) $(LIBS)");
}
writeMakeObjFilesRules(file);
}
@ -80,9 +80,9 @@ void ProjectCompiler::createDynamicMakeFile()
writeln(file,"$(BIN): $(LINKOBJ)");
if (!mOnlyCheckSyntax) {
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 {
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);
@ -126,7 +126,7 @@ void ProjectCompiler::newMakeFile(QFile& file)
if (mProject->options().usePrecompiledHeader
&& fileExists(mProject->options().precompiledHeader)) {
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);
}
}
@ -473,13 +473,13 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file)
writeln(file, "\t(CC) -c " + genMakePath1(shortFileName) + " $(CFLAGS) " + encodingStr);
} else {
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
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) {
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 {
writeln(file);
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);
}
writeln(file);

View File

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

View File

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

View File

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