work save: CppPreprocessor clean

This commit is contained in:
Roy Qu 2022-10-22 10:44:10 +08:00
parent 921a6b41c5
commit 6ba6030af7
4 changed files with 96 additions and 86 deletions

View File

@ -55,7 +55,6 @@ CppParser::CppParser(QObject *parent) : QObject(parent),
mCppTypeKeywords = CppTypeKeywords;
mEnabled = true;
mPreprocessor = std::make_shared<CppPreprocessor>();
//mNamespaces;
//mBlockBeginSkips;
//mBlockEndSkips;
@ -84,34 +83,34 @@ void CppParser::addHardDefineByLine(const QString &line)
{
QMutexLocker locker(&mMutex);
if (line.startsWith('#')) {
mPreprocessor->addHardDefineByLine(line.mid(1).trimmed());
mPreprocessor.addHardDefineByLine(line.mid(1).trimmed());
} else {
mPreprocessor->addHardDefineByLine(line);
mPreprocessor.addHardDefineByLine(line);
}
}
void CppParser::addIncludePath(const QString &value)
{
QMutexLocker locker(&mMutex);
mPreprocessor->addIncludePath(includeTrailingPathDelimiter(value));
mPreprocessor.addIncludePath(includeTrailingPathDelimiter(value));
}
void CppParser::addProjectIncludePath(const QString &value)
{
QMutexLocker locker(&mMutex);
mPreprocessor->addProjectIncludePath(includeTrailingPathDelimiter(value));
mPreprocessor.addProjectIncludePath(includeTrailingPathDelimiter(value));
}
void CppParser::clearIncludePaths()
{
QMutexLocker locker(&mMutex);
mPreprocessor->clearIncludePaths();
mPreprocessor.clearIncludePaths();
}
void CppParser::clearProjectIncludePaths()
{
QMutexLocker locker(&mMutex);
mPreprocessor->clearProjectIncludePaths();
mPreprocessor.clearProjectIncludePaths();
}
void CppParser::clearProjectFiles()
@ -156,7 +155,7 @@ PStatement CppParser::findAndScanBlockAt(const QString &filename, int line)
if (mParsing) {
return PStatement();
}
PFileIncludes fileIncludes = mPreprocessor->includesList().value(filename);
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename);
if (!fileIncludes)
return PStatement();
@ -167,9 +166,9 @@ PStatement CppParser::findAndScanBlockAt(const QString &filename, int line)
PFileIncludes CppParser::findFileIncludes(const QString &filename, bool deleteIt)
{
QMutexLocker locker(&mMutex);
PFileIncludes fileIncludes = mPreprocessor->includesList().value(filename,PFileIncludes());
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
if (deleteIt && fileIncludes)
mPreprocessor->includesList().remove(filename);
mPreprocessor.includesList().remove(filename);
return fileIncludes;
}
QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QString &phrase, const PStatement& currentScope)
@ -201,7 +200,7 @@ QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QStri
PStatement CppParser::findFunctionAt(const QString &fileName, int line)
{
QMutexLocker locker(&mMutex);
PFileIncludes fileIncludes = mPreprocessor->includesList().value(fileName);
PFileIncludes fileIncludes = mPreprocessor.includesList().value(fileName);
if (!fileIncludes)
return PStatement();
for (PStatement& statement : fileIncludes->statements) {
@ -650,7 +649,7 @@ QStringList CppParser::getFileDirectIncludes(const QString &filename)
return QStringList();
if (filename.isEmpty())
return QStringList();
PFileIncludes fileIncludes = mPreprocessor->includesList().value(filename,PFileIncludes());
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
if (fileIncludes) {
return fileIncludes->directIncludes;
@ -668,7 +667,7 @@ QSet<QString> CppParser::getFileIncludes(const QString &filename)
if (filename.isEmpty())
return list;
list.insert(filename);
PFileIncludes fileIncludes = mPreprocessor->includesList().value(filename,PFileIncludes());
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
if (fileIncludes) {
foreach (const QString& file, fileIncludes->includeFiles.keys()) {
@ -686,13 +685,13 @@ QSet<QString> CppParser::getFileUsings(const QString &filename)
return result;
if (mParsing)
return result;
PFileIncludes fileIncludes= mPreprocessor->includesList().value(filename,PFileIncludes());
PFileIncludes fileIncludes= mPreprocessor.includesList().value(filename,PFileIncludes());
if (fileIncludes) {
foreach (const QString& usingName, fileIncludes->usings) {
result.insert(usingName);
}
foreach (const QString& subFile,fileIncludes->includeFiles.keys()){
PFileIncludes subIncludes = mPreprocessor->includesList().value(subFile,PFileIncludes());
PFileIncludes subIncludes = mPreprocessor.includesList().value(subFile,PFileIncludes());
if (subIncludes) {
foreach (const QString& usingName, subIncludes->usings) {
result.insert(usingName);
@ -710,18 +709,18 @@ QString CppParser::getHeaderFileName(const QString &relativeTo, const QString &h
QStringList includes;
QStringList projectIncludes;
bool found=false;
if (fromNext && mPreprocessor->includePaths().contains(currentDir)) {
foreach(const QString& s, mPreprocessor->includePathList()) {
if (fromNext && mPreprocessor.includePaths().contains(currentDir)) {
foreach(const QString& s, mPreprocessor.includePathList()) {
if (found) {
includes.append(s);
continue;
} else if (s == currentDir)
found = true;
}
projectIncludes = mPreprocessor->projectIncludePathList();
} else if (fromNext && mPreprocessor->projectIncludePaths().contains(currentDir)) {
includes = mPreprocessor->includePathList();
foreach(const QString& s, mPreprocessor->projectIncludePathList()) {
projectIncludes = mPreprocessor.projectIncludePathList();
} else if (fromNext && mPreprocessor.projectIncludePaths().contains(currentDir)) {
includes = mPreprocessor.includePathList();
foreach(const QString& s, mPreprocessor.projectIncludePathList()) {
if (found) {
includes.append(s);
continue;
@ -729,8 +728,8 @@ QString CppParser::getHeaderFileName(const QString &relativeTo, const QString &h
found = true;
}
} else {
includes = mPreprocessor->includePathList();
projectIncludes = mPreprocessor->projectIncludePathList();
includes = mPreprocessor.includePathList();
projectIncludes = mPreprocessor.projectIncludePathList();
}
return ::getHeaderFilename(relativeTo, headerName, includes,
projectIncludes);
@ -777,13 +776,13 @@ bool CppParser::isIncludeNextLine(const QString &line)
bool CppParser::isProjectHeaderFile(const QString &fileName)
{
QMutexLocker locker(&mMutex);
return ::isSystemHeaderFile(fileName,mPreprocessor->projectIncludePaths());
return ::isSystemHeaderFile(fileName,mPreprocessor.projectIncludePaths());
}
bool CppParser::isSystemHeaderFile(const QString &fileName)
{
QMutexLocker locker(&mMutex);
return ::isSystemHeaderFile(fileName,mPreprocessor->includePaths());
return ::isSystemHeaderFile(fileName,mPreprocessor.includePaths());
}
void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNotParsed, bool updateView)
@ -810,7 +809,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
emit onEndParsing(mFilesScannedCount,0);
});
QString fName = fileName;
if (onlyIfNotParsed && mPreprocessor->scannedFiles().contains(fName))
if (onlyIfNotParsed && mPreprocessor.scannedFiles().contains(fName))
return;
QSet<QString> files = calculateFilesToBeReparsed(fileName);
@ -831,7 +830,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
if (isHFile(file)) {
mFilesScannedCount++;
emit onProgress(file,mFilesToScanCount,mFilesScannedCount);
if (!mPreprocessor->scannedFiles().contains(file)) {
if (!mPreprocessor.scannedFiles().contains(file)) {
internalParse(file);
}
}
@ -841,7 +840,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
if (!isHFile(file)) {
mFilesScannedCount++;
emit onProgress(file,mFilesToScanCount,mFilesScannedCount);
if (!mPreprocessor->scannedFiles().contains(file)) {
if (!mPreprocessor.scannedFiles().contains(file)) {
internalParse(file);
}
}
@ -879,7 +878,7 @@ void CppParser::parseFileList(bool updateView)
if (isHFile(file)) {
mFilesScannedCount++;
emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
if (!mPreprocessor->scannedFiles().contains(file)) {
if (!mPreprocessor.scannedFiles().contains(file)) {
internalParse(file);
}
}
@ -889,7 +888,7 @@ void CppParser::parseFileList(bool updateView)
if (isCFile(file)) {
mFilesScannedCount++;
emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
if (!mPreprocessor->scannedFiles().contains(file)) {
if (!mPreprocessor.scannedFiles().contains(file)) {
internalParse(file);
}
}
@ -911,7 +910,7 @@ void CppParser::parseHardDefines()
mParsing = false;
mIsSystemHeader=oldIsSystemHeader;
});
for (const PDefine& define:mPreprocessor->hardDefines()) {
for (const PDefine& define:mPreprocessor.hardDefines()) {
addStatement(
PStatement(), // defines don't belong to any scope
"",
@ -953,7 +952,6 @@ void CppParser::resetParser()
mParsing = false;
});
emit onBusy();
mPreprocessor->clear();
mUniqId = 0;
mParseLocalHeaders = true;
@ -977,7 +975,7 @@ void CppParser::resetParser()
mNamespaces.clear(); // namespace and the statements in its scope
mInlineNamespaces.clear();
mPreprocessor = std::make_shared<CppPreprocessor>();
mPreprocessor.clear();
mTokenizer.reset();
}
@ -991,12 +989,12 @@ void CppParser::unFreeze()
QSet<QString> CppParser::scannedFiles()
{
return mPreprocessor->scannedFiles();
return mPreprocessor.scannedFiles();
}
bool CppParser::isFileParsed(const QString &filename)
{
return mPreprocessor->scannedFiles().contains(filename);
return mPreprocessor.scannedFiles().contains(filename);
}
QString CppParser::getScopePrefix(const PStatement& statement){
@ -1133,7 +1131,7 @@ void CppParser::addFileToScan(const QString& value, bool inProject)
mProjectFiles.insert(value);
// Only parse given file
if (!mPreprocessor->scannedFiles().contains(value)) {
if (!mPreprocessor.scannedFiles().contains(value)) {
mFilesToScan.insert(value);
}
@ -1212,12 +1210,12 @@ PStatement CppParser::addStatement(const PStatement& parent,
if (oldStatement && !oldStatement->hasDefinition) {
oldStatement->hasDefinition = true;
if (oldStatement->fileName!=fileName) {
PFileIncludes fileIncludes1=mPreprocessor->includesList().value(fileName);
PFileIncludes fileIncludes1=mPreprocessor.includesList().value(fileName);
if (fileIncludes1) {
fileIncludes1->statements.insert(oldStatement->fullName,
oldStatement);
fileIncludes1->dependingFiles.insert(oldStatement->fileName);
PFileIncludes fileIncludes2=mPreprocessor->includesList().value(oldStatement->fileName);
PFileIncludes fileIncludes2=mPreprocessor.includesList().value(oldStatement->fileName);
if (fileIncludes2) {
fileIncludes2->dependedFiles.insert(fileName);
}
@ -1274,7 +1272,7 @@ PStatement CppParser::addStatement(const PStatement& parent,
}
if (result->kind!= StatementKind::skBlock) {
PFileIncludes fileIncludes = mPreprocessor->includesList().value(fileName);
PFileIncludes fileIncludes = mPreprocessor.includesList().value(fileName);
if (fileIncludes) {
fileIncludes->statements.insert(result->fullName,result);
fileIncludes->declaredStatements.insert(result->fullName,result);
@ -1353,7 +1351,7 @@ void CppParser::addSoloScopeLevel(PStatement& statement, int line, bool shouldRe
mCurrentScope.append(statement);
PFileIncludes fileIncludes = mPreprocessor->includesList().value(mCurrentFile);
PFileIncludes fileIncludes = mPreprocessor.includesList().value(mCurrentFile);
if (fileIncludes) {
fileIncludes->scopes.addScope(line,statement);
@ -1377,7 +1375,7 @@ void CppParser::removeScopeLevel(int line)
if (mCurrentScope.isEmpty())
return; // TODO: should be an exception
PStatement currentScope = mCurrentScope.back();;
PFileIncludes fileIncludes = mPreprocessor->includesList().value(mCurrentFile);
PFileIncludes fileIncludes = mPreprocessor.includesList().value(mCurrentFile);
if (currentScope && (currentScope->kind == StatementKind::skBlock)) {
if (currentScope->children.isEmpty()) {
// remove no children block
@ -2592,7 +2590,7 @@ void CppParser::handlePreprocessor()
s = s.trimmed();
// Ask the preprocessor to cut parts up
QString name,args,value;
mPreprocessor->getDefineParts(s,name,args,value);
mPreprocessor.getDefineParts(s,name,args,value);
addStatement(
nullptr, // defines don't belong to any scope
@ -3074,7 +3072,7 @@ void CppParser::handleUsing()
scopeStatement->usingList.insert(fullName);
}
} else {
PFileIncludes fileInfo = mPreprocessor->includesList().value(mCurrentFile);
PFileIncludes fileInfo = mPreprocessor.includesList().value(mCurrentFile);
if (!fileInfo)
return;
if (mNamespaces.contains(usingName)) {
@ -3262,24 +3260,24 @@ void CppParser::internalParse(const QString &fileName)
// Preprocess the file...
{
auto action = finally([this]{
mPreprocessor->reset();
mPreprocessor.reset();
mTokenizer.reset();
});
// Let the preprocessor augment the include records
// mPreprocessor->setIncludesList(mIncludesList);
// mPreprocessor->setScannedFileList(mScannedFiles);
// mPreprocessor->setIncludePaths(mIncludePaths);
// mPreprocessor->setProjectIncludePaths(mProjectIncludePaths);
mPreprocessor->setScanOptions(mParseGlobalHeaders, mParseLocalHeaders);
mPreprocessor->preprocess(fileName, buffer);
// mPreprocessor.setIncludesList(mIncludesList);
// mPreprocessor.setScannedFileList(mScannedFiles);
// mPreprocessor.setIncludePaths(mIncludePaths);
// mPreprocessor.setProjectIncludePaths(mProjectIncludePaths);
mPreprocessor.setScanOptions(mParseGlobalHeaders, mParseLocalHeaders);
mPreprocessor.preprocess(fileName, buffer);
QStringList preprocessResult = mPreprocessor->result();
QStringList preprocessResult = mPreprocessor.result();
//reduce memory usage
mPreprocessor->clearResult();
mPreprocessor.clearResult();
#ifdef QT_DEBUG
// stringsToFile(mPreprocessor->result(),"r:\\preprocess.txt");
// mPreprocessor->dumpDefinesTo("r:\\defines.txt");
// mPreprocessor->dumpIncludesListTo("r:\\includes.txt");
// stringsToFile(mPreprocessor.result(),"r:\\preprocess.txt");
// mPreprocessor.dumpDefinesTo("r:\\defines.txt");
// mPreprocessor.dumpIncludesListTo("r:\\includes.txt");
#endif
// Tokenize the preprocessed buffer file
@ -3310,8 +3308,8 @@ void CppParser::internalParse(const QString &fileName)
void CppParser::inheritClassStatement(const PStatement& derived, bool isStruct,
const PStatement& base, StatementClassScope access)
{
PFileIncludes fileIncludes1=mPreprocessor->includesList().value(derived->fileName);
PFileIncludes fileIncludes2=mPreprocessor->includesList().value(base->fileName);
PFileIncludes fileIncludes1=mPreprocessor.includesList().value(derived->fileName);
PFileIncludes fileIncludes2=mPreprocessor.includesList().value(base->fileName);
if (fileIncludes1 && fileIncludes2) {
//derived class depeneds on base class
fileIncludes1->dependingFiles.insert(base->fileName);
@ -4275,7 +4273,7 @@ void CppParser::internalInvalidateFile(const QString &fileName)
}
}
// delete it from scannedfiles
mPreprocessor->scannedFiles().remove(fileName);
mPreprocessor.scannedFiles().remove(fileName);
// remove its include files list
PFileIncludes p = findFileIncludes(fileName, true);
@ -4321,7 +4319,7 @@ QSet<QString> CppParser::calculateFilesToBeReparsed(const QString &fileName)
while (!queue.isEmpty()) {
QString name = queue.dequeue();
processed.insert(name);
PFileIncludes p=mPreprocessor->includesList().value(name);
PFileIncludes p=mPreprocessor.includesList().value(name);
if (!p)
continue;
foreach (const QString& s,p->dependedFiles) {
@ -4710,12 +4708,12 @@ void CppParser::setParseGlobalHeaders(bool newParseGlobalHeaders)
const QSet<QString> &CppParser::includePaths()
{
return mPreprocessor->includePaths();
return mPreprocessor.includePaths();
}
const QSet<QString> &CppParser::projectIncludePaths()
{
return mPreprocessor->projectIncludePaths();
return mPreprocessor.projectIncludePaths();
}
bool CppParser::parseLocalHeaders() const

View File

@ -207,7 +207,7 @@ private:
bool checkForUsing();
bool checkForVar();
QString expandMacroType(const QString& name);
//{procedure ResetDefines;}
void fillListOfFunctions(const QString& fileName, int line,
const PStatement& statement,
const PStatement& scopeStatement, QStringList& list);
@ -535,7 +535,7 @@ private:
//It's used in preprocessor, so we can't use fIncludeList instead
CppTokenizer mTokenizer;
PCppPreprocessor mPreprocessor;
CppPreprocessor mPreprocessor;
QSet<QString> mProjectFiles;
QVector<int> mBlockBeginSkips; //list of for/catch block begin token index;
QVector<int> mBlockEndSkips; //list of for/catch block end token index;

View File

@ -28,22 +28,33 @@ CppPreprocessor::CppPreprocessor()
void CppPreprocessor::clear()
{
mIncludes.clear();
mDefines.clear();
mHardDefines.clear();
mProcessed.clear();
mFileDefines.clear();
mBranchResults.clear();
mResult.clear();
mCurrentIncludes.reset();
//don't use reset(), it will reset(add) defines.
clearResult();
//Result across processings.
//used by parser even preprocess finished
mIncludesList.clear();
mFileDefines.clear(); //dictionary to save defines for each headerfile;
mScannedFiles.clear();
//option data for the parser
//{ List of current project's include path }
mHardDefines.clear(); // set by "cpp -dM -E -xc NUL"
mProjectIncludePaths.clear();
//we also need include paths in order (for #include_next)
mIncludePathList.clear();
mProjectIncludePathList.clear();
//{ List of current compiler set's include path}
mIncludePaths.clear();
}
void CppPreprocessor::clearResult()
{
mFileName.clear();
{
//temporary data when preprocessing single file
mFileName="";
mBuffer.clear();
mResult.clear();
mCurrentIncludes = nullptr;
mCurrentIncludes=nullptr;
mIncludes.clear(); // stack of files we've stepped into. last one is current file, first one is source file
mBranchResults.clear();// stack of branch results (boolean). last one is current branch, first one is outermost branch
mDefines.clear(); // working set, editable
@ -150,13 +161,8 @@ PDefine CppPreprocessor::getHardDefine(const QString &name)
void CppPreprocessor::reset()
{
mResult.clear();
clearResult();
// Clear extracted data
mIncludes.clear();
mBranchResults.clear();
mCurrentIncludes.reset();
mProcessed.clear();
resetDefines(); // do not throw away hardcoded
}

View File

@ -190,22 +190,29 @@ private:
int evaluateExpression(QString line);
private:
int mIndex; // points to current file buffer. do not free
QString mFileName; // idem
QStringList mBuffer; // idem
//temporary data when preprocessing single file
int mIndex; // points to current file buffer.
QString mFileName;
QStringList mBuffer;
QStringList mResult;
PFileIncludes mCurrentIncludes;
int mPreProcIndex;
int mPreProcIndex;
QList<PParsedFile> mIncludes; // stack of files we've stepped into. last one is current file, first one is source file
QList<bool> mBranchResults;// stack of branch results (boolean). last one is current branch, first one is outermost branch
DefineMap mDefines; // working set, editable
QSet<QString> mProcessed; // dictionary to save filename already processed
//Result across processings.
//used by parser even preprocess finished
DefineMap mHardDefines; // set by "cpp -dM -E -xc NUL"
QHash<QString,PFileIncludes> mIncludesList;
QHash<QString, PDefineMap> mFileDefines; //dictionary to save defines for each headerfile;
QSet<QString> mScannedFiles;
//option data for the parser
//{ List of current project's include path }
DefineMap mHardDefines; // set by "cpp -dM -E -xc NUL"
QSet<QString> mProjectIncludePaths;
//we also need include paths in order (for #include_next)
QList<QString> mIncludePathList;
@ -215,7 +222,6 @@ private:
bool mParseSystem;
bool mParseLocal;
QSet<QString> mScannedFiles;
};
using PCppPreprocessor = std::shared_ptr<CppPreprocessor>;