LLVM API Documentation
00001 //===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements compile-time type-safe variadic functions. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ADT_VARIADICFUNCTION_H 00015 #define LLVM_ADT_VARIADICFUNCTION_H 00016 00017 #include "llvm/ADT/ArrayRef.h" 00018 00019 namespace llvm { 00020 00021 // Define macros to aid in expanding a comma separated series with the index of 00022 // the series pasted onto the last token. 00023 #define LLVM_COMMA_JOIN1(x) x ## 0 00024 #define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1 00025 #define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2 00026 #define LLVM_COMMA_JOIN4(x) LLVM_COMMA_JOIN3(x), x ## 3 00027 #define LLVM_COMMA_JOIN5(x) LLVM_COMMA_JOIN4(x), x ## 4 00028 #define LLVM_COMMA_JOIN6(x) LLVM_COMMA_JOIN5(x), x ## 5 00029 #define LLVM_COMMA_JOIN7(x) LLVM_COMMA_JOIN6(x), x ## 6 00030 #define LLVM_COMMA_JOIN8(x) LLVM_COMMA_JOIN7(x), x ## 7 00031 #define LLVM_COMMA_JOIN9(x) LLVM_COMMA_JOIN8(x), x ## 8 00032 #define LLVM_COMMA_JOIN10(x) LLVM_COMMA_JOIN9(x), x ## 9 00033 #define LLVM_COMMA_JOIN11(x) LLVM_COMMA_JOIN10(x), x ## 10 00034 #define LLVM_COMMA_JOIN12(x) LLVM_COMMA_JOIN11(x), x ## 11 00035 #define LLVM_COMMA_JOIN13(x) LLVM_COMMA_JOIN12(x), x ## 12 00036 #define LLVM_COMMA_JOIN14(x) LLVM_COMMA_JOIN13(x), x ## 13 00037 #define LLVM_COMMA_JOIN15(x) LLVM_COMMA_JOIN14(x), x ## 14 00038 #define LLVM_COMMA_JOIN16(x) LLVM_COMMA_JOIN15(x), x ## 15 00039 #define LLVM_COMMA_JOIN17(x) LLVM_COMMA_JOIN16(x), x ## 16 00040 #define LLVM_COMMA_JOIN18(x) LLVM_COMMA_JOIN17(x), x ## 17 00041 #define LLVM_COMMA_JOIN19(x) LLVM_COMMA_JOIN18(x), x ## 18 00042 #define LLVM_COMMA_JOIN20(x) LLVM_COMMA_JOIN19(x), x ## 19 00043 #define LLVM_COMMA_JOIN21(x) LLVM_COMMA_JOIN20(x), x ## 20 00044 #define LLVM_COMMA_JOIN22(x) LLVM_COMMA_JOIN21(x), x ## 21 00045 #define LLVM_COMMA_JOIN23(x) LLVM_COMMA_JOIN22(x), x ## 22 00046 #define LLVM_COMMA_JOIN24(x) LLVM_COMMA_JOIN23(x), x ## 23 00047 #define LLVM_COMMA_JOIN25(x) LLVM_COMMA_JOIN24(x), x ## 24 00048 #define LLVM_COMMA_JOIN26(x) LLVM_COMMA_JOIN25(x), x ## 25 00049 #define LLVM_COMMA_JOIN27(x) LLVM_COMMA_JOIN26(x), x ## 26 00050 #define LLVM_COMMA_JOIN28(x) LLVM_COMMA_JOIN27(x), x ## 27 00051 #define LLVM_COMMA_JOIN29(x) LLVM_COMMA_JOIN28(x), x ## 28 00052 #define LLVM_COMMA_JOIN30(x) LLVM_COMMA_JOIN29(x), x ## 29 00053 #define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30 00054 #define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31 00055 00056 /// \brief Class which can simulate a type-safe variadic function. 00057 /// 00058 /// The VariadicFunction class template makes it easy to define 00059 /// type-safe variadic functions where all arguments have the same 00060 /// type. 00061 /// 00062 /// Suppose we need a variadic function like this: 00063 /// 00064 /// ResultT Foo(const ArgT &A_0, const ArgT &A_1, ..., const ArgT &A_N); 00065 /// 00066 /// Instead of many overloads of Foo(), we only need to define a helper 00067 /// function that takes an array of arguments: 00068 /// 00069 /// ResultT FooImpl(ArrayRef<const ArgT *> Args) { 00070 /// // 'Args[i]' is a pointer to the i-th argument passed to Foo(). 00071 /// ... 00072 /// } 00073 /// 00074 /// and then define Foo() like this: 00075 /// 00076 /// const VariadicFunction<ResultT, ArgT, FooImpl> Foo; 00077 /// 00078 /// VariadicFunction takes care of defining the overloads of Foo(). 00079 /// 00080 /// Actually, Foo is a function object (i.e. functor) instead of a plain 00081 /// function. This object is stateless and its constructor/destructor 00082 /// does nothing, so it's safe to create global objects and call Foo(...) at 00083 /// any time. 00084 /// 00085 /// Sometimes we need a variadic function to have some fixed leading 00086 /// arguments whose types may be different from that of the optional 00087 /// arguments. For example: 00088 /// 00089 /// bool FullMatch(const StringRef &S, const RE &Regex, 00090 /// const ArgT &A_0, ..., const ArgT &A_N); 00091 /// 00092 /// VariadicFunctionN is for such cases, where N is the number of fixed 00093 /// arguments. It is like VariadicFunction, except that it takes N more 00094 /// template arguments for the types of the fixed arguments: 00095 /// 00096 /// bool FullMatchImpl(const StringRef &S, const RE &Regex, 00097 /// ArrayRef<const ArgT *> Args) { ... } 00098 /// const VariadicFunction2<bool, const StringRef&, 00099 /// const RE&, ArgT, FullMatchImpl> 00100 /// FullMatch; 00101 /// 00102 /// Currently VariadicFunction and friends support up-to 3 00103 /// fixed leading arguments and up-to 32 optional arguments. 00104 template <typename ResultT, typename ArgT, 00105 ResultT (*Func)(ArrayRef<const ArgT *>)> 00106 struct VariadicFunction { 00107 ResultT operator()() const { 00108 return Func(None); 00109 } 00110 00111 #define LLVM_DEFINE_OVERLOAD(N) \ 00112 ResultT operator()(LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \ 00113 const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \ 00114 return Func(makeArrayRef(Args)); \ 00115 } 00116 LLVM_DEFINE_OVERLOAD(1) 00117 LLVM_DEFINE_OVERLOAD(2) 00118 LLVM_DEFINE_OVERLOAD(3) 00119 LLVM_DEFINE_OVERLOAD(4) 00120 LLVM_DEFINE_OVERLOAD(5) 00121 LLVM_DEFINE_OVERLOAD(6) 00122 LLVM_DEFINE_OVERLOAD(7) 00123 LLVM_DEFINE_OVERLOAD(8) 00124 LLVM_DEFINE_OVERLOAD(9) 00125 LLVM_DEFINE_OVERLOAD(10) 00126 LLVM_DEFINE_OVERLOAD(11) 00127 LLVM_DEFINE_OVERLOAD(12) 00128 LLVM_DEFINE_OVERLOAD(13) 00129 LLVM_DEFINE_OVERLOAD(14) 00130 LLVM_DEFINE_OVERLOAD(15) 00131 LLVM_DEFINE_OVERLOAD(16) 00132 LLVM_DEFINE_OVERLOAD(17) 00133 LLVM_DEFINE_OVERLOAD(18) 00134 LLVM_DEFINE_OVERLOAD(19) 00135 LLVM_DEFINE_OVERLOAD(20) 00136 LLVM_DEFINE_OVERLOAD(21) 00137 LLVM_DEFINE_OVERLOAD(22) 00138 LLVM_DEFINE_OVERLOAD(23) 00139 LLVM_DEFINE_OVERLOAD(24) 00140 LLVM_DEFINE_OVERLOAD(25) 00141 LLVM_DEFINE_OVERLOAD(26) 00142 LLVM_DEFINE_OVERLOAD(27) 00143 LLVM_DEFINE_OVERLOAD(28) 00144 LLVM_DEFINE_OVERLOAD(29) 00145 LLVM_DEFINE_OVERLOAD(30) 00146 LLVM_DEFINE_OVERLOAD(31) 00147 LLVM_DEFINE_OVERLOAD(32) 00148 #undef LLVM_DEFINE_OVERLOAD 00149 }; 00150 00151 template <typename ResultT, typename Param0T, typename ArgT, 00152 ResultT (*Func)(Param0T, ArrayRef<const ArgT *>)> 00153 struct VariadicFunction1 { 00154 ResultT operator()(Param0T P0) const { 00155 return Func(P0, None); 00156 } 00157 00158 #define LLVM_DEFINE_OVERLOAD(N) \ 00159 ResultT operator()(Param0T P0, LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \ 00160 const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \ 00161 return Func(P0, makeArrayRef(Args)); \ 00162 } 00163 LLVM_DEFINE_OVERLOAD(1) 00164 LLVM_DEFINE_OVERLOAD(2) 00165 LLVM_DEFINE_OVERLOAD(3) 00166 LLVM_DEFINE_OVERLOAD(4) 00167 LLVM_DEFINE_OVERLOAD(5) 00168 LLVM_DEFINE_OVERLOAD(6) 00169 LLVM_DEFINE_OVERLOAD(7) 00170 LLVM_DEFINE_OVERLOAD(8) 00171 LLVM_DEFINE_OVERLOAD(9) 00172 LLVM_DEFINE_OVERLOAD(10) 00173 LLVM_DEFINE_OVERLOAD(11) 00174 LLVM_DEFINE_OVERLOAD(12) 00175 LLVM_DEFINE_OVERLOAD(13) 00176 LLVM_DEFINE_OVERLOAD(14) 00177 LLVM_DEFINE_OVERLOAD(15) 00178 LLVM_DEFINE_OVERLOAD(16) 00179 LLVM_DEFINE_OVERLOAD(17) 00180 LLVM_DEFINE_OVERLOAD(18) 00181 LLVM_DEFINE_OVERLOAD(19) 00182 LLVM_DEFINE_OVERLOAD(20) 00183 LLVM_DEFINE_OVERLOAD(21) 00184 LLVM_DEFINE_OVERLOAD(22) 00185 LLVM_DEFINE_OVERLOAD(23) 00186 LLVM_DEFINE_OVERLOAD(24) 00187 LLVM_DEFINE_OVERLOAD(25) 00188 LLVM_DEFINE_OVERLOAD(26) 00189 LLVM_DEFINE_OVERLOAD(27) 00190 LLVM_DEFINE_OVERLOAD(28) 00191 LLVM_DEFINE_OVERLOAD(29) 00192 LLVM_DEFINE_OVERLOAD(30) 00193 LLVM_DEFINE_OVERLOAD(31) 00194 LLVM_DEFINE_OVERLOAD(32) 00195 #undef LLVM_DEFINE_OVERLOAD 00196 }; 00197 00198 template <typename ResultT, typename Param0T, typename Param1T, typename ArgT, 00199 ResultT (*Func)(Param0T, Param1T, ArrayRef<const ArgT *>)> 00200 struct VariadicFunction2 { 00201 ResultT operator()(Param0T P0, Param1T P1) const { 00202 return Func(P0, P1, None); 00203 } 00204 00205 #define LLVM_DEFINE_OVERLOAD(N) \ 00206 ResultT operator()(Param0T P0, Param1T P1, \ 00207 LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \ 00208 const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \ 00209 return Func(P0, P1, makeArrayRef(Args)); \ 00210 } 00211 LLVM_DEFINE_OVERLOAD(1) 00212 LLVM_DEFINE_OVERLOAD(2) 00213 LLVM_DEFINE_OVERLOAD(3) 00214 LLVM_DEFINE_OVERLOAD(4) 00215 LLVM_DEFINE_OVERLOAD(5) 00216 LLVM_DEFINE_OVERLOAD(6) 00217 LLVM_DEFINE_OVERLOAD(7) 00218 LLVM_DEFINE_OVERLOAD(8) 00219 LLVM_DEFINE_OVERLOAD(9) 00220 LLVM_DEFINE_OVERLOAD(10) 00221 LLVM_DEFINE_OVERLOAD(11) 00222 LLVM_DEFINE_OVERLOAD(12) 00223 LLVM_DEFINE_OVERLOAD(13) 00224 LLVM_DEFINE_OVERLOAD(14) 00225 LLVM_DEFINE_OVERLOAD(15) 00226 LLVM_DEFINE_OVERLOAD(16) 00227 LLVM_DEFINE_OVERLOAD(17) 00228 LLVM_DEFINE_OVERLOAD(18) 00229 LLVM_DEFINE_OVERLOAD(19) 00230 LLVM_DEFINE_OVERLOAD(20) 00231 LLVM_DEFINE_OVERLOAD(21) 00232 LLVM_DEFINE_OVERLOAD(22) 00233 LLVM_DEFINE_OVERLOAD(23) 00234 LLVM_DEFINE_OVERLOAD(24) 00235 LLVM_DEFINE_OVERLOAD(25) 00236 LLVM_DEFINE_OVERLOAD(26) 00237 LLVM_DEFINE_OVERLOAD(27) 00238 LLVM_DEFINE_OVERLOAD(28) 00239 LLVM_DEFINE_OVERLOAD(29) 00240 LLVM_DEFINE_OVERLOAD(30) 00241 LLVM_DEFINE_OVERLOAD(31) 00242 LLVM_DEFINE_OVERLOAD(32) 00243 #undef LLVM_DEFINE_OVERLOAD 00244 }; 00245 00246 template <typename ResultT, typename Param0T, typename Param1T, 00247 typename Param2T, typename ArgT, 00248 ResultT (*Func)(Param0T, Param1T, Param2T, ArrayRef<const ArgT *>)> 00249 struct VariadicFunction3 { 00250 ResultT operator()(Param0T P0, Param1T P1, Param2T P2) const { 00251 return Func(P0, P1, P2, None); 00252 } 00253 00254 #define LLVM_DEFINE_OVERLOAD(N) \ 00255 ResultT operator()(Param0T P0, Param1T P1, Param2T P2, \ 00256 LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \ 00257 const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \ 00258 return Func(P0, P1, P2, makeArrayRef(Args)); \ 00259 } 00260 LLVM_DEFINE_OVERLOAD(1) 00261 LLVM_DEFINE_OVERLOAD(2) 00262 LLVM_DEFINE_OVERLOAD(3) 00263 LLVM_DEFINE_OVERLOAD(4) 00264 LLVM_DEFINE_OVERLOAD(5) 00265 LLVM_DEFINE_OVERLOAD(6) 00266 LLVM_DEFINE_OVERLOAD(7) 00267 LLVM_DEFINE_OVERLOAD(8) 00268 LLVM_DEFINE_OVERLOAD(9) 00269 LLVM_DEFINE_OVERLOAD(10) 00270 LLVM_DEFINE_OVERLOAD(11) 00271 LLVM_DEFINE_OVERLOAD(12) 00272 LLVM_DEFINE_OVERLOAD(13) 00273 LLVM_DEFINE_OVERLOAD(14) 00274 LLVM_DEFINE_OVERLOAD(15) 00275 LLVM_DEFINE_OVERLOAD(16) 00276 LLVM_DEFINE_OVERLOAD(17) 00277 LLVM_DEFINE_OVERLOAD(18) 00278 LLVM_DEFINE_OVERLOAD(19) 00279 LLVM_DEFINE_OVERLOAD(20) 00280 LLVM_DEFINE_OVERLOAD(21) 00281 LLVM_DEFINE_OVERLOAD(22) 00282 LLVM_DEFINE_OVERLOAD(23) 00283 LLVM_DEFINE_OVERLOAD(24) 00284 LLVM_DEFINE_OVERLOAD(25) 00285 LLVM_DEFINE_OVERLOAD(26) 00286 LLVM_DEFINE_OVERLOAD(27) 00287 LLVM_DEFINE_OVERLOAD(28) 00288 LLVM_DEFINE_OVERLOAD(29) 00289 LLVM_DEFINE_OVERLOAD(30) 00290 LLVM_DEFINE_OVERLOAD(31) 00291 LLVM_DEFINE_OVERLOAD(32) 00292 #undef LLVM_DEFINE_OVERLOAD 00293 }; 00294 00295 // Cleanup the macro namespace. 00296 #undef LLVM_COMMA_JOIN1 00297 #undef LLVM_COMMA_JOIN2 00298 #undef LLVM_COMMA_JOIN3 00299 #undef LLVM_COMMA_JOIN4 00300 #undef LLVM_COMMA_JOIN5 00301 #undef LLVM_COMMA_JOIN6 00302 #undef LLVM_COMMA_JOIN7 00303 #undef LLVM_COMMA_JOIN8 00304 #undef LLVM_COMMA_JOIN9 00305 #undef LLVM_COMMA_JOIN10 00306 #undef LLVM_COMMA_JOIN11 00307 #undef LLVM_COMMA_JOIN12 00308 #undef LLVM_COMMA_JOIN13 00309 #undef LLVM_COMMA_JOIN14 00310 #undef LLVM_COMMA_JOIN15 00311 #undef LLVM_COMMA_JOIN16 00312 #undef LLVM_COMMA_JOIN17 00313 #undef LLVM_COMMA_JOIN18 00314 #undef LLVM_COMMA_JOIN19 00315 #undef LLVM_COMMA_JOIN20 00316 #undef LLVM_COMMA_JOIN21 00317 #undef LLVM_COMMA_JOIN22 00318 #undef LLVM_COMMA_JOIN23 00319 #undef LLVM_COMMA_JOIN24 00320 #undef LLVM_COMMA_JOIN25 00321 #undef LLVM_COMMA_JOIN26 00322 #undef LLVM_COMMA_JOIN27 00323 #undef LLVM_COMMA_JOIN28 00324 #undef LLVM_COMMA_JOIN29 00325 #undef LLVM_COMMA_JOIN30 00326 #undef LLVM_COMMA_JOIN31 00327 #undef LLVM_COMMA_JOIN32 00328 00329 } // end namespace llvm 00330 00331 #endif // LLVM_ADT_VARIADICFUNCTION_H