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
This commit is contained in:
Luboš Luňák 2012-10-05 18:17:13 +02:00
parent 7b34748b1b
commit 02a8d36ebf
12 changed files with 277 additions and 2 deletions

View File

@ -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 $@

1
compilerplugins/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
obj

23
compilerplugins/Makefile Normal file
View File

@ -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:

View File

@ -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:

View File

@ -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:

27
compilerplugins/README Normal file
View File

@ -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

View File

@ -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" );

View File

@ -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

View File

@ -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@

View File

@ -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.]))
@ -5023,6 +5028,40 @@ if test "$cross_compiling" != "yes" -a "$enable_dbgutil" != "no" -a \
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 ===================================================================

View File

@ -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) \

View File

@ -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 :=