From 67e3187653a51f011aef9599bb497430479b454b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 17 May 2017 10:25:37 +0200 Subject: [PATCH] Preprocessor: Refactor handling of #pragma asm --- lib/preprocessor.cpp | 108 +++++++++++++++++++------------------- lib/preprocessor.h | 4 ++ test/testpreprocessor.cpp | 5 +- 3 files changed, 61 insertions(+), 56 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index cde6f6526..ea2916553 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -436,7 +436,6 @@ void Preprocessor::preprocess(std::istream &istr, std::map files; const simplecpp::TokenList tokens1(istr, files, filename, &outputList); - const std::set configs = getConfigs(tokens1); for (std::set::const_iterator it = configs.begin(); it != configs.end(); ++it) { @@ -567,6 +566,10 @@ void Preprocessor::loadFiles(const simplecpp::TokenList &rawtokens, std::vector< simplecpp::OutputList outputList; tokenlists = simplecpp::load(rawtokens, files, dui, &outputList); + + for (std::map::iterator it = tokenlists.begin(); it != tokenlists.end(); ++it) { + Preprocessor::simplifyPragmaAsm(it->second); + } } void Preprocessor::removeComments() @@ -597,7 +600,7 @@ void Preprocessor::setPlatformInfo(simplecpp::TokenList *tokens) const tokens->sizeOfType["long double *"] = _settings.sizeof_pointer; } -std::string Preprocessor::getcode(const simplecpp::TokenList &tokens1, const std::string &cfg, std::vector &files, const bool writeLocations) +simplecpp::TokenList Preprocessor::preprocess(const simplecpp::TokenList &tokens1, const std::string &cfg, std::vector &files) { const simplecpp::DUI dui = createDUI(_settings, cfg, files[0]); @@ -609,45 +612,20 @@ std::string Preprocessor::getcode(const simplecpp::TokenList &tokens1, const std bool showerror = (!_settings.userDefines.empty() && !_settings.force); reportOutput(outputList, showerror); if (hasErrors(outputList)) - return ""; + return simplecpp::TokenList(files); tokens2.removeComments(); // ensure that guessed define macros without value are not used in the code if (!validateCfg(cfg, macroUsage)) - return ""; + return simplecpp::TokenList(files); - // assembler code locations.. - std::set assemblerLocations; - for (std::list::const_iterator dirIt = directives.begin(); dirIt != directives.end(); ++dirIt) { - const Directive &d1 = *dirIt; - if (d1.str.compare(0, 11, "#pragma asm") != 0) - continue; - std::list::const_iterator dirIt2 = dirIt; - ++dirIt2; - if (dirIt2 == directives.end()) - continue; - - const Directive &d2 = *dirIt2; - if (d2.str.compare(0,14,"#pragma endasm") != 0 || d1.file != d2.file) - continue; - - simplecpp::Location loc(files); - loc.fileIndex = ~0U; - loc.col = 0U; - for (unsigned int i = 0; i < files.size(); ++i) { - if (files[i] == d1.file) { - loc.fileIndex = i; - break; - } - } - - for (unsigned int linenr = d1.linenr + 1U; linenr < d2.linenr; linenr++) { - loc.line = linenr; - assemblerLocations.insert(loc); - } - } + return tokens2; +} +std::string Preprocessor::getcode(const simplecpp::TokenList &tokens1, const std::string &cfg, std::vector &files, const bool writeLocations) +{ + simplecpp::TokenList tokens2 = preprocess(tokens1, cfg, files); unsigned int prevfile = 0; unsigned int line = 1; std::ostringstream ret; @@ -660,29 +638,9 @@ std::string Preprocessor::getcode(const simplecpp::TokenList &tokens1, const std if (tok->previous && line >= tok->location.line) // #7912 ret << ' '; - bool newline = false; while (tok->location.line > line) { ret << '\n'; line++; - newline = true; - } - if (newline) { - simplecpp::Location loc = tok->location; - loc.col = 0U; - if (assemblerLocations.find(loc) != assemblerLocations.end()) { - ret << "asm();"; - while (assemblerLocations.find(loc) != assemblerLocations.end()) { - loc.line++; - } - while (tok && tok->location.line < loc.line) - tok = tok->next; - if (!tok) - break; - while (line < tok->location.line) { - ret << '\n'; - ++line; - } - } } if (!tok->macro.empty()) ret << Preprocessor::macroChar; @@ -926,3 +884,45 @@ unsigned int Preprocessor::calculateChecksum(const simplecpp::TokenList &tokens1 } return crc32(ostr.str()); } + +void Preprocessor::simplifyPragmaAsm(simplecpp::TokenList *tokenList) +{ + // assembler code.. + for (simplecpp::Token *tok = tokenList->front(); tok; tok = tok->next) { + if (tok->op != '#') + continue; + if (sameline(tok, tok->previousSkipComments())) + continue; + + const simplecpp::Token * const tok2 = tok->nextSkipComments(); + if (!tok2 || !sameline(tok, tok2) || tok2->str != "pragma") + continue; + + const simplecpp::Token * const tok3 = tok2->nextSkipComments(); + if (!tok3 || !sameline(tok, tok3) || tok3->str != "asm") + continue; + + const simplecpp::Token *endasm = tok3; + while ((endasm = endasm->next) != 0) { + if (endasm->op != '#' || sameline(endasm,endasm->previousSkipComments())) + continue; + const simplecpp::Token * const endasm2 = endasm->nextSkipComments(); + if (!endasm2 || !sameline(endasm, endasm2) || endasm2->str != "pragma") + continue; + const simplecpp::Token * const endasm3 = endasm2->nextSkipComments(); + if (!endasm3 || !sameline(endasm2, endasm3) || endasm3->str != "endasm") + continue; + while (sameline(endasm,endasm3)) + endasm = endasm->next; + break; + } + + const simplecpp::Token * const tok4 = tok3->next; + tok->setstr("asm"); + const_cast(tok2)->setstr("("); + const_cast(tok3)->setstr(")"); + const_cast(tok4)->setstr(";"); + while (tok4->next != endasm) + tokenList->deleteToken(tok4->next); + } +} diff --git a/lib/preprocessor.h b/lib/preprocessor.h index f81c08be2..a17cd4ea7 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -135,6 +135,8 @@ public: */ void preprocess(std::istream &srcCodeStream, std::string &processedFile, std::list &resultConfigurations, const std::string &filename, const std::list &includePaths); + simplecpp::TokenList preprocess(const simplecpp::TokenList &tokens1, const std::string &cfg, std::vector &files); + std::string getcode(const simplecpp::TokenList &tokens1, const std::string &cfg, std::vector &files, const bool writeLocations); /** @@ -169,6 +171,8 @@ public: */ unsigned int calculateChecksum(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const; + static void simplifyPragmaAsm(simplecpp::TokenList *tokenList); + private: /** diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 2d17254fb..f2eb7886b 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -253,6 +253,7 @@ private: std::vector files; simplecpp::TokenList tokens(istr, files, filename, &outputList); tokens.removeComments(); + Preprocessor::simplifyPragmaAsm(&tokens); const std::set configs(preprocessor0.getConfigs(tokens)); preprocessor0.setDirectives(tokens); for (std::set::const_iterator it = configs.begin(); it != configs.end(); ++it) { @@ -1376,7 +1377,7 @@ private: // Compare results.. ASSERT_EQUALS(1, static_cast(actual.size())); - ASSERT_EQUALS("\nasm();\n\naaa\n\nasm();\n\nbbb", actual[""]); + ASSERT_EQUALS("asm ( )\n;\n\naaa\nasm ( ) ;\n\n\nbbb", actual[""]); } void pragma_asm_2() { @@ -1391,7 +1392,7 @@ private: // Compare results.. ASSERT_EQUALS(1, static_cast(actual.size())); - ASSERT_EQUALS("\nasm();\n\nbbb", actual[""]); + ASSERT_EQUALS("asm ( )\n;\n\nbbb", actual[""]); } void endifsemicolon() {