summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/plugin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'compilerplugins/clang/plugin.cxx')
-rw-r--r--compilerplugins/clang/plugin.cxx197
1 files changed, 102 insertions, 95 deletions
diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx
index ea646d29da89..66e22d507818 100644
--- a/compilerplugins/clang/plugin.cxx
+++ b/compilerplugins/clang/plugin.cxx
@@ -28,16 +28,16 @@ namespace loplugin
Plugin::Plugin( const InstantiationData& data )
: compiler( data.compiler ), handler( data.handler ), name( data.name )
- {
- }
+{
+}
DiagnosticBuilder Plugin::report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc ) const
- {
+{
return handler.report( level, name, message, compiler, loc );
- }
+}
bool Plugin::ignoreLocation( SourceLocation loc )
- {
+{
SourceLocation expansionLoc = compiler.getSourceManager().getExpansionLoc( loc );
if( compiler.getSourceManager().isInSystemHeader( expansionLoc ))
return true;
@@ -68,19 +68,19 @@ bool Plugin::ignoreLocation( SourceLocation loc )
}
std::string s(bufferName);
normalizeDotDotInFilePath(s);
- if (hasPathnamePrefix(s, WORKDIR)) {
+ if (hasPathnamePrefix(s, WORKDIR))
return true;
- }
}
if( hasPathnamePrefix(bufferName, BUILDDIR)
|| hasPathnamePrefix(bufferName, SRCDIR) )
return false; // ok
return true;
- }
+}
void Plugin::normalizeDotDotInFilePath( std::string & s )
+{
+ for (std::string::size_type i = 0;;)
{
- for (std::string::size_type i = 0;;) {
i = s.find("/.", i);
if (i == std::string::npos) {
break;
@@ -94,7 +94,8 @@ void Plugin::normalizeDotDotInFilePath( std::string & s )
break;
}
auto j = s.rfind('/', i - 1);
- if (j == std::string::npos) {
+ if (j == std::string::npos)
+ {
// BBB/..[/CCC] -> BBB/..[/CCC] (instead of BBB/../CCC ->
// CCC, to avoid wrong ../../CCC -> CCC; relative paths
// shouldn't happen anyway, and even if they did, wouldn't
@@ -108,34 +109,34 @@ void Plugin::normalizeDotDotInFilePath( std::string & s )
i += 2;
}
}
- }
+}
void Plugin::registerPlugin( Plugin* (*create)( const InstantiationData& ), const char* optionName, bool isPPCallback, bool byDefault )
- {
+{
PluginHandler::registerPlugin( create, optionName, isPPCallback, byDefault );
- }
+}
-unordered_map< const Stmt*, const Stmt* > Plugin::parents;
+std::unordered_map< const Stmt*, const Stmt* > Plugin::parents;
const Stmt* Plugin::parentStmt( const Stmt* stmt )
- {
+{
if( parents.empty())
buildParents( compiler );
//if(parents.count(stmt)!=1)stmt->dump();
//assert( parents.count( stmt ) == 1 );
return parents[ stmt ];
- }
+}
Stmt* Plugin::parentStmt( Stmt* stmt )
- {
+{
if( parents.empty())
buildParents( compiler );
//assert( parents.count( stmt ) == 1 );
return const_cast< Stmt* >( parents[ stmt ] );
- }
+}
static const Decl* getDeclContext(ASTContext& context, const Stmt* stmt)
- {
+{
auto it = context.getParents(*stmt).begin();
if (it == context.getParents(*stmt).end())
@@ -150,19 +151,20 @@ static const Decl* getDeclContext(ASTContext& context, const Stmt* stmt)
return getDeclContext(context, aStmt);
return nullptr;
- }
+}
const FunctionDecl* Plugin::parentFunctionDecl( const Stmt* stmt )
- {
+{
const Decl *decl = getDeclContext(compiler.getASTContext(), stmt);
if (decl)
return static_cast<const FunctionDecl*>(decl->getNonClosureContext());
return nullptr;
- }
+}
-bool Plugin::isInUnoIncludeFile(SourceLocation spellingLocation) const {
+bool Plugin::isInUnoIncludeFile(SourceLocation spellingLocation) const
+{
StringRef name {
compiler.getSourceManager().getFilename(spellingLocation) };
return compiler.getSourceManager().isInMainFile(spellingLocation)
@@ -181,7 +183,8 @@ bool Plugin::isInUnoIncludeFile(SourceLocation spellingLocation) const {
|| hasPathnamePrefix(name, SRCDIR "/include/uno/"));
}
-bool Plugin::isInUnoIncludeFile(const FunctionDecl* functionDecl) const {
+bool Plugin::isInUnoIncludeFile(const FunctionDecl* functionDecl) const
+{
return isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(
functionDecl->getCanonicalDecl()->getNameInfo().getLoc()));
}
@@ -190,167 +193,167 @@ namespace
{
class ParentBuilder
: public RecursiveASTVisitor< ParentBuilder >
- {
- public:
- bool VisitFunctionDecl( const FunctionDecl* function );
- bool VisitObjCMethodDecl( const ObjCMethodDecl* method );
- void walk( const Stmt* stmt );
- bool shouldVisitTemplateInstantiations () const { return true; }
- unordered_map< const Stmt*, const Stmt* >* parents;
- };
+{
+public:
+ bool VisitFunctionDecl( const FunctionDecl* function );
+ bool VisitObjCMethodDecl( const ObjCMethodDecl* method );
+ void walk( const Stmt* stmt );
+ bool shouldVisitTemplateInstantiations () const { return true; }
+ std::unordered_map< const Stmt*, const Stmt* >* parents;
+};
bool ParentBuilder::VisitFunctionDecl( const FunctionDecl* function )
- {
+{
// if( ignoreLocation( declaration ))
// return true; ???
if( function->doesThisDeclarationHaveABody())
- {
+ {
const Stmt* body = function->getBody();
(*parents)[ body ] = NULL; // no parent
walk( body );
- }
+ }
if( const CXXConstructorDecl* ctor = dyn_cast< CXXConstructorDecl >( function ))
- {
+ {
for( CXXConstructorDecl::init_const_iterator it = ctor->init_begin();
it != ctor->init_end();
++it )
- {
+ {
const Expr* init_expression = (*it)->getInit();
(*parents)[ init_expression ] = NULL;
walk( init_expression );
- }
}
- return true;
}
+ return true;
+}
bool ParentBuilder::VisitObjCMethodDecl( const ObjCMethodDecl* method )
- {
+{
// if( ignoreLocation( declaration ))
// return true; ???
if( method->hasBody())
- {
+ {
const Stmt* body = method->getBody();
(*parents)[ body ] = NULL; // no parent
walk( body );
- }
- return true;
}
+ return true;
+}
void ParentBuilder::walk( const Stmt* stmt )
- {
+{
for( ConstStmtIterator it = stmt->child_begin();
it != stmt->child_end();
++it )
- {
+ {
if( *it != NULL )
- {
+ {
(*parents)[ *it ] = stmt;
walk( *it );
- }
}
}
+}
} // namespace
void Plugin::buildParents( CompilerInstance& compiler )
- {
+{
assert( parents.empty());
ParentBuilder builder;
builder.parents = &parents;
builder.TraverseDecl( compiler.getASTContext().getTranslationUnitDecl());
- }
+}
SourceLocation Plugin::locationAfterToken( SourceLocation location )
- {
+{
return Lexer::getLocForEndOfToken( location, 0, compiler.getSourceManager(), compiler.getLangOpts());
- }
+}
bool Plugin::isUnitTestMode()
- {
+{
return PluginHandler::isUnitTestMode();
- }
+}
RewritePlugin::RewritePlugin( const InstantiationData& data )
: Plugin( data )
, rewriter( data.rewriter )
- {
- }
+{
+}
bool RewritePlugin::insertText( SourceLocation Loc, StringRef Str, bool InsertAfter, bool indentNewLines )
- {
+{
assert( rewriter );
if (wouldRewriteWorkdir(Loc))
return false;
if( rewriter->InsertText( Loc, Str, InsertAfter, indentNewLines ))
return reportEditFailure( Loc );
return true;
- }
+}
bool RewritePlugin::insertTextAfter( SourceLocation Loc, StringRef Str )
- {
+{
assert( rewriter );
if (wouldRewriteWorkdir(Loc))
return false;
if( rewriter->InsertTextAfter( Loc, Str ))
return reportEditFailure( Loc );
return true;
- }
+}
bool RewritePlugin::insertTextAfterToken( SourceLocation Loc, StringRef Str )
- {
+{
assert( rewriter );
if (wouldRewriteWorkdir(Loc))
return false;
if( rewriter->InsertTextAfterToken( Loc, Str ))
return reportEditFailure( Loc );
return true;
- }
+}
bool RewritePlugin::insertTextBefore( SourceLocation Loc, StringRef Str )
- {
+{
assert( rewriter );
if (wouldRewriteWorkdir(Loc))
return false;
if( rewriter->InsertTextBefore( Loc, Str ))
return reportEditFailure( Loc );
return true;
- }
+}
bool RewritePlugin::removeText( SourceLocation Start, unsigned Length, RewriteOptions opts )
- {
+{
CharSourceRange range( SourceRange( Start, Start.getLocWithOffset( Length )), false );
return removeText( range, opts );
- }
+}
bool RewritePlugin::removeText( SourceRange range, RewriteOptions opts )
- {
+{
return removeText( CharSourceRange( range, true ), opts );
- }
+}
bool RewritePlugin::removeText( CharSourceRange range, RewriteOptions opts )
- {
+{
assert( rewriter );
if (wouldRewriteWorkdir(range.getBegin()))
return false;
if( rewriter->getRangeSize( range, opts ) == -1 )
return reportEditFailure( range.getBegin());
if( !handler.addRemoval( range.getBegin() ) )
- {
+ {
report( DiagnosticsEngine::Warning, "double code removal, possible plugin error", range.getBegin());
return true;
- }
+ }
if( opts.flags & RemoveWholeStatement || opts.flags & RemoveAllWhitespace )
- {
+ {
if( !adjustRangeForOptions( &range, opts ))
return reportEditFailure( range.getBegin());
- }
+ }
if( rewriter->RemoveText( range, opts ))
return reportEditFailure( range.getBegin());
return true;
- }
+}
bool RewritePlugin::adjustRangeForOptions( CharSourceRange* range, RewriteOptions opts )
- {
+{
assert( rewriter );
SourceManager& SM = rewriter->getSourceMgr();
SourceLocation fileStartLoc = SM.getLocForStartOfFile( SM.getFileID( range->getBegin()));
@@ -379,67 +382,68 @@ bool RewritePlugin::adjustRangeForOptions( CharSourceRange* range, RewriteOption
while( *endPos == ' ' || *endPos == '\t' )
++endPos;
if( opts.flags & RemoveWholeStatement )
- {
+ {
if( *endPos == ';' )
++endPos;
else
return false;
- }
+ }
*range = CharSourceRange( SourceRange( range->getBegin().getLocWithOffset( startPos - startBuf + 1 ),
locationEnd.getLocWithOffset( endPos - endBuf )), false );
return true;
- }
+}
bool RewritePlugin::replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr )
- {
+{
assert( rewriter );
if (wouldRewriteWorkdir(Start))
return false;
if( OrigLength != 0 && !handler.addRemoval( Start ) )
- {
+ {
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", Start );
return true;
- }
+ }
if( rewriter->ReplaceText( Start, OrigLength, NewStr ))
return reportEditFailure( Start );
return true;
- }
+}
bool RewritePlugin::replaceText( SourceRange range, StringRef NewStr )
- {
+{
assert( rewriter );
if (wouldRewriteWorkdir(range.getBegin()))
return false;
if( rewriter->getRangeSize( range ) == -1 )
return reportEditFailure( range.getBegin());
if( !handler.addRemoval( range.getBegin() ) )
- {
+ {
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", range.getBegin());
return true;
- }
+ }
if( rewriter->ReplaceText( range, NewStr ))
return reportEditFailure( range.getBegin());
return true;
- }
+}
bool RewritePlugin::replaceText( SourceRange range, SourceRange replacementRange )
- {
+{
assert( rewriter );
if (wouldRewriteWorkdir(range.getBegin()))
return false;
if( rewriter->getRangeSize( range ) == -1 )
return reportEditFailure( range.getBegin());
if( !handler.addRemoval( range.getBegin() ) )
- {
+ {
report( DiagnosticsEngine::Warning, "double code replacement, possible plugin error", range.getBegin());
return true;
- }
+ }
if( rewriter->ReplaceText( range, replacementRange ))
return reportEditFailure( range.getBegin());
return true;
- }
+}
-bool RewritePlugin::wouldRewriteWorkdir(SourceLocation loc) {
+bool RewritePlugin::wouldRewriteWorkdir(SourceLocation loc)
+{
if (loc.isInvalid() || loc.isMacroID()) {
return false;
}
@@ -450,10 +454,10 @@ bool RewritePlugin::wouldRewriteWorkdir(SourceLocation loc) {
}
bool RewritePlugin::reportEditFailure( SourceLocation loc )
- {
+{
report( DiagnosticsEngine::Warning, "cannot perform source modification (macro expansion involved?)", loc );
return false;
- }
+}
namespace {
@@ -464,7 +468,8 @@ template<typename Fn> bool checkPathname(
return true;
}
#if defined _WIN32
- for (std::size_t n = 0;;) {
+ for (std::size_t n = 0;;)
+ {
std::size_t n1 = pathname.find('\\', n);
if (n1 >= against.size()) {
return check(pathname.substr(n), against.substr(n));
@@ -482,13 +487,15 @@ template<typename Fn> bool checkPathname(
}
-bool hasPathnamePrefix(StringRef pathname, StringRef prefix) {
+bool hasPathnamePrefix(StringRef pathname, StringRef prefix)
+{
return checkPathname(
pathname, prefix,
[](StringRef p, StringRef a) { return p.startswith(a); });
}
-bool isSamePathname(StringRef pathname, StringRef other) {
+bool isSamePathname(StringRef pathname, StringRef other)
+{
return checkPathname(
pathname, other, [](StringRef p, StringRef a) { return p == a; });
}