]> granicus.if.org Git - clang/commitdiff
Add new methods for TargetInfo:
authorStepan Dyatkovskiy <stpworld@narod.ru>
Thu, 5 Sep 2013 11:23:21 +0000 (11:23 +0000)
committerStepan Dyatkovskiy <stpworld@narod.ru>
Thu, 5 Sep 2013 11:23:21 +0000 (11:23 +0000)
     getRealTypeByWidth and getIntTypeByWidth
  for ASTContext names are almost same(invokes new methods from TargetInfo):
     getIntTypeForBitwidth and getRealTypeForBitwidth.

As first commit for PR16752 fix: 'mode' attribute for unusual targets doesn't work properly
Description:
Troubles could be happened due to some assumptions in handleModeAttr function (see SemaDeclAttr.cpp).
For example, it assumes that 32 bit integer is 'int', while it could be 16 bit only.
Instead of asking target: 'which type do you want to use for int32_t ?' it just hardcodes general opinion. That doesn't looks pretty correct.
Please consider the next solution:
1. In Basic/TargetInfo add getIntTypeByWidth and getRealTypeByWidth virtual methods. By default current behaviour could be implemented here.
2. Fix handleModeAttr according to new methods in TargetInfo.
This approach is implemented in the patch attached to this post.

Fixes:
1st Commit (Current): Add new methods for TargetInfo:
     getRealTypeByWidth and getIntTypeByWidth
  for ASTContext names are almost same(invokes new methods from TargetInfo):
     getIntTypeForBitwidth and getRealTypeForBitwidth

2nd Commit (Next): Fix SemaDeclAttr, handleModeAttr function.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190044 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
include/clang/Basic/TargetInfo.h
lib/AST/ASTContext.cpp
lib/Basic/TargetInfo.cpp
lib/Frontend/InitPreprocessor.cpp

index 6f27fbee0e7100da0d854b2f1353f2e8fd535eba..377282ff657e9c680630374291baf6a160324042 100644 (file)
@@ -480,6 +480,17 @@ public:
 
   const TargetInfo &getTargetInfo() const { return *Target; }
   
+  /// getIntTypeForBitwidth -
+  /// sets integer QualTy according to specified details:
+  /// bitwidth, signed/unsigned.
+  /// Returns empty type if there is no appropriate target types.
+  QualType getIntTypeForBitwidth(unsigned DestWidth,
+                                 unsigned Signed) const;
+  /// getRealTypeForBitwidth -
+  /// sets floating point QualTy according to specified bitwidth.
+  /// Returns empty type if there is no appropriate target types.
+  QualType getRealTypeForBitwidth(unsigned DestWidth) const;
+
   bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
   
   const LangOptions& getLangOpts() const { return LangOpts; }
index 1073711ce4a49aac93237200b34ae8448c1c78f3..c5dc390be97a2c029a548c26df9a9b12cf441fc6 100644 (file)
@@ -112,6 +112,8 @@ public:
   ///===---- Target Data Type Query Methods -------------------------------===//
   enum IntType {
     NoInt = 0,
+    SignedChar,
+    UnsignedChar,
     SignedShort,
     UnsignedShort,
     SignedInt,
@@ -123,6 +125,7 @@ public:
   };
 
   enum RealType {
+    NoFloat = 255,
     Float = 0,
     Double,
     LongDouble
@@ -220,6 +223,12 @@ public:
   /// For example, SignedInt -> getIntWidth().
   unsigned getTypeWidth(IntType T) const;
 
+  /// \brief Return integer type with specified width.
+  IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
+
+  /// \brief Return floating point type with specified width.
+  RealType getRealTypeByWidth(unsigned BitWidth) const;
+
   /// \brief Return the alignment (in bits) of the specified integer type enum.
   ///
   /// For example, SignedInt -> getIntAlign().
index 94d9e918e75d3d5d097f05273e87fbefb8862766..85ac734a45c073b04435b41bd8dae7d39ded82f3 100644 (file)
@@ -6314,6 +6314,8 @@ ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
 CanQualType ASTContext::getFromTargetType(unsigned Type) const {
   switch (Type) {
   case TargetInfo::NoInt: return CanQualType();
+  case TargetInfo::SignedChar: return SignedCharTy;
+  case TargetInfo::UnsignedChar: return UnsignedCharTy;
   case TargetInfo::SignedShort: return ShortTy;
   case TargetInfo::UnsignedShort: return UnsignedShortTy;
   case TargetInfo::SignedInt: return IntTy;
@@ -7990,6 +7992,38 @@ size_t ASTContext::getSideTableAllocatedMemory() const {
          llvm::capacity_in_bytes(ClassScopeSpecializationPattern);
 }
 
+/// getIntTypeForBitwidth -
+/// sets integer QualTy according to specified details:
+/// bitwidth, signed/unsigned.
+/// Returns empty type if there is no appropriate target types.
+QualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth,
+                                           unsigned Signed) const {
+  TargetInfo::IntType Ty = getTargetInfo().getIntTypeByWidth(DestWidth, Signed);
+  CanQualType QualTy = getFromTargetType(Ty);
+  if (!QualTy && DestWidth == 128)
+    return Signed ? Int128Ty : UnsignedInt128Ty;
+  return QualTy;
+}
+
+/// getRealTypeForBitwidth -
+/// sets floating point QualTy according to specified bitwidth.
+/// Returns empty type if there is no appropriate target types.
+QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const {
+  TargetInfo::RealType Ty = getTargetInfo().getRealTypeByWidth(DestWidth);
+  switch (Ty) {
+  case TargetInfo::Float:
+    return FloatTy;
+  case TargetInfo::Double:
+    return DoubleTy;
+  case TargetInfo::LongDouble:
+    return LongDoubleTy;
+  case TargetInfo::NoFloat:
+    return QualType();
+  }
+
+  llvm_unreachable("Unhandled TargetInfo::RealType value");
+}
+
 void ASTContext::setManglingNumber(const NamedDecl *ND, unsigned Number) {
   if (Number > 1)
     MangleNumbers[ND] = Number;
index f8c10d1c02603380f4b2e9c4e9d2e321cc966f5f..94d90d366ea1208333ccfcafa7bc3ef8233725b5 100644 (file)
@@ -102,6 +102,8 @@ TargetInfo::~TargetInfo() {}
 const char *TargetInfo::getTypeName(IntType T) {
   switch (T) {
   default: llvm_unreachable("not an integer!");
+  case SignedChar:       return "char";
+  case UnsignedChar:     return "unsigned char";
   case SignedShort:      return "short";
   case UnsignedShort:    return "unsigned short";
   case SignedInt:        return "int";
@@ -118,10 +120,12 @@ const char *TargetInfo::getTypeName(IntType T) {
 const char *TargetInfo::getTypeConstantSuffix(IntType T) {
   switch (T) {
   default: llvm_unreachable("not an integer!");
+  case SignedChar:
   case SignedShort:
   case SignedInt:        return "";
   case SignedLong:       return "L";
   case SignedLongLong:   return "LL";
+  case UnsignedChar:
   case UnsignedShort:
   case UnsignedInt:      return "U";
   case UnsignedLong:     return "UL";
@@ -134,6 +138,8 @@ const char *TargetInfo::getTypeConstantSuffix(IntType T) {
 unsigned TargetInfo::getTypeWidth(IntType T) const {
   switch (T) {
   default: llvm_unreachable("not an integer!");
+  case SignedChar:
+  case UnsignedChar:     return getCharWidth();
   case SignedShort:
   case UnsignedShort:    return getShortWidth();
   case SignedInt:
@@ -145,11 +151,48 @@ unsigned TargetInfo::getTypeWidth(IntType T) const {
   };
 }
 
+TargetInfo::IntType TargetInfo::getIntTypeByWidth(
+    unsigned BitWidth, bool IsSigned) const {
+  if (getCharWidth() == BitWidth)
+    return IsSigned ? SignedChar : UnsignedChar;
+  if (getShortWidth() == BitWidth)
+    return IsSigned ? SignedShort : UnsignedShort;
+  if (getIntWidth() == BitWidth)
+    return IsSigned ? SignedInt : UnsignedInt;
+  if (getLongWidth() == BitWidth)
+    return IsSigned ? SignedLong : UnsignedLong;
+  if (getLongLongWidth() == BitWidth)
+    return IsSigned ? SignedLongLong : UnsignedLongLong;
+  return NoInt;
+}
+
+TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const {
+  if (getFloatWidth() == BitWidth)
+    return Float;
+  if (getDoubleWidth() == BitWidth)
+    return Double;
+
+  switch (BitWidth) {
+  case 96:
+    if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended)
+      return LongDouble;
+    break;
+  case 128:
+    if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble)
+      return LongDouble;
+    break;
+  }
+
+  return NoFloat;
+}
+
 /// getTypeAlign - Return the alignment (in bits) of the specified integer type
 /// enum. For example, SignedInt -> getIntAlign().
 unsigned TargetInfo::getTypeAlign(IntType T) const {
   switch (T) {
   default: llvm_unreachable("not an integer!");
+  case SignedChar:
+  case UnsignedChar:     return getCharAlign();
   case SignedShort:
   case UnsignedShort:    return getShortAlign();
   case SignedInt:
@@ -166,11 +209,13 @@ unsigned TargetInfo::getTypeAlign(IntType T) const {
 bool TargetInfo::isTypeSigned(IntType T) {
   switch (T) {
   default: llvm_unreachable("not an integer!");
+  case SignedChar:
   case SignedShort:
   case SignedInt:
   case SignedLong:
   case SignedLongLong:
     return true;
+  case UnsignedChar:
   case UnsignedShort:
   case UnsignedInt:
   case UnsignedLong:
index 2eb74e0825f157a1187a9fa213735ebd29b1c17b..0d76069a8433a331db47af97c283cc315502bf88 100644 (file)
@@ -497,7 +497,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
   assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
   Builder.defineMacro("__CHAR_BIT__", "8");
 
-  DefineTypeSize("__SCHAR_MAX__", TI.getCharWidth(), "", true, Builder);
+  DefineTypeSize("__SCHAR_MAX__", TargetInfo::SignedChar, TI, Builder);
   DefineTypeSize("__SHRT_MAX__", TargetInfo::SignedShort, TI, Builder);
   DefineTypeSize("__INT_MAX__", TargetInfo::SignedInt, TI, Builder);
   DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, TI, Builder);