[Libreoffice-commits] core.git: 2 commits - compilerplugins/clang

Luboš Luňák l.lunak at suse.cz
Thu Apr 4 04:05:25 PDT 2013


 compilerplugins/clang/checkconfigmacros.cxx |  100 ++++++++++++++++++++++++++++
 compilerplugins/clang/pluginhandler.cxx     |    7 +
 2 files changed, 106 insertions(+), 1 deletion(-)

New commits:
commit c3ffd741b207774be787896dfd305db89aca0e42
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Thu Apr 4 13:02:34 2013 +0200

    compiler plugin to check incorrect #ifdef for config_XXX.h macros
    
    http://lists.freedesktop.org/archives/libreoffice/2013-March/047769.html
    
    Change-Id: Ibba9d3dcc87d6d6eee58ab3690a8f87339d00956

diff --git a/compilerplugins/clang/checkconfigmacros.cxx b/compilerplugins/clang/checkconfigmacros.cxx
new file mode 100644
index 0000000..3ffaff8
--- /dev/null
+++ b/compilerplugins/clang/checkconfigmacros.cxx
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * Based on LLVM/Clang.
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ */
+
+#include "plugin.hxx"
+
+#include <clang/Lex/Preprocessor.h>
+
+namespace loplugin
+{
+
+/*
+This is a compile check.
+
+Feature macros from config_XXX.h headers are always #defined (to 1 or 0 in case of yes/no
+settings). It is a mistake to use #ifdef/#ifndef/defined to check them.
+
+Using 1/0 instead of defined/undefined avoids undetected problems when e.g. the necessary
+#include of the config_XXX.h file is missing.
+*/
+
+class CheckConfigMacros
+    : public PPCallbacks
+    , public Plugin
+    {
+    public:
+        explicit CheckConfigMacros( CompilerInstance& compiler );
+        virtual void run();
+        virtual void MacroDefined( const Token& macroToken, const MacroInfo* info );
+        virtual void MacroUndefined( const Token& macroToken , const MacroInfo* info );
+        virtual void Ifdef( SourceLocation location, const Token& macroToken );
+        virtual void Ifndef( SourceLocation location, const Token& macroToken );
+        virtual void Defined( const Token& macroToken );
+    private:
+        void checkMacro( const Token& macroToken, SourceLocation location );
+        std::set< string > configMacros;
+    };
+
+CheckConfigMacros::CheckConfigMacros( CompilerInstance& compiler )
+    : Plugin( compiler )
+    {
+    compiler.getPreprocessor().addPPCallbacks( this );
+    }
+
+void CheckConfigMacros::run()
+    {
+    // nothing, only check preprocessor usage
+    }
+
+void CheckConfigMacros::MacroDefined( const Token& macroToken, const MacroInfo* info )
+    {
+    const char* filename = compiler.getSourceManager().getPresumedLoc( info->getDefinitionLoc()).getFilename();
+    if( filename != NULL
+        && ( strncmp( filename, BUILDDIR "/config_host/", strlen( BUILDDIR "/config_host/" )) == 0
+            || strncmp( filename, BUILDDIR "/config_build/", strlen( BUILDDIR "/config_build/" )) == 0 ))
+        {
+//        fprintf(stderr,"DEF: %s %s\n", macroToken.getIdentifierInfo()->getName().data(), filename );
+        configMacros.insert( macroToken.getIdentifierInfo()->getName());
+        }
+    }
+
+void CheckConfigMacros::MacroUndefined( const Token& macroToken, const MacroInfo* )
+    {
+    configMacros.erase( macroToken.getIdentifierInfo()->getName());
+    }
+
+void CheckConfigMacros::Ifdef( SourceLocation location, const Token& macroToken )
+    {
+    checkMacro( macroToken, location );
+    }
+
+void CheckConfigMacros::Ifndef( SourceLocation location, const Token& macroToken )
+    {
+    checkMacro( macroToken, location );
+    }
+
+void CheckConfigMacros::Defined( const Token& macroToken )
+    {
+    checkMacro( macroToken, macroToken.getLocation());
+    }
+
+void CheckConfigMacros::checkMacro( const Token& macroToken, SourceLocation location )
+    {
+    if( configMacros.find( macroToken.getIdentifierInfo()->getName()) != configMacros.end())
+        {
+        report( DiagnosticsEngine::Error, "checking whether a config macro %0 is defined",
+            location ) << macroToken.getIdentifierInfo()->getName();
+        report( DiagnosticsEngine::Note, "use #if instead of #ifdef/#ifndef/defined", location );
+        }
+    }
+
+static Plugin::Registration< CheckConfigMacros > X( "bodynotinblock" );
+
+} // namespace
commit 996b6fc92b847f70f73cda58f64e5cf438585127
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Thu Apr 4 12:52:04 2013 +0200

    don't explicitly delete PPCallbacks-based compiler plugin actions
    
    If the class is based on PPCallbacks too, Clang internals will delete
    the instance.
    
    Change-Id: I6dd83d800e6cca17eb0b5de23c8994f11c087fd5

diff --git a/compilerplugins/clang/pluginhandler.cxx b/compilerplugins/clang/pluginhandler.cxx
index 69b8c04..cd554aa 100644
--- a/compilerplugins/clang/pluginhandler.cxx
+++ b/compilerplugins/clang/pluginhandler.cxx
@@ -12,6 +12,7 @@
 
 #include <clang/Frontend/CompilerInstance.h>
 #include <clang/Frontend/FrontendPluginRegistry.h>
+#include <clang/Lex/PPCallbacks.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -65,7 +66,11 @@ PluginHandler::~PluginHandler()
          i < pluginCount;
          ++i )
         if( plugins[ i ].object != NULL )
-            delete plugins[ i ].object;
+            {
+            // PPCallbacks is owned by preprocessor object, don't delete those
+            if( dynamic_cast< PPCallbacks* >( plugins[ i ].object ) == NULL )
+                delete plugins[ i ].object;
+            }
     }
 
 void PluginHandler::handleOption( const string& option )


More information about the Libreoffice-commits mailing list