Path: blob/main/contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp
35234 views
//===--- DeclSpec.cpp - Declaration Specifier Semantic Analysis -----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements semantic analysis for declaration specifiers.9//10//===----------------------------------------------------------------------===//1112#include "clang/Sema/DeclSpec.h"13#include "clang/AST/ASTContext.h"14#include "clang/AST/DeclCXX.h"15#include "clang/AST/Expr.h"16#include "clang/AST/LocInfoType.h"17#include "clang/AST/TypeLoc.h"18#include "clang/Basic/LangOptions.h"19#include "clang/Basic/SourceManager.h"20#include "clang/Basic/Specifiers.h"21#include "clang/Basic/TargetInfo.h"22#include "clang/Sema/ParsedTemplate.h"23#include "clang/Sema/Sema.h"24#include "clang/Sema/SemaDiagnostic.h"25#include "llvm/ADT/STLExtras.h"26#include "llvm/ADT/SmallString.h"27#include <cstring>28using namespace clang;293031void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {32assert(TemplateId && "NULL template-id annotation?");33assert(!TemplateId->isInvalid() &&34"should not convert invalid template-ids to unqualified-ids");3536Kind = UnqualifiedIdKind::IK_TemplateId;37this->TemplateId = TemplateId;38StartLocation = TemplateId->TemplateNameLoc;39EndLocation = TemplateId->RAngleLoc;40}4142void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {43assert(TemplateId && "NULL template-id annotation?");44assert(!TemplateId->isInvalid() &&45"should not convert invalid template-ids to unqualified-ids");4647Kind = UnqualifiedIdKind::IK_ConstructorTemplateId;48this->TemplateId = TemplateId;49StartLocation = TemplateId->TemplateNameLoc;50EndLocation = TemplateId->RAngleLoc;51}5253void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,54TypeLoc TL, SourceLocation ColonColonLoc) {55Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);56if (Range.getBegin().isInvalid())57Range.setBegin(TL.getBeginLoc());58Range.setEnd(ColonColonLoc);5960assert(Range == Builder.getSourceRange() &&61"NestedNameSpecifierLoc range computation incorrect");62}6364void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,65SourceLocation IdentifierLoc,66SourceLocation ColonColonLoc) {67Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);6869if (Range.getBegin().isInvalid())70Range.setBegin(IdentifierLoc);71Range.setEnd(ColonColonLoc);7273assert(Range == Builder.getSourceRange() &&74"NestedNameSpecifierLoc range computation incorrect");75}7677void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,78SourceLocation NamespaceLoc,79SourceLocation ColonColonLoc) {80Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);8182if (Range.getBegin().isInvalid())83Range.setBegin(NamespaceLoc);84Range.setEnd(ColonColonLoc);8586assert(Range == Builder.getSourceRange() &&87"NestedNameSpecifierLoc range computation incorrect");88}8990void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,91SourceLocation AliasLoc,92SourceLocation ColonColonLoc) {93Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);9495if (Range.getBegin().isInvalid())96Range.setBegin(AliasLoc);97Range.setEnd(ColonColonLoc);9899assert(Range == Builder.getSourceRange() &&100"NestedNameSpecifierLoc range computation incorrect");101}102103void CXXScopeSpec::MakeGlobal(ASTContext &Context,104SourceLocation ColonColonLoc) {105Builder.MakeGlobal(Context, ColonColonLoc);106107Range = SourceRange(ColonColonLoc);108109assert(Range == Builder.getSourceRange() &&110"NestedNameSpecifierLoc range computation incorrect");111}112113void CXXScopeSpec::MakeSuper(ASTContext &Context, CXXRecordDecl *RD,114SourceLocation SuperLoc,115SourceLocation ColonColonLoc) {116Builder.MakeSuper(Context, RD, SuperLoc, ColonColonLoc);117118Range.setBegin(SuperLoc);119Range.setEnd(ColonColonLoc);120121assert(Range == Builder.getSourceRange() &&122"NestedNameSpecifierLoc range computation incorrect");123}124125void CXXScopeSpec::MakeTrivial(ASTContext &Context,126NestedNameSpecifier *Qualifier, SourceRange R) {127Builder.MakeTrivial(Context, Qualifier, R);128Range = R;129}130131void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {132if (!Other) {133Range = SourceRange();134Builder.Clear();135return;136}137138Range = Other.getSourceRange();139Builder.Adopt(Other);140assert(Range == Builder.getSourceRange() &&141"NestedNameSpecifierLoc range computation incorrect");142}143144SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const {145if (!Builder.getRepresentation())146return SourceLocation();147return Builder.getTemporary().getLocalBeginLoc();148}149150NestedNameSpecifierLoc151CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {152if (!Builder.getRepresentation())153return NestedNameSpecifierLoc();154155return Builder.getWithLocInContext(Context);156}157158/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.159/// "TheDeclarator" is the declarator that this will be added to.160DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,161bool isAmbiguous,162SourceLocation LParenLoc,163ParamInfo *Params,164unsigned NumParams,165SourceLocation EllipsisLoc,166SourceLocation RParenLoc,167bool RefQualifierIsLvalueRef,168SourceLocation RefQualifierLoc,169SourceLocation MutableLoc,170ExceptionSpecificationType171ESpecType,172SourceRange ESpecRange,173ParsedType *Exceptions,174SourceRange *ExceptionRanges,175unsigned NumExceptions,176Expr *NoexceptExpr,177CachedTokens *ExceptionSpecTokens,178ArrayRef<NamedDecl*>179DeclsInPrototype,180SourceLocation LocalRangeBegin,181SourceLocation LocalRangeEnd,182Declarator &TheDeclarator,183TypeResult TrailingReturnType,184SourceLocation185TrailingReturnTypeLoc,186DeclSpec *MethodQualifiers) {187assert(!(MethodQualifiers && MethodQualifiers->getTypeQualifiers() & DeclSpec::TQ_atomic) &&188"function cannot have _Atomic qualifier");189190DeclaratorChunk I;191I.Kind = Function;192I.Loc = LocalRangeBegin;193I.EndLoc = LocalRangeEnd;194new (&I.Fun) FunctionTypeInfo;195I.Fun.hasPrototype = hasProto;196I.Fun.isVariadic = EllipsisLoc.isValid();197I.Fun.isAmbiguous = isAmbiguous;198I.Fun.LParenLoc = LParenLoc;199I.Fun.EllipsisLoc = EllipsisLoc;200I.Fun.RParenLoc = RParenLoc;201I.Fun.DeleteParams = false;202I.Fun.NumParams = NumParams;203I.Fun.Params = nullptr;204I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;205I.Fun.RefQualifierLoc = RefQualifierLoc;206I.Fun.MutableLoc = MutableLoc;207I.Fun.ExceptionSpecType = ESpecType;208I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin();209I.Fun.ExceptionSpecLocEnd = ESpecRange.getEnd();210I.Fun.NumExceptionsOrDecls = 0;211I.Fun.Exceptions = nullptr;212I.Fun.NoexceptExpr = nullptr;213I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() ||214TrailingReturnType.isInvalid();215I.Fun.TrailingReturnType = TrailingReturnType.get();216I.Fun.TrailingReturnTypeLoc = TrailingReturnTypeLoc;217I.Fun.MethodQualifiers = nullptr;218I.Fun.QualAttrFactory = nullptr;219220if (MethodQualifiers && (MethodQualifiers->getTypeQualifiers() ||221MethodQualifiers->getAttributes().size())) {222auto &attrs = MethodQualifiers->getAttributes();223I.Fun.MethodQualifiers = new DeclSpec(attrs.getPool().getFactory());224MethodQualifiers->forEachCVRUQualifier(225[&](DeclSpec::TQ TypeQual, StringRef PrintName, SourceLocation SL) {226I.Fun.MethodQualifiers->SetTypeQual(TypeQual, SL);227});228I.Fun.MethodQualifiers->getAttributes().takeAllFrom(attrs);229I.Fun.MethodQualifiers->getAttributePool().takeAllFrom(attrs.getPool());230}231232assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow");233234// new[] a parameter array if needed.235if (NumParams) {236// If the 'InlineParams' in Declarator is unused and big enough, put our237// parameter list there (in an effort to avoid new/delete traffic). If it238// is already used (consider a function returning a function pointer) or too239// small (function with too many parameters), go to the heap.240if (!TheDeclarator.InlineStorageUsed &&241NumParams <= std::size(TheDeclarator.InlineParams)) {242I.Fun.Params = TheDeclarator.InlineParams;243new (I.Fun.Params) ParamInfo[NumParams];244I.Fun.DeleteParams = false;245TheDeclarator.InlineStorageUsed = true;246} else {247I.Fun.Params = new DeclaratorChunk::ParamInfo[NumParams];248I.Fun.DeleteParams = true;249}250for (unsigned i = 0; i < NumParams; i++)251I.Fun.Params[i] = std::move(Params[i]);252}253254// Check what exception specification information we should actually store.255switch (ESpecType) {256default: break; // By default, save nothing.257case EST_Dynamic:258// new[] an exception array if needed259if (NumExceptions) {260I.Fun.NumExceptionsOrDecls = NumExceptions;261I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];262for (unsigned i = 0; i != NumExceptions; ++i) {263I.Fun.Exceptions[i].Ty = Exceptions[i];264I.Fun.Exceptions[i].Range = ExceptionRanges[i];265}266}267break;268269case EST_DependentNoexcept:270case EST_NoexceptFalse:271case EST_NoexceptTrue:272I.Fun.NoexceptExpr = NoexceptExpr;273break;274275case EST_Unparsed:276I.Fun.ExceptionSpecTokens = ExceptionSpecTokens;277break;278}279280if (!DeclsInPrototype.empty()) {281assert(ESpecType == EST_None && NumExceptions == 0 &&282"cannot have exception specifiers and decls in prototype");283I.Fun.NumExceptionsOrDecls = DeclsInPrototype.size();284// Copy the array of decls into stable heap storage.285I.Fun.DeclsInPrototype = new NamedDecl *[DeclsInPrototype.size()];286for (size_t J = 0; J < DeclsInPrototype.size(); ++J)287I.Fun.DeclsInPrototype[J] = DeclsInPrototype[J];288}289290return I;291}292293void Declarator::setDecompositionBindings(294SourceLocation LSquareLoc,295MutableArrayRef<DecompositionDeclarator::Binding> Bindings,296SourceLocation RSquareLoc) {297assert(!hasName() && "declarator given multiple names!");298299BindingGroup.LSquareLoc = LSquareLoc;300BindingGroup.RSquareLoc = RSquareLoc;301BindingGroup.NumBindings = Bindings.size();302Range.setEnd(RSquareLoc);303304// We're now past the identifier.305SetIdentifier(nullptr, LSquareLoc);306Name.EndLocation = RSquareLoc;307308// Allocate storage for bindings and stash them away.309if (Bindings.size()) {310if (!InlineStorageUsed && Bindings.size() <= std::size(InlineBindings)) {311BindingGroup.Bindings = InlineBindings;312BindingGroup.DeleteBindings = false;313InlineStorageUsed = true;314} else {315BindingGroup.Bindings =316new DecompositionDeclarator::Binding[Bindings.size()];317BindingGroup.DeleteBindings = true;318}319std::uninitialized_move(Bindings.begin(), Bindings.end(),320BindingGroup.Bindings);321}322}323324bool Declarator::isDeclarationOfFunction() const {325for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {326switch (DeclTypeInfo[i].Kind) {327case DeclaratorChunk::Function:328return true;329case DeclaratorChunk::Paren:330continue;331case DeclaratorChunk::Pointer:332case DeclaratorChunk::Reference:333case DeclaratorChunk::Array:334case DeclaratorChunk::BlockPointer:335case DeclaratorChunk::MemberPointer:336case DeclaratorChunk::Pipe:337return false;338}339llvm_unreachable("Invalid type chunk");340}341342switch (DS.getTypeSpecType()) {343case TST_atomic:344case TST_auto:345case TST_auto_type:346case TST_bool:347case TST_char:348case TST_char8:349case TST_char16:350case TST_char32:351case TST_class:352case TST_decimal128:353case TST_decimal32:354case TST_decimal64:355case TST_double:356case TST_Accum:357case TST_Fract:358case TST_Float16:359case TST_float128:360case TST_ibm128:361case TST_enum:362case TST_error:363case TST_float:364case TST_half:365case TST_int:366case TST_int128:367case TST_bitint:368case TST_struct:369case TST_interface:370case TST_union:371case TST_unknown_anytype:372case TST_unspecified:373case TST_void:374case TST_wchar:375case TST_BFloat16:376case TST_typename_pack_indexing:377#define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:378#include "clang/Basic/OpenCLImageTypes.def"379return false;380381case TST_decltype_auto:382// This must have an initializer, so can't be a function declaration,383// even if the initializer has function type.384return false;385386case TST_decltype:387case TST_typeof_unqualExpr:388case TST_typeofExpr:389if (Expr *E = DS.getRepAsExpr())390return E->getType()->isFunctionType();391return false;392393#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:394#include "clang/Basic/TransformTypeTraits.def"395case TST_typename:396case TST_typeof_unqualType:397case TST_typeofType: {398QualType QT = DS.getRepAsType().get();399if (QT.isNull())400return false;401402if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))403QT = LIT->getType();404405if (QT.isNull())406return false;407408return QT->isFunctionType();409}410}411412llvm_unreachable("Invalid TypeSpecType!");413}414415bool Declarator::isStaticMember() {416assert(getContext() == DeclaratorContext::Member);417return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||418(!isDeclarationOfFunction() && !getTemplateParameterLists().empty()) ||419(getName().getKind() == UnqualifiedIdKind::IK_OperatorFunctionId &&420CXXMethodDecl::isStaticOverloadedOperator(421getName().OperatorFunctionId.Operator));422}423424bool Declarator::isExplicitObjectMemberFunction() {425if (!isFunctionDeclarator())426return false;427DeclaratorChunk::FunctionTypeInfo &Fun = getFunctionTypeInfo();428if (Fun.NumParams) {429auto *P = dyn_cast_or_null<ParmVarDecl>(Fun.Params[0].Param);430if (P && P->isExplicitObjectParameter())431return true;432}433return false;434}435436bool Declarator::isCtorOrDtor() {437return (getName().getKind() == UnqualifiedIdKind::IK_ConstructorName) ||438(getName().getKind() == UnqualifiedIdKind::IK_DestructorName);439}440441void DeclSpec::forEachCVRUQualifier(442llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) {443if (TypeQualifiers & TQ_const)444Handle(TQ_const, "const", TQ_constLoc);445if (TypeQualifiers & TQ_volatile)446Handle(TQ_volatile, "volatile", TQ_volatileLoc);447if (TypeQualifiers & TQ_restrict)448Handle(TQ_restrict, "restrict", TQ_restrictLoc);449if (TypeQualifiers & TQ_unaligned)450Handle(TQ_unaligned, "unaligned", TQ_unalignedLoc);451}452453void DeclSpec::forEachQualifier(454llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) {455forEachCVRUQualifier(Handle);456// FIXME: Add code below to iterate through the attributes and call Handle.457}458459bool DeclSpec::hasTagDefinition() const {460if (!TypeSpecOwned)461return false;462return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition();463}464465/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this466/// declaration specifier includes.467///468unsigned DeclSpec::getParsedSpecifiers() const {469unsigned Res = 0;470if (StorageClassSpec != SCS_unspecified ||471ThreadStorageClassSpec != TSCS_unspecified)472Res |= PQ_StorageClassSpecifier;473474if (TypeQualifiers != TQ_unspecified)475Res |= PQ_TypeQualifier;476477if (hasTypeSpecifier())478Res |= PQ_TypeSpecifier;479480if (FS_inline_specified || FS_virtual_specified || hasExplicitSpecifier() ||481FS_noreturn_specified || FS_forceinline_specified)482Res |= PQ_FunctionSpecifier;483return Res;484}485486template <class T> static bool BadSpecifier(T TNew, T TPrev,487const char *&PrevSpec,488unsigned &DiagID,489bool IsExtension = true) {490PrevSpec = DeclSpec::getSpecifierName(TPrev);491if (TNew != TPrev)492DiagID = diag::err_invalid_decl_spec_combination;493else494DiagID = IsExtension ? diag::ext_warn_duplicate_declspec :495diag::warn_duplicate_declspec;496return true;497}498499const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {500switch (S) {501case DeclSpec::SCS_unspecified: return "unspecified";502case DeclSpec::SCS_typedef: return "typedef";503case DeclSpec::SCS_extern: return "extern";504case DeclSpec::SCS_static: return "static";505case DeclSpec::SCS_auto: return "auto";506case DeclSpec::SCS_register: return "register";507case DeclSpec::SCS_private_extern: return "__private_extern__";508case DeclSpec::SCS_mutable: return "mutable";509}510llvm_unreachable("Unknown typespec!");511}512513const char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) {514switch (S) {515case DeclSpec::TSCS_unspecified: return "unspecified";516case DeclSpec::TSCS___thread: return "__thread";517case DeclSpec::TSCS_thread_local: return "thread_local";518case DeclSpec::TSCS__Thread_local: return "_Thread_local";519}520llvm_unreachable("Unknown typespec!");521}522523const char *DeclSpec::getSpecifierName(TypeSpecifierWidth W) {524switch (W) {525case TypeSpecifierWidth::Unspecified:526return "unspecified";527case TypeSpecifierWidth::Short:528return "short";529case TypeSpecifierWidth::Long:530return "long";531case TypeSpecifierWidth::LongLong:532return "long long";533}534llvm_unreachable("Unknown typespec!");535}536537const char *DeclSpec::getSpecifierName(TSC C) {538switch (C) {539case TSC_unspecified: return "unspecified";540case TSC_imaginary: return "imaginary";541case TSC_complex: return "complex";542}543llvm_unreachable("Unknown typespec!");544}545546const char *DeclSpec::getSpecifierName(TypeSpecifierSign S) {547switch (S) {548case TypeSpecifierSign::Unspecified:549return "unspecified";550case TypeSpecifierSign::Signed:551return "signed";552case TypeSpecifierSign::Unsigned:553return "unsigned";554}555llvm_unreachable("Unknown typespec!");556}557558const char *DeclSpec::getSpecifierName(DeclSpec::TST T,559const PrintingPolicy &Policy) {560switch (T) {561case DeclSpec::TST_unspecified: return "unspecified";562case DeclSpec::TST_void: return "void";563case DeclSpec::TST_char: return "char";564case DeclSpec::TST_wchar: return Policy.MSWChar ? "__wchar_t" : "wchar_t";565case DeclSpec::TST_char8: return "char8_t";566case DeclSpec::TST_char16: return "char16_t";567case DeclSpec::TST_char32: return "char32_t";568case DeclSpec::TST_int: return "int";569case DeclSpec::TST_int128: return "__int128";570case DeclSpec::TST_bitint: return "_BitInt";571case DeclSpec::TST_half: return "half";572case DeclSpec::TST_float: return "float";573case DeclSpec::TST_double: return "double";574case DeclSpec::TST_accum: return "_Accum";575case DeclSpec::TST_fract: return "_Fract";576case DeclSpec::TST_float16: return "_Float16";577case DeclSpec::TST_float128: return "__float128";578case DeclSpec::TST_ibm128: return "__ibm128";579case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";580case DeclSpec::TST_decimal32: return "_Decimal32";581case DeclSpec::TST_decimal64: return "_Decimal64";582case DeclSpec::TST_decimal128: return "_Decimal128";583case DeclSpec::TST_enum: return "enum";584case DeclSpec::TST_class: return "class";585case DeclSpec::TST_union: return "union";586case DeclSpec::TST_struct: return "struct";587case DeclSpec::TST_interface: return "__interface";588case DeclSpec::TST_typename: return "type-name";589case DeclSpec::TST_typename_pack_indexing:590return "type-name-pack-indexing";591case DeclSpec::TST_typeofType:592case DeclSpec::TST_typeofExpr: return "typeof";593case DeclSpec::TST_typeof_unqualType:594case DeclSpec::TST_typeof_unqualExpr: return "typeof_unqual";595case DeclSpec::TST_auto: return "auto";596case DeclSpec::TST_auto_type: return "__auto_type";597case DeclSpec::TST_decltype: return "(decltype)";598case DeclSpec::TST_decltype_auto: return "decltype(auto)";599#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \600case DeclSpec::TST_##Trait: \601return "__" #Trait;602#include "clang/Basic/TransformTypeTraits.def"603case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";604case DeclSpec::TST_atomic: return "_Atomic";605case DeclSpec::TST_BFloat16: return "__bf16";606#define GENERIC_IMAGE_TYPE(ImgType, Id) \607case DeclSpec::TST_##ImgType##_t: \608return #ImgType "_t";609#include "clang/Basic/OpenCLImageTypes.def"610case DeclSpec::TST_error: return "(error)";611}612llvm_unreachable("Unknown typespec!");613}614615const char *DeclSpec::getSpecifierName(ConstexprSpecKind C) {616switch (C) {617case ConstexprSpecKind::Unspecified:618return "unspecified";619case ConstexprSpecKind::Constexpr:620return "constexpr";621case ConstexprSpecKind::Consteval:622return "consteval";623case ConstexprSpecKind::Constinit:624return "constinit";625}626llvm_unreachable("Unknown ConstexprSpecKind");627}628629const char *DeclSpec::getSpecifierName(TQ T) {630switch (T) {631case DeclSpec::TQ_unspecified: return "unspecified";632case DeclSpec::TQ_const: return "const";633case DeclSpec::TQ_restrict: return "restrict";634case DeclSpec::TQ_volatile: return "volatile";635case DeclSpec::TQ_atomic: return "_Atomic";636case DeclSpec::TQ_unaligned: return "__unaligned";637}638llvm_unreachable("Unknown typespec!");639}640641bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,642const char *&PrevSpec,643unsigned &DiagID,644const PrintingPolicy &Policy) {645// OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class646// specifiers are not supported.647// It seems sensible to prohibit private_extern too648// The cl_clang_storage_class_specifiers extension enables support for649// these storage-class specifiers.650// OpenCL v1.2 s6.8 changes this to "The auto and register storage-class651// specifiers are not supported."652if (S.getLangOpts().OpenCL &&653!S.getOpenCLOptions().isAvailableOption(654"cl_clang_storage_class_specifiers", S.getLangOpts())) {655switch (SC) {656case SCS_extern:657case SCS_private_extern:658case SCS_static:659if (S.getLangOpts().getOpenCLCompatibleVersion() < 120) {660DiagID = diag::err_opencl_unknown_type_specifier;661PrevSpec = getSpecifierName(SC);662return true;663}664break;665case SCS_auto:666case SCS_register:667DiagID = diag::err_opencl_unknown_type_specifier;668PrevSpec = getSpecifierName(SC);669return true;670default:671break;672}673}674675if (StorageClassSpec != SCS_unspecified) {676// Maybe this is an attempt to use C++11 'auto' outside of C++11 mode.677bool isInvalid = true;678if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {679if (SC == SCS_auto)680return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID, Policy);681if (StorageClassSpec == SCS_auto) {682isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,683PrevSpec, DiagID, Policy);684assert(!isInvalid && "auto SCS -> TST recovery failed");685}686}687688// Changing storage class is allowed only if the previous one689// was the 'extern' that is part of a linkage specification and690// the new storage class is 'typedef'.691if (isInvalid &&692!(SCS_extern_in_linkage_spec &&693StorageClassSpec == SCS_extern &&694SC == SCS_typedef))695return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);696}697StorageClassSpec = SC;698StorageClassSpecLoc = Loc;699assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");700return false;701}702703bool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,704const char *&PrevSpec,705unsigned &DiagID) {706if (ThreadStorageClassSpec != TSCS_unspecified)707return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID);708709ThreadStorageClassSpec = TSC;710ThreadStorageClassSpecLoc = Loc;711return false;712}713714/// These methods set the specified attribute of the DeclSpec, but return true715/// and ignore the request if invalid (e.g. "extern" then "auto" is716/// specified).717bool DeclSpec::SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc,718const char *&PrevSpec, unsigned &DiagID,719const PrintingPolicy &Policy) {720// Overwrite TSWRange.Begin only if TypeSpecWidth was unspecified, so that721// for 'long long' we will keep the source location of the first 'long'.722if (getTypeSpecWidth() == TypeSpecifierWidth::Unspecified)723TSWRange.setBegin(Loc);724// Allow turning long -> long long.725else if (W != TypeSpecifierWidth::LongLong ||726getTypeSpecWidth() != TypeSpecifierWidth::Long)727return BadSpecifier(W, getTypeSpecWidth(), PrevSpec, DiagID);728TypeSpecWidth = static_cast<unsigned>(W);729// Remember location of the last 'long'730TSWRange.setEnd(Loc);731return false;732}733734bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,735const char *&PrevSpec,736unsigned &DiagID) {737if (TypeSpecComplex != TSC_unspecified)738return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);739TypeSpecComplex = C;740TSCLoc = Loc;741return false;742}743744bool DeclSpec::SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc,745const char *&PrevSpec, unsigned &DiagID) {746if (getTypeSpecSign() != TypeSpecifierSign::Unspecified)747return BadSpecifier(S, getTypeSpecSign(), PrevSpec, DiagID);748TypeSpecSign = static_cast<unsigned>(S);749TSSLoc = Loc;750return false;751}752753bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,754const char *&PrevSpec,755unsigned &DiagID,756ParsedType Rep,757const PrintingPolicy &Policy) {758return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Policy);759}760761bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,762SourceLocation TagNameLoc,763const char *&PrevSpec,764unsigned &DiagID,765ParsedType Rep,766const PrintingPolicy &Policy) {767assert(isTypeRep(T) && "T does not store a type");768assert(Rep && "no type provided!");769if (TypeSpecType == TST_error)770return false;771if (TypeSpecType != TST_unspecified) {772PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);773DiagID = diag::err_invalid_decl_spec_combination;774return true;775}776TypeSpecType = T;777TypeRep = Rep;778TSTLoc = TagKwLoc;779TSTNameLoc = TagNameLoc;780TypeSpecOwned = false;781782if (T == TST_typename_pack_indexing) {783// we got there from a an annotation. Reconstruct the type784// Ugly...785QualType QT = Rep.get();786const PackIndexingType *LIT = cast<PackIndexingType>(QT);787TypeRep = ParsedType::make(LIT->getPattern());788PackIndexingExpr = LIT->getIndexExpr();789}790return false;791}792793bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,794const char *&PrevSpec,795unsigned &DiagID,796Expr *Rep,797const PrintingPolicy &Policy) {798assert(isExprRep(T) && "T does not store an expr");799assert(Rep && "no expression provided!");800if (TypeSpecType == TST_error)801return false;802if (TypeSpecType != TST_unspecified) {803PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);804DiagID = diag::err_invalid_decl_spec_combination;805return true;806}807TypeSpecType = T;808ExprRep = Rep;809TSTLoc = Loc;810TSTNameLoc = Loc;811TypeSpecOwned = false;812return false;813}814815bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,816const char *&PrevSpec,817unsigned &DiagID,818Decl *Rep, bool Owned,819const PrintingPolicy &Policy) {820return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned, Policy);821}822823bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,824SourceLocation TagNameLoc,825const char *&PrevSpec,826unsigned &DiagID,827Decl *Rep, bool Owned,828const PrintingPolicy &Policy) {829assert(isDeclRep(T) && "T does not store a decl");830// Unlike the other cases, we don't assert that we actually get a decl.831832if (TypeSpecType == TST_error)833return false;834if (TypeSpecType != TST_unspecified) {835PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);836DiagID = diag::err_invalid_decl_spec_combination;837return true;838}839TypeSpecType = T;840DeclRep = Rep;841TSTLoc = TagKwLoc;842TSTNameLoc = TagNameLoc;843TypeSpecOwned = Owned && Rep != nullptr;844return false;845}846847bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,848unsigned &DiagID, TemplateIdAnnotation *Rep,849const PrintingPolicy &Policy) {850assert(T == TST_auto || T == TST_decltype_auto);851ConstrainedAuto = true;852TemplateIdRep = Rep;853return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Policy);854}855856bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,857const char *&PrevSpec,858unsigned &DiagID,859const PrintingPolicy &Policy) {860assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&861"rep required for these type-spec kinds!");862if (TypeSpecType == TST_error)863return false;864if (TypeSpecType != TST_unspecified) {865PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);866DiagID = diag::err_invalid_decl_spec_combination;867return true;868}869TSTLoc = Loc;870TSTNameLoc = Loc;871if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {872TypeAltiVecBool = true;873return false;874}875TypeSpecType = T;876TypeSpecOwned = false;877return false;878}879880bool DeclSpec::SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec,881unsigned &DiagID) {882// Cannot set twice883if (TypeSpecSat) {884DiagID = diag::warn_duplicate_declspec;885PrevSpec = "_Sat";886return true;887}888TypeSpecSat = true;889TSSatLoc = Loc;890return false;891}892893bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,894const char *&PrevSpec, unsigned &DiagID,895const PrintingPolicy &Policy) {896if (TypeSpecType == TST_error)897return false;898if (TypeSpecType != TST_unspecified) {899PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);900DiagID = diag::err_invalid_vector_decl_spec_combination;901return true;902}903TypeAltiVecVector = isAltiVecVector;904AltiVecLoc = Loc;905return false;906}907908bool DeclSpec::SetTypePipe(bool isPipe, SourceLocation Loc,909const char *&PrevSpec, unsigned &DiagID,910const PrintingPolicy &Policy) {911if (TypeSpecType == TST_error)912return false;913if (TypeSpecType != TST_unspecified) {914PrevSpec = DeclSpec::getSpecifierName((TST)TypeSpecType, Policy);915DiagID = diag::err_invalid_decl_spec_combination;916return true;917}918919if (isPipe) {920TypeSpecPipe = static_cast<unsigned>(TypeSpecifiersPipe::Pipe);921}922return false;923}924925bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,926const char *&PrevSpec, unsigned &DiagID,927const PrintingPolicy &Policy) {928if (TypeSpecType == TST_error)929return false;930if (!TypeAltiVecVector || TypeAltiVecPixel ||931(TypeSpecType != TST_unspecified)) {932PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);933DiagID = diag::err_invalid_pixel_decl_spec_combination;934return true;935}936TypeAltiVecPixel = isAltiVecPixel;937TSTLoc = Loc;938TSTNameLoc = Loc;939return false;940}941942bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,943const char *&PrevSpec, unsigned &DiagID,944const PrintingPolicy &Policy) {945if (TypeSpecType == TST_error)946return false;947if (!TypeAltiVecVector || TypeAltiVecBool ||948(TypeSpecType != TST_unspecified)) {949PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);950DiagID = diag::err_invalid_vector_bool_decl_spec;951return true;952}953TypeAltiVecBool = isAltiVecBool;954TSTLoc = Loc;955TSTNameLoc = Loc;956return false;957}958959bool DeclSpec::SetTypeSpecError() {960TypeSpecType = TST_error;961TypeSpecOwned = false;962TSTLoc = SourceLocation();963TSTNameLoc = SourceLocation();964return false;965}966967bool DeclSpec::SetBitIntType(SourceLocation KWLoc, Expr *BitsExpr,968const char *&PrevSpec, unsigned &DiagID,969const PrintingPolicy &Policy) {970assert(BitsExpr && "no expression provided!");971if (TypeSpecType == TST_error)972return false;973974if (TypeSpecType != TST_unspecified) {975PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);976DiagID = diag::err_invalid_decl_spec_combination;977return true;978}979980TypeSpecType = TST_bitint;981ExprRep = BitsExpr;982TSTLoc = KWLoc;983TSTNameLoc = KWLoc;984TypeSpecOwned = false;985return false;986}987988void DeclSpec::SetPackIndexingExpr(SourceLocation EllipsisLoc,989Expr *IndexingExpr) {990assert(TypeSpecType == TST_typename &&991"pack indexing can only be applied to typename");992TypeSpecType = TST_typename_pack_indexing;993PackIndexingExpr = IndexingExpr;994this->EllipsisLoc = EllipsisLoc;995}996997bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,998unsigned &DiagID, const LangOptions &Lang) {999// Duplicates are permitted in C99 onwards, but are not permitted in C89 or1000// C++. However, since this is likely not what the user intended, we will1001// always warn. We do not need to set the qualifier's location since we1002// already have it.1003if (TypeQualifiers & T) {1004bool IsExtension = true;1005if (Lang.C99)1006IsExtension = false;1007return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);1008}10091010return SetTypeQual(T, Loc);1011}10121013bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc) {1014TypeQualifiers |= T;10151016switch (T) {1017case TQ_unspecified: break;1018case TQ_const: TQ_constLoc = Loc; return false;1019case TQ_restrict: TQ_restrictLoc = Loc; return false;1020case TQ_volatile: TQ_volatileLoc = Loc; return false;1021case TQ_unaligned: TQ_unalignedLoc = Loc; return false;1022case TQ_atomic: TQ_atomicLoc = Loc; return false;1023}10241025llvm_unreachable("Unknown type qualifier!");1026}10271028bool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,1029unsigned &DiagID) {1030// 'inline inline' is ok. However, since this is likely not what the user1031// intended, we will always warn, similar to duplicates of type qualifiers.1032if (FS_inline_specified) {1033DiagID = diag::warn_duplicate_declspec;1034PrevSpec = "inline";1035return true;1036}1037FS_inline_specified = true;1038FS_inlineLoc = Loc;1039return false;1040}10411042bool DeclSpec::setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec,1043unsigned &DiagID) {1044if (FS_forceinline_specified) {1045DiagID = diag::warn_duplicate_declspec;1046PrevSpec = "__forceinline";1047return true;1048}1049FS_forceinline_specified = true;1050FS_forceinlineLoc = Loc;1051return false;1052}10531054bool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc,1055const char *&PrevSpec,1056unsigned &DiagID) {1057// 'virtual virtual' is ok, but warn as this is likely not what the user1058// intended.1059if (FS_virtual_specified) {1060DiagID = diag::warn_duplicate_declspec;1061PrevSpec = "virtual";1062return true;1063}1064FS_virtual_specified = true;1065FS_virtualLoc = Loc;1066return false;1067}10681069bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc,1070const char *&PrevSpec, unsigned &DiagID,1071ExplicitSpecifier ExplicitSpec,1072SourceLocation CloseParenLoc) {1073// 'explicit explicit' is ok, but warn as this is likely not what the user1074// intended.1075if (hasExplicitSpecifier()) {1076DiagID = (ExplicitSpec.getExpr() || FS_explicit_specifier.getExpr())1077? diag::err_duplicate_declspec1078: diag::ext_warn_duplicate_declspec;1079PrevSpec = "explicit";1080return true;1081}1082FS_explicit_specifier = ExplicitSpec;1083FS_explicitLoc = Loc;1084FS_explicitCloseParenLoc = CloseParenLoc;1085return false;1086}10871088bool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc,1089const char *&PrevSpec,1090unsigned &DiagID) {1091// '_Noreturn _Noreturn' is ok, but warn as this is likely not what the user1092// intended.1093if (FS_noreturn_specified) {1094DiagID = diag::warn_duplicate_declspec;1095PrevSpec = "_Noreturn";1096return true;1097}1098FS_noreturn_specified = true;1099FS_noreturnLoc = Loc;1100return false;1101}11021103bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,1104unsigned &DiagID) {1105if (isFriendSpecified()) {1106PrevSpec = "friend";1107DiagID = diag::warn_duplicate_declspec;1108return true;1109}11101111FriendSpecifiedFirst = isEmpty();1112FriendLoc = Loc;1113return false;1114}11151116bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,1117unsigned &DiagID) {1118if (isModulePrivateSpecified()) {1119PrevSpec = "__module_private__";1120DiagID = diag::ext_warn_duplicate_declspec;1121return true;1122}11231124ModulePrivateLoc = Loc;1125return false;1126}11271128bool DeclSpec::SetConstexprSpec(ConstexprSpecKind ConstexprKind,1129SourceLocation Loc, const char *&PrevSpec,1130unsigned &DiagID) {1131if (getConstexprSpecifier() != ConstexprSpecKind::Unspecified)1132return BadSpecifier(ConstexprKind, getConstexprSpecifier(), PrevSpec,1133DiagID);1134ConstexprSpecifier = static_cast<unsigned>(ConstexprKind);1135ConstexprLoc = Loc;1136return false;1137}11381139void DeclSpec::SaveWrittenBuiltinSpecs() {1140writtenBS.Sign = static_cast<int>(getTypeSpecSign());1141writtenBS.Width = static_cast<int>(getTypeSpecWidth());1142writtenBS.Type = getTypeSpecType();1143// Search the list of attributes for the presence of a mode attribute.1144writtenBS.ModeAttr = getAttributes().hasAttribute(ParsedAttr::AT_Mode);1145}11461147/// Finish - This does final analysis of the declspec, rejecting things like1148/// "_Complex" (lacking an FP type). After calling this method, DeclSpec is1149/// guaranteed to be self-consistent, even if an error occurred.1150void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {1151// Before possibly changing their values, save specs as written.1152SaveWrittenBuiltinSpecs();11531154// Check the type specifier components first. No checking for an invalid1155// type.1156if (TypeSpecType == TST_error)1157return;11581159// If decltype(auto) is used, no other type specifiers are permitted.1160if (TypeSpecType == TST_decltype_auto &&1161(getTypeSpecWidth() != TypeSpecifierWidth::Unspecified ||1162TypeSpecComplex != TSC_unspecified ||1163getTypeSpecSign() != TypeSpecifierSign::Unspecified ||1164TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool ||1165TypeQualifiers)) {1166const unsigned NumLocs = 9;1167SourceLocation ExtraLocs[NumLocs] = {1168TSWRange.getBegin(), TSCLoc, TSSLoc,1169AltiVecLoc, TQ_constLoc, TQ_restrictLoc,1170TQ_volatileLoc, TQ_atomicLoc, TQ_unalignedLoc};1171FixItHint Hints[NumLocs];1172SourceLocation FirstLoc;1173for (unsigned I = 0; I != NumLocs; ++I) {1174if (ExtraLocs[I].isValid()) {1175if (FirstLoc.isInvalid() ||1176S.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I],1177FirstLoc))1178FirstLoc = ExtraLocs[I];1179Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]);1180}1181}1182TypeSpecWidth = static_cast<unsigned>(TypeSpecifierWidth::Unspecified);1183TypeSpecComplex = TSC_unspecified;1184TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unspecified);1185TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false;1186TypeQualifiers = 0;1187S.Diag(TSTLoc, diag::err_decltype_auto_cannot_be_combined)1188<< Hints[0] << Hints[1] << Hints[2] << Hints[3]1189<< Hints[4] << Hints[5] << Hints[6] << Hints[7];1190}11911192// Validate and finalize AltiVec vector declspec.1193if (TypeAltiVecVector) {1194// No vector long long without VSX (or ZVector).1195if ((getTypeSpecWidth() == TypeSpecifierWidth::LongLong) &&1196!S.Context.getTargetInfo().hasFeature("vsx") &&1197!S.getLangOpts().ZVector)1198S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_long_decl_spec);11991200// No vector __int128 prior to Power8.1201if ((TypeSpecType == TST_int128) &&1202!S.Context.getTargetInfo().hasFeature("power8-vector"))1203S.Diag(TSTLoc, diag::err_invalid_vector_int128_decl_spec);12041205// Complex vector types are not supported.1206if (TypeSpecComplex != TSC_unspecified)1207S.Diag(TSCLoc, diag::err_invalid_vector_complex_decl_spec);1208else if (TypeAltiVecBool) {1209// Sign specifiers are not allowed with vector bool. (PIM 2.1)1210if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) {1211S.Diag(TSSLoc, diag::err_invalid_vector_bool_decl_spec)1212<< getSpecifierName(getTypeSpecSign());1213}1214// Only char/int are valid with vector bool prior to Power10.1215// Power10 adds instructions that produce vector bool data1216// for quadwords as well so allow vector bool __int128.1217if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&1218(TypeSpecType != TST_int) && (TypeSpecType != TST_int128)) ||1219TypeAltiVecPixel) {1220S.Diag(TSTLoc, diag::err_invalid_vector_bool_decl_spec)1221<< (TypeAltiVecPixel ? "__pixel" :1222getSpecifierName((TST)TypeSpecType, Policy));1223}1224// vector bool __int128 requires Power10.1225if ((TypeSpecType == TST_int128) &&1226(!S.Context.getTargetInfo().hasFeature("power10-vector")))1227S.Diag(TSTLoc, diag::err_invalid_vector_bool_int128_decl_spec);12281229// Only 'short' and 'long long' are valid with vector bool. (PIM 2.1)1230if ((getTypeSpecWidth() != TypeSpecifierWidth::Unspecified) &&1231(getTypeSpecWidth() != TypeSpecifierWidth::Short) &&1232(getTypeSpecWidth() != TypeSpecifierWidth::LongLong))1233S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_bool_decl_spec)1234<< getSpecifierName(getTypeSpecWidth());12351236// Elements of vector bool are interpreted as unsigned. (PIM 2.1)1237if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||1238(TypeSpecType == TST_int128) ||1239(getTypeSpecWidth() != TypeSpecifierWidth::Unspecified))1240TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unsigned);1241} else if (TypeSpecType == TST_double) {1242// vector long double and vector long long double are never allowed.1243// vector double is OK for Power7 and later, and ZVector.1244if (getTypeSpecWidth() == TypeSpecifierWidth::Long ||1245getTypeSpecWidth() == TypeSpecifierWidth::LongLong)1246S.Diag(TSWRange.getBegin(),1247diag::err_invalid_vector_long_double_decl_spec);1248else if (!S.Context.getTargetInfo().hasFeature("vsx") &&1249!S.getLangOpts().ZVector)1250S.Diag(TSTLoc, diag::err_invalid_vector_double_decl_spec);1251} else if (TypeSpecType == TST_float) {1252// vector float is unsupported for ZVector unless we have the1253// vector-enhancements facility 1 (ISA revision 12).1254if (S.getLangOpts().ZVector &&1255!S.Context.getTargetInfo().hasFeature("arch12"))1256S.Diag(TSTLoc, diag::err_invalid_vector_float_decl_spec);1257} else if (getTypeSpecWidth() == TypeSpecifierWidth::Long) {1258// Vector long is unsupported for ZVector, or without VSX, and deprecated1259// for AltiVec.1260// It has also been historically deprecated on AIX (as an alias for1261// "vector int" in both 32-bit and 64-bit modes). It was then made1262// unsupported in the Clang-based XL compiler since the deprecated type1263// has a number of conflicting semantics and continuing to support it1264// is a disservice to users.1265if (S.getLangOpts().ZVector ||1266!S.Context.getTargetInfo().hasFeature("vsx") ||1267S.Context.getTargetInfo().getTriple().isOSAIX())1268S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_decl_spec);1269else1270S.Diag(TSWRange.getBegin(),1271diag::warn_vector_long_decl_spec_combination)1272<< getSpecifierName((TST)TypeSpecType, Policy);1273}12741275if (TypeAltiVecPixel) {1276//TODO: perform validation1277TypeSpecType = TST_int;1278TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unsigned);1279TypeSpecWidth = static_cast<unsigned>(TypeSpecifierWidth::Short);1280TypeSpecOwned = false;1281}1282}12831284bool IsFixedPointType =1285TypeSpecType == TST_accum || TypeSpecType == TST_fract;12861287// signed/unsigned are only valid with int/char/wchar_t/_Accum.1288if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) {1289if (TypeSpecType == TST_unspecified)1290TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.1291else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&1292TypeSpecType != TST_char && TypeSpecType != TST_wchar &&1293!IsFixedPointType && TypeSpecType != TST_bitint) {1294S.Diag(TSSLoc, diag::err_invalid_sign_spec)1295<< getSpecifierName((TST)TypeSpecType, Policy);1296// signed double -> double.1297TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unspecified);1298}1299}13001301// Validate the width of the type.1302switch (getTypeSpecWidth()) {1303case TypeSpecifierWidth::Unspecified:1304break;1305case TypeSpecifierWidth::Short: // short int1306case TypeSpecifierWidth::LongLong: // long long int1307if (TypeSpecType == TST_unspecified)1308TypeSpecType = TST_int; // short -> short int, long long -> long long int.1309else if (!(TypeSpecType == TST_int ||1310(IsFixedPointType &&1311getTypeSpecWidth() != TypeSpecifierWidth::LongLong))) {1312S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)1313<< (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);1314TypeSpecType = TST_int;1315TypeSpecSat = false;1316TypeSpecOwned = false;1317}1318break;1319case TypeSpecifierWidth::Long: // long double, long int1320if (TypeSpecType == TST_unspecified)1321TypeSpecType = TST_int; // long -> long int.1322else if (TypeSpecType != TST_int && TypeSpecType != TST_double &&1323!IsFixedPointType) {1324S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)1325<< (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);1326TypeSpecType = TST_int;1327TypeSpecSat = false;1328TypeSpecOwned = false;1329}1330break;1331}13321333// TODO: if the implementation does not implement _Complex, disallow their1334// use. Need information about the backend.1335if (TypeSpecComplex != TSC_unspecified) {1336if (TypeSpecType == TST_unspecified) {1337S.Diag(TSCLoc, diag::ext_plain_complex)1338<< FixItHint::CreateInsertion(1339S.getLocForEndOfToken(getTypeSpecComplexLoc()),1340" double");1341TypeSpecType = TST_double; // _Complex -> _Complex double.1342} else if (TypeSpecType == TST_int || TypeSpecType == TST_char ||1343TypeSpecType == TST_bitint) {1344// Note that this intentionally doesn't include _Complex _Bool.1345if (!S.getLangOpts().CPlusPlus)1346S.Diag(TSTLoc, diag::ext_integer_complex);1347} else if (TypeSpecType != TST_float && TypeSpecType != TST_double &&1348TypeSpecType != TST_float128 && TypeSpecType != TST_float16 &&1349TypeSpecType != TST_ibm128) {1350// FIXME: __fp16?1351S.Diag(TSCLoc, diag::err_invalid_complex_spec)1352<< getSpecifierName((TST)TypeSpecType, Policy);1353TypeSpecComplex = TSC_unspecified;1354}1355}13561357// C11 6.7.1/3, C++11 [dcl.stc]p1, GNU TLS: __thread, thread_local and1358// _Thread_local can only appear with the 'static' and 'extern' storage class1359// specifiers. We also allow __private_extern__ as an extension.1360if (ThreadStorageClassSpec != TSCS_unspecified) {1361switch (StorageClassSpec) {1362case SCS_unspecified:1363case SCS_extern:1364case SCS_private_extern:1365case SCS_static:1366break;1367default:1368if (S.getSourceManager().isBeforeInTranslationUnit(1369getThreadStorageClassSpecLoc(), getStorageClassSpecLoc()))1370S.Diag(getStorageClassSpecLoc(),1371diag::err_invalid_decl_spec_combination)1372<< DeclSpec::getSpecifierName(getThreadStorageClassSpec())1373<< SourceRange(getThreadStorageClassSpecLoc());1374else1375S.Diag(getThreadStorageClassSpecLoc(),1376diag::err_invalid_decl_spec_combination)1377<< DeclSpec::getSpecifierName(getStorageClassSpec())1378<< SourceRange(getStorageClassSpecLoc());1379// Discard the thread storage class specifier to recover.1380ThreadStorageClassSpec = TSCS_unspecified;1381ThreadStorageClassSpecLoc = SourceLocation();1382}1383if (S.getLangOpts().C23 &&1384getConstexprSpecifier() == ConstexprSpecKind::Constexpr) {1385S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination)1386<< DeclSpec::getSpecifierName(getThreadStorageClassSpec())1387<< SourceRange(getThreadStorageClassSpecLoc());1388}1389}13901391if (S.getLangOpts().C23 &&1392getConstexprSpecifier() == ConstexprSpecKind::Constexpr &&1393StorageClassSpec == SCS_extern) {1394S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination)1395<< DeclSpec::getSpecifierName(getStorageClassSpec())1396<< SourceRange(getStorageClassSpecLoc());1397}13981399// If no type specifier was provided and we're parsing a language where1400// the type specifier is not optional, but we got 'auto' as a storage1401// class specifier, then assume this is an attempt to use C++0x's 'auto'1402// type specifier.1403if (S.getLangOpts().CPlusPlus &&1404TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {1405TypeSpecType = TST_auto;1406StorageClassSpec = SCS_unspecified;1407TSTLoc = TSTNameLoc = StorageClassSpecLoc;1408StorageClassSpecLoc = SourceLocation();1409}1410// Diagnose if we've recovered from an ill-formed 'auto' storage class1411// specifier in a pre-C++11 dialect of C++ or in a pre-C23 dialect of C.1412if (!S.getLangOpts().CPlusPlus11 && !S.getLangOpts().C23 &&1413TypeSpecType == TST_auto)1414S.Diag(TSTLoc, diag::ext_auto_type_specifier);1415if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11 &&1416StorageClassSpec == SCS_auto)1417S.Diag(StorageClassSpecLoc, diag::warn_auto_storage_class)1418<< FixItHint::CreateRemoval(StorageClassSpecLoc);1419if (TypeSpecType == TST_char8)1420S.Diag(TSTLoc, diag::warn_cxx17_compat_unicode_type);1421else if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)1422S.Diag(TSTLoc, diag::warn_cxx98_compat_unicode_type)1423<< (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");1424if (getConstexprSpecifier() == ConstexprSpecKind::Constexpr)1425S.Diag(ConstexprLoc, diag::warn_cxx98_compat_constexpr);1426else if (getConstexprSpecifier() == ConstexprSpecKind::Consteval)1427S.Diag(ConstexprLoc, diag::warn_cxx20_compat_consteval);1428else if (getConstexprSpecifier() == ConstexprSpecKind::Constinit)1429S.Diag(ConstexprLoc, diag::warn_cxx20_compat_constinit);1430// C++ [class.friend]p6:1431// No storage-class-specifier shall appear in the decl-specifier-seq1432// of a friend declaration.1433if (isFriendSpecified() &&1434(getStorageClassSpec() || getThreadStorageClassSpec())) {1435SmallString<32> SpecName;1436SourceLocation SCLoc;1437FixItHint StorageHint, ThreadHint;14381439if (DeclSpec::SCS SC = getStorageClassSpec()) {1440SpecName = getSpecifierName(SC);1441SCLoc = getStorageClassSpecLoc();1442StorageHint = FixItHint::CreateRemoval(SCLoc);1443}14441445if (DeclSpec::TSCS TSC = getThreadStorageClassSpec()) {1446if (!SpecName.empty()) SpecName += " ";1447SpecName += getSpecifierName(TSC);1448SCLoc = getThreadStorageClassSpecLoc();1449ThreadHint = FixItHint::CreateRemoval(SCLoc);1450}14511452S.Diag(SCLoc, diag::err_friend_decl_spec)1453<< SpecName << StorageHint << ThreadHint;14541455ClearStorageClassSpecs();1456}14571458// C++11 [dcl.fct.spec]p5:1459// The virtual specifier shall be used only in the initial1460// declaration of a non-static class member function;1461// C++11 [dcl.fct.spec]p6:1462// The explicit specifier shall be used only in the declaration of1463// a constructor or conversion function within its class1464// definition;1465if (isFriendSpecified() && (isVirtualSpecified() || hasExplicitSpecifier())) {1466StringRef Keyword;1467FixItHint Hint;1468SourceLocation SCLoc;14691470if (isVirtualSpecified()) {1471Keyword = "virtual";1472SCLoc = getVirtualSpecLoc();1473Hint = FixItHint::CreateRemoval(SCLoc);1474} else {1475Keyword = "explicit";1476SCLoc = getExplicitSpecLoc();1477Hint = FixItHint::CreateRemoval(getExplicitSpecRange());1478}14791480S.Diag(SCLoc, diag::err_friend_decl_spec)1481<< Keyword << Hint;14821483FS_virtual_specified = false;1484FS_explicit_specifier = ExplicitSpecifier();1485FS_virtualLoc = FS_explicitLoc = SourceLocation();1486}14871488assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));14891490// Okay, now we can infer the real type.14911492// TODO: return "auto function" and other bad things based on the real type.14931494// 'data definition has no type or storage class'?1495}14961497bool DeclSpec::isMissingDeclaratorOk() {1498TST tst = getTypeSpecType();1499return isDeclRep(tst) && getRepAsDecl() != nullptr &&1500StorageClassSpec != DeclSpec::SCS_typedef;1501}15021503void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,1504OverloadedOperatorKind Op,1505SourceLocation SymbolLocations[3]) {1506Kind = UnqualifiedIdKind::IK_OperatorFunctionId;1507StartLocation = OperatorLoc;1508EndLocation = OperatorLoc;1509new (&OperatorFunctionId) struct OFI;1510OperatorFunctionId.Operator = Op;1511for (unsigned I = 0; I != 3; ++I) {1512OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I];15131514if (SymbolLocations[I].isValid())1515EndLocation = SymbolLocations[I];1516}1517}15181519bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,1520const char *&PrevSpec) {1521if (!FirstLocation.isValid())1522FirstLocation = Loc;1523LastLocation = Loc;1524LastSpecifier = VS;15251526if (Specifiers & VS) {1527PrevSpec = getSpecifierName(VS);1528return true;1529}15301531Specifiers |= VS;15321533switch (VS) {1534default: llvm_unreachable("Unknown specifier!");1535case VS_Override: VS_overrideLoc = Loc; break;1536case VS_GNU_Final:1537case VS_Sealed:1538case VS_Final: VS_finalLoc = Loc; break;1539case VS_Abstract: VS_abstractLoc = Loc; break;1540}15411542return false;1543}15441545const char *VirtSpecifiers::getSpecifierName(Specifier VS) {1546switch (VS) {1547default: llvm_unreachable("Unknown specifier");1548case VS_Override: return "override";1549case VS_Final: return "final";1550case VS_GNU_Final: return "__final";1551case VS_Sealed: return "sealed";1552case VS_Abstract: return "abstract";1553}1554}155515561557