1212795Sdim//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===// 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim// 8212795Sdim//===----------------------------------------------------------------------===// 9212795Sdim// 10212795Sdim// This file implements semantic analysis for declaration specifiers. 11212795Sdim// 12212795Sdim//===----------------------------------------------------------------------===// 13212795Sdim 14212795Sdim#include "clang/Sema/DeclSpec.h" 15219077Sdim#include "clang/AST/ASTContext.h" 16263508Sdim#include "clang/AST/DeclCXX.h" 17224145Sdim#include "clang/AST/Expr.h" 18219077Sdim#include "clang/AST/NestedNameSpecifier.h" 19219077Sdim#include "clang/AST/TypeLoc.h" 20249423Sdim#include "clang/Basic/LangOptions.h" 21212795Sdim#include "clang/Lex/Preprocessor.h" 22249423Sdim#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency! 23249423Sdim#include "clang/Sema/LocInfoType.h" 24249423Sdim#include "clang/Sema/ParsedTemplate.h" 25249423Sdim#include "clang/Sema/Sema.h" 26249423Sdim#include "clang/Sema/SemaDiagnostic.h" 27212795Sdim#include "llvm/ADT/STLExtras.h" 28251662Sdim#include "llvm/ADT/SmallString.h" 29212795Sdim#include "llvm/Support/ErrorHandling.h" 30212795Sdim#include <cstring> 31212795Sdimusing namespace clang; 32212795Sdim 33212795Sdim 34226633Sdimstatic DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc, 35218893Sdim unsigned DiagID) { 36218893Sdim return D.Report(Loc, DiagID); 37212795Sdim} 38212795Sdim 39212795Sdim 40212795Sdimvoid UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { 41212795Sdim assert(TemplateId && "NULL template-id annotation?"); 42212795Sdim Kind = IK_TemplateId; 43212795Sdim this->TemplateId = TemplateId; 44212795Sdim StartLocation = TemplateId->TemplateNameLoc; 45212795Sdim EndLocation = TemplateId->RAngleLoc; 46212795Sdim} 47212795Sdim 48212795Sdimvoid UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { 49212795Sdim assert(TemplateId && "NULL template-id annotation?"); 50212795Sdim Kind = IK_ConstructorTemplateId; 51212795Sdim this->TemplateId = TemplateId; 52212795Sdim StartLocation = TemplateId->TemplateNameLoc; 53212795Sdim EndLocation = TemplateId->RAngleLoc; 54212795Sdim} 55212795Sdim 56219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc, 57219077Sdim TypeLoc TL, SourceLocation ColonColonLoc) { 58221345Sdim Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc); 59219077Sdim if (Range.getBegin().isInvalid()) 60219077Sdim Range.setBegin(TL.getBeginLoc()); 61219077Sdim Range.setEnd(ColonColonLoc); 62219077Sdim 63221345Sdim assert(Range == Builder.getSourceRange() && 64219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 65219077Sdim} 66219077Sdim 67219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier, 68219077Sdim SourceLocation IdentifierLoc, 69219077Sdim SourceLocation ColonColonLoc) { 70221345Sdim Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc); 71221345Sdim 72219077Sdim if (Range.getBegin().isInvalid()) 73219077Sdim Range.setBegin(IdentifierLoc); 74219077Sdim Range.setEnd(ColonColonLoc); 75219077Sdim 76221345Sdim assert(Range == Builder.getSourceRange() && 77219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 78219077Sdim} 79219077Sdim 80219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace, 81219077Sdim SourceLocation NamespaceLoc, 82219077Sdim SourceLocation ColonColonLoc) { 83221345Sdim Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc); 84221345Sdim 85219077Sdim if (Range.getBegin().isInvalid()) 86219077Sdim Range.setBegin(NamespaceLoc); 87219077Sdim Range.setEnd(ColonColonLoc); 88219077Sdim 89221345Sdim assert(Range == Builder.getSourceRange() && 90219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 91219077Sdim} 92219077Sdim 93219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 94219077Sdim SourceLocation AliasLoc, 95219077Sdim SourceLocation ColonColonLoc) { 96221345Sdim Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc); 97221345Sdim 98219077Sdim if (Range.getBegin().isInvalid()) 99219077Sdim Range.setBegin(AliasLoc); 100219077Sdim Range.setEnd(ColonColonLoc); 101219077Sdim 102221345Sdim assert(Range == Builder.getSourceRange() && 103219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 104219077Sdim} 105219077Sdim 106219077Sdimvoid CXXScopeSpec::MakeGlobal(ASTContext &Context, 107219077Sdim SourceLocation ColonColonLoc) { 108221345Sdim Builder.MakeGlobal(Context, ColonColonLoc); 109221345Sdim 110219077Sdim Range = SourceRange(ColonColonLoc); 111219077Sdim 112221345Sdim assert(Range == Builder.getSourceRange() && 113219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 114219077Sdim} 115219077Sdim 116219077Sdimvoid CXXScopeSpec::MakeTrivial(ASTContext &Context, 117219077Sdim NestedNameSpecifier *Qualifier, SourceRange R) { 118221345Sdim Builder.MakeTrivial(Context, Qualifier, R); 119219077Sdim Range = R; 120219077Sdim} 121219077Sdim 122219077Sdimvoid CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) { 123219077Sdim if (!Other) { 124219077Sdim Range = SourceRange(); 125221345Sdim Builder.Clear(); 126219077Sdim return; 127219077Sdim } 128221345Sdim 129219077Sdim Range = Other.getSourceRange(); 130221345Sdim Builder.Adopt(Other); 131219077Sdim} 132219077Sdim 133224145SdimSourceLocation CXXScopeSpec::getLastQualifierNameLoc() const { 134224145Sdim if (!Builder.getRepresentation()) 135224145Sdim return SourceLocation(); 136224145Sdim return Builder.getTemporary().getLocalBeginLoc(); 137224145Sdim} 138224145Sdim 139219077SdimNestedNameSpecifierLoc 140219077SdimCXXScopeSpec::getWithLocInContext(ASTContext &Context) const { 141221345Sdim if (!Builder.getRepresentation()) 142219077Sdim return NestedNameSpecifierLoc(); 143219077Sdim 144221345Sdim return Builder.getWithLocInContext(Context); 145219077Sdim} 146219077Sdim 147212795Sdim/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. 148212795Sdim/// "TheDeclarator" is the declarator that this will be added to. 149243830SdimDeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, 150239462Sdim bool isAmbiguous, 151243830Sdim SourceLocation LParenLoc, 152212795Sdim ParamInfo *ArgInfo, 153212795Sdim unsigned NumArgs, 154243830Sdim SourceLocation EllipsisLoc, 155243830Sdim SourceLocation RParenLoc, 156212795Sdim unsigned TypeQuals, 157218893Sdim bool RefQualifierIsLvalueRef, 158218893Sdim SourceLocation RefQualifierLoc, 159234353Sdim SourceLocation ConstQualifierLoc, 160234353Sdim SourceLocation 161234353Sdim VolatileQualifierLoc, 162224145Sdim SourceLocation MutableLoc, 163221345Sdim ExceptionSpecificationType 164221345Sdim ESpecType, 165221345Sdim SourceLocation ESpecLoc, 166212795Sdim ParsedType *Exceptions, 167212795Sdim SourceRange *ExceptionRanges, 168212795Sdim unsigned NumExceptions, 169221345Sdim Expr *NoexceptExpr, 170221345Sdim SourceLocation LocalRangeBegin, 171221345Sdim SourceLocation LocalRangeEnd, 172218893Sdim Declarator &TheDeclarator, 173239462Sdim TypeResult TrailingReturnType) { 174249423Sdim assert(!(TypeQuals & DeclSpec::TQ_atomic) && 175249423Sdim "function cannot have _Atomic qualifier"); 176249423Sdim 177212795Sdim DeclaratorChunk I; 178221345Sdim I.Kind = Function; 179221345Sdim I.Loc = LocalRangeBegin; 180221345Sdim I.EndLoc = LocalRangeEnd; 181221345Sdim I.Fun.AttrList = 0; 182221345Sdim I.Fun.hasPrototype = hasProto; 183243830Sdim I.Fun.isVariadic = EllipsisLoc.isValid(); 184239462Sdim I.Fun.isAmbiguous = isAmbiguous; 185243830Sdim I.Fun.LParenLoc = LParenLoc.getRawEncoding(); 186221345Sdim I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); 187243830Sdim I.Fun.RParenLoc = RParenLoc.getRawEncoding(); 188221345Sdim I.Fun.DeleteArgInfo = false; 189221345Sdim I.Fun.TypeQuals = TypeQuals; 190221345Sdim I.Fun.NumArgs = NumArgs; 191221345Sdim I.Fun.ArgInfo = 0; 192218893Sdim I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; 193221345Sdim I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); 194234353Sdim I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding(); 195234353Sdim I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding(); 196224145Sdim I.Fun.MutableLoc = MutableLoc.getRawEncoding(); 197221345Sdim I.Fun.ExceptionSpecType = ESpecType; 198221345Sdim I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); 199221345Sdim I.Fun.NumExceptions = 0; 200221345Sdim I.Fun.Exceptions = 0; 201221345Sdim I.Fun.NoexceptExpr = 0; 202239462Sdim I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() || 203239462Sdim TrailingReturnType.isInvalid(); 204239462Sdim I.Fun.TrailingReturnType = TrailingReturnType.get(); 205212795Sdim 206212795Sdim // new[] an argument array if needed. 207212795Sdim if (NumArgs) { 208212795Sdim // If the 'InlineParams' in Declarator is unused and big enough, put our 209212795Sdim // parameter list there (in an effort to avoid new/delete traffic). If it 210212795Sdim // is already used (consider a function returning a function pointer) or too 211212795Sdim // small (function taking too many arguments), go to the heap. 212212795Sdim if (!TheDeclarator.InlineParamsUsed && 213212795Sdim NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) { 214212795Sdim I.Fun.ArgInfo = TheDeclarator.InlineParams; 215212795Sdim I.Fun.DeleteArgInfo = false; 216212795Sdim TheDeclarator.InlineParamsUsed = true; 217212795Sdim } else { 218212795Sdim I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs]; 219212795Sdim I.Fun.DeleteArgInfo = true; 220212795Sdim } 221212795Sdim memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs); 222212795Sdim } 223221345Sdim 224221345Sdim // Check what exception specification information we should actually store. 225221345Sdim switch (ESpecType) { 226221345Sdim default: break; // By default, save nothing. 227221345Sdim case EST_Dynamic: 228221345Sdim // new[] an exception array if needed 229221345Sdim if (NumExceptions) { 230221345Sdim I.Fun.NumExceptions = NumExceptions; 231221345Sdim I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions]; 232221345Sdim for (unsigned i = 0; i != NumExceptions; ++i) { 233221345Sdim I.Fun.Exceptions[i].Ty = Exceptions[i]; 234221345Sdim I.Fun.Exceptions[i].Range = ExceptionRanges[i]; 235221345Sdim } 236212795Sdim } 237221345Sdim break; 238221345Sdim 239221345Sdim case EST_ComputedNoexcept: 240221345Sdim I.Fun.NoexceptExpr = NoexceptExpr; 241221345Sdim break; 242212795Sdim } 243212795Sdim return I; 244212795Sdim} 245212795Sdim 246224145Sdimbool Declarator::isDeclarationOfFunction() const { 247224145Sdim for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { 248224145Sdim switch (DeclTypeInfo[i].Kind) { 249224145Sdim case DeclaratorChunk::Function: 250224145Sdim return true; 251224145Sdim case DeclaratorChunk::Paren: 252224145Sdim continue; 253224145Sdim case DeclaratorChunk::Pointer: 254224145Sdim case DeclaratorChunk::Reference: 255224145Sdim case DeclaratorChunk::Array: 256224145Sdim case DeclaratorChunk::BlockPointer: 257224145Sdim case DeclaratorChunk::MemberPointer: 258224145Sdim return false; 259224145Sdim } 260224145Sdim llvm_unreachable("Invalid type chunk"); 261224145Sdim } 262224145Sdim 263224145Sdim switch (DS.getTypeSpecType()) { 264226633Sdim case TST_atomic: 265224145Sdim case TST_auto: 266224145Sdim case TST_bool: 267224145Sdim case TST_char: 268224145Sdim case TST_char16: 269224145Sdim case TST_char32: 270224145Sdim case TST_class: 271224145Sdim case TST_decimal128: 272224145Sdim case TST_decimal32: 273224145Sdim case TST_decimal64: 274224145Sdim case TST_double: 275224145Sdim case TST_enum: 276224145Sdim case TST_error: 277224145Sdim case TST_float: 278226633Sdim case TST_half: 279224145Sdim case TST_int: 280234353Sdim case TST_int128: 281224145Sdim case TST_struct: 282243830Sdim case TST_interface: 283224145Sdim case TST_union: 284224145Sdim case TST_unknown_anytype: 285224145Sdim case TST_unspecified: 286224145Sdim case TST_void: 287224145Sdim case TST_wchar: 288249423Sdim case TST_image1d_t: 289249423Sdim case TST_image1d_array_t: 290249423Sdim case TST_image1d_buffer_t: 291249423Sdim case TST_image2d_t: 292249423Sdim case TST_image2d_array_t: 293249423Sdim case TST_image3d_t: 294249423Sdim case TST_sampler_t: 295249423Sdim case TST_event_t: 296224145Sdim return false; 297224145Sdim 298251662Sdim case TST_decltype_auto: 299251662Sdim // This must have an initializer, so can't be a function declaration, 300251662Sdim // even if the initializer has function type. 301251662Sdim return false; 302251662Sdim 303224145Sdim case TST_decltype: 304224145Sdim case TST_typeofExpr: 305224145Sdim if (Expr *E = DS.getRepAsExpr()) 306224145Sdim return E->getType()->isFunctionType(); 307224145Sdim return false; 308224145Sdim 309224145Sdim case TST_underlyingType: 310224145Sdim case TST_typename: 311224145Sdim case TST_typeofType: { 312224145Sdim QualType QT = DS.getRepAsType().get(); 313224145Sdim if (QT.isNull()) 314224145Sdim return false; 315224145Sdim 316224145Sdim if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) 317224145Sdim QT = LIT->getType(); 318224145Sdim 319224145Sdim if (QT.isNull()) 320224145Sdim return false; 321224145Sdim 322224145Sdim return QT->isFunctionType(); 323224145Sdim } 324224145Sdim } 325234353Sdim 326234353Sdim llvm_unreachable("Invalid TypeSpecType!"); 327224145Sdim} 328224145Sdim 329263508Sdimbool Declarator::isStaticMember() { 330263508Sdim assert(getContext() == MemberContext); 331263508Sdim return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || 332263508Sdim CXXMethodDecl::isStaticOverloadedOperator( 333263508Sdim getName().OperatorFunctionId.Operator); 334263508Sdim} 335263508Sdim 336263508Sdimbool DeclSpec::hasTagDefinition() const { 337263508Sdim if (!TypeSpecOwned) 338263508Sdim return false; 339263508Sdim return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition(); 340263508Sdim} 341263508Sdim 342212795Sdim/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this 343212795Sdim/// declaration specifier includes. 344212795Sdim/// 345212795Sdimunsigned DeclSpec::getParsedSpecifiers() const { 346212795Sdim unsigned Res = 0; 347212795Sdim if (StorageClassSpec != SCS_unspecified || 348251662Sdim ThreadStorageClassSpec != TSCS_unspecified) 349212795Sdim Res |= PQ_StorageClassSpecifier; 350212795Sdim 351212795Sdim if (TypeQualifiers != TQ_unspecified) 352212795Sdim Res |= PQ_TypeQualifier; 353212795Sdim 354212795Sdim if (hasTypeSpecifier()) 355212795Sdim Res |= PQ_TypeSpecifier; 356212795Sdim 357249423Sdim if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified || 358263508Sdim FS_noreturn_specified || FS_forceinline_specified) 359212795Sdim Res |= PQ_FunctionSpecifier; 360212795Sdim return Res; 361212795Sdim} 362212795Sdim 363212795Sdimtemplate <class T> static bool BadSpecifier(T TNew, T TPrev, 364212795Sdim const char *&PrevSpec, 365243830Sdim unsigned &DiagID, 366243830Sdim bool IsExtension = true) { 367212795Sdim PrevSpec = DeclSpec::getSpecifierName(TPrev); 368243830Sdim if (TNew != TPrev) 369243830Sdim DiagID = diag::err_invalid_decl_spec_combination; 370243830Sdim else 371243830Sdim DiagID = IsExtension ? diag::ext_duplicate_declspec : 372243830Sdim diag::warn_duplicate_declspec; 373212795Sdim return true; 374212795Sdim} 375212795Sdim 376212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::SCS S) { 377212795Sdim switch (S) { 378212795Sdim case DeclSpec::SCS_unspecified: return "unspecified"; 379212795Sdim case DeclSpec::SCS_typedef: return "typedef"; 380212795Sdim case DeclSpec::SCS_extern: return "extern"; 381212795Sdim case DeclSpec::SCS_static: return "static"; 382212795Sdim case DeclSpec::SCS_auto: return "auto"; 383212795Sdim case DeclSpec::SCS_register: return "register"; 384212795Sdim case DeclSpec::SCS_private_extern: return "__private_extern__"; 385212795Sdim case DeclSpec::SCS_mutable: return "mutable"; 386212795Sdim } 387212795Sdim llvm_unreachable("Unknown typespec!"); 388212795Sdim} 389212795Sdim 390251662Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) { 391251662Sdim switch (S) { 392251662Sdim case DeclSpec::TSCS_unspecified: return "unspecified"; 393251662Sdim case DeclSpec::TSCS___thread: return "__thread"; 394251662Sdim case DeclSpec::TSCS_thread_local: return "thread_local"; 395251662Sdim case DeclSpec::TSCS__Thread_local: return "_Thread_local"; 396251662Sdim } 397251662Sdim llvm_unreachable("Unknown typespec!"); 398251662Sdim} 399251662Sdim 400212795Sdimconst char *DeclSpec::getSpecifierName(TSW W) { 401212795Sdim switch (W) { 402212795Sdim case TSW_unspecified: return "unspecified"; 403212795Sdim case TSW_short: return "short"; 404212795Sdim case TSW_long: return "long"; 405212795Sdim case TSW_longlong: return "long long"; 406212795Sdim } 407212795Sdim llvm_unreachable("Unknown typespec!"); 408212795Sdim} 409212795Sdim 410212795Sdimconst char *DeclSpec::getSpecifierName(TSC C) { 411212795Sdim switch (C) { 412212795Sdim case TSC_unspecified: return "unspecified"; 413212795Sdim case TSC_imaginary: return "imaginary"; 414212795Sdim case TSC_complex: return "complex"; 415212795Sdim } 416212795Sdim llvm_unreachable("Unknown typespec!"); 417212795Sdim} 418212795Sdim 419212795Sdim 420212795Sdimconst char *DeclSpec::getSpecifierName(TSS S) { 421212795Sdim switch (S) { 422212795Sdim case TSS_unspecified: return "unspecified"; 423212795Sdim case TSS_signed: return "signed"; 424212795Sdim case TSS_unsigned: return "unsigned"; 425212795Sdim } 426212795Sdim llvm_unreachable("Unknown typespec!"); 427212795Sdim} 428212795Sdim 429212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::TST T) { 430212795Sdim switch (T) { 431212795Sdim case DeclSpec::TST_unspecified: return "unspecified"; 432212795Sdim case DeclSpec::TST_void: return "void"; 433212795Sdim case DeclSpec::TST_char: return "char"; 434212795Sdim case DeclSpec::TST_wchar: return "wchar_t"; 435212795Sdim case DeclSpec::TST_char16: return "char16_t"; 436212795Sdim case DeclSpec::TST_char32: return "char32_t"; 437212795Sdim case DeclSpec::TST_int: return "int"; 438234353Sdim case DeclSpec::TST_int128: return "__int128"; 439226633Sdim case DeclSpec::TST_half: return "half"; 440212795Sdim case DeclSpec::TST_float: return "float"; 441212795Sdim case DeclSpec::TST_double: return "double"; 442212795Sdim case DeclSpec::TST_bool: return "_Bool"; 443212795Sdim case DeclSpec::TST_decimal32: return "_Decimal32"; 444212795Sdim case DeclSpec::TST_decimal64: return "_Decimal64"; 445212795Sdim case DeclSpec::TST_decimal128: return "_Decimal128"; 446212795Sdim case DeclSpec::TST_enum: return "enum"; 447212795Sdim case DeclSpec::TST_class: return "class"; 448212795Sdim case DeclSpec::TST_union: return "union"; 449212795Sdim case DeclSpec::TST_struct: return "struct"; 450243830Sdim case DeclSpec::TST_interface: return "__interface"; 451212795Sdim case DeclSpec::TST_typename: return "type-name"; 452212795Sdim case DeclSpec::TST_typeofType: 453212795Sdim case DeclSpec::TST_typeofExpr: return "typeof"; 454212795Sdim case DeclSpec::TST_auto: return "auto"; 455212795Sdim case DeclSpec::TST_decltype: return "(decltype)"; 456251662Sdim case DeclSpec::TST_decltype_auto: return "decltype(auto)"; 457223017Sdim case DeclSpec::TST_underlyingType: return "__underlying_type"; 458221345Sdim case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; 459226633Sdim case DeclSpec::TST_atomic: return "_Atomic"; 460249423Sdim case DeclSpec::TST_image1d_t: return "image1d_t"; 461249423Sdim case DeclSpec::TST_image1d_array_t: return "image1d_array_t"; 462249423Sdim case DeclSpec::TST_image1d_buffer_t: return "image1d_buffer_t"; 463249423Sdim case DeclSpec::TST_image2d_t: return "image2d_t"; 464249423Sdim case DeclSpec::TST_image2d_array_t: return "image2d_array_t"; 465249423Sdim case DeclSpec::TST_image3d_t: return "image3d_t"; 466249423Sdim case DeclSpec::TST_sampler_t: return "sampler_t"; 467249423Sdim case DeclSpec::TST_event_t: return "event_t"; 468212795Sdim case DeclSpec::TST_error: return "(error)"; 469212795Sdim } 470212795Sdim llvm_unreachable("Unknown typespec!"); 471212795Sdim} 472212795Sdim 473212795Sdimconst char *DeclSpec::getSpecifierName(TQ T) { 474212795Sdim switch (T) { 475212795Sdim case DeclSpec::TQ_unspecified: return "unspecified"; 476212795Sdim case DeclSpec::TQ_const: return "const"; 477212795Sdim case DeclSpec::TQ_restrict: return "restrict"; 478212795Sdim case DeclSpec::TQ_volatile: return "volatile"; 479249423Sdim case DeclSpec::TQ_atomic: return "_Atomic"; 480212795Sdim } 481212795Sdim llvm_unreachable("Unknown typespec!"); 482212795Sdim} 483212795Sdim 484226633Sdimbool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, 485212795Sdim const char *&PrevSpec, 486226633Sdim unsigned &DiagID) { 487239462Sdim // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class 488239462Sdim // specifiers are not supported. 489218893Sdim // It seems sensible to prohibit private_extern too 490226633Sdim // The cl_clang_storage_class_specifiers extension enables support for 491226633Sdim // these storage-class specifiers. 492239462Sdim // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class 493239462Sdim // specifiers are not supported." 494234353Sdim if (S.getLangOpts().OpenCL && 495226633Sdim !S.getOpenCLOptions().cl_clang_storage_class_specifiers) { 496226633Sdim switch (SC) { 497218893Sdim case SCS_extern: 498218893Sdim case SCS_private_extern: 499239462Sdim case SCS_static: 500239462Sdim if (S.getLangOpts().OpenCLVersion < 120) { 501239462Sdim DiagID = diag::err_not_opencl_storage_class_specifier; 502239462Sdim PrevSpec = getSpecifierName(SC); 503239462Sdim return true; 504239462Sdim } 505239462Sdim break; 506218893Sdim case SCS_auto: 507218893Sdim case SCS_register: 508218893Sdim DiagID = diag::err_not_opencl_storage_class_specifier; 509226633Sdim PrevSpec = getSpecifierName(SC); 510218893Sdim return true; 511218893Sdim default: 512218893Sdim break; 513218893Sdim } 514218893Sdim } 515218893Sdim 516212795Sdim if (StorageClassSpec != SCS_unspecified) { 517251662Sdim // Maybe this is an attempt to use C++11 'auto' outside of C++11 mode. 518226633Sdim bool isInvalid = true; 519234353Sdim if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) { 520226633Sdim if (SC == SCS_auto) 521226633Sdim return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID); 522226633Sdim if (StorageClassSpec == SCS_auto) { 523226633Sdim isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc, 524226633Sdim PrevSpec, DiagID); 525226633Sdim assert(!isInvalid && "auto SCS -> TST recovery failed"); 526226633Sdim } 527226633Sdim } 528226633Sdim 529212795Sdim // Changing storage class is allowed only if the previous one 530212795Sdim // was the 'extern' that is part of a linkage specification and 531212795Sdim // the new storage class is 'typedef'. 532226633Sdim if (isInvalid && 533226633Sdim !(SCS_extern_in_linkage_spec && 534212795Sdim StorageClassSpec == SCS_extern && 535226633Sdim SC == SCS_typedef)) 536226633Sdim return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID); 537212795Sdim } 538226633Sdim StorageClassSpec = SC; 539212795Sdim StorageClassSpecLoc = Loc; 540226633Sdim assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield"); 541212795Sdim return false; 542212795Sdim} 543212795Sdim 544251662Sdimbool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, 545212795Sdim const char *&PrevSpec, 546212795Sdim unsigned &DiagID) { 547251662Sdim if (ThreadStorageClassSpec != TSCS_unspecified) 548251662Sdim return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID); 549251662Sdim 550251662Sdim ThreadStorageClassSpec = TSC; 551251662Sdim ThreadStorageClassSpecLoc = Loc; 552212795Sdim return false; 553212795Sdim} 554212795Sdim 555212795Sdim/// These methods set the specified attribute of the DeclSpec, but return true 556212795Sdim/// and ignore the request if invalid (e.g. "extern" then "auto" is 557212795Sdim/// specified). 558212795Sdimbool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, 559212795Sdim const char *&PrevSpec, 560212795Sdim unsigned &DiagID) { 561221345Sdim // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that 562221345Sdim // for 'long long' we will keep the source location of the first 'long'. 563221345Sdim if (TypeSpecWidth == TSW_unspecified) 564221345Sdim TSWLoc = Loc; 565221345Sdim // Allow turning long -> long long. 566221345Sdim else if (W != TSW_longlong || TypeSpecWidth != TSW_long) 567212795Sdim return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); 568212795Sdim TypeSpecWidth = W; 569212795Sdim if (TypeAltiVecVector && !TypeAltiVecBool && 570212795Sdim ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { 571212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 572212795Sdim DiagID = diag::warn_vector_long_decl_spec_combination; 573212795Sdim return true; 574212795Sdim } 575212795Sdim return false; 576212795Sdim} 577212795Sdim 578212795Sdimbool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, 579212795Sdim const char *&PrevSpec, 580212795Sdim unsigned &DiagID) { 581212795Sdim if (TypeSpecComplex != TSC_unspecified) 582212795Sdim return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); 583212795Sdim TypeSpecComplex = C; 584212795Sdim TSCLoc = Loc; 585212795Sdim return false; 586212795Sdim} 587212795Sdim 588212795Sdimbool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, 589212795Sdim const char *&PrevSpec, 590212795Sdim unsigned &DiagID) { 591212795Sdim if (TypeSpecSign != TSS_unspecified) 592212795Sdim return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); 593212795Sdim TypeSpecSign = S; 594212795Sdim TSSLoc = Loc; 595212795Sdim return false; 596212795Sdim} 597212795Sdim 598212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 599212795Sdim const char *&PrevSpec, 600212795Sdim unsigned &DiagID, 601212795Sdim ParsedType Rep) { 602221345Sdim return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep); 603221345Sdim} 604221345Sdim 605221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 606221345Sdim SourceLocation TagNameLoc, 607221345Sdim const char *&PrevSpec, 608221345Sdim unsigned &DiagID, 609221345Sdim ParsedType Rep) { 610212795Sdim assert(isTypeRep(T) && "T does not store a type"); 611212795Sdim assert(Rep && "no type provided!"); 612212795Sdim if (TypeSpecType != TST_unspecified) { 613212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 614212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 615212795Sdim return true; 616212795Sdim } 617212795Sdim TypeSpecType = T; 618212795Sdim TypeRep = Rep; 619221345Sdim TSTLoc = TagKwLoc; 620221345Sdim TSTNameLoc = TagNameLoc; 621212795Sdim TypeSpecOwned = false; 622212795Sdim return false; 623212795Sdim} 624212795Sdim 625212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 626212795Sdim const char *&PrevSpec, 627212795Sdim unsigned &DiagID, 628212795Sdim Expr *Rep) { 629212795Sdim assert(isExprRep(T) && "T does not store an expr"); 630212795Sdim assert(Rep && "no expression provided!"); 631212795Sdim if (TypeSpecType != TST_unspecified) { 632212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 633212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 634212795Sdim return true; 635212795Sdim } 636212795Sdim TypeSpecType = T; 637212795Sdim ExprRep = Rep; 638212795Sdim TSTLoc = Loc; 639221345Sdim TSTNameLoc = Loc; 640212795Sdim TypeSpecOwned = false; 641212795Sdim return false; 642212795Sdim} 643212795Sdim 644212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 645212795Sdim const char *&PrevSpec, 646212795Sdim unsigned &DiagID, 647212795Sdim Decl *Rep, bool Owned) { 648221345Sdim return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned); 649221345Sdim} 650221345Sdim 651221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 652221345Sdim SourceLocation TagNameLoc, 653221345Sdim const char *&PrevSpec, 654221345Sdim unsigned &DiagID, 655221345Sdim Decl *Rep, bool Owned) { 656212795Sdim assert(isDeclRep(T) && "T does not store a decl"); 657212795Sdim // Unlike the other cases, we don't assert that we actually get a decl. 658212795Sdim 659212795Sdim if (TypeSpecType != TST_unspecified) { 660212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 661212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 662212795Sdim return true; 663212795Sdim } 664212795Sdim TypeSpecType = T; 665212795Sdim DeclRep = Rep; 666221345Sdim TSTLoc = TagKwLoc; 667221345Sdim TSTNameLoc = TagNameLoc; 668263508Sdim TypeSpecOwned = Owned && Rep != 0; 669212795Sdim return false; 670212795Sdim} 671212795Sdim 672212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 673212795Sdim const char *&PrevSpec, 674212795Sdim unsigned &DiagID) { 675212795Sdim assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && 676212795Sdim "rep required for these type-spec kinds!"); 677212795Sdim if (TypeSpecType != TST_unspecified) { 678212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 679212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 680212795Sdim return true; 681212795Sdim } 682221345Sdim TSTLoc = Loc; 683221345Sdim TSTNameLoc = Loc; 684212795Sdim if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { 685212795Sdim TypeAltiVecBool = true; 686212795Sdim return false; 687212795Sdim } 688212795Sdim TypeSpecType = T; 689212795Sdim TypeSpecOwned = false; 690212795Sdim if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { 691212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 692212795Sdim DiagID = diag::err_invalid_vector_decl_spec; 693212795Sdim return true; 694212795Sdim } 695212795Sdim return false; 696212795Sdim} 697212795Sdim 698212795Sdimbool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 699212795Sdim const char *&PrevSpec, unsigned &DiagID) { 700212795Sdim if (TypeSpecType != TST_unspecified) { 701212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 702212795Sdim DiagID = diag::err_invalid_vector_decl_spec_combination; 703212795Sdim return true; 704212795Sdim } 705212795Sdim TypeAltiVecVector = isAltiVecVector; 706212795Sdim AltiVecLoc = Loc; 707212795Sdim return false; 708212795Sdim} 709212795Sdim 710212795Sdimbool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 711212795Sdim const char *&PrevSpec, unsigned &DiagID) { 712212795Sdim if (!TypeAltiVecVector || TypeAltiVecPixel || 713212795Sdim (TypeSpecType != TST_unspecified)) { 714212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 715212795Sdim DiagID = diag::err_invalid_pixel_decl_spec_combination; 716212795Sdim return true; 717212795Sdim } 718212795Sdim TypeAltiVecPixel = isAltiVecPixel; 719212795Sdim TSTLoc = Loc; 720221345Sdim TSTNameLoc = Loc; 721212795Sdim return false; 722212795Sdim} 723212795Sdim 724263508Sdimbool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, 725263508Sdim const char *&PrevSpec, unsigned &DiagID) { 726263508Sdim if (!TypeAltiVecVector || TypeAltiVecBool || 727263508Sdim (TypeSpecType != TST_unspecified)) { 728263508Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 729263508Sdim DiagID = diag::err_invalid_vector_bool_decl_spec; 730263508Sdim return true; 731263508Sdim } 732263508Sdim TypeAltiVecBool = isAltiVecBool; 733263508Sdim TSTLoc = Loc; 734263508Sdim TSTNameLoc = Loc; 735263508Sdim return false; 736263508Sdim} 737263508Sdim 738212795Sdimbool DeclSpec::SetTypeSpecError() { 739212795Sdim TypeSpecType = TST_error; 740212795Sdim TypeSpecOwned = false; 741212795Sdim TSTLoc = SourceLocation(); 742221345Sdim TSTNameLoc = SourceLocation(); 743212795Sdim return false; 744212795Sdim} 745212795Sdim 746212795Sdimbool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 747243830Sdim unsigned &DiagID, const LangOptions &Lang) { 748263508Sdim // Duplicates are permitted in C99 onwards, but are not permitted in C89 or 749263508Sdim // C++. However, since this is likely not what the user intended, we will 750263508Sdim // always warn. We do not need to set the qualifier's location since we 751263508Sdim // already have it. 752243830Sdim if (TypeQualifiers & T) { 753243830Sdim bool IsExtension = true; 754243830Sdim if (Lang.C99) 755243830Sdim IsExtension = false; 756243830Sdim return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension); 757243830Sdim } 758212795Sdim TypeQualifiers |= T; 759212795Sdim 760212795Sdim switch (T) { 761249423Sdim case TQ_unspecified: break; 762249423Sdim case TQ_const: TQ_constLoc = Loc; return false; 763249423Sdim case TQ_restrict: TQ_restrictLoc = Loc; return false; 764249423Sdim case TQ_volatile: TQ_volatileLoc = Loc; return false; 765249423Sdim case TQ_atomic: TQ_atomicLoc = Loc; return false; 766212795Sdim } 767249423Sdim 768249423Sdim llvm_unreachable("Unknown type qualifier!"); 769212795Sdim} 770212795Sdim 771263508Sdimbool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, 772263508Sdim unsigned &DiagID) { 773263508Sdim // 'inline inline' is ok. However, since this is likely not what the user 774263508Sdim // intended, we will always warn, similar to duplicates of type qualifiers. 775263508Sdim if (FS_inline_specified) { 776263508Sdim DiagID = diag::warn_duplicate_declspec; 777263508Sdim PrevSpec = "inline"; 778263508Sdim return true; 779263508Sdim } 780212795Sdim FS_inline_specified = true; 781212795Sdim FS_inlineLoc = Loc; 782212795Sdim return false; 783212795Sdim} 784212795Sdim 785263508Sdimbool DeclSpec::setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, 786263508Sdim unsigned &DiagID) { 787263508Sdim if (FS_forceinline_specified) { 788263508Sdim DiagID = diag::warn_duplicate_declspec; 789263508Sdim PrevSpec = "__forceinline"; 790263508Sdim return true; 791263508Sdim } 792263508Sdim FS_forceinline_specified = true; 793263508Sdim FS_forceinlineLoc = Loc; 794263508Sdim return false; 795263508Sdim} 796263508Sdim 797263508Sdimbool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc, 798263508Sdim const char *&PrevSpec, 799263508Sdim unsigned &DiagID) { 800263508Sdim // 'virtual virtual' is ok, but warn as this is likely not what the user 801263508Sdim // intended. 802263508Sdim if (FS_virtual_specified) { 803263508Sdim DiagID = diag::warn_duplicate_declspec; 804263508Sdim PrevSpec = "virtual"; 805263508Sdim return true; 806263508Sdim } 807212795Sdim FS_virtual_specified = true; 808212795Sdim FS_virtualLoc = Loc; 809212795Sdim return false; 810212795Sdim} 811212795Sdim 812263508Sdimbool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc, 813263508Sdim const char *&PrevSpec, 814263508Sdim unsigned &DiagID) { 815263508Sdim // 'explicit explicit' is ok, but warn as this is likely not what the user 816263508Sdim // intended. 817263508Sdim if (FS_explicit_specified) { 818263508Sdim DiagID = diag::warn_duplicate_declspec; 819263508Sdim PrevSpec = "explicit"; 820263508Sdim return true; 821263508Sdim } 822212795Sdim FS_explicit_specified = true; 823212795Sdim FS_explicitLoc = Loc; 824212795Sdim return false; 825212795Sdim} 826212795Sdim 827263508Sdimbool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc, 828263508Sdim const char *&PrevSpec, 829263508Sdim unsigned &DiagID) { 830263508Sdim // '_Noreturn _Noreturn' is ok, but warn as this is likely not what the user 831263508Sdim // intended. 832263508Sdim if (FS_noreturn_specified) { 833263508Sdim DiagID = diag::warn_duplicate_declspec; 834263508Sdim PrevSpec = "_Noreturn"; 835263508Sdim return true; 836263508Sdim } 837249423Sdim FS_noreturn_specified = true; 838249423Sdim FS_noreturnLoc = Loc; 839249423Sdim return false; 840249423Sdim} 841249423Sdim 842212795Sdimbool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 843212795Sdim unsigned &DiagID) { 844212795Sdim if (Friend_specified) { 845212795Sdim PrevSpec = "friend"; 846212795Sdim DiagID = diag::ext_duplicate_declspec; 847212795Sdim return true; 848212795Sdim } 849212795Sdim 850212795Sdim Friend_specified = true; 851212795Sdim FriendLoc = Loc; 852212795Sdim return false; 853212795Sdim} 854212795Sdim 855226633Sdimbool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, 856226633Sdim unsigned &DiagID) { 857226633Sdim if (isModulePrivateSpecified()) { 858226633Sdim PrevSpec = "__module_private__"; 859226633Sdim DiagID = diag::ext_duplicate_declspec; 860226633Sdim return true; 861226633Sdim } 862226633Sdim 863226633Sdim ModulePrivateLoc = Loc; 864226633Sdim return false; 865226633Sdim} 866226633Sdim 867212795Sdimbool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, 868212795Sdim unsigned &DiagID) { 869212795Sdim // 'constexpr constexpr' is ok. 870212795Sdim Constexpr_specified = true; 871212795Sdim ConstexprLoc = Loc; 872212795Sdim return false; 873212795Sdim} 874212795Sdim 875212795Sdimvoid DeclSpec::setProtocolQualifiers(Decl * const *Protos, 876212795Sdim unsigned NP, 877212795Sdim SourceLocation *ProtoLocs, 878212795Sdim SourceLocation LAngleLoc) { 879212795Sdim if (NP == 0) return; 880249423Sdim Decl **ProtoQuals = new Decl*[NP]; 881249423Sdim memcpy(ProtoQuals, Protos, sizeof(Decl*)*NP); 882249423Sdim ProtocolQualifiers = ProtoQuals; 883212795Sdim ProtocolLocs = new SourceLocation[NP]; 884212795Sdim memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); 885212795Sdim NumProtocolQualifiers = NP; 886212795Sdim ProtocolLAngleLoc = LAngleLoc; 887212795Sdim} 888212795Sdim 889212795Sdimvoid DeclSpec::SaveWrittenBuiltinSpecs() { 890212795Sdim writtenBS.Sign = getTypeSpecSign(); 891212795Sdim writtenBS.Width = getTypeSpecWidth(); 892212795Sdim writtenBS.Type = getTypeSpecType(); 893212795Sdim // Search the list of attributes for the presence of a mode attribute. 894212795Sdim writtenBS.ModeAttr = false; 895218893Sdim AttributeList* attrs = getAttributes().getList(); 896212795Sdim while (attrs) { 897239462Sdim if (attrs->getKind() == AttributeList::AT_Mode) { 898212795Sdim writtenBS.ModeAttr = true; 899212795Sdim break; 900212795Sdim } 901212795Sdim attrs = attrs->getNext(); 902212795Sdim } 903212795Sdim} 904212795Sdim 905212795Sdim/// Finish - This does final analysis of the declspec, rejecting things like 906212795Sdim/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or 907212795Sdim/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, 908212795Sdim/// DeclSpec is guaranteed self-consistent, even if an error occurred. 909226633Sdimvoid DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { 910212795Sdim // Before possibly changing their values, save specs as written. 911212795Sdim SaveWrittenBuiltinSpecs(); 912212795Sdim 913212795Sdim // Check the type specifier components first. 914212795Sdim 915251662Sdim // If decltype(auto) is used, no other type specifiers are permitted. 916251662Sdim if (TypeSpecType == TST_decltype_auto && 917251662Sdim (TypeSpecWidth != TSW_unspecified || 918251662Sdim TypeSpecComplex != TSC_unspecified || 919251662Sdim TypeSpecSign != TSS_unspecified || 920251662Sdim TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool || 921251662Sdim TypeQualifiers)) { 922251662Sdim const unsigned NumLocs = 8; 923251662Sdim SourceLocation ExtraLocs[NumLocs] = { 924251662Sdim TSWLoc, TSCLoc, TSSLoc, AltiVecLoc, 925251662Sdim TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc 926251662Sdim }; 927251662Sdim FixItHint Hints[NumLocs]; 928251662Sdim SourceLocation FirstLoc; 929251662Sdim for (unsigned I = 0; I != NumLocs; ++I) { 930251662Sdim if (!ExtraLocs[I].isInvalid()) { 931251662Sdim if (FirstLoc.isInvalid() || 932251662Sdim PP.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I], 933251662Sdim FirstLoc)) 934251662Sdim FirstLoc = ExtraLocs[I]; 935251662Sdim Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]); 936251662Sdim } 937251662Sdim } 938251662Sdim TypeSpecWidth = TSW_unspecified; 939251662Sdim TypeSpecComplex = TSC_unspecified; 940251662Sdim TypeSpecSign = TSS_unspecified; 941251662Sdim TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false; 942251662Sdim TypeQualifiers = 0; 943251662Sdim Diag(D, TSTLoc, diag::err_decltype_auto_cannot_be_combined) 944251662Sdim << Hints[0] << Hints[1] << Hints[2] << Hints[3] 945251662Sdim << Hints[4] << Hints[5] << Hints[6] << Hints[7]; 946251662Sdim } 947251662Sdim 948212795Sdim // Validate and finalize AltiVec vector declspec. 949212795Sdim if (TypeAltiVecVector) { 950212795Sdim if (TypeAltiVecBool) { 951212795Sdim // Sign specifiers are not allowed with vector bool. (PIM 2.1) 952212795Sdim if (TypeSpecSign != TSS_unspecified) { 953218893Sdim Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec) 954212795Sdim << getSpecifierName((TSS)TypeSpecSign); 955212795Sdim } 956212795Sdim 957212795Sdim // Only char/int are valid with vector bool. (PIM 2.1) 958212795Sdim if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && 959212795Sdim (TypeSpecType != TST_int)) || TypeAltiVecPixel) { 960218893Sdim Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec) 961212795Sdim << (TypeAltiVecPixel ? "__pixel" : 962212795Sdim getSpecifierName((TST)TypeSpecType)); 963212795Sdim } 964212795Sdim 965212795Sdim // Only 'short' is valid with vector bool. (PIM 2.1) 966212795Sdim if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) 967218893Sdim Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) 968212795Sdim << getSpecifierName((TSW)TypeSpecWidth); 969212795Sdim 970212795Sdim // Elements of vector bool are interpreted as unsigned. (PIM 2.1) 971212795Sdim if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || 972212795Sdim (TypeSpecWidth != TSW_unspecified)) 973212795Sdim TypeSpecSign = TSS_unsigned; 974212795Sdim } 975212795Sdim 976212795Sdim if (TypeAltiVecPixel) { 977212795Sdim //TODO: perform validation 978212795Sdim TypeSpecType = TST_int; 979212795Sdim TypeSpecSign = TSS_unsigned; 980212795Sdim TypeSpecWidth = TSW_short; 981212795Sdim TypeSpecOwned = false; 982212795Sdim } 983212795Sdim } 984212795Sdim 985212795Sdim // signed/unsigned are only valid with int/char/wchar_t. 986212795Sdim if (TypeSpecSign != TSS_unspecified) { 987212795Sdim if (TypeSpecType == TST_unspecified) 988212795Sdim TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. 989234353Sdim else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && 990212795Sdim TypeSpecType != TST_char && TypeSpecType != TST_wchar) { 991218893Sdim Diag(D, TSSLoc, diag::err_invalid_sign_spec) 992212795Sdim << getSpecifierName((TST)TypeSpecType); 993212795Sdim // signed double -> double. 994212795Sdim TypeSpecSign = TSS_unspecified; 995212795Sdim } 996212795Sdim } 997212795Sdim 998212795Sdim // Validate the width of the type. 999212795Sdim switch (TypeSpecWidth) { 1000212795Sdim case TSW_unspecified: break; 1001212795Sdim case TSW_short: // short int 1002212795Sdim case TSW_longlong: // long long int 1003212795Sdim if (TypeSpecType == TST_unspecified) 1004212795Sdim TypeSpecType = TST_int; // short -> short int, long long -> long long int. 1005212795Sdim else if (TypeSpecType != TST_int) { 1006218893Sdim Diag(D, TSWLoc, 1007212795Sdim TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec 1008212795Sdim : diag::err_invalid_longlong_spec) 1009212795Sdim << getSpecifierName((TST)TypeSpecType); 1010212795Sdim TypeSpecType = TST_int; 1011212795Sdim TypeSpecOwned = false; 1012212795Sdim } 1013212795Sdim break; 1014212795Sdim case TSW_long: // long double, long int 1015212795Sdim if (TypeSpecType == TST_unspecified) 1016212795Sdim TypeSpecType = TST_int; // long -> long int. 1017212795Sdim else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { 1018218893Sdim Diag(D, TSWLoc, diag::err_invalid_long_spec) 1019212795Sdim << getSpecifierName((TST)TypeSpecType); 1020212795Sdim TypeSpecType = TST_int; 1021212795Sdim TypeSpecOwned = false; 1022212795Sdim } 1023212795Sdim break; 1024212795Sdim } 1025212795Sdim 1026212795Sdim // TODO: if the implementation does not implement _Complex or _Imaginary, 1027212795Sdim // disallow their use. Need information about the backend. 1028212795Sdim if (TypeSpecComplex != TSC_unspecified) { 1029212795Sdim if (TypeSpecType == TST_unspecified) { 1030218893Sdim Diag(D, TSCLoc, diag::ext_plain_complex) 1031212795Sdim << FixItHint::CreateInsertion( 1032212795Sdim PP.getLocForEndOfToken(getTypeSpecComplexLoc()), 1033212795Sdim " double"); 1034212795Sdim TypeSpecType = TST_double; // _Complex -> _Complex double. 1035212795Sdim } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { 1036212795Sdim // Note that this intentionally doesn't include _Complex _Bool. 1037234353Sdim if (!PP.getLangOpts().CPlusPlus) 1038234353Sdim Diag(D, TSTLoc, diag::ext_integer_complex); 1039212795Sdim } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { 1040218893Sdim Diag(D, TSCLoc, diag::err_invalid_complex_spec) 1041212795Sdim << getSpecifierName((TST)TypeSpecType); 1042212795Sdim TypeSpecComplex = TSC_unspecified; 1043212795Sdim } 1044212795Sdim } 1045212795Sdim 1046251662Sdim // C11 6.7.1/3, C++11 [dcl.stc]p1, GNU TLS: __thread, thread_local and 1047251662Sdim // _Thread_local can only appear with the 'static' and 'extern' storage class 1048251662Sdim // specifiers. We also allow __private_extern__ as an extension. 1049251662Sdim if (ThreadStorageClassSpec != TSCS_unspecified) { 1050251662Sdim switch (StorageClassSpec) { 1051251662Sdim case SCS_unspecified: 1052251662Sdim case SCS_extern: 1053251662Sdim case SCS_private_extern: 1054251662Sdim case SCS_static: 1055251662Sdim break; 1056251662Sdim default: 1057251662Sdim if (PP.getSourceManager().isBeforeInTranslationUnit( 1058251662Sdim getThreadStorageClassSpecLoc(), getStorageClassSpecLoc())) 1059251662Sdim Diag(D, getStorageClassSpecLoc(), 1060251662Sdim diag::err_invalid_decl_spec_combination) 1061251662Sdim << DeclSpec::getSpecifierName(getThreadStorageClassSpec()) 1062251662Sdim << SourceRange(getThreadStorageClassSpecLoc()); 1063251662Sdim else 1064251662Sdim Diag(D, getThreadStorageClassSpecLoc(), 1065251662Sdim diag::err_invalid_decl_spec_combination) 1066251662Sdim << DeclSpec::getSpecifierName(getStorageClassSpec()) 1067251662Sdim << SourceRange(getStorageClassSpecLoc()); 1068251662Sdim // Discard the thread storage class specifier to recover. 1069251662Sdim ThreadStorageClassSpec = TSCS_unspecified; 1070251662Sdim ThreadStorageClassSpecLoc = SourceLocation(); 1071251662Sdim } 1072251662Sdim } 1073251662Sdim 1074226633Sdim // If no type specifier was provided and we're parsing a language where 1075226633Sdim // the type specifier is not optional, but we got 'auto' as a storage 1076226633Sdim // class specifier, then assume this is an attempt to use C++0x's 'auto' 1077226633Sdim // type specifier. 1078251662Sdim if (PP.getLangOpts().CPlusPlus && 1079226633Sdim TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) { 1080226633Sdim TypeSpecType = TST_auto; 1081249423Sdim StorageClassSpec = SCS_unspecified; 1082226633Sdim TSTLoc = TSTNameLoc = StorageClassSpecLoc; 1083226633Sdim StorageClassSpecLoc = SourceLocation(); 1084226633Sdim } 1085226633Sdim // Diagnose if we've recovered from an ill-formed 'auto' storage class 1086251662Sdim // specifier in a pre-C++11 dialect of C++. 1087249423Sdim if (!PP.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto) 1088226633Sdim Diag(D, TSTLoc, diag::ext_auto_type_specifier); 1089249423Sdim if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus11 && 1090226633Sdim StorageClassSpec == SCS_auto) 1091226633Sdim Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class) 1092226633Sdim << FixItHint::CreateRemoval(StorageClassSpecLoc); 1093234353Sdim if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) 1094234353Sdim Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type) 1095234353Sdim << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); 1096234353Sdim if (Constexpr_specified) 1097234353Sdim Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr); 1098226633Sdim 1099212795Sdim // C++ [class.friend]p6: 1100212795Sdim // No storage-class-specifier shall appear in the decl-specifier-seq 1101212795Sdim // of a friend declaration. 1102251662Sdim if (isFriendSpecified() && 1103251662Sdim (getStorageClassSpec() || getThreadStorageClassSpec())) { 1104251662Sdim SmallString<32> SpecName; 1105251662Sdim SourceLocation SCLoc; 1106251662Sdim FixItHint StorageHint, ThreadHint; 1107212795Sdim 1108251662Sdim if (DeclSpec::SCS SC = getStorageClassSpec()) { 1109251662Sdim SpecName = getSpecifierName(SC); 1110251662Sdim SCLoc = getStorageClassSpecLoc(); 1111251662Sdim StorageHint = FixItHint::CreateRemoval(SCLoc); 1112251662Sdim } 1113212795Sdim 1114251662Sdim if (DeclSpec::TSCS TSC = getThreadStorageClassSpec()) { 1115251662Sdim if (!SpecName.empty()) SpecName += " "; 1116251662Sdim SpecName += getSpecifierName(TSC); 1117251662Sdim SCLoc = getThreadStorageClassSpecLoc(); 1118251662Sdim ThreadHint = FixItHint::CreateRemoval(SCLoc); 1119251662Sdim } 1120251662Sdim 1121218893Sdim Diag(D, SCLoc, diag::err_friend_storage_spec) 1122251662Sdim << SpecName << StorageHint << ThreadHint; 1123212795Sdim 1124212795Sdim ClearStorageClassSpecs(); 1125212795Sdim } 1126212795Sdim 1127212795Sdim assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType)); 1128226633Sdim 1129212795Sdim // Okay, now we can infer the real type. 1130212795Sdim 1131212795Sdim // TODO: return "auto function" and other bad things based on the real type. 1132212795Sdim 1133212795Sdim // 'data definition has no type or storage class'? 1134212795Sdim} 1135212795Sdim 1136212795Sdimbool DeclSpec::isMissingDeclaratorOk() { 1137212795Sdim TST tst = getTypeSpecType(); 1138212795Sdim return isDeclRep(tst) && getRepAsDecl() != 0 && 1139212795Sdim StorageClassSpec != DeclSpec::SCS_typedef; 1140212795Sdim} 1141212795Sdim 1142212795Sdimvoid UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 1143212795Sdim OverloadedOperatorKind Op, 1144212795Sdim SourceLocation SymbolLocations[3]) { 1145212795Sdim Kind = IK_OperatorFunctionId; 1146212795Sdim StartLocation = OperatorLoc; 1147212795Sdim EndLocation = OperatorLoc; 1148212795Sdim OperatorFunctionId.Operator = Op; 1149212795Sdim for (unsigned I = 0; I != 3; ++I) { 1150212795Sdim OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); 1151212795Sdim 1152212795Sdim if (SymbolLocations[I].isValid()) 1153212795Sdim EndLocation = SymbolLocations[I]; 1154212795Sdim } 1155212795Sdim} 1156218893Sdim 1157218893Sdimbool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, 1158218893Sdim const char *&PrevSpec) { 1159221345Sdim LastLocation = Loc; 1160221345Sdim 1161218893Sdim if (Specifiers & VS) { 1162218893Sdim PrevSpec = getSpecifierName(VS); 1163218893Sdim return true; 1164218893Sdim } 1165218893Sdim 1166218893Sdim Specifiers |= VS; 1167218893Sdim 1168218893Sdim switch (VS) { 1169226633Sdim default: llvm_unreachable("Unknown specifier!"); 1170218893Sdim case VS_Override: VS_overrideLoc = Loc; break; 1171263508Sdim case VS_Sealed: 1172218893Sdim case VS_Final: VS_finalLoc = Loc; break; 1173218893Sdim } 1174218893Sdim 1175218893Sdim return false; 1176218893Sdim} 1177218893Sdim 1178218893Sdimconst char *VirtSpecifiers::getSpecifierName(Specifier VS) { 1179218893Sdim switch (VS) { 1180226633Sdim default: llvm_unreachable("Unknown specifier"); 1181218893Sdim case VS_Override: return "override"; 1182218893Sdim case VS_Final: return "final"; 1183263508Sdim case VS_Sealed: return "sealed"; 1184218893Sdim } 1185218893Sdim} 1186