10b57cec5SDimitry Andric //===--- DeclSpec.cpp - Declaration Specifier Semantic Analysis -----------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements semantic analysis for declaration specifiers. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h" 140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 150b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 160b57cec5SDimitry Andric #include "clang/AST/Expr.h" 170b57cec5SDimitry Andric #include "clang/AST/LocInfoType.h" 180b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h" 190b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h" 205ffd83dbSDimitry Andric #include "clang/Basic/SourceManager.h" 21bdd1243dSDimitry Andric #include "clang/Basic/Specifiers.h" 220b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 230b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h" 240b57cec5SDimitry Andric #include "clang/Sema/Sema.h" 250b57cec5SDimitry Andric #include "clang/Sema/SemaDiagnostic.h" 260b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 270b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 280b57cec5SDimitry Andric #include <cstring> 290b57cec5SDimitry Andric using namespace clang; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { 330b57cec5SDimitry Andric assert(TemplateId && "NULL template-id annotation?"); 345ffd83dbSDimitry Andric assert(!TemplateId->isInvalid() && 355ffd83dbSDimitry Andric "should not convert invalid template-ids to unqualified-ids"); 365ffd83dbSDimitry Andric 370b57cec5SDimitry Andric Kind = UnqualifiedIdKind::IK_TemplateId; 380b57cec5SDimitry Andric this->TemplateId = TemplateId; 390b57cec5SDimitry Andric StartLocation = TemplateId->TemplateNameLoc; 400b57cec5SDimitry Andric EndLocation = TemplateId->RAngleLoc; 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { 440b57cec5SDimitry Andric assert(TemplateId && "NULL template-id annotation?"); 455ffd83dbSDimitry Andric assert(!TemplateId->isInvalid() && 465ffd83dbSDimitry Andric "should not convert invalid template-ids to unqualified-ids"); 475ffd83dbSDimitry Andric 480b57cec5SDimitry Andric Kind = UnqualifiedIdKind::IK_ConstructorTemplateId; 490b57cec5SDimitry Andric this->TemplateId = TemplateId; 500b57cec5SDimitry Andric StartLocation = TemplateId->TemplateNameLoc; 510b57cec5SDimitry Andric EndLocation = TemplateId->RAngleLoc; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc, 550b57cec5SDimitry Andric TypeLoc TL, SourceLocation ColonColonLoc) { 560b57cec5SDimitry Andric Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc); 570b57cec5SDimitry Andric if (Range.getBegin().isInvalid()) 580b57cec5SDimitry Andric Range.setBegin(TL.getBeginLoc()); 590b57cec5SDimitry Andric Range.setEnd(ColonColonLoc); 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric assert(Range == Builder.getSourceRange() && 620b57cec5SDimitry Andric "NestedNameSpecifierLoc range computation incorrect"); 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier, 660b57cec5SDimitry Andric SourceLocation IdentifierLoc, 670b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 680b57cec5SDimitry Andric Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric if (Range.getBegin().isInvalid()) 710b57cec5SDimitry Andric Range.setBegin(IdentifierLoc); 720b57cec5SDimitry Andric Range.setEnd(ColonColonLoc); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric assert(Range == Builder.getSourceRange() && 750b57cec5SDimitry Andric "NestedNameSpecifierLoc range computation incorrect"); 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace, 790b57cec5SDimitry Andric SourceLocation NamespaceLoc, 800b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 810b57cec5SDimitry Andric Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc); 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric if (Range.getBegin().isInvalid()) 840b57cec5SDimitry Andric Range.setBegin(NamespaceLoc); 850b57cec5SDimitry Andric Range.setEnd(ColonColonLoc); 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric assert(Range == Builder.getSourceRange() && 880b57cec5SDimitry Andric "NestedNameSpecifierLoc range computation incorrect"); 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 920b57cec5SDimitry Andric SourceLocation AliasLoc, 930b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 940b57cec5SDimitry Andric Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc); 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric if (Range.getBegin().isInvalid()) 970b57cec5SDimitry Andric Range.setBegin(AliasLoc); 980b57cec5SDimitry Andric Range.setEnd(ColonColonLoc); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric assert(Range == Builder.getSourceRange() && 1010b57cec5SDimitry Andric "NestedNameSpecifierLoc range computation incorrect"); 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric void CXXScopeSpec::MakeGlobal(ASTContext &Context, 1050b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 1060b57cec5SDimitry Andric Builder.MakeGlobal(Context, ColonColonLoc); 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric Range = SourceRange(ColonColonLoc); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric assert(Range == Builder.getSourceRange() && 1110b57cec5SDimitry Andric "NestedNameSpecifierLoc range computation incorrect"); 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric void CXXScopeSpec::MakeSuper(ASTContext &Context, CXXRecordDecl *RD, 1150b57cec5SDimitry Andric SourceLocation SuperLoc, 1160b57cec5SDimitry Andric SourceLocation ColonColonLoc) { 1170b57cec5SDimitry Andric Builder.MakeSuper(Context, RD, SuperLoc, ColonColonLoc); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric Range.setBegin(SuperLoc); 1200b57cec5SDimitry Andric Range.setEnd(ColonColonLoc); 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric assert(Range == Builder.getSourceRange() && 1230b57cec5SDimitry Andric "NestedNameSpecifierLoc range computation incorrect"); 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric void CXXScopeSpec::MakeTrivial(ASTContext &Context, 1270b57cec5SDimitry Andric NestedNameSpecifier *Qualifier, SourceRange R) { 1280b57cec5SDimitry Andric Builder.MakeTrivial(Context, Qualifier, R); 1290b57cec5SDimitry Andric Range = R; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) { 1330b57cec5SDimitry Andric if (!Other) { 1340b57cec5SDimitry Andric Range = SourceRange(); 1350b57cec5SDimitry Andric Builder.Clear(); 1360b57cec5SDimitry Andric return; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric Range = Other.getSourceRange(); 1400b57cec5SDimitry Andric Builder.Adopt(Other); 1415ffd83dbSDimitry Andric assert(Range == Builder.getSourceRange() && 1425ffd83dbSDimitry Andric "NestedNameSpecifierLoc range computation incorrect"); 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const { 1460b57cec5SDimitry Andric if (!Builder.getRepresentation()) 1470b57cec5SDimitry Andric return SourceLocation(); 1480b57cec5SDimitry Andric return Builder.getTemporary().getLocalBeginLoc(); 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric NestedNameSpecifierLoc 1520b57cec5SDimitry Andric CXXScopeSpec::getWithLocInContext(ASTContext &Context) const { 1530b57cec5SDimitry Andric if (!Builder.getRepresentation()) 1540b57cec5SDimitry Andric return NestedNameSpecifierLoc(); 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric return Builder.getWithLocInContext(Context); 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. 1600b57cec5SDimitry Andric /// "TheDeclarator" is the declarator that this will be added to. 1610b57cec5SDimitry Andric DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, 1620b57cec5SDimitry Andric bool isAmbiguous, 1630b57cec5SDimitry Andric SourceLocation LParenLoc, 1640b57cec5SDimitry Andric ParamInfo *Params, 1650b57cec5SDimitry Andric unsigned NumParams, 1660b57cec5SDimitry Andric SourceLocation EllipsisLoc, 1670b57cec5SDimitry Andric SourceLocation RParenLoc, 1680b57cec5SDimitry Andric bool RefQualifierIsLvalueRef, 1690b57cec5SDimitry Andric SourceLocation RefQualifierLoc, 1700b57cec5SDimitry Andric SourceLocation MutableLoc, 1710b57cec5SDimitry Andric ExceptionSpecificationType 1720b57cec5SDimitry Andric ESpecType, 1730b57cec5SDimitry Andric SourceRange ESpecRange, 1740b57cec5SDimitry Andric ParsedType *Exceptions, 1750b57cec5SDimitry Andric SourceRange *ExceptionRanges, 1760b57cec5SDimitry Andric unsigned NumExceptions, 1770b57cec5SDimitry Andric Expr *NoexceptExpr, 1780b57cec5SDimitry Andric CachedTokens *ExceptionSpecTokens, 1790b57cec5SDimitry Andric ArrayRef<NamedDecl*> 1800b57cec5SDimitry Andric DeclsInPrototype, 1810b57cec5SDimitry Andric SourceLocation LocalRangeBegin, 1820b57cec5SDimitry Andric SourceLocation LocalRangeEnd, 1830b57cec5SDimitry Andric Declarator &TheDeclarator, 1840b57cec5SDimitry Andric TypeResult TrailingReturnType, 185e8d8bef9SDimitry Andric SourceLocation 186e8d8bef9SDimitry Andric TrailingReturnTypeLoc, 1870b57cec5SDimitry Andric DeclSpec *MethodQualifiers) { 1880b57cec5SDimitry Andric assert(!(MethodQualifiers && MethodQualifiers->getTypeQualifiers() & DeclSpec::TQ_atomic) && 1890b57cec5SDimitry Andric "function cannot have _Atomic qualifier"); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric DeclaratorChunk I; 1920b57cec5SDimitry Andric I.Kind = Function; 1930b57cec5SDimitry Andric I.Loc = LocalRangeBegin; 1940b57cec5SDimitry Andric I.EndLoc = LocalRangeEnd; 195e8d8bef9SDimitry Andric new (&I.Fun) FunctionTypeInfo; 1960b57cec5SDimitry Andric I.Fun.hasPrototype = hasProto; 1970b57cec5SDimitry Andric I.Fun.isVariadic = EllipsisLoc.isValid(); 1980b57cec5SDimitry Andric I.Fun.isAmbiguous = isAmbiguous; 199e8d8bef9SDimitry Andric I.Fun.LParenLoc = LParenLoc; 200e8d8bef9SDimitry Andric I.Fun.EllipsisLoc = EllipsisLoc; 201e8d8bef9SDimitry Andric I.Fun.RParenLoc = RParenLoc; 2020b57cec5SDimitry Andric I.Fun.DeleteParams = false; 2030b57cec5SDimitry Andric I.Fun.NumParams = NumParams; 2040b57cec5SDimitry Andric I.Fun.Params = nullptr; 2050b57cec5SDimitry Andric I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; 206e8d8bef9SDimitry Andric I.Fun.RefQualifierLoc = RefQualifierLoc; 207e8d8bef9SDimitry Andric I.Fun.MutableLoc = MutableLoc; 2080b57cec5SDimitry Andric I.Fun.ExceptionSpecType = ESpecType; 209e8d8bef9SDimitry Andric I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin(); 210e8d8bef9SDimitry Andric I.Fun.ExceptionSpecLocEnd = ESpecRange.getEnd(); 2110b57cec5SDimitry Andric I.Fun.NumExceptionsOrDecls = 0; 2120b57cec5SDimitry Andric I.Fun.Exceptions = nullptr; 2130b57cec5SDimitry Andric I.Fun.NoexceptExpr = nullptr; 2140b57cec5SDimitry Andric I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() || 2150b57cec5SDimitry Andric TrailingReturnType.isInvalid(); 2160b57cec5SDimitry Andric I.Fun.TrailingReturnType = TrailingReturnType.get(); 217e8d8bef9SDimitry Andric I.Fun.TrailingReturnTypeLoc = TrailingReturnTypeLoc; 2180b57cec5SDimitry Andric I.Fun.MethodQualifiers = nullptr; 2190b57cec5SDimitry Andric I.Fun.QualAttrFactory = nullptr; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric if (MethodQualifiers && (MethodQualifiers->getTypeQualifiers() || 2220b57cec5SDimitry Andric MethodQualifiers->getAttributes().size())) { 2230b57cec5SDimitry Andric auto &attrs = MethodQualifiers->getAttributes(); 2240b57cec5SDimitry Andric I.Fun.MethodQualifiers = new DeclSpec(attrs.getPool().getFactory()); 2250b57cec5SDimitry Andric MethodQualifiers->forEachCVRUQualifier( 2260b57cec5SDimitry Andric [&](DeclSpec::TQ TypeQual, StringRef PrintName, SourceLocation SL) { 2270b57cec5SDimitry Andric I.Fun.MethodQualifiers->SetTypeQual(TypeQual, SL); 2280b57cec5SDimitry Andric }); 2290b57cec5SDimitry Andric I.Fun.MethodQualifiers->getAttributes().takeAllFrom(attrs); 2300b57cec5SDimitry Andric I.Fun.MethodQualifiers->getAttributePool().takeAllFrom(attrs.getPool()); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow"); 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric // new[] a parameter array if needed. 2360b57cec5SDimitry Andric if (NumParams) { 2370b57cec5SDimitry Andric // If the 'InlineParams' in Declarator is unused and big enough, put our 2380b57cec5SDimitry Andric // parameter list there (in an effort to avoid new/delete traffic). If it 2390b57cec5SDimitry Andric // is already used (consider a function returning a function pointer) or too 2400b57cec5SDimitry Andric // small (function with too many parameters), go to the heap. 2410b57cec5SDimitry Andric if (!TheDeclarator.InlineStorageUsed && 242bdd1243dSDimitry Andric NumParams <= std::size(TheDeclarator.InlineParams)) { 2430b57cec5SDimitry Andric I.Fun.Params = TheDeclarator.InlineParams; 2440b57cec5SDimitry Andric new (I.Fun.Params) ParamInfo[NumParams]; 2450b57cec5SDimitry Andric I.Fun.DeleteParams = false; 2460b57cec5SDimitry Andric TheDeclarator.InlineStorageUsed = true; 2470b57cec5SDimitry Andric } else { 2480b57cec5SDimitry Andric I.Fun.Params = new DeclaratorChunk::ParamInfo[NumParams]; 2490b57cec5SDimitry Andric I.Fun.DeleteParams = true; 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric for (unsigned i = 0; i < NumParams; i++) 2520b57cec5SDimitry Andric I.Fun.Params[i] = std::move(Params[i]); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric // Check what exception specification information we should actually store. 2560b57cec5SDimitry Andric switch (ESpecType) { 2570b57cec5SDimitry Andric default: break; // By default, save nothing. 2580b57cec5SDimitry Andric case EST_Dynamic: 2590b57cec5SDimitry Andric // new[] an exception array if needed 2600b57cec5SDimitry Andric if (NumExceptions) { 2610b57cec5SDimitry Andric I.Fun.NumExceptionsOrDecls = NumExceptions; 2620b57cec5SDimitry Andric I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions]; 2630b57cec5SDimitry Andric for (unsigned i = 0; i != NumExceptions; ++i) { 2640b57cec5SDimitry Andric I.Fun.Exceptions[i].Ty = Exceptions[i]; 2650b57cec5SDimitry Andric I.Fun.Exceptions[i].Range = ExceptionRanges[i]; 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric break; 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric case EST_DependentNoexcept: 2710b57cec5SDimitry Andric case EST_NoexceptFalse: 2720b57cec5SDimitry Andric case EST_NoexceptTrue: 2730b57cec5SDimitry Andric I.Fun.NoexceptExpr = NoexceptExpr; 2740b57cec5SDimitry Andric break; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric case EST_Unparsed: 2770b57cec5SDimitry Andric I.Fun.ExceptionSpecTokens = ExceptionSpecTokens; 2780b57cec5SDimitry Andric break; 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric if (!DeclsInPrototype.empty()) { 2820b57cec5SDimitry Andric assert(ESpecType == EST_None && NumExceptions == 0 && 2830b57cec5SDimitry Andric "cannot have exception specifiers and decls in prototype"); 2840b57cec5SDimitry Andric I.Fun.NumExceptionsOrDecls = DeclsInPrototype.size(); 2850b57cec5SDimitry Andric // Copy the array of decls into stable heap storage. 2860b57cec5SDimitry Andric I.Fun.DeclsInPrototype = new NamedDecl *[DeclsInPrototype.size()]; 2870b57cec5SDimitry Andric for (size_t J = 0; J < DeclsInPrototype.size(); ++J) 2880b57cec5SDimitry Andric I.Fun.DeclsInPrototype[J] = DeclsInPrototype[J]; 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric return I; 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric void Declarator::setDecompositionBindings( 2950b57cec5SDimitry Andric SourceLocation LSquareLoc, 296*0fca6ea1SDimitry Andric MutableArrayRef<DecompositionDeclarator::Binding> Bindings, 2970b57cec5SDimitry Andric SourceLocation RSquareLoc) { 2980b57cec5SDimitry Andric assert(!hasName() && "declarator given multiple names!"); 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric BindingGroup.LSquareLoc = LSquareLoc; 3010b57cec5SDimitry Andric BindingGroup.RSquareLoc = RSquareLoc; 3020b57cec5SDimitry Andric BindingGroup.NumBindings = Bindings.size(); 3030b57cec5SDimitry Andric Range.setEnd(RSquareLoc); 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric // We're now past the identifier. 3060b57cec5SDimitry Andric SetIdentifier(nullptr, LSquareLoc); 3070b57cec5SDimitry Andric Name.EndLocation = RSquareLoc; 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric // Allocate storage for bindings and stash them away. 3100b57cec5SDimitry Andric if (Bindings.size()) { 311bdd1243dSDimitry Andric if (!InlineStorageUsed && Bindings.size() <= std::size(InlineBindings)) { 3120b57cec5SDimitry Andric BindingGroup.Bindings = InlineBindings; 3130b57cec5SDimitry Andric BindingGroup.DeleteBindings = false; 3140b57cec5SDimitry Andric InlineStorageUsed = true; 3150b57cec5SDimitry Andric } else { 3160b57cec5SDimitry Andric BindingGroup.Bindings = 3170b57cec5SDimitry Andric new DecompositionDeclarator::Binding[Bindings.size()]; 3180b57cec5SDimitry Andric BindingGroup.DeleteBindings = true; 3190b57cec5SDimitry Andric } 320*0fca6ea1SDimitry Andric std::uninitialized_move(Bindings.begin(), Bindings.end(), 3210b57cec5SDimitry Andric BindingGroup.Bindings); 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric bool Declarator::isDeclarationOfFunction() const { 3260b57cec5SDimitry Andric for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { 3270b57cec5SDimitry Andric switch (DeclTypeInfo[i].Kind) { 3280b57cec5SDimitry Andric case DeclaratorChunk::Function: 3290b57cec5SDimitry Andric return true; 3300b57cec5SDimitry Andric case DeclaratorChunk::Paren: 3310b57cec5SDimitry Andric continue; 3320b57cec5SDimitry Andric case DeclaratorChunk::Pointer: 3330b57cec5SDimitry Andric case DeclaratorChunk::Reference: 3340b57cec5SDimitry Andric case DeclaratorChunk::Array: 3350b57cec5SDimitry Andric case DeclaratorChunk::BlockPointer: 3360b57cec5SDimitry Andric case DeclaratorChunk::MemberPointer: 3370b57cec5SDimitry Andric case DeclaratorChunk::Pipe: 3380b57cec5SDimitry Andric return false; 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric llvm_unreachable("Invalid type chunk"); 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric switch (DS.getTypeSpecType()) { 3440b57cec5SDimitry Andric case TST_atomic: 3450b57cec5SDimitry Andric case TST_auto: 3460b57cec5SDimitry Andric case TST_auto_type: 3470b57cec5SDimitry Andric case TST_bool: 3480b57cec5SDimitry Andric case TST_char: 3490b57cec5SDimitry Andric case TST_char8: 3500b57cec5SDimitry Andric case TST_char16: 3510b57cec5SDimitry Andric case TST_char32: 3520b57cec5SDimitry Andric case TST_class: 3530b57cec5SDimitry Andric case TST_decimal128: 3540b57cec5SDimitry Andric case TST_decimal32: 3550b57cec5SDimitry Andric case TST_decimal64: 3560b57cec5SDimitry Andric case TST_double: 3570b57cec5SDimitry Andric case TST_Accum: 3580b57cec5SDimitry Andric case TST_Fract: 3590b57cec5SDimitry Andric case TST_Float16: 3600b57cec5SDimitry Andric case TST_float128: 361349cc55cSDimitry Andric case TST_ibm128: 3620b57cec5SDimitry Andric case TST_enum: 3630b57cec5SDimitry Andric case TST_error: 3640b57cec5SDimitry Andric case TST_float: 3650b57cec5SDimitry Andric case TST_half: 3660b57cec5SDimitry Andric case TST_int: 3670b57cec5SDimitry Andric case TST_int128: 3680eae32dcSDimitry Andric case TST_bitint: 3690b57cec5SDimitry Andric case TST_struct: 3700b57cec5SDimitry Andric case TST_interface: 3710b57cec5SDimitry Andric case TST_union: 3720b57cec5SDimitry Andric case TST_unknown_anytype: 3730b57cec5SDimitry Andric case TST_unspecified: 3740b57cec5SDimitry Andric case TST_void: 3750b57cec5SDimitry Andric case TST_wchar: 3765ffd83dbSDimitry Andric case TST_BFloat16: 377*0fca6ea1SDimitry Andric case TST_typename_pack_indexing: 3780b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: 3790b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 3800b57cec5SDimitry Andric return false; 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric case TST_decltype_auto: 3830b57cec5SDimitry Andric // This must have an initializer, so can't be a function declaration, 3840b57cec5SDimitry Andric // even if the initializer has function type. 3850b57cec5SDimitry Andric return false; 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric case TST_decltype: 388bdd1243dSDimitry Andric case TST_typeof_unqualExpr: 3890b57cec5SDimitry Andric case TST_typeofExpr: 3900b57cec5SDimitry Andric if (Expr *E = DS.getRepAsExpr()) 3910b57cec5SDimitry Andric return E->getType()->isFunctionType(); 3920b57cec5SDimitry Andric return false; 3930b57cec5SDimitry Andric 394bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: 395bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 3960b57cec5SDimitry Andric case TST_typename: 397bdd1243dSDimitry Andric case TST_typeof_unqualType: 3980b57cec5SDimitry Andric case TST_typeofType: { 3990b57cec5SDimitry Andric QualType QT = DS.getRepAsType().get(); 4000b57cec5SDimitry Andric if (QT.isNull()) 4010b57cec5SDimitry Andric return false; 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) 4040b57cec5SDimitry Andric QT = LIT->getType(); 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric if (QT.isNull()) 4070b57cec5SDimitry Andric return false; 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric return QT->isFunctionType(); 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric llvm_unreachable("Invalid TypeSpecType!"); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric bool Declarator::isStaticMember() { 417e8d8bef9SDimitry Andric assert(getContext() == DeclaratorContext::Member); 4180b57cec5SDimitry Andric return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || 419*0fca6ea1SDimitry Andric (!isDeclarationOfFunction() && !getTemplateParameterLists().empty()) || 420bdd1243dSDimitry Andric (getName().getKind() == UnqualifiedIdKind::IK_OperatorFunctionId && 4210b57cec5SDimitry Andric CXXMethodDecl::isStaticOverloadedOperator( 4220b57cec5SDimitry Andric getName().OperatorFunctionId.Operator)); 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric 4255f757f3fSDimitry Andric bool Declarator::isExplicitObjectMemberFunction() { 4265f757f3fSDimitry Andric if (!isFunctionDeclarator()) 4275f757f3fSDimitry Andric return false; 4285f757f3fSDimitry Andric DeclaratorChunk::FunctionTypeInfo &Fun = getFunctionTypeInfo(); 4295f757f3fSDimitry Andric if (Fun.NumParams) { 4305f757f3fSDimitry Andric auto *P = dyn_cast_or_null<ParmVarDecl>(Fun.Params[0].Param); 4315f757f3fSDimitry Andric if (P && P->isExplicitObjectParameter()) 4325f757f3fSDimitry Andric return true; 4335f757f3fSDimitry Andric } 4345f757f3fSDimitry Andric return false; 4355f757f3fSDimitry Andric } 4365f757f3fSDimitry Andric 4370b57cec5SDimitry Andric bool Declarator::isCtorOrDtor() { 4380b57cec5SDimitry Andric return (getName().getKind() == UnqualifiedIdKind::IK_ConstructorName) || 4390b57cec5SDimitry Andric (getName().getKind() == UnqualifiedIdKind::IK_DestructorName); 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric void DeclSpec::forEachCVRUQualifier( 4430b57cec5SDimitry Andric llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) { 4440b57cec5SDimitry Andric if (TypeQualifiers & TQ_const) 4450b57cec5SDimitry Andric Handle(TQ_const, "const", TQ_constLoc); 4460b57cec5SDimitry Andric if (TypeQualifiers & TQ_volatile) 4470b57cec5SDimitry Andric Handle(TQ_volatile, "volatile", TQ_volatileLoc); 4480b57cec5SDimitry Andric if (TypeQualifiers & TQ_restrict) 4490b57cec5SDimitry Andric Handle(TQ_restrict, "restrict", TQ_restrictLoc); 4500b57cec5SDimitry Andric if (TypeQualifiers & TQ_unaligned) 4510b57cec5SDimitry Andric Handle(TQ_unaligned, "unaligned", TQ_unalignedLoc); 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric void DeclSpec::forEachQualifier( 4550b57cec5SDimitry Andric llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) { 4560b57cec5SDimitry Andric forEachCVRUQualifier(Handle); 4570b57cec5SDimitry Andric // FIXME: Add code below to iterate through the attributes and call Handle. 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric bool DeclSpec::hasTagDefinition() const { 4610b57cec5SDimitry Andric if (!TypeSpecOwned) 4620b57cec5SDimitry Andric return false; 4630b57cec5SDimitry Andric return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition(); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this 4670b57cec5SDimitry Andric /// declaration specifier includes. 4680b57cec5SDimitry Andric /// 4690b57cec5SDimitry Andric unsigned DeclSpec::getParsedSpecifiers() const { 4700b57cec5SDimitry Andric unsigned Res = 0; 4710b57cec5SDimitry Andric if (StorageClassSpec != SCS_unspecified || 4720b57cec5SDimitry Andric ThreadStorageClassSpec != TSCS_unspecified) 4730b57cec5SDimitry Andric Res |= PQ_StorageClassSpecifier; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric if (TypeQualifiers != TQ_unspecified) 4760b57cec5SDimitry Andric Res |= PQ_TypeQualifier; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric if (hasTypeSpecifier()) 4790b57cec5SDimitry Andric Res |= PQ_TypeSpecifier; 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric if (FS_inline_specified || FS_virtual_specified || hasExplicitSpecifier() || 4820b57cec5SDimitry Andric FS_noreturn_specified || FS_forceinline_specified) 4830b57cec5SDimitry Andric Res |= PQ_FunctionSpecifier; 4840b57cec5SDimitry Andric return Res; 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric template <class T> static bool BadSpecifier(T TNew, T TPrev, 4880b57cec5SDimitry Andric const char *&PrevSpec, 4890b57cec5SDimitry Andric unsigned &DiagID, 4900b57cec5SDimitry Andric bool IsExtension = true) { 4910b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName(TPrev); 4920b57cec5SDimitry Andric if (TNew != TPrev) 4930b57cec5SDimitry Andric DiagID = diag::err_invalid_decl_spec_combination; 4940b57cec5SDimitry Andric else 4950b57cec5SDimitry Andric DiagID = IsExtension ? diag::ext_warn_duplicate_declspec : 4960b57cec5SDimitry Andric diag::warn_duplicate_declspec; 4970b57cec5SDimitry Andric return true; 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) { 5010b57cec5SDimitry Andric switch (S) { 5020b57cec5SDimitry Andric case DeclSpec::SCS_unspecified: return "unspecified"; 5030b57cec5SDimitry Andric case DeclSpec::SCS_typedef: return "typedef"; 5040b57cec5SDimitry Andric case DeclSpec::SCS_extern: return "extern"; 5050b57cec5SDimitry Andric case DeclSpec::SCS_static: return "static"; 5060b57cec5SDimitry Andric case DeclSpec::SCS_auto: return "auto"; 5070b57cec5SDimitry Andric case DeclSpec::SCS_register: return "register"; 5080b57cec5SDimitry Andric case DeclSpec::SCS_private_extern: return "__private_extern__"; 5090b57cec5SDimitry Andric case DeclSpec::SCS_mutable: return "mutable"; 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric llvm_unreachable("Unknown typespec!"); 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric const char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) { 5150b57cec5SDimitry Andric switch (S) { 5160b57cec5SDimitry Andric case DeclSpec::TSCS_unspecified: return "unspecified"; 5170b57cec5SDimitry Andric case DeclSpec::TSCS___thread: return "__thread"; 5180b57cec5SDimitry Andric case DeclSpec::TSCS_thread_local: return "thread_local"; 5190b57cec5SDimitry Andric case DeclSpec::TSCS__Thread_local: return "_Thread_local"; 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric llvm_unreachable("Unknown typespec!"); 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric 524e8d8bef9SDimitry Andric const char *DeclSpec::getSpecifierName(TypeSpecifierWidth W) { 5250b57cec5SDimitry Andric switch (W) { 526e8d8bef9SDimitry Andric case TypeSpecifierWidth::Unspecified: 527e8d8bef9SDimitry Andric return "unspecified"; 528e8d8bef9SDimitry Andric case TypeSpecifierWidth::Short: 529e8d8bef9SDimitry Andric return "short"; 530e8d8bef9SDimitry Andric case TypeSpecifierWidth::Long: 531e8d8bef9SDimitry Andric return "long"; 532e8d8bef9SDimitry Andric case TypeSpecifierWidth::LongLong: 533e8d8bef9SDimitry Andric return "long long"; 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric llvm_unreachable("Unknown typespec!"); 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric const char *DeclSpec::getSpecifierName(TSC C) { 5390b57cec5SDimitry Andric switch (C) { 5400b57cec5SDimitry Andric case TSC_unspecified: return "unspecified"; 5410b57cec5SDimitry Andric case TSC_imaginary: return "imaginary"; 5420b57cec5SDimitry Andric case TSC_complex: return "complex"; 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric llvm_unreachable("Unknown typespec!"); 5450b57cec5SDimitry Andric } 5460b57cec5SDimitry Andric 547e8d8bef9SDimitry Andric const char *DeclSpec::getSpecifierName(TypeSpecifierSign S) { 5480b57cec5SDimitry Andric switch (S) { 549e8d8bef9SDimitry Andric case TypeSpecifierSign::Unspecified: 550e8d8bef9SDimitry Andric return "unspecified"; 551e8d8bef9SDimitry Andric case TypeSpecifierSign::Signed: 552e8d8bef9SDimitry Andric return "signed"; 553e8d8bef9SDimitry Andric case TypeSpecifierSign::Unsigned: 554e8d8bef9SDimitry Andric return "unsigned"; 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric llvm_unreachable("Unknown typespec!"); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric const char *DeclSpec::getSpecifierName(DeclSpec::TST T, 5600b57cec5SDimitry Andric const PrintingPolicy &Policy) { 5610b57cec5SDimitry Andric switch (T) { 5620b57cec5SDimitry Andric case DeclSpec::TST_unspecified: return "unspecified"; 5630b57cec5SDimitry Andric case DeclSpec::TST_void: return "void"; 5640b57cec5SDimitry Andric case DeclSpec::TST_char: return "char"; 5650b57cec5SDimitry Andric case DeclSpec::TST_wchar: return Policy.MSWChar ? "__wchar_t" : "wchar_t"; 5660b57cec5SDimitry Andric case DeclSpec::TST_char8: return "char8_t"; 5670b57cec5SDimitry Andric case DeclSpec::TST_char16: return "char16_t"; 5680b57cec5SDimitry Andric case DeclSpec::TST_char32: return "char32_t"; 5690b57cec5SDimitry Andric case DeclSpec::TST_int: return "int"; 5700b57cec5SDimitry Andric case DeclSpec::TST_int128: return "__int128"; 5710eae32dcSDimitry Andric case DeclSpec::TST_bitint: return "_BitInt"; 5720b57cec5SDimitry Andric case DeclSpec::TST_half: return "half"; 5730b57cec5SDimitry Andric case DeclSpec::TST_float: return "float"; 5740b57cec5SDimitry Andric case DeclSpec::TST_double: return "double"; 5750b57cec5SDimitry Andric case DeclSpec::TST_accum: return "_Accum"; 5760b57cec5SDimitry Andric case DeclSpec::TST_fract: return "_Fract"; 5770b57cec5SDimitry Andric case DeclSpec::TST_float16: return "_Float16"; 5780b57cec5SDimitry Andric case DeclSpec::TST_float128: return "__float128"; 579349cc55cSDimitry Andric case DeclSpec::TST_ibm128: return "__ibm128"; 5800b57cec5SDimitry Andric case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool"; 5810b57cec5SDimitry Andric case DeclSpec::TST_decimal32: return "_Decimal32"; 5820b57cec5SDimitry Andric case DeclSpec::TST_decimal64: return "_Decimal64"; 5830b57cec5SDimitry Andric case DeclSpec::TST_decimal128: return "_Decimal128"; 5840b57cec5SDimitry Andric case DeclSpec::TST_enum: return "enum"; 5850b57cec5SDimitry Andric case DeclSpec::TST_class: return "class"; 5860b57cec5SDimitry Andric case DeclSpec::TST_union: return "union"; 5870b57cec5SDimitry Andric case DeclSpec::TST_struct: return "struct"; 5880b57cec5SDimitry Andric case DeclSpec::TST_interface: return "__interface"; 5890b57cec5SDimitry Andric case DeclSpec::TST_typename: return "type-name"; 590*0fca6ea1SDimitry Andric case DeclSpec::TST_typename_pack_indexing: 591*0fca6ea1SDimitry Andric return "type-name-pack-indexing"; 5920b57cec5SDimitry Andric case DeclSpec::TST_typeofType: 5930b57cec5SDimitry Andric case DeclSpec::TST_typeofExpr: return "typeof"; 594bdd1243dSDimitry Andric case DeclSpec::TST_typeof_unqualType: 595bdd1243dSDimitry Andric case DeclSpec::TST_typeof_unqualExpr: return "typeof_unqual"; 5960b57cec5SDimitry Andric case DeclSpec::TST_auto: return "auto"; 5970b57cec5SDimitry Andric case DeclSpec::TST_auto_type: return "__auto_type"; 5980b57cec5SDimitry Andric case DeclSpec::TST_decltype: return "(decltype)"; 5990b57cec5SDimitry Andric case DeclSpec::TST_decltype_auto: return "decltype(auto)"; 600bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ 601bdd1243dSDimitry Andric case DeclSpec::TST_##Trait: \ 602bdd1243dSDimitry Andric return "__" #Trait; 603bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def" 6040b57cec5SDimitry Andric case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; 6050b57cec5SDimitry Andric case DeclSpec::TST_atomic: return "_Atomic"; 6065ffd83dbSDimitry Andric case DeclSpec::TST_BFloat16: return "__bf16"; 6070b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) \ 6080b57cec5SDimitry Andric case DeclSpec::TST_##ImgType##_t: \ 6090b57cec5SDimitry Andric return #ImgType "_t"; 6100b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def" 6110b57cec5SDimitry Andric case DeclSpec::TST_error: return "(error)"; 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric llvm_unreachable("Unknown typespec!"); 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric const char *DeclSpec::getSpecifierName(ConstexprSpecKind C) { 6170b57cec5SDimitry Andric switch (C) { 618e8d8bef9SDimitry Andric case ConstexprSpecKind::Unspecified: 619e8d8bef9SDimitry Andric return "unspecified"; 620e8d8bef9SDimitry Andric case ConstexprSpecKind::Constexpr: 621e8d8bef9SDimitry Andric return "constexpr"; 622e8d8bef9SDimitry Andric case ConstexprSpecKind::Consteval: 623e8d8bef9SDimitry Andric return "consteval"; 624e8d8bef9SDimitry Andric case ConstexprSpecKind::Constinit: 625e8d8bef9SDimitry Andric return "constinit"; 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric llvm_unreachable("Unknown ConstexprSpecKind"); 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric const char *DeclSpec::getSpecifierName(TQ T) { 6310b57cec5SDimitry Andric switch (T) { 6320b57cec5SDimitry Andric case DeclSpec::TQ_unspecified: return "unspecified"; 6330b57cec5SDimitry Andric case DeclSpec::TQ_const: return "const"; 6340b57cec5SDimitry Andric case DeclSpec::TQ_restrict: return "restrict"; 6350b57cec5SDimitry Andric case DeclSpec::TQ_volatile: return "volatile"; 6360b57cec5SDimitry Andric case DeclSpec::TQ_atomic: return "_Atomic"; 6370b57cec5SDimitry Andric case DeclSpec::TQ_unaligned: return "__unaligned"; 6380b57cec5SDimitry Andric } 6390b57cec5SDimitry Andric llvm_unreachable("Unknown typespec!"); 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, 6430b57cec5SDimitry Andric const char *&PrevSpec, 6440b57cec5SDimitry Andric unsigned &DiagID, 6450b57cec5SDimitry Andric const PrintingPolicy &Policy) { 6460b57cec5SDimitry Andric // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class 6470b57cec5SDimitry Andric // specifiers are not supported. 6480b57cec5SDimitry Andric // It seems sensible to prohibit private_extern too 6490b57cec5SDimitry Andric // The cl_clang_storage_class_specifiers extension enables support for 6500b57cec5SDimitry Andric // these storage-class specifiers. 6510b57cec5SDimitry Andric // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class 6520b57cec5SDimitry Andric // specifiers are not supported." 6530b57cec5SDimitry Andric if (S.getLangOpts().OpenCL && 654fe6060f1SDimitry Andric !S.getOpenCLOptions().isAvailableOption( 655fe6060f1SDimitry Andric "cl_clang_storage_class_specifiers", S.getLangOpts())) { 6560b57cec5SDimitry Andric switch (SC) { 6570b57cec5SDimitry Andric case SCS_extern: 6580b57cec5SDimitry Andric case SCS_private_extern: 6590b57cec5SDimitry Andric case SCS_static: 660349cc55cSDimitry Andric if (S.getLangOpts().getOpenCLCompatibleVersion() < 120) { 6610b57cec5SDimitry Andric DiagID = diag::err_opencl_unknown_type_specifier; 6620b57cec5SDimitry Andric PrevSpec = getSpecifierName(SC); 6630b57cec5SDimitry Andric return true; 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric break; 6660b57cec5SDimitry Andric case SCS_auto: 6670b57cec5SDimitry Andric case SCS_register: 6680b57cec5SDimitry Andric DiagID = diag::err_opencl_unknown_type_specifier; 6690b57cec5SDimitry Andric PrevSpec = getSpecifierName(SC); 6700b57cec5SDimitry Andric return true; 6710b57cec5SDimitry Andric default: 6720b57cec5SDimitry Andric break; 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric if (StorageClassSpec != SCS_unspecified) { 6770b57cec5SDimitry Andric // Maybe this is an attempt to use C++11 'auto' outside of C++11 mode. 6780b57cec5SDimitry Andric bool isInvalid = true; 6790b57cec5SDimitry Andric if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) { 6800b57cec5SDimitry Andric if (SC == SCS_auto) 6810b57cec5SDimitry Andric return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID, Policy); 6820b57cec5SDimitry Andric if (StorageClassSpec == SCS_auto) { 6830b57cec5SDimitry Andric isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc, 6840b57cec5SDimitry Andric PrevSpec, DiagID, Policy); 6850b57cec5SDimitry Andric assert(!isInvalid && "auto SCS -> TST recovery failed"); 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric // Changing storage class is allowed only if the previous one 6900b57cec5SDimitry Andric // was the 'extern' that is part of a linkage specification and 6910b57cec5SDimitry Andric // the new storage class is 'typedef'. 6920b57cec5SDimitry Andric if (isInvalid && 6930b57cec5SDimitry Andric !(SCS_extern_in_linkage_spec && 6940b57cec5SDimitry Andric StorageClassSpec == SCS_extern && 6950b57cec5SDimitry Andric SC == SCS_typedef)) 6960b57cec5SDimitry Andric return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID); 6970b57cec5SDimitry Andric } 6980b57cec5SDimitry Andric StorageClassSpec = SC; 6990b57cec5SDimitry Andric StorageClassSpecLoc = Loc; 7000b57cec5SDimitry Andric assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield"); 7010b57cec5SDimitry Andric return false; 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric bool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, 7050b57cec5SDimitry Andric const char *&PrevSpec, 7060b57cec5SDimitry Andric unsigned &DiagID) { 7070b57cec5SDimitry Andric if (ThreadStorageClassSpec != TSCS_unspecified) 7080b57cec5SDimitry Andric return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID); 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric ThreadStorageClassSpec = TSC; 7110b57cec5SDimitry Andric ThreadStorageClassSpecLoc = Loc; 7120b57cec5SDimitry Andric return false; 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric /// These methods set the specified attribute of the DeclSpec, but return true 7160b57cec5SDimitry Andric /// and ignore the request if invalid (e.g. "extern" then "auto" is 7170b57cec5SDimitry Andric /// specified). 718e8d8bef9SDimitry Andric bool DeclSpec::SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, 719e8d8bef9SDimitry Andric const char *&PrevSpec, unsigned &DiagID, 7200b57cec5SDimitry Andric const PrintingPolicy &Policy) { 7210b57cec5SDimitry Andric // Overwrite TSWRange.Begin only if TypeSpecWidth was unspecified, so that 7220b57cec5SDimitry Andric // for 'long long' we will keep the source location of the first 'long'. 723e8d8bef9SDimitry Andric if (getTypeSpecWidth() == TypeSpecifierWidth::Unspecified) 7240b57cec5SDimitry Andric TSWRange.setBegin(Loc); 7250b57cec5SDimitry Andric // Allow turning long -> long long. 726e8d8bef9SDimitry Andric else if (W != TypeSpecifierWidth::LongLong || 727e8d8bef9SDimitry Andric getTypeSpecWidth() != TypeSpecifierWidth::Long) 728e8d8bef9SDimitry Andric return BadSpecifier(W, getTypeSpecWidth(), PrevSpec, DiagID); 729e8d8bef9SDimitry Andric TypeSpecWidth = static_cast<unsigned>(W); 7300b57cec5SDimitry Andric // Remember location of the last 'long' 7310b57cec5SDimitry Andric TSWRange.setEnd(Loc); 7320b57cec5SDimitry Andric return false; 7330b57cec5SDimitry Andric } 7340b57cec5SDimitry Andric 7350b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, 7360b57cec5SDimitry Andric const char *&PrevSpec, 7370b57cec5SDimitry Andric unsigned &DiagID) { 7380b57cec5SDimitry Andric if (TypeSpecComplex != TSC_unspecified) 7390b57cec5SDimitry Andric return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); 7400b57cec5SDimitry Andric TypeSpecComplex = C; 7410b57cec5SDimitry Andric TSCLoc = Loc; 7420b57cec5SDimitry Andric return false; 7430b57cec5SDimitry Andric } 7440b57cec5SDimitry Andric 745e8d8bef9SDimitry Andric bool DeclSpec::SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, 746e8d8bef9SDimitry Andric const char *&PrevSpec, unsigned &DiagID) { 747e8d8bef9SDimitry Andric if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) 748e8d8bef9SDimitry Andric return BadSpecifier(S, getTypeSpecSign(), PrevSpec, DiagID); 749e8d8bef9SDimitry Andric TypeSpecSign = static_cast<unsigned>(S); 7500b57cec5SDimitry Andric TSSLoc = Loc; 7510b57cec5SDimitry Andric return false; 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 7550b57cec5SDimitry Andric const char *&PrevSpec, 7560b57cec5SDimitry Andric unsigned &DiagID, 7570b57cec5SDimitry Andric ParsedType Rep, 7580b57cec5SDimitry Andric const PrintingPolicy &Policy) { 7590b57cec5SDimitry Andric return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Policy); 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 7630b57cec5SDimitry Andric SourceLocation TagNameLoc, 7640b57cec5SDimitry Andric const char *&PrevSpec, 7650b57cec5SDimitry Andric unsigned &DiagID, 7660b57cec5SDimitry Andric ParsedType Rep, 7670b57cec5SDimitry Andric const PrintingPolicy &Policy) { 7680b57cec5SDimitry Andric assert(isTypeRep(T) && "T does not store a type"); 7690b57cec5SDimitry Andric assert(Rep && "no type provided!"); 7700b57cec5SDimitry Andric if (TypeSpecType == TST_error) 7710b57cec5SDimitry Andric return false; 7720b57cec5SDimitry Andric if (TypeSpecType != TST_unspecified) { 7730b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); 7740b57cec5SDimitry Andric DiagID = diag::err_invalid_decl_spec_combination; 7750b57cec5SDimitry Andric return true; 7760b57cec5SDimitry Andric } 7770b57cec5SDimitry Andric TypeSpecType = T; 7780b57cec5SDimitry Andric TypeRep = Rep; 7790b57cec5SDimitry Andric TSTLoc = TagKwLoc; 7800b57cec5SDimitry Andric TSTNameLoc = TagNameLoc; 7810b57cec5SDimitry Andric TypeSpecOwned = false; 782*0fca6ea1SDimitry Andric 783*0fca6ea1SDimitry Andric if (T == TST_typename_pack_indexing) { 784*0fca6ea1SDimitry Andric // we got there from a an annotation. Reconstruct the type 785*0fca6ea1SDimitry Andric // Ugly... 786*0fca6ea1SDimitry Andric QualType QT = Rep.get(); 787*0fca6ea1SDimitry Andric const PackIndexingType *LIT = cast<PackIndexingType>(QT); 788*0fca6ea1SDimitry Andric TypeRep = ParsedType::make(LIT->getPattern()); 789*0fca6ea1SDimitry Andric PackIndexingExpr = LIT->getIndexExpr(); 790*0fca6ea1SDimitry Andric } 7910b57cec5SDimitry Andric return false; 7920b57cec5SDimitry Andric } 7930b57cec5SDimitry Andric 7940b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 7950b57cec5SDimitry Andric const char *&PrevSpec, 7960b57cec5SDimitry Andric unsigned &DiagID, 7970b57cec5SDimitry Andric Expr *Rep, 7980b57cec5SDimitry Andric const PrintingPolicy &Policy) { 7990b57cec5SDimitry Andric assert(isExprRep(T) && "T does not store an expr"); 8000b57cec5SDimitry Andric assert(Rep && "no expression provided!"); 8010b57cec5SDimitry Andric if (TypeSpecType == TST_error) 8020b57cec5SDimitry Andric return false; 8030b57cec5SDimitry Andric if (TypeSpecType != TST_unspecified) { 8040b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); 8050b57cec5SDimitry Andric DiagID = diag::err_invalid_decl_spec_combination; 8060b57cec5SDimitry Andric return true; 8070b57cec5SDimitry Andric } 8080b57cec5SDimitry Andric TypeSpecType = T; 8090b57cec5SDimitry Andric ExprRep = Rep; 8100b57cec5SDimitry Andric TSTLoc = Loc; 8110b57cec5SDimitry Andric TSTNameLoc = Loc; 8120b57cec5SDimitry Andric TypeSpecOwned = false; 8130b57cec5SDimitry Andric return false; 8140b57cec5SDimitry Andric } 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 8170b57cec5SDimitry Andric const char *&PrevSpec, 8180b57cec5SDimitry Andric unsigned &DiagID, 8190b57cec5SDimitry Andric Decl *Rep, bool Owned, 8200b57cec5SDimitry Andric const PrintingPolicy &Policy) { 8210b57cec5SDimitry Andric return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned, Policy); 8220b57cec5SDimitry Andric } 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 8250b57cec5SDimitry Andric SourceLocation TagNameLoc, 8260b57cec5SDimitry Andric const char *&PrevSpec, 8270b57cec5SDimitry Andric unsigned &DiagID, 8280b57cec5SDimitry Andric Decl *Rep, bool Owned, 8290b57cec5SDimitry Andric const PrintingPolicy &Policy) { 8300b57cec5SDimitry Andric assert(isDeclRep(T) && "T does not store a decl"); 8310b57cec5SDimitry Andric // Unlike the other cases, we don't assert that we actually get a decl. 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric if (TypeSpecType == TST_error) 8340b57cec5SDimitry Andric return false; 8350b57cec5SDimitry Andric if (TypeSpecType != TST_unspecified) { 8360b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); 8370b57cec5SDimitry Andric DiagID = diag::err_invalid_decl_spec_combination; 8380b57cec5SDimitry Andric return true; 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric TypeSpecType = T; 8410b57cec5SDimitry Andric DeclRep = Rep; 8420b57cec5SDimitry Andric TSTLoc = TagKwLoc; 8430b57cec5SDimitry Andric TSTNameLoc = TagNameLoc; 8440b57cec5SDimitry Andric TypeSpecOwned = Owned && Rep != nullptr; 8450b57cec5SDimitry Andric return false; 8460b57cec5SDimitry Andric } 8470b57cec5SDimitry Andric 84855e4f9d5SDimitry Andric bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, 84955e4f9d5SDimitry Andric unsigned &DiagID, TemplateIdAnnotation *Rep, 85055e4f9d5SDimitry Andric const PrintingPolicy &Policy) { 85155e4f9d5SDimitry Andric assert(T == TST_auto || T == TST_decltype_auto); 85255e4f9d5SDimitry Andric ConstrainedAuto = true; 85355e4f9d5SDimitry Andric TemplateIdRep = Rep; 85455e4f9d5SDimitry Andric return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Policy); 85555e4f9d5SDimitry Andric } 85655e4f9d5SDimitry Andric 8570b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 8580b57cec5SDimitry Andric const char *&PrevSpec, 8590b57cec5SDimitry Andric unsigned &DiagID, 8600b57cec5SDimitry Andric const PrintingPolicy &Policy) { 8610b57cec5SDimitry Andric assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && 8620b57cec5SDimitry Andric "rep required for these type-spec kinds!"); 8630b57cec5SDimitry Andric if (TypeSpecType == TST_error) 8640b57cec5SDimitry Andric return false; 8650b57cec5SDimitry Andric if (TypeSpecType != TST_unspecified) { 8660b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); 8670b57cec5SDimitry Andric DiagID = diag::err_invalid_decl_spec_combination; 8680b57cec5SDimitry Andric return true; 8690b57cec5SDimitry Andric } 8700b57cec5SDimitry Andric TSTLoc = Loc; 8710b57cec5SDimitry Andric TSTNameLoc = Loc; 8720b57cec5SDimitry Andric if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { 8730b57cec5SDimitry Andric TypeAltiVecBool = true; 8740b57cec5SDimitry Andric return false; 8750b57cec5SDimitry Andric } 8760b57cec5SDimitry Andric TypeSpecType = T; 8770b57cec5SDimitry Andric TypeSpecOwned = false; 8780b57cec5SDimitry Andric return false; 8790b57cec5SDimitry Andric } 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, 8820b57cec5SDimitry Andric unsigned &DiagID) { 8830b57cec5SDimitry Andric // Cannot set twice 8840b57cec5SDimitry Andric if (TypeSpecSat) { 8850b57cec5SDimitry Andric DiagID = diag::warn_duplicate_declspec; 8860b57cec5SDimitry Andric PrevSpec = "_Sat"; 8870b57cec5SDimitry Andric return true; 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric TypeSpecSat = true; 8900b57cec5SDimitry Andric TSSatLoc = Loc; 8910b57cec5SDimitry Andric return false; 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 8950b57cec5SDimitry Andric const char *&PrevSpec, unsigned &DiagID, 8960b57cec5SDimitry Andric const PrintingPolicy &Policy) { 8970b57cec5SDimitry Andric if (TypeSpecType == TST_error) 8980b57cec5SDimitry Andric return false; 8990b57cec5SDimitry Andric if (TypeSpecType != TST_unspecified) { 9000b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); 9010b57cec5SDimitry Andric DiagID = diag::err_invalid_vector_decl_spec_combination; 9020b57cec5SDimitry Andric return true; 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric TypeAltiVecVector = isAltiVecVector; 9050b57cec5SDimitry Andric AltiVecLoc = Loc; 9060b57cec5SDimitry Andric return false; 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric bool DeclSpec::SetTypePipe(bool isPipe, SourceLocation Loc, 9100b57cec5SDimitry Andric const char *&PrevSpec, unsigned &DiagID, 9110b57cec5SDimitry Andric const PrintingPolicy &Policy) { 9120b57cec5SDimitry Andric if (TypeSpecType == TST_error) 9130b57cec5SDimitry Andric return false; 9140b57cec5SDimitry Andric if (TypeSpecType != TST_unspecified) { 9150b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST)TypeSpecType, Policy); 9160b57cec5SDimitry Andric DiagID = diag::err_invalid_decl_spec_combination; 9170b57cec5SDimitry Andric return true; 9180b57cec5SDimitry Andric } 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric if (isPipe) { 921e8d8bef9SDimitry Andric TypeSpecPipe = static_cast<unsigned>(TypeSpecifiersPipe::Pipe); 9220b57cec5SDimitry Andric } 9230b57cec5SDimitry Andric return false; 9240b57cec5SDimitry Andric } 9250b57cec5SDimitry Andric 9260b57cec5SDimitry Andric bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 9270b57cec5SDimitry Andric const char *&PrevSpec, unsigned &DiagID, 9280b57cec5SDimitry Andric const PrintingPolicy &Policy) { 9290b57cec5SDimitry Andric if (TypeSpecType == TST_error) 9300b57cec5SDimitry Andric return false; 9310b57cec5SDimitry Andric if (!TypeAltiVecVector || TypeAltiVecPixel || 9320b57cec5SDimitry Andric (TypeSpecType != TST_unspecified)) { 9330b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); 9340b57cec5SDimitry Andric DiagID = diag::err_invalid_pixel_decl_spec_combination; 9350b57cec5SDimitry Andric return true; 9360b57cec5SDimitry Andric } 9370b57cec5SDimitry Andric TypeAltiVecPixel = isAltiVecPixel; 9380b57cec5SDimitry Andric TSTLoc = Loc; 9390b57cec5SDimitry Andric TSTNameLoc = Loc; 9400b57cec5SDimitry Andric return false; 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, 9440b57cec5SDimitry Andric const char *&PrevSpec, unsigned &DiagID, 9450b57cec5SDimitry Andric const PrintingPolicy &Policy) { 9460b57cec5SDimitry Andric if (TypeSpecType == TST_error) 9470b57cec5SDimitry Andric return false; 9480b57cec5SDimitry Andric if (!TypeAltiVecVector || TypeAltiVecBool || 9490b57cec5SDimitry Andric (TypeSpecType != TST_unspecified)) { 9500b57cec5SDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); 9510b57cec5SDimitry Andric DiagID = diag::err_invalid_vector_bool_decl_spec; 9520b57cec5SDimitry Andric return true; 9530b57cec5SDimitry Andric } 9540b57cec5SDimitry Andric TypeAltiVecBool = isAltiVecBool; 9550b57cec5SDimitry Andric TSTLoc = Loc; 9560b57cec5SDimitry Andric TSTNameLoc = Loc; 9570b57cec5SDimitry Andric return false; 9580b57cec5SDimitry Andric } 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric bool DeclSpec::SetTypeSpecError() { 9610b57cec5SDimitry Andric TypeSpecType = TST_error; 9620b57cec5SDimitry Andric TypeSpecOwned = false; 9630b57cec5SDimitry Andric TSTLoc = SourceLocation(); 9640b57cec5SDimitry Andric TSTNameLoc = SourceLocation(); 9650b57cec5SDimitry Andric return false; 9660b57cec5SDimitry Andric } 9670b57cec5SDimitry Andric 9680eae32dcSDimitry Andric bool DeclSpec::SetBitIntType(SourceLocation KWLoc, Expr *BitsExpr, 9695ffd83dbSDimitry Andric const char *&PrevSpec, unsigned &DiagID, 9705ffd83dbSDimitry Andric const PrintingPolicy &Policy) { 9715ffd83dbSDimitry Andric assert(BitsExpr && "no expression provided!"); 9725ffd83dbSDimitry Andric if (TypeSpecType == TST_error) 9735ffd83dbSDimitry Andric return false; 9745ffd83dbSDimitry Andric 9755ffd83dbSDimitry Andric if (TypeSpecType != TST_unspecified) { 9765ffd83dbSDimitry Andric PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); 9775ffd83dbSDimitry Andric DiagID = diag::err_invalid_decl_spec_combination; 9785ffd83dbSDimitry Andric return true; 9795ffd83dbSDimitry Andric } 9805ffd83dbSDimitry Andric 9810eae32dcSDimitry Andric TypeSpecType = TST_bitint; 9825ffd83dbSDimitry Andric ExprRep = BitsExpr; 9835ffd83dbSDimitry Andric TSTLoc = KWLoc; 9845ffd83dbSDimitry Andric TSTNameLoc = KWLoc; 9855ffd83dbSDimitry Andric TypeSpecOwned = false; 9865ffd83dbSDimitry Andric return false; 9875ffd83dbSDimitry Andric } 9885ffd83dbSDimitry Andric 989*0fca6ea1SDimitry Andric void DeclSpec::SetPackIndexingExpr(SourceLocation EllipsisLoc, 990*0fca6ea1SDimitry Andric Expr *IndexingExpr) { 991*0fca6ea1SDimitry Andric assert(TypeSpecType == TST_typename && 992*0fca6ea1SDimitry Andric "pack indexing can only be applied to typename"); 993*0fca6ea1SDimitry Andric TypeSpecType = TST_typename_pack_indexing; 994*0fca6ea1SDimitry Andric PackIndexingExpr = IndexingExpr; 995*0fca6ea1SDimitry Andric this->EllipsisLoc = EllipsisLoc; 996*0fca6ea1SDimitry Andric } 997*0fca6ea1SDimitry Andric 9980b57cec5SDimitry Andric bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 9990b57cec5SDimitry Andric unsigned &DiagID, const LangOptions &Lang) { 10000b57cec5SDimitry Andric // Duplicates are permitted in C99 onwards, but are not permitted in C89 or 10010b57cec5SDimitry Andric // C++. However, since this is likely not what the user intended, we will 10020b57cec5SDimitry Andric // always warn. We do not need to set the qualifier's location since we 10030b57cec5SDimitry Andric // already have it. 10040b57cec5SDimitry Andric if (TypeQualifiers & T) { 10050b57cec5SDimitry Andric bool IsExtension = true; 10060b57cec5SDimitry Andric if (Lang.C99) 10070b57cec5SDimitry Andric IsExtension = false; 10080b57cec5SDimitry Andric return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension); 10090b57cec5SDimitry Andric } 10100b57cec5SDimitry Andric 10110b57cec5SDimitry Andric return SetTypeQual(T, Loc); 10120b57cec5SDimitry Andric } 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andric bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc) { 10150b57cec5SDimitry Andric TypeQualifiers |= T; 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric switch (T) { 10180b57cec5SDimitry Andric case TQ_unspecified: break; 10190b57cec5SDimitry Andric case TQ_const: TQ_constLoc = Loc; return false; 10200b57cec5SDimitry Andric case TQ_restrict: TQ_restrictLoc = Loc; return false; 10210b57cec5SDimitry Andric case TQ_volatile: TQ_volatileLoc = Loc; return false; 10220b57cec5SDimitry Andric case TQ_unaligned: TQ_unalignedLoc = Loc; return false; 10230b57cec5SDimitry Andric case TQ_atomic: TQ_atomicLoc = Loc; return false; 10240b57cec5SDimitry Andric } 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric llvm_unreachable("Unknown type qualifier!"); 10270b57cec5SDimitry Andric } 10280b57cec5SDimitry Andric 10290b57cec5SDimitry Andric bool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, 10300b57cec5SDimitry Andric unsigned &DiagID) { 10310b57cec5SDimitry Andric // 'inline inline' is ok. However, since this is likely not what the user 10320b57cec5SDimitry Andric // intended, we will always warn, similar to duplicates of type qualifiers. 10330b57cec5SDimitry Andric if (FS_inline_specified) { 10340b57cec5SDimitry Andric DiagID = diag::warn_duplicate_declspec; 10350b57cec5SDimitry Andric PrevSpec = "inline"; 10360b57cec5SDimitry Andric return true; 10370b57cec5SDimitry Andric } 10380b57cec5SDimitry Andric FS_inline_specified = true; 10390b57cec5SDimitry Andric FS_inlineLoc = Loc; 10400b57cec5SDimitry Andric return false; 10410b57cec5SDimitry Andric } 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric bool DeclSpec::setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, 10440b57cec5SDimitry Andric unsigned &DiagID) { 10450b57cec5SDimitry Andric if (FS_forceinline_specified) { 10460b57cec5SDimitry Andric DiagID = diag::warn_duplicate_declspec; 10470b57cec5SDimitry Andric PrevSpec = "__forceinline"; 10480b57cec5SDimitry Andric return true; 10490b57cec5SDimitry Andric } 10500b57cec5SDimitry Andric FS_forceinline_specified = true; 10510b57cec5SDimitry Andric FS_forceinlineLoc = Loc; 10520b57cec5SDimitry Andric return false; 10530b57cec5SDimitry Andric } 10540b57cec5SDimitry Andric 10550b57cec5SDimitry Andric bool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc, 10560b57cec5SDimitry Andric const char *&PrevSpec, 10570b57cec5SDimitry Andric unsigned &DiagID) { 10580b57cec5SDimitry Andric // 'virtual virtual' is ok, but warn as this is likely not what the user 10590b57cec5SDimitry Andric // intended. 10600b57cec5SDimitry Andric if (FS_virtual_specified) { 10610b57cec5SDimitry Andric DiagID = diag::warn_duplicate_declspec; 10620b57cec5SDimitry Andric PrevSpec = "virtual"; 10630b57cec5SDimitry Andric return true; 10640b57cec5SDimitry Andric } 10650b57cec5SDimitry Andric FS_virtual_specified = true; 10660b57cec5SDimitry Andric FS_virtualLoc = Loc; 10670b57cec5SDimitry Andric return false; 10680b57cec5SDimitry Andric } 10690b57cec5SDimitry Andric 10700b57cec5SDimitry Andric bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc, 10710b57cec5SDimitry Andric const char *&PrevSpec, unsigned &DiagID, 10720b57cec5SDimitry Andric ExplicitSpecifier ExplicitSpec, 10730b57cec5SDimitry Andric SourceLocation CloseParenLoc) { 10740b57cec5SDimitry Andric // 'explicit explicit' is ok, but warn as this is likely not what the user 10750b57cec5SDimitry Andric // intended. 10760b57cec5SDimitry Andric if (hasExplicitSpecifier()) { 10770b57cec5SDimitry Andric DiagID = (ExplicitSpec.getExpr() || FS_explicit_specifier.getExpr()) 10780b57cec5SDimitry Andric ? diag::err_duplicate_declspec 10790b57cec5SDimitry Andric : diag::ext_warn_duplicate_declspec; 10800b57cec5SDimitry Andric PrevSpec = "explicit"; 10810b57cec5SDimitry Andric return true; 10820b57cec5SDimitry Andric } 10830b57cec5SDimitry Andric FS_explicit_specifier = ExplicitSpec; 10840b57cec5SDimitry Andric FS_explicitLoc = Loc; 10850b57cec5SDimitry Andric FS_explicitCloseParenLoc = CloseParenLoc; 10860b57cec5SDimitry Andric return false; 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric bool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc, 10900b57cec5SDimitry Andric const char *&PrevSpec, 10910b57cec5SDimitry Andric unsigned &DiagID) { 10920b57cec5SDimitry Andric // '_Noreturn _Noreturn' is ok, but warn as this is likely not what the user 10930b57cec5SDimitry Andric // intended. 10940b57cec5SDimitry Andric if (FS_noreturn_specified) { 10950b57cec5SDimitry Andric DiagID = diag::warn_duplicate_declspec; 10960b57cec5SDimitry Andric PrevSpec = "_Noreturn"; 10970b57cec5SDimitry Andric return true; 10980b57cec5SDimitry Andric } 10990b57cec5SDimitry Andric FS_noreturn_specified = true; 11000b57cec5SDimitry Andric FS_noreturnLoc = Loc; 11010b57cec5SDimitry Andric return false; 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric 11040b57cec5SDimitry Andric bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 11050b57cec5SDimitry Andric unsigned &DiagID) { 1106*0fca6ea1SDimitry Andric if (isFriendSpecified()) { 11070b57cec5SDimitry Andric PrevSpec = "friend"; 11080b57cec5SDimitry Andric DiagID = diag::warn_duplicate_declspec; 11090b57cec5SDimitry Andric return true; 11100b57cec5SDimitry Andric } 11110b57cec5SDimitry Andric 1112*0fca6ea1SDimitry Andric FriendSpecifiedFirst = isEmpty(); 11130b57cec5SDimitry Andric FriendLoc = Loc; 11140b57cec5SDimitry Andric return false; 11150b57cec5SDimitry Andric } 11160b57cec5SDimitry Andric 11170b57cec5SDimitry Andric bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, 11180b57cec5SDimitry Andric unsigned &DiagID) { 11190b57cec5SDimitry Andric if (isModulePrivateSpecified()) { 11200b57cec5SDimitry Andric PrevSpec = "__module_private__"; 11210b57cec5SDimitry Andric DiagID = diag::ext_warn_duplicate_declspec; 11220b57cec5SDimitry Andric return true; 11230b57cec5SDimitry Andric } 11240b57cec5SDimitry Andric 11250b57cec5SDimitry Andric ModulePrivateLoc = Loc; 11260b57cec5SDimitry Andric return false; 11270b57cec5SDimitry Andric } 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric bool DeclSpec::SetConstexprSpec(ConstexprSpecKind ConstexprKind, 11300b57cec5SDimitry Andric SourceLocation Loc, const char *&PrevSpec, 11310b57cec5SDimitry Andric unsigned &DiagID) { 1132e8d8bef9SDimitry Andric if (getConstexprSpecifier() != ConstexprSpecKind::Unspecified) 1133a7dea167SDimitry Andric return BadSpecifier(ConstexprKind, getConstexprSpecifier(), PrevSpec, 1134a7dea167SDimitry Andric DiagID); 1135e8d8bef9SDimitry Andric ConstexprSpecifier = static_cast<unsigned>(ConstexprKind); 11360b57cec5SDimitry Andric ConstexprLoc = Loc; 11370b57cec5SDimitry Andric return false; 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric void DeclSpec::SaveWrittenBuiltinSpecs() { 1141e8d8bef9SDimitry Andric writtenBS.Sign = static_cast<int>(getTypeSpecSign()); 1142e8d8bef9SDimitry Andric writtenBS.Width = static_cast<int>(getTypeSpecWidth()); 11430b57cec5SDimitry Andric writtenBS.Type = getTypeSpecType(); 11440b57cec5SDimitry Andric // Search the list of attributes for the presence of a mode attribute. 11450b57cec5SDimitry Andric writtenBS.ModeAttr = getAttributes().hasAttribute(ParsedAttr::AT_Mode); 11460b57cec5SDimitry Andric } 11470b57cec5SDimitry Andric 11480b57cec5SDimitry Andric /// Finish - This does final analysis of the declspec, rejecting things like 1149*0fca6ea1SDimitry Andric /// "_Complex" (lacking an FP type). After calling this method, DeclSpec is 1150bdd1243dSDimitry Andric /// guaranteed to be self-consistent, even if an error occurred. 11510b57cec5SDimitry Andric void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { 11520b57cec5SDimitry Andric // Before possibly changing their values, save specs as written. 11530b57cec5SDimitry Andric SaveWrittenBuiltinSpecs(); 11540b57cec5SDimitry Andric 11550b57cec5SDimitry Andric // Check the type specifier components first. No checking for an invalid 11560b57cec5SDimitry Andric // type. 11570b57cec5SDimitry Andric if (TypeSpecType == TST_error) 11580b57cec5SDimitry Andric return; 11590b57cec5SDimitry Andric 11600b57cec5SDimitry Andric // If decltype(auto) is used, no other type specifiers are permitted. 11610b57cec5SDimitry Andric if (TypeSpecType == TST_decltype_auto && 1162e8d8bef9SDimitry Andric (getTypeSpecWidth() != TypeSpecifierWidth::Unspecified || 11630b57cec5SDimitry Andric TypeSpecComplex != TSC_unspecified || 1164e8d8bef9SDimitry Andric getTypeSpecSign() != TypeSpecifierSign::Unspecified || 11650b57cec5SDimitry Andric TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool || 11660b57cec5SDimitry Andric TypeQualifiers)) { 11670b57cec5SDimitry Andric const unsigned NumLocs = 9; 11680b57cec5SDimitry Andric SourceLocation ExtraLocs[NumLocs] = { 11690b57cec5SDimitry Andric TSWRange.getBegin(), TSCLoc, TSSLoc, 11700b57cec5SDimitry Andric AltiVecLoc, TQ_constLoc, TQ_restrictLoc, 11710b57cec5SDimitry Andric TQ_volatileLoc, TQ_atomicLoc, TQ_unalignedLoc}; 11720b57cec5SDimitry Andric FixItHint Hints[NumLocs]; 11730b57cec5SDimitry Andric SourceLocation FirstLoc; 11740b57cec5SDimitry Andric for (unsigned I = 0; I != NumLocs; ++I) { 11750b57cec5SDimitry Andric if (ExtraLocs[I].isValid()) { 11760b57cec5SDimitry Andric if (FirstLoc.isInvalid() || 11770b57cec5SDimitry Andric S.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I], 11780b57cec5SDimitry Andric FirstLoc)) 11790b57cec5SDimitry Andric FirstLoc = ExtraLocs[I]; 11800b57cec5SDimitry Andric Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]); 11810b57cec5SDimitry Andric } 11820b57cec5SDimitry Andric } 1183e8d8bef9SDimitry Andric TypeSpecWidth = static_cast<unsigned>(TypeSpecifierWidth::Unspecified); 11840b57cec5SDimitry Andric TypeSpecComplex = TSC_unspecified; 1185e8d8bef9SDimitry Andric TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unspecified); 11860b57cec5SDimitry Andric TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false; 11870b57cec5SDimitry Andric TypeQualifiers = 0; 11880b57cec5SDimitry Andric S.Diag(TSTLoc, diag::err_decltype_auto_cannot_be_combined) 11890b57cec5SDimitry Andric << Hints[0] << Hints[1] << Hints[2] << Hints[3] 11900b57cec5SDimitry Andric << Hints[4] << Hints[5] << Hints[6] << Hints[7]; 11910b57cec5SDimitry Andric } 11920b57cec5SDimitry Andric 11930b57cec5SDimitry Andric // Validate and finalize AltiVec vector declspec. 11940b57cec5SDimitry Andric if (TypeAltiVecVector) { 1195349cc55cSDimitry Andric // No vector long long without VSX (or ZVector). 1196349cc55cSDimitry Andric if ((getTypeSpecWidth() == TypeSpecifierWidth::LongLong) && 1197349cc55cSDimitry Andric !S.Context.getTargetInfo().hasFeature("vsx") && 1198349cc55cSDimitry Andric !S.getLangOpts().ZVector) 1199349cc55cSDimitry Andric S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_long_decl_spec); 1200349cc55cSDimitry Andric 1201349cc55cSDimitry Andric // No vector __int128 prior to Power8. 1202349cc55cSDimitry Andric if ((TypeSpecType == TST_int128) && 1203349cc55cSDimitry Andric !S.Context.getTargetInfo().hasFeature("power8-vector")) 1204349cc55cSDimitry Andric S.Diag(TSTLoc, diag::err_invalid_vector_int128_decl_spec); 1205349cc55cSDimitry Andric 1206*0fca6ea1SDimitry Andric // Complex vector types are not supported. 1207*0fca6ea1SDimitry Andric if (TypeSpecComplex != TSC_unspecified) 1208*0fca6ea1SDimitry Andric S.Diag(TSCLoc, diag::err_invalid_vector_complex_decl_spec); 1209*0fca6ea1SDimitry Andric else if (TypeAltiVecBool) { 12100b57cec5SDimitry Andric // Sign specifiers are not allowed with vector bool. (PIM 2.1) 1211e8d8bef9SDimitry Andric if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) { 12120b57cec5SDimitry Andric S.Diag(TSSLoc, diag::err_invalid_vector_bool_decl_spec) 1213e8d8bef9SDimitry Andric << getSpecifierName(getTypeSpecSign()); 12140b57cec5SDimitry Andric } 12155ffd83dbSDimitry Andric // Only char/int are valid with vector bool prior to Power10. 12165ffd83dbSDimitry Andric // Power10 adds instructions that produce vector bool data 12175ffd83dbSDimitry Andric // for quadwords as well so allow vector bool __int128. 12180b57cec5SDimitry Andric if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && 12195ffd83dbSDimitry Andric (TypeSpecType != TST_int) && (TypeSpecType != TST_int128)) || 12205ffd83dbSDimitry Andric TypeAltiVecPixel) { 12210b57cec5SDimitry Andric S.Diag(TSTLoc, diag::err_invalid_vector_bool_decl_spec) 12220b57cec5SDimitry Andric << (TypeAltiVecPixel ? "__pixel" : 12230b57cec5SDimitry Andric getSpecifierName((TST)TypeSpecType, Policy)); 12240b57cec5SDimitry Andric } 12255ffd83dbSDimitry Andric // vector bool __int128 requires Power10. 12265ffd83dbSDimitry Andric if ((TypeSpecType == TST_int128) && 12275ffd83dbSDimitry Andric (!S.Context.getTargetInfo().hasFeature("power10-vector"))) 12285ffd83dbSDimitry Andric S.Diag(TSTLoc, diag::err_invalid_vector_bool_int128_decl_spec); 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric // Only 'short' and 'long long' are valid with vector bool. (PIM 2.1) 1231e8d8bef9SDimitry Andric if ((getTypeSpecWidth() != TypeSpecifierWidth::Unspecified) && 1232e8d8bef9SDimitry Andric (getTypeSpecWidth() != TypeSpecifierWidth::Short) && 1233e8d8bef9SDimitry Andric (getTypeSpecWidth() != TypeSpecifierWidth::LongLong)) 12340b57cec5SDimitry Andric S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_bool_decl_spec) 1235e8d8bef9SDimitry Andric << getSpecifierName(getTypeSpecWidth()); 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric // Elements of vector bool are interpreted as unsigned. (PIM 2.1) 12380b57cec5SDimitry Andric if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || 1239e8d8bef9SDimitry Andric (TypeSpecType == TST_int128) || 1240e8d8bef9SDimitry Andric (getTypeSpecWidth() != TypeSpecifierWidth::Unspecified)) 1241e8d8bef9SDimitry Andric TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unsigned); 12420b57cec5SDimitry Andric } else if (TypeSpecType == TST_double) { 12430b57cec5SDimitry Andric // vector long double and vector long long double are never allowed. 12440b57cec5SDimitry Andric // vector double is OK for Power7 and later, and ZVector. 1245e8d8bef9SDimitry Andric if (getTypeSpecWidth() == TypeSpecifierWidth::Long || 1246e8d8bef9SDimitry Andric getTypeSpecWidth() == TypeSpecifierWidth::LongLong) 12470b57cec5SDimitry Andric S.Diag(TSWRange.getBegin(), 12480b57cec5SDimitry Andric diag::err_invalid_vector_long_double_decl_spec); 12490b57cec5SDimitry Andric else if (!S.Context.getTargetInfo().hasFeature("vsx") && 12500b57cec5SDimitry Andric !S.getLangOpts().ZVector) 12510b57cec5SDimitry Andric S.Diag(TSTLoc, diag::err_invalid_vector_double_decl_spec); 12520b57cec5SDimitry Andric } else if (TypeSpecType == TST_float) { 12530b57cec5SDimitry Andric // vector float is unsupported for ZVector unless we have the 12540b57cec5SDimitry Andric // vector-enhancements facility 1 (ISA revision 12). 12550b57cec5SDimitry Andric if (S.getLangOpts().ZVector && 12560b57cec5SDimitry Andric !S.Context.getTargetInfo().hasFeature("arch12")) 12570b57cec5SDimitry Andric S.Diag(TSTLoc, diag::err_invalid_vector_float_decl_spec); 1258e8d8bef9SDimitry Andric } else if (getTypeSpecWidth() == TypeSpecifierWidth::Long) { 1259349cc55cSDimitry Andric // Vector long is unsupported for ZVector, or without VSX, and deprecated 1260349cc55cSDimitry Andric // for AltiVec. 1261e8d8bef9SDimitry Andric // It has also been historically deprecated on AIX (as an alias for 1262e8d8bef9SDimitry Andric // "vector int" in both 32-bit and 64-bit modes). It was then made 1263e8d8bef9SDimitry Andric // unsupported in the Clang-based XL compiler since the deprecated type 1264e8d8bef9SDimitry Andric // has a number of conflicting semantics and continuing to support it 1265e8d8bef9SDimitry Andric // is a disservice to users. 1266e8d8bef9SDimitry Andric if (S.getLangOpts().ZVector || 1267349cc55cSDimitry Andric !S.Context.getTargetInfo().hasFeature("vsx") || 1268e8d8bef9SDimitry Andric S.Context.getTargetInfo().getTriple().isOSAIX()) 12690b57cec5SDimitry Andric S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_decl_spec); 12700b57cec5SDimitry Andric else 12710b57cec5SDimitry Andric S.Diag(TSWRange.getBegin(), 12720b57cec5SDimitry Andric diag::warn_vector_long_decl_spec_combination) 12730b57cec5SDimitry Andric << getSpecifierName((TST)TypeSpecType, Policy); 12740b57cec5SDimitry Andric } 12750b57cec5SDimitry Andric 12760b57cec5SDimitry Andric if (TypeAltiVecPixel) { 12770b57cec5SDimitry Andric //TODO: perform validation 12780b57cec5SDimitry Andric TypeSpecType = TST_int; 1279e8d8bef9SDimitry Andric TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unsigned); 1280e8d8bef9SDimitry Andric TypeSpecWidth = static_cast<unsigned>(TypeSpecifierWidth::Short); 12810b57cec5SDimitry Andric TypeSpecOwned = false; 12820b57cec5SDimitry Andric } 12830b57cec5SDimitry Andric } 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric bool IsFixedPointType = 12860b57cec5SDimitry Andric TypeSpecType == TST_accum || TypeSpecType == TST_fract; 12870b57cec5SDimitry Andric 12880b57cec5SDimitry Andric // signed/unsigned are only valid with int/char/wchar_t/_Accum. 1289e8d8bef9SDimitry Andric if (getTypeSpecSign() != TypeSpecifierSign::Unspecified) { 12900b57cec5SDimitry Andric if (TypeSpecType == TST_unspecified) 12910b57cec5SDimitry Andric TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. 12920b57cec5SDimitry Andric else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && 12930b57cec5SDimitry Andric TypeSpecType != TST_char && TypeSpecType != TST_wchar && 12940eae32dcSDimitry Andric !IsFixedPointType && TypeSpecType != TST_bitint) { 12950b57cec5SDimitry Andric S.Diag(TSSLoc, diag::err_invalid_sign_spec) 12960b57cec5SDimitry Andric << getSpecifierName((TST)TypeSpecType, Policy); 12970b57cec5SDimitry Andric // signed double -> double. 1298e8d8bef9SDimitry Andric TypeSpecSign = static_cast<unsigned>(TypeSpecifierSign::Unspecified); 12990b57cec5SDimitry Andric } 13000b57cec5SDimitry Andric } 13010b57cec5SDimitry Andric 13020b57cec5SDimitry Andric // Validate the width of the type. 1303e8d8bef9SDimitry Andric switch (getTypeSpecWidth()) { 1304e8d8bef9SDimitry Andric case TypeSpecifierWidth::Unspecified: 1305e8d8bef9SDimitry Andric break; 1306e8d8bef9SDimitry Andric case TypeSpecifierWidth::Short: // short int 1307e8d8bef9SDimitry Andric case TypeSpecifierWidth::LongLong: // long long int 13080b57cec5SDimitry Andric if (TypeSpecType == TST_unspecified) 13090b57cec5SDimitry Andric TypeSpecType = TST_int; // short -> short int, long long -> long long int. 13100b57cec5SDimitry Andric else if (!(TypeSpecType == TST_int || 1311e8d8bef9SDimitry Andric (IsFixedPointType && 1312e8d8bef9SDimitry Andric getTypeSpecWidth() != TypeSpecifierWidth::LongLong))) { 13130b57cec5SDimitry Andric S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec) 13140b57cec5SDimitry Andric << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy); 13150b57cec5SDimitry Andric TypeSpecType = TST_int; 13160b57cec5SDimitry Andric TypeSpecSat = false; 13170b57cec5SDimitry Andric TypeSpecOwned = false; 13180b57cec5SDimitry Andric } 13190b57cec5SDimitry Andric break; 1320e8d8bef9SDimitry Andric case TypeSpecifierWidth::Long: // long double, long int 13210b57cec5SDimitry Andric if (TypeSpecType == TST_unspecified) 13220b57cec5SDimitry Andric TypeSpecType = TST_int; // long -> long int. 13230b57cec5SDimitry Andric else if (TypeSpecType != TST_int && TypeSpecType != TST_double && 13240b57cec5SDimitry Andric !IsFixedPointType) { 13250b57cec5SDimitry Andric S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec) 13260b57cec5SDimitry Andric << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy); 13270b57cec5SDimitry Andric TypeSpecType = TST_int; 13280b57cec5SDimitry Andric TypeSpecSat = false; 13290b57cec5SDimitry Andric TypeSpecOwned = false; 13300b57cec5SDimitry Andric } 13310b57cec5SDimitry Andric break; 13320b57cec5SDimitry Andric } 13330b57cec5SDimitry Andric 1334*0fca6ea1SDimitry Andric // TODO: if the implementation does not implement _Complex, disallow their 1335*0fca6ea1SDimitry Andric // use. Need information about the backend. 13360b57cec5SDimitry Andric if (TypeSpecComplex != TSC_unspecified) { 13370b57cec5SDimitry Andric if (TypeSpecType == TST_unspecified) { 13380b57cec5SDimitry Andric S.Diag(TSCLoc, diag::ext_plain_complex) 13390b57cec5SDimitry Andric << FixItHint::CreateInsertion( 13400b57cec5SDimitry Andric S.getLocForEndOfToken(getTypeSpecComplexLoc()), 13410b57cec5SDimitry Andric " double"); 13420b57cec5SDimitry Andric TypeSpecType = TST_double; // _Complex -> _Complex double. 13435ffd83dbSDimitry Andric } else if (TypeSpecType == TST_int || TypeSpecType == TST_char || 13440eae32dcSDimitry Andric TypeSpecType == TST_bitint) { 13450b57cec5SDimitry Andric // Note that this intentionally doesn't include _Complex _Bool. 13460b57cec5SDimitry Andric if (!S.getLangOpts().CPlusPlus) 13470b57cec5SDimitry Andric S.Diag(TSTLoc, diag::ext_integer_complex); 13485ffd83dbSDimitry Andric } else if (TypeSpecType != TST_float && TypeSpecType != TST_double && 1349349cc55cSDimitry Andric TypeSpecType != TST_float128 && TypeSpecType != TST_float16 && 1350349cc55cSDimitry Andric TypeSpecType != TST_ibm128) { 1351349cc55cSDimitry Andric // FIXME: __fp16? 13520b57cec5SDimitry Andric S.Diag(TSCLoc, diag::err_invalid_complex_spec) 13530b57cec5SDimitry Andric << getSpecifierName((TST)TypeSpecType, Policy); 13540b57cec5SDimitry Andric TypeSpecComplex = TSC_unspecified; 13550b57cec5SDimitry Andric } 13560b57cec5SDimitry Andric } 13570b57cec5SDimitry Andric 13580b57cec5SDimitry Andric // C11 6.7.1/3, C++11 [dcl.stc]p1, GNU TLS: __thread, thread_local and 13590b57cec5SDimitry Andric // _Thread_local can only appear with the 'static' and 'extern' storage class 13600b57cec5SDimitry Andric // specifiers. We also allow __private_extern__ as an extension. 13610b57cec5SDimitry Andric if (ThreadStorageClassSpec != TSCS_unspecified) { 13620b57cec5SDimitry Andric switch (StorageClassSpec) { 13630b57cec5SDimitry Andric case SCS_unspecified: 13640b57cec5SDimitry Andric case SCS_extern: 13650b57cec5SDimitry Andric case SCS_private_extern: 13660b57cec5SDimitry Andric case SCS_static: 13670b57cec5SDimitry Andric break; 13680b57cec5SDimitry Andric default: 13690b57cec5SDimitry Andric if (S.getSourceManager().isBeforeInTranslationUnit( 13700b57cec5SDimitry Andric getThreadStorageClassSpecLoc(), getStorageClassSpecLoc())) 13710b57cec5SDimitry Andric S.Diag(getStorageClassSpecLoc(), 13720b57cec5SDimitry Andric diag::err_invalid_decl_spec_combination) 13730b57cec5SDimitry Andric << DeclSpec::getSpecifierName(getThreadStorageClassSpec()) 13740b57cec5SDimitry Andric << SourceRange(getThreadStorageClassSpecLoc()); 13750b57cec5SDimitry Andric else 13760b57cec5SDimitry Andric S.Diag(getThreadStorageClassSpecLoc(), 13770b57cec5SDimitry Andric diag::err_invalid_decl_spec_combination) 13780b57cec5SDimitry Andric << DeclSpec::getSpecifierName(getStorageClassSpec()) 13790b57cec5SDimitry Andric << SourceRange(getStorageClassSpecLoc()); 13800b57cec5SDimitry Andric // Discard the thread storage class specifier to recover. 13810b57cec5SDimitry Andric ThreadStorageClassSpec = TSCS_unspecified; 13820b57cec5SDimitry Andric ThreadStorageClassSpecLoc = SourceLocation(); 13830b57cec5SDimitry Andric } 1384*0fca6ea1SDimitry Andric if (S.getLangOpts().C23 && 1385*0fca6ea1SDimitry Andric getConstexprSpecifier() == ConstexprSpecKind::Constexpr) { 1386*0fca6ea1SDimitry Andric S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination) 1387*0fca6ea1SDimitry Andric << DeclSpec::getSpecifierName(getThreadStorageClassSpec()) 1388*0fca6ea1SDimitry Andric << SourceRange(getThreadStorageClassSpecLoc()); 1389*0fca6ea1SDimitry Andric } 1390*0fca6ea1SDimitry Andric } 1391*0fca6ea1SDimitry Andric 1392*0fca6ea1SDimitry Andric if (S.getLangOpts().C23 && 1393*0fca6ea1SDimitry Andric getConstexprSpecifier() == ConstexprSpecKind::Constexpr && 1394*0fca6ea1SDimitry Andric StorageClassSpec == SCS_extern) { 1395*0fca6ea1SDimitry Andric S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination) 1396*0fca6ea1SDimitry Andric << DeclSpec::getSpecifierName(getStorageClassSpec()) 1397*0fca6ea1SDimitry Andric << SourceRange(getStorageClassSpecLoc()); 13980b57cec5SDimitry Andric } 13990b57cec5SDimitry Andric 14000b57cec5SDimitry Andric // If no type specifier was provided and we're parsing a language where 14010b57cec5SDimitry Andric // the type specifier is not optional, but we got 'auto' as a storage 14020b57cec5SDimitry Andric // class specifier, then assume this is an attempt to use C++0x's 'auto' 14030b57cec5SDimitry Andric // type specifier. 14040b57cec5SDimitry Andric if (S.getLangOpts().CPlusPlus && 14050b57cec5SDimitry Andric TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) { 14060b57cec5SDimitry Andric TypeSpecType = TST_auto; 14070b57cec5SDimitry Andric StorageClassSpec = SCS_unspecified; 14080b57cec5SDimitry Andric TSTLoc = TSTNameLoc = StorageClassSpecLoc; 14090b57cec5SDimitry Andric StorageClassSpecLoc = SourceLocation(); 14100b57cec5SDimitry Andric } 14110b57cec5SDimitry Andric // Diagnose if we've recovered from an ill-formed 'auto' storage class 14125f757f3fSDimitry Andric // specifier in a pre-C++11 dialect of C++ or in a pre-C23 dialect of C. 14135f757f3fSDimitry Andric if (!S.getLangOpts().CPlusPlus11 && !S.getLangOpts().C23 && 14145f757f3fSDimitry Andric TypeSpecType == TST_auto) 14150b57cec5SDimitry Andric S.Diag(TSTLoc, diag::ext_auto_type_specifier); 14160b57cec5SDimitry Andric if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11 && 14170b57cec5SDimitry Andric StorageClassSpec == SCS_auto) 14180b57cec5SDimitry Andric S.Diag(StorageClassSpecLoc, diag::warn_auto_storage_class) 14190b57cec5SDimitry Andric << FixItHint::CreateRemoval(StorageClassSpecLoc); 14200b57cec5SDimitry Andric if (TypeSpecType == TST_char8) 14210b57cec5SDimitry Andric S.Diag(TSTLoc, diag::warn_cxx17_compat_unicode_type); 14220b57cec5SDimitry Andric else if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) 14230b57cec5SDimitry Andric S.Diag(TSTLoc, diag::warn_cxx98_compat_unicode_type) 14240b57cec5SDimitry Andric << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); 1425e8d8bef9SDimitry Andric if (getConstexprSpecifier() == ConstexprSpecKind::Constexpr) 14260b57cec5SDimitry Andric S.Diag(ConstexprLoc, diag::warn_cxx98_compat_constexpr); 1427e8d8bef9SDimitry Andric else if (getConstexprSpecifier() == ConstexprSpecKind::Consteval) 14280b57cec5SDimitry Andric S.Diag(ConstexprLoc, diag::warn_cxx20_compat_consteval); 1429e8d8bef9SDimitry Andric else if (getConstexprSpecifier() == ConstexprSpecKind::Constinit) 1430a7dea167SDimitry Andric S.Diag(ConstexprLoc, diag::warn_cxx20_compat_constinit); 14310b57cec5SDimitry Andric // C++ [class.friend]p6: 14320b57cec5SDimitry Andric // No storage-class-specifier shall appear in the decl-specifier-seq 14330b57cec5SDimitry Andric // of a friend declaration. 14340b57cec5SDimitry Andric if (isFriendSpecified() && 14350b57cec5SDimitry Andric (getStorageClassSpec() || getThreadStorageClassSpec())) { 14360b57cec5SDimitry Andric SmallString<32> SpecName; 14370b57cec5SDimitry Andric SourceLocation SCLoc; 14380b57cec5SDimitry Andric FixItHint StorageHint, ThreadHint; 14390b57cec5SDimitry Andric 14400b57cec5SDimitry Andric if (DeclSpec::SCS SC = getStorageClassSpec()) { 14410b57cec5SDimitry Andric SpecName = getSpecifierName(SC); 14420b57cec5SDimitry Andric SCLoc = getStorageClassSpecLoc(); 14430b57cec5SDimitry Andric StorageHint = FixItHint::CreateRemoval(SCLoc); 14440b57cec5SDimitry Andric } 14450b57cec5SDimitry Andric 14460b57cec5SDimitry Andric if (DeclSpec::TSCS TSC = getThreadStorageClassSpec()) { 14470b57cec5SDimitry Andric if (!SpecName.empty()) SpecName += " "; 14480b57cec5SDimitry Andric SpecName += getSpecifierName(TSC); 14490b57cec5SDimitry Andric SCLoc = getThreadStorageClassSpecLoc(); 14500b57cec5SDimitry Andric ThreadHint = FixItHint::CreateRemoval(SCLoc); 14510b57cec5SDimitry Andric } 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andric S.Diag(SCLoc, diag::err_friend_decl_spec) 14540b57cec5SDimitry Andric << SpecName << StorageHint << ThreadHint; 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric ClearStorageClassSpecs(); 14570b57cec5SDimitry Andric } 14580b57cec5SDimitry Andric 14590b57cec5SDimitry Andric // C++11 [dcl.fct.spec]p5: 14600b57cec5SDimitry Andric // The virtual specifier shall be used only in the initial 14610b57cec5SDimitry Andric // declaration of a non-static class member function; 14620b57cec5SDimitry Andric // C++11 [dcl.fct.spec]p6: 14630b57cec5SDimitry Andric // The explicit specifier shall be used only in the declaration of 14640b57cec5SDimitry Andric // a constructor or conversion function within its class 14650b57cec5SDimitry Andric // definition; 14660b57cec5SDimitry Andric if (isFriendSpecified() && (isVirtualSpecified() || hasExplicitSpecifier())) { 14670b57cec5SDimitry Andric StringRef Keyword; 14680b57cec5SDimitry Andric FixItHint Hint; 14690b57cec5SDimitry Andric SourceLocation SCLoc; 14700b57cec5SDimitry Andric 14710b57cec5SDimitry Andric if (isVirtualSpecified()) { 14720b57cec5SDimitry Andric Keyword = "virtual"; 14730b57cec5SDimitry Andric SCLoc = getVirtualSpecLoc(); 14740b57cec5SDimitry Andric Hint = FixItHint::CreateRemoval(SCLoc); 14750b57cec5SDimitry Andric } else { 14760b57cec5SDimitry Andric Keyword = "explicit"; 14770b57cec5SDimitry Andric SCLoc = getExplicitSpecLoc(); 14780b57cec5SDimitry Andric Hint = FixItHint::CreateRemoval(getExplicitSpecRange()); 14790b57cec5SDimitry Andric } 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andric S.Diag(SCLoc, diag::err_friend_decl_spec) 14820b57cec5SDimitry Andric << Keyword << Hint; 14830b57cec5SDimitry Andric 14840b57cec5SDimitry Andric FS_virtual_specified = false; 14850b57cec5SDimitry Andric FS_explicit_specifier = ExplicitSpecifier(); 14860b57cec5SDimitry Andric FS_virtualLoc = FS_explicitLoc = SourceLocation(); 14870b57cec5SDimitry Andric } 14880b57cec5SDimitry Andric 14890b57cec5SDimitry Andric assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType)); 14900b57cec5SDimitry Andric 14910b57cec5SDimitry Andric // Okay, now we can infer the real type. 14920b57cec5SDimitry Andric 14930b57cec5SDimitry Andric // TODO: return "auto function" and other bad things based on the real type. 14940b57cec5SDimitry Andric 14950b57cec5SDimitry Andric // 'data definition has no type or storage class'? 14960b57cec5SDimitry Andric } 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andric bool DeclSpec::isMissingDeclaratorOk() { 14990b57cec5SDimitry Andric TST tst = getTypeSpecType(); 15000b57cec5SDimitry Andric return isDeclRep(tst) && getRepAsDecl() != nullptr && 15010b57cec5SDimitry Andric StorageClassSpec != DeclSpec::SCS_typedef; 15020b57cec5SDimitry Andric } 15030b57cec5SDimitry Andric 15040b57cec5SDimitry Andric void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 15050b57cec5SDimitry Andric OverloadedOperatorKind Op, 15060b57cec5SDimitry Andric SourceLocation SymbolLocations[3]) { 15070b57cec5SDimitry Andric Kind = UnqualifiedIdKind::IK_OperatorFunctionId; 15080b57cec5SDimitry Andric StartLocation = OperatorLoc; 15090b57cec5SDimitry Andric EndLocation = OperatorLoc; 1510e8d8bef9SDimitry Andric new (&OperatorFunctionId) struct OFI; 15110b57cec5SDimitry Andric OperatorFunctionId.Operator = Op; 15120b57cec5SDimitry Andric for (unsigned I = 0; I != 3; ++I) { 1513e8d8bef9SDimitry Andric OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I]; 15140b57cec5SDimitry Andric 15150b57cec5SDimitry Andric if (SymbolLocations[I].isValid()) 15160b57cec5SDimitry Andric EndLocation = SymbolLocations[I]; 15170b57cec5SDimitry Andric } 15180b57cec5SDimitry Andric } 15190b57cec5SDimitry Andric 15200b57cec5SDimitry Andric bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, 15210b57cec5SDimitry Andric const char *&PrevSpec) { 15220b57cec5SDimitry Andric if (!FirstLocation.isValid()) 15230b57cec5SDimitry Andric FirstLocation = Loc; 15240b57cec5SDimitry Andric LastLocation = Loc; 15250b57cec5SDimitry Andric LastSpecifier = VS; 15260b57cec5SDimitry Andric 15270b57cec5SDimitry Andric if (Specifiers & VS) { 15280b57cec5SDimitry Andric PrevSpec = getSpecifierName(VS); 15290b57cec5SDimitry Andric return true; 15300b57cec5SDimitry Andric } 15310b57cec5SDimitry Andric 15320b57cec5SDimitry Andric Specifiers |= VS; 15330b57cec5SDimitry Andric 15340b57cec5SDimitry Andric switch (VS) { 15350b57cec5SDimitry Andric default: llvm_unreachable("Unknown specifier!"); 15360b57cec5SDimitry Andric case VS_Override: VS_overrideLoc = Loc; break; 15370b57cec5SDimitry Andric case VS_GNU_Final: 15380b57cec5SDimitry Andric case VS_Sealed: 15390b57cec5SDimitry Andric case VS_Final: VS_finalLoc = Loc; break; 1540fe6060f1SDimitry Andric case VS_Abstract: VS_abstractLoc = Loc; break; 15410b57cec5SDimitry Andric } 15420b57cec5SDimitry Andric 15430b57cec5SDimitry Andric return false; 15440b57cec5SDimitry Andric } 15450b57cec5SDimitry Andric 15460b57cec5SDimitry Andric const char *VirtSpecifiers::getSpecifierName(Specifier VS) { 15470b57cec5SDimitry Andric switch (VS) { 15480b57cec5SDimitry Andric default: llvm_unreachable("Unknown specifier"); 15490b57cec5SDimitry Andric case VS_Override: return "override"; 15500b57cec5SDimitry Andric case VS_Final: return "final"; 15510b57cec5SDimitry Andric case VS_GNU_Final: return "__final"; 15520b57cec5SDimitry Andric case VS_Sealed: return "sealed"; 1553fe6060f1SDimitry Andric case VS_Abstract: return "abstract"; 15540b57cec5SDimitry Andric } 15550b57cec5SDimitry Andric } 1556