1a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
2a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//
3a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//                     The LLVM Compiler Infrastructure
4a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
7a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//
8a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//===----------------------------------------------------------------------===//
9a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//
10a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek// This file defines the AlignOf function that computes alignments for
11a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek// arbitrary types.
12a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//
13a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek//===----------------------------------------------------------------------===//
14a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek
15a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek#ifndef LLVM_SUPPORT_ALIGNOF_H
16a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek#define LLVM_SUPPORT_ALIGNOF_H
17a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek
18a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremeneknamespace llvm {
19fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
20a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenektemplate <typename T>
21a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenekstruct AlignmentCalcImpl {
22a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek  char x;
23a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek  T t;
24a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenekprivate:
25a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek  AlignmentCalcImpl() {} // Never instantiate.
26a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek};
27fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
28a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek/// AlignOf - A templated class that contains an enum value representing
29a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek///  the alignment of the template argument.  For example,
30a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek///  AlignOf<int>::Alignment represents the alignment of type "int".  The
31a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek///  alignment calculated is the minimum alignment, and not necessarily
32a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek///  the "desired" alignment returned by GCC's __alignof__ (for example).  Note
33a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek///  that because the alignment is an enum value, it can be used as a
34a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek///  compile-time constant (e.g., for template instantiation).
35a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenektemplate <typename T>
36a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenekstruct AlignOf {
3734cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  enum { Alignment =
3834cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng         static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)) };
399d695d5f7d31e912a2be74229b3e2baab2564820Ted Kremenek
401f801fa5ada9cb40fb97ae755c282e91af54a1bcTed Kremenek  enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
411f801fa5ada9cb40fb97ae755c282e91af54a1bcTed Kremenek  enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
421f801fa5ada9cb40fb97ae755c282e91af54a1bcTed Kremenek  enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
431f801fa5ada9cb40fb97ae755c282e91af54a1bcTed Kremenek  enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
44fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
459d695d5f7d31e912a2be74229b3e2baab2564820Ted Kremenek  enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
46fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman  enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
479d695d5f7d31e912a2be74229b3e2baab2564820Ted Kremenek  enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
489d695d5f7d31e912a2be74229b3e2baab2564820Ted Kremenek  enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
499d695d5f7d31e912a2be74229b3e2baab2564820Ted Kremenek
50a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek};
5187f3870db9d92eca87e2f42c3537efe4bfb6e9c2Ted Kremenek
526511988cd477db280c7e1057af81025a40039811Michael J. Spencer/// alignOf - A templated function that returns the minimum alignment of
5387f3870db9d92eca87e2f42c3537efe4bfb6e9c2Ted Kremenek///  of a type.  This provides no extra functionality beyond the AlignOf
5487f3870db9d92eca87e2f42c3537efe4bfb6e9c2Ted Kremenek///  class besides some cosmetic cleanliness.  Example usage:
5516c3b647eb100fe404ee65f106d563ddef6c74b7Chris Lattner///  alignOf<int>() returns the alignment of an int.
5687f3870db9d92eca87e2f42c3537efe4bfb6e9c2Ted Kremenektemplate <typename T>
5716c3b647eb100fe404ee65f106d563ddef6c74b7Chris Lattnerstatic inline unsigned alignOf() { return AlignOf<T>::Alignment; }
58fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
59a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek} // end namespace llvm
60a4d9869cf291e6f87bf9e7adfcd9a2c4e4518172Ted Kremenek#endif
61