1218885Sdim//===- llvm/Support/IncludeFile.h - Ensure Linking Of Library ---*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file defines the FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR 11218885Sdim// macros. 12218885Sdim// 13218885Sdim//===----------------------------------------------------------------------===// 14218885Sdim 15249423Sdim#ifndef LLVM_SUPPORT_INCLUDEFILE_H 16249423Sdim#define LLVM_SUPPORT_INCLUDEFILE_H 17218885Sdim 18218885Sdim/// This macro is the public interface that IncludeFile.h exports. This gives 19218885Sdim/// us the option to implement the "link the definition" capability in any 20218885Sdim/// manner that we choose. All header files that depend on a specific .cpp 21218885Sdim/// file being linked at run time should use this macro instead of the 22218885Sdim/// IncludeFile class directly. 23218885Sdim/// 24218885Sdim/// For example, foo.h would use:<br/> 25218885Sdim/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/> 26218885Sdim/// 27218885Sdim/// And, foo.cp would use:<br/> 28218885Sdim/// <tt>DEFINING_FILE_FOR(foo)</tt><br/> 29218885Sdim#ifdef __GNUC__ 30218885Sdim// If the `used' attribute is available, use it to create a variable 31218885Sdim// with an initializer that will force the linking of the defining file. 32218885Sdim#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \ 33218885Sdim namespace llvm { \ 34218885Sdim extern const char name ## LinkVar; \ 35218885Sdim __attribute__((used)) static const char *const name ## LinkObj = \ 36218885Sdim &name ## LinkVar; \ 37218885Sdim } 38218885Sdim#else 39218885Sdim// Otherwise use a constructor call. 40218885Sdim#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \ 41218885Sdim namespace llvm { \ 42218885Sdim extern const char name ## LinkVar; \ 43218885Sdim static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \ 44218885Sdim } 45218885Sdim#endif 46218885Sdim 47218885Sdim/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should 48218885Sdim/// be used in a .cpp file to define the name referenced in a header file that 49218885Sdim/// will cause linkage of the .cpp file. It should only be used at extern level. 50218885Sdim#define DEFINING_FILE_FOR(name) \ 51218885Sdim namespace llvm { const char name ## LinkVar = 0; } 52218885Sdim 53218885Sdimnamespace llvm { 54218885Sdim 55218885Sdim/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED 56218885Sdim/// macro to make sure that the implementation of a header file is included 57218885Sdim/// into a tool that uses the header. This is solely 58218885Sdim/// to overcome problems linking .a files and not getting the implementation 59218885Sdim/// of compilation units we need. This is commonly an issue with the various 60218885Sdim/// Passes but also occurs elsewhere in LLVM. We like to use .a files because 61218885Sdim/// they link faster and provide the smallest executables. However, sometimes 62218885Sdim/// those executables are too small, if the program doesn't reference something 63218885Sdim/// that might be needed, especially by a loaded share object. This little class 64218885Sdim/// helps to resolve that problem. The basic strategy is to use this class in 65218885Sdim/// a header file and pass the address of a variable to the constructor. If the 66218885Sdim/// variable is defined in the header file's corresponding .cpp file then all 67218885Sdim/// tools/libraries that \#include the header file will require the .cpp as 68218885Sdim/// well. 69218885Sdim/// For example:<br/> 70218885Sdim/// <tt>extern int LinkMyCodeStub;</tt><br/> 71218885Sdim/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/> 72218885Sdim/// @brief Class to ensure linking of corresponding object file. 73218885Sdimstruct IncludeFile { 74218885Sdim explicit IncludeFile(const void *); 75218885Sdim}; 76218885Sdim 77218885Sdim} 78218885Sdim 79218885Sdim#endif 80