<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    This is mostly in line with what I thought the answers would be, so
    +1 from me, at least for the concept.  I haven't peered into the
    implementation.<br>
    <br>
    <div class="moz-cite-prefix">On 2/3/2016 12:18 PM, Lang Hames wrote:<br>
    </div>
    <blockquote
cite="mid:CALLttgo_2M189ruk=aAMgAEPfNbvAK+Vg0jMdeSwoeQ-bgZkJg@mail.gmail.com"
      type="cite">
      <div dir="ltr">Hi Craig,
        <div><br>
        </div>
        <div>> <span style="font-size:13px">TypedError Err = foo();</span></div>
        <span style="font-size:13px">> // no checking in between</span><br
          style="font-size:13px">
        <span style="font-size:13px">> Err = foo();</span><br
          style="font-size:13px">
        <div><span style="font-size:13px"><br>
          </span></div>
        <div>This will cause an abort - the assignment operator for
          TypedError checks that you're not overwriting an unhanded
          error.</div>
        <div><br>
        </div>
        <div><span style="font-size:13px">> TypedError Err = foo();</span><br
            style="font-size:13px">
          <span style="font-size:13px">>
            functionWithHorribleSideEffect</span><span
            style="font-size:13px">s();</span><br style="font-size:13px">
          <span style="font-size:13px">> if (Err) return;</span><br>
        </div>
        <div><span style="font-size:13px"><br>
          </span></div>
        <div>This is potentially reasonable code - it's impossible to
          distinguish in general from:</div>
        <div><br>
        </div>
        <div>TypedError Err = foo();</div>
        <div>functionWithPerfectlyReasonableSideEffects();</div>
        <div>if (Err) return;</div>
        <div><br>
        </div>
        <div>That said, to avoid problems related to this style we can
          offer style guidelines. Idiomatic usage of the system looks
          like:<br>
        </div>
        <div><br>
        </div>
        <div>if (auto Err = foo())</div>
        <div>  return Err;</div>
        <div>functionWithHorribleSideEffects();</div>
        <div><br>
        </div>
        <div>This is how people tend to write error checks in most of
          the LLVM code I've seen to date.</div>
        <div><br>
        </div>
        <div><span style="font-size:13px">> Do you anticipate giving
            these kinds of errors to out of tree projects?  If so, are
            there any kind of binary compatibility guarantee?</span><br
            style="font-size:13px">
        </div>
        <div><br>
        </div>
        <div>Out of tree projects can use the TypedError.h header and
          derive their own error classes. This is all pure C++, I don't
          think there are binary compatibility issues.</div>
        <div><br>
        </div>
        <div>> <span style="font-size:13px">What about errors that
            should come out of constructors?  Or <shudder>
            destructors?</span></div>
        <div><br>
        </div>
        <div>TypedError can't be "thrown" in the same way that C++
          exceptions can. It's an ordinary C++ value. You can't return
          an error from a constructor, but you can pass a reference to
          an error in and set that. In general the style guideline for a
          "may-fail" constructors would be to write something like this:</div>
        <div><br>
        </div>
        <div><font face="monospace, monospace">class Foo {</font></div>
        <div><font face="monospace, monospace">public:</font></div>
        <div><font face="monospace, monospace"><br>
          </font></div>
        <div><font face="monospace, monospace">  static
            TypedErrorOr<Foo> create(int X, int Y) {</font></div>
        <div><font face="monospace, monospace">    TypedError Err;</font></div>
        <div><font face="monospace, monospace">    Foo F(X, Y, Err);</font></div>
        <div><font face="monospace, monospace">    if (Err)</font></div>
        <div><font face="monospace, monospace">      return
            std::move(Err);</font></div>
        <div><font face="monospace, monospace">    return std::move(F);</font></div>
        <div><font face="monospace, monospace">  }</font></div>
        <div><font face="monospace, monospace"><br>
          </font></div>
        <div><font face="monospace, monospace">private:</font></div>
        <div><font face="monospace, monospace">  Foo(int x, int y,
            TypedError &Err) {</font></div>
        <div><font face="monospace, monospace">    if (x == y) {</font></div>
        <div><font face="monospace, monospace">      Err =
            make_typed_error<BadFoo>();</font></div>
        <div><font face="monospace, monospace">      return;</font></div>
        <div><font face="monospace, monospace">    }</font></div>
        <div><font face="monospace, monospace">  }</font></div>
        <div><font face="monospace, monospace">};</font></div>
        <div><br>
        </div>
        <div>Then you have:</div>
        <div><br>
        </div>
        <div><font face="monospace, monospace">TypedErrorOr<Foo> F
            = Foo::create(X, Y);</font></div>
        <div><br>
        </div>
        <div><br>
        </div>
        <div>The only way to catch failure of a destructor is for the
          class to hold a reference to a TypedError, and set that. This
          is extremely difficult to do correctly, but as far is I know
          all error schemes suffer from poor interaction with
          destructors. In LLVM failing destructors are very rare, so I
          don't anticipate this being a problem in general.</div>
        <div><br>
        </div>
        <div>> <span style="font-size:13px"> </span><span
            style="font-size:13px">If a constructor fails and doesn't
            establish it's invariant, what will prevent the use of that
            invalid object?</span></div>
        <div><span style="font-size:13px"><br>
          </span></div>
        <div><span style="font-size:13px">If the style guideline above
            is followed the invalid object will never be returned to the
            user. Care must be taken to ensure that the destructor can
            destruct the partially constructed object, but that's always
            the case.</span></div>
        <div><br>
        </div>
        <div>> <span style="font-size:13px"> </span><span
            style="font-size:13px">How many subclasses do you expect to
            make of TypedError? Less than 10? More than 100?</span></div>
        <div><span style="font-size:13px"><br>
          </span></div>
        <div>This is a support library, so it's not possible to reason
          about how many external clients will want to use it in their
          projects, or how many errors they would define. In LLVM I'd
          like to see us adopt a 'less-is-more' approach: New error
          types should be introduced sparingly, and each new error type
          should require a rationale for its existence. In particular,
          distinct error types should only be introduced when it's
          reasonable for some client to make a meaningful distinction
          between them. If an error is only being returned in order to
          produce a string diagnostic, a generic StringDiagnosticError
          should suffice.</div>
        <div><br>
        </div>
        <div>Answering your question more directly: In the LLVM code I'm
          familiar with I can see room for more than 10 error types, but
          fewer than 100.</div>
        <div><br>
        </div>
        <div>> <span style="font-size:13px">How common is it to want
            to handle a specific error code in a non-local way?  In my
            experience, I either want a specific error handled locally,
            or a fail / not-failed from farther away.  The answer to
            this question may influence the number of subclasses you
            want to make.</span></div>
        <div><span style="font-size:13px"><br>
          </span></div>
        <div>Errors usually get handled locally, or just produce a
          diagnostic and failure, however there are some cases where we
          want non-local recovery from specific errors. The
          archive-walking example I gave earlier is one such case.
          You're right on the point about subclasses too - that's what I
          was hoping to capture with my comment above: only introduce an
          error type if it's meaningful for a client to distinguish it
          from other errors.</div>
        <div><br>
        </div>
        <div> > <span style="font-size:13px">Are file, line number,
            and / or call stack information captured?  I've found file
            and line number information to be incredibly useful from a
            productivity standpoint.</span></div>
        <div><span style="font-size:13px"><br>
          </span></div>
        <div>I think that information is helpful for programmatic
          errors, but those are better represented by asserts or
          "report_fatal_error". This system is intended to support
          modelling of non-programmatic errors - bad input, resource
          failures and the like. For those, the specific point in the
          code where the error was triggered is less useful. If such
          information is needed, this system makes it easy to break on
          the failure point in a debugger.</div>
        <div><br>
        </div>
        <div>Cheers,</div>
        <div>Lang.</div>
        <div><br>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Wed, Feb 3, 2016 at 6:15 AM, Craig,
          Ben via llvm-dev <span dir="ltr"><<a
              moz-do-not-send="true"
              href="mailto:llvm-dev@lists.llvm.org" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a></a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div bgcolor="#FFFFFF" text="#000000"> I've had some
              experience dealing with rich error descriptions without
              exceptions before.  The scheme I used was somewhat similar
              to what you have.  Here are some items to consider.<br>
              <br>
              * How will the following code be avoided?  The answer may
              be compile time error, runtime error, style
              recommendations, or maybe something else.<br>
              <br>
              TypedError Err = foo();<br>
              // no checking in between<br>
              Err = foo();<br>
              <br>
              * How about this?<br>
              <br>
              TypedError Err = foo();<br>
              functionWithHorribleSideEffects();<br>
              if(Err) return;<br>
              <br>
              * Do you anticipate giving these kinds of errors to out of
              tree projects?  If so, are there any kind of binary
              compatibility guarantee?<br>
              <br>
              * What about errors that should come out of constructors? 
              Or <shudder> destructors?<br>
              <br>
              * If a constructor fails and doesn't establish it's
              invariant, what will prevent the use of that invalid
              object?<br>
              <br>
              * How many subclasses do you expect to make of TypedError?
              Less than 10? More than 100?<br>
              <br>
              * How common is it to want to handle a specific error code
              in a non-local way?  In my experience, I either want a
              specific error handled locally, or a fail / not-failed
              from farther away.  The answer to this question may
              influence the number of subclasses you want to make.<br>
              <br>
              * Are file, line number, and / or call stack information
              captured?  I've found file and line number information to
              be incredibly useful from a productivity standpoint.
              <div>
                <div class="h5"><br>
                  <br>
                  <div>On 2/2/2016 7:29 PM, Lang Hames via llvm-dev
                    wrote:<br>
                  </div>
                </div>
              </div>
              <blockquote type="cite">
                <div>
                  <div class="h5">
                    <div dir="ltr"><span style="font-size:13px">Hi All,</span>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">I've been thinking
                        lately about how to improve LLVM's error model
                        and error reporting. A lack of good error
                        reporting in Orc and MCJIT has forced me to
                        spend a lot of time investigating hard-to-debug
                        errors that could easily have been identified if
                        we provided richer error information to the
                        client, rather than just aborting. Kevin Enderby
                        has made similar observations about the state of
                        libObject and the difficulty of producing good
                        error messages for damaged object files. I
                        expect to encounter more issues like this as I
                        continue work on the MachO side of LLD. I see
                        tackling the error modeling problem as a first
                        step towards improving error handling in
                        general: if we make it easy to model errors, it
                        may pave the way for better error handling in
                        many parts of our libraries.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">At present in LLVM we
                        model errors with std::error_code (and its
                        helper, ErrorOr) and use diagnostic streams for
                        error reporting. Neither of these seem entirely
                        up to the job of providing a solid
                        error-handling mechanism for library code.
                        Diagnostic streams are great if all you want to
                        do is report failure to the user and then
                        terminate, but they can't be used to distinguish
                        between different kinds of errors, and so are
                        unsuited to many use-cases (especially error
                        recovery). On the other hand, std::error_code
                        allows error kinds to be distinguished, but
                        suffers a number of drawbacks:</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">1. It carries no
                        context: It tells you what went wrong, but not
                        where or why, making it difficult to produce
                        good diagnostics.</div>
                      <div style="font-size:13px">2. It's extremely easy
                        to ignore or forget: instances can be silently
                        dropped.</div>
                      <div style="font-size:13px">3. It's not especially
                        debugger friendly: Most people call the
                        error_code constructors directly for both
                        success and failure values. Breakpoints have to
                        be set carefully to avoid stopping when success
                        values are constructed.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">In fairness to
                        std::error_code, it has some nice properties
                        too:</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">1. It's extremely
                        lightweight.</div>
                      <div style="font-size:13px">2. It's explicit in
                        the API (unlike exceptions).</div>
                      <div style="font-size:13px">3. It doesn't require
                        C++ RTTI (a requirement for use in LLVM).</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">To address these
                        shortcomings I have prototyped a new
                        error-handling scheme partially inspired by C++
                        exceptions. The aim was to preserve the
                        performance and API visibility of
                        std::error_code, while allowing users to define
                        custom error classes and inheritance
                        relationships between them. My hope is that
                        library code could use this scheme to model
                        errors in a meaningful way, allowing clients to
                        inspect the error information and recover where
                        possible, or provide a rich diagnostic when
                        aborting.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">The scheme has three
                        major "moving parts":</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">1. A new 'TypedError'
                        class that can be used as a replacement for
                        std::error_code. E.g.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">std::error_code foo();</font></div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">becomes</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">TypedError foo();</font></div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">The TypedError class
                        serves as a lightweight wrapper for the real
                        error information (see (2)). It also contains a
                        'Checked' flag, initially set to false, that
                        tracks whether the error has been handled or
                        not. If a TypedError is ever destructed without
                        being checked (or passed on to someone else) it
                        will call std::terminate(). TypedError cannot be
                        silently dropped.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">2. A utility class,
                        TypedErrorInfo, for building error class
                        hierarchies rooted at 'TypedErrorInfoBase' with
                        custom RTTI. E.g.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">// Define a new error type
                          implicitly inheriting from TypedErrorInfoBase.</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">class MyCustomError : public
                          TypedErrorInfo<MyCustomError> {</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">public:</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">  // Custom error info.</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">};</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace"><br>
                        </font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">// Define a subclass of
                          MyCustomError.</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">class MyCustomSubError : public
                          TypedErrorInfo<MyCustomSubError,
                          MyCustomError> {</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">public:</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">  // Extends MyCustomError, adds
                          new members.</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">};</font></div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">3.  A set of utility
                        functions that use the custom RTTI system to
                        inspect and handle typed errors. For example
                        'catchAllTypedErrors' and 'handleTypedError'
                        cooperate to handle error instances in a
                        type-safe way:</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">TypedError foo() {</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">  if (SomeFailureCondition)</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">    return
                          make_typed_error<MyCustomError>();</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">}</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace"><br>
                        </font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">TypedError Err = foo();</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace"><br>
                        </font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">catchAllTypedErrors(std::move(Err),</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace"> 
                          handleTypedError<MyCustomError>(</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">   
                          [](std::unique_ptr<MyCustomError> E) {</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">      // Handle the error.</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">      return TypedError(); // <-
                          Indicate success from handler.</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">    }</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">  )</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">);</font></div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">If your initial
                        reaction is "Too much boilerplate!" I
                        understand, but take comfort: (1) In the
                        overwhelmingly common case of simply returning
                        errors, the usage is identical to
                        std::error_code:</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">if (TypedError Err = foo())</font></div>
                      <div style="font-size:13px"><font face="monospace,
                          monospace">  return Err;</font></div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">and (2) the
                        boilerplate for catching errors is usually
                        easily contained in a handful of utility
                        functions, and tends not to crowd the rest of
                        your source code. My initial experiments with
                        this scheme involved updating many source lines,
                        but did not add much code at all beyond the new
                        error classes that were introduced.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">I believe that this
                        scheme addresses many of the shortcomings of
                        std::error_code while maintaining the
                        strengths: </div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">1. Context - Custom
                        error classes enable the user to attach as much
                        contextual information as desired.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">2. Difficult to drop -
                        The 'checked' flag in TypedError ensures that it
                        can't be dropped, it must be explicitly
                        "handled", even if that only involves catching
                        the error and doing nothing.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">3. Debugger friendly -
                        You can set a breakpoint on any custom error
                        class's constructor to catch that error being
                        created. Since the error class hierarchy is
                        rooted you can break on
                        TypedErrorInfoBase::TypedErrorInfoBase to catch
                        any error being raised.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">4. Lightweight -
                        Because TypedError instances are just a pointer
                        and a checked-bit, move-constructing it is very
                        cheap. We may also want to consider ignoring the
                        'checked' bit in release mode, at which point
                        TypedError should be as cheap as
                        std::error_code.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">5. Explicit -
                        TypedError is represented explicitly in the
                        APIs, the same as std::error_code.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">6. Does not require
                        C++ RTTI - The custom RTTI system does not rely
                        on any standard C++ RTTI features.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">This scheme also has
                        one attribute that I haven't seen in previous
                        error handling systems (though my experience in
                        this area is limited): Errors are not copyable,
                        due to ownership semantics of TypedError. I
                        think this actually neatly captures the idea
                        that there is a chain of responsibility for
                        dealing with any given error. Responsibility may
                        be transferred (e.g. by returning it to a
                        caller), but it cannot be duplicated as it
                        doesn't generally make sense for multiple people
                        to report or attempt to recover from the same
                        error.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">I've tested this
                        prototype out by threading it through the
                        object-creation APIs of libObject and using
                        custom error classes to report errors in MachO
                        headers. My initial experience is that this has
                        enabled much richer error messages than are
                        possible with std::error_code.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">To enable interaction
                        with APIs that still use std::error_code I have
                        added a custom ECError class that wraps a
                        std::error_code, and can be converted back to a
                        std::error_code using the typedErrorToErrorCode
                        function. For now, all custom error code classes
                        should (and do, in the prototype) derive from
                        this utility class. In my experiments, this has
                        made it easy to thread TypedError selectively
                        through parts of the API. Eventually my hope is
                        that TypedError could replace std::error_code
                        for user-facing APIs, at which point custom
                        errors would no longer need to derive from
                        ECError, and ECError could be relegated to a
                        utility for interacting with other codebases
                        that still use std::error_code.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">So - I look forward to
                        hearing your thoughts. :)</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">Cheers,</div>
                      <div style="font-size:13px">Lang.</div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">
                        <div>Attached files:<br>
                        </div>
                        <div><br>
                        </div>
                        <div>typed_error.patch - Adds
                          include/llvm/Support/TypedError.h (also adds
                          anchor() method to
                          lib/Support/ErrorHandling.cpp).</div>
                        <div><br>
                        </div>
                        <div>error_demo.tgz - Stand-alone program
                          demo'ing basic use of the TypedError API.</div>
                      </div>
                      <div style="font-size:13px"><br>
                      </div>
                      <div style="font-size:13px">libobject_typed_error_demo.patch
                        - Threads TypedError through the binary-file
                        creation methods (createBinary,
                        createObjectFile, etc). Proof-of-concept for how
                        TypedError can be integrated into an existing
                        system.</div>
                      <div style="font-size:13px"><br>
                      </div>
                    </div>
                    <br>
                    <fieldset></fieldset>
                    <br>
                  </div>
                </div>
                <span class="">
                  <pre>_______________________________________________
LLVM Developers mailing list
<a moz-do-not-send="true" href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>
<a moz-do-not-send="true" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
                </span></blockquote>
              <span class="HOEnZb"><font color="#888888"> <br>
                  <pre cols="72">-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
</pre>
                </font></span></div>
            <br>
            _______________________________________________<br>
            LLVM Developers mailing list<br>
            <a moz-do-not-send="true"
              href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
            <a moz-do-not-send="true"
              href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev"
              rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
            <br>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
    <pre class="moz-signature" cols="72">-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
</pre>
  </body>
</html>