From e38003f8399531b00e9fc8e9c6cfe311bc3ad4fb Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Tue, 9 May 2017 19:31:13 +0000 Subject: Suppress all uses of LLVM_END_WITH_NULL. NFC. Use variadic templates instead of relying on + sentinel. This enforces better type checking and makes code more readable. Differential Revision: https://reviews.llvm.org/D32541 llvm-svn: 302571 --- llvm/include/llvm/ADT/STLExtras.h | 12 ++++++++++++ llvm/include/llvm/IR/Constants.h | 10 +++++++++- llvm/include/llvm/IR/DerivedTypes.h | 29 ++++++++++++++++++++++++++--- llvm/include/llvm/Support/Compiler.h | 6 ------ 4 files changed, 47 insertions(+), 10 deletions(-) (limited to 'llvm/include') diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index 86cc28458df..8c28412bb60 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -706,6 +706,18 @@ struct is_one_of { std::is_same::value || is_one_of::value; }; +/// \brief traits class for checking whether type T is a base class for all +/// the given types in the variadic list. +template struct are_base_of { + static const bool value = true; +}; + +template +struct are_base_of { + static const bool value = + std::is_base_of::value && are_base_of::value; +}; + //===----------------------------------------------------------------------===// // Extra additions for arrays //===----------------------------------------------------------------------===// diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index ad83b21c7bf..a4dee43d21b 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -26,6 +26,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Constant.h" #include "llvm/IR/DerivedTypes.h" @@ -452,7 +453,14 @@ class ConstantStruct final : public ConstantAggregate { public: // ConstantStruct accessors static Constant *get(StructType *T, ArrayRef V); - static Constant *get(StructType *T, ...) LLVM_END_WITH_NULL; + + template + static typename std::enable_if::value, + Constant *>::type + get(StructType *T, Csts *... Vs) { + SmallVector Values{{Vs...}}; + return get(T, Values); + } /// Return an anonymous struct that has the specified elements. /// If the struct is possibly empty, then you must specify a context. diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h index 05e99157b8d..82b5eb834c8 100644 --- a/llvm/include/llvm/IR/DerivedTypes.h +++ b/llvm/include/llvm/IR/DerivedTypes.h @@ -19,6 +19,7 @@ #define LLVM_IR_DERIVEDTYPES_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Type.h" #include "llvm/Support/Casting.h" @@ -228,7 +229,14 @@ public: static StructType *create(LLVMContext &Context, ArrayRef Elements, StringRef Name, bool isPacked = false); static StructType *create(LLVMContext &Context, ArrayRef Elements); - static StructType *create(StringRef Name, Type *elt1, ...) LLVM_END_WITH_NULL; + template + static typename std::enable_if::value, + StructType *>::type + create(StringRef Name, Type *elt1, Tys *... elts) { + assert(elt1 && "Cannot create a struct type with no elements with this"); + SmallVector StructFields{{elt1, elts...}}; + return create(StructFields, Name); + } /// This static method is the primary way to create a literal StructType. static StructType *get(LLVMContext &Context, ArrayRef Elements, @@ -240,7 +248,15 @@ public: /// This static method is a convenience method for creating structure types by /// specifying the elements as arguments. Note that this method always returns /// a non-packed struct, and requires at least one element type. - static StructType *get(Type *elt1, ...) LLVM_END_WITH_NULL; + template + static typename std::enable_if::value, + StructType *>::type + get(Type *elt1, Tys *... elts) { + assert(elt1 && "Cannot create a struct type with no elements with this"); + LLVMContext &Ctx = elt1->getContext(); + SmallVector StructFields{{elt1, elts...}}; + return llvm::StructType::get(Ctx, StructFields); + } bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; } @@ -269,7 +285,14 @@ public: /// Specify a body for an opaque identified type. void setBody(ArrayRef Elements, bool isPacked = false); - void setBody(Type *elt1, ...) LLVM_END_WITH_NULL; + + template + typename std::enable_if::value, void>::type + setBody(Type *elt1, Tys *... elts) { + assert(elt1 && "Cannot create a struct type with no elements with this"); + SmallVector StructFields{{elt1, elts...}}; + setBody(StructFields); + } /// Return true if the specified type is valid as a element type. static bool isValidElementType(Type *ElemTy); diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h index a56bc93e111..a29240d35be 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h @@ -111,12 +111,6 @@ #define LLVM_PREFETCH(addr, rw, locality) #endif -#if __has_attribute(sentinel) || LLVM_GNUC_PREREQ(3, 0, 0) -#define LLVM_END_WITH_NULL __attribute__((sentinel)) -#else -#define LLVM_END_WITH_NULL -#endif - #if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0) #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) #else -- cgit v1.2.3