summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2012-10-05 18:17:13 +0200
committerLuboš Luňák <l.lunak@suse.cz>2012-10-09 17:25:27 +0200
commit02a8d36ebf3d54784903f2899eafe010bedf2f4c (patch)
tree61ba648242b1356b7da72336073b91e397814e50
parent7b34748b1bfd8b5fe0406c1f6bdaaa585d7bc4c3 (diff)
initial support for clang compiler plugins
The plugin is intentionally built using a custom Makefile, because it's used by gbuild, so I don't want to build the plugin using gbuild too. It is also intentionally not placed under workdir/, as that is cleaned by 'make clean', the plugin is cleaned only by 'make distclean', so that cleaning it doesn't cause ccache misses. No actual functionality in the plugin itself yet. Change-Id: Ic05eba8d6260eec123c9e699eb5385abfe1b832f
-rw-r--r--Makefile.top6
-rw-r--r--compilerplugins/.gitignore1
-rw-r--r--compilerplugins/Makefile23
-rw-r--r--compilerplugins/Makefile-clang.mk60
-rw-r--r--compilerplugins/Makefile.mk32
-rw-r--r--compilerplugins/README27
-rw-r--r--compilerplugins/clang/compileplugin.cxx68
-rw-r--r--compilerplugins/clang/compileplugin.hxx14
-rw-r--r--config_host.mk.in1
-rw-r--r--configure.in39
-rw-r--r--solenv/gbuild/platform/com_GCC_class.mk2
-rw-r--r--solenv/gbuild/platform/com_GCC_defs.mk6
12 files changed, 277 insertions, 2 deletions
diff --git a/Makefile.top b/Makefile.top
index e5bd89d1da0a..d8bde500ca26 100644
--- a/Makefile.top
+++ b/Makefile.top
@@ -351,10 +351,12 @@ ifeq ($(CROSS_COMPILING),YES)
rm -rf $(SRCDIR)/*/$(INPATH_FOR_BUILD)
endif
+include $(SRCDIR)/compilerplugins/Makefile.mk
+
#
# Distclean
#
-distclean : clean
+distclean : clean compilerplugins-clean
ifeq ($(BUILD_DMAKE),YES)
(if [ -f dmake/Makefile ] ; then $(GNUMAKE) -j $(GMAKE_PARALLELISM) -C dmake distclean; fi) && \
rm -f solenv/*/bin/dmake*
@@ -393,7 +395,7 @@ endif
#
bootstrap: $(WORKDIR)/bootstrap
-$(WORKDIR)/bootstrap: solenv/bin/concat-deps.c
+$(WORKDIR)/bootstrap: solenv/bin/concat-deps.c compilerplugins
@cd $(SRCDIR) && ./bootstrap
@mkdir -p $(dir $@) && touch $@
diff --git a/compilerplugins/.gitignore b/compilerplugins/.gitignore
new file mode 100644
index 000000000000..b672fdeaf35b
--- /dev/null
+++ b/compilerplugins/.gitignore
@@ -0,0 +1 @@
+obj
diff --git a/compilerplugins/Makefile b/compilerplugins/Makefile
new file mode 100644
index 000000000000..4281c12da996
--- /dev/null
+++ b/compilerplugins/Makefile
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+ifeq ($(SOLARENV),)
+ifeq ($(gb_Side),)
+gb_Side:=host
+endif
+include $(dir $(realpath $(lastword $(MAKEFILE_LIST))))../config_$(gb_Side).mk
+endif
+
+include $(SRCDIR)/compilerplugins/Makefile.mk
+
+all: build
+build: compilerplugins
+clean: compilerplugins-clean
+
+# vim: set noet sw=4 ts=4:
diff --git a/compilerplugins/Makefile-clang.mk b/compilerplugins/Makefile-clang.mk
new file mode 100644
index 000000000000..1797e424ddb1
--- /dev/null
+++ b/compilerplugins/Makefile-clang.mk
@@ -0,0 +1,60 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# Make sure variables in this Makefile do not conflict with other variables (e.g. from gbuild).
+
+# The list of source files.
+CLANGSRC=compileplugin.cxx
+
+# You may occassionally want to override some of these
+
+# Compile flags ('make CLANGCXXFLAGS=-g' if you need to debug the plugin)
+CLANGCXXFLAGS=-O2 -Wall -g
+# The prefix where Clang resides, override to where Clang resides if using a source build.
+CLANGDIR=/usr
+# The build directory (different from CLANGDIR if using a Clang out-of-source build)
+CLANGBUILD=/usr
+
+# The uninteresting rest.
+
+# Clang headers require these.
+CLANGDEFS=-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fno-rtti
+# All include locations needed.
+CLANGINCLUDES=-I$(CLANGDIR)/include -I$(CLANGDIR)/tools/clang/include -I$(CLANGBUILD)/include -I$(CLANGBUILD)/tools/clang/include
+
+CLANGINDIR=$(SRCDIR)/compilerplugins/clang
+# Cannot use $(WORKDIR), the plugin should survive even 'make clean', otherwise the rebuilt
+# plugin will cause cache misses with ccache.
+CLANGOUTDIR=$(SRCDIR)/compilerplugins/obj
+
+compilerplugins: $(CLANGOUTDIR) $(CLANGOUTDIR)/compileplugin.so
+
+compilerplugins-clean:
+ rm -rf $(CLANGOUTDIR)
+
+$(CLANGOUTDIR):
+ mkdir -p $(CLANGOUTDIR)
+
+CLANGOBJS=
+
+define clangbuildsrc
+$(3): $(2) $(SRCDIR)/compilerplugins/Makefile-clang.mk
+ $(CXX) $(CLANGCXXFLAGS) $(CLANGDEFS) $(CLANGINCLUDES) $(2) -fPIC -c -o $(3) -MMD -MT $(3) -MP -MF $(CLANGOUTDIR)/$(1).d
+
+-include $(CLANGOUTDIR)/$(1).d
+
+$(CLANGOUTDIR)/compileplugin.so: $(3)
+$(CLANGOUTDIR)/compileplugin.so: CLANGOBJS += $(3)
+endef
+
+$(foreach src, $(CLANGSRC), $(eval $(call clangbuildsrc,$(src),$(CLANGINDIR)/$(src),$(CLANGOUTDIR)/$(src:.cxx=.o))))
+
+$(CLANGOUTDIR)/compileplugin.so: $(CLANGOBJS)
+ $(CXX) -shared $(CLANGOBJS) -o $@
+
+# vim: set noet sw=4 ts=4:
diff --git a/compilerplugins/Makefile.mk b/compilerplugins/Makefile.mk
new file mode 100644
index 000000000000..c3b5290c9b2d
--- /dev/null
+++ b/compilerplugins/Makefile.mk
@@ -0,0 +1,32 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+.PHONY: compilerplugins compilerplugins-clean
+
+ifeq ($(COMPILER_PLUGINS),)
+
+# no support
+
+compilerplugins:
+compilerplugins-clean:
+compilerplugins.clean:
+
+else
+
+ifeq ($(COM_GCC_IS_CLANG),TRUE)
+
+include $(SRCDIR)/compilerplugins/Makefile-clang.mk
+
+compilerplugins.clean: compilerplugins-clean
+
+endif
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/compilerplugins/README b/compilerplugins/README
new file mode 100644
index 000000000000..98ac70c85ef5
--- /dev/null
+++ b/compilerplugins/README
@@ -0,0 +1,27 @@
+Compiler plugins.
+
+== Overview ==
+
+This directory contains code for compiler plugins. These are used to perform
+additional actions during compilation (such as additional warnings) and
+also to perform mass code refactoring.
+
+Currently only the Clang compiler is supported (http://clang.llvm.org).
+
+== Usage ==
+
+Compiler plugins are enabled automatically by --enable-dbgutil if Clang headers
+are found or explicitly using --enable-compiler-plugins.
+
+
+== Functionality ==
+
+=== Compile plugin ===
+
+The compile plugin is used during normal compilation to perform additional checks.
+All warnings and errors are marked '[loplugin]' in the message.
+
+
+== Code documentation / howtos ==
+
+TBD
diff --git a/compilerplugins/clang/compileplugin.cxx b/compilerplugins/clang/compileplugin.cxx
new file mode 100644
index 000000000000..fb2632e3d2cd
--- /dev/null
+++ b/compilerplugins/clang/compileplugin.cxx
@@ -0,0 +1,68 @@
+/*
+ * 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 "compileplugin.hxx"
+
+#include <clang/AST/ASTConsumer.h>
+#include <clang/AST/ASTContext.h>
+#include <clang/Frontend/CompilerInstance.h>
+#include <clang/Frontend/FrontendAction.h>
+#include <clang/Frontend/FrontendPluginRegistry.h>
+#include <clang/Rewrite/Rewriter.h>
+
+using namespace clang;
+
+namespace loplugin
+{
+
+/**
+ Class that manages all LO modules.
+*/
+class PluginHandler
+ : public ASTConsumer
+ {
+ public:
+ explicit PluginHandler( ASTContext& context )
+ : rewriter( context.getSourceManager(), context.getLangOpts())
+ {
+ }
+ virtual void HandleTranslationUnit( ASTContext& context )
+ {
+ if( context.getDiagnostics().hasErrorOccurred())
+ return;
+ // TODO also LO header files? or a subdir?
+ if( const RewriteBuffer* buf = rewriter.getRewriteBufferFor( context.getSourceManager().getMainFileID()))
+ buf->write( llvm::outs());
+ // TODO else write out the original file?
+ }
+ private:
+ Rewriter rewriter;
+ };
+
+/**
+ The Clang plugin class, just forwards to PluginHandler.
+*/
+class LibreOfficeAction
+ : public PluginASTAction
+ {
+ public:
+ virtual ASTConsumer* CreateASTConsumer( CompilerInstance& Compiler, StringRef InFile )
+ {
+ return new PluginHandler( Compiler.getASTContext());
+ }
+ virtual bool ParseArgs( const CompilerInstance& CI, const std::vector< std::string >& args )
+ {
+ return true;
+ }
+ };
+
+} // namespace
+
+static FrontendPluginRegistry::Add< loplugin::LibreOfficeAction > X( "loplugin", "LibreOffice compile check plugin" );
diff --git a/compilerplugins/clang/compileplugin.hxx b/compilerplugins/clang/compileplugin.hxx
new file mode 100644
index 000000000000..f7d5182b7b0f
--- /dev/null
+++ b/compilerplugins/clang/compileplugin.hxx
@@ -0,0 +1,14 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef COMPILEPLUGIN_H
+#define COMPILEPLUGIN_H
+
+#endif // COMPILEPLUGIN_H
diff --git a/config_host.mk.in b/config_host.mk.in
index 605d701c7727..5c0dcf2e6179 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -71,6 +71,7 @@ export COMMONS_HTTPCLIENT_JAR=@COMMONS_HTTPCLIENT_JAR@
export COMMONS_LANG_JAR=@COMMONS_LANG_JAR@
export COMMONS_LOGGING_JAR=@COMMONS_LOGGING_JAR@
export COMPATH=@COMPATH@
+export COMPILER_PLUGINS=@COMPILER_PLUGINS@
export COMP_ENV=@OUTPATH@
export COM_FOR_BUILD=@COM_FOR_BUILD@
export CPPUNIT_CFLAGS=@CPPUNIT_CFLAGS@
diff --git a/configure.in b/configure.in
index 5d37a667b2d8..8b29eb30d755 100644
--- a/configure.in
+++ b/configure.in
@@ -791,6 +791,11 @@ AC_ARG_ENABLE(dbgutil,
It is not possible to mix object files or libraries from a
--enable-dbgutil and a --disable-dbgutil build.]))
+AC_ARG_ENABLE(compiler-plugins,
+ AS_HELP_STRING([--enable-compiler-plugins],
+ [Enable compiler plugins that will perform additional checks during
+ building. Enabled automatically by --enable-dbgutil.]))
+
AC_ARG_ENABLE(linkoo,
AS_HELP_STRING([--disable-linkoo],
[Disable linkoo for the smoketest installation.]))
@@ -5024,6 +5029,40 @@ fi
AC_SUBST([VALGRIND_CFLAGS])
dnl ===================================================================
+dnl Compiler plugins
+dnl ===================================================================
+
+COMPILER_PLUGINS=
+# currently only Clang
+if test "$COM_GCC_IS_CLANG" = "TRUE"; then
+ if test -n "$enable_compiler_plugins"; then
+ compiler_plugins="$enable_compiler_plugins"
+ elif test -n "$enable_dbgutil" -a "$enable_dbgutil" != "no"; then
+ compiler_plugins=test
+ else
+ compiler_plugins=no
+ fi
+ if test "$compiler_plugins" != "no"; then
+ AC_LANG_PUSH([C++])
+ save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
+ AC_CHECK_HEADER(clang/AST/RecursiveASTVisitor.h,
+ [COMPILER_PLUGINS=TRUE],
+ [
+ if test "$compiler_plugins" = "yes"; then
+ AC_MSG_ERROR([Cannot find Clang headers to build compiler plugins.])
+ else
+ AC_MSG_WARN([Cannot find Clang headers to build compiler plugins, plugins disabled])
+ add_warning "Cannot find Clang headers to build compiler plugins, plugins disabled."
+ fi
+ ])
+ CPPFLAGS=$save_CPPFLAGS
+ AC_LANG_POP([C++])
+ fi
+fi
+AC_SUBST(COMPILER_PLUGINS)
+
+dnl ===================================================================
dnl Set the MinGW sys-root
dnl ===================================================================
if test "$WITH_MINGW" = "yes"; then
diff --git a/solenv/gbuild/platform/com_GCC_class.mk b/solenv/gbuild/platform/com_GCC_class.mk
index 630eed78c560..aa00267222f0 100644
--- a/solenv/gbuild/platform/com_GCC_class.mk
+++ b/solenv/gbuild/platform/com_GCC_class.mk
@@ -60,6 +60,7 @@ $(call gb_Helper_abbreviate_dirs,\
$(if $(filter Library,$(TARGETTYPE)),$(gb_Library_LTOFLAGS)) \
$(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
$(if $(WARNINGS_NOT_ERRORS),,$(gb_CFLAGS_WERROR)) \
+ $(if $(COMPILER_PLUGINS),$(gb_COMPILER_PLUGINS)) \
$(T_CFLAGS) \
-c $(3) \
-o $(1) \
@@ -82,6 +83,7 @@ $(call gb_Helper_abbreviate_dirs,\
$(if $(filter Library,$(TARGETTYPE)),$(gb_Library_LTOFLAGS)) \
$(if $(VISIBILITY),,$(gb_VISIBILITY_FLAGS)) \
$(if $(WARNINGS_NOT_ERRORS),,$(gb_CXXFLAGS_WERROR)) \
+ $(if $(COMPILER_PLUGINS),$(gb_COMPILER_PLUGINS)) \
$(T_CXXFLAGS) \
-c $(3) \
-o $(1) \
diff --git a/solenv/gbuild/platform/com_GCC_defs.mk b/solenv/gbuild/platform/com_GCC_defs.mk
index 1e349f0a8325..0cc32b52505b 100644
--- a/solenv/gbuild/platform/com_GCC_defs.mk
+++ b/solenv/gbuild/platform/com_GCC_defs.mk
@@ -153,6 +153,12 @@ gb_DEBUG_CXXFLAGS := $(FNO_DEFAULT_INLINE)
gb_LinkTarget_INCLUDE := $(filter-out %/stl, $(subst -I. , ,$(SOLARINC)))
gb_LinkTarget_INCLUDE_STL := $(filter %/stl, $(subst -I. , ,$(SOLARINC)))
+ifeq ($(COM_GCC_IS_CLANG),TRUE)
+gb_COMPILER_PLUGINS :=-Xclang -load -Xclang $(SRCDIR)/compilerplugins/obj/compileplugin.so -Xclang -add-plugin -Xclang loplugin
+else
+gb_COMPILER_PLUGINS :=
+endif
+
# Executable class
gb_Executable_EXT_for_build :=