X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FIncludeFile.h;h=a9319725d4775502d3d4c1ade7be85767a7cf267;hb=5eb301740c4ee5d978535caa917cc004733a7fca;hp=2e4f12dbbf8f574bd71acce409e73243816b6bf3;hpb=6df60a9effe4d20a48cfd9d105c0ab3c5dc3e690;p=oota-llvm.git diff --git a/include/llvm/Support/IncludeFile.h b/include/llvm/Support/IncludeFile.h index 2e4f12dbbf8..a9319725d47 100644 --- a/include/llvm/Support/IncludeFile.h +++ b/include/llvm/Support/IncludeFile.h @@ -2,18 +2,60 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Reid Spencer and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This file defines the IncludeFile class. +// This file defines the FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR +// macros. // //===----------------------------------------------------------------------===// -/// This class is used as a facility to make sure that the implementation of a -/// header file is included into a tool that uses the header. This is solely -/// to overcome problems linking .a files and not getting the implementation +#ifndef LLVM_SYSTEM_INCLUDEFILE_H +#define LLVM_SYSTEM_INCLUDEFILE_H + +/// This macro is the public interface that IncludeFile.h exports. This gives +/// us the option to implement the "link the definition" capability in any +/// manner that we choose. All header files that depend on a specific .cpp +/// file being linked at run time should use this macro instead of the +/// IncludeFile class directly. +/// +/// For example, foo.h would use:
+/// FORCE_DEFINING_FILE_TO_BE_LINKED(foo)
+/// +/// And, foo.cp would use:
+/// DEFINING_FILE_FOR(foo)
+#ifdef __GNUC__ +// If the `used' attribute is available, use it to create a variable +// with an initializer that will force the linking of the defining file. +#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \ + namespace llvm { \ + extern const char name ## LinkVar; \ + __attribute__((used)) static const char *const name ## LinkObj = \ + &name ## LinkVar; \ + } +#else +// Otherwise use a constructor call. +#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \ + namespace llvm { \ + extern const char name ## LinkVar; \ + static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \ + } +#endif + +/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should +/// be used in a .cpp file to define the name referenced in a header file that +/// will cause linkage of the .cpp file. It should only be used at extern level. +#define DEFINING_FILE_FOR(name) \ + namespace llvm { const char name ## LinkVar = 0; } + +namespace llvm { + +/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED +/// macro to make sure that the implementation of a header file is included +/// into a tool that uses the header. This is solely +/// to overcome problems linking .a files and not getting the implementation /// of compilation units we need. This is commonly an issue with the various /// Passes but also occurs elsewhere in LLVM. We like to use .a files because /// they link faster and provide the smallest executables. However, sometimes @@ -22,19 +64,16 @@ /// helps to resolve that problem. The basic strategy is to use this class in /// a header file and pass the address of a variable to the constructor. If the /// variable is defined in the header file's corresponding .cpp file then all -/// tools/libraries that #include the header file will require the .cpp as well. +/// tools/libraries that \#include the header file will require the .cpp as +/// well. /// For example:
/// extern int LinkMyCodeStub;
/// static IncludeFile LinkMyModule(&LinkMyCodeStub);
/// @brief Class to ensure linking of corresponding object file. - -#ifndef LLVM_SUPPORT_INCLUDEFILE_H -#define LLVM_SUPPORT_INCLUDEFILE_H - -namespace llvm { struct IncludeFile { - IncludeFile(void *); + explicit IncludeFile(const void *); }; + } #endif