diff options
Diffstat (limited to 'clang/lib/Sema/DeclSpec.cpp')
| -rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 167 |
1 files changed, 95 insertions, 72 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index f4c30c90ad27..da42db3e8f7b 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -181,6 +181,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType, + SourceLocation + TrailingReturnTypeLoc, DeclSpec *MethodQualifiers) { assert(!(MethodQualifiers && MethodQualifiers->getTypeQualifiers() & DeclSpec::TQ_atomic) && "function cannot have _Atomic qualifier"); @@ -189,27 +191,29 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, I.Kind = Function; I.Loc = LocalRangeBegin; I.EndLoc = LocalRangeEnd; + new (&I.Fun) FunctionTypeInfo; I.Fun.hasPrototype = hasProto; I.Fun.isVariadic = EllipsisLoc.isValid(); I.Fun.isAmbiguous = isAmbiguous; - I.Fun.LParenLoc = LParenLoc.getRawEncoding(); - I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); - I.Fun.RParenLoc = RParenLoc.getRawEncoding(); + I.Fun.LParenLoc = LParenLoc; + I.Fun.EllipsisLoc = EllipsisLoc; + I.Fun.RParenLoc = RParenLoc; I.Fun.DeleteParams = false; I.Fun.NumParams = NumParams; I.Fun.Params = nullptr; I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; - I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); - I.Fun.MutableLoc = MutableLoc.getRawEncoding(); + I.Fun.RefQualifierLoc = RefQualifierLoc; + I.Fun.MutableLoc = MutableLoc; I.Fun.ExceptionSpecType = ESpecType; - I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin().getRawEncoding(); - I.Fun.ExceptionSpecLocEnd = ESpecRange.getEnd().getRawEncoding(); + I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin(); + I.Fun.ExceptionSpecLocEnd = ESpecRange.getEnd(); I.Fun.NumExceptionsOrDecls = 0; I.Fun.Exceptions = nullptr; I.Fun.NoexceptExpr = nullptr; I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() || TrailingReturnType.isInvalid(); I.Fun.TrailingReturnType = TrailingReturnType.get(); + I.Fun.TrailingReturnTypeLoc = TrailingReturnTypeLoc; I.Fun.MethodQualifiers = nullptr; I.Fun.QualAttrFactory = nullptr; @@ -405,7 +409,7 @@ bool Declarator::isDeclarationOfFunction() const { } bool Declarator::isStaticMember() { - assert(getContext() == DeclaratorContext::MemberContext); + assert(getContext() == DeclaratorContext::Member); return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || (getName().Kind == UnqualifiedIdKind::IK_OperatorFunctionId && CXXMethodDecl::isStaticOverloadedOperator( @@ -499,12 +503,16 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) { llvm_unreachable("Unknown typespec!"); } -const char *DeclSpec::getSpecifierName(TSW W) { +const char *DeclSpec::getSpecifierName(TypeSpecifierWidth W) { switch (W) { - case TSW_unspecified: return "unspecified"; - case TSW_short: return "short"; - case TSW_long: return "long"; - case TSW_longlong: return "long long"; + case TypeSpecifierWidth::Unspecified: + return "unspecified"; + case TypeSpecifierWidth::Short: + return "short"; + case TypeSpecifierWidth::Long: + return "long"; + case TypeSpecifierWidth::LongLong: + return "long long"; } llvm_unreachable("Unknown typespec!"); } @@ -518,12 +526,14 @@ const char *DeclSpec::getSpecifierName(TSC C) { llvm_unreachable("Unknown typespec!"); } - -const char *DeclSpec::getSpecifierName(TSS S) { +const char *DeclSpec::getSpecifierName(TypeSpecifierSign S) { switch (S) { - case TSS_unspecified: return "unspecified"; - case TSS_signed: return "signed"; - case TSS_unsigned: return "unsigned"; + case TypeSpecifierSign::Unspecified: + return "unspecified"; + case TypeSpecifierSign::Signed: + return "signed"; + case TypeSpecifierSign::Unsigned: + return "unsigned"; } llvm_unreachable("Unknown typespec!"); } @@ -579,10 +589,14 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, const char *DeclSpec::getSpecifierName(ConstexprSpecKind C) { switch (C) { - case CSK_unspecified: return "unspecified"; - case CSK_constexpr: return "constexpr"; - case CSK_consteval: return "consteval"; - case CSK_constinit: return "constinit"; + case ConstexprSpecKind::Unspecified: + return "unspecified"; + case ConstexprSpecKind::Constexpr: + return "constexpr"; + case ConstexprSpecKind::Consteval: + return "consteval"; + case ConstexprSpecKind::Constinit: + return "constinit"; } llvm_unreachable("Unknown ConstexprSpecKind"); } @@ -675,18 +689,18 @@ bool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, /// These methods set the specified attribute of the DeclSpec, but return true /// and ignore the request if invalid (e.g. "extern" then "auto" is /// specified). -bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, - const char *&PrevSpec, - unsigned &DiagID, +bool DeclSpec::SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy) { // Overwrite TSWRange.Begin only if TypeSpecWidth was unspecified, so that // for 'long long' we will keep the source location of the first 'long'. - if (TypeSpecWidth == TSW_unspecified) + if (getTypeSpecWidth() == TypeSpecifierWidth::Unspecified) TSWRange.setBegin(Loc); // Allow turning long -> long long. - else if (W != TSW_longlong || TypeSpecWidth != TSW_long) - return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); - TypeSpecWidth = W; + else if (W != TypeSpecifierWidth::LongLong || + getTypeSpecWidth() != TypeSpecifierWidth::Long) + return BadSpecifier(W, getTypeSpecWidth(), PrevSpec, DiagID); + TypeSpecWidth = static_cast<unsigned>(W); // Remember location of the last 'long' TSWRange.setEnd(Loc); return false; @@ -702,12 +716,11 @@ bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, return false; } -bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, - const char *&PrevSpec, - unsigned &DiagID) { - if (TypeSpecSign != TSS_unspecified) - return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); - TypeSpecSign = S; +bool DeclSpec::SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID) { + if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) + return BadSpecifier(S, getTypeSpecSign(), PrevSpec, DiagID); + TypeSpecSign = static_cast<unsigned>(S); TSSLoc = Loc; return false; } @@ -870,7 +883,7 @@ bool DeclSpec::SetTypePipe(bool isPipe, SourceLocation Loc, } if (isPipe) { - TypeSpecPipe = TSP_pipe; + TypeSpecPipe = static_cast<unsigned>(TypeSpecifiersPipe::Pipe); } return false; } @@ -1014,9 +1027,6 @@ bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc) { - assert((ExplicitSpec.getKind() == ExplicitSpecKind::ResolvedTrue || - ExplicitSpec.getExpr()) && - "invalid ExplicitSpecifier"); // 'explicit explicit' is ok, but warn as this is likely not what the user // intended. if (hasExplicitSpecifier()) { @@ -1080,17 +1090,17 @@ bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, bool DeclSpec::SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID) { - if (getConstexprSpecifier() != CSK_unspecified) + if (getConstexprSpecifier() != ConstexprSpecKind::Unspecified) return BadSpecifier(ConstexprKind, getConstexprSpecifier(), PrevSpec, DiagID); - ConstexprSpecifier = ConstexprKind; + ConstexprSpecifier = static_cast<unsigned>(ConstexprKind); ConstexprLoc = Loc; return false; } void DeclSpec::SaveWrittenBuiltinSpecs() { - writtenBS.Sign = getTypeSpecSign(); - writtenBS.Width = getTypeSpecWidth(); + writtenBS.Sign = static_cast<int>(getTypeSpecSign()); + writtenBS.Width = static_cast<int>(getTypeSpecWidth()); writtenBS.Type = getTypeSpecType(); // Search the list of attributes for the presence of a mode attribute. writtenBS.ModeAttr = getAttributes().hasAttribute(ParsedAttr::AT_Mode); @@ -1111,9 +1121,9 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { // If decltype(auto) is used, no other type specifiers are permitted. if (TypeSpecType == TST_decltype_auto && - (TypeSpecWidth != TSW_unspecified || + (getTypeSpecWidth() != TypeSpecifierWidth::Unspecified || TypeSpecComplex != TSC_unspecified || - TypeSpecSign != TSS_unspecified || + getTypeSpecSign() != TypeSpecifierSign::Unspecified || TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool || TypeQualifiers)) { const unsigned NumLocs = 9; @@ -1132,9 +1142,9 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]); } } - TypeSpecWidth = TSW_unspecified; + TypeSpecWidth = static_cast<unsigned>(TypeSpecifierWidth::Unspecified); TypeSpecComplex = TSC_unspecified; - TypeSpecSign = TSS_unspecified; + TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unspecified); TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false; TypeQualifiers = 0; S.Diag(TSTLoc, diag::err_decltype_auto_cannot_be_combined) @@ -1146,9 +1156,9 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { if (TypeAltiVecVector) { if (TypeAltiVecBool) { // Sign specifiers are not allowed with vector bool. (PIM 2.1) - if (TypeSpecSign != TSS_unspecified) { + if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) { S.Diag(TSSLoc, diag::err_invalid_vector_bool_decl_spec) - << getSpecifierName((TSS)TypeSpecSign); + << getSpecifierName(getTypeSpecSign()); } // Only char/int are valid with vector bool prior to Power10. // Power10 adds instructions that produce vector bool data @@ -1166,13 +1176,14 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { S.Diag(TSTLoc, diag::err_invalid_vector_bool_int128_decl_spec); // Only 'short' and 'long long' are valid with vector bool. (PIM 2.1) - if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short) && - (TypeSpecWidth != TSW_longlong)) + if ((getTypeSpecWidth() != TypeSpecifierWidth::Unspecified) && + (getTypeSpecWidth() != TypeSpecifierWidth::Short) && + (getTypeSpecWidth() != TypeSpecifierWidth::LongLong)) S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_bool_decl_spec) - << getSpecifierName((TSW)TypeSpecWidth); + << getSpecifierName(getTypeSpecWidth()); // vector bool long long requires VSX support or ZVector. - if ((TypeSpecWidth == TSW_longlong) && + if ((getTypeSpecWidth() == TypeSpecifierWidth::LongLong) && (!S.Context.getTargetInfo().hasFeature("vsx")) && (!S.Context.getTargetInfo().hasFeature("power8-vector")) && !S.getLangOpts().ZVector) @@ -1180,12 +1191,14 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { // Elements of vector bool are interpreted as unsigned. (PIM 2.1) if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || - (TypeSpecType == TST_int128) || (TypeSpecWidth != TSW_unspecified)) - TypeSpecSign = TSS_unsigned; + (TypeSpecType == TST_int128) || + (getTypeSpecWidth() != TypeSpecifierWidth::Unspecified)) + TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unsigned); } else if (TypeSpecType == TST_double) { // vector long double and vector long long double are never allowed. // vector double is OK for Power7 and later, and ZVector. - if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong) + if (getTypeSpecWidth() == TypeSpecifierWidth::Long || + getTypeSpecWidth() == TypeSpecifierWidth::LongLong) S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_double_decl_spec); else if (!S.Context.getTargetInfo().hasFeature("vsx") && @@ -1197,9 +1210,15 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { if (S.getLangOpts().ZVector && !S.Context.getTargetInfo().hasFeature("arch12")) S.Diag(TSTLoc, diag::err_invalid_vector_float_decl_spec); - } else if (TypeSpecWidth == TSW_long) { + } else if (getTypeSpecWidth() == TypeSpecifierWidth::Long) { // vector long is unsupported for ZVector and deprecated for AltiVec. - if (S.getLangOpts().ZVector) + // It has also been historically deprecated on AIX (as an alias for + // "vector int" in both 32-bit and 64-bit modes). It was then made + // unsupported in the Clang-based XL compiler since the deprecated type + // has a number of conflicting semantics and continuing to support it + // is a disservice to users. + if (S.getLangOpts().ZVector || + S.Context.getTargetInfo().getTriple().isOSAIX()) S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_decl_spec); else S.Diag(TSWRange.getBegin(), @@ -1210,8 +1229,8 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { if (TypeAltiVecPixel) { //TODO: perform validation TypeSpecType = TST_int; - TypeSpecSign = TSS_unsigned; - TypeSpecWidth = TSW_short; + TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unsigned); + TypeSpecWidth = static_cast<unsigned>(TypeSpecifierWidth::Short); TypeSpecOwned = false; } } @@ -1220,7 +1239,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { TypeSpecType == TST_accum || TypeSpecType == TST_fract; // signed/unsigned are only valid with int/char/wchar_t/_Accum. - if (TypeSpecSign != TSS_unspecified) { + if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) { if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && @@ -1229,19 +1248,21 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { S.Diag(TSSLoc, diag::err_invalid_sign_spec) << getSpecifierName((TST)TypeSpecType, Policy); // signed double -> double. - TypeSpecSign = TSS_unspecified; + TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unspecified); } } // Validate the width of the type. - switch (TypeSpecWidth) { - case TSW_unspecified: break; - case TSW_short: // short int - case TSW_longlong: // long long int + switch (getTypeSpecWidth()) { + case TypeSpecifierWidth::Unspecified: + break; + case TypeSpecifierWidth::Short: // short int + case TypeSpecifierWidth::LongLong: // long long int if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // short -> short int, long long -> long long int. else if (!(TypeSpecType == TST_int || - (IsFixedPointType && TypeSpecWidth != TSW_longlong))) { + (IsFixedPointType && + getTypeSpecWidth() != TypeSpecifierWidth::LongLong))) { S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec) << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy); TypeSpecType = TST_int; @@ -1249,7 +1270,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { TypeSpecOwned = false; } break; - case TSW_long: // long double, long int + case TypeSpecifierWidth::Long: // long double, long int if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // long -> long int. else if (TypeSpecType != TST_int && TypeSpecType != TST_double && @@ -1279,6 +1300,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { S.Diag(TSTLoc, diag::ext_integer_complex); } else if (TypeSpecType != TST_float && TypeSpecType != TST_double && TypeSpecType != TST_float128) { + // FIXME: _Float16, __fp16? S.Diag(TSCLoc, diag::err_invalid_complex_spec) << getSpecifierName((TST)TypeSpecType, Policy); TypeSpecComplex = TSC_unspecified; @@ -1337,11 +1359,11 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { 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 (getConstexprSpecifier() == CSK_constexpr) + if (getConstexprSpecifier() == ConstexprSpecKind::Constexpr) S.Diag(ConstexprLoc, diag::warn_cxx98_compat_constexpr); - else if (getConstexprSpecifier() == CSK_consteval) + else if (getConstexprSpecifier() == ConstexprSpecKind::Consteval) S.Diag(ConstexprLoc, diag::warn_cxx20_compat_consteval); - else if (getConstexprSpecifier() == CSK_constinit) + else if (getConstexprSpecifier() == ConstexprSpecKind::Constinit) S.Diag(ConstexprLoc, diag::warn_cxx20_compat_constinit); // C++ [class.friend]p6: // No storage-class-specifier shall appear in the decl-specifier-seq @@ -1422,9 +1444,10 @@ void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, Kind = UnqualifiedIdKind::IK_OperatorFunctionId; StartLocation = OperatorLoc; EndLocation = OperatorLoc; + new (&OperatorFunctionId) struct OFI; OperatorFunctionId.Operator = Op; for (unsigned I = 0; I != 3; ++I) { - OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); + OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I]; if (SymbolLocations[I].isValid()) EndLocation = SymbolLocations[I]; |
