summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp143
-rw-r--r--clang/lib/AST/ExprConstant.cpp9
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp18
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp18
-rw-r--r--clang/lib/AST/NSAPI.cpp18
-rw-r--r--clang/lib/AST/Type.cpp36
-rw-r--r--clang/lib/AST/TypeLoc.cpp18
-rw-r--r--clang/lib/Analysis/PrintfFormatString.cpp18
-rw-r--r--clang/lib/Basic/TargetInfo.cpp3
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp18
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp18
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp18
-rw-r--r--clang/lib/Index/USRGeneration.cpp18
-rw-r--r--clang/lib/Parse/ParseDecl.cpp35
-rw-r--r--clang/lib/Sema/DeclSpec.cpp26
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp1
-rw-r--r--clang/lib/Sema/SemaType.cpp80
-rw-r--r--clang/lib/Serialization/ASTCommon.cpp54
-rw-r--r--clang/lib/Serialization/ASTReader.cpp54
19 files changed, 559 insertions, 44 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 64f45af6189..de32de5dca6 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1135,12 +1135,30 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
InitBuiltinType(Float16Ty, BuiltinType::Float16);
// ISO/IEC JTC1 SC22 WG14 N1169 Extension
- InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum);
- InitBuiltinType(AccumTy, BuiltinType::Accum);
- InitBuiltinType(LongAccumTy, BuiltinType::LongAccum);
- InitBuiltinType(UnsignedShortAccumTy, BuiltinType::UShortAccum);
- InitBuiltinType(UnsignedAccumTy, BuiltinType::UAccum);
- InitBuiltinType(UnsignedLongAccumTy, BuiltinType::ULongAccum);
+ InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum);
+ InitBuiltinType(AccumTy, BuiltinType::Accum);
+ InitBuiltinType(LongAccumTy, BuiltinType::LongAccum);
+ InitBuiltinType(UnsignedShortAccumTy, BuiltinType::UShortAccum);
+ InitBuiltinType(UnsignedAccumTy, BuiltinType::UAccum);
+ InitBuiltinType(UnsignedLongAccumTy, BuiltinType::ULongAccum);
+ InitBuiltinType(ShortFractTy, BuiltinType::ShortFract);
+ InitBuiltinType(FractTy, BuiltinType::Fract);
+ InitBuiltinType(LongFractTy, BuiltinType::LongFract);
+ InitBuiltinType(UnsignedShortFractTy, BuiltinType::UShortFract);
+ InitBuiltinType(UnsignedFractTy, BuiltinType::UFract);
+ InitBuiltinType(UnsignedLongFractTy, BuiltinType::ULongFract);
+ InitBuiltinType(SatShortAccumTy, BuiltinType::SatShortAccum);
+ InitBuiltinType(SatAccumTy, BuiltinType::SatAccum);
+ InitBuiltinType(SatLongAccumTy, BuiltinType::SatLongAccum);
+ InitBuiltinType(SatUnsignedShortAccumTy, BuiltinType::SatUShortAccum);
+ InitBuiltinType(SatUnsignedAccumTy, BuiltinType::SatUAccum);
+ InitBuiltinType(SatUnsignedLongAccumTy, BuiltinType::SatULongAccum);
+ InitBuiltinType(SatShortFractTy, BuiltinType::SatShortFract);
+ InitBuiltinType(SatFractTy, BuiltinType::SatFract);
+ InitBuiltinType(SatLongFractTy, BuiltinType::SatLongFract);
+ InitBuiltinType(SatUnsignedShortFractTy, BuiltinType::SatUShortFract);
+ InitBuiltinType(SatUnsignedFractTy, BuiltinType::SatUFract);
+ InitBuiltinType(SatUnsignedLongFractTy, BuiltinType::SatULongFract);
// GNU extension, 128-bit integers.
InitBuiltinType(Int128Ty, BuiltinType::Int128);
@@ -1795,19 +1813,46 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;
case BuiltinType::ShortAccum:
case BuiltinType::UShortAccum:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatUShortAccum:
Width = Target->getShortAccumWidth();
Align = Target->getShortAccumAlign();
break;
case BuiltinType::Accum:
case BuiltinType::UAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatUAccum:
Width = Target->getAccumWidth();
Align = Target->getAccumAlign();
break;
case BuiltinType::LongAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatULongAccum:
Width = Target->getLongAccumWidth();
Align = Target->getLongAccumAlign();
break;
+ case BuiltinType::ShortFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatUShortFract:
+ Width = Target->getShortFractWidth();
+ Align = Target->getShortFractAlign();
+ break;
+ case BuiltinType::Fract:
+ case BuiltinType::UFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatUFract:
+ Width = Target->getFractWidth();
+ Align = Target->getFractAlign();
+ break;
+ case BuiltinType::LongFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatULongFract:
+ Width = Target->getLongFractWidth();
+ Align = Target->getLongFractAlign();
+ break;
case BuiltinType::Float16:
case BuiltinType::Half:
Width = Target->getHalfWidth();
@@ -6251,6 +6296,24 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
// FIXME: potentially need @encodes for these!
return ' ';
@@ -8854,7 +8917,8 @@ unsigned ASTContext::getIntWidth(QualType T) const {
}
QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
- assert(T->hasSignedIntegerRepresentation() && "Unexpected type");
+ assert((T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) &&
+ "Unexpected type");
// Turn <4 x signed int> -> <4 x unsigned int>
if (const auto *VTy = T->getAs<VectorType>())
@@ -8866,7 +8930,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
T = ETy->getDecl()->getIntegerType();
const auto *BTy = T->getAs<BuiltinType>();
- assert(BTy && "Unexpected signed integer type");
+ assert(BTy && "Unexpected signed integer or fixed point type");
switch (BTy->getKind()) {
case BuiltinType::Char_S:
case BuiltinType::SChar:
@@ -8881,8 +8945,33 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
return UnsignedLongLongTy;
case BuiltinType::Int128:
return UnsignedInt128Ty;
+
+ case BuiltinType::ShortAccum:
+ return UnsignedShortAccumTy;
+ case BuiltinType::Accum:
+ return UnsignedAccumTy;
+ case BuiltinType::LongAccum:
+ return UnsignedLongAccumTy;
+ case BuiltinType::SatShortAccum:
+ return SatUnsignedShortAccumTy;
+ case BuiltinType::SatAccum:
+ return SatUnsignedAccumTy;
+ case BuiltinType::SatLongAccum:
+ return SatUnsignedLongAccumTy;
+ case BuiltinType::ShortFract:
+ return UnsignedShortFractTy;
+ case BuiltinType::Fract:
+ return UnsignedFractTy;
+ case BuiltinType::LongFract:
+ return UnsignedLongFractTy;
+ case BuiltinType::SatShortFract:
+ return SatUnsignedShortFractTy;
+ case BuiltinType::SatFract:
+ return SatUnsignedFractTy;
+ case BuiltinType::SatLongFract:
+ return SatUnsignedLongFractTy;
default:
- llvm_unreachable("Unexpected signed integer type");
+ llvm_unreachable("Unexpected signed integer or fixed point type");
}
}
@@ -10029,6 +10118,42 @@ unsigned ASTContext::getTargetAddressSpace(LangAS AS) const {
return (*AddrSpaceMap)[(unsigned)AS];
}
+QualType ASTContext::getCorrespondingSaturatedType(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+
+ if (Ty->isSaturatedFixedPointType()) return Ty;
+
+ const auto &BT = Ty->getAs<BuiltinType>();
+ switch (BT->getKind()) {
+ default:
+ llvm_unreachable("Not a fixed point type!");
+ case BuiltinType::ShortAccum:
+ return SatShortAccumTy;
+ case BuiltinType::Accum:
+ return SatAccumTy;
+ case BuiltinType::LongAccum:
+ return SatLongAccumTy;
+ case BuiltinType::UShortAccum:
+ return SatUnsignedShortAccumTy;
+ case BuiltinType::UAccum:
+ return SatUnsignedAccumTy;
+ case BuiltinType::ULongAccum:
+ return SatUnsignedLongAccumTy;
+ case BuiltinType::ShortFract:
+ return SatShortFractTy;
+ case BuiltinType::Fract:
+ return SatFractTy;
+ case BuiltinType::LongFract:
+ return SatLongFractTy;
+ case BuiltinType::UShortFract:
+ return SatUnsignedShortFractTy;
+ case BuiltinType::UFract:
+ return SatUnsignedFractTy;
+ case BuiltinType::ULongFract:
+ return SatUnsignedLongFractTy;
+ }
+}
+
// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
// doesn't include ASTContext.h
template
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 028834e79b5..2079f901ed3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -7358,6 +7358,15 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) {
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
return GCCTypeClass::None;
case BuiltinType::NullPtr:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 80b91dca7f8..380cfc47ddd 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2558,6 +2558,24 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
llvm_unreachable("Fixed point types are disabled for c++");
case BuiltinType::Half:
Out << "Dh";
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 94e41991c9b..6ffd7e3183b 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1934,6 +1934,24 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
case BuiltinType::Char8:
case BuiltinType::Float128: {
DiagnosticsEngine &Diags = Context.getDiags();
diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp
index d61638e54a1..536bf2c378f 100644
--- a/clang/lib/AST/NSAPI.cpp
+++ b/clang/lib/AST/NSAPI.cpp
@@ -447,6 +447,24 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
case BuiltinType::UInt128:
case BuiltinType::Float16:
case BuiltinType::Float128:
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 6615ea88b66..5c37c100028 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2668,6 +2668,42 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
return "unsigned _Accum";
case ULongAccum:
return "unsigned long _Accum";
+ case BuiltinType::ShortFract:
+ return "short _Fract";
+ case BuiltinType::Fract:
+ return "_Fract";
+ case BuiltinType::LongFract:
+ return "long _Fract";
+ case BuiltinType::UShortFract:
+ return "unsigned short _Fract";
+ case BuiltinType::UFract:
+ return "unsigned _Fract";
+ case BuiltinType::ULongFract:
+ return "unsigned long _Fract";
+ case BuiltinType::SatShortAccum:
+ return "_Sat short _Accum";
+ case BuiltinType::SatAccum:
+ return "_Sat _Accum";
+ case BuiltinType::SatLongAccum:
+ return "_Sat long _Accum";
+ case BuiltinType::SatUShortAccum:
+ return "_Sat unsigned short _Accum";
+ case BuiltinType::SatUAccum:
+ return "_Sat unsigned _Accum";
+ case BuiltinType::SatULongAccum:
+ return "_Sat unsigned long _Accum";
+ case BuiltinType::SatShortFract:
+ return "_Sat short _Fract";
+ case BuiltinType::SatFract:
+ return "_Sat _Fract";
+ case BuiltinType::SatLongFract:
+ return "_Sat long _Fract";
+ case BuiltinType::SatUShortFract:
+ return "_Sat unsigned short _Fract";
+ case BuiltinType::SatUFract:
+ return "_Sat unsigned _Fract";
+ case BuiltinType::SatULongFract:
+ return "_Sat unsigned long _Fract";
case Float16:
return "_Float16";
case Float128:
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 1aa7b5a3cdc..2bf560305a1 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -350,6 +350,24 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
llvm_unreachable("Builtin type needs extra local data!");
// Fall through, if the impossible happens.
diff --git a/clang/lib/Analysis/PrintfFormatString.cpp b/clang/lib/Analysis/PrintfFormatString.cpp
index 5884d33136f..3b64508b5a6 100644
--- a/clang/lib/Analysis/PrintfFormatString.cpp
+++ b/clang/lib/Analysis/PrintfFormatString.cpp
@@ -661,6 +661,24 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
// Various types which are non-trivial to correct.
return false;
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index bf36effbe3b..8dfcbcc8e26 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -43,6 +43,9 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
ShortAccumWidth = ShortAccumAlign = 16;
AccumWidth = AccumAlign = 32;
LongAccumWidth = LongAccumAlign = 64;
+ ShortFractWidth = ShortFractAlign = 16;
+ FractWidth = FractAlign = 32;
+ LongFractWidth = LongFractAlign = 64;
SuitableAlign = 64;
DefaultAlignForAttributeAligned = 128;
MinGlobalAlign = 0;
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index db6a82b415d..3ca6459a6a3 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -705,11 +705,29 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
case BuiltinType::ShortAccum:
case BuiltinType::Accum:
case BuiltinType::LongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
Encoding = llvm::dwarf::DW_ATE_signed_fixed;
break;
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
break;
}
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index c1ff9d28463..16ec1dd301a 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -446,6 +446,24 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
ResultType = llvm::IntegerType::get(getLLVMContext(),
static_cast<unsigned>(Context.getTypeSize(T)));
break;
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 6ac7d29752d..b79e51f3ae1 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2738,6 +2738,24 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
return false;
case BuiltinType::Dependent:
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index 9c9600188f7..e69fa749b45 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -715,6 +715,24 @@ void USRGenerator::VisitType(QualType T) {
case BuiltinType::UShortAccum:
case BuiltinType::UAccum:
case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
IgnoreResults = true;
return;
case BuiltinType::ObjCId:
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 2b9c4afaaf1..9e4669a8720 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2876,6 +2876,17 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
return false;
}
+// Choose the apprpriate diagnostic error for why fixed point types are
+// disabled, set the previous specifier, and mark as invalid.
+static void SetupFixedPointError(const LangOptions &LangOpts,
+ const char *&PrevSpec, unsigned &DiagID,
+ bool &isInvalid) {
+ assert(!LangOpts.FixedPoint);
+ DiagID = diag::err_fixed_point_not_enabled;
+ PrevSpec = ""; // Not used by diagnostic
+ isInvalid = true;
+}
+
/// ParseDeclarationSpecifiers
/// declaration-specifiers: [C99 6.7]
/// storage-class-specifier declaration-specifiers[opt]
@@ -3582,14 +3593,27 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
break;
case tok::kw__Accum:
if (!getLangOpts().FixedPoint) {
- DiagID = diag::err_fixed_point_not_enabled;
- PrevSpec = ""; // Not used by diagnostic
- isInvalid = true;
+ SetupFixedPointError(getLangOpts(), PrevSpec, DiagID, isInvalid);
} else {
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec,
DiagID, Policy);
}
break;
+ case tok::kw__Fract:
+ if (!getLangOpts().FixedPoint) {
+ SetupFixedPointError(getLangOpts(), PrevSpec, DiagID, isInvalid);
+ } else {
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_fract, Loc, PrevSpec,
+ DiagID, Policy);
+ }
+ break;
+ case tok::kw__Sat:
+ if (!getLangOpts().FixedPoint) {
+ SetupFixedPointError(getLangOpts(), PrevSpec, DiagID, isInvalid);
+ } else {
+ isInvalid = DS.SetTypeSpecSat(Loc, PrevSpec, DiagID);
+ }
+ break;
case tok::kw___float128:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,
DiagID, Policy);
@@ -4617,6 +4641,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
case tok::kw_float:
case tok::kw_double:
case tok::kw__Accum:
+ case tok::kw__Fract:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
@@ -4695,6 +4720,7 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_float:
case tok::kw_double:
case tok::kw__Accum:
+ case tok::kw__Fract:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
@@ -4718,6 +4744,7 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_const:
case tok::kw_volatile:
case tok::kw_restrict:
+ case tok::kw__Sat:
// Debugger support.
case tok::kw___unknown_anytype:
@@ -4854,6 +4881,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
case tok::kw_float:
case tok::kw_double:
case tok::kw__Accum:
+ case tok::kw__Fract:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
@@ -4875,6 +4903,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
case tok::kw_const:
case tok::kw_volatile:
case tok::kw_restrict:
+ case tok::kw__Sat:
// function-specifier
case tok::kw_inline:
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index aa5f197b541..fe111a5ddea 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -340,6 +340,7 @@ bool Declarator::isDeclarationOfFunction() const {
case TST_decimal64:
case TST_double:
case TST_Accum:
+ case TST_Fract:
case TST_Float16:
case TST_float128:
case TST_enum:
@@ -512,6 +513,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_float: return "float";
case DeclSpec::TST_double: return "double";
case DeclSpec::TST_accum: return "_Accum";
+ case DeclSpec::TST_fract: return "_Fract";
case DeclSpec::TST_float16: return "_Float16";
case DeclSpec::TST_float128: return "__float128";
case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
@@ -767,6 +769,19 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
return false;
}
+bool DeclSpec::SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
+ // Cannot set twice
+ if (TypeSpecSat) {
+ DiagID = diag::warn_duplicate_declspec;
+ PrevSpec = "_Sat";
+ return true;
+ }
+ TypeSpecSat = true;
+ TSSatLoc = Loc;
+ return false;
+}
+
bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy) {
@@ -1102,13 +1117,16 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
}
}
+ bool IsFixedPointType =
+ TypeSpecType == TST_accum || TypeSpecType == TST_fract;
+
// signed/unsigned are only valid with int/char/wchar_t/_Accum.
if (TypeSpecSign != TSS_unspecified) {
if (TypeSpecType == TST_unspecified)
TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&
TypeSpecType != TST_char && TypeSpecType != TST_wchar &&
- TypeSpecType != TST_accum) {
+ !IsFixedPointType) {
S.Diag(TSSLoc, diag::err_invalid_sign_spec)
<< getSpecifierName((TST)TypeSpecType, Policy);
// signed double -> double.
@@ -1124,10 +1142,11 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
if (TypeSpecType == TST_unspecified)
TypeSpecType = TST_int; // short -> short int, long long -> long long int.
else if (!(TypeSpecType == TST_int ||
- (TypeSpecType == TST_accum && TypeSpecWidth != TSW_longlong))) {
+ (IsFixedPointType && TypeSpecWidth != TSW_longlong))) {
S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
<< (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);
TypeSpecType = TST_int;
+ TypeSpecSat = false;
TypeSpecOwned = false;
}
break;
@@ -1135,10 +1154,11 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
if (TypeSpecType == TST_unspecified)
TypeSpecType = TST_int; // long -> long int.
else if (TypeSpecType != TST_int && TypeSpecType != TST_double &&
- TypeSpecType != TST_accum) {
+ !IsFixedPointType) {
S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
<< (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);
TypeSpecType = TST_int;
+ TypeSpecSat = false;
TypeSpecOwned = false;
}
break;
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index dc67c8ef19a..71c583367bd 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -831,6 +831,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
case TST_float:
case TST_double:
case TST_Accum:
+ case TST_Fract:
case TST_Float16:
case TST_float128:
case TST_bool:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 1f6034a07d3..9ee947b80a3 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1392,36 +1392,49 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
break;
}
case DeclSpec::TST_accum: {
- if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) {
- switch (DS.getTypeSpecWidth()) {
- case DeclSpec::TSW_short:
- Result = Context.ShortAccumTy;
- break;
- case DeclSpec::TSW_unspecified:
- Result = Context.AccumTy;
- break;
- case DeclSpec::TSW_long:
- Result = Context.LongAccumTy;
- break;
- case DeclSpec::TSW_longlong:
- // Unreachable b/c this is caught in final analysis of the DeclSpec.
- llvm_unreachable("Unable to specify long long as _Accum width");
- }
- } else {
- switch (DS.getTypeSpecWidth()) {
- case DeclSpec::TSW_short:
- Result = Context.UnsignedShortAccumTy;
- break;
- case DeclSpec::TSW_unspecified:
- Result = Context.UnsignedAccumTy;
- break;
- case DeclSpec::TSW_long:
- Result = Context.UnsignedLongAccumTy;
- break;
- case DeclSpec::TSW_longlong:
- llvm_unreachable("Unable to specify long long as _Accum width");
- }
+ switch (DS.getTypeSpecWidth()) {
+ case DeclSpec::TSW_short:
+ Result = Context.ShortAccumTy;
+ break;
+ case DeclSpec::TSW_unspecified:
+ Result = Context.AccumTy;
+ break;
+ case DeclSpec::TSW_long:
+ Result = Context.LongAccumTy;
+ break;
+ case DeclSpec::TSW_longlong:
+ llvm_unreachable("Unable to specify long long as _Accum width");
}
+
+ if (DS.getTypeSpecSign() == DeclSpec::TSS_unsigned)
+ Result = Context.getCorrespondingUnsignedType(Result);
+
+ if (DS.isTypeSpecSat())
+ Result = Context.getCorrespondingSaturatedType(Result);
+
+ break;
+ }
+ case DeclSpec::TST_fract: {
+ switch (DS.getTypeSpecWidth()) {
+ case DeclSpec::TSW_short:
+ Result = Context.ShortFractTy;
+ break;
+ case DeclSpec::TSW_unspecified:
+ Result = Context.FractTy;
+ break;
+ case DeclSpec::TSW_long:
+ Result = Context.LongFractTy;
+ break;
+ case DeclSpec::TSW_longlong:
+ llvm_unreachable("Unable to specify long long as _Fract width");
+ }
+
+ if (DS.getTypeSpecSign() == DeclSpec::TSS_unsigned)
+ Result = Context.getCorrespondingUnsignedType(Result);
+
+ if (DS.isTypeSpecSat())
+ Result = Context.getCorrespondingSaturatedType(Result);
+
break;
}
case DeclSpec::TST_int128:
@@ -1592,6 +1605,15 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
S.checkOpenCLDisabledTypeDeclSpec(DS, Result))
declarator.setInvalidType(true);
+ bool IsFixedPointType = DS.getTypeSpecType() == DeclSpec::TST_accum ||
+ DS.getTypeSpecType() == DeclSpec::TST_fract;
+
+ // Only fixed point types can be saturated
+ if (DS.isTypeSpecSat() && !IsFixedPointType)
+ S.Diag(DS.getTypeSpecSatLoc(), diag::err_invalid_saturation_spec)
+ << DS.getSpecifierName(DS.getTypeSpecType(),
+ Context.getPrintingPolicy());
+
// Handle complex types.
if (DS.getTypeSpecComplex() == DeclSpec::TSC_complex) {
if (S.getLangOpts().Freestanding)
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index f5584cc04d1..fcebe5982ff 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -109,6 +109,60 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
case BuiltinType::ULongAccum:
ID = PREDEF_TYPE_ULONG_ACCUM_ID;
break;
+ case BuiltinType::ShortFract:
+ ID = PREDEF_TYPE_SHORT_FRACT_ID;
+ break;
+ case BuiltinType::Fract:
+ ID = PREDEF_TYPE_FRACT_ID;
+ break;
+ case BuiltinType::LongFract:
+ ID = PREDEF_TYPE_LONG_FRACT_ID;
+ break;
+ case BuiltinType::UShortFract:
+ ID = PREDEF_TYPE_USHORT_FRACT_ID;
+ break;
+ case BuiltinType::UFract:
+ ID = PREDEF_TYPE_UFRACT_ID;
+ break;
+ case BuiltinType::ULongFract:
+ ID = PREDEF_TYPE_ULONG_FRACT_ID;
+ break;
+ case BuiltinType::SatShortAccum:
+ ID = PREDEF_TYPE_SAT_SHORT_ACCUM_ID;
+ break;
+ case BuiltinType::SatAccum:
+ ID = PREDEF_TYPE_SAT_ACCUM_ID;
+ break;
+ case BuiltinType::SatLongAccum:
+ ID = PREDEF_TYPE_SAT_LONG_ACCUM_ID;
+ break;
+ case BuiltinType::SatUShortAccum:
+ ID = PREDEF_TYPE_SAT_USHORT_ACCUM_ID;
+ break;
+ case BuiltinType::SatUAccum:
+ ID = PREDEF_TYPE_SAT_UACCUM_ID;
+ break;
+ case BuiltinType::SatULongAccum:
+ ID = PREDEF_TYPE_SAT_ULONG_ACCUM_ID;
+ break;
+ case BuiltinType::SatShortFract:
+ ID = PREDEF_TYPE_SAT_SHORT_FRACT_ID;
+ break;
+ case BuiltinType::SatFract:
+ ID = PREDEF_TYPE_SAT_FRACT_ID;
+ break;
+ case BuiltinType::SatLongFract:
+ ID = PREDEF_TYPE_SAT_LONG_FRACT_ID;
+ break;
+ case BuiltinType::SatUShortFract:
+ ID = PREDEF_TYPE_SAT_USHORT_FRACT_ID;
+ break;
+ case BuiltinType::SatUFract:
+ ID = PREDEF_TYPE_SAT_UFRACT_ID;
+ break;
+ case BuiltinType::SatULongFract:
+ ID = PREDEF_TYPE_SAT_ULONG_FRACT_ID;
+ break;
case BuiltinType::Float16:
ID = PREDEF_TYPE_FLOAT16_ID;
break;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 89dff67446a..3dd233e449b 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -6837,6 +6837,60 @@ QualType ASTReader::GetType(TypeID ID) {
case PREDEF_TYPE_ULONG_ACCUM_ID:
T = Context.UnsignedLongAccumTy;
break;
+ case PREDEF_TYPE_SHORT_FRACT_ID:
+ T = Context.ShortFractTy;
+ break;
+ case PREDEF_TYPE_FRACT_ID:
+ T = Context.FractTy;
+ break;
+ case PREDEF_TYPE_LONG_FRACT_ID:
+ T = Context.LongFractTy;
+ break;
+ case PREDEF_TYPE_USHORT_FRACT_ID:
+ T = Context.UnsignedShortFractTy;
+ break;
+ case PREDEF_TYPE_UFRACT_ID:
+ T = Context.UnsignedFractTy;
+ break;
+ case PREDEF_TYPE_ULONG_FRACT_ID:
+ T = Context.UnsignedLongFractTy;
+ break;
+ case PREDEF_TYPE_SAT_SHORT_ACCUM_ID:
+ T = Context.SatShortAccumTy;
+ break;
+ case PREDEF_TYPE_SAT_ACCUM_ID:
+ T = Context.SatAccumTy;
+ break;
+ case PREDEF_TYPE_SAT_LONG_ACCUM_ID:
+ T = Context.SatLongAccumTy;
+ break;
+ case PREDEF_TYPE_SAT_USHORT_ACCUM_ID:
+ T = Context.SatUnsignedShortAccumTy;
+ break;
+ case PREDEF_TYPE_SAT_UACCUM_ID:
+ T = Context.SatUnsignedAccumTy;
+ break;
+ case PREDEF_TYPE_SAT_ULONG_ACCUM_ID:
+ T = Context.SatUnsignedLongAccumTy;
+ break;
+ case PREDEF_TYPE_SAT_SHORT_FRACT_ID:
+ T = Context.SatShortFractTy;
+ break;
+ case PREDEF_TYPE_SAT_FRACT_ID:
+ T = Context.SatFractTy;
+ break;
+ case PREDEF_TYPE_SAT_LONG_FRACT_ID:
+ T = Context.SatLongFractTy;
+ break;
+ case PREDEF_TYPE_SAT_USHORT_FRACT_ID:
+ T = Context.SatUnsignedShortFractTy;
+ break;
+ case PREDEF_TYPE_SAT_UFRACT_ID:
+ T = Context.SatUnsignedFractTy;
+ break;
+ case PREDEF_TYPE_SAT_ULONG_FRACT_ID:
+ T = Context.SatUnsignedLongFractTy;
+ break;
case PREDEF_TYPE_FLOAT16_ID:
T = Context.Float16Ty;
break;
OpenPOWER on IntegriCloud