TargetInfo.h revision 5f016e2cb5d11daeb237544de1c5d59f20fe1a6e
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
55f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file was developed by Chris Lattner and is distributed under
65f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// the University of Illinois Open Source License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file defines the TargetInfo and TargetInfoImpl interfaces.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_BASIC_TARGETINFO_H
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/SourceLocation.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <vector>
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <string>
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass TargetInfoImpl;
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass Diagnostic;
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace Builtin { struct Info; }
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// TargetInfo - This class exposes information about the current target set.
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// A target set consists of a primary target and zero or more secondary targets
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// which are each represented by a TargetInfoImpl object.  TargetInfo responds
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// to various queries as though it were the primary target, but keeps track of,
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// and warns about, the first query made of it that are contradictary among the
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// targets it tracks.  For example, if it contains a "PPC32" and "PPC64"
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// target, it will warn the first time the size of the 'long' datatype is
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// queried.
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Note that TargetInfo does not take ownership of the various targets or the
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// diagnostic info, but does expect them to be alive for as long as it is.
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass TargetInfo {
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Primary - This tracks the primary target in the target set.
415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const TargetInfoImpl *PrimaryTarget;
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SecondaryTargets - This tracks the set of secondary targets.
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::vector<const TargetInfoImpl*> SecondaryTargets;
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Diag - If non-null, this object is used to report the first use of
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// non-portable functionality in the translation unit.
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Diagnostic *Diag;
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NonPortable - This instance variable keeps track of whether or not the
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// current translation unit is portable across the set of targets tracked.
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool NonPortable;
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// These are all caches for target values.
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned WCharWidth;
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TargetInfo(const TargetInfoImpl *Primary, Diagnostic *D = 0) {
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PrimaryTarget = Primary;
635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag = D;
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NonPortable = false;
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Initialize Cache values to uncomputed.
675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    WCharWidth = 0;
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isNonPortable - Return true if the current translation unit has used a
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// target property that is non-portable across the secondary targets.
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isNonPortable() const {
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return NonPortable;
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isPortable - Return true if this translation unit is portable across the
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// secondary targets so far.
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isPortable() const {
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return !NonPortable;
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// AddSecondaryTarget - Add a secondary target to the target set.
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void AddSecondaryTarget(const TargetInfoImpl *Secondary) {
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SecondaryTargets.push_back(Secondary);
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///===---- Target property query methods --------------------------------===//
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// DiagnoseNonPortability - Emit a diagnostic indicating that the current
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// translation unit is non-portable due to a construct at the specified
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// location.  DiagKind indicates what went wrong.
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void DiagnoseNonPortability(SourceLocation Loc, unsigned DiagKind);
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getTargetDefines - Appends the target-specific #define values for this
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// target set to the specified buffer.
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void getTargetDefines(std::vector<char> &DefineBuffer);
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isCharSigned - Return true if 'char' is 'signed char' or false if it is
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// treated as 'unsigned char'.  This is implementation defined according to
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// C99 6.2.5p15.  In our implementation, this is target-specific.
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isCharSigned(SourceLocation Loc) {
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FIXME: implement correctly.
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return true;
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getPointerWidth - Return the width of pointers on this target, we
1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// currently assume one pointer type.
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getPointerWidth(SourceLocation Loc) {
1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 32;   // FIXME: implement correctly.
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getBoolWidth - Return the size of '_Bool' and C++ 'bool' for this target,
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// in bits.
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getBoolWidth(SourceLocation Loc) {
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 8;    // FIXME: implement correctly: wrong for ppc32.
1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getCharWidth - Return the size of 'char', 'signed char' and
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// 'unsigned char' for this target, in bits.
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getCharWidth(SourceLocation Loc) {
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 8; // FIXME: implement correctly.
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getShortWidth - Return the size of 'signed short' and 'unsigned short' for
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// this target, in bits.
1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getShortWidth(SourceLocation Loc) {
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 16; // FIXME: implement correctly.
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getIntWidth - Return the size of 'signed int' and 'unsigned int' for this
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// target, in bits.
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getIntWidth(SourceLocation Loc) {
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 32; // FIXME: implement correctly.
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getLongWidth - Return the size of 'signed long' and 'unsigned long' for
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// this target, in bits.
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getLongWidth(SourceLocation Loc) {
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 32;  // FIXME: implement correctly: wrong for ppc64/x86-64
1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getLongLongWidth - Return the size of 'signed long long' and
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// 'unsigned long long' for this target, in bits.
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getLongLongWidth(SourceLocation Loc) {
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 64; // FIXME: implement correctly.
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getWCharWidth - Return the size of wchar_t in bits.
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getWCharWidth(SourceLocation Loc) {
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (!WCharWidth) ComputeWCharWidth(Loc);
1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return WCharWidth;
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// target, in bits.
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getIntMaxTWidth(SourceLocation Loc) {
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FIXME: implement correctly.
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 64;
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getTargetBuiltins - Return information about target-specific builtins for
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// the current primary target, and info about which builtins are non-portable
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// across the current set of primary and secondary targets.
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords,
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                         std::vector<const char *> &NonPortableBuiltins) const;
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ComputeWCharWidth(SourceLocation Loc);
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// TargetInfoImpl - This class is implemented for specific targets and is used
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// by the TargetInfo class.  Target implementations should initialize instance
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// variables and implement various virtual methods if the default values are
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// not appropriate for the target.
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass TargetInfoImpl {
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned WCharWidth;    /// sizeof(wchar_t) in bits.  Default value is 32.
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TargetInfoImpl() : WCharWidth(32) {}
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual ~TargetInfoImpl() {}
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getTargetDefines - Return a list of the target-specific #define values set
1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// when compiling to this target.  Each string should be of the form "X",
1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// which results in '#define X 1' or "X=Y" which results in "#define X Y"
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getTargetDefines(std::vector<std::string> &Defines) const = 0;
1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getWCharWidth - Return the size of wchar_t in bits.
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned getWCharWidth() const { return WCharWidth; }
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getTargetBuiltins - Return information about target-specific builtins for
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// the target.
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void getTargetBuiltins(const Builtin::Info *&Records,
1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                 unsigned &NumRecords) const {
1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Records = 0;
2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NumRecords = 0;
2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void ANCHOR(); // out-of-line virtual method for class.
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
209