mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-26 18:20:39 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172025 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			332 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			332 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| //  This file implements compile-time type-safe variadic functions.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_ADT_VARIADICFUNCTION_H
 | |
| #define LLVM_ADT_VARIADICFUNCTION_H
 | |
| 
 | |
| #include "llvm/ADT/ArrayRef.h"
 | |
| 
 | |
| namespace llvm {
 | |
| 
 | |
| // Define macros to aid in expanding a comma separated series with the index of
 | |
| // the series pasted onto the last token.
 | |
| #define LLVM_COMMA_JOIN1(x) x ## 0
 | |
| #define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1
 | |
| #define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2
 | |
| #define LLVM_COMMA_JOIN4(x) LLVM_COMMA_JOIN3(x), x ## 3
 | |
| #define LLVM_COMMA_JOIN5(x) LLVM_COMMA_JOIN4(x), x ## 4
 | |
| #define LLVM_COMMA_JOIN6(x) LLVM_COMMA_JOIN5(x), x ## 5
 | |
| #define LLVM_COMMA_JOIN7(x) LLVM_COMMA_JOIN6(x), x ## 6
 | |
| #define LLVM_COMMA_JOIN8(x) LLVM_COMMA_JOIN7(x), x ## 7
 | |
| #define LLVM_COMMA_JOIN9(x) LLVM_COMMA_JOIN8(x), x ## 8
 | |
| #define LLVM_COMMA_JOIN10(x) LLVM_COMMA_JOIN9(x), x ## 9
 | |
| #define LLVM_COMMA_JOIN11(x) LLVM_COMMA_JOIN10(x), x ## 10
 | |
| #define LLVM_COMMA_JOIN12(x) LLVM_COMMA_JOIN11(x), x ## 11
 | |
| #define LLVM_COMMA_JOIN13(x) LLVM_COMMA_JOIN12(x), x ## 12
 | |
| #define LLVM_COMMA_JOIN14(x) LLVM_COMMA_JOIN13(x), x ## 13
 | |
| #define LLVM_COMMA_JOIN15(x) LLVM_COMMA_JOIN14(x), x ## 14
 | |
| #define LLVM_COMMA_JOIN16(x) LLVM_COMMA_JOIN15(x), x ## 15
 | |
| #define LLVM_COMMA_JOIN17(x) LLVM_COMMA_JOIN16(x), x ## 16
 | |
| #define LLVM_COMMA_JOIN18(x) LLVM_COMMA_JOIN17(x), x ## 17
 | |
| #define LLVM_COMMA_JOIN19(x) LLVM_COMMA_JOIN18(x), x ## 18
 | |
| #define LLVM_COMMA_JOIN20(x) LLVM_COMMA_JOIN19(x), x ## 19
 | |
| #define LLVM_COMMA_JOIN21(x) LLVM_COMMA_JOIN20(x), x ## 20
 | |
| #define LLVM_COMMA_JOIN22(x) LLVM_COMMA_JOIN21(x), x ## 21
 | |
| #define LLVM_COMMA_JOIN23(x) LLVM_COMMA_JOIN22(x), x ## 22
 | |
| #define LLVM_COMMA_JOIN24(x) LLVM_COMMA_JOIN23(x), x ## 23
 | |
| #define LLVM_COMMA_JOIN25(x) LLVM_COMMA_JOIN24(x), x ## 24
 | |
| #define LLVM_COMMA_JOIN26(x) LLVM_COMMA_JOIN25(x), x ## 25
 | |
| #define LLVM_COMMA_JOIN27(x) LLVM_COMMA_JOIN26(x), x ## 26
 | |
| #define LLVM_COMMA_JOIN28(x) LLVM_COMMA_JOIN27(x), x ## 27
 | |
| #define LLVM_COMMA_JOIN29(x) LLVM_COMMA_JOIN28(x), x ## 28
 | |
| #define LLVM_COMMA_JOIN30(x) LLVM_COMMA_JOIN29(x), x ## 29
 | |
| #define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30
 | |
| #define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31
 | |
| 
 | |
| /// \brief Class which can simulate a type-safe variadic function.
 | |
| ///
 | |
| /// The VariadicFunction class template makes it easy to define
 | |
| /// type-safe variadic functions where all arguments have the same
 | |
| /// type.
 | |
| ///
 | |
| /// Suppose we need a variadic function like this:
 | |
| ///
 | |
| ///   ResultT Foo(const ArgT &A_0, const ArgT &A_1, ..., const ArgT &A_N);
 | |
| ///
 | |
| /// Instead of many overloads of Foo(), we only need to define a helper
 | |
| /// function that takes an array of arguments:
 | |
| ///
 | |
| ///   ResultT FooImpl(ArrayRef<const ArgT *> Args) {
 | |
| ///     // 'Args[i]' is a pointer to the i-th argument passed to Foo().
 | |
| ///     ...
 | |
| ///   }
 | |
| ///
 | |
| /// and then define Foo() like this:
 | |
| ///
 | |
| ///   const VariadicFunction<ResultT, ArgT, FooImpl> Foo;
 | |
| ///
 | |
| /// VariadicFunction takes care of defining the overloads of Foo().
 | |
| ///
 | |
| /// Actually, Foo is a function object (i.e. functor) instead of a plain
 | |
| /// function.  This object is stateless and its constructor/destructor
 | |
| /// does nothing, so it's safe to create global objects and call Foo(...) at
 | |
| /// any time.
 | |
| ///
 | |
| /// Sometimes we need a variadic function to have some fixed leading
 | |
| /// arguments whose types may be different from that of the optional
 | |
| /// arguments.  For example:
 | |
| ///
 | |
| ///   bool FullMatch(const StringRef &S, const RE &Regex,
 | |
| ///                  const ArgT &A_0, ..., const ArgT &A_N);
 | |
| ///
 | |
| /// VariadicFunctionN is for such cases, where N is the number of fixed
 | |
| /// arguments.  It is like VariadicFunction, except that it takes N more
 | |
| /// template arguments for the types of the fixed arguments:
 | |
| ///
 | |
| ///   bool FullMatchImpl(const StringRef &S, const RE &Regex,
 | |
| ///                      ArrayRef<const ArgT *> Args) { ... }
 | |
| ///   const VariadicFunction2<bool, const StringRef&,
 | |
| ///                           const RE&, ArgT, FullMatchImpl>
 | |
| ///       FullMatch;
 | |
| ///
 | |
| /// Currently VariadicFunction and friends support up-to 3
 | |
| /// fixed leading arguments and up-to 32 optional arguments.
 | |
| template <typename ResultT, typename ArgT,
 | |
|           ResultT (*Func)(ArrayRef<const ArgT *>)>
 | |
| struct VariadicFunction {
 | |
|   ResultT operator()() const {
 | |
|     return Func(ArrayRef<const ArgT *>());
 | |
|   }
 | |
| 
 | |
| #define LLVM_DEFINE_OVERLOAD(N) \
 | |
|   ResultT operator()(LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
 | |
|     const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
 | |
|     return Func(makeArrayRef(Args)); \
 | |
|   }
 | |
|   LLVM_DEFINE_OVERLOAD(1)
 | |
|   LLVM_DEFINE_OVERLOAD(2)
 | |
|   LLVM_DEFINE_OVERLOAD(3)
 | |
|   LLVM_DEFINE_OVERLOAD(4)
 | |
|   LLVM_DEFINE_OVERLOAD(5)
 | |
|   LLVM_DEFINE_OVERLOAD(6)
 | |
|   LLVM_DEFINE_OVERLOAD(7)
 | |
|   LLVM_DEFINE_OVERLOAD(8)
 | |
|   LLVM_DEFINE_OVERLOAD(9)
 | |
|   LLVM_DEFINE_OVERLOAD(10)
 | |
|   LLVM_DEFINE_OVERLOAD(11)
 | |
|   LLVM_DEFINE_OVERLOAD(12)
 | |
|   LLVM_DEFINE_OVERLOAD(13)
 | |
|   LLVM_DEFINE_OVERLOAD(14)
 | |
|   LLVM_DEFINE_OVERLOAD(15)
 | |
|   LLVM_DEFINE_OVERLOAD(16)
 | |
|   LLVM_DEFINE_OVERLOAD(17)
 | |
|   LLVM_DEFINE_OVERLOAD(18)
 | |
|   LLVM_DEFINE_OVERLOAD(19)
 | |
|   LLVM_DEFINE_OVERLOAD(20)
 | |
|   LLVM_DEFINE_OVERLOAD(21)
 | |
|   LLVM_DEFINE_OVERLOAD(22)
 | |
|   LLVM_DEFINE_OVERLOAD(23)
 | |
|   LLVM_DEFINE_OVERLOAD(24)
 | |
|   LLVM_DEFINE_OVERLOAD(25)
 | |
|   LLVM_DEFINE_OVERLOAD(26)
 | |
|   LLVM_DEFINE_OVERLOAD(27)
 | |
|   LLVM_DEFINE_OVERLOAD(28)
 | |
|   LLVM_DEFINE_OVERLOAD(29)
 | |
|   LLVM_DEFINE_OVERLOAD(30)
 | |
|   LLVM_DEFINE_OVERLOAD(31)
 | |
|   LLVM_DEFINE_OVERLOAD(32)
 | |
| #undef LLVM_DEFINE_OVERLOAD
 | |
| };
 | |
| 
 | |
| template <typename ResultT, typename Param0T, typename ArgT,
 | |
|           ResultT (*Func)(Param0T, ArrayRef<const ArgT *>)>
 | |
| struct VariadicFunction1 {
 | |
|   ResultT operator()(Param0T P0) const {
 | |
|     return Func(P0, ArrayRef<const ArgT *>());
 | |
|   }
 | |
| 
 | |
| #define LLVM_DEFINE_OVERLOAD(N) \
 | |
|   ResultT operator()(Param0T P0, LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
 | |
|     const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
 | |
|     return Func(P0, makeArrayRef(Args)); \
 | |
|   }
 | |
|   LLVM_DEFINE_OVERLOAD(1)
 | |
|   LLVM_DEFINE_OVERLOAD(2)
 | |
|   LLVM_DEFINE_OVERLOAD(3)
 | |
|   LLVM_DEFINE_OVERLOAD(4)
 | |
|   LLVM_DEFINE_OVERLOAD(5)
 | |
|   LLVM_DEFINE_OVERLOAD(6)
 | |
|   LLVM_DEFINE_OVERLOAD(7)
 | |
|   LLVM_DEFINE_OVERLOAD(8)
 | |
|   LLVM_DEFINE_OVERLOAD(9)
 | |
|   LLVM_DEFINE_OVERLOAD(10)
 | |
|   LLVM_DEFINE_OVERLOAD(11)
 | |
|   LLVM_DEFINE_OVERLOAD(12)
 | |
|   LLVM_DEFINE_OVERLOAD(13)
 | |
|   LLVM_DEFINE_OVERLOAD(14)
 | |
|   LLVM_DEFINE_OVERLOAD(15)
 | |
|   LLVM_DEFINE_OVERLOAD(16)
 | |
|   LLVM_DEFINE_OVERLOAD(17)
 | |
|   LLVM_DEFINE_OVERLOAD(18)
 | |
|   LLVM_DEFINE_OVERLOAD(19)
 | |
|   LLVM_DEFINE_OVERLOAD(20)
 | |
|   LLVM_DEFINE_OVERLOAD(21)
 | |
|   LLVM_DEFINE_OVERLOAD(22)
 | |
|   LLVM_DEFINE_OVERLOAD(23)
 | |
|   LLVM_DEFINE_OVERLOAD(24)
 | |
|   LLVM_DEFINE_OVERLOAD(25)
 | |
|   LLVM_DEFINE_OVERLOAD(26)
 | |
|   LLVM_DEFINE_OVERLOAD(27)
 | |
|   LLVM_DEFINE_OVERLOAD(28)
 | |
|   LLVM_DEFINE_OVERLOAD(29)
 | |
|   LLVM_DEFINE_OVERLOAD(30)
 | |
|   LLVM_DEFINE_OVERLOAD(31)
 | |
|   LLVM_DEFINE_OVERLOAD(32)
 | |
| #undef LLVM_DEFINE_OVERLOAD
 | |
| };
 | |
| 
 | |
| template <typename ResultT, typename Param0T, typename Param1T, typename ArgT,
 | |
|           ResultT (*Func)(Param0T, Param1T, ArrayRef<const ArgT *>)>
 | |
| struct VariadicFunction2 {
 | |
|   ResultT operator()(Param0T P0, Param1T P1) const {
 | |
|     return Func(P0, P1, ArrayRef<const ArgT *>());
 | |
|   }
 | |
| 
 | |
| #define LLVM_DEFINE_OVERLOAD(N) \
 | |
|   ResultT operator()(Param0T P0, Param1T P1, \
 | |
|                      LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
 | |
|     const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
 | |
|     return Func(P0, P1, makeArrayRef(Args)); \
 | |
|   }
 | |
|   LLVM_DEFINE_OVERLOAD(1)
 | |
|   LLVM_DEFINE_OVERLOAD(2)
 | |
|   LLVM_DEFINE_OVERLOAD(3)
 | |
|   LLVM_DEFINE_OVERLOAD(4)
 | |
|   LLVM_DEFINE_OVERLOAD(5)
 | |
|   LLVM_DEFINE_OVERLOAD(6)
 | |
|   LLVM_DEFINE_OVERLOAD(7)
 | |
|   LLVM_DEFINE_OVERLOAD(8)
 | |
|   LLVM_DEFINE_OVERLOAD(9)
 | |
|   LLVM_DEFINE_OVERLOAD(10)
 | |
|   LLVM_DEFINE_OVERLOAD(11)
 | |
|   LLVM_DEFINE_OVERLOAD(12)
 | |
|   LLVM_DEFINE_OVERLOAD(13)
 | |
|   LLVM_DEFINE_OVERLOAD(14)
 | |
|   LLVM_DEFINE_OVERLOAD(15)
 | |
|   LLVM_DEFINE_OVERLOAD(16)
 | |
|   LLVM_DEFINE_OVERLOAD(17)
 | |
|   LLVM_DEFINE_OVERLOAD(18)
 | |
|   LLVM_DEFINE_OVERLOAD(19)
 | |
|   LLVM_DEFINE_OVERLOAD(20)
 | |
|   LLVM_DEFINE_OVERLOAD(21)
 | |
|   LLVM_DEFINE_OVERLOAD(22)
 | |
|   LLVM_DEFINE_OVERLOAD(23)
 | |
|   LLVM_DEFINE_OVERLOAD(24)
 | |
|   LLVM_DEFINE_OVERLOAD(25)
 | |
|   LLVM_DEFINE_OVERLOAD(26)
 | |
|   LLVM_DEFINE_OVERLOAD(27)
 | |
|   LLVM_DEFINE_OVERLOAD(28)
 | |
|   LLVM_DEFINE_OVERLOAD(29)
 | |
|   LLVM_DEFINE_OVERLOAD(30)
 | |
|   LLVM_DEFINE_OVERLOAD(31)
 | |
|   LLVM_DEFINE_OVERLOAD(32)
 | |
| #undef LLVM_DEFINE_OVERLOAD
 | |
| };
 | |
| 
 | |
| template <typename ResultT, typename Param0T, typename Param1T,
 | |
|           typename Param2T, typename ArgT,
 | |
|           ResultT (*Func)(Param0T, Param1T, Param2T, ArrayRef<const ArgT *>)>
 | |
| struct VariadicFunction3 {
 | |
|   ResultT operator()(Param0T P0, Param1T P1, Param2T P2) const {
 | |
|     return Func(P0, P1, P2, ArrayRef<const ArgT *>());
 | |
|   }
 | |
| 
 | |
| #define LLVM_DEFINE_OVERLOAD(N) \
 | |
|   ResultT operator()(Param0T P0, Param1T P1, Param2T P2, \
 | |
|                      LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
 | |
|     const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
 | |
|     return Func(P0, P1, P2, makeArrayRef(Args)); \
 | |
|   }
 | |
|   LLVM_DEFINE_OVERLOAD(1)
 | |
|   LLVM_DEFINE_OVERLOAD(2)
 | |
|   LLVM_DEFINE_OVERLOAD(3)
 | |
|   LLVM_DEFINE_OVERLOAD(4)
 | |
|   LLVM_DEFINE_OVERLOAD(5)
 | |
|   LLVM_DEFINE_OVERLOAD(6)
 | |
|   LLVM_DEFINE_OVERLOAD(7)
 | |
|   LLVM_DEFINE_OVERLOAD(8)
 | |
|   LLVM_DEFINE_OVERLOAD(9)
 | |
|   LLVM_DEFINE_OVERLOAD(10)
 | |
|   LLVM_DEFINE_OVERLOAD(11)
 | |
|   LLVM_DEFINE_OVERLOAD(12)
 | |
|   LLVM_DEFINE_OVERLOAD(13)
 | |
|   LLVM_DEFINE_OVERLOAD(14)
 | |
|   LLVM_DEFINE_OVERLOAD(15)
 | |
|   LLVM_DEFINE_OVERLOAD(16)
 | |
|   LLVM_DEFINE_OVERLOAD(17)
 | |
|   LLVM_DEFINE_OVERLOAD(18)
 | |
|   LLVM_DEFINE_OVERLOAD(19)
 | |
|   LLVM_DEFINE_OVERLOAD(20)
 | |
|   LLVM_DEFINE_OVERLOAD(21)
 | |
|   LLVM_DEFINE_OVERLOAD(22)
 | |
|   LLVM_DEFINE_OVERLOAD(23)
 | |
|   LLVM_DEFINE_OVERLOAD(24)
 | |
|   LLVM_DEFINE_OVERLOAD(25)
 | |
|   LLVM_DEFINE_OVERLOAD(26)
 | |
|   LLVM_DEFINE_OVERLOAD(27)
 | |
|   LLVM_DEFINE_OVERLOAD(28)
 | |
|   LLVM_DEFINE_OVERLOAD(29)
 | |
|   LLVM_DEFINE_OVERLOAD(30)
 | |
|   LLVM_DEFINE_OVERLOAD(31)
 | |
|   LLVM_DEFINE_OVERLOAD(32)
 | |
| #undef LLVM_DEFINE_OVERLOAD
 | |
| };
 | |
| 
 | |
| // Cleanup the macro namespace.
 | |
| #undef LLVM_COMMA_JOIN1
 | |
| #undef LLVM_COMMA_JOIN2
 | |
| #undef LLVM_COMMA_JOIN3
 | |
| #undef LLVM_COMMA_JOIN4
 | |
| #undef LLVM_COMMA_JOIN5
 | |
| #undef LLVM_COMMA_JOIN6
 | |
| #undef LLVM_COMMA_JOIN7
 | |
| #undef LLVM_COMMA_JOIN8
 | |
| #undef LLVM_COMMA_JOIN9
 | |
| #undef LLVM_COMMA_JOIN10
 | |
| #undef LLVM_COMMA_JOIN11
 | |
| #undef LLVM_COMMA_JOIN12
 | |
| #undef LLVM_COMMA_JOIN13
 | |
| #undef LLVM_COMMA_JOIN14
 | |
| #undef LLVM_COMMA_JOIN15
 | |
| #undef LLVM_COMMA_JOIN16
 | |
| #undef LLVM_COMMA_JOIN17
 | |
| #undef LLVM_COMMA_JOIN18
 | |
| #undef LLVM_COMMA_JOIN19
 | |
| #undef LLVM_COMMA_JOIN20
 | |
| #undef LLVM_COMMA_JOIN21
 | |
| #undef LLVM_COMMA_JOIN22
 | |
| #undef LLVM_COMMA_JOIN23
 | |
| #undef LLVM_COMMA_JOIN24
 | |
| #undef LLVM_COMMA_JOIN25
 | |
| #undef LLVM_COMMA_JOIN26
 | |
| #undef LLVM_COMMA_JOIN27
 | |
| #undef LLVM_COMMA_JOIN28
 | |
| #undef LLVM_COMMA_JOIN29
 | |
| #undef LLVM_COMMA_JOIN30
 | |
| #undef LLVM_COMMA_JOIN31
 | |
| #undef LLVM_COMMA_JOIN32
 | |
| 
 | |
| } // end namespace llvm
 | |
| 
 | |
| #endif  // LLVM_ADT_VARIADICFUNCTION_H
 |