aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r--lib/AST/Type.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 24cf853555..ad5026b98b 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -510,6 +510,8 @@ bool Type::isIntegerType() const {
// FIXME: In C++, enum types are never integer types.
if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
return true;
+ if (isa<FixedWidthIntType>(CanonicalType))
+ return true;
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isIntegerType();
if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
@@ -525,6 +527,8 @@ bool Type::isIntegralType() const {
if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
return true; // Complete enum types are integral.
// FIXME: In C++, enum types are never integral.
+ if (isa<FixedWidthIntType>(CanonicalType))
+ return true;
if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
return ASQT->getBaseType()->isIntegralType();
return false;
@@ -578,6 +582,10 @@ bool Type::isSignedIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
+ if (const FixedWidthIntType *FWIT =
+ dyn_cast<FixedWidthIntType>(CanonicalType))
+ return FWIT->isSigned();
+
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isSignedIntegerType();
if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
@@ -598,6 +606,10 @@ bool Type::isUnsignedIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
+ if (const FixedWidthIntType *FWIT =
+ dyn_cast<FixedWidthIntType>(CanonicalType))
+ return !FWIT->isSigned();
+
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isUnsignedIntegerType();
if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
@@ -635,6 +647,8 @@ bool Type::isRealType() const {
BT->getKind() <= BuiltinType::LongDouble;
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
return TT->getDecl()->isEnum() && TT->getDecl()->isDefinition();
+ if (isa<FixedWidthIntType>(CanonicalType))
+ return true;
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isRealType();
if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
@@ -650,6 +664,8 @@ bool Type::isArithmeticType() const {
// GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
// If a body isn't seen by the time we get here, return false.
return ET->getDecl()->isDefinition();
+ if (isa<FixedWidthIntType>(CanonicalType))
+ return true;
if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
return ASQT->getBaseType()->isArithmeticType();
return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
@@ -667,6 +683,8 @@ bool Type::isScalarType() const {
}
if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
return ASQT->getBaseType()->isScalarType();
+ if (isa<FixedWidthIntType>(CanonicalType))
+ return true;
return isa<PointerType>(CanonicalType) ||
isa<BlockPointerType>(CanonicalType) ||
isa<MemberPointerType>(CanonicalType) ||
@@ -1014,6 +1032,21 @@ void BuiltinType::getAsStringInternal(std::string &S) const {
}
}
+void FixedWidthIntType::getAsStringInternal(std::string &S) const {
+ // FIXME: Once we get bitwidth attribute, write as
+ // "int __attribute__((bitwidth(x)))".
+ std::string prefix = "__clang_fixedwidth";
+ prefix += llvm::utostr_32(Width);
+ prefix += (char)(Signed ? 'S' : 'U');
+ if (S.empty()) {
+ S = prefix;
+ } else {
+ // Prefix the basic type, e.g. 'int X'.
+ S = prefix + S;
+ }
+}
+
+
void ComplexType::getAsStringInternal(std::string &S) const {
ElementType->getAsStringInternal(S);
S = "_Complex " + S;