my_compiler.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #ifndef MY_COMPILER_INCLUDED
  2. #define MY_COMPILER_INCLUDED
  3. /* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; version 2 of the License.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
  14. /**
  15. Header for compiler-dependent features.
  16. Intended to contain a set of reusable wrappers for preprocessor
  17. macros, attributes, pragmas, and any other features that are
  18. specific to a target compiler.
  19. */
  20. #include <my_global.h> /* stddef.h offsetof */
  21. /**
  22. Compiler-dependent internal convenience macros.
  23. */
  24. /* GNU C/C++ */
  25. #if defined __GNUC__
  26. /* Convenience macro to test the minimum required GCC version. */
  27. # define MY_GNUC_PREREQ(maj, min) \
  28. ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
  29. /* Any after 2.95... */
  30. # define MY_ALIGN_EXT
  31. /* Comunicate to the compiler the unreachability of the code. */
  32. # if MY_GNUC_PREREQ(4,5)
  33. # define MY_ASSERT_UNREACHABLE() __builtin_unreachable()
  34. # endif
  35. /* Microsoft Visual C++ */
  36. #elif defined _MSC_VER
  37. # define MY_ALIGNOF(type) __alignof(type)
  38. # define MY_ALIGNED(n) __declspec(align(n))
  39. /* Oracle Solaris Studio */
  40. #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
  41. # if __SUNPRO_C >= 0x590
  42. # define MY_ALIGN_EXT
  43. # endif
  44. /* IBM XL C/C++ */
  45. #elif defined __xlC__
  46. # if __xlC__ >= 0x0600
  47. # define MY_ALIGN_EXT
  48. # endif
  49. /* HP aCC */
  50. #elif defined(__HP_aCC) || defined(__HP_cc)
  51. # if (__HP_aCC >= 60000) || (__HP_cc >= 60000)
  52. # define MY_ALIGN_EXT
  53. # endif
  54. #endif
  55. #ifdef MY_ALIGN_EXT
  56. /** Specifies the minimum alignment of a type. */
  57. # define MY_ALIGNOF(type) __alignof__(type)
  58. /** Determine the alignment requirement of a type. */
  59. # define MY_ALIGNED(n) __attribute__((__aligned__((n))))
  60. #endif
  61. /**
  62. Generic (compiler-independent) features.
  63. */
  64. #ifndef MY_GNUC_PREREQ
  65. # define MY_GNUC_PREREQ(maj, min) (0)
  66. #endif
  67. #ifndef MY_ALIGNOF
  68. # ifdef __cplusplus
  69. template<typename type> struct my_alignof_helper { char m1; type m2; };
  70. /* Invalid for non-POD types, but most compilers give the right answer. */
  71. # define MY_ALIGNOF(type) offsetof(my_alignof_helper<type>, m2)
  72. # else
  73. # define MY_ALIGNOF(type) offsetof(struct { char m1; type m2; }, m2)
  74. # endif
  75. #endif
  76. #ifndef MY_ASSERT_UNREACHABLE
  77. # define MY_ASSERT_UNREACHABLE() do { assert(0); } while (0)
  78. #endif
  79. /**
  80. C++ Type Traits
  81. */
  82. #ifdef __cplusplus
  83. /**
  84. Opaque storage with a particular alignment.
  85. */
  86. # if defined(MY_ALIGNED)
  87. /* Partial specialization used due to MSVC++. */
  88. template<size_t alignment> struct my_alignment_imp;
  89. template<> struct MY_ALIGNED(1) my_alignment_imp<1> {};
  90. template<> struct MY_ALIGNED(2) my_alignment_imp<2> {};
  91. template<> struct MY_ALIGNED(4) my_alignment_imp<4> {};
  92. template<> struct MY_ALIGNED(8) my_alignment_imp<8> {};
  93. template<> struct MY_ALIGNED(16) my_alignment_imp<16> {};
  94. /* ... expand as necessary. */
  95. # else
  96. template<size_t alignment>
  97. struct my_alignment_imp { double m1; };
  98. # endif
  99. /**
  100. A POD type with a given size and alignment.
  101. @remark If the compiler does not support a alignment attribute
  102. (MY_ALIGN macro), the default alignment of a double is
  103. used instead.
  104. @tparam size The minimum size.
  105. @tparam alignment The desired alignment: 1, 2, 4, 8 or 16.
  106. */
  107. template <size_t size, size_t alignment>
  108. struct my_aligned_storage
  109. {
  110. union
  111. {
  112. char data[size];
  113. my_alignment_imp<alignment> align;
  114. };
  115. };
  116. #endif /* __cplusplus */
  117. # ifndef MY_ALIGNED
  118. /*
  119. Make sure MY_ALIGNED can be used also on platforms where we don't
  120. have a way of aligning data structures.
  121. */
  122. #define MY_ALIGNED(size)
  123. #endif
  124. #include <my_attribute.h>
  125. #endif /* MY_COMPILER_INCLUDED */