- enhancement: support #include_next (and clang libc++)

This commit is contained in:
royqh1979@gmail.com 2021-10-04 21:59:48 +08:00
parent 5180387ec7
commit 77e8eda8a3
5 changed files with 83 additions and 14 deletions

View File

@ -17,6 +17,7 @@ Version 0.6.0
- implement: when startup , open file provided by command line options - implement: when startup , open file provided by command line options
- implement: open files pasted by clipboard - implement: open files pasted by clipboard
- fix: code fold parsing not correct - fix: code fold parsing not correct
- enhancement: support #include_next (and clang libc++)
Version 0.5.0 Version 0.5.0
- enhancement: support C++ using type alias; - enhancement: support C++ using type alias;

View File

@ -68,25 +68,25 @@ void CppParser::addHardDefineByLine(const QString &line)
void CppParser::addIncludePath(const QString &value) void CppParser::addIncludePath(const QString &value)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
mPreprocessor.includePaths().insert(includeTrailingPathDelimiter(value)); mPreprocessor.addIncludePath(includeTrailingPathDelimiter(value));
} }
void CppParser::addProjectIncludePath(const QString &value) void CppParser::addProjectIncludePath(const QString &value)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
mPreprocessor.projectIncludePaths().insert(includeTrailingPathDelimiter(value)); mPreprocessor.addProjectIncludePath(includeTrailingPathDelimiter(value));
} }
void CppParser::clearIncludePaths() void CppParser::clearIncludePaths()
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
mPreprocessor.includePaths().clear(); mPreprocessor.clearIncludePaths();
} }
void CppParser::clearProjectIncludePaths() void CppParser::clearProjectIncludePaths()
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
mPreprocessor.projectIncludePaths().clear(); mPreprocessor.clearProjectIncludePaths();
} }
void CppParser::clearProjectFiles() void CppParser::clearProjectFiles()
@ -819,8 +819,8 @@ void CppParser::reset()
mNamespaces.clear(); mNamespaces.clear();
mInlineNamespaces.clear(); mInlineNamespaces.clear();
mPreprocessor.projectIncludePaths().clear(); mPreprocessor.clearProjectIncludePaths();
mPreprocessor.includePaths().clear(); mPreprocessor.clearIncludePaths();
mProjectFiles.clear(); mProjectFiles.clear();
} }
} }

View File

@ -212,6 +212,30 @@ void CppPreprocessor::dumpIncludesListTo(const QString &fileName) const
} }
} }
void CppPreprocessor::addIncludePath(const QString &fileName)
{
mIncludePaths.insert(fileName);
mIncludePathList.append(fileName);
}
void CppPreprocessor::addProjectIncludePath(const QString &fileName)
{
mProjectIncludePaths.insert(fileName);
mProjectIncludeList.append(fileName);
}
void CppPreprocessor::clearIncludePaths()
{
mIncludePaths.clear();
mIncludePathList.clear();
}
void CppPreprocessor::clearProjectIncludePaths()
{
mProjectIncludePaths.clear();
mProjectIncludeList.clear();
}
QString CppPreprocessor::getNextPreprocessor() QString CppPreprocessor::getNextPreprocessor()
{ {
skipToPreprocessor(); // skip until # at start of line skipToPreprocessor(); // skip until # at start of line
@ -323,15 +347,42 @@ void CppPreprocessor::handleDefine(const QString &line)
} }
} }
void CppPreprocessor::handleInclude(const QString &line) void CppPreprocessor::handleInclude(const QString &line, bool fromNext)
{ {
if (!getCurrentBranch()) // we're skipping due to a branch failure if (!getCurrentBranch()) // we're skipping due to a branch failure
return; return;
PParsedFile file = mIncludes.back(); PParsedFile file = mIncludes.back();
QString fileName;
// Get full header file name // Get full header file name
QString fileName = getHeaderFilename(file->fileName, line,mIncludePaths, QString currentDir = includeTrailingPathDelimiter(extractFileDir(file->fileName));
mProjectIncludePaths); QSet<QString> includes;
QSet<QString> projectIncludes;
if (fromNext && mIncludePaths.contains(currentDir)) {
bool found = false;
foreach(const QString& s, mIncludePathList) {
if (found)
includes.insert(s);
if (s == currentDir)
found = true;
}
} else
includes = mIncludePaths;
if (fromNext && mProjectIncludePaths.contains(currentDir)) {
bool found = false;
foreach(const QString& s, mProjectIncludeList) {
if (found)
projectIncludes.insert(s);
if (s == currentDir)
found = true;
}
} else
projectIncludes = mProjectIncludePaths;
fileName = getHeaderFilename(
file->fileName,
line,
includes,
projectIncludes);
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
@ -354,6 +405,8 @@ void CppPreprocessor::handlePreprocessor(const QString &value)
handleBranch(value); handleBranch(value);
else if (value.startsWith("include")) else if (value.startsWith("include"))
handleInclude(value); handleInclude(value);
else if (value.startsWith("include_next"))
handleInclude(value,true);
} }
void CppPreprocessor::handleUndefine(const QString &line) void CppPreprocessor::handleUndefine(const QString &line)
@ -1662,12 +1715,12 @@ const DefineMap &CppPreprocessor::hardDefines() const
return mHardDefines; return mHardDefines;
} }
QSet<QString> &CppPreprocessor::projectIncludePaths() const QSet<QString> &CppPreprocessor::projectIncludePaths()
{ {
return mProjectIncludePaths; return mProjectIncludePaths;
} }
QSet<QString> &CppPreprocessor::includePaths() const QSet<QString> &CppPreprocessor::includePaths()
{ {
return mIncludePaths; return mIncludePaths;
} }

View File

@ -60,15 +60,19 @@ public:
void dumpDefinesTo(const QString& fileName) const; void dumpDefinesTo(const QString& fileName) const;
void dumpIncludesListTo(const QString& fileName) const; void dumpIncludesListTo(const QString& fileName) const;
void addIncludePath(const QString& fileName);
void addProjectIncludePath(const QString& fileName);
void clearIncludePaths();
void clearProjectIncludePaths();
QStringList result() const; QStringList result() const;
QHash<QString, PFileIncludes> &includesList(); QHash<QString, PFileIncludes> &includesList();
QSet<QString> &scannedFiles(); QSet<QString> &scannedFiles();
QSet<QString> &includePaths(); const QSet<QString> &includePaths();
QSet<QString> &projectIncludePaths(); const QSet<QString> &projectIncludePaths();
const DefineMap &hardDefines() const; const DefineMap &hardDefines() const;
@ -82,7 +86,7 @@ private:
void simplify(QString& output); void simplify(QString& output);
void handleBranch(const QString& line); void handleBranch(const QString& line);
void handleDefine(const QString& line); void handleDefine(const QString& line);
void handleInclude(const QString& line); void handleInclude(const QString& line, bool fromNext=false);
void handlePreprocessor(const QString& value); void handlePreprocessor(const QString& value);
void handleUndefine(const QString& line); void handleUndefine(const QString& line);
QString expandMacros(const QString& line, int depth); QString expandMacros(const QString& line, int depth);
@ -183,6 +187,9 @@ private:
QSet<QString> mIncludePaths; QSet<QString> mIncludePaths;
//{ List of current project's include path } //{ List of current project's include path }
QSet<QString> mProjectIncludePaths; QSet<QString> mProjectIncludePaths;
//we also need include paths in order (for #include_next)
QList<QString> mIncludePathList;
QList<QString> mProjectIncludeList;
bool mParseSystem; bool mParseSystem;
bool mParseLocal; bool mParseLocal;

View File

@ -70,6 +70,10 @@ void FunctionTooltipWidget::setParamPos(int newParamPos)
void FunctionTooltipWidget::nextTip() void FunctionTooltipWidget::nextTip()
{ {
if (mInfoIndex>=mInfos.length()-1) {
hide();
return;
}
if (mInfos.length()>0) if (mInfos.length()>0)
mInfoIndex = std::min(mInfoIndex+1,mInfos.length()-1); mInfoIndex = std::min(mInfoIndex+1,mInfos.length()-1);
updateTip(); updateTip();
@ -77,6 +81,10 @@ void FunctionTooltipWidget::nextTip()
void FunctionTooltipWidget::previousTip() void FunctionTooltipWidget::previousTip()
{ {
if (mInfoIndex==0) {
hide();
return ;
}
if (mInfos.length()>0) if (mInfos.length()>0)
mInfoIndex = std::max(mInfoIndex-1,0); mInfoIndex = std::max(mInfoIndex-1,0);
updateTip(); updateTip();