aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/DeclSpec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/DeclSpec.cpp')
-rw-r--r--clang/lib/Sema/DeclSpec.cpp167
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];