[PATCH] D48807: Add llvm::Any

Tim Shen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 3 10:37:34 PDT 2018


timshen added a comment.

In https://reviews.llvm.org/D48807#1150258, @zturner wrote:

> Also, one more area where `Any` makes code cleaner with my planned design is that there isn't really a 1-to-1 mapping between platform events and library events, because platforms have such different semantics.
>
> For example, in Windows a single platform events corresponds to what on Linux is covered by the union of `SIGTRAP`, `SIGBUS`, `SIGFPE`, `SIGILL`, `SIGSEGV`, `SIGUSR`, and other various signals.  And those signals themselves are Linux specific, and may be different from how the same types of events are communicated on Mac, BSD, or some other platform.
>
> To abstract all these platform differences away, it's nice for the library's view of events to be independent of any particular platform.  You might have a `BreakpointEvent`, an `ArithmeticErrorEvent`, an `IllegalInstructionEvent`, an `InvalidMemoryReferenceEvent`, and so on and so forth.  On Windows, however, the `PlatformPiece` would be of the exact same concrete type for all of these (and others).  So if you had some Windows specific code, you'd end up doing something like:
>
>   unique_ptr<EventBase> E = waitForEvent();
>   EXCEPTION_RECORD *E;
>   switch (E->Type) {
>   case EventBase::Breakpoint:
>     E = &(dyn_cast<BreakpointEvent>(E.get())->PlatformPiece);
>     break;
>   case EventBase::ArithmeticError:
>     E = &(dyn_cast<ArithmeticErrorEvent>(E.get())->PlatformPiece);
>     break;
>   case EventBase::IllegalInstruction:
>     E = &(dyn_cast<IllegalInstructionEvent>(E.get())->PlatformPiece);
>     break;
>   case EventBase::InvalidMemoryReference:
>     E = &(dyn_cast<InvalidMemoryReferenceEvent>(E.get())->PlatformPiece);
>     break;
>   }
>
>
> On the other hand, with `Any` you can store the `PlatformPiece` directly in `EventBase`, and this code becomes:
>
>   unique_ptr<EventBase> E = waitForEvent();
>   const EXCEPTION_RECORD *E;
>   switch (E->Type) {
>   case EventBase::Breakpoint:
>   case EventBase::ArithmeticError:
>   case EventBase::IllegalInstruction:
>   case EventBase::InvalidMemoryReference:
>     E = llvm::any_cast<const EXCEPTION_RECORD*>(&E->PlatformPiece);
>     break;
>   }
>


Aren't virtual functions exactly for homogeneous operations over sub-classes?

  unique_ptr<EventBase> Event = waitForEvent();
  const EXCEPTION_RECORD *E;
  switch (Event->Type) {
  case EventBase::Breakpoint:
  case EventBase::ArithmeticError:
  case EventBase::IllegalInstruction:
  case EventBase::InvalidMemoryReference:
    E = Event->getPlatformPiece();  // getPlatformPiece() is a virtual function in EventBase.
    break;
  }


https://reviews.llvm.org/D48807





More information about the llvm-commits mailing list