1 #ifndef PETSC_PREPROCESSOR_MACROS_H 2 #define PETSC_PREPROCESSOR_MACROS_H 3 4 #include <petscconf.h> 5 #include <petscconf_poison.h> /* for PetscDefined() error checking */ 6 7 /* SUBMANSEC = Sys */ 8 9 #if defined(__cplusplus) 10 #if __cplusplus <= 201103L 11 #define PETSC_CPP_VERSION 11 12 #elif __cplusplus <= 201402L 13 #define PETSC_CPP_VERSION 14 14 #elif __cplusplus <= 201703L 15 #define PETSC_CPP_VERSION 17 16 #elif __cplusplus <= 202002L 17 #define PETSC_CPP_VERSION 20 18 #else 19 #define PETSC_CPP_VERSION 22 // current year, or date of c++2b ratification 20 #endif 21 #endif // __cplusplus 22 23 #ifndef PETSC_CPP_VERSION 24 #define PETSC_CPP_VERSION 0 25 #endif 26 27 #if defined(__STDC_VERSION__) 28 #if __STDC_VERSION__ <= 199901L 29 // C99 except that 99 is >= 11 or 17 so we shorten it to 9 instead 30 #define PETSC_C_VERSION 9 31 #elif __STDC_VERSION__ <= 201112L 32 #define PETSC_C_VERSION 11 33 #elif __STDC_VERSION__ <= 201710L 34 #define PETSC_C_VERSION 17 35 #else 36 #define PETSC_C_VERSION 22 // current year, or date of c2b ratification 37 #endif 38 #endif // __STDC_VERSION__ 39 40 #ifndef PETSC_C_VERSION 41 #define PETSC_C_VERSION 0 42 #endif 43 44 /* ========================================================================== */ 45 /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */ 46 #if defined(__cplusplus) 47 #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX 48 #else 49 #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C 50 #endif 51 52 /* ========================================================================== */ 53 /* Since PETSc manages its own extern "C" handling users should never include PETSc include 54 * files within extern "C". This will generate a compiler error if a user does put the include 55 * file within an extern "C". 56 */ 57 #if defined(__cplusplus) 58 void assert_never_put_petsc_headers_inside_an_extern_c(int); 59 void assert_never_put_petsc_headers_inside_an_extern_c(double); 60 #endif 61 62 #if defined(__cplusplus) 63 #define PETSC_RESTRICT PETSC_CXX_RESTRICT 64 #else 65 #define PETSC_RESTRICT restrict 66 #endif 67 68 #define PETSC_INLINE PETSC_DEPRECATED_MACRO(3, 17, 0, "inline", ) inline 69 #define PETSC_STATIC_INLINE PETSC_DEPRECATED_MACRO(3, 17, 0, "static inline", ) static inline 70 71 #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */ 72 #define PETSC_DLLEXPORT __declspec(dllexport) 73 #define PETSC_DLLIMPORT __declspec(dllimport) 74 #define PETSC_VISIBILITY_INTERNAL 75 #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX) 76 #define PETSC_DLLEXPORT __attribute__((visibility("default"))) 77 #define PETSC_DLLIMPORT __attribute__((visibility("default"))) 78 #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden"))) 79 #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C) 80 #define PETSC_DLLEXPORT __attribute__((visibility("default"))) 81 #define PETSC_DLLIMPORT __attribute__((visibility("default"))) 82 #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden"))) 83 #else 84 #define PETSC_DLLEXPORT 85 #define PETSC_DLLIMPORT 86 #define PETSC_VISIBILITY_INTERNAL 87 #endif 88 89 #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */ 90 #define PETSC_VISIBILITY_PUBLIC PETSC_DLLEXPORT 91 #else /* Win32 users need this to import symbols from petsc.dll */ 92 #define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT 93 #endif 94 95 /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when 96 * compiled with C++ so they may be used from C and are always visible in the shared libraries 97 */ 98 #if defined(__cplusplus) 99 #define PETSC_EXTERN extern "C" PETSC_VISIBILITY_PUBLIC 100 #define PETSC_EXTERN_TYPEDEF extern "C" 101 #define PETSC_INTERN extern "C" PETSC_VISIBILITY_INTERNAL 102 #else 103 #define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC 104 #define PETSC_EXTERN_TYPEDEF 105 #define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL 106 #endif 107 108 #if defined(PETSC_USE_SINGLE_LIBRARY) 109 #define PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PETSC_VISIBILITY_INTERNAL 110 #define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN 111 #else 112 #define PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PETSC_VISIBILITY_PUBLIC 113 #define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN 114 #endif 115 116 #if !defined(__has_feature) 117 #define __has_feature(x) 0 118 #endif 119 120 /*MC 121 PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler 122 123 Synopsis: 124 #include <petscmacros.h> 125 int PetscHasAttribute(name) 126 127 Input Parameter: 128 . name - The name of the attribute to test 129 130 Notes: 131 name should be identical to what you might pass to the __attribute__ declaration itself -- 132 plain, unbroken text. 133 134 As `PetscHasAttribute()` is wrapper over the function-like macro `__has_attribute()`, the 135 exact type and value returned is implementation defined. In practice however, it usually 136 returns `1` if the attribute is supported and `0` if the attribute is not supported. 137 138 Example Usage: 139 Typical usage is using the preprocessor 140 141 .vb 142 #if PetscHasAttribute(always_inline) 143 # define MY_ALWAYS_INLINE __attribute__((always_inline)) 144 #else 145 # define MY_ALWAYS_INLINE 146 #endif 147 148 void foo(void) MY_ALWAYS_INLINE; 149 .ve 150 151 but it can also be used in regular code 152 153 .vb 154 if (PetscHasAttribute(some_attribute)) { 155 foo(); 156 } else { 157 bar(); 158 } 159 .ve 160 161 Level: intermediate 162 163 .seealso: `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`, 164 `PETSC_ATTRIBUTE_FORMAT`, `PETSC_ATTRIBUTE_MAY_ALIAS` 165 M*/ 166 #if !defined(__has_attribute) 167 #define __has_attribute(x) 0 168 #endif 169 #define PetscHasAttribute(name) __has_attribute(name) 170 171 /*MC 172 PetscHasBuiltin - Determine whether a particular builtin method is supported by the compiler 173 174 Synopsis: 175 #include <petscmacros.h> 176 int PetscHasBuiltin(name) 177 178 Input Parameter: 179 . name - the name of the builtin routine 180 181 Notes: 182 Evaluates to `1` if the builtin is supported and `0` otherwise. Note the term "evaluates" 183 (vs "expands") is deliberate; even though `PetscHasBuiltin()` is a macro the underlying 184 detector is itself is a compiler extension with implementation-defined return type and 185 semantics. Some compilers implement it as a macro, others as a compiler function. In practice 186 however, all supporting compilers return an integer boolean as described. 187 188 Example Usage: 189 Typical usage is in preprocessor directives 190 191 .vb 192 #if PetscHasBuiltin(__builtin_trap) 193 __builtin_trap(); 194 #else 195 abort(); 196 #endif 197 .ve 198 199 But it may also be used in regular code 200 201 .vb 202 if (PetscHasBuiltin(__builtin_alloca)) { 203 foo(); 204 } else { 205 bar(); 206 } 207 .ve 208 209 Level: intermediate 210 211 .seealso: `PetscHasAttribute()`, `PetscAssume()` 212 M*/ 213 #if !defined(__has_builtin) 214 #define __has_builtin(x) 0 215 #endif 216 // clangs __has_builtin prior to clang 10 did not properly handle non-function builtins such as 217 // __builtin_types_compatible_p which take types or other non-functiony things as 218 // arguments. The correct way to detect these then is to use __is_identifier (also a clang 219 // extension). GCC has always worked as expected. see https://stackoverflow.com/a/45043153 220 #if defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 10) && defined(__is_identifier) 221 #define PetscHasBuiltin(name) __is_identifier(name) 222 #else 223 #define PetscHasBuiltin(name) __has_builtin(name) 224 #endif 225 226 #if !defined(PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG) 227 /* 228 Support for Clang (>=3.2) matching type tag arguments with void* buffer types. 229 This allows the compiler to detect cases where the MPI datatype argument passed to a MPI routine 230 does not match the actual type of the argument being passed in 231 */ 232 #if PetscHasAttribute(pointer_with_type_tag) 233 #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) __attribute__((pointer_with_type_tag(MPI, bufno, typeno))) 234 #endif 235 236 #if PetscHasAttribute(type_tag_for_datatype) 237 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type) __attribute__((type_tag_for_datatype(MPI, type))) 238 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) __attribute__((type_tag_for_datatype(MPI, type, layout_compatible))) 239 #endif 240 #endif // PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG 241 242 #ifndef PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE 243 #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) 244 #endif 245 246 #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG 247 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type) 248 #endif 249 250 #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE 251 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) 252 #endif 253 254 /*MC 255 PETSC_ATTRIBUTE_FORMAT - Indicate to the compiler that specified arguments should be treated 256 as format specifiers and checked for validity 257 258 Synopsis: 259 #include <petscmacros.h> 260 <attribute declaration> PETSC_ATTRIBUTE_FORMAT(int strIdx, int vaArgIdx) 261 262 Input Parameters: 263 + strIdx - The (1-indexed) location of the format string in the argument list 264 - vaArgIdx - The (1-indexed) location of the first formattable argument in the argument list 265 266 Level: developer 267 268 Notes: 269 This function attribute causes the compiler to issue warnings when the format specifier does 270 not match the type of the variable that will be formatted, or when there exists a mismatch 271 between the number of format specifiers and variables to be formatted. It is safe to use this 272 macro if your compiler does not support format specifier checking (though this is 273 exceeedingly rare). 274 275 Both `strIdx` and `vaArgIdx` must be compile-time constant integer literals and cannot have the 276 same value. 277 278 The arguments to be formatted (and therefore checked by the compiler) must be "contiguous" in 279 the argument list, that is, there is no way to indicate gaps which should not be checked. 280 281 Definition is suppressed by defining `PETSC_SKIP_ATTRIBUTE_FORMAT` prior to including PETSc 282 header files. In this case the macro will expand empty. 283 284 Example Usage: 285 .vb 286 // format string is 2nd argument, variable argument list containing args is 3rd argument 287 void my_printf(void *obj, const char *fmt_string, ...) PETSC_ATTRIBUTE_FORMAT(2,3) 288 289 int x = 1; 290 double y = 50.0; 291 292 my_printf(NULL,"%g",x); // WARNING, format specifier does not match for 'int'! 293 my_printf(NULL,"%d",x,y); // WARNING, more arguments than format specifiers! 294 my_printf(NULL,"%d %g",x,y); // OK 295 .ve 296 297 .seealso: `PETSC_ATTRIBUTE_COLD`, `PetscHasAttribute()` 298 M*/ 299 #if PetscHasAttribute(format) && !defined(PETSC_SKIP_ATTRIBUTE_FORMAT) 300 #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) __attribute__((format(printf, strIdx, vaArgIdx))) 301 #else 302 #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) 303 #endif 304 305 /*MC 306 PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be 307 executed 308 309 Level: intermediate 310 311 Notes: 312 The marked function is often optimized for size rather than speed and may be grouped alongside 313 other equally frigid routines improving code locality of lukewarm or hotter parts of program. 314 315 The paths leading to cold functions are usually automatically marked as unlikely by the 316 compiler. It may thus be useful to mark functions used to handle unlikely conditions -- such 317 as error handlers -- as cold to improve optimization of the surrounding temperate functions. 318 319 Example Usage: 320 .vb 321 void my_error_handler(...) PETSC_ATTRIBUTE_COLD; 322 323 if (temperature < 0) { 324 return my_error_handler(...); // chilly! 325 } 326 .ve 327 328 .seealso: `PetscUnlikely()`, `PetscUnlikelyDebug()`, `PetscLikely()`, `PetscLikelyDebug()`, 329 `PetscUnreachable()`, `PETSC_ATTRIBUTE_FORMAT` 330 M*/ 331 #if PetscHasAttribute(__cold__) 332 #define PETSC_ATTRIBUTE_COLD __attribute__((__cold__)) 333 #elif PetscHasAttribute(cold) /* some implementations (old gcc) use no underscores */ 334 #define PETSC_ATTRIBUTE_COLD __attribute__((cold)) 335 #else 336 #define PETSC_ATTRIBUTE_COLD 337 #endif 338 339 /*MC 340 PETSC_ATTRIBUTE_MAY_ALIAS - Indicate to the compiler that a type is not 341 subjected to type-based alias analysis, but is instead assumed to be able to 342 alias any other type of objects 343 344 Example Usage: 345 .vb 346 typedef PetscScalar PetscScalarAlias PETSC_ATTRIBUTE_MAY_ALIAS; 347 348 PetscReal *pointer; 349 PetscScalarAlias *other_pointer = reinterpret_cast<PetscScalarAlias *>(pointer); 350 .ve 351 352 Level: advanced 353 354 .seealso: `PetscHasAttribute()` 355 M*/ 356 #if PetscHasAttribute(may_alias) && !defined(PETSC_SKIP_ATTRIBUTE_MAY_ALIAS) 357 #define PETSC_ATTRIBUTE_MAY_ALIAS __attribute__((may_alias)) 358 #else 359 #define PETSC_ATTRIBUTE_MAY_ALIAS 360 #endif 361 362 /*MC 363 PETSC_NULLPTR - Standard way of indicating a null value or pointer 364 365 No Fortran Support 366 367 Level: beginner 368 369 Notes: 370 Equivalent to `NULL` in C source, and `nullptr` in C++ source. Note that for the purposes of 371 interoperability between C and C++, setting a pointer to `PETSC_NULLPTR` in C++ is functonially 372 equivalent to setting the same pointer to `NULL` in C. That is to say that the following 373 expressions are equivalent\: 374 375 .vb 376 ptr == PETSC_NULLPTR 377 ptr == NULL 378 ptr == 0 379 !ptr 380 381 ptr = PETSC_NULLPTR 382 ptr = NULL 383 ptr = 0 384 .ve 385 386 and for completeness' sake\: 387 388 .vb 389 PETSC_NULLPTR == NULL 390 .ve 391 392 Example Usage: 393 .vb 394 // may be used in place of '\0' or other such teminators in the definition of char arrays 395 const char *const MyEnumTypes[] = { 396 "foo", 397 "bar", 398 PETSC_NULLPTR 399 }; 400 401 // may be used to nullify objects 402 PetscObject obj = PETSC_NULLPTR; 403 404 // may be used in any function expecting NULL 405 PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor"); 406 .ve 407 408 Developer Notes: 409 `PETSC_NULLPTR` must be used in place of `NULL` in all C++ source files. Using `NULL` in source 410 files compiled with a C++ compiler may lead to unexpected side-effects in function overload 411 resolution and/or compiler warnings. 412 413 .seealso: `PETSC_CONSTEXPR_14`, `PETSC_NODISCARD` 414 M*/ 415 416 /*MC 417 PETSC_CONSTEXPR_14 - C++14 constexpr 418 419 No Fortran Support 420 421 Level: beginner 422 423 Notes: 424 Equivalent to `constexpr` when using a C++ compiler that supports C++14. Expands to nothing 425 if the C++ compiler does not support C++14 or when not compiling with a C++ compiler. Note 426 that this cannot be used in cases where an empty expansion would result in invalid code. It 427 is safe to use this in C source files. 428 429 Example Usage: 430 .vb 431 PETSC_CONSTEXPR_14 int factorial(int n) 432 { 433 int r = 1; 434 435 do { 436 r *= n; 437 } while (--n); 438 return r; 439 } 440 .ve 441 442 .seealso: `PETSC_NULLPTR`, `PETSC_NODISCARD` 443 M*/ 444 445 /*MC 446 PETSC_NODISCARD - Mark the return value of a function as non-discardable 447 448 Not available in Fortran 449 450 Level: beginner 451 452 Notes: 453 Hints to the compiler that the return value of a function must be captured. A diagnostic may 454 (but is not required to) be emitted if the value is discarded. It is safe to use this in both 455 C and C++ source files. 456 457 In this context "captured" means assigning the return value of a function to a named 458 variable or casting it to `void`. Between the two, assigning to a named variable is the most 459 portable way of silencing any warnings, since `PETSC_NODISCARD` may expand to GCC's 460 `__attribute__((warn_unused_result))` which will still emit warnings when casting results to 461 `void`. 462 463 Example Usage: 464 .vb 465 class Foo 466 { 467 int x; 468 469 public: 470 PETSC_NODISCARD Foo(int y) : x(y) { } 471 }; 472 473 PETSC_NODISCARD int factorial(int n) 474 { 475 return n <= 1 ? 1 : (n * factorial(n - 1)); 476 } 477 478 factorial(10); // Warning: ignoring return value of function declared 'nodiscard' 479 auto x = factorial(10); // OK, capturing return value 480 (void)factorial(10); // Maybe OK, casting to void 481 auto y = factorial(10); // OK, capturing in y (and casting y to void to silence 482 (void)y; // set-but-not-used warnings) 483 484 Foo(x); // Warning: Ignoring temporary created by a constructor declared 'nodiscard' 485 auto f = Foo(x); // OK, capturing constructed object 486 (void)Foo(x); // Maybe OK, casting to void 487 auto g = Foo(x); // OK, capturing in g (and casting g to void to silence set-but-not-used 488 (void)g; // warnings) 489 .ve 490 491 .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14` 492 M*/ 493 494 /* C++11 features */ 495 #if defined(__cplusplus) || (PETSC_C_VERSION >= 23) 496 #define PETSC_NULLPTR nullptr 497 #else 498 #define PETSC_NULLPTR NULL 499 #endif 500 501 /* C++14 features */ 502 #if PETSC_CPP_VERSION >= 14 503 #define PETSC_CONSTEXPR_14 constexpr 504 #else 505 #define PETSC_CONSTEXPR_14 506 #endif 507 508 /* C++17 features */ 509 #if PETSC_CPP_VERSION >= 17 510 #define PETSC_CONSTEXPR_17 constexpr 511 #else 512 #define PETSC_CONSTEXPR_17 513 #endif 514 515 #if (PETSC_CPP_VERSION >= 17) || (PETSC_C_VERSION >= 23) 516 #define PETSC_NODISCARD [[nodiscard]] 517 #elif PetscHasAttribute(warn_unused_result) 518 #define PETSC_NODISCARD __attribute__((warn_unused_result)) 519 #else 520 #define PETSC_NODISCARD 521 #endif 522 523 #include <petscversion.h> 524 #define PETSC_AUTHOR_INFO " The PETSc Team\n petsc-maint@mcs.anl.gov\n https://petsc.org/\n" 525 526 /* designated initializers since C99 and C++20, MSVC never supports them though */ 527 #if defined(_MSC_VER) || (defined(__cplusplus) && (PETSC_CPP_VERSION < 20)) 528 #define PetscDesignatedInitializer(name, ...) __VA_ARGS__ 529 #else 530 #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__ 531 #endif 532 533 /*MC 534 PetscUnlikely - Hints the compiler that the given condition is usually false 535 536 Synopsis: 537 #include <petscmacros.h> 538 bool PetscUnlikely(bool cond) 539 540 Not Collective; No Fortran Support 541 542 Input Parameter: 543 . cond - Boolean expression 544 545 Level: advanced 546 547 Notes: 548 This returns the same truth value, it is only a hint to compilers that the result of cond is 549 unlikely to be true. 550 551 Example usage: 552 .vb 553 if (PetscUnlikely(cond)) { 554 foo(); // cold path 555 } else { 556 bar(); // hot path 557 } 558 .ve 559 560 .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`, 561 `PETSC_ATTRIBUTE_COLD` 562 M*/ 563 564 /*MC 565 PetscLikely - Hints the compiler that the given condition is usually true 566 567 Synopsis: 568 #include <petscmacros.h> 569 bool PetscLikely(bool cond) 570 571 Not Collective; No Fortran Support 572 573 Input Parameter: 574 . cond - Boolean expression 575 576 Level: advanced 577 578 Notes: 579 This returns the same truth value, it is only a hint to compilers that the result of cond is 580 likely to be true. 581 582 Example usage: 583 .vb 584 if (PetscLikely(cond)) { 585 foo(); // hot path 586 } else { 587 bar(); // cold path 588 } 589 .ve 590 591 .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()` 592 `PETSC_ATTRIBUTE_COLD` 593 M*/ 594 #if defined(PETSC_HAVE_BUILTIN_EXPECT) 595 #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0) 596 #define PetscLikely(cond) __builtin_expect(!!(cond), 1) 597 #else 598 #define PetscUnlikely(cond) (cond) 599 #define PetscLikely(cond) (cond) 600 #endif 601 602 /*MC 603 PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable 604 605 Synopsis: 606 #include <petscmacros.h> 607 void PetscUnreachable(void) 608 609 Level: advanced 610 611 Notes: 612 Indicates to the compiler (usually via some built-in) that a particular code path is always 613 unreachable. Behavior is undefined if this function is ever executed, the user can expect an 614 unceremonious crash. 615 616 Example usage: 617 Useful in situations such as switches over enums where not all enumeration values are 618 explicitly covered by the switch 619 620 .vb 621 typedef enum {RED, GREEN, BLUE} Color; 622 623 int foo(Color c) 624 { 625 // it is known to programmer (or checked previously) that c is either RED or GREEN 626 // but compiler may not be able to deduce this and/or emit spurious warnings 627 switch (c) { 628 case RED: 629 return bar(); 630 case GREEN: 631 return baz(); 632 default: 633 PetscUnreachable(); // program is ill-formed if executed 634 } 635 } 636 .ve 637 638 .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD`, `PetscAssume()` 639 M*/ 640 #if PETSC_CPP_VERSION >= 23 641 #include <utility> 642 #define PetscUnreachable() std::unreachable() 643 #elif defined(__GNUC__) 644 /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */ 645 #define PetscUnreachable() __builtin_unreachable() 646 #elif defined(_MSC_VER) /* MSVC */ 647 #define PetscUnreachable() __assume(0) 648 #else /* ??? */ 649 #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed") 650 #endif 651 652 /*MC 653 PetscAssume - Indicate to the compiler a condition that is defined to be true 654 655 Synopsis: 656 #include <petscmacros.h> 657 void PetscAssume(bool cond) 658 659 Input Parameter: 660 . cond - Boolean expression 661 662 Level: advanced 663 664 Notes: 665 If supported by the compiler, `cond` is used to inform the optimizer of an invariant 666 truth. The argument itself is never evaluated, so any side effects of the expression will be 667 discarded. This macro is used in `PetscAssert()` to retain information gained from debug 668 checks that would be lost in optimized builds. For example\: 669 670 .vb 671 PetscErrorCode foo(PetscInt x) { 672 673 PetscAssert(x >= 0, ...); 674 } 675 .ve 676 677 The assertion checks that `x` is positive when debugging is enabled (and returns from `foo()` 678 if it is not). This implicitly informs the optimizer that `x` cannot be negative. However, 679 when debugging is disabled any `PetscAssert()` checks are tautologically false, and hence the 680 optimizer cannot deduce any information from them. 681 682 Due to compiler limitations `PetscAssume()` works best when `cond` involves 683 constants. Certain compilers do not yet propagate symbolic inequalities i.e.\: 684 685 .vb 686 int a, b, var_five; 687 688 // BEST, all supporting compilers will understand a cannot be >= 5 689 PetscAssume(a < 5); 690 691 // OK, some compilers may understand that a cannot be >= 5 692 PetscAssume(a <= b && b < 5); 693 694 // WORST, most compilers will not get the memo 695 PetscAssume(a <= b && b < var_five); 696 .ve 697 698 If the condition is violated at runtime then behavior is wholly undefined. If the 699 condition is violated at compile-time, the condition "supersedes" the compile-time violation 700 and the program is ill-formed, no diagnostic required. For example consider the following\: 701 702 .vb 703 PetscInt x = 0; 704 705 PetscAssume(x != 0); 706 if (x == 0) { 707 x += 10; 708 } else { 709 popen("rm -rf /", "w"); 710 } 711 .ve 712 713 Even though `x` is demonstrably `0` the compiler may opt to\: 714 715 - emit an unconditional `popen("rm -rf /", "w")` 716 - ignore `PetscAssume()` altogether and emit the correct path of `x += 10` 717 - reformat the primary disk partition 718 719 .seealso: `PetscAssert()` 720 M*/ 721 #if PETSC_CPP_VERSION >= 23 722 #define PetscAssume(...) [[assume(__VA_ARGS__)]] 723 #elif defined(_MSC_VER) // msvc 724 #define PetscAssume(...) __assume(__VA_ARGS__) 725 #elif defined(__clang__) && PetscHasBuiltin(__builtin_assume) // clang 726 #define PetscAssume(...) \ 727 do { \ 728 _Pragma("clang diagnostic push"); \ 729 _Pragma("clang diagnostic ignored \"-Wassume\""); \ 730 __builtin_assume(__VA_ARGS__); \ 731 _Pragma("clang diagnostic pop"); \ 732 } while (0) 733 #else // gcc (and really old clang) 734 // gcc does not have its own __builtin_assume() intrinsic. One could fake it via 735 // 736 // if (PetscUnlikely(!cond)) PetscUnreachable(); 737 // 738 // but this it unsavory because the side effects of cond are not guaranteed to be 739 // discarded. Though in most circumstances gcc will optimize out the if (because any evaluation 740 // for which cond is false would be undefined results in undefined behavior anyway) it cannot 741 // always do so. This is especially the case for opaque or non-inline function calls: 742 // 743 // extern int bar(int); 744 // 745 // int foo(int x) { 746 // PetscAssume(bar(x) == 2); 747 // if (bar(x) == 2) { 748 // return 1; 749 // } else { 750 // return 0; 751 // } 752 // } 753 // 754 // Here gcc would (if just using builtin_expect()) emit 2 calls to bar(). Note we still have 755 // cond "tested" in the condition, but this is done to silence unused-but-set variable warnings 756 #define PetscAssume(...) \ 757 do { \ 758 if (0 && (__VA_ARGS__)) PetscUnreachable(); \ 759 } while (0) 760 #endif 761 762 /*MC 763 PetscExpand - Expand macro argument 764 765 Synopsis: 766 #include <petscmacros.h> 767 <macro-expansion> PetscExpand(x) 768 769 Input Parameter: 770 . x - The preprocessor token to expand 771 772 Level: beginner 773 774 .seealso: `PetscStringize()`, `PetscConcat()` 775 M*/ 776 #define PetscExpand_(...) __VA_ARGS__ 777 #define PetscExpand(...) PetscExpand_(__VA_ARGS__) 778 779 /*MC 780 PetscStringize - Stringize a token 781 782 Synopsis: 783 #include <petscmacros.h> 784 const char* PetscStringize(x) 785 786 No Fortran Support 787 788 Input Parameter: 789 . x - The token you would like to stringize 790 791 Output Parameter: 792 . <return-value> - The string representation of `x` 793 794 Level: beginner 795 796 Note: 797 `PetscStringize()` expands `x` before stringizing it, if you do not wish to do so, use 798 `PetscStringize_()` instead. 799 800 Example Usage: 801 .vb 802 #define MY_OTHER_VAR hello there 803 #define MY_VAR MY_OTHER_VAR 804 805 PetscStringize(MY_VAR) -> "hello there" 806 PetscStringize_(MY_VAR) -> "MY_VAR" 807 808 int foo; 809 PetscStringize(foo) -> "foo" 810 PetscStringize_(foo) -> "foo" 811 .ve 812 813 .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()` 814 M*/ 815 #define PetscStringize_(...) #__VA_ARGS__ 816 #define PetscStringize(...) PetscStringize_(__VA_ARGS__) 817 818 /*MC 819 PetscConcat - Concatenate two tokens 820 821 Synopsis: 822 #include <petscmacros.h> 823 <macro-expansion> PetscConcat(x, y) 824 825 No Fortran Support 826 827 Input Parameters: 828 + x - First token 829 - y - Second token 830 831 Level: beginner 832 833 Note: 834 `PetscConcat()` will expand both arguments before pasting them together, use `PetscConcat_()` 835 if you don't want to expand them. 836 837 Example usage: 838 .vb 839 PetscConcat(hello,there) -> hellothere 840 841 #define HELLO hello 842 PetscConcat(HELLO,there) -> hellothere 843 PetscConcat_(HELLO,there) -> HELLOthere 844 .ve 845 846 .seealso: `PetscStringize()`, `PetscExpand()` 847 M*/ 848 #define PetscConcat_(x, y) x##y 849 #define PetscConcat(x, y) PetscConcat_(x, y) 850 851 #define PETSC_INTERNAL_COMPL_0 1 852 #define PETSC_INTERNAL_COMPL_1 0 853 854 /*MC 855 PetscCompl - Expands to the integer complement of its argument 856 857 Synopsis: 858 #include <petscmacros.h> 859 int PetscCompl(b) 860 861 No Fortran Support 862 863 Input Parameter: 864 . b - Preprocessor variable, must expand to either integer literal 0 or 1 865 866 Output Parameter: 867 . <return-value> - Either integer literal 0 or 1 868 869 Level: beginner 870 871 Notes: 872 Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to 873 0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its 874 argument before returning the complement. 875 876 This macro can be useful for negating `PetscDefined()` inside macros e.g. 877 878 $ #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO)) 879 880 Example usage: 881 .vb 882 #define MY_VAR 1 883 PetscCompl(MY_VAR) -> 0 884 885 #undef MY_VAR 886 #define MY_VAR 0 887 PetscCompl(MY_VAR) -> 1 888 .ve 889 890 .seealso: `PetscConcat()`, `PetscDefined()` 891 M*/ 892 #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b)) 893 894 /*MC 895 PetscDefined - Determine whether a boolean macro is defined 896 897 Synopsis: 898 #include <petscmacros.h> 899 int PetscDefined(def) 900 901 No Fortran Support 902 903 Input Parameter: 904 . def - PETSc-style preprocessor variable (without PETSC_ prepended!) 905 906 Output Parameter: 907 . <return-value> - Either integer literal 0 or 1 908 909 Level: intermediate 910 911 Notes: 912 `PetscDefined()` returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to 913 integer literal 1. In all other cases, `PetscDefined()` returns integer literal 0. Therefore 914 this macro should not be used if its argument may be defined to a non-empty value other than 915 1. 916 917 The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to 918 add custom checks in user code, one should use `PetscDefined_()`. 919 920 $ #define FooDefined(d) PetscDefined_(PetscConcat(FOO_, d)) 921 922 Developer Notes: 923 Getting something that works in C and CPP for an arg that may or may not be defined is 924 tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define, 925 insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks 926 the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair, 927 and when the last step cherry picks the 2nd arg, we get a zero. 928 929 Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a 930 nonconforming implementation of variadic macros. 931 932 Example Usage: 933 Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG 934 is defined then 935 936 .vb 937 #if PetscDefined(USE_DEBUG) 938 foo(); 939 #else 940 bar(); 941 #endif 942 943 // or alternatively within normal code 944 if (PetscDefined(USE_DEBUG)) { 945 foo(); 946 } else { 947 bar(); 948 } 949 .ve 950 951 is equivalent to 952 953 .vb 954 #if defined(PETSC_USE_DEBUG) 955 # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro 956 foo(); 957 # elif PETSC_USE_DEBUG == 1 958 foo(); 959 # else 960 bar(); 961 # endif 962 #else 963 bar(); 964 #endif 965 .ve 966 967 .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`, 968 `PetscExpandToNothing()`, `PetscCompl()` 969 M*/ 970 #define PetscDefined_arg_1 shift, 971 #define PetscDefined_arg_ shift, 972 #define PetscDefined__take_second_expanded(ignored, val, ...) val 973 #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args 974 #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__)) 975 #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_) 976 #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_, value)) 977 #define PetscDefined(def) PetscDefined_(PetscConcat(PETSC_, def)) 978 979 /*MC 980 PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding 981 the check in optimized mode 982 983 Synopsis: 984 #include <petscmacros.h> 985 bool PetscUnlikelyDebug(bool cond) 986 987 No Fortran Support 988 989 Not Collective 990 991 Input Parameter: 992 . cond - Boolean expression 993 994 Level: advanced 995 996 Note: 997 This returns the same truth value, it is only a hint to compilers that the result of `cond` is 998 likely to be false. When PETSc is compiled in optimized mode this will always return 999 false. Additionally, `cond` is guaranteed to not be evaluated when PETSc is compiled in 1000 optimized mode. 1001 1002 Example usage: 1003 This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG) 1004 is true. So 1005 1006 .vb 1007 if (PetscUnlikelyDebug(cond)) { 1008 foo(); 1009 } else { 1010 bar(); 1011 } 1012 .ve 1013 1014 is equivalent to 1015 1016 .vb 1017 if (PetscDefined(USE_DEBUG)) { 1018 if (PetscUnlikely(cond)) { 1019 foo(); 1020 } else { 1021 bar(); 1022 } 1023 } else { 1024 bar(); 1025 } 1026 .ve 1027 1028 .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ` 1029 M*/ 1030 #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond)) 1031 1032 #if defined(PETSC_CLANG_STATIC_ANALYZER) 1033 // silence compiler warnings when using -pedantic, this is only used by the linter and it cares 1034 // not what ISO C allows 1035 #define PetscMacroReturns_(retexpr, ...) \ 1036 __extension__({ \ 1037 __VA_ARGS__; \ 1038 retexpr; \ 1039 }) 1040 #else 1041 #define PetscMacroReturns_(retexpr, ...) \ 1042 retexpr; \ 1043 do { \ 1044 __VA_ARGS__; \ 1045 } while (0) 1046 #endif 1047 1048 /*MC 1049 PetscExpandToNothing - Expands to absolutely nothing 1050 1051 Synopsis: 1052 #include <petscmacros.h> 1053 void PetscExpandToNothing(...) 1054 1055 No Fortran Support 1056 1057 Input Parameter: 1058 . __VA_ARGS__ - Anything at all 1059 1060 Level: beginner 1061 1062 Note: 1063 Must have at least 1 parameter. 1064 1065 Example usage: 1066 .vb 1067 PetscExpandToNothing(a,b,c) -> *nothing* 1068 .ve 1069 1070 .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()` 1071 M*/ 1072 #define PetscExpandToNothing(...) 1073 1074 /*MC 1075 PetscMacroReturns - Define a macro body that returns a value 1076 1077 Synopsis: 1078 #include <petscmacros.h> 1079 return_type PetscMacroReturns(return_type retexpr, ...) 1080 1081 Input Parameters: 1082 + retexpr - The value or expression that the macro should return 1083 - __VA_ARGS__ - The body of the macro 1084 1085 Level: intermediate 1086 1087 Notes: 1088 Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the 1089 body of the macro and should not depend on values produced as a result of the expression. The 1090 user should not assume that the result of this macro is equivalent to a single logical source 1091 line. It is not portable to use macros defined using this one in conditional or loop bodies 1092 without enclosing them in curly braces\: 1093 1094 .vb 1095 #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0 1096 1097 int err,x = 10; 1098 1099 if (...) err = FOO(x); // ERROR, body of FOO() executed outside the if statement 1100 if (...) { err = FOO(x); } // OK 1101 1102 for (...) err = FOO(x); // ERROR, body of FOO() executed outside the loop 1103 for (...) { err = FOO(x); } // OK 1104 .ve 1105 1106 It is also not portable to use this macro directly inside function call, conditional, loop, 1107 or switch statements\: 1108 1109 .vb 1110 extern void bar(int); 1111 1112 int ret = FOO(x); 1113 1114 bar(FOO(x)); // ERROR, may not compile 1115 bar(ret); // OK 1116 1117 if (FOO(x)) // ERROR, may not compile 1118 if (ret) // OK 1119 .ve 1120 1121 Example usage: 1122 .vb 1123 #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10) 1124 1125 int x = 10; 1126 int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20 1127 1128 // multiline macros allowed, but must declare with line continuation as usual 1129 #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \ 1130 if (arg1 > 10) { \ 1131 puts("big int!"); \ 1132 } else { \ 1133 return 7355608; \ 1134 } \ 1135 ) 1136 1137 // if retexpr contains commas, must enclose it with braces 1138 #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...) 1139 #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...) 1140 1141 int x = 10; 1142 int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0 1143 int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20 1144 .ve 1145 1146 .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()` 1147 M*/ 1148 #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__) 1149 1150 #define PetscMacroReturnStandard(...) PetscMacroReturns(PETSC_SUCCESS, __VA_ARGS__) 1151 1152 /*MC 1153 PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array 1154 1155 Synopsis: 1156 #include <petscmacros.h> 1157 size_t PETSC_STATIC_ARRAY_LENGTH(a) 1158 1159 Input Parameter: 1160 . a - a static array of any type 1161 1162 Output Parameter: 1163 . <return-value> - the length of the array 1164 1165 Example: 1166 .vb 1167 PetscInt a[22]; 1168 size_t sa = PETSC_STATIC_ARRAY_LENGTH(a) 1169 .ve 1170 `sa` will have a value of 22 1171 1172 Level: intermediate 1173 M*/ 1174 #define PETSC_STATIC_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) 1175 1176 /* 1177 These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro. 1178 1179 Example usage: 1180 1181 #define mymacro(obj,...) { 1182 PETSC_FIRST_ARG((__VA_ARGS__,unused)); 1183 f(22 PETSC_REST_ARG(__VA_ARGS__)); 1184 } 1185 1186 Note you add a dummy extra argument to __VA_ARGS__ and enclose them in an extra set of () for PETSC_FIRST_ARG() and PETSC_REST_ARG(__VA_ARGS__) automatically adds a leading comma only if there are additional arguments 1187 1188 Reference: 1189 https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick 1190 */ 1191 #define PETSC_FIRST_ARG_(N, ...) N 1192 #define PETSC_FIRST_ARG(args) PETSC_FIRST_ARG_ args 1193 #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16 1194 #define PETSC_NUM(...) PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) 1195 #define PETSC_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__ 1196 #define PETSC_REST_HELPER_ONE(first) 1197 #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__) 1198 #define PETSC_REST_HELPER(qty, ...) PETSC_REST_HELPER2(qty, __VA_ARGS__) 1199 #define PETSC_REST_ARG(...) PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__) 1200 1201 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(name, ...) \ 1202 _Pragma(PetscStringize(name diagnostic push)) \ 1203 _Pragma(PetscStringize(name diagnostic ignored __VA_ARGS__)) 1204 1205 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(name) _Pragma(PetscStringize(name diagnostic pop)) 1206 1207 #if defined(__clang__) 1208 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(clang, __VA_ARGS__) 1209 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END() PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(clang) 1210 #elif defined(__GNUC__) || defined(__GNUG__) 1211 // gcc >= 4.6.0 1212 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600 1213 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(GCC, __VA_ARGS__) 1214 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END() PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(GCC) 1215 #endif 1216 #endif 1217 1218 #ifndef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN 1219 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) 1220 #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END(...) 1221 // only undefine these if they are not used 1222 #undef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_ 1223 #undef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_ 1224 #endif 1225 1226 /* OpenMP support */ 1227 #if defined(_OPENMP) 1228 #if defined(_MSC_VER) 1229 #define PetscPragmaOMP(...) __pragma(__VA_ARGS__) 1230 #else 1231 #define PetscPragmaOMP(...) _Pragma(PetscStringize(omp __VA_ARGS__)) 1232 #endif 1233 #endif 1234 1235 #ifndef PetscPragmaOMP 1236 #define PetscPragmaOMP(...) 1237 #endif 1238 1239 /* PetscPragmaSIMD - from CeedPragmaSIMD */ 1240 #if defined(__NEC__) 1241 #define PetscPragmaSIMD _Pragma("_NEC ivdep") 1242 #elif defined(__INTEL_COMPILER) && !defined(_WIN32) 1243 #define PetscPragmaSIMD _Pragma("vector") 1244 #elif defined(__GNUC__) 1245 #if __GNUC__ >= 5 && !defined(__PGI) 1246 #define PetscPragmaSIMD _Pragma("GCC ivdep") 1247 #endif 1248 #elif defined(_OPENMP) && _OPENMP >= 201307 1249 #define PetscPragmaSIMD PetscPragmaOMP(simd) 1250 #elif defined(PETSC_HAVE_CRAY_VECTOR) 1251 #define PetscPragmaSIMD _Pragma("_CRI ivdep") 1252 #endif 1253 1254 #ifndef PetscPragmaSIMD 1255 #define PetscPragmaSIMD 1256 #endif 1257 1258 #include <petsc/private/petscadvancedmacros.h> 1259 1260 #define PetscConcat6_(a, b, c, d, e, f) a##b##c##d##e##f 1261 #define PetscConcat6(a, b, c, d, e, f) PetscConcat6_(a, b, c, d, e, f) 1262 1263 #define PETSC_DEPRECATED_IDENTIFIER_(__PETSC_DEPRECATION_MACRO__, __SILENCE_MACRO__, major, minor, subminor, replacement, ...) \ 1264 PetscIfPetscDefined(__SILENCE_MACRO__, PetscExpandToNothing, \ 1265 __PETSC_DEPRECATION_MACRO__)(PetscStringize(Use replacement (since version major.minor.subminor) instead. Silence this warning (as well as all others for this version) by defining PetscConcat_(PETSC_, __SILENCE_MACRO__). __VA_ARGS__)) 1266 1267 #define PETSC_DEPRECATED_IDENTIFIER(__PETSC_DEPRECATION_MACRO__, major, minor, subminor, ...) \ 1268 PETSC_DEPRECATED_IDENTIFIER_(__PETSC_DEPRECATION_MACRO__, PetscConcat6(SILENCE_DEPRECATION_WARNINGS_, major, _, minor, _, subminor), major, minor, subminor, __VA_ARGS__) 1269 1270 #define PETSC_DEPRECATED_FUNCTION(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_FUNCTION_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1271 #define PETSC_DEPRECATED_TYPEDEF(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_TYPEDEF_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1272 #define PETSC_DEPRECATED_ENUM(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_ENUM_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1273 #define PETSC_DEPRECATED_MACRO(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_MACRO_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1274 1275 #endif /* PETSC_PREPROCESSOR_MACROS_H */ 1276