Ifyouwanttocreateanon-rewriteraction,inheritfromthisclass.Remembertoalso usePlugin::Registration.
*/ class Plugin
{ public: explicit Plugin( const InstantiationData& data ); virtual ~Plugin() {} // The main function of the plugin. // Note that for shared plugins, its functionality must be split into preRun() and postRun(), // see sharedvisitor/generator.cxx . virtualvoid run() = 0; // Should be called from run() before TraverseDecl(). // If returns false, run() should not do anything. virtualbool preRun() { returntrue; } virtualvoid postRun() {} template< typename T > class Registration; // Returns location right after the end of the token that starts at the given location.
SourceLocation locationAfterToken( SourceLocation location ); virtualbool setSharedPlugin( Plugin* /*plugin*/, const char* /*name*/ ) { return false; } enum { isPPCallback = false }; enum { isSharedPlugin = false }; protected:
DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation()) const; // Look at the line containing location and the previous line for any comments that overlap // either of those two lines and that contain "[-loplugin:<name>]" (with the name of this // plugin), indicating that warnings from this plugin should be suppressed here: bool suppressWarningAt(SourceLocation location) const; bool ignoreLocation( SourceLocation loc ) const
{ return handler.ignoreLocation(loc); } bool ignoreLocation( const Decl* decl ) const; bool ignoreLocation( const Stmt* stmt ) const; bool ignoreLocation(TypeLoc tloc) const;
CompilerInstance& compiler;
PluginHandler& handler; /** ReturnstheparentofthegivenASTnode.Clang'sinternalASTrepresentationdoesn'tprovidethisinformation, itcanonlyprovidechildren,butgettingtheparentisoftenusefulforinspectingapartoftheAST.
*/ const Stmt* getParentStmt( const Stmt* stmt );
Stmt* getParentStmt( Stmt* stmt ); const FunctionDecl* getParentFunctionDecl( const Stmt* stmt );
template<typename Derived> class FilteringPlugin : public RecursiveASTVisitor<Derived>, public Plugin
{ public: explicit FilteringPlugin( const InstantiationData& data ) : Plugin(data) {}
RemembertoalsousePlugin::Registration.
*/ class RewritePlugin
: public Plugin
{ public: explicit RewritePlugin( const InstantiationData& data ); protected: enum RewriteOption
{ // This enum allows passing just 'RemoveLineIfEmpty' to functions below. // If the resulting line would be completely empty, it'll be removed.
RemoveLineIfEmpty = 1 << 0, // Use this to remove the declaration/statement as a whole, i.e. all whitespace before the statement // and the trailing semicolon (is not part of the AST element range itself). // The trailing semicolon must be present.
RemoveWholeStatement = 1 << 1, // Removes also all whitespace preceding and following the expression (completely, so that // the preceding and following tokens would be right next to each other, follow with insertText( " " ) // if this is not wanted). Despite the name, indentation whitespace is not removed.
RemoveAllWhitespace = 1 << 2
}; struct RewriteOptions
: public Rewriter::RewriteOptions
{
RewriteOptions() : flags( 0 ) {} explicit RewriteOptions( RewriteOption option ); constint flags;
}; // syntactic sugar to be able to write 'RemoveLineIfEmpty | RemoveWholeStatement' friend RewriteOption operator|( RewriteOption option1, RewriteOption option2 ); // These following insert/remove/replaceText functions map to functions // in clang::Rewriter, with these differences: // - they (more intuitively) return false on failure rather than true // - they report a warning when the change cannot be done // - There are more options for easier removal of surroundings of a statement/expression. bool insertText( SourceLocation Loc, StringRef Str, bool InsertAfter = true, bool indentNewLines = false ); bool insertTextAfter( SourceLocation Loc, StringRef Str ); bool insertTextAfterToken( SourceLocation Loc, StringRef Str ); bool insertTextBefore( SourceLocation Loc, StringRef Str ); bool removeText( SourceLocation Start, unsigned Length, RewriteOptions opts = RewriteOptions()); bool removeText( CharSourceRange range, RewriteOptions opts = RewriteOptions()); bool removeText( SourceRange range, RewriteOptions opts = RewriteOptions()); bool replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr ); bool replaceText( SourceRange range, StringRef NewStr ); bool replaceText( SourceRange range, SourceRange replacementRange );
Rewriter* rewriter; private: template< typename T > friendclass Plugin::Registration; enum { isRewriter = true }; bool wouldRewriteWorkdir(SourceLocation loc); bool reportEditFailure( SourceLocation loc ); bool adjustRangeForOptions( CharSourceRange* range, RewriteOptions options );
};
inline bool Plugin::ignoreLocation( const Stmt* stmt ) const
{ // Invalid location can happen at least for ImplicitCastExpr of // ImplicitParam 'self' in Objective C method declarations: return stmt->getBeginLoc().isValid() && ignoreLocation( stmt->getBeginLoc());
}
template< typename T >
Plugin* Plugin::createHelper( const InstantiationData& data )
{ returnnew T( data );
}
template< typename T > inline
Plugin::Registration< T >::Registration( constchar* optionName, bool byDefault )
{
registerPlugin( &T::template createHelper< T >, optionName, T::isPPCallback, T::isSharedPlugin, byDefault );
}
inline
RewritePlugin::RewriteOptions::RewriteOptions( RewriteOption option )
: flags( option )
{ // Note that 'flags' stores also RemoveLineIfEmpty, it must be kept in sync with the base class. if( flags & RewritePlugin::RemoveLineIfEmpty )
RemoveLineIfEmpty = true;
}
template<typename Derived> class FilteringRewritePlugin : public RecursiveASTVisitor<Derived>, public RewritePlugin
{ public: explicit FilteringRewritePlugin( const InstantiationData& data ) : RewritePlugin(data) {}
// Same as pathname.startswith(prefix), except on Windows, where pathname and // prefix may also contain backslashes: bool hasPathnamePrefix(StringRef pathname, StringRef prefix);
// Same as pathname == other, except on Windows, where pathname and other may // also contain backslashes: bool isSamePathname(StringRef pathname, StringRef other);
// Check whether fullPathname is either SRCDIR/include/includePathname or // SDKDIR/include/includePathname: bool isSameUnoIncludePathname(StringRef fullPathname, StringRef includePathname);
// It appears that, given a function declaration, there is no way to determine // the language linkage of the function's type, only of the function's name // (via FunctionDecl::isExternC); however, in a case like // // extern "C" { static void f(); } // // the function's name does not have C language linkage while the function's // type does (as clarified in C++11 [decl.link]); cf. <http://clang-developers. // 42468.n3.nabble.com/Language-linkage-of-function-type-tt4037248.html> // "Language linkage of function type": bool hasCLanguageLinkageType(FunctionDecl const * decl);
// Count the number of times the base class is present in the subclass hierarchy // int derivedFromCount(clang::QualType subclassType, clang::QualType baseclassType); int derivedFromCount(const CXXRecordDecl* subtypeRecord, const CXXRecordDecl* baseRecord);
// It looks like Clang wrongly implements DR 4 // (<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#4>) and treats // a variable declared in an 'extern "..." {...}'-style linkage-specification as // if it contained the 'extern' specifier: bool hasExternalLinkage(VarDecl const * decl);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.