diff options
-rw-r--r-- | clang/include/clang/AST/ASTContext.h | 11 | ||||
-rw-r--r-- | clang/include/clang/Basic/TargetInfo.h | 9 | ||||
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Basic/TargetInfo.cpp | 45 | ||||
-rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 2 |
5 files changed, 100 insertions, 1 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 6f27fbee0e7..377282ff657 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -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; } diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 1073711ce4a..c5dc390be97 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -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(). diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 94d9e918e75..85ac734a45c 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -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; diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index f8c10d1c026..94d90d366ea 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -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: diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 2eb74e0825f..0d76069a843 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -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); |