LCOV - code coverage report
Current view: top level - llvm/Support - AlignOf.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 1 1 100.0 %
Date: 2016-01-31 12:01:00 Functions: 1 5 20.0 %

          Line data    Source code
       1             : //===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file defines the AlignOf function that computes alignments for
      11             : // arbitrary types.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_SUPPORT_ALIGNOF_H
      16             : #define LLVM_SUPPORT_ALIGNOF_H
      17             : 
      18             : #include "llvm/Support/Compiler.h"
      19             : #include <cstddef>
      20             : 
      21             : namespace llvm {
      22             : template <typename T>
      23             : struct AlignmentCalcImpl {
      24             :   char x;
      25             : #if defined(_MSC_VER)
      26             : // Disables "structure was padded due to __declspec(align())" warnings that are
      27             : // generated by any class using AlignOf<T> with a manually specified alignment.
      28             : // Although the warning is disabled in the LLVM project we need this pragma
      29             : // as AlignOf.h is a published support header that's available for use
      30             : // out-of-tree, and we would like that to compile cleanly at /W4.
      31             : #pragma warning(suppress : 4324)
      32             : #endif
      33             :   T t;
      34             : private:
      35             :   AlignmentCalcImpl() {} // Never instantiate.
      36             : };
      37             : 
      38             : /// AlignOf - A templated class that contains an enum value representing
      39             : ///  the alignment of the template argument.  For example,
      40             : ///  AlignOf<int>::Alignment represents the alignment of type "int".  The
      41             : ///  alignment calculated is the minimum alignment, and not necessarily
      42             : ///  the "desired" alignment returned by GCC's __alignof__ (for example).  Note
      43             : ///  that because the alignment is an enum value, it can be used as a
      44             : ///  compile-time constant (e.g., for template instantiation).
      45             : template <typename T>
      46             : struct AlignOf {
      47             : #ifndef _MSC_VER
      48             :   // Avoid warnings from GCC like:
      49             :   //   comparison between 'enum llvm::AlignOf<X>::<anonymous>' and 'enum
      50             :   //   llvm::AlignOf<Y>::<anonymous>' [-Wenum-compare]
      51             :   // by using constexpr instead of enum.
      52             :   // (except on MSVC, since it doesn't support constexpr yet).
      53             :   static constexpr unsigned Alignment =
      54             :       static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T));
      55             : #else
      56             :   enum { Alignment =
      57             :          static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)) };
      58             : #endif
      59             :   enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
      60             :   enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
      61             :   enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
      62             :   enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
      63             : 
      64             :   enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
      65             :   enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
      66             :   enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
      67             :   enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
      68             : };
      69             : 
      70             : #ifndef _MSC_VER
      71             : template <typename T> constexpr unsigned AlignOf<T>::Alignment;
      72             : #endif
      73             : 
      74             : /// alignOf - A templated function that returns the minimum alignment of
      75             : ///  of a type.  This provides no extra functionality beyond the AlignOf
      76             : ///  class besides some cosmetic cleanliness.  Example usage:
      77             : ///  alignOf<int>() returns the alignment of an int.
      78             : template <typename T>
      79          40 : inline unsigned alignOf() { return AlignOf<T>::Alignment; }
      80             : 
      81             : /// \struct AlignedCharArray
      82             : /// \brief Helper for building an aligned character array type.
      83             : ///
      84             : /// This template is used to explicitly build up a collection of aligned
      85             : /// character array types. We have to build these up using a macro and explicit
      86             : /// specialization to cope with old versions of MSVC and GCC where only an
      87             : /// integer literal can be used to specify an alignment constraint. Once built
      88             : /// up here, we can then begin to indirect between these using normal C++
      89             : /// template parameters.
      90             : 
      91             : // MSVC requires special handling here.
      92             : #ifndef _MSC_VER
      93             : 
      94             : #if __has_feature(cxx_alignas)
      95             : template<std::size_t Alignment, std::size_t Size>
      96             : struct AlignedCharArray {
      97             :   alignas(Alignment) char buffer[Size];
      98             : };
      99             : 
     100             : #elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
     101             : /// \brief Create a type with an aligned char buffer.
     102             : template<std::size_t Alignment, std::size_t Size>
     103             : struct AlignedCharArray;
     104             : 
     105             : #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
     106             :   template<std::size_t Size> \
     107             :   struct AlignedCharArray<x, Size> { \
     108             :     __attribute__((aligned(x))) char buffer[Size]; \
     109             :   };
     110             : 
     111             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1)
     112             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2)
     113             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4)
     114             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8)
     115             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
     116             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
     117             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
     118             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
     119             : 
     120             : #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
     121             : 
     122             : #else
     123             : # error No supported align as directive.
     124             : #endif
     125             : 
     126             : #else // _MSC_VER
     127             : 
     128             : /// \brief Create a type with an aligned char buffer.
     129             : template<std::size_t Alignment, std::size_t Size>
     130             : struct AlignedCharArray;
     131             : 
     132             : // We provide special variations of this template for the most common
     133             : // alignments because __declspec(align(...)) doesn't actually work when it is
     134             : // a member of a by-value function argument in MSVC, even if the alignment
     135             : // request is something reasonably like 8-byte or 16-byte. Note that we can't
     136             : // even include the declspec with the union that forces the alignment because
     137             : // MSVC warns on the existence of the declspec despite the union member forcing
     138             : // proper alignment.
     139             : 
     140             : template<std::size_t Size>
     141             : struct AlignedCharArray<1, Size> {
     142             :   union {
     143             :     char aligned;
     144             :     char buffer[Size];
     145             :   };
     146             : };
     147             : 
     148             : template<std::size_t Size>
     149             : struct AlignedCharArray<2, Size> {
     150             :   union {
     151             :     short aligned;
     152             :     char buffer[Size];
     153             :   };
     154             : };
     155             : 
     156             : template<std::size_t Size>
     157             : struct AlignedCharArray<4, Size> {
     158             :   union {
     159             :     int aligned;
     160             :     char buffer[Size];
     161             :   };
     162             : };
     163             : 
     164             : template<std::size_t Size>
     165             : struct AlignedCharArray<8, Size> {
     166             :   union {
     167             :     double aligned;
     168             :     char buffer[Size];
     169             :   };
     170             : };
     171             : 
     172             : 
     173             : // The rest of these are provided with a __declspec(align(...)) and we simply
     174             : // can't pass them by-value as function arguments on MSVC.
     175             : 
     176             : #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
     177             :   template<std::size_t Size> \
     178             :   struct AlignedCharArray<x, Size> { \
     179             :     __declspec(align(x)) char buffer[Size]; \
     180             :   };
     181             : 
     182             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
     183             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
     184             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
     185             : LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
     186             : 
     187             : #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
     188             : 
     189             : #endif // _MSC_VER
     190             : 
     191             : namespace detail {
     192             : template <typename T1,
     193             :           typename T2 = char, typename T3 = char, typename T4 = char,
     194             :           typename T5 = char, typename T6 = char, typename T7 = char,
     195             :           typename T8 = char, typename T9 = char, typename T10 = char>
     196             : class AlignerImpl {
     197             :   T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
     198             : 
     199             :   AlignerImpl(); // Never defined or instantiated.
     200             : };
     201             : 
     202             : template <typename T1,
     203             :           typename T2 = char, typename T3 = char, typename T4 = char,
     204             :           typename T5 = char, typename T6 = char, typename T7 = char,
     205             :           typename T8 = char, typename T9 = char, typename T10 = char>
     206             : union SizerImpl {
     207             :   char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
     208             :        arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
     209             :        arr9[sizeof(T9)], arr10[sizeof(T10)];
     210             : };
     211             : } // end namespace detail
     212             : 
     213             : /// \brief This union template exposes a suitably aligned and sized character
     214             : /// array member which can hold elements of any of up to ten types.
     215             : ///
     216             : /// These types may be arrays, structs, or any other types. The goal is to
     217             : /// expose a char array buffer member which can be used as suitable storage for
     218             : /// a placement new of any of these types. Support for more than ten types can
     219             : /// be added at the cost of more boilerplate.
     220             : template <typename T1,
     221             :           typename T2 = char, typename T3 = char, typename T4 = char,
     222             :           typename T5 = char, typename T6 = char, typename T7 = char,
     223             :           typename T8 = char, typename T9 = char, typename T10 = char>
     224             : struct AlignedCharArrayUnion : llvm::AlignedCharArray<
     225             :     AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5,
     226             :                                 T6, T7, T8, T9, T10> >::Alignment,
     227             :     sizeof(detail::SizerImpl<T1, T2, T3, T4, T5,
     228             :                              T6, T7, T8, T9, T10>)> {
     229             : };
     230             : } // end namespace llvm
     231             : #endif

Generated by: LCOV version 1.11