aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp86
1 files changed, 57 insertions, 29 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp b/contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp
index 72d9ea6dd3bf..781f24cb71ae 100644
--- a/contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Sema.h"
@@ -238,7 +239,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
// is already used (consider a function returning a function pointer) or too
// small (function with too many parameters), go to the heap.
if (!TheDeclarator.InlineStorageUsed &&
- NumParams <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
+ NumParams <= std::size(TheDeclarator.InlineParams)) {
I.Fun.Params = TheDeclarator.InlineParams;
new (I.Fun.Params) ParamInfo[NumParams];
I.Fun.DeleteParams = false;
@@ -307,8 +308,7 @@ void Declarator::setDecompositionBindings(
// Allocate storage for bindings and stash them away.
if (Bindings.size()) {
- if (!InlineStorageUsed &&
- Bindings.size() <= llvm::array_lengthof(InlineBindings)) {
+ if (!InlineStorageUsed && Bindings.size() <= std::size(InlineBindings)) {
BindingGroup.Bindings = InlineBindings;
BindingGroup.DeleteBindings = false;
InlineStorageUsed = true;
@@ -358,13 +358,14 @@ bool Declarator::isDeclarationOfFunction() const {
case TST_Fract:
case TST_Float16:
case TST_float128:
+ case TST_ibm128:
case TST_enum:
case TST_error:
case TST_float:
case TST_half:
case TST_int:
case TST_int128:
- case TST_extint:
+ case TST_bitint:
case TST_struct:
case TST_interface:
case TST_union:
@@ -383,13 +384,16 @@ bool Declarator::isDeclarationOfFunction() const {
return false;
case TST_decltype:
+ case TST_typeof_unqualExpr:
case TST_typeofExpr:
if (Expr *E = DS.getRepAsExpr())
return E->getType()->isFunctionType();
return false;
- case TST_underlyingType:
+#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
+#include "clang/Basic/TransformTypeTraits.def"
case TST_typename:
+ case TST_typeof_unqualType:
case TST_typeofType: {
QualType QT = DS.getRepAsType().get();
if (QT.isNull())
@@ -411,11 +415,23 @@ bool Declarator::isDeclarationOfFunction() const {
bool Declarator::isStaticMember() {
assert(getContext() == DeclaratorContext::Member);
return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
- (getName().Kind == UnqualifiedIdKind::IK_OperatorFunctionId &&
+ (getName().getKind() == UnqualifiedIdKind::IK_OperatorFunctionId &&
CXXMethodDecl::isStaticOverloadedOperator(
getName().OperatorFunctionId.Operator));
}
+bool Declarator::isExplicitObjectMemberFunction() {
+ if (!isFunctionDeclarator())
+ return false;
+ DeclaratorChunk::FunctionTypeInfo &Fun = getFunctionTypeInfo();
+ if (Fun.NumParams) {
+ auto *P = dyn_cast_or_null<ParmVarDecl>(Fun.Params[0].Param);
+ if (P && P->isExplicitObjectParameter())
+ return true;
+ }
+ return false;
+}
+
bool Declarator::isCtorOrDtor() {
return (getName().getKind() == UnqualifiedIdKind::IK_ConstructorName) ||
(getName().getKind() == UnqualifiedIdKind::IK_DestructorName);
@@ -550,7 +566,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_char32: return "char32_t";
case DeclSpec::TST_int: return "int";
case DeclSpec::TST_int128: return "__int128";
- case DeclSpec::TST_extint: return "_ExtInt";
+ case DeclSpec::TST_bitint: return "_BitInt";
case DeclSpec::TST_half: return "half";
case DeclSpec::TST_float: return "float";
case DeclSpec::TST_double: return "double";
@@ -558,6 +574,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_fract: return "_Fract";
case DeclSpec::TST_float16: return "_Float16";
case DeclSpec::TST_float128: return "__float128";
+ case DeclSpec::TST_ibm128: return "__ibm128";
case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
case DeclSpec::TST_decimal32: return "_Decimal32";
case DeclSpec::TST_decimal64: return "_Decimal64";
@@ -570,11 +587,16 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_typename: return "type-name";
case DeclSpec::TST_typeofType:
case DeclSpec::TST_typeofExpr: return "typeof";
+ case DeclSpec::TST_typeof_unqualType:
+ case DeclSpec::TST_typeof_unqualExpr: return "typeof_unqual";
case DeclSpec::TST_auto: return "auto";
case DeclSpec::TST_auto_type: return "__auto_type";
case DeclSpec::TST_decltype: return "(decltype)";
case DeclSpec::TST_decltype_auto: return "decltype(auto)";
- case DeclSpec::TST_underlyingType: return "__underlying_type";
+#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
+ case DeclSpec::TST_##Trait: \
+ return "__" #Trait;
+#include "clang/Basic/TransformTypeTraits.def"
case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
case DeclSpec::TST_atomic: return "_Atomic";
case DeclSpec::TST_BFloat16: return "__bf16";
@@ -631,8 +653,7 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
case SCS_extern:
case SCS_private_extern:
case SCS_static:
- if (S.getLangOpts().OpenCLVersion < 120 &&
- !S.getLangOpts().OpenCLCPlusPlus) {
+ if (S.getLangOpts().getOpenCLCompatibleVersion() < 120) {
DiagID = diag::err_opencl_unknown_type_specifier;
PrevSpec = getSpecifierName(SC);
return true;
@@ -931,7 +952,7 @@ bool DeclSpec::SetTypeSpecError() {
return false;
}
-bool DeclSpec::SetExtIntType(SourceLocation KWLoc, Expr *BitsExpr,
+bool DeclSpec::SetBitIntType(SourceLocation KWLoc, Expr *BitsExpr,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy) {
assert(BitsExpr && "no expression provided!");
@@ -944,7 +965,7 @@ bool DeclSpec::SetExtIntType(SourceLocation KWLoc, Expr *BitsExpr,
return true;
}
- TypeSpecType = TST_extint;
+ TypeSpecType = TST_bitint;
ExprRep = BitsExpr;
TSTLoc = KWLoc;
TSTNameLoc = KWLoc;
@@ -1108,9 +1129,8 @@ void DeclSpec::SaveWrittenBuiltinSpecs() {
}
/// Finish - This does final analysis of the declspec, rejecting things like
-/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
-/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
-/// DeclSpec is guaranteed self-consistent, even if an error occurred.
+/// "_Imaginary" (lacking an FP type). After calling this method, DeclSpec is
+/// guaranteed to be self-consistent, even if an error occurred.
void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
// Before possibly changing their values, save specs as written.
SaveWrittenBuiltinSpecs();
@@ -1155,6 +1175,17 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
// Validate and finalize AltiVec vector declspec.
if (TypeAltiVecVector) {
+ // No vector long long without VSX (or ZVector).
+ if ((getTypeSpecWidth() == TypeSpecifierWidth::LongLong) &&
+ !S.Context.getTargetInfo().hasFeature("vsx") &&
+ !S.getLangOpts().ZVector)
+ S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_long_decl_spec);
+
+ // No vector __int128 prior to Power8.
+ if ((TypeSpecType == TST_int128) &&
+ !S.Context.getTargetInfo().hasFeature("power8-vector"))
+ S.Diag(TSTLoc, diag::err_invalid_vector_int128_decl_spec);
+
if (TypeAltiVecBool) {
// Sign specifiers are not allowed with vector bool. (PIM 2.1)
if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) {
@@ -1183,13 +1214,6 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_bool_decl_spec)
<< getSpecifierName(getTypeSpecWidth());
- // vector bool long long requires VSX support or ZVector.
- if ((getTypeSpecWidth() == TypeSpecifierWidth::LongLong) &&
- (!S.Context.getTargetInfo().hasFeature("vsx")) &&
- (!S.Context.getTargetInfo().hasFeature("power8-vector")) &&
- !S.getLangOpts().ZVector)
- S.Diag(TSTLoc, diag::err_invalid_vector_long_long_decl_spec);
-
// Elements of vector bool are interpreted as unsigned. (PIM 2.1)
if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
(TypeSpecType == TST_int128) ||
@@ -1212,13 +1236,15 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
!S.Context.getTargetInfo().hasFeature("arch12"))
S.Diag(TSTLoc, diag::err_invalid_vector_float_decl_spec);
} else if (getTypeSpecWidth() == TypeSpecifierWidth::Long) {
- // vector long is unsupported for ZVector and deprecated for AltiVec.
+ // Vector long is unsupported for ZVector, or without VSX, and deprecated
+ // for AltiVec.
// 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().hasFeature("vsx") ||
S.Context.getTargetInfo().getTriple().isOSAIX())
S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_decl_spec);
else
@@ -1245,7 +1271,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&
TypeSpecType != TST_char && TypeSpecType != TST_wchar &&
- !IsFixedPointType && TypeSpecType != TST_extint) {
+ !IsFixedPointType && TypeSpecType != TST_bitint) {
S.Diag(TSSLoc, diag::err_invalid_sign_spec)
<< getSpecifierName((TST)TypeSpecType, Policy);
// signed double -> double.
@@ -1295,13 +1321,14 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
" double");
TypeSpecType = TST_double; // _Complex -> _Complex double.
} else if (TypeSpecType == TST_int || TypeSpecType == TST_char ||
- TypeSpecType == TST_extint) {
+ TypeSpecType == TST_bitint) {
// Note that this intentionally doesn't include _Complex _Bool.
if (!S.getLangOpts().CPlusPlus)
S.Diag(TSTLoc, diag::ext_integer_complex);
} else if (TypeSpecType != TST_float && TypeSpecType != TST_double &&
- TypeSpecType != TST_float128) {
- // FIXME: _Float16, __fp16?
+ TypeSpecType != TST_float128 && TypeSpecType != TST_float16 &&
+ TypeSpecType != TST_ibm128) {
+ // FIXME: __fp16?
S.Diag(TSCLoc, diag::err_invalid_complex_spec)
<< getSpecifierName((TST)TypeSpecType, Policy);
TypeSpecComplex = TSC_unspecified;
@@ -1348,8 +1375,9 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
StorageClassSpecLoc = SourceLocation();
}
// Diagnose if we've recovered from an ill-formed 'auto' storage class
- // specifier in a pre-C++11 dialect of C++.
- if (!S.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto)
+ // specifier in a pre-C++11 dialect of C++ or in a pre-C23 dialect of C.
+ if (!S.getLangOpts().CPlusPlus11 && !S.getLangOpts().C23 &&
+ TypeSpecType == TST_auto)
S.Diag(TSTLoc, diag::ext_auto_type_specifier);
if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11 &&
StorageClassSpec == SCS_auto)