diff --git a/externals/simplecpp/simplecpp.cpp b/externals/simplecpp/simplecpp.cpp index 9f7de67dae2..d1c930222e6 100644 --- a/externals/simplecpp/simplecpp.cpp +++ b/externals/simplecpp/simplecpp.cpp @@ -3072,6 +3072,9 @@ std::pair simplecpp::FileDataCache::tryload(FileDat mIdMap.emplace(fileId, data); mData.emplace_back(data); + if (mCallback) + mCallback(*data); + return {data, true}; } diff --git a/externals/simplecpp/simplecpp.h b/externals/simplecpp/simplecpp.h index da859cbab41..d6f48634ebc 100644 --- a/externals/simplecpp/simplecpp.h +++ b/externals/simplecpp/simplecpp.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -465,6 +466,12 @@ namespace simplecpp { return mData.cend(); } + using callback_type = std::function; + + void set_callback(callback_type cb) { + mCallback = cb; + } + private: struct FileID { #ifdef _WIN32 @@ -511,6 +518,7 @@ namespace simplecpp { container_type mData; name_map_type mNameMap; id_map_type mIdMap; + callback_type mCallback; }; SIMPLECPP_LIB long long characterLiteralToLL(const std::string& str); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 2048d6f8098..acd8a6e3271 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -99,9 +99,9 @@ class CppCheck::CppCheckLogger : public ErrorLogger closePlist(); } - void setRemarkComments(std::vector remarkComments) + std::vector& remarkComments() { - mRemarkComments = std::move(remarkComments); + return mRemarkComments; } void setLocationMacros(const Token* startTok, const std::vector& files) @@ -123,17 +123,25 @@ class CppCheck::CppCheckLogger : public ErrorLogger mErrorList.clear(); } - void openPlist(const std::string& filename, const std::vector& files) + void openPlist(const std::string& filename) { mPlistFile.open(filename); - mPlistFile << ErrorLogger::plistHeader(version(), files); + mPlistFile << ErrorLogger::plistHeader(version()); + } + + void setPlistFilenames(std::vector files) + { + if (mPlistFile.is_open()) { + mPlistFilenames = std::move(files); + } } void closePlist() { if (mPlistFile.is_open()) { - mPlistFile << ErrorLogger::plistFooter(); + mPlistFile << ErrorLogger::plistFooter(mPlistFilenames); mPlistFile.close(); + mPlistFilenames.clear(); } } @@ -276,6 +284,7 @@ class CppCheck::CppCheckLogger : public ErrorLogger std::map> mLocationMacros; // What macros are used on a location? std::ofstream mPlistFile; + std::vector mPlistFilenames; unsigned int mExitCode{}; @@ -986,9 +995,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str Preprocessor preprocessor(mSettings, mErrorLogger, file.lang()); - if (!preprocessor.loadFiles(tokens1, files)) - return mLogger->exitcode(); - if (!mSettings.plistOutput.empty()) { std::string filename2; if (file.spath().find('/') != std::string::npos) @@ -997,23 +1003,18 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str filename2 = file.spath(); const std::size_t fileNameHash = std::hash {}(file.spath()); filename2 = mSettings.plistOutput + filename2.substr(0, filename2.find('.')) + "_" + std::to_string(fileNameHash) + ".plist"; - mLogger->openPlist(filename2, files); + mLogger->openPlist(filename2); } - std::string dumpProlog; + std::string dumpFooter; if (mSettings.dump || !mSettings.addons.empty()) { - dumpProlog += getDumpFileContentsRawTokens(files, tokens1); + dumpFooter += getDumpFileContentsRawTokensFooter(tokens1); } // Parse comments and then remove them - mLogger->setRemarkComments(preprocessor.getRemarkComments(tokens1)); + preprocessor.addRemarkComments(tokens1, mLogger->remarkComments()); preprocessor.inlineSuppressions(tokens1, mSuppressions.nomsg); - if (mSettings.dump || !mSettings.addons.empty()) { - std::ostringstream oss; - mSuppressions.nomsg.dump(oss); - dumpProlog += oss.str(); - } - preprocessor.removeComments(tokens1); + Preprocessor::removeComments(tokens1); if (!mSettings.buildDir.empty()) { analyzerInformation.reset(new AnalyzerInformation); @@ -1035,19 +1036,39 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str } // Get directives - std::list directives = preprocessor.createDirectives(tokens1); - preprocessor.simplifyPragmaAsm(tokens1); + std::list directives; + Preprocessor::createDirectives(tokens1, directives); + Preprocessor::simplifyPragmaAsm(tokens1); + + // This needs to be a linked list to allow new configurations to be discovered + // and added while iterating and checking existing configurations + std::list configurations; + std::set configDefines = { "__cplusplus" }; + + preprocessor.setLoadCallback([&](simplecpp::FileData& data) { + // Do preprocessing on included file + preprocessor.addRemarkComments(data.tokens, mLogger->remarkComments()); + preprocessor.inlineSuppressions(data.tokens, mSuppressions.nomsg); + Preprocessor::removeComments(data.tokens); + Preprocessor::createDirectives(data.tokens, directives); + Preprocessor::simplifyPragmaAsm(data.tokens); + // Discover new configurations from included file + if ((mSettings.checkAllConfigurations && mSettings.userDefines.empty()) || mSettings.force) + preprocessor.getConfigs(data.filename, data.tokens, configDefines, configurations); + }); Preprocessor::setPlatformInfo(tokens1, mSettings); // Get configurations.. - std::set configurations; if ((mSettings.checkAllConfigurations && mSettings.userDefines.empty()) || mSettings.force) { Timer::run("Preprocessor::getConfigs", mSettings.showtime, &s_timerResults, [&]() { - configurations = preprocessor.getConfigs(tokens1); + configurations = { "" }; + preprocessor.getConfigs(file.spath(), tokens1, configDefines, configurations); + preprocessor.loadFiles(tokens1, files); + configurations.sort(); }); } else { - configurations.insert(mSettings.userDefines); + configurations = { mSettings.userDefines }; } if (mSettings.checkConfiguration) { @@ -1089,7 +1110,6 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str createDumpFile(mSettings, file, fileIndex, fdump, dumpFile); if (fdump.is_open()) { fdump << getLibraryDumpData(); - fdump << dumpProlog; if (!mSettings.dump) filesDeleter.addFile(dumpFile); } @@ -1272,12 +1292,20 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str } // TODO: will not be closed if we encountered an exception - // dumped all configs, close root element now if (fdump.is_open()) { + // dump all filenames, raw tokens, suppressions + std::string dumpHeader = getDumpFileContentsRawTokensHeader(files); + fdump << getDumpFileContentsRawTokens(dumpHeader, dumpFooter); + mSuppressions.nomsg.dump(fdump); + // dumped all configs, close root element now fdump << "" << std::endl; fdump.close(); } + if (!mSettings.plistOutput.empty()) { + mLogger->setPlistFilenames(std::move(files)); + } + executeAddons(dumpFile, file); } catch (const TerminateException &) { // Analysis is terminated @@ -1949,9 +1977,26 @@ bool CppCheck::isPremiumCodingStandardId(const std::string& id) const { return false; } -std::string CppCheck::getDumpFileContentsRawTokens(const std::vector& files, const simplecpp::TokenList& tokens1) const { +std::string CppCheck::getDumpFileContentsRawTokens(const std::vector& files, const simplecpp::TokenList& tokens1) const +{ + std::string header = getDumpFileContentsRawTokensHeader(files); + std::string footer = getDumpFileContentsRawTokensFooter(tokens1); + return getDumpFileContentsRawTokens(header, footer); +} + +std::string CppCheck::getDumpFileContentsRawTokens(const std::string& header, const std::string& footer) +{ std::string dumpProlog; dumpProlog += " \n"; + dumpProlog += header; + dumpProlog += footer; + dumpProlog += " \n"; + return dumpProlog; +} + +std::string CppCheck::getDumpFileContentsRawTokensHeader(const std::vector& files) const +{ + std::string dumpProlog; for (unsigned int i = 0; i < files.size(); ++i) { dumpProlog += " \n"; } - for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) { + return dumpProlog; +} + +std::string CppCheck::getDumpFileContentsRawTokensFooter(const simplecpp::TokenList& tokens1) +{ + std::string dumpProlog; + for (const simplecpp::Token* tok = tokens1.cfront(); tok; tok = tok->next) { dumpProlog += " location.line); dumpProlog += "\" "; - dumpProlog +="column=\""; + dumpProlog += "column=\""; dumpProlog += std::to_string(tok->location.col); dumpProlog += "\" "; @@ -1980,6 +2031,5 @@ std::string CppCheck::getDumpFileContentsRawTokens(const std::vector contents, this is only public for testing purposes */ std::string getDumpFileContentsRawTokens(const std::vector& files, const simplecpp::TokenList& tokens1) const; + static std::string getDumpFileContentsRawTokens(const std::string& header, const std::string& footer); + std::string getDumpFileContentsRawTokensHeader(const std::vector& files) const; + static std::string getDumpFileContentsRawTokensFooter(const simplecpp::TokenList& tokens1); std::string getLibraryDumpData() const; diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 78e9eaecd69..8c4a6f69dda 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -200,25 +200,25 @@ DynamicLibrary Unicode false - v142 + v143 DynamicLibrary Unicode false - v142 + v143 DynamicLibrary Unicode false - v142 + v143 DynamicLibrary Unicode false - v142 + v143 diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 47157f7a504..6992f514add 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -818,7 +818,7 @@ std::string ErrorLogger::toxml(const std::string &str) return xml; } -std::string ErrorLogger::plistHeader(const std::string &version, const std::vector &files) +std::string ErrorLogger::plistHeader(const std::string &version) { std::ostringstream ostr; ostr << "\r\n" @@ -826,12 +826,7 @@ std::string ErrorLogger::plistHeader(const std::string &version, const std::vect << "\r\n" << "\r\n" << " clang_version\r\n" - << "cppcheck version " << version << "\r\n" - << " files\r\n" - << " \r\n"; - for (const std::string & file : files) - ostr << " " << ErrorLogger::toxml(file) << "\r\n"; - ostr << " \r\n" + << " cppcheck version " << version << "\r\n" << " diagnostics\r\n" << " \r\n"; return ostr.str(); diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 5101f765fad..da02b096e4b 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -268,12 +269,19 @@ class CPPCHECKLIB ErrorLogger { */ static std::string toxml(const std::string &str); - static std::string plistHeader(const std::string &version, const std::vector &files); + static std::string plistHeader(const std::string &version); static std::string plistData(const ErrorMessage &msg); - static const char *plistFooter() { - return " \r\n" - "\r\n" - ""; + static std::string plistFooter(const std::vector& files) { + std::ostringstream ostr; + ostr << " \r\n" + << " files\r\n" + << " \r\n"; + for (const std::string& file : files) + ostr << " " << ErrorLogger::toxml(file) << "\r\n"; + ostr << " \r\n" + << "\r\n" + << ""; + return ostr.str(); } static bool isCriticalErrorId(const std::string& id) { diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index a701d29a962..1a3d08904dd 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -307,14 +307,12 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens, Suppre return; std::list err; ::addInlineSuppressions(tokens, mSettings, suppressions, err); - for (const auto &filedata : mFileCache) { - ::addInlineSuppressions(filedata->tokens, mSettings, suppressions, err); - } for (const BadInlineSuppression &bad : err) { error(bad.file, bad.line, bad.errmsg); } } +// cppcheck-suppress unusedFunction - only used in tests std::vector Preprocessor::getRemarkComments(const simplecpp::TokenList &tokens) const { std::vector ret; @@ -325,43 +323,28 @@ std::vector Preprocessor::getRemarkComments(const simplecpp::Toke return ret; } -std::list Preprocessor::createDirectives(const simplecpp::TokenList &tokens) const +void Preprocessor::createDirectives(const simplecpp::TokenList &tokens, std::list& directives) { - // directive list.. - std::list directives; - - std::vector list; - list.reserve(1U + mFileCache.size()); - list.push_back(&tokens); - std::transform(mFileCache.cbegin(), mFileCache.cend(), std::back_inserter(list), - [](const std::unique_ptr &filedata) { - return &filedata->tokens; - }); - - for (const simplecpp::TokenList *tokenList : list) { - for (const simplecpp::Token *tok = tokenList->cfront(); tok; tok = tok->next) { - if ((tok->op != '#') || (tok->previous && tok->previous->location.line == tok->location.line)) - continue; - if (tok->next && tok->next->str() == "endfile") + for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) { + if ((tok->op != '#') || (tok->previous && tok->previous->location.line == tok->location.line)) + continue; + if (tok->next && tok->next->str() == "endfile") + continue; + Directive directive(tok->location, ""); + for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) { + if (tok2->comment) continue; - Directive directive(tok->location, ""); - for (const simplecpp::Token *tok2 = tok; tok2 && tok2->location.line == directive.linenr; tok2 = tok2->next) { - if (tok2->comment) - continue; - if (!directive.str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str().size())) - directive.str += ' '; - if (directive.str == "#" && tok2->str() == "file") - directive.str += "include"; - else - directive.str += tok2->str(); - - directive.strTokens.emplace_back(*tok2); - } - directives.push_back(std::move(directive)); + if (!directive.str.empty() && (tok2->location.col > tok2->previous->location.col + tok2->previous->str().size())) + directive.str += ' '; + if (directive.str == "#" && tok2->str() == "file") + directive.str += "include"; + else + directive.str += tok2->str(); + + directive.strTokens.emplace_back(*tok2); } + directives.push_back(std::move(directive)); } - - return directives; } static std::string readcondition(const simplecpp::Token *iftok, const std::set &defined, const std::set &undefined) @@ -513,7 +496,13 @@ static const simplecpp::Token *gotoEndIf(const simplecpp::Token *cmdtok) return nullptr; } -static void getConfigs(const simplecpp::TokenList &tokens, std::set &defined, const std::string &userDefines, const std::set &undefined, std::set &ret) +static void insertUniqueCfg(std::list& configs, std::string&& cfg) +{ + if (std::find(configs.begin(), configs.end(), cfg) == configs.end()) + configs.push_back(std::move(cfg)); +} + +static void getConfigs(const simplecpp::TokenList &tokens, std::set &defined, const std::string &userDefines, const std::set &undefined, std::list &ret) { std::vector configs_if; std::vector configs_ifndef; @@ -574,7 +563,7 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set configs_if.push_back((cmdtok->str() == "ifndef") ? std::string() : config); configs_ifndef.push_back((cmdtok->str() == "ifndef") ? std::move(config) : std::string()); - ret.insert(cfg(configs_if,userDefines)); + insertUniqueCfg(ret, cfg(configs_if,userDefines)); } else if (cmdtok->str() == "elif" || cmdtok->str() == "else") { if (getConfigsElseIsFalse(configs_if,userDefines)) { tok = gotoEndIf(tok); @@ -603,10 +592,10 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set if (isUndefined(config,undefined)) config.clear(); configs_if.push_back(std::move(config)); - ret.insert(cfg(configs_if, userDefines)); + insertUniqueCfg(ret, cfg(configs_if, userDefines)); } else if (!configs_ifndef.empty()) { configs_if.push_back(configs_ifndef.back()); - ret.insert(cfg(configs_if, userDefines)); + insertUniqueCfg(ret, cfg(configs_if, userDefines)); } } else if (cmdtok->str() == "endif" && !sameline(tok, cmdtok->next)) { if (!configs_if.empty()) @@ -616,19 +605,19 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set } else if (cmdtok->str() == "error") { if (!configs_ifndef.empty() && !configs_ifndef.back().empty()) { if (configs_ifndef.size() == 1U) - ret.erase(emptyString); + ret.remove(emptyString); std::vector configs(configs_if); configs.push_back(configs_ifndef.back()); - ret.erase(cfg(configs, userDefines)); - std::set temp; + ret.remove(cfg(configs, userDefines)); + std::list temp; temp.swap(ret); - for (const std::string &c: temp) { + for (std::string &c: temp) { if (c.find(configs_ifndef.back()) != std::string::npos) - ret.insert(c); + insertUniqueCfg(ret, std::move(c)); else if (c.empty()) - ret.insert(""); + insertUniqueCfg(ret, ""); else - ret.insert(c + ";" + configs_ifndef.back()); + insertUniqueCfg(ret, c + ";" + configs_ifndef.back()); } if (!elseError.empty()) elseError += ';'; @@ -638,10 +627,10 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set const std::string &last = configs_if.back(); if (last.size() > 2U && last.compare(last.size()-2U,2,"=0") == 0) { std::vector configs(configs_if); - ret.erase(cfg(configs, userDefines)); + ret.remove(cfg(configs, userDefines)); configs[configs.size() - 1U] = last.substr(0,last.size()-2U); if (configs.size() == 1U) - ret.erase(""); + ret.remove(""); if (!elseError.empty()) elseError += ';'; elseError += cfg(configs, userDefines); @@ -652,26 +641,17 @@ static void getConfigs(const simplecpp::TokenList &tokens, std::set } } if (!elseError.empty()) - ret.insert(std::move(elseError)); + insertUniqueCfg(ret, std::move(elseError)); } -std::set Preprocessor::getConfigs(const simplecpp::TokenList &tokens) const +void Preprocessor::getConfigs(const std::string& filename, const simplecpp::TokenList &tokens, std::set& defined, std::list& configs) const { - std::set ret = { "" }; if (!tokens.cfront()) - return ret; - - std::set defined = { "__cplusplus" }; - - ::getConfigs(tokens, defined, mSettings.userDefines, mSettings.userUndefs, ret); - - for (const auto &filedata : mFileCache) { - if (!mSettings.configurationExcluded(filedata->filename)) - ::getConfigs(filedata->tokens, defined, mSettings.userDefines, mSettings.userUndefs, ret); - } + return; - return ret; + if (!mSettings.configurationExcluded(filename)) + ::getConfigs(tokens, defined, mSettings.userDefines, mSettings.userUndefs, configs); } static void splitcfg(const std::string &cfg, std::list &defines, const std::string &defaultValue) @@ -779,17 +759,14 @@ bool Preprocessor::loadFiles(const simplecpp::TokenList &rawtokens, std::vector< const simplecpp::DUI dui = createDUI(mSettings, "", mLang); simplecpp::OutputList outputList; - mFileCache = simplecpp::load(rawtokens, files, dui, &outputList); + mFileCache = simplecpp::load(rawtokens, files, dui, &outputList, std::move(mFileCache)); handleErrors(outputList, false); return !hasErrors(outputList); } -void Preprocessor::removeComments(simplecpp::TokenList &tokens) const +void Preprocessor::removeComments(simplecpp::TokenList &tokens) { tokens.removeComments(); - for (const auto &filedata : mFileCache) { - filedata->tokens.removeComments(); - } } void Preprocessor::setPlatformInfo(simplecpp::TokenList &tokens, const Settings& settings) @@ -993,15 +970,7 @@ std::size_t Preprocessor::calculateHash(const simplecpp::TokenList &tokens1, con return (std::hash{})(hashData); } -void Preprocessor::simplifyPragmaAsm(simplecpp::TokenList &tokenList) const -{ - Preprocessor::simplifyPragmaAsmPrivate(tokenList); - for (const auto &filedata : mFileCache) { - Preprocessor::simplifyPragmaAsmPrivate(filedata->tokens); - } -} - -void Preprocessor::simplifyPragmaAsmPrivate(simplecpp::TokenList &tokenList) +void Preprocessor::simplifyPragmaAsm(simplecpp::TokenList &tokenList) { // assembler code.. for (simplecpp::Token *tok = tokenList.front(); tok; tok = tok->next) { diff --git a/lib/preprocessor.h b/lib/preprocessor.h index ddb43266454..7d015a3b347 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -113,15 +113,16 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { void inlineSuppressions(const simplecpp::TokenList &tokens, SuppressionList &suppressions); - std::list createDirectives(const simplecpp::TokenList &tokens) const; + static void createDirectives(const simplecpp::TokenList &tokens, std::list& directives); - std::set getConfigs(const simplecpp::TokenList &tokens) const; + void getConfigs(const std::string& filename, const simplecpp::TokenList& tokens, std::set& defined, std::list& configs) const; std::vector getRemarkComments(const simplecpp::TokenList &tokens) const; + void addRemarkComments(const simplecpp::TokenList& tokens, std::vector& remarkComments) const; - bool loadFiles(const simplecpp::TokenList &rawtokens, std::vector &files); + bool loadFiles(const simplecpp::TokenList& rawtokens, std::vector& files); - void removeComments(simplecpp::TokenList &tokens) const; + static void removeComments(simplecpp::TokenList &tokens); static void setPlatformInfo(simplecpp::TokenList &tokens, const Settings& settings); @@ -138,7 +139,7 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { */ std::size_t calculateHash(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const; - void simplifyPragmaAsm(simplecpp::TokenList &tokenList) const; + static void simplifyPragmaAsm(simplecpp::TokenList &tokenList); static void getErrorMessages(ErrorLogger &errorLogger, const Settings &settings); @@ -149,13 +150,15 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { static bool hasErrors(const simplecpp::Output &output); + void setLoadCallback(simplecpp::FileDataCache::callback_type cb) { + mFileCache.set_callback(std::move(cb)); + } + private: void handleErrors(const simplecpp::OutputList &outputList, bool throwError); void reportOutput(const simplecpp::OutputList &outputList, bool showerror); - static void simplifyPragmaAsmPrivate(simplecpp::TokenList &tokenList); - /** * Include file types. */ @@ -169,8 +172,6 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { static bool hasErrors(const simplecpp::OutputList &outputList); - void addRemarkComments(const simplecpp::TokenList &tokens, std::vector &remarkComments) const; - const Settings& mSettings; ErrorLogger &mErrorLogger; diff --git a/test/helpers.cpp b/test/helpers.cpp index 3530854f5b5..f011cdcf335 100644 --- a/test/helpers.cpp +++ b/test/helpers.cpp @@ -121,7 +121,8 @@ void SimpleTokenizer2::preprocess(const char* code, std::size_t size, std::vecto // Tokenizer.. tokenizer.list.createTokens(std::move(tokens2)); - std::list directives = preprocessor.createDirectives(tokens1); + std::list directives; + Preprocessor::createDirectives(tokens1, directives); tokenizer.setDirectives(std::move(directives)); } diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 0582b8ef70e..00dd8be473b 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -93,7 +93,7 @@ class TestPreprocessor : public TestFixture { static std::string getcodeforcfg(const Settings& settings, ErrorLogger& errorlogger, const char* code, std::size_t size, const std::string &cfg, const std::string &filename, SuppressionList *inlineSuppression = nullptr) { - std::map cfgcode = getcode(settings, errorlogger, code, size, std::set{cfg}, filename, inlineSuppression); + std::map cfgcode = getcode(settings, errorlogger, code, size, std::list{cfg}, filename, inlineSuppression); const auto it = cfgcode.find(cfg); if (it == cfgcode.end()) return ""; @@ -112,7 +112,7 @@ class TestPreprocessor : public TestFixture { return getcode(settings, errorlogger, code, size-1, {}, filename, nullptr); } - static std::map getcode(const Settings& settings, ErrorLogger& errorlogger, const char* code, std::size_t size, std::set cfgs, const std::string &filename, SuppressionList *inlineSuppression) + static std::map getcode(const Settings& settings, ErrorLogger& errorlogger, const char* code, std::size_t size, std::list cfgs, const std::string &filename, SuppressionList *inlineSuppression) { simplecpp::OutputList outputList; std::vector files; @@ -122,8 +122,8 @@ class TestPreprocessor : public TestFixture { Preprocessor preprocessor(settings, errorlogger, Path::identify(tokens.getFiles()[0], false)); if (inlineSuppression) preprocessor.inlineSuppressions(tokens, *inlineSuppression); - preprocessor.removeComments(tokens); - preprocessor.simplifyPragmaAsm(tokens); + Preprocessor::removeComments(tokens); + Preprocessor::simplifyPragmaAsm(tokens); preprocessor.reportOutput(outputList, true); @@ -131,8 +131,11 @@ class TestPreprocessor : public TestFixture { return {}; std::map cfgcode; - if (cfgs.empty()) - cfgs = preprocessor.getConfigs(tokens); + if (cfgs.empty()) { + cfgs.emplace_back(""); + std::set configDefines = { "__cplusplus" }; + preprocessor.getConfigs(filename, tokens, configDefines, cfgs); + } for (const std::string & config : cfgs) { try { const bool writeLocations = (strstr(code, "#file") != nullptr) || (strstr(code, "#include") != nullptr); @@ -366,9 +369,14 @@ class TestPreprocessor : public TestFixture { std::vector files; // TODO: this adds an empty filename simplecpp::TokenList tokens(code,files); - tokens.removeComments(); + Preprocessor::removeComments(tokens); Preprocessor preprocessor(settings, *this, Standards::Language::C); // TODO: do we need to consider #file? - const std::set configs = preprocessor.getConfigs(tokens); + std::list configs = { "" }; + { + std::set configDefines = { "__cplusplus" }; + preprocessor.getConfigs("", tokens, configDefines, configs); + } + configs.sort(); std::string ret; for (const std::string & config : configs) ret += config + '\n'; @@ -380,7 +388,7 @@ class TestPreprocessor : public TestFixture { std::vector files; // TODO: this adds an empty filename simplecpp::TokenList tokens(code,files); - tokens.removeComments(); + Preprocessor::removeComments(tokens); Preprocessor preprocessor(settingsDefault, *this, Standards::Language::C); // TODO: do we need to consider #file? return preprocessor.calculateHash(tokens, ""); } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b872a152fa0..8d386191ef5 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -581,8 +581,8 @@ class TestTokenizer : public TestFixture { simplecpp::OutputList outputList; std::vector files; const simplecpp::TokenList tokens1(code, files, filename, &outputList); - Preprocessor preprocessor(settings, *this, Path::identify(tokens1.getFiles()[0], false)); - std::list directives = preprocessor.createDirectives(tokens1); + std::list directives; + Preprocessor::createDirectives(tokens1, directives); TokenList tokenlist{settings, Path::identify(filename, false)}; Tokenizer tokenizer(std::move(tokenlist), *this);