summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compilerplugins/clang/casttovoid.cxx47
-rw-r--r--compilerplugins/clang/oncevar.cxx11
-rw-r--r--compilerplugins/clang/plugin.cxx48
-rw-r--r--compilerplugins/clang/plugin.hxx3
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 );