diff options
-rw-r--r-- | compilerplugins/clang/casttovoid.cxx | 47 | ||||
-rw-r--r-- | compilerplugins/clang/oncevar.cxx | 11 | ||||
-rw-r--r-- | compilerplugins/clang/plugin.cxx | 48 | ||||
-rw-r--r-- | compilerplugins/clang/plugin.hxx | 3 |
4 files changed, 62 insertions, 47 deletions
diff --git a/compilerplugins/clang/casttovoid.cxx b/compilerplugins/clang/casttovoid.cxx index f38d366314c5..49c086139a00 100644 --- a/compilerplugins/clang/casttovoid.cxx +++ b/compilerplugins/clang/casttovoid.cxx @@ -414,53 +414,6 @@ private: || compiler.getSourceManager().isMacroBodyExpansion(loc)); } - bool containsPreprocessingConditionalInclusion(SourceRange range) { - auto const begin = compiler.getSourceManager().getExpansionLoc( - range.getBegin()); - auto const end = compiler.getSourceManager().getExpansionLoc( - range.getEnd()); - assert(begin.isFileID() && end.isFileID()); - if (!(begin == end - || compiler.getSourceManager().isBeforeInTranslationUnit( - begin, end))) - { - // Conservatively assume "yes" if lexing fails (e.g., due to - // macros): - return true; - } - auto hash = false; - for (auto loc = begin;;) { - Token tok; - if (Lexer::getRawToken( - loc, tok, compiler.getSourceManager(), - compiler.getLangOpts(), true)) - { - // Conservatively assume "yes" if lexing fails (e.g., due to - // macros): - return true; - } - if (hash && tok.is(tok::raw_identifier)) { - auto const id = tok.getRawIdentifier(); - if (id == "if" || id == "ifdef" || id == "ifndef" - || id == "elif" || id == "else" || id == "endif") - { - return true; - } - } - if (loc == range.getEnd()) { - break; - } - hash = tok.is(tok::hash) && tok.isAtStartOfLine(); - loc = loc.getLocWithOffset( - std::max<unsigned>( - Lexer::MeasureTokenLength( - loc, compiler.getSourceManager(), - compiler.getLangOpts()), - 1)); - } - return false; - } - DeclRefExpr const * checkCast(ExplicitCastExpr const * expr) { if (!loplugin::TypeCheck(expr->getTypeAsWritten()).Void()) { return nullptr; diff --git a/compilerplugins/clang/oncevar.cxx b/compilerplugins/clang/oncevar.cxx index 18105584bbb8..00ecb1b6003a 100644 --- a/compilerplugins/clang/oncevar.cxx +++ b/compilerplugins/clang/oncevar.cxx @@ -242,6 +242,7 @@ public: bool VisitDeclRefExpr( const DeclRefExpr* ); bool VisitVarDecl( const VarDecl* ); + bool TraverseFunctionDecl( FunctionDecl* functionDecl ); private: std::unordered_set<VarDecl const *> maVarDeclSet; @@ -287,6 +288,16 @@ private: } }; +bool OnceVar::TraverseFunctionDecl( FunctionDecl* functionDecl ) +{ + // Ignore functions that contains #ifdef-ery, can be quite tricky + // to make useful changes when this plugin fires in such functions + if (containsPreprocessingConditionalInclusion( + functionDecl->getSourceRange())) + return true; + return RecursiveASTVisitor::TraverseFunctionDecl(functionDecl); +} + bool OnceVar::VisitVarDecl( const VarDecl* varDecl ) { if (ignoreLocation(varDecl)) { diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx index 66e22d507818..5bfdc4ed3a83 100644 --- a/compilerplugins/clang/plugin.cxx +++ b/compilerplugins/clang/plugin.cxx @@ -273,6 +273,54 @@ bool Plugin::isUnitTestMode() return PluginHandler::isUnitTestMode(); } +bool Plugin::containsPreprocessingConditionalInclusion(SourceRange range) +{ + auto const begin = compiler.getSourceManager().getExpansionLoc( + range.getBegin()); + auto const end = compiler.getSourceManager().getExpansionLoc( + range.getEnd()); + assert(begin.isFileID() && end.isFileID()); + if (!(begin == end + || compiler.getSourceManager().isBeforeInTranslationUnit( + begin, end))) + { + // Conservatively assume "yes" if lexing fails (e.g., due to + // macros): + return true; + } + auto hash = false; + for (auto loc = begin;;) { + Token tok; + if (Lexer::getRawToken( + loc, tok, compiler.getSourceManager(), + compiler.getLangOpts(), true)) + { + // Conservatively assume "yes" if lexing fails (e.g., due to + // macros): + return true; + } + if (hash && tok.is(tok::raw_identifier)) { + auto const id = tok.getRawIdentifier(); + if (id == "if" || id == "ifdef" || id == "ifndef" + || id == "elif" || id == "else" || id == "endif") + { + return true; + } + } + if (loc == range.getEnd()) { + break; + } + hash = tok.is(tok::hash) && tok.isAtStartOfLine(); + loc = loc.getLocWithOffset( + std::max<unsigned>( + Lexer::MeasureTokenLength( + loc, compiler.getSourceManager(), + compiler.getLangOpts()), + 1)); + } + return false; +} + RewritePlugin::RewritePlugin( const InstantiationData& data ) : Plugin( data ) , rewriter( data.rewriter ) diff --git a/compilerplugins/clang/plugin.hxx b/compilerplugins/clang/plugin.hxx index 92f796f0f7c8..87a7d22ff222 100644 --- a/compilerplugins/clang/plugin.hxx +++ b/compilerplugins/clang/plugin.hxx @@ -80,6 +80,9 @@ protected: static void normalizeDotDotInFilePath(std::string&); static bool isUnitTestMode(); + + bool containsPreprocessingConditionalInclusion(SourceRange range); + private: static void registerPlugin( Plugin* (*create)( const InstantiationData& ), const char* optionName, bool isPPCallback, bool byDefault ); template< typename T > static Plugin* createHelper( const InstantiationData& data ); |