diff options
Diffstat (limited to 'compilerplugins/clang/plugin.cxx')
-rw-r--r-- | compilerplugins/clang/plugin.cxx | 197 |
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; }); } |