1// RUN: rm -rf %t 2// RUN: split-file %s %t 3// RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json 4 5// Invoke C++ with no-rtti. 6// RUN: clang-installapi -target arm64-apple-macos13.1 \ 7// RUN: -I%t/usr/include -I%t/usr/local/include -x c++ -dynamiclib \ 8// RUN: -install_name @rpath/lib/libcpp.dylib -fno-rtti \ 9// RUN: %t/inputs.json -o %t/no-rtti.tbd 2>&1 | FileCheck %s --allow-empty 10 11// RUN: llvm-readtapi -compare %t/no-rtti.tbd \ 12// RUN: %t/expected-no-rtti.tbd 2>&1 | FileCheck %s --allow-empty 13 14// Invoke C++ with rtti. 15// RUN: clang-installapi -target arm64-apple-macos13.1 \ 16// RUN: -I%t/usr/include -I%t/usr/local/include -x c++ \ 17// RUN: -install_name @rpath/lib/libcpp.dylib -frtti -dynamiclib \ 18// RUN: %t/inputs.json -o %t/rtti.tbd 2>&1 | FileCheck %s --allow-empty 19// RUN: llvm-readtapi -compare %t/rtti.tbd \ 20// RUN: %t/expected-rtti.tbd 2>&1 | FileCheck %s --allow-empty 21 22// CHECK-NOT: error: 23// CHECK-NOT: warning: 24 25//--- usr/include/basic.h 26#ifndef CPP_H 27#define CPP_H 28 29inline int foo(int x) { return x + 1; } 30 31extern int bar(int x) { return x + 1; } 32 33inline int baz(int x) { 34 static const int a[] = {1, 2, 3}; 35 return a[x]; 36} 37 38extern "C" { 39 int cFunc(const char*); 40} 41 42class Bar { 43public: 44 static const int x = 0; 45 static int y; 46 47 inline int func1(int x) { return x + 2; } 48 inline int func2(int x); 49 int func3(int x); 50}; 51 52class __attribute__((visibility("hidden"))) BarI { 53 static const int x = 0; 54 static int y; 55 56 inline int func1(int x) { return x + 2; } 57 inline int func2(int x); 58 int func3(int x); 59}; 60 61int Bar::func2(int x) { return x + 3; } 62inline int Bar::func3(int x) { return x + 4; } 63 64int BarI::func2(int x) { return x + 3; } 65inline int BarI::func3(int x) { return x + 4; } 66#endif 67 68//--- usr/local/include/vtable.h 69// Simple test class with no virtual functions. There should be no vtable or 70// RTTI. 71namespace test1 { 72class Simple { 73public: 74 void run(); 75}; 76} // end namespace test1 77 78// Simple test class with virtual function. There should be an external vtable 79// and RTTI. 80namespace test2 { 81class Simple { 82public: 83 virtual void run(); 84}; 85} // end namespace test2 86 87// Abstract class with no sub classes. There should be no vtable or RTTI. 88namespace test3 { 89class Abstract { 90public: 91 virtual ~Abstract() {} 92 virtual void run() = 0; 93}; 94} // end namespace test3 95 96// Abstract base class with a sub class. There should be weak-def RTTI for the 97// abstract base class. 98// The sub-class should have vtable and RTTI. 99namespace test4 { 100class Base { 101public: 102 virtual ~Base() {} 103 virtual void run() = 0; 104}; 105 106class Sub : public Base { 107public: 108 void run() override; 109}; 110} // end namespace test4 111 112// Abstract base class with a sub class. Same as above, but with a user defined 113// inlined destructor. 114namespace test5 { 115class Base { 116public: 117 virtual ~Base() {} 118 virtual void run() = 0; 119}; 120 121class Sub : public Base { 122public: 123 virtual ~Sub() {} 124 void run() override; 125}; 126} // end namespace test5 127 128// Abstract base class with a sub class. Same as above, but with a different 129// inlined key method. 130namespace test6 { 131class Base { 132public: 133 virtual ~Base() {} 134 virtual void run() = 0; 135}; 136 137class Sub : public Base { 138public: 139 virtual void foo() {} 140 void run() override; 141}; 142} // end namespace test6 143 144// Abstract base class with a sub class. Overloaded method is implemented 145// inline. No vtable or RTTI. 146namespace test7 { 147class Base { 148public: 149 virtual ~Base() {} 150 virtual bool run() = 0; 151}; 152 153class Sub : public Base { 154public: 155 bool run() override { return true; } 156}; 157} // end namespace test7 158 159// Abstract base class with a sub class. Overloaded method has no inline 160// attribute and is recognized as key method, 161// but is later implemented inline. Weak-def RTTI only. 162namespace test8 { 163class Base { 164public: 165 virtual ~Base() {} 166 virtual void run() = 0; 167}; 168 169class Sub : public Base { 170public: 171 void run() override; 172}; 173 174inline void Sub::run() {} 175} // end namespace test8 176 177namespace test9 { 178class Base { 179public: 180 virtual ~Base() {} 181 virtual void run1() = 0; 182 virtual void run2() = 0; 183}; 184 185class Sub : public Base { 186public: 187 void run1() override {} 188 void run2() override; 189}; 190 191inline void Sub::run2() {} 192} // end namespace test9 193 194namespace test10 { 195class Base { 196public: 197 virtual ~Base() {} 198 virtual void run1() = 0; 199 virtual void run2() = 0; 200}; 201 202class Sub : public Base { 203public: 204 void run1() override {} 205 inline void run2() override; 206}; 207 208void Sub::run2() {} 209} // end namespace test10 210 211namespace test11 { 212class Base { 213public: 214 virtual ~Base() {} 215 virtual void run1() = 0; 216 virtual void run2() = 0; 217 virtual void run3() = 0; 218}; 219 220class Sub : public Base { 221public: 222 void run1() override {} 223 void run2() override; 224 void run3() override; 225}; 226 227inline void Sub::run2() {} 228} // end namespace test11 229 230namespace test12 { 231template <class T> class Simple { 232public: 233 virtual void foo() {} 234}; 235extern template class Simple<int>; 236} // end namespace test12 237 238namespace test13 { 239class Base { 240public: 241 virtual ~Base() {} 242 virtual void run1() = 0; 243 virtual void run2() {}; 244 virtual void run3(); // key function. 245}; 246 247class Sub : public Base { 248public: 249 void run1() override {} 250 void run2() override {} 251}; 252 253} // end namespace test13 254 255namespace test14 { 256 257class __attribute__((visibility("hidden"))) Base 258{ 259public: 260 Base() {} 261 virtual ~Base(); // keyfunction. 262 virtual void run1() const = 0; 263}; 264 265class Sub : public Base 266{ 267public: 268 Sub(); 269 virtual ~Sub(); 270 virtual void run1() const; 271 void run2() const {} 272}; 273 274} // end namespace test14 275 276namespace test15 { 277 278class Base { 279public: 280 virtual ~Base() {} 281 virtual void run() {}; 282}; 283 284class Base1 { 285public: 286 virtual ~Base1() {} 287 virtual void run1() {}; 288}; 289 290class Sub : public Base, public Base1 { 291public: 292 Sub() {} 293 ~Sub(); 294 void run() override; 295 void run1() override; 296}; 297 298class Sub1 : public Base, public Base1 { 299public: 300 Sub1() {} 301 ~Sub1() = default; 302 void run() override; 303 void run1() override; 304}; 305 306} // end namespace test15 307 308//--- usr/local/include/templates.h 309#ifndef TEMPLATES_H 310#define TEMPLATES_H 311 312namespace templates { 313 314// Full specialization. 315template <class T> int foo1(T a) { return 1; } 316template <> int foo1<int>(int a); 317extern template int foo1<short>(short a); 318 319template <class T> int foo2(T a); 320 321// Partial specialization. 322template <class A, class B> class Partial { 323 static int run(A a, B b) { return a + b; } 324}; 325 326template <class A> class Partial<A, int> { 327 static int run(A a, int b) { return a - b; } 328}; 329 330template <class T> class Foo { 331public: 332 Foo(); 333 ~Foo(); 334}; 335 336template <class T> class Bar { 337public: 338 Bar(); 339 ~Bar() {} 340 341 inline int bazinga() { return 7; } 342}; 343 344extern template class Bar<int>; 345 346class Bazz { 347public: 348 Bazz() {} 349 350 template <class T> int buzz(T a); 351 352 float implicit() const { return foo1(0.0f); } 353}; 354 355template <class T> int Bazz::buzz(T a) { return sizeof(T); } 356 357template <class T> struct S { static int x; }; 358 359template <class T> int S<T>::x = 0; 360 361} // end namespace templates. 362 363#endif 364 365 366//--- inputs.json.in 367{ 368 "headers": [ { 369 "path" : "DSTROOT/usr/include/basic.h", 370 "type" : "public" 371 }, 372 { 373 "path" : "DSTROOT/usr/local/include/vtable.h", 374 "type" : "private" 375 }, 376 { 377 "path" : "DSTROOT/usr/local/include/templates.h", 378 "type" : "private" 379 } 380 ], 381 "version": "3" 382} 383 384//--- expected-no-rtti.tbd 385{ 386 "main_library": { 387 "compatibility_versions": [ 388 { 389 "version": "0" 390 } 391 ], 392 "current_versions": [ 393 { 394 "version": "0" 395 } 396 ], 397 "exported_symbols": [ 398 { 399 "data": { 400 "global": [ 401 "__ZTVN6test143SubE", "__ZTVN6test113SubE", "__ZTVN5test26SimpleE", 402 "__ZTVN5test53SubE", "__ZTVN6test154Sub1E", "__ZTVN6test153SubE", 403 "__ZN3Bar1yE", "__ZTVN5test43SubE", "__ZTVN5test63SubE", 404 "__ZTVN6test134BaseE" 405 ], 406 "weak": [ 407 "__ZTVN6test126SimpleIiEE" 408 ] 409 }, 410 "text": { 411 "global": [ 412 "__ZN6test153Sub3runEv", "__ZN6test154Sub13runEv", 413 "__Z3bari", "__ZThn8_N6test153SubD1Ev", 414 "__ZNK6test143Sub4run1Ev", "__ZN6test154Sub14run1Ev", 415 "__ZThn8_N6test153Sub4run1Ev", "__ZN6test143SubD1Ev", 416 "__ZN6test134Base4run3Ev", "__ZN5test16Simple3runEv", 417 "__ZN5test43Sub3runEv", "__ZN6test113Sub4run3Ev", "__ZN6test153SubD2Ev", 418 "__ZN5test53Sub3runEv", "__ZN6test153SubD1Ev", "__ZN6test143SubC1Ev", 419 "__ZN9templates4foo1IiEEiT_", "__ZN6test143SubC2Ev", "__ZN5test63Sub3runEv", 420 "__ZN5test26Simple3runEv", "__ZN6test153SubD0Ev", 421 "__ZN6test143SubD2Ev", "__ZN6test153Sub4run1Ev", "__ZN6test143SubD0Ev", 422 "__ZThn8_N6test153SubD0Ev", "__ZThn8_N6test154Sub14run1Ev", "_cFunc" 423 ], 424 "weak": [ 425 "__ZN9templates3BarIiED2Ev", "__ZN9templates3BarIiEC2Ev", 426 "__ZN9templates3BarIiEC1Ev", "__ZN9templates3BarIiED1Ev", 427 "__ZN6test126SimpleIiE3fooEv", "__ZN9templates3BarIiE7bazingaEv", 428 "__ZN9templates4foo1IsEEiT_" 429 ] 430 } 431 } 432 ], 433 "flags": [ 434 { 435 "attributes": [ 436 "not_app_extension_safe" 437 ] 438 } 439 ], 440 "install_names": [ 441 { 442 "name": "@rpath/lib/libcpp.dylib" 443 } 444 ], 445 "target_info": [ 446 { 447 "min_deployment": "13.1", 448 "target": "arm64-macos" 449 } 450 ] 451 }, 452 "tapi_tbd_version": 5 453} 454 455//--- expected-rtti.tbd 456{ 457 "main_library": { 458 "compatibility_versions": [ 459 { 460 "version": "0" 461 } 462 ], 463 "current_versions": [ 464 { 465 "version": "0" 466 } 467 ], 468 "exported_symbols": [ 469 { 470 "data": { 471 "global": [ 472 "__ZTVN6test143SubE", "__ZTIN5test63SubE", "__ZTSN5test26SimpleE", 473 "__ZTIN6test153SubE", "__ZTVN6test113SubE", "__ZTIN5test43SubE", 474 "__ZTIN6test134BaseE", "__ZTVN5test26SimpleE", "__ZTIN5test26SimpleE", 475 "__ZTSN6test134BaseE", "__ZTVN6test154Sub1E", "__ZTVN5test43SubE", 476 "__ZTVN5test63SubE", "__ZTSN5test43SubE", "__ZTSN6test113SubE", 477 "__ZTIN6test154Sub1E", "__ZTSN6test153SubE", "__ZTSN5test63SubE", 478 "__ZTSN6test154Sub1E", "__ZTIN6test113SubE", "__ZTSN6test143SubE", 479 "__ZTVN5test53SubE", "__ZTIN6test143SubE", "__ZTVN6test153SubE", 480 "__ZTIN5test53SubE", "__ZN3Bar1yE", "__ZTVN6test134BaseE", 481 "__ZTSN5test53SubE" 482 ], 483 "weak": [ 484 "__ZTVN6test126SimpleIiEE" 485 ] 486 }, 487 "text": { 488 "global": [ 489 "__ZN6test154Sub13runEv", "__ZN6test153Sub3runEv", "__ZNK6test143Sub4run1Ev", 490 "__ZN6test134Base4run3Ev", "__ZN5test16Simple3runEv", "__ZN6test153SubD2Ev", 491 "__ZN6test143SubC2Ev", "__ZN5test63Sub3runEv", "__ZN6test153SubD0Ev", 492 "__ZN6test143SubD2Ev", "__ZThn8_N6test154Sub14run1Ev", 493 "__ZThn8_N6test153SubD0Ev", "__Z3bari", "__ZThn8_N6test153SubD1Ev", 494 "__ZN6test154Sub14run1Ev", "__ZThn8_N6test153Sub4run1Ev", 495 "__ZN6test143SubD1Ev", "__ZN5test43Sub3runEv", 496 "__ZN6test113Sub4run3Ev", "__ZN5test53Sub3runEv", "__ZN6test143SubC1Ev", 497 "__ZN6test153SubD1Ev", "__ZN9templates4foo1IiEEiT_", "__ZN5test26Simple3runEv", 498 "__ZN6test153Sub4run1Ev", "__ZN6test143SubD0Ev", "_cFunc" 499 ], 500 "weak": [ 501 "__ZN9templates3BarIiEC2Ev", "__ZN9templates3BarIiEC1Ev", 502 "__ZN9templates3BarIiED1Ev", "__ZN6test126SimpleIiE3fooEv", 503 "__ZN9templates4foo1IsEEiT_", "__ZN9templates3BarIiED2Ev", 504 "__ZN9templates3BarIiE7bazingaEv" 505 ] 506 } 507 } 508 ], 509 "flags": [ 510 { 511 "attributes": [ 512 "not_app_extension_safe" 513 ] 514 } 515 ], 516 "install_names": [ 517 { 518 "name": "@rpath/lib/libcpp.dylib" 519 } 520 ], 521 "target_info": [ 522 { 523 "min_deployment": "13.1", 524 "target": "arm64-macos" 525 } 526 ] 527 }, 528 "tapi_tbd_version": 5 529} 530 531