Kaydet (Commit) 0281b187 authored tarafından Noel Grandin's avatar Noel Grandin

make oncevar plugin ignore methods with #ifdef-ery

Change-Id: I8a9cf2c4b81b95bf654f7e90306328d72e3d3408
Reviewed-on: https://gerrit.libreoffice.org/40280Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst 827aa375
......@@ -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;
......
......@@ -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)) {
......
......@@ -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 )
......
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment