[clang] [clang] Implement `__is_virtual_base_of()` intrinsic (PR #100393)

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 24 11:45:25 PDT 2024


================
@@ -2457,6 +2457,75 @@ void is_base_of() {
   static_assert(!__is_base_of(DerivedB<int>, BaseA<int>));
 }
 
+struct DerivedTransitiveViaNonVirtual : Derived3 {};
+struct DerivedTransitiveViaVirtual : virtual Derived3 {};
+
+template <typename T>
+struct CrazyDerivedVirtual : virtual T {};
+
+struct DerivedPrivate : private virtual Base {};
+struct DerivedProtected : protected virtual Base {};
+struct DerivedPrivatePrivate : private DerivedPrivate {};
+struct DerivedPrivateProtected : private DerivedProtected {};
+struct DerivedProtectedPrivate : protected DerivedProtected {};
+struct DerivedProtectedProtected : protected DerivedProtected {};
+
+void is_virtual_base_of(int n) {
+  static_assert(!__is_virtual_base_of(Base, Derived));
+  static_assert(!__is_virtual_base_of(const Base, Derived));
+  static_assert(!__is_virtual_base_of(Derived, Base));
+  static_assert(!__is_virtual_base_of(Derived, int));
+  static_assert(!__is_virtual_base_of(Base, Base));
+  static_assert(!__is_virtual_base_of(Base, Derived3));
+  static_assert(!__is_virtual_base_of(Derived, Derived3));
+  static_assert(__is_virtual_base_of(Derived2b, Derived3));
+  static_assert(__is_virtual_base_of(Derived2a, Derived3));
+  static_assert(!__is_virtual_base_of(BaseA<int>, DerivedB<int>));
+  static_assert(!__is_virtual_base_of(DerivedB<int>, BaseA<int>));
+  static_assert(!__is_virtual_base_of(Union, Union));
+  static_assert(!__is_virtual_base_of(Empty, Empty));
+  static_assert(!__is_virtual_base_of(class_forward, class_forward)); // expected-error {{incomplete type 'class_forward' where a complete type is required}}
+  static_assert(!__is_virtual_base_of(Empty, class_forward)); // expected-error {{incomplete type 'class_forward' where a complete type is required}}
+  static_assert(!__is_virtual_base_of(Base&, Derived&));
+  static_assert(!__is_virtual_base_of(Base[10], Derived[10]));
+  static_assert(!__is_virtual_base_of(Base[n], Derived[n])); // expected-error 2 {{variable length arrays are not supported in '__is_virtual_base_of'}}
+  static_assert(!__is_virtual_base_of(int, int));
+  static_assert(!__is_virtual_base_of(int[], int[]));
+  static_assert(!__is_virtual_base_of(long, int));
+  static_assert(!__is_virtual_base_of(Base, DerivedTemp<int>));
+  static_assert(!__is_virtual_base_of(Base, NonderivedTemp<int>));
+  static_assert(!__is_virtual_base_of(Base, UndefinedTemp<int>)); // expected-error {{implicit instantiation of undefined template 'UndefinedTemp<int>'}}
+  static_assert(__is_virtual_base_of(Base, DerivedPrivate));
+  static_assert(__is_virtual_base_of(Base, DerivedProtected));
+  static_assert(__is_virtual_base_of(Base, DerivedPrivatePrivate));
+  static_assert(__is_virtual_base_of(Base, DerivedPrivateProtected));
+  static_assert(__is_virtual_base_of(Base, DerivedProtectedPrivate));
+  static_assert(__is_virtual_base_of(Base, DerivedProtectedProtected));
+  static_assert(__is_virtual_base_of(Derived2a, DerivedTransitiveViaNonVirtual));
+  static_assert(__is_virtual_base_of(Derived2b, DerivedTransitiveViaNonVirtual));
+  static_assert(__is_virtual_base_of(Derived2a, DerivedTransitiveViaVirtual));
+  static_assert(__is_virtual_base_of(Derived2b, DerivedTransitiveViaVirtual));
+  static_assert(!__is_virtual_base_of(Base, CrazyDerived<Base>));
+  static_assert(!__is_virtual_base_of(CrazyDerived<Base>, Base));
+  static_assert(__is_virtual_base_of(Base, CrazyDerivedVirtual<Base>));
+  static_assert(!__is_virtual_base_of(CrazyDerivedVirtual<Base>, Base));
+
+  static_assert(!__is_virtual_base_of(IncompleteUnion, IncompleteUnion));
----------------
Endilll wrote:

I added a slightly different test in a different place.

https://github.com/llvm/llvm-project/pull/100393


More information about the cfe-commits mailing list