Skip to content

Instantly share code, notes, and snippets.

@Kimundi
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kimundi/e3e292188221ee8afdf2 to your computer and use it in GitHub Desktop.
Save Kimundi/e3e292188221ee8afdf2 to your computer and use it in GitHub Desktop.

no inheritance

Foo

code

trait Foo { fn method_foo(&self) -> uint; }

struct T1(uint);
struct T2;

impl Foo for T1 { fn method_foo(&self) -> uint { 2 } }
impl Foo for T2 { fn method_foo(&self) -> uint { 32 } }

fn main() {
    let a = [box T2 as Box<Foo>, box T1(0) as Box<Foo>];
    for a in a.iter() {
        println!("{}", a.method_foo());
    }
}

current vtable IR

@vtable1429 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.141817h9b2dcf678835dc41E",
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20h4f9febb1e3359066waaE }

@vtable1381 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.137917h3a8515f8d1ba5035E,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h904413edfd653a3cIaaE }
Foo:    [glue_drop, method_foo]

new vtable layout

Foo-Combined:                 [glue_drop, method_foo]
Direct cast:
  => Foo:                     [glue_drop, method_foo]

single inheritance

 Foo
  |
FooBar

code

trait Foo { fn method_foo(&self) -> uint; }
trait FooBar: Foo { fn method_foobar(&self) -> uint; }

struct T1(uint);
struct T2;

impl Foo for T1 { fn method_foo(&self) -> uint { 2 } }
impl FooBar for T1 { fn method_foobar(&self) -> uint { 8 } }
impl Foo for T2 { fn method_foo(&self) -> uint { 32 } }
impl FooBar for T2 { fn method_foobar(&self) -> uint { 128 } }

fn main() {
    let a = [box T2 as Box<Foo>, box T1(0) as Box<Foo>];
    for a in a.iter() {
        println!("{}", a.method_foo());
    }

    let a = [box T2 as Box<FooBar>, box T1(0) as Box<FooBar>];
    for a in a.iter() {
        println!("{}", a.method_foobar());
    }
}

current vtable IR

@vtable1455 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.144417hc8f132d975db67fcE",
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20h314d43e182e03730EaaE }
@vtable1592 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.144417hc8f132d975db67fcE",
    i64 (%"struct.T1<[]>"*)* @_ZN9T1.FooBar13method_foobar20hca4326865a3b8625QaaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20h314d43e182e03730EaaE }

@vtable1407 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.140517h4b09dd12d1e7b903E,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h9d7b60d69cff14d62aaE }
@vtable1588 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.140517h4b09dd12d1e7b903E,
    i64 (%"struct.T2<[]>"*)* @_ZN9T2.FooBar13method_foobar20h294505c62e3282b4ebaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h9d7b60d69cff14d62aaE }
Foo:    [glue_drop, method_foo]
FooBar: [glue_drop, method_foobar, method_foo]

new vtable layout

FooBar-Combined:              [glue_drop, method_foo, method_foobar]
Direct cast:
  => Foo:                     [glue_drop, method_foo]
  => FooBar:                  [glue_drop, method_foo, method_foobar]
Upcast:
  => FooBar -> Foo:           [glue_drop, method_foo]

multiple inheritance

Foo  Bar
  \ /
 FooBar

code

trait Foo { fn method_foo(&self) -> uint; }
trait Bar { fn method_bar(&self) -> uint; }
trait FooBar: Foo + Bar { fn method_foobar(&self) -> uint; }

struct T1(uint);
struct T2;

impl Foo for T1 { fn method_foo(&self) -> uint { 2 } }
impl Bar for T1 { fn method_bar(&self) -> uint { 4 } }
impl FooBar for T1 { fn method_foobar(&self) -> uint { 8 } }
impl Foo for T2 { fn method_foo(&self) -> uint { 32 } }
impl Bar for T2 { fn method_bar(&self) -> uint { 64 } }
impl FooBar for T2 { fn method_foobar(&self) -> uint { 128 } }

fn main() {
    let a = [box T2 as Box<Foo>, box T1(0) as Box<Foo>];
    for a in a.iter() {
        println!("{}", a.method_foo());
    }

    let a = [box T2 as Box<Bar>, box T1(0) as Box<Bar>];
    for a in a.iter() {
        println!("{}", a.method_bar());
    }

    let a = [box T2 as Box<FooBar>, box T1(0) as Box<FooBar>];
    for a in a.iter() {
        println!("{}", a.method_foobar());
    }
}

current vtable IR

@vtable1481 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.147017h29023da52dd75a80E",
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20hf66b3083e0916b28MaaE }
@vtable1618 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.147017h29023da52dd75a80E",
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Bar10method_bar20hddccc56862636586YaaE }
@vtable1626 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.147017h29023da52dd75a80E",
    i64 (%"struct.T1<[]>"*)* @_ZN9T1.FooBar13method_foobar20h1cf3e0ca5c200a10abaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20hf66b3083e0916b28MaaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Bar10method_bar20hddccc56862636586YaaE }

@vtable1433 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.143117h39569ef7783041e9E,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20heccfe48691528124mbaE }
@vtable1614 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.143117h39569ef7783041e9E,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Bar10method_bar20h074a6a638fb3cb83ybaE }
@vtable1622 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.143117h39569ef7783041e9E,
    i64 (%"struct.T2<[]>"*)* @_ZN9T2.FooBar13method_foobar20h8bdfa049f3e59c29KbaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20heccfe48691528124mbaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Bar10method_bar20h074a6a638fb3cb83ybaE }
Foo:    [glue_drop, method_foo]
Bar:    [glue_drop, method_bar]
FooBar: [glue_drop, method_foobar, method_foo, method_bar]

new vtable layout

FooBar-Combined:              [glue_drop, method_foo, glue_drop, method_bar, method_foobar]
Direct cast:
  => Foo:                     [glue_drop, method_foo]
  => Bar:                                            [glue_drop, method_bar]
  => FooBar:                  [glue_drop, method_foo,            method_bar, method_foobar]
Upcast:
  => FooBar -> Foo:           [glue_drop, method_foo]
  => FooBar -> Bar:                                  [glue_drop, method_bar]

diamond inheritance:

   A
  / \
Foo  Bar
  \ /
 FooBar

code

trait A{ fn method_a(&self) -> uint; }
trait Foo: A { fn method_foo(&self) -> uint; }
trait Bar: A { fn method_bar(&self) -> uint; }
trait FooBar: Foo + Bar { fn method_foobar(&self) -> uint; }

struct T1(uint);
struct T2;

impl A for T1 { fn method_a(&self) -> uint { 1 } }
impl Foo for T1 { fn method_foo(&self) -> uint { 2 } }
impl Bar for T1 { fn method_bar(&self) -> uint { 4 } }
impl FooBar for T1 { fn method_foobar(&self) -> uint { 8 } }
impl A for T2 { fn method_a(&self) -> uint { 16 } }
impl Foo for T2 { fn method_foo(&self) -> uint { 32 } }
impl Bar for T2 { fn method_bar(&self) -> uint { 64 } }
impl FooBar for T2 { fn method_foobar(&self) -> uint { 128 } }

fn main() {
    let a = [box T2 as Box<A>, box T1(0) as Box<A>];
    for a in a.iter() {
        println!("{}", a.method_a());
    }

    let a = [box T2 as Box<Foo>, box T1(0) as Box<Foo>];
    for a in a.iter() {
        println!("{}", a.method_foo());
    }

    let a = [box T2 as Box<Bar>, box T1(0) as Box<Bar>];
    for a in a.iter() {
        println!("{}", a.method_bar());
    }

    let a = [box T2 as Box<FooBar>, box T1(0) as Box<FooBar>];
    for a in a.iter() {
        println!("{}", a.method_foobar());
    }
}

current vtable IR

@vtable1506 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.149517ha952f7b925d9031eE",
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20ha5beb5262ac79338VaaE }
@vtable1643 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.149517ha952f7b925d9031eE",
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20h26eae3befdaa19e47aaE,
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20ha5beb5262ac79338VaaE }
@vtable1651 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.149517ha952f7b925d9031eE",
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Bar10method_bar20h936f9cc49be11acejbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20ha5beb5262ac79338VaaE }
@vtable1659 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.149517ha952f7b925d9031eE",
    i64 (%"struct.T1<[]>"*)* @_ZN9T1.FooBar13method_foobar20hb69600fa639fb686vbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20h26eae3befdaa19e47aaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Bar10method_bar20h936f9cc49be11acejbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20ha5beb5262ac79338VaaE }

@vtable1458 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.145617hc2f2c341746ef135E,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20hd16988d372c164f6HbaE }
@vtable1639 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.145617hc2f2c341746ef135E,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h2e77482a712e7f8fTbaE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20hd16988d372c164f6HbaE }
@vtable1647 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.145617hc2f2c341746ef135E,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Bar10method_bar20hac038f7e055368a85baE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20hd16988d372c164f6HbaE }
@vtable1655 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.145617hc2f2c341746ef135E,
    i64 (%"struct.T2<[]>"*)* @_ZN9T2.FooBar13method_foobar20h8ede4cff752e3fa0hcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h2e77482a712e7f8fTbaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Bar10method_bar20hac038f7e055368a85baE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20hd16988d372c164f6HbaE }
A:      [glue_drop, method_a]
Foo:    [glue_drop, method_foo, method_a]
Bar:    [glue_drop, method_bar, method_a]
FooBar: [glue_drop, method_foobar, method_foo, method_bar, method_a]

new vtable layout

FooBar-Combined:              [glue_drop, method_a, method_foo, glue_drop, method_a, method_bar, method_foobar]
Direct cast:
  => A:                       [glue_drop, method_a]
  => Foo:                     [glue_drop, method_a, method_foo]
  => Bar:                                                      [glue_drop, method_a, method_bar]
  => FooBar:                  [glue_drop, method_a, method_foo,                      method_bar, method_foobar]
Upcast:
  => FooBar -> Foo:           [glue_drop, method_a, method_foo]
  => FooBar -> Foo -> A:      [glue_drop, method_a]
  => FooBar -> Bar:                                            [glue_drop, method_a, method_bar]
  => FooBar -> Bar -> A:                                       [glue_drop, method_a]

fish inheritance

   A
  / \
Foo  Bar
  \ /
 FooBar
  / \
 B   C

code

trait A{ fn method_a(&self) -> uint; }
trait Foo: A { fn method_foo(&self) -> uint; }
trait Bar: A { fn method_bar(&self) -> uint; }
trait FooBar: Foo + Bar { fn method_foobar(&self) -> uint; }
trait B: FooBar { fn method_b(&self) -> uint; }
trait C: FooBar { fn method_c(&self) -> uint; }

struct T1(uint);
struct T2;

impl A for T1 { fn method_a(&self) -> uint { 1 } }
impl Foo for T1 { fn method_foo(&self) -> uint { 2 } }
impl Bar for T1 { fn method_bar(&self) -> uint { 4 } }
impl FooBar for T1 { fn method_foobar(&self) -> uint { 8 } }
impl B for T1 { fn method_b(&self) -> uint { 256 } }
impl C for T1 { fn method_c(&self) -> uint { 512 } }
impl A for T2 { fn method_a(&self) -> uint { 16 } }
impl Foo for T2 { fn method_foo(&self) -> uint { 32 } }
impl Bar for T2 { fn method_bar(&self) -> uint { 64 } }
impl FooBar for T2 { fn method_foobar(&self) -> uint { 128 } }
impl B for T2 { fn method_b(&self) -> uint { 1024 } }
impl C for T2 { fn method_c(&self) -> uint { 2048 } }

fn main() {
    let a = [box T2 as Box<A>, box T1(0) as Box<A>];
    for a in a.iter() {
        println!("{}", a.method_a());
    }

    let a = [box T2 as Box<Foo>, box T1(0) as Box<Foo>];
    for a in a.iter() {
        println!("{}", a.method_foo());
    }

    let a = [box T2 as Box<Bar>, box T1(0) as Box<Bar>];
    for a in a.iter() {
        println!("{}", a.method_bar());
    }

    let a = [box T2 as Box<FooBar>, box T1(0) as Box<FooBar>];
    for a in a.iter() {
        println!("{}", a.method_foobar());
    }

    let a = [box T2 as Box<B>, box T1(0) as Box<B>];
    for a in a.iter() {
        println!("{}", a.method_b());
    }

    let a = [box T2 as Box<C>, box T1(0) as Box<C>];
    for a in a.iter() {
        println!("{}", a.method_c());
    }
}

current vtable IR

@vtable1556 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.154517h69fc043111c6f4a4E",
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20h0dc5223ed12f1d06bbaE }
@vtable1693 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.154517h69fc043111c6f4a4E",
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20hf1cab8292a2bea58nbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20h0dc5223ed12f1d06bbaE }
@vtable1701 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.154517h69fc043111c6f4a4E",
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Bar10method_bar20h7a8785d457033a80zbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20h0dc5223ed12f1d06bbaE }
@vtable1709 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.154517h69fc043111c6f4a4E",
    i64 (%"struct.T1<[]>"*)* @_ZN9T1.FooBar13method_foobar20h06c2af0d174d09ecLbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20hf1cab8292a2bea58nbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Bar10method_bar20h7a8785d457033a80zbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20h0dc5223ed12f1d06bbaE }
@vtable1717 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.154517h69fc043111c6f4a4E",
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.B8method_b20h3b91951006295970XbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN9T1.FooBar13method_foobar20h06c2af0d174d09ecLbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20hf1cab8292a2bea58nbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Bar10method_bar20h7a8785d457033a80zbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20h0dc5223ed12f1d06bbaE }
@vtable1725 = internal constant { void (i8**)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)*, i64 (%"struct.T1<[]>"*)* } {
    void (i8**)* @"_ZN13Box$LT$i8$GT$14glue_drop.154517h69fc043111c6f4a4E",
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.C8method_c20hfda0e84c891b2a829baE,
    i64 (%"struct.T1<[]>"*)* @_ZN9T1.FooBar13method_foobar20h06c2af0d174d09ecLbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Foo10method_foo20hf1cab8292a2bea58nbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN6T1.Bar10method_bar20h7a8785d457033a80zbaE,
    i64 (%"struct.T1<[]>"*)* @_ZN4T1.A8method_a20h0dc5223ed12f1d06bbaE }

@vtable1509 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.150717hfa0ed45a1a15e17eE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20h33487a944e49a77alcaE }
@vtable1689 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.150717hfa0ed45a1a15e17eE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h7ef16e906159aa0axcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20h33487a944e49a77alcaE }
@vtable1697 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.150717hfa0ed45a1a15e17eE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Bar10method_bar20h02bd3739de3a4738JcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20h33487a944e49a77alcaE }
@vtable1705 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.150717hfa0ed45a1a15e17eE,
    i64 (%"struct.T2<[]>"*)* @_ZN9T2.FooBar13method_foobar20hee276845a7ed36aaVcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h7ef16e906159aa0axcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Bar10method_bar20h02bd3739de3a4738JcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20h33487a944e49a77alcaE }
@vtable1713 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.150717hfa0ed45a1a15e17eE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.B8method_b20h110532557de640a37caE,
    i64 (%"struct.T2<[]>"*)* @_ZN9T2.FooBar13method_foobar20hee276845a7ed36aaVcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h7ef16e906159aa0axcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Bar10method_bar20h02bd3739de3a4738JcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20h33487a944e49a77alcaE }
@vtable1721 = internal constant { void (i8*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)*, i64 (%"struct.T2<[]>"*)* } {
    void (i8*)* @_ZN2i814glue_drop.150717hfa0ed45a1a15e17eE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.C8method_c20h9341e72ab9aaa015jdaE,
    i64 (%"struct.T2<[]>"*)* @_ZN9T2.FooBar13method_foobar20hee276845a7ed36aaVcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Foo10method_foo20h7ef16e906159aa0axcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN6T2.Bar10method_bar20h02bd3739de3a4738JcaE,
    i64 (%"struct.T2<[]>"*)* @_ZN4T2.A8method_a20h33487a944e49a77alcaE }
A:      [glue_drop, method_a]
Foo:    [glue_drop, method_foo, method_a]
Bar:    [glue_drop, method_bar, method_a]
FooBar: [glue_drop, method_foobar, method_foo, method_bar, method_a]
B:      [glue_drop, method_b, method_foobar, method_foo, method_bar, method_a]
C:      [glue_drop, method_c, method_foobar, method_foo, method_bar, method_a]

new vtable layout

B-Combined:                   [glue_drop, method_a, method_foo, glue_drop, method_a, method_bar, method_foobar, method_b]
Direct cast:
  => A:                       [glue_drop, method_a]
  => Foo:                     [glue_drop, method_a, method_foo]
  => Bar:                                                      [glue_drop, method_a, method_bar]
  => FooBar:                  [glue_drop, method_a, method_foo,                      method_bar, method_foobar]
  => B:                       [glue_drop, method_a, method_foo,                      method_bar, method_foobar, method_b]
Upcast:
  => B -> FooBar:             [glue_drop, method_a, method_foo,                      method_bar, method_foobar]
  => B -> FooBar -> Foo:      [glue_drop, method_a, method_foo]
  => B -> FooBar -> Foo -> A: [glue_drop, method_a]
  => B -> FooBar -> Bar:                                       [glue_drop, method_a, method_bar]
  => B -> FooBar -> Bar -> A:                                  [glue_drop, method_a]

C-Combined:                   [glue_drop, method_a, method_foo, glue_drop, method_a, method_bar, method_foobar, method_c]
Direct cast:
  => C:                       [glue_drop, method_a, method_foo,                      method_bar, method_foobar, method_c]
Upcast:
  => C -> FooBar:             [glue_drop, method_a, method_foo,                      method_bar, method_foobar]
  => C -> FooBar -> Foo:      [glue_drop, method_a, method_foo]
  => C -> FooBar -> Foo -> A: [glue_drop, method_a]
  => C -> FooBar -> Bar:                                       [glue_drop, method_a, method_bar]
  => C -> FooBar -> Bar -> A:                                  [glue_drop, method_a]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment