From 1372ac774fb89e8a511d75eaab15f246a8ca7751 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Mon, 1 Apr 2024 10:59:01 +0800 Subject: [PATCH] - enhancement: Support "extern template" in parser. --- NEWS.md | 1 + RedPandaIDE/parser/cppparser.cpp | 46 +++++++++++++++++++++++------- RedPandaIDE/parser/cppparser.h | 1 + RedPandaIDE/parser/parserutils.cpp | 2 +- RedPandaIDE/parser/parserutils.h | 1 + 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index c73ac568..c4b5f250 100644 --- a/NEWS.md +++ b/NEWS.md @@ -111,6 +111,7 @@ Red Panda C++ Version 2.27 - enhancement: Make colors in code suggestion popup consistent with the editor. - enhancement: Make colors in header suggestion popup consistent with the editor. - fix: C++ source after ';' are treated as comments in cpu info window. + - enhancement: Support "extern template" in code parser. Red Panda C++ Version 2.26 - enhancement: Code suggestion for embedded std::vectors. diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index ffa58409..08bd4442 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -636,6 +636,23 @@ PStatement CppParser::doFindAliasedStatement(const PStatement &statement) const return doFindAliasedStatement(statement,foundSet); } +PStatement CppParser::doFindNoTemplateSpecializationClass(const PStatement &statement) const +{ + Q_ASSERT(statement!=nullptr); + Q_ASSERT(statement->kind == StatementKind::skClass); + if (statement->templateSpecializationParams.isEmpty()) + return statement; + PStatement parent = statement->parentScope.lock(); + const StatementMap & statementMap = mStatementList.childrenStatements(parent); + QList list = statementMap.values(statement->command); + foreach(const PStatement &child, list) { + if (child->kind == StatementKind::skClass + && child->templateSpecializationParams.isEmpty()) + return child; + } + return statement; +} + PStatement CppParser::doFindAliasedStatement(const PStatement &statement, QSet foundSet) const { if (!statement) @@ -2040,6 +2057,7 @@ bool CppParser::checkForKeyword(KeywordType& keywordType) case KeywordType::Operator: case KeywordType::Requires: case KeywordType::Concept: + case KeywordType::Extern: return false; default: return true; @@ -3548,11 +3566,21 @@ bool CppParser::handleStatement(int maxIndex) } else if (keywordType == KeywordType::Inline) { mIndex++; }else { + if (keywordType == KeywordType::Extern) { + if (mIndex+1text=="template") { + //extern template, skit it + mIndex+=2; + goto _exit; + } + } + keywordType = KeywordType::None; + } // it should be method/constructor/var checkAndHandleMethodOrVar(keywordType, maxIndex); } //Q_ASSERT(mIndex<999999); - +_exit: return mIndex < maxIndex; } @@ -5256,18 +5284,14 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName, case StatementKind::skNamespaceAlias: result = doFindAliasedNamespace(statement); break; - // case StatementKind::skAlias: { - // statement = - // if (statement) - // result = doCreateEvalType(fileName,statement); - // } - // break; case StatementKind::skVariable: case StatementKind::skParameter: result = doCreateEvalVariable(fileName,statement, previousResult?previousResult->templateParams:"",scope); break; - case StatementKind::skEnumType: case StatementKind::skClass: + statement = doFindNoTemplateSpecializationClass(statement); + [[fallthrough]]; + case StatementKind::skEnumType: case StatementKind::skEnumClassType: case StatementKind::skTypedef: result = doCreateEvalType(fileName,statement); @@ -5542,7 +5566,7 @@ PEvalStatement CppParser::doCreateEvalType(const QString& fileName,const PStatem int pointerLevel=0; QString templateParams; PStatement tempStatement; - PStatement effetiveTypeStatement = doParseEvalTypeInfo( + PStatement effectiveTypeStatement = doParseEvalTypeInfo( fileName, typeStatement->parentScope.lock(), typeStatement->type + typeStatement->args, @@ -5550,12 +5574,14 @@ PEvalStatement CppParser::doCreateEvalType(const QString& fileName,const PStatem tempStatement, pointerLevel, templateParams); + if (effectiveTypeStatement && effectiveTypeStatement->kind == StatementKind::skClass) + effectiveTypeStatement = doFindNoTemplateSpecializationClass(effectiveTypeStatement); return std::make_shared( baseType, EvalStatementKind::Type, PStatement(), typeStatement, - effetiveTypeStatement, + effectiveTypeStatement, pointerLevel, templateParams ); diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index 4889d9c4..498e9068 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -262,6 +262,7 @@ private: int line) const; PStatement doFindAliasedStatement(const PStatement& statement, QSet foundSet) const; PStatement doFindAliasedStatement(const PStatement& statement) const; + PStatement doFindNoTemplateSpecializationClass(const PStatement& statement) const; QList doListTypeStatements(const QString& fileName,int line) const; diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index 31122f93..9add7799 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -218,7 +218,7 @@ void initParser() // it's part of type info CppKeywords.insert("const",KeywordType::None); - CppKeywords.insert("extern",KeywordType::None); + CppKeywords.insert("extern",KeywordType::Extern); CppKeywords.insert("operator",KeywordType::Operator); diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index 0b94b35d..c293fcd8 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -84,6 +84,7 @@ enum class KeywordType { Concept, //concept Requires, //requires None, // It's a keyword but don't process here + Extern, NotKeyword };