diff --git a/RedPandaIDE/parser/cpppreprocessor.cpp b/RedPandaIDE/parser/cpppreprocessor.cpp index 586b928f..0828562f 100644 --- a/RedPandaIDE/parser/cpppreprocessor.cpp +++ b/RedPandaIDE/parser/cpppreprocessor.cpp @@ -144,35 +144,24 @@ void CppPreprocessor::handlePreprocessor(const QString &value) void CppPreprocessor::handleUndefine(const QString &line) { // Remove undef - Name := TrimLeft(Copy(Line, Length('undef') + 1, MaxInt)); + constexpr int UNDEF_LEN = 5; + QString name = line.mid(UNDEF_LEN).trimmed(); - files:=TStringList.Create; - files.Sorted:=True; - files.Duplicates:=dupIgnore; - try - // may be defined many times - while True do begin - Define := GetDefine(Name, Index); - if Assigned(Define) then begin - fDefineIndex.Remove(Name); - fDefines.objects[index]:=nil; - files.AddObject(Define^.FileName,Pointer(Define)); - end else - break; - end; - for i:=0 to files.Count-1 do begin - Define:= PDefine(files.objects[i]); - idx:=FastIndexOf(fFileDefines,files[i]); - if idx>0 then begin - DefineList:=TList(fFileDefines.Objects[idx]); - DefineList.Remove(Pointer(Define)); - define^.ArgList.Free; - Dispose(PDefine(Define)); - end; - end; - finally - files.Free; - end; + int index; +// //may be defined many times +// while (true) { + PDefine define = getDefine(name, index); + if (define) { + //remove the define from defines set + mDefines.remove(name); + //remove the define form the file where it defines + if (define->filename == mFileName) { + PDefineMap defineMap = mFileDefines.value(mFileName); + if (defineMap) { + defineMap->remove(name); + } + } + } } QString CppPreprocessor::expandMacros(const QString &line, int depth) @@ -277,6 +266,7 @@ PParsedFile CppPreprocessor::getInclude(int index) return mIncludes[index]; } + void CppPreprocessor::closeInclude() { if (mIncludes.isEmpty()) @@ -340,19 +330,22 @@ void CppPreprocessor::addDefinesInFile(const QString &fileName) if (!mScannedFiles.contains(fileName)) return; - PDefineMap defineList = mFileDefines.value(fileName, PDefineMap()); - - if (defineList) { - for (PDefine define: defineList->values()) { - mDefines.insert(define->name,define); - } - } + //May be redefined, so order is important + //first add the defines in the files it included PFileIncludes fileIncludes = getFileIncludesEntry(fileName); if (fileIncludes) { for (QString s:fileIncludes->includeFiles.keys()) { addDefinesInFile(s); } } + + // then add the defines defined in it + PDefineMap defineList = mFileDefines.value(fileName, PDefineMap()); + if (defineList) { + for (PDefine define: defineList->values()) { + mDefines.insert(define->name,define); + } + } } bool CppPreprocessor::isWordChar(const QChar &ch) diff --git a/RedPandaIDE/parser/cpppreprocessor.h b/RedPandaIDE/parser/cpppreprocessor.h index 1fc9511b..43768826 100644 --- a/RedPandaIDE/parser/cpppreprocessor.h +++ b/RedPandaIDE/parser/cpppreprocessor.h @@ -142,8 +142,8 @@ private: QHash mFileDefines; //dictionary to save defines for each headerfile; QList mIncludes; // stack of files we've stepped into. last one is current file, first one is source file QList mBranchResults;// stack of branch results (boolean). last one is current branch, first one is outermost branch - QStringList mIncludePaths; // path to include folders - QStringList mProjectIncludePaths; + std::shared_ptr mIncludePaths; // path to include folders + std::shared_ptr mProjectIncludePaths; bool mParseSystem; bool mParseLocal; QSet mScannedFiles; diff --git a/RedPandaIDE/parser/statementmodel.cpp b/RedPandaIDE/parser/statementmodel.cpp index 6031059a..776087e6 100644 --- a/RedPandaIDE/parser/statementmodel.cpp +++ b/RedPandaIDE/parser/statementmodel.cpp @@ -70,46 +70,41 @@ void StatementModel::addMember(StatementMap &map, PStatement statement) { if (!statement) return ; - PStatementList lst = map.value(statement->command, PStatementList()); - if (!lst) { - lst=std::make_shared(); - map.insert(statement->command,lst); - } - lst->append(statement); + map.insert(statement->command,statement); +// QList lst = map.values(statement->command); +// if (!lst) { +// lst=std::make_shared(); +// map.insert(,lst); +// } +// lst->append(statement); } int StatementModel::deleteMember(StatementMap &map, PStatement statement) { if (!statement) return 0; - PStatementList lst = map.value(statement->command, PStatementList()); - if (!lst) { - return 0; - } - return lst->removeAll(statement); + map.remove(statement->command,statement); } void StatementModel::dumpStatementMap(StatementMap &map, QTextStream &out, int level) { QString indent(' ',level); - for (PStatementList lst:map) { - for (PStatement statement:(*lst)) { - out<command).arg(int(statement->kind)) - .arg(statement->type).arg(statement->fullName) - .arg((size_t)(statement->parentScope.lock().get())) - .arg((int)statement->classScope) - .arg(statement->fileName) - .arg(statement->line) - .arg(statement->endLine) - .arg(statement->definitionFileName) - .arg(statement->definitionLine) - .arg(statement->definitionEndLine)<children.isEmpty()) - continue; - out<command<<" {"<children,out,level+1); - out<command).arg(int(statement->kind)) + .arg(statement->type).arg(statement->fullName) + .arg((size_t)(statement->parentScope.lock().get())) + .arg((int)statement->classScope) + .arg(statement->fileName) + .arg(statement->line) + .arg(statement->endLine) + .arg(statement->definitionFileName) + .arg(statement->definitionLine) + .arg(statement->definitionEndLine)<children.isEmpty()) + continue; + out<command<<" {"<children,out,level+1); + out<includePaths, std::shared_ptr projectIncludePaths) { QString result = ""; // Handle <> @@ -284,13 +285,13 @@ QString getLocalHeaderFileName(const QString &relativeTo, const QString &fileNam return ""; } -QString getSystemHeaderFileName(const QString &fileName, const QStringList &includePaths) +QString getSystemHeaderFileName(const QString &fileName, std::shared_ptr includePaths) { - if (includePaths.isEmpty()) + if (!includePaths) return ""; // Search compiler include directories - for (QString path:includePaths) { + for (QString path:*includePaths) { QDir dir(path); if (dir.exists(fileName)) return dir.absoluteFilePath(fileName); diff --git a/RedPandaIDE/parser/utils.h b/RedPandaIDE/parser/utils.h index 78214113..5f5a77bd 100644 --- a/RedPandaIDE/parser/utils.h +++ b/RedPandaIDE/parser/utils.h @@ -89,9 +89,9 @@ using PRemovedStatement = std::shared_ptr; struct Statement; using PStatement = std::shared_ptr; -using StatementList = QVector; +using StatementList = QList; using PStatementList = std::shared_ptr; -using StatementMap = QHash; +using StatementMap = QMultiHash; struct Statement { std::weak_ptr parentScope; // parent class/struct/namespace scope, don't use auto pointer to prevent circular reference QString hintText; // text to force display when using PrettyPrintStatement @@ -164,9 +164,9 @@ extern QSet STLElementMethods; void initParser(); QString getHeaderFileName(const QString& relativeTo, const QString& line, - const QStringList& includePaths, const QStringList &projectIncludePaths); + std::shared_ptr includePaths, std::shared_ptr projectIncludePaths); QString getLocalHeaderFileName(const QString& relativeTo, const QString& fileName); -QString getSystemHeaderFileName(const QString& fileName, const QStringList& includePaths); +QString getSystemHeaderFileName(const QString& fileName, std::shared_ptr includePaths); #endif // PARSER_UTILS_H