diff --git a/Makefile.rules b/Makefile.rules index 9325ca4b5d1..c706bed68ae 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -198,6 +198,7 @@ install-bytecode:: install-bytecode-local ifdef LLVMC_PLUGIN LIBRARYNAME := $(patsubst %,plugin_llvmc_%,$(LLVMC_PLUGIN)) +CPP.Flags += -DLLVMC_PLUGIN_NAME=$(LLVMC_PLUGIN) REQUIRES_EH := 1 # Build a dynamic library if the user runs `make` directly from the plugin diff --git a/include/llvm/CompilerDriver/ForceLinkage.h b/include/llvm/CompilerDriver/ForceLinkage.h new file mode 100644 index 00000000000..58ea16710e4 --- /dev/null +++ b/include/llvm/CompilerDriver/ForceLinkage.h @@ -0,0 +1,82 @@ +//===--- ForceLinkage.h - The LLVM Compiler Driver --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// A bit of preprocessor magic to force references to static libraries. Needed +// because plugin initialization is done via static variables. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H +#define LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H + +#include "llvm/CompilerDriver/ForceLinkageMacros.h" + +namespace llvmc { + +// Declare all ForceLinkage$(PluginName) functions. + +#ifdef LLVMC_BUILTIN_PLUGIN_1 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_1); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_2 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_2); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_3 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_3); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_4 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_4); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_5 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_5); +#endif + +namespace force_linkage { + + struct LinkageForcer { + + LinkageForcer() { + +// Call all ForceLinkage$(PluginName) functions. +#ifdef LLVMC_BUILTIN_PLUGIN_1 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_1); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_2 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_2); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_3 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_3); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_4 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_4); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_5 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_5); +#endif + + } + }; +} // End namespace force_linkage. + +// The only externally used bit. +void ForceLinkage() { + force_linkage::LinkageForcer dummy; +} + +} // End namespace llvmc. + +#endif // LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H diff --git a/include/llvm/CompilerDriver/ForceLinkageMacros.h b/include/llvm/CompilerDriver/ForceLinkageMacros.h new file mode 100644 index 00000000000..8862b008234 --- /dev/null +++ b/include/llvm/CompilerDriver/ForceLinkageMacros.h @@ -0,0 +1,29 @@ +//===--- ForceLinkageMacros.h - The LLVM Compiler Driver --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Preprocessor magic that forces references to static libraries - common +// macros used by both driver and plugins. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H +#define LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H + +#define LLVMC_FORCE_LINKAGE_PREFIX(PluginName) ForceLinkage ## PluginName + +#define LLVMC_FORCE_LINKAGE_FUN(PluginName) \ + LLVMC_FORCE_LINKAGE_PREFIX(PluginName) + +#define LLVMC_FORCE_LINKAGE_DECL(PluginName) \ + void LLVMC_FORCE_LINKAGE_FUN(PluginName) () + +#define LLVMC_FORCE_LINKAGE_CALL(PluginName) \ + LLVMC_FORCE_LINKAGE_FUN(PluginName) () + +#endif // LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H diff --git a/include/llvm/CompilerDriver/Main.inc b/include/llvm/CompilerDriver/Main.inc index e81acf14476..638189387c2 100644 --- a/include/llvm/CompilerDriver/Main.inc +++ b/include/llvm/CompilerDriver/Main.inc @@ -19,6 +19,7 @@ #include "llvm/CompilerDriver/CompilationGraph.h" #include "llvm/CompilerDriver/Error.h" +#include "llvm/CompilerDriver/ForceLinkage.h" #include "llvm/CompilerDriver/Plugin.h" #include "llvm/System/Path.h" @@ -85,6 +86,8 @@ namespace { int main(int argc, char** argv) { try { + ForceLinkage(); + LanguageMap langMap; CompilationGraph graph; diff --git a/tools/llvmc/driver/Makefile b/tools/llvmc/driver/Makefile index 5f5ec533dd0..67fc996ba6f 100644 --- a/tools/llvmc/driver/Makefile +++ b/tools/llvmc/driver/Makefile @@ -8,15 +8,46 @@ ##===----------------------------------------------------------------------===## LEVEL = ../../.. +include $(LEVEL)/Makefile.config TOOLNAME = $(LLVMC_BASED_DRIVER_NAME) LLVMLIBS = CompilerDriver.a - -ifneq ($(LLVMC_BUILTIN_PLUGINS),) -USEDLIBS += $(patsubst %,plugin_llvmc_%.a,$(LLVMC_BUILTIN_PLUGINS)) -endif - LINK_COMPONENTS = support system REQUIRES_EH := 1 +# Preprocessor magic that generates references to static variables in built-in +# plugins. +# TODO: Move this to Makefile.rules? (also used by examples/{Skeleton, mcc16}) +ifneq ($(LLVMC_BUILTIN_PLUGINS),) + +USEDLIBS += $(patsubst %,plugin_llvmc_%.a,$(LLVMC_BUILTIN_PLUGINS)) + +LLVMC_BUILTIN_PLUGIN_1 = $(word 1, $(LLVMC_BUILTIN_PLUGINS)) +LLVMC_BUILTIN_PLUGIN_2 = $(word 2, $(LLVMC_BUILTIN_PLUGINS)) +LLVMC_BUILTIN_PLUGIN_3 = $(word 3, $(LLVMC_BUILTIN_PLUGINS)) +LLVMC_BUILTIN_PLUGIN_4 = $(word 4, $(LLVMC_BUILTIN_PLUGINS)) +LLVMC_BUILTIN_PLUGIN_5 = $(word 5, $(LLVMC_BUILTIN_PLUGINS)) + +ifneq ($(LLVMC_BUILTIN_PLUGIN_1),) +CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_1=$(LLVMC_BUILTIN_PLUGIN_1) +endif + +ifneq ($(LLVMC_BUILTIN_PLUGIN_2),) +CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_2=$(LLVMC_BUILTIN_PLUGIN_2) +endif + +ifneq ($(LLVMC_BUILTIN_PLUGIN_3),) +CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_3=$(LLVMC_BUILTIN_PLUGIN_3) +endif + +ifneq ($(LLVMC_BUILTIN_PLUGIN_4),) +CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_4=$(LLVMC_BUILTIN_PLUGIN_4) +endif + +ifneq ($(LLVMC_BUILTIN_PLUGIN_5),) +CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_5=$(LLVMC_BUILTIN_PLUGIN_5) +endif + +endif + include $(LEVEL)/Makefile.common diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 36f094d3261..e9acd9668cc 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -1984,6 +1984,7 @@ void EmitRegisterPlugin(int Priority, std::ostream& O) { /// additional declarations. void EmitIncludes(std::ostream& O) { O << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n" + << "#include \"llvm/CompilerDriver/ForceLinkageMacros.h\"\n" << "#include \"llvm/CompilerDriver/Plugin.h\"\n" << "#include \"llvm/CompilerDriver/Tool.h\"\n\n" @@ -2106,7 +2107,13 @@ void EmitPluginCode(const PluginData& Data, std::ostream& O) { // Emit code for plugin registration. EmitRegisterPlugin(Data.Priority, O); - O << "} // End anonymous namespace.\n"; + O << "} // End anonymous namespace.\n\n"; + + // Force linkage magic. + O << "namespace llvmc {\n"; + O << "LLVMC_FORCE_LINKAGE_DECL(LLVMC_PLUGIN_NAME) {}\n"; + O << "}\n"; + // EOF }