Thank you, looks good!<br><br>Thanks<br><br>Galina<br><br><br><br><div class="gmail_quote">On Tue, Jan 22, 2013 at 3:23 PM, Michael Spencer <span dir="ltr"><<a href="mailto:bigcheesegs@gmail.com" target="_blank">bigcheesegs@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Tue, Jan 22, 2013 at 3:17 PM, Galina Kistanova <<a href="mailto:gkistanova@gmail.com">gkistanova@gmail.com</a>> wrote:<br>

> clang-X86_64-freebsd:<br>
><br>
> gcc 4.2.1 20070719 [FreeBSD]<br>
> g++ 4.2.1. 20070719 [FreeBSD]<br>
> ld  2.15 [FreeBSD] 2004-05-23<br>
><br>
> clang-x86_64-darwin11-self-mingw32:<br>
><br>
> i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build<br>
> 5658) (LLVM build 2336.1.00)<br>
><br>
> i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build<br>
> i686-apple-darwin11-llvm-g++5658) (LLVM build 2336.1.00)<br>
><br>
> llvm version 3.0svn, from Apple Clang 3.0 (build 211.9)<br>
><br>
> Thanks<br>
><br>
> Galina<br>
<br>
</div>Thanks, it should be fixed now.<br>
<span class="HOEnZb"><font color="#888888"><br>
- Michael Spencer<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
><br>
><br>
><br>
><br>
> On Tue, Jan 22, 2013 at 2:21 PM, Michael Spencer <<a href="mailto:bigcheesegs@gmail.com">bigcheesegs@gmail.com</a>><br>
> wrote:<br>
>><br>
>> On Tue, Jan 22, 2013 at 2:05 PM, Galina Kistanova <<a href="mailto:gkistanova@gmail.com">gkistanova@gmail.com</a>><br>
>> wrote:<br>
>> > Builder clang-x86_64-darwin11-self-mingw32 seems have issues with<br>
>> > r172991<br>
>> > also.<br>
>> ><br>
>> > The last successful build:<br>
>> ><br>
>> > <a href="http://lab.llvm.org:8011/builders/clang-x86_64-darwin11-self-mingw32/builds/8667" target="_blank">http://lab.llvm.org:8011/builders/clang-x86_64-darwin11-self-mingw32/builds/8667</a><br>
>> > r 172988<br>
>> ><br>
>> > the fist failed:<br>
>> ><br>
>> > <a href="http://lab.llvm.org:8011/builders/clang-x86_64-darwin11-self-mingw32/builds/8668" target="_blank">http://lab.llvm.org:8011/builders/clang-x86_64-darwin11-self-mingw32/builds/8668</a><br>
>> > r 172991<br>
>> ><br>
>> > Please let me know if you need more info from me.<br>
>> ><br>
>> > Thanks<br>
>> ><br>
>> > Galina<br>
>> ><br>
>> ><br>
>> ><br>
>> ><br>
>> > On Tue, Jan 22, 2013 at 1:53 PM, Galina Kistanova <<a href="mailto:gkistanova@gmail.com">gkistanova@gmail.com</a>><br>
>> > wrote:<br>
>> >><br>
>> >> Hi Michael,<br>
>> >><br>
>> >> Seems this revision broke clang-X86_64-freebsd build.<br>
>> >><br>
>> >> The last successful build was for r 172988:<br>
>> >> <a href="http://lab.llvm.org:8011/builders/clang-X86_64-freebsd/builds/6722" target="_blank">http://lab.llvm.org:8011/builders/clang-X86_64-freebsd/builds/6722</a><br>
>> >><br>
>> >> The next builded revision was 172992 and it failed:<br>
>> >> <a href="http://lab.llvm.org:8011/builders/clang-X86_64-freebsd/builds/6723" target="_blank">http://lab.llvm.org:8011/builders/clang-X86_64-freebsd/builds/6723</a><br>
>> >><br>
>> >> Please have a look at this?<br>
>> >> Let me know if you need more information on it.<br>
>> >><br>
>> >> Thanks<br>
>> >><br>
>> >> Galina<br>
>><br>
>> Which compiler is in use on these two bots?<br>
>><br>
>> - Michael Spencer<br>
>><br>
>> >><br>
>> >><br>
>> >><br>
>> >><br>
>> >> On Sun, Jan 20, 2013 at 12:32 PM, Michael J. Spencer<br>
>> >> <<a href="mailto:bigcheesegs@gmail.com">bigcheesegs@gmail.com</a>> wrote:<br>
>> >>><br>
>> >>> Author: mspencer<br>
>> >>> Date: Sun Jan 20 14:32:30 2013<br>
>> >>> New Revision: 172991<br>
>> >>><br>
>> >>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=172991&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=172991&view=rev</a><br>
>> >>> Log:<br>
>> >>> [Support] Port ErrorOr<T> from lld to C++03.<br>
>> >>><br>
>> >>> Added:<br>
>> >>>     llvm/trunk/include/llvm/Support/ErrorOr.h<br>
>> >>>     llvm/trunk/unittests/Support/ErrorOrTest.cpp<br>
>> >>> Modified:<br>
>> >>>     llvm/trunk/include/llvm/Support/Compiler.h<br>
>> >>>     llvm/trunk/include/llvm/Support/type_traits.h<br>
>> >>>     llvm/trunk/unittests/Support/CMakeLists.txt<br>
>> >>><br>
>> >>> Modified: llvm/trunk/include/llvm/Support/Compiler.h<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Compiler.h?rev=172991&r1=172990&r2=172991&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Compiler.h?rev=172991&r1=172990&r2=172991&view=diff</a><br>

>> >>><br>
>> >>><br>
>> >>> ==============================================================================<br>
>> >>> --- llvm/trunk/include/llvm/Support/Compiler.h (original)<br>
>> >>> +++ llvm/trunk/include/llvm/Support/Compiler.h Sun Jan 20 14:32:30<br>
>> >>> 2013<br>
>> >>> @@ -42,6 +42,33 @@<br>
>> >>>  #define LLVM_HAS_RVALUE_REFERENCE_THIS 0<br>
>> >>>  #endif<br>
>> >>><br>
>> >>> +/// \macro LLVM_HAS_CXX11_TYPETRAITS<br>
>> >>> +/// \brief Does the compiler have the C++11 type traits.<br>
>> >>> +///<br>
>> >>> +/// #include <type_traits><br>
>> >>> +///<br>
>> >>> +/// * enable_if<br>
>> >>> +/// * {true,false}_type<br>
>> >>> +/// * is_constructible<br>
>> >>> +/// * etc...<br>
>> >>> +#if defined(__GXX_EXPERIMENTAL_CXX0X__) \<br>
>> >>> +    || (defined(_MSC_VER) && _MSC_VER >= 1600)<br>
>> >>> +#define LLVM_HAS_CXX11_TYPETRAITS 1<br>
>> >>> +#else<br>
>> >>> +#define LLVM_HAS_CXX11_TYPETRAITS 0<br>
>> >>> +#endif<br>
>> >>> +<br>
>> >>> +/// \macro LLVM_HAS_CXX11_STDLIB<br>
>> >>> +/// \brief Does the compiler have the C++11 standard library.<br>
>> >>> +///<br>
>> >>> +/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS<br>
>> >>> +#if defined(__GXX_EXPERIMENTAL_CXX0X__) \<br>
>> >>> +    || (defined(_MSC_VER) && _MSC_VER >= 1600)<br>
>> >>> +#define LLVM_HAS_CXX11_STDLIB 1<br>
>> >>> +#else<br>
>> >>> +#define LLVM_HAS_CXX11_STDLIB 0<br>
>> >>> +#endif<br>
>> >>> +<br>
>> >>>  /// llvm_move - Expands to ::std::move if the compiler supports<br>
>> >>>  /// r-value references; otherwise, expands to the argument.<br>
>> >>>  #if LLVM_HAS_RVALUE_REFERENCES<br>
>> >>><br>
>> >>> Added: llvm/trunk/include/llvm/Support/ErrorOr.h<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ErrorOr.h?rev=172991&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ErrorOr.h?rev=172991&view=auto</a><br>

>> >>><br>
>> >>><br>
>> >>> ==============================================================================<br>
>> >>> --- llvm/trunk/include/llvm/Support/ErrorOr.h (added)<br>
>> >>> +++ llvm/trunk/include/llvm/Support/ErrorOr.h Sun Jan 20 14:32:30 2013<br>
>> >>> @@ -0,0 +1,342 @@<br>
>> >>> +//===- llvm/Support/ErrorOr.h - Error Smart Pointer<br>
>> >>> -----------------------===//<br>
>> >>> +//<br>
>> >>> +//                             The LLVM Linker<br>
>> >>> +//<br>
>> >>> +// This file is distributed under the University of Illinois Open<br>
>> >>> Source<br>
>> >>> +// License. See LICENSE.TXT for details.<br>
>> >>> +//<br>
>> >>><br>
>> >>><br>
>> >>> +//===----------------------------------------------------------------------===//<br>
>> >>> +///<br>
>> >>> +/// \file<br>
>> >>> +///<br>
>> >>> +/// Provides ErrorOr<T> smart pointer.<br>
>> >>> +///<br>
>> >>><br>
>> >>><br>
>> >>> +//===----------------------------------------------------------------------===//<br>
>> >>> +<br>
>> >>> +#ifndef LLVM_SUPPORT_ERROR_OR_H<br>
>> >>> +#define LLVM_SUPPORT_ERROR_OR_H<br>
>> >>> +<br>
>> >>> +#include "llvm/Support/AlignOf.h"<br>
>> >>> +#include "llvm/Support/system_error.h"<br>
>> >>> +#include "llvm/Support/type_traits.h"<br>
>> >>> +<br>
>> >>> +#include <cassert><br>
>> >>> +#if LLVM_HAS_CXX11_TYPETRAITS<br>
>> >>> +#include <type_traits><br>
>> >>> +#endif<br>
>> >>> +<br>
>> >>> +namespace llvm {<br>
>> >>> +struct ErrorHolderBase {<br>
>> >>> +  error_code Error;<br>
>> >>> +  uint16_t RefCount;<br>
>> >>> +  bool HasUserData;<br>
>> >>> +<br>
>> >>> +  ErrorHolderBase() : RefCount(1) {}<br>
>> >>> +<br>
>> >>> +  void aquire() {<br>
>> >>> +    ++RefCount;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  void release() {<br>
>> >>> +    if (--RefCount == 0)<br>
>> >>> +      delete this;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +protected:<br>
>> >>> +  virtual ~ErrorHolderBase() {}<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +template<class T><br>
>> >>> +struct ErrorHolder : ErrorHolderBase {<br>
>> >>> +#if LLVM_HAS_RVALUE_REFERENCES<br>
>> >>> +  ErrorHolder(T &&UD) : UserData(llvm_move(UD)) {}<br>
>> >>> +#else<br>
>> >>> +  ErrorHolder(T &UD) : UserData(UD) {}<br>
>> >>> +#endif<br>
>> >>> +  T UserData;<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +template<class Tp> struct ErrorOrUserDataTraits : llvm::false_type<br>
>> >>> {};<br>
>> >>> +<br>
>> >>> +#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES<br>
>> >>> +template<class T, class V><br>
>> >>> +typename std::enable_if< std::is_constructible<T, V>::value<br>
>> >>> +                       , typename<br>
>> >>> std::remove_reference<V>::type>::type<br>
>> >>> &&<br>
>> >>> + moveIfMoveConstructible(V &Val) {<br>
>> >>> +  return std::move(Val);<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +template<class T, class V><br>
>> >>> +typename std::enable_if< !std::is_constructible<T, V>::value<br>
>> >>> +                       , typename<br>
>> >>> std::remove_reference<V>::type>::type<br>
>> >>> &<br>
>> >>> +moveIfMoveConstructible(V &Val) {<br>
>> >>> +  return Val;<br>
>> >>> +}<br>
>> >>> +#else<br>
>> >>> +template<class T, class V><br>
>> >>> +V &moveIfMoveConstructible(V &Val) {<br>
>> >>> +  return Val;<br>
>> >>> +}<br>
>> >>> +#endif<br>
>> >>> +<br>
>> >>> +/// \brief Stores a reference that can be changed.<br>
>> >>> +template <typename T><br>
>> >>> +class ReferenceStorage {<br>
>> >>> +  T *Storage;<br>
>> >>> +<br>
>> >>> +public:<br>
>> >>> +  ReferenceStorage(T &Ref) : Storage(&Ref) {}<br>
>> >>> +<br>
>> >>> +  operator T &() const { return *Storage; }<br>
>> >>> +  T &get() const { return *Storage; }<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +/// \brief Represents either an error or a value T.<br>
>> >>> +///<br>
>> >>> +/// ErrorOr<T> is a pointer-like class that represents the result of<br>
>> >>> an<br>
>> >>> +/// operation. The result is either an error, or a value of type T.<br>
>> >>> This<br>
>> >>> is<br>
>> >>> +/// designed to emulate the usage of returning a pointer where<br>
>> >>> nullptr<br>
>> >>> indicates<br>
>> >>> +/// failure. However instead of just knowing that the operation<br>
>> >>> failed,<br>
>> >>> we also<br>
>> >>> +/// have an error_code and optional user data that describes why it<br>
>> >>> failed.<br>
>> >>> +///<br>
>> >>> +/// It is used like the following.<br>
>> >>> +/// \code<br>
>> >>> +///   ErrorOr<Buffer> getBuffer();<br>
>> >>> +///   void handleError(error_code ec);<br>
>> >>> +///<br>
>> >>> +///   auto buffer = getBuffer();<br>
>> >>> +///   if (!buffer)<br>
>> >>> +///     handleError(buffer);<br>
>> >>> +///   buffer->write("adena");<br>
>> >>> +/// \endcode<br>
>> >>> +///<br>
>> >>> +/// ErrorOr<T> also supports user defined data for specific<br>
>> >>> error_codes.<br>
>> >>> To use<br>
>> >>> +/// this feature you must first add a template specialization of<br>
>> >>> +/// ErrorOrUserDataTraits derived from std::true_type for your type<br>
>> >>> in<br>
>> >>> the lld<br>
>> >>> +/// namespace. This specialization must have a static error_code<br>
>> >>> error()<br>
>> >>> +/// function that returns the error_code this data is used with.<br>
>> >>> +///<br>
>> >>> +/// getError<UserData>() may be called to get either the stored user<br>
>> >>> data, or<br>
>> >>> +/// a default constructed UserData if none was stored.<br>
>> >>> +///<br>
>> >>> +/// Example:<br>
>> >>> +/// \code<br>
>> >>> +///   struct InvalidArgError {<br>
>> >>> +///     InvalidArgError() {}<br>
>> >>> +///     InvalidArgError(std::string S) : ArgName(S) {}<br>
>> >>> +///     std::string ArgName;<br>
>> >>> +///   };<br>
>> >>> +///<br>
>> >>> +///   namespace llvm {<br>
>> >>> +///   template<><br>
>> >>> +///   struct ErrorOrUserDataTraits<InvalidArgError> : std::true_type<br>
>> >>> {<br>
>> >>> +///     static error_code error() {<br>
>> >>> +///       return make_error_code(errc::invalid_argument);<br>
>> >>> +///     }<br>
>> >>> +///   };<br>
>> >>> +///   } // end namespace llvm<br>
>> >>> +///<br>
>> >>> +///   using namespace llvm;<br>
>> >>> +///<br>
>> >>> +///   ErrorOr<int> foo() {<br>
>> >>> +///     return InvalidArgError("adena");<br>
>> >>> +///   }<br>
>> >>> +///<br>
>> >>> +///   int main() {<br>
>> >>> +///     auto a = foo();<br>
>> >>> +///     if (!a && error_code(a) == errc::invalid_argument)<br>
>> >>> +///       llvm::errs() << a.getError<InvalidArgError>().ArgName <<<br>
>> >>> "\n";<br>
>> >>> +///   }<br>
>> >>> +/// \endcode<br>
>> >>> +///<br>
>> >>> +/// An implicit conversion to bool provides a way to check if there<br>
>> >>> was<br>
>> >>> an<br>
>> >>> +/// error. The unary * and -> operators provide pointer like access<br>
>> >>> to<br>
>> >>> the<br>
>> >>> +/// value. Accessing the value when there is an error has undefined<br>
>> >>> behavior.<br>
>> >>> +///<br>
>> >>> +/// When T is a reference type the behaivor is slightly different.<br>
>> >>> The<br>
>> >>> reference<br>
>> >>> +/// is held in a<br>
>> >>> std::reference_wrapper<std::remove_reference<T>::type>,<br>
>> >>> and<br>
>> >>> +/// there is special handling to make operator -> work as if T was<br>
>> >>> not a<br>
>> >>> +/// reference.<br>
>> >>> +///<br>
>> >>> +/// T cannot be a rvalue reference.<br>
>> >>> +template<class T><br>
>> >>> +class ErrorOr {<br>
>> >>> +  static const bool isRef = is_reference<T>::value;<br>
>> >>> +  typedef ReferenceStorage<typename remove_reference<T>::type> wrap;<br>
>> >>> +<br>
>> >>> +public:<br>
>> >>> +  typedef typename<br>
>> >>> +    conditional< isRef<br>
>> >>> +               , wrap<br>
>> >>> +               , T<br>
>> >>> +               >::type storage_type;<br>
>> >>> +<br>
>> >>> +private:<br>
>> >>> +  typedef T &reference;<br>
>> >>> +  typedef typename remove_reference<T>::type *pointer;<br>
>> >>> +<br>
>> >>> +public:<br>
>> >>> +  ErrorOr() : IsValid(false) {}<br>
>> >>> +<br>
>> >>> +  ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) {<br>
>> >>> +    Error = new ErrorHolderBase;<br>
>> >>> +    Error->Error = EC;<br>
>> >>> +    Error->HasUserData = false;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  template<class UserDataT><br>
>> >>> +  ErrorOr(UserDataT UD, typename<br>
>> >>> +          enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type*<br>
>> >>> =<br>
>> >>> 0)<br>
>> >>> +    : HasError(true), IsValid(true) {<br>
>> >>> +    Error = new ErrorHolder<UserDataT>(llvm_move(UD));<br>
>> >>> +    Error->Error = ErrorOrUserDataTraits<UserDataT>::error();<br>
>> >>> +    Error->HasUserData = true;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  ErrorOr(T Val) : HasError(false), IsValid(true) {<br>
>> >>> +    new (get())<br>
>> >>> storage_type(moveIfMoveConstructible<storage_type>(Val));<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  ErrorOr(const ErrorOr &Other) : IsValid(false) {<br>
>> >>> +    // Construct an invalid ErrorOr if other is invalid.<br>
>> >>> +    if (!Other.IsValid)<br>
>> >>> +      return;<br>
>> >>> +    if (!Other.HasError) {<br>
>> >>> +      // Get the other value.<br>
>> >>> +      new (get()) storage_type(*Other.get());<br>
>> >>> +      HasError = false;<br>
>> >>> +    } else {<br>
>> >>> +      // Get other's error.<br>
>> >>> +      Error = Other.Error;<br>
>> >>> +      HasError = true;<br>
>> >>> +      Error->aquire();<br>
>> >>> +    }<br>
>> >>> +<br>
>> >>> +    IsValid = true;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  ErrorOr &operator =(const ErrorOr &Other) {<br>
>> >>> +    if (this == &Other)<br>
>> >>> +      return *this;<br>
>> >>> +<br>
>> >>> +    this->~ErrorOr();<br>
>> >>> +    new (this) ErrorOr(Other);<br>
>> >>> +<br>
>> >>> +    return *this;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +#if LLVM_HAS_RVALUE_REFERENCES<br>
>> >>> +  ErrorOr(ErrorOr &&Other) : IsValid(false) {<br>
>> >>> +    // Construct an invalid ErrorOr if other is invalid.<br>
>> >>> +    if (!Other.IsValid)<br>
>> >>> +      return;<br>
>> >>> +    if (!Other.HasError) {<br>
>> >>> +      // Get the other value.<br>
>> >>> +      IsValid = true;<br>
>> >>> +      new (get()) storage_type(std::move(*Other.get()));<br>
>> >>> +      HasError = false;<br>
>> >>> +      // Tell other not to do any destruction.<br>
>> >>> +      Other.IsValid = false;<br>
>> >>> +    } else {<br>
>> >>> +      // Get other's error.<br>
>> >>> +      Error = Other.Error;<br>
>> >>> +      HasError = true;<br>
>> >>> +      // Tell other not to do any destruction.<br>
>> >>> +      Other.IsValid = false;<br>
>> >>> +    }<br>
>> >>> +<br>
>> >>> +    IsValid = true;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  ErrorOr &operator =(ErrorOr &&Other) {<br>
>> >>> +    if (this == &Other)<br>
>> >>> +      return *this;<br>
>> >>> +<br>
>> >>> +    this->~ErrorOr();<br>
>> >>> +    new (this) ErrorOr(std::move(Other));<br>
>> >>> +<br>
>> >>> +    return *this;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  ~ErrorOr() {<br>
>> >>> +    if (!IsValid)<br>
>> >>> +      return;<br>
>> >>> +    if (HasError)<br>
>> >>> +      Error->release();<br>
>> >>> +    else<br>
>> >>> +      get()->~storage_type();<br>
>> >>> +  }<br>
>> >>> +#endif<br>
>> >>> +<br>
>> >>> +  template<class ET><br>
>> >>> +  ET getError() const {<br>
>> >>> +    assert(IsValid && "Cannot get the error of a default constructed<br>
>> >>> ErrorOr!");<br>
>> >>> +    assert(HasError && "Cannot get an error if none exists!");<br>
>> >>> +    assert(ErrorOrUserDataTraits<ET>::error() == Error->Error &&<br>
>> >>> +           "Incorrect user error data type for error!");<br>
>> >>> +    if (!Error->HasUserData)<br>
>> >>> +      return ET();<br>
>> >>> +    return reinterpret_cast<const ErrorHolder<ET>*>(Error)->UserData;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  typedef void (*unspecified_bool_type)();<br>
>> >>> +  static void unspecified_bool_true() {}<br>
>> >>> +<br>
>> >>> +  /// \brief Return false if there is an error.<br>
>> >>> +  operator unspecified_bool_type() const {<br>
>> >>> +    assert(IsValid && "Can't do anything on a default constructed<br>
>> >>> ErrorOr!");<br>
>> >>> +    return HasError ? 0 : unspecified_bool_true;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  operator llvm::error_code() const {<br>
>> >>> +    assert(IsValid && "Can't do anything on a default constructed<br>
>> >>> ErrorOr!");<br>
>> >>> +    return HasError ? Error->Error : llvm::error_code::success();<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  pointer operator ->() {<br>
>> >>> +    return toPointer(get());<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  reference operator *() {<br>
>> >>> +    return *get();<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +private:<br>
>> >>> +  pointer toPointer(pointer Val) {<br>
>> >>> +    return Val;<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  pointer toPointer(wrap *Val) {<br>
>> >>> +    return &Val->get();<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +protected:<br>
>> >>> +  storage_type *get() {<br>
>> >>> +    assert(IsValid && "Can't do anything on a default constructed<br>
>> >>> ErrorOr!");<br>
>> >>> +    assert(!HasError && "Cannot get value when an error exists!");<br>
>> >>> +    return reinterpret_cast<storage_type*>(TStorage.buffer);<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  const storage_type *get() const {<br>
>> >>> +    assert(IsValid && "Can't do anything on a default constructed<br>
>> >>> ErrorOr!");<br>
>> >>> +    assert(!HasError && "Cannot get value when an error exists!");<br>
>> >>> +    return reinterpret_cast<const storage_type*>(TStorage.buffer);<br>
>> >>> +  }<br>
>> >>> +<br>
>> >>> +  union {<br>
>> >>> +    AlignedCharArrayUnion<storage_type> TStorage;<br>
>> >>> +    ErrorHolderBase *Error;<br>
>> >>> +  };<br>
>> >>> +  bool HasError : 1;<br>
>> >>> +  bool IsValid : 1;<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +template<class T, class E><br>
>> >>> +typename enable_if_c<is_error_code_enum<E>::value ||<br>
>> >>> +                     is_error_condition_enum<E>::value, bool>::type<br>
>> >>> +operator ==(ErrorOr<T> &Err, E Code) {<br>
>> >>> +  return error_code(Err) == Code;<br>
>> >>> +}<br>
>> >>> +} // end namespace llvm<br>
>> >>> +<br>
>> >>> +#endif<br>
>> >>><br>
>> >>> Modified: llvm/trunk/include/llvm/Support/type_traits.h<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/type_traits.h?rev=172991&r1=172990&r2=172991&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/type_traits.h?rev=172991&r1=172990&r2=172991&view=diff</a><br>

>> >>><br>
>> >>><br>
>> >>> ==============================================================================<br>
>> >>> --- llvm/trunk/include/llvm/Support/type_traits.h (original)<br>
>> >>> +++ llvm/trunk/include/llvm/Support/type_traits.h Sun Jan 20 14:32:30<br>
>> >>> 2013<br>
>> >>> @@ -145,6 +145,10 @@<br>
>> >>>  template <typename T> struct is_pointer<T* volatile> : true_type {};<br>
>> >>>  template <typename T> struct is_pointer<T* const volatile> :<br>
>> >>> true_type<br>
>> >>> {};<br>
>> >>><br>
>> >>> +/// \brief Metafunction that determines wheather the given type is a<br>
>> >>> reference.<br>
>> >>> +template <typename T> struct is_reference : false_type {};<br>
>> >>> +template <typename T> struct is_reference<T&> : true_type {};<br>
>> >>> +<br>
>> >>>  /// \brief Metafunction that determines whether the given type is<br>
>> >>> either<br>
>> >>> an<br>
>> >>>  /// integral type or an enumeration type.<br>
>> >>>  ///<br>
>> >>><br>
>> >>> Modified: llvm/trunk/unittests/Support/CMakeLists.txt<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=172991&r1=172990&r2=172991&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=172991&r1=172990&r2=172991&view=diff</a><br>

>> >>><br>
>> >>><br>
>> >>> ==============================================================================<br>
>> >>> --- llvm/trunk/unittests/Support/CMakeLists.txt (original)<br>
>> >>> +++ llvm/trunk/unittests/Support/CMakeLists.txt Sun Jan 20 14:32:30<br>
>> >>> 2013<br>
>> >>> @@ -13,6 +13,7 @@<br>
>> >>>    ConstantRangeTest.cpp<br>
>> >>>    DataExtractorTest.cpp<br>
>> >>>    EndianTest.cpp<br>
>> >>> +  ErrorOrTest.cpp<br>
>> >>>    FileOutputBufferTest.cpp<br>
>> >>>    IntegersSubsetTest.cpp<br>
>> >>>    LeakDetectorTest.cpp<br>
>> >>><br>
>> >>> Added: llvm/trunk/unittests/Support/ErrorOrTest.cpp<br>
>> >>> URL:<br>
>> >>><br>
>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ErrorOrTest.cpp?rev=172991&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ErrorOrTest.cpp?rev=172991&view=auto</a><br>

>> >>><br>
>> >>><br>
>> >>> ==============================================================================<br>
>> >>> --- llvm/trunk/unittests/Support/ErrorOrTest.cpp (added)<br>
>> >>> +++ llvm/trunk/unittests/Support/ErrorOrTest.cpp Sun Jan 20 14:32:30<br>
>> >>> 2013<br>
>> >>> @@ -0,0 +1,78 @@<br>
>> >>> +//===- unittests/ErrorOrTest.cpp - ErrorOr.h tests<br>
>> >>> ------------------------===//<br>
>> >>> +//<br>
>> >>> +//                     The LLVM Compiler Infrastructure<br>
>> >>> +//<br>
>> >>> +// This file is distributed under the University of Illinois Open<br>
>> >>> Source<br>
>> >>> +// License. See LICENSE.TXT for details.<br>
>> >>> +//<br>
>> >>><br>
>> >>><br>
>> >>> +//===----------------------------------------------------------------------===//<br>
>> >>> +<br>
>> >>> +#include "llvm/Support/ErrorOr.h"<br>
>> >>> +<br>
>> >>> +#include "gtest/gtest.h"<br>
>> >>> +<br>
>> >>> +#include <memory><br>
>> >>> +<br>
>> >>> +using namespace llvm;<br>
>> >>> +<br>
>> >>> +namespace {<br>
>> >>> +<br>
>> >>> +ErrorOr<int> t1() {return 1;}<br>
>> >>> +ErrorOr<int> t2() {return make_error_code(errc::invalid_argument);}<br>
>> >>> +<br>
>> >>> +TEST(ErrorOr, SimpleValue) {<br>
>> >>> +  ErrorOr<int> a = t1();<br>
>> >>> +  EXPECT_TRUE(a);<br>
>> >>> +  EXPECT_EQ(1, *a);<br>
>> >>> +<br>
>> >>> +  a = t2();<br>
>> >>> +  EXPECT_FALSE(a);<br>
>> >>> +  EXPECT_EQ(errc::invalid_argument, a);<br>
>> >>> +  EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists");<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +#if LLVM_HAS_CXX11_STDLIB<br>
>> >>> +ErrorOr<std::unique_ptr<int> > t3() {<br>
>> >>> +  return std::unique_ptr<int>(new int(3));<br>
>> >>> +}<br>
>> >>> +#endif<br>
>> >>> +<br>
>> >>> +TEST(ErrorOr, Types) {<br>
>> >>> +  int x;<br>
>> >>> +  ErrorOr<int&> a(x);<br>
>> >>> +  *a = 42;<br>
>> >>> +  EXPECT_EQ(42, x);<br>
>> >>> +<br>
>> >>> +#if LLVM_HAS_CXX11_STDLIB<br>
>> >>> +  // Move only types.<br>
>> >>> +  EXPECT_EQ(3, **t3());<br>
>> >>> +#endif<br>
>> >>> +}<br>
>> >>> +} // end anon namespace<br>
>> >>> +<br>
>> >>> +struct InvalidArgError {<br>
>> >>> +  InvalidArgError() {}<br>
>> >>> +  InvalidArgError(std::string S) : ArgName(S) {}<br>
>> >>> +  std::string ArgName;<br>
>> >>> +};<br>
>> >>> +<br>
>> >>> +namespace llvm {<br>
>> >>> +template<><br>
>> >>> +struct ErrorOrUserDataTraits<InvalidArgError> : std::true_type {<br>
>> >>> +  static error_code error() {<br>
>> >>> +    return make_error_code(errc::invalid_argument);<br>
>> >>> +  }<br>
>> >>> +};<br>
>> >>> +} // end namespace lld<br>
>> >>> +<br>
>> >>> +ErrorOr<int> t4() {<br>
>> >>> +  return InvalidArgError("adena");<br>
>> >>> +}<br>
>> >>> +<br>
>> >>> +namespace {<br>
>> >>> +TEST(ErrorOr, UserErrorData) {<br>
>> >>> +  ErrorOr<int> a = t4();<br>
>> >>> +  EXPECT_EQ(errc::invalid_argument, a);<br>
>> >>> +  EXPECT_EQ("adena", t4().getError<InvalidArgError>().ArgName);<br>
>> >>> +}<br>
>> >>> +} // end anon namespace<br>
>> >>><br>
>> >>><br>
>> >>> _______________________________________________<br>
>> >>> llvm-commits mailing list<br>
>> >>> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
>> >>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
>> >><br>
>> >><br>
>> ><br>
><br>
><br>
</div></div></blockquote></div><br>