summaryrefslogtreecommitdiffstats
path: root/compilerplugins/clang/plugin.hxx
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2013-02-02 17:45:18 +0100
committerLuboš Luňák <l.lunak@suse.cz>2013-02-02 22:59:44 +0100
commita7c3adb773e5b69601716bda181cc481090a4d59 (patch)
tree1ffbb7bb5863a316058553ba941be5b9facc7e1b /compilerplugins/clang/plugin.hxx
parentmove plugin handling to separate source files (diff)
downloadcore-a7c3adb773e5b69601716bda181cc481090a4d59.tar.gz
core-a7c3adb773e5b69601716bda181cc481090a4d59.zip
avoid having to manuall modify sources when adding a new clang plugin
Now each one registers in its .cxx file. Change-Id: I811c0d4400c2bdccc1c287269378d7e8ad8743ce
Diffstat (limited to 'compilerplugins/clang/plugin.hxx')
-rw-r--r--compilerplugins/clang/plugin.hxx71
1 files changed, 71 insertions, 0 deletions
diff --git a/compilerplugins/clang/plugin.hxx b/compilerplugins/clang/plugin.hxx
index af1394d57b6f..014329e12eb1 100644
--- a/compilerplugins/clang/plugin.hxx
+++ b/compilerplugins/clang/plugin.hxx
@@ -28,18 +28,36 @@ using namespace std;
namespace loplugin
{
+/**
+ Base class for plugins.
+
+ If you want to create a non-rewriter action, inherit from this class. Remember to also
+ use Plugin::Registration.
+*/
class Plugin
{
public:
explicit Plugin( ASTContext& context );
+ virtual ~Plugin();
+ virtual void run() = 0;
+ template< typename T > class Registration;
protected:
DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation());
bool ignoreLocation( SourceLocation loc );
bool ignoreLocation( const Decl* decl );
bool ignoreLocation( const Stmt* stmt );
ASTContext& context;
+ private:
+ static void registerPlugin( Plugin* (*create)( ASTContext&, Rewriter& ), const char* optionName, bool isRewriter );
+ template< typename T > static Plugin* createHelper( ASTContext& context, Rewriter& rewriter );
+ enum { isRewriter = false };
};
+/**
+ Base class for rewriter plugins.
+
+ Remember to also use Plugin::Registration.
+*/
class RewritePlugin
: public Plugin
{
@@ -85,10 +103,44 @@ class RewritePlugin
bool replaceText( SourceRange range, SourceRange replacementRange );
Rewriter& rewriter;
private:
+ template< typename T > friend class Plugin::Registration;
+ template< typename T > static Plugin* createHelper( ASTContext& context, Rewriter& rewriter );
+ enum { isRewriter = true };
bool reportEditFailure( SourceLocation loc );
bool adjustForWholeStatement( SourceRange* range );
};
+/**
+ Plugin registration helper.
+
+ If you create a new helper class, create also an instance of this class to automatically register it.
+ The passed argument is name of the plugin, used for explicitly invoking rewriter plugins
+ (it is ignored for non-rewriter plugins).
+
+ @code
+ static Plugin::Registration< NameOfClass > X( "nameofclass" );
+ @endcode
+*/
+template< typename T >
+class Plugin::Registration
+ {
+ public:
+ Registration( const char* optionName );
+ };
+
+class RegistrationCreate
+ {
+ public:
+ template< typename T, bool > static T* create( ASTContext& context, Rewriter& rewriter );
+ };
+
+/////
+
+inline
+Plugin::~Plugin()
+ {
+ }
+
inline
bool Plugin::ignoreLocation( const Decl* decl )
{
@@ -101,6 +153,25 @@ bool Plugin::ignoreLocation( const Stmt* stmt )
return ignoreLocation( stmt->getLocStart());
}
+template< typename T >
+Plugin* Plugin::createHelper( ASTContext& context, Rewriter& )
+ {
+ return new T( context );
+ }
+
+template< typename T >
+Plugin* RewritePlugin::createHelper( ASTContext& context, Rewriter& rewriter )
+ {
+ return new T( context, rewriter );
+ }
+
+template< typename T >
+inline
+Plugin::Registration< T >::Registration( const char* optionName )
+ {
+ registerPlugin( &T::template createHelper< T >, optionName, T::isRewriter );
+ }
+
} // namespace
#endif // COMPILEPLUGIN_H