diff options
Diffstat (limited to 'lib/Sema/DeclSpec.cpp')
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 70 |
1 files changed, 46 insertions, 24 deletions
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 6fe2dcc9895fb..ccca5d37ea395 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -30,7 +30,7 @@ using namespace clang; void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { assert(TemplateId && "NULL template-id annotation?"); - Kind = IK_TemplateId; + Kind = UnqualifiedIdKind::IK_TemplateId; this->TemplateId = TemplateId; StartLocation = TemplateId->TemplateNameLoc; EndLocation = TemplateId->RAngleLoc; @@ -38,7 +38,7 @@ void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { assert(TemplateId && "NULL template-id annotation?"); - Kind = IK_ConstructorTemplateId; + Kind = UnqualifiedIdKind::IK_ConstructorTemplateId; this->TemplateId = TemplateId; StartLocation = TemplateId->TemplateNameLoc; EndLocation = TemplateId->RAngleLoc; @@ -186,7 +186,6 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, I.Kind = Function; I.Loc = LocalRangeBegin; I.EndLoc = LocalRangeEnd; - I.Fun.AttrList = nullptr; I.Fun.hasPrototype = hasProto; I.Fun.isVariadic = EllipsisLoc.isValid(); I.Fun.isAmbiguous = isAmbiguous; @@ -251,7 +250,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, } break; - case EST_ComputedNoexcept: + case EST_DependentNoexcept: + case EST_NoexceptFalse: + case EST_NoexceptTrue: I.Fun.NoexceptExpr = NoexceptExpr; break; @@ -329,6 +330,7 @@ bool Declarator::isDeclarationOfFunction() const { case TST_auto_type: case TST_bool: case TST_char: + case TST_char8: case TST_char16: case TST_char32: case TST_class: @@ -336,6 +338,8 @@ bool Declarator::isDeclarationOfFunction() const { case TST_decimal32: case TST_decimal64: case TST_double: + case TST_Accum: + case TST_Fract: case TST_Float16: case TST_float128: case TST_enum: @@ -387,16 +391,16 @@ bool Declarator::isDeclarationOfFunction() const { } bool Declarator::isStaticMember() { - assert(getContext() == MemberContext); + assert(getContext() == DeclaratorContext::MemberContext); return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || - (getName().Kind == UnqualifiedId::IK_OperatorFunctionId && + (getName().Kind == UnqualifiedIdKind::IK_OperatorFunctionId && CXXMethodDecl::isStaticOverloadedOperator( getName().OperatorFunctionId.Operator)); } bool Declarator::isCtorOrDtor() { - return (getName().getKind() == UnqualifiedId::IK_ConstructorName) || - (getName().getKind() == UnqualifiedId::IK_DestructorName); + return (getName().getKind() == UnqualifiedIdKind::IK_ConstructorName) || + (getName().getKind() == UnqualifiedIdKind::IK_DestructorName); } bool DeclSpec::hasTagDefinition() const { @@ -499,6 +503,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, case DeclSpec::TST_void: return "void"; case DeclSpec::TST_char: return "char"; case DeclSpec::TST_wchar: return Policy.MSWChar ? "__wchar_t" : "wchar_t"; + case DeclSpec::TST_char8: return "char8_t"; case DeclSpec::TST_char16: return "char16_t"; case DeclSpec::TST_char32: return "char32_t"; case DeclSpec::TST_int: return "int"; @@ -506,6 +511,8 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, case DeclSpec::TST_half: return "half"; 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"; @@ -761,6 +768,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) { @@ -974,15 +994,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() { writtenBS.Width = getTypeSpecWidth(); writtenBS.Type = getTypeSpecType(); // Search the list of attributes for the presence of a mode attribute. - writtenBS.ModeAttr = false; - AttributeList* attrs = getAttributes().getList(); - while (attrs) { - if (attrs->getKind() == AttributeList::AT_Mode) { - writtenBS.ModeAttr = true; - break; - } - attrs = attrs->getNext(); - } + writtenBS.ModeAttr = getAttributes().hasAttribute(ParsedAttr::AT_Mode); } /// Finish - This does final analysis of the declspec, rejecting things like @@ -1096,12 +1108,16 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { } } - // signed/unsigned are only valid with int/char/wchar_t. + 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) { + else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && + TypeSpecType != TST_char && TypeSpecType != TST_wchar && + !IsFixedPointType) { S.Diag(TSSLoc, diag::err_invalid_sign_spec) << getSpecifierName((TST)TypeSpecType, Policy); // signed double -> double. @@ -1116,20 +1132,24 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { case TSW_longlong: // long long int if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // short -> short int, long long -> long long int. - else if (TypeSpecType != TST_int) { + else if (!(TypeSpecType == TST_int || + (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; case TSW_long: // long double, long int if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // long -> long int. - else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { + else if (TypeSpecType != TST_int && TypeSpecType != TST_double && + !IsFixedPointType) { S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec) << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy); TypeSpecType = TST_int; + TypeSpecSat = false; TypeSpecOwned = false; } break; @@ -1202,7 +1222,9 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { StorageClassSpec == SCS_auto) S.Diag(StorageClassSpecLoc, diag::warn_auto_storage_class) << FixItHint::CreateRemoval(StorageClassSpecLoc); - if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) + if (TypeSpecType == TST_char8) + S.Diag(TSTLoc, diag::warn_cxx17_compat_unicode_type); + else if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) S.Diag(TSTLoc, diag::warn_cxx98_compat_unicode_type) << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); if (Constexpr_specified) @@ -1281,7 +1303,7 @@ bool DeclSpec::isMissingDeclaratorOk() { void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3]) { - Kind = IK_OperatorFunctionId; + Kind = UnqualifiedIdKind::IK_OperatorFunctionId; StartLocation = OperatorLoc; EndLocation = OperatorLoc; OperatorFunctionId.Operator = Op; |