diff --git a/NEWS.md b/NEWS.md index 4c0150fd..621f8fb1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -96,6 +96,8 @@ Red Panda C++ Version 2.27 - fix: An undefined macro is still missing the the parse result after #undef is removed. - fix: If a class method is overloaded, only one of them is inherited by it's children. - enhancement: Adjust function tip pos to prevent it from run outside the right window edge. + - enhancement: Open ".def" (Module definition file) file in editor when double click it in the project view. + - enhancement: When a dll project has .def file, use it when generating the dll file. Red Panda C++ Version 2.26 - enhancement: Code suggestion for embedded std::vectors. diff --git a/RedPandaIDE/compiler/projectcompiler.cpp b/RedPandaIDE/compiler/projectcompiler.cpp index b003ff84..863a5f8f 100644 --- a/RedPandaIDE/compiler/projectcompiler.cpp +++ b/RedPandaIDE/compiler/projectcompiler.cpp @@ -54,7 +54,8 @@ void ProjectCompiler::buildMakeFile() void ProjectCompiler::createStandardMakeFile() { QFile file(mProject->makeFileName()); - newMakeFile(file); + bool genModuleDef; + newMakeFile(file, genModuleDef); QString executable = extractRelativePath(mProject->makeFileName(), mProject->executable()); QString exeTarget = escapeFilenameForMakefileTarget(executable); QString exeCommand = escapeArgumentForMakefileRecipe(executable, false); @@ -84,20 +85,35 @@ void ProjectCompiler::createStaticMakeFile() void ProjectCompiler::createDynamicMakeFile() { QFile file(mProject->makeFileName()); - newMakeFile(file); + bool genModuleDef; + newMakeFile(file, genModuleDef); QString executable = extractRelativePath(mProject->makeFileName(), mProject->executable()); QString exeTarget = escapeFilenameForMakefileTarget(executable); QString exeCommand = escapeArgumentForMakefileRecipe(executable, false); - writeln(file, exeTarget + ": $(OBJ)"); - if (mProject->options().isCpp) { - writeln(file, "\t$(CXX) -mdll $(LINKOBJ) -o " + exeCommand + " $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)"); + writeln(file, exeTarget + ": $(DEF) $(OBJ)"); + if (genModuleDef) { + if (mProject->options().isCpp) { + writeln(file, "\t$(CXX) -mdll $(LINKOBJ) -o " + exeCommand + " $(LIBS) $(DEF) -Wl,--output-def,$(OUTPUT_DEF),--out-implib,$(STATIC)"); + } else { + writeln(file, "\t$(CC) -mdll $(LINKOBJ) -o " + exeCommand + " $(LIBS) $(DEF) -Wl,--output-def,$(OUTPUT_DEF),--out-implib,$(STATIC)"); + } } else { - writeln(file, "\t$(CC) -mdll $(LINKOBJ) -o " + exeCommand + " $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)"); + if (mProject->options().isCpp) { + writeln(file, "\t$(CXX) -mdll $(LINKOBJ) -o " + exeCommand + " $(LIBS) $(DEF) -Wl,--out-implib,$(STATIC)"); + } else { + writeln(file, "\t$(CC) -mdll $(LINKOBJ) -o " + exeCommand + " $(LIBS) $(DEF) -Wl,--out-implib,$(STATIC)"); + } } writeMakeObjFilesRules(file); } -void ProjectCompiler::newMakeFile(QFile& file) +void ProjectCompiler::newMakeFile(QFile &file) +{ + bool dummy; + newMakeFile(file, dummy); +} + +void ProjectCompiler::newMakeFile(QFile& file, bool &genModuleDef) { // Create OBJ output directory if (!mProject->options().objectOutput.isEmpty()) { @@ -120,7 +136,7 @@ void ProjectCompiler::newMakeFile(QFile& file) writeMakeHeader(file); // Writes definition list - writeMakeDefines(file); + writeMakeDefines(file, genModuleDef); // Write PHONY and all targets writeMakeTarget(file); @@ -152,24 +168,25 @@ void ProjectCompiler::writeMakeHeader(QFile &file) writeln(file); } -void ProjectCompiler::writeMakeDefines(QFile &file) +void ProjectCompiler::writeMakeDefines(QFile &file, bool &genModuleDef) { // Get list of object files QStringList Objects; QStringList LinkObjects; QStringList cleanObjects; + QStringList moduleDefines; + + genModuleDef = false; // Create a list of object files foreach(const PProjectUnit &unit, mProject->unitList()) { - if (!unit->compile() && !unit->link()) - continue; // Only process source files - QString RelativeName = extractRelativePath(mProject->directory(), unit->fileName()); - FileType fileType = getFileType(RelativeName); + FileType fileType = getFileType(unit->fileName()); if (fileType == FileType::CSource || fileType == FileType::CppSource || fileType==FileType::GAS) { + QString relativeName = extractRelativePath(mProject->directory(), unit->fileName()); if (!mProject->options().objectOutput.isEmpty()) { // ofile = C:\MyProgram\obj\main.o QString fullObjFile = includeTrailingPathDelimiter(mProject->options().objectOutput) @@ -181,14 +198,15 @@ void ProjectCompiler::writeMakeDefines(QFile &file) LinkObjects << relativeObjFile; } } else { - Objects << changeFileExt(RelativeName, OBJ_EXT); - cleanObjects << localizePath(changeFileExt(RelativeName, OBJ_EXT)); + Objects << changeFileExt(relativeName, OBJ_EXT); + cleanObjects << localizePath(changeFileExt(relativeName, OBJ_EXT)); if (unit->link()) - LinkObjects << changeFileExt(RelativeName, OBJ_EXT); + LinkObjects << changeFileExt(relativeName, OBJ_EXT); } } + if (fileType == FileType::ModuleDef) + moduleDefines.append(extractRelativePath(mProject->makeFileName(), unit->fileName())); } - // Get windres file QString objResFile; QString cleanRes; @@ -299,9 +317,12 @@ void ProjectCompiler::writeMakeDefines(QFile &file) QString defFile = localizePath(changeFileExt(libOutputFile, DEF_EXT)); QString staticFile = localizePath(changeFileExt(libOutputFile, LIB_EXT)); + writeln(file,"DEF = " + escapeFilenamesForMakefilePrerequisite(moduleDefines)); + writeln(file,"STATIC = " + escapeFilenameForMakefilePrerequisite(staticFile)); - writeln(file,"DEF = " + escapeArgumentForMakefileVariableValue(defFile, false)); - writeln(file,"STATIC = " + escapeArgumentForMakefileVariableValue(staticFile, false)); + genModuleDef = !moduleDefines.contains(defFile); + if (genModuleDef) + writeln(file,"OUTPUT_DEF = " + escapeFilenameForMakefilePrerequisite(defFile)); } writeln(file); } @@ -336,7 +357,7 @@ void ProjectCompiler::writeMakeClean(QFile &file) } if (mProject->options().type == ProjectType::DynamicLib) { - target +=" $(DEF) $(STATIC)"; + target +=" $(STATIC)"; } writeln(file, QString("\t-$(RM) %1 > %2 2>&1").arg(target,NULL_FILE)); writeln(file); diff --git a/RedPandaIDE/compiler/projectcompiler.h b/RedPandaIDE/compiler/projectcompiler.h index 552f76fc..acdaa42b 100644 --- a/RedPandaIDE/compiler/projectcompiler.h +++ b/RedPandaIDE/compiler/projectcompiler.h @@ -39,8 +39,9 @@ private: void createStaticMakeFile(); void createDynamicMakeFile(); void newMakeFile(QFile& file); + void newMakeFile(QFile& file, bool &genModuleDef); void writeMakeHeader(QFile& file); - void writeMakeDefines(QFile& file); + void writeMakeDefines(QFile& file, bool &genModuleDef); void writeMakeTarget(QFile& file); void writeMakeIncludes(QFile& file); void writeMakeClean(QFile& file); diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index c975476f..4d0a0acc 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -4392,17 +4392,16 @@ void CppParser::inheritClassStatement(const PStatement& derived, bool isStruct, || statement->kind == StatementKind::skDestructor) continue; if (derived->children.contains(statement->command)) { - // test if all children with the same name are not inherited. - // If so, it's overwrited and shouldn't inherit. + // Check if it's overwritten(hidden) by the derived QList children = derived->children.values(statement->command); - bool hasInherited = false; + bool overwritten = false; foreach(const PStatement& child, children) { - if (child->isInherited()) { - hasInherited = true; + if (!child->isInherited() && child->noNameArgs == statement->noNameArgs) { + overwritten = true; break; } } - if (!hasInherited) + if (overwritten) continue; } StatementAccessibility m_acc; diff --git a/RedPandaIDE/utils.cpp b/RedPandaIDE/utils.cpp index 5c3368d6..83599455 100644 --- a/RedPandaIDE/utils.cpp +++ b/RedPandaIDE/utils.cpp @@ -105,6 +105,9 @@ FileType getFileType(const QString &filename) if (filename.endsWith(".vs",PATH_SENSITIVITY)) { return FileType::VerticeShader; } + if (filename.endsWith(".def",PATH_SENSITIVITY)) { + return FileType::ModuleDef; + } QFileInfo info(filename); if (info.suffix().isEmpty()) { return FileType::Other; diff --git a/RedPandaIDE/utils.h b/RedPandaIDE/utils.h index 0f351862..f192fd42 100644 --- a/RedPandaIDE/utils.h +++ b/RedPandaIDE/utils.h @@ -49,6 +49,7 @@ enum class FileType{ Text, // text file FragmentShader, VerticeShader, + ModuleDef, // Windows Module Definition Other // any others };