diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 143 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 9 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 18 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 18 | ||||
-rw-r--r-- | clang/lib/AST/NSAPI.cpp | 18 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 36 | ||||
-rw-r--r-- | clang/lib/AST/TypeLoc.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Analysis/PrintfFormatString.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Basic/TargetInfo.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Index/USRGeneration.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 26 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 80 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTCommon.cpp | 54 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 54 |
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; |