DeclSpec.cpp revision 263508
1//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements semantic analysis for declaration specifiers. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Sema/DeclSpec.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/DeclCXX.h" 17#include "clang/AST/Expr.h" 18#include "clang/AST/NestedNameSpecifier.h" 19#include "clang/AST/TypeLoc.h" 20#include "clang/Basic/LangOptions.h" 21#include "clang/Lex/Preprocessor.h" 22#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency! 23#include "clang/Sema/LocInfoType.h" 24#include "clang/Sema/ParsedTemplate.h" 25#include "clang/Sema/Sema.h" 26#include "clang/Sema/SemaDiagnostic.h" 27#include "llvm/ADT/STLExtras.h" 28#include "llvm/ADT/SmallString.h" 29#include "llvm/Support/ErrorHandling.h" 30#include <cstring> 31using namespace clang; 32 33 34static DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc, 35 unsigned DiagID) { 36 return D.Report(Loc, DiagID); 37} 38 39 40void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { 41 assert(TemplateId && "NULL template-id annotation?"); 42 Kind = IK_TemplateId; 43 this->TemplateId = TemplateId; 44 StartLocation = TemplateId->TemplateNameLoc; 45 EndLocation = TemplateId->RAngleLoc; 46} 47 48void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { 49 assert(TemplateId && "NULL template-id annotation?"); 50 Kind = IK_ConstructorTemplateId; 51 this->TemplateId = TemplateId; 52 StartLocation = TemplateId->TemplateNameLoc; 53 EndLocation = TemplateId->RAngleLoc; 54} 55 56void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc, 57 TypeLoc TL, SourceLocation ColonColonLoc) { 58 Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc); 59 if (Range.getBegin().isInvalid()) 60 Range.setBegin(TL.getBeginLoc()); 61 Range.setEnd(ColonColonLoc); 62 63 assert(Range == Builder.getSourceRange() && 64 "NestedNameSpecifierLoc range computation incorrect"); 65} 66 67void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier, 68 SourceLocation IdentifierLoc, 69 SourceLocation ColonColonLoc) { 70 Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc); 71 72 if (Range.getBegin().isInvalid()) 73 Range.setBegin(IdentifierLoc); 74 Range.setEnd(ColonColonLoc); 75 76 assert(Range == Builder.getSourceRange() && 77 "NestedNameSpecifierLoc range computation incorrect"); 78} 79 80void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace, 81 SourceLocation NamespaceLoc, 82 SourceLocation ColonColonLoc) { 83 Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc); 84 85 if (Range.getBegin().isInvalid()) 86 Range.setBegin(NamespaceLoc); 87 Range.setEnd(ColonColonLoc); 88 89 assert(Range == Builder.getSourceRange() && 90 "NestedNameSpecifierLoc range computation incorrect"); 91} 92 93void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 94 SourceLocation AliasLoc, 95 SourceLocation ColonColonLoc) { 96 Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc); 97 98 if (Range.getBegin().isInvalid()) 99 Range.setBegin(AliasLoc); 100 Range.setEnd(ColonColonLoc); 101 102 assert(Range == Builder.getSourceRange() && 103 "NestedNameSpecifierLoc range computation incorrect"); 104} 105 106void CXXScopeSpec::MakeGlobal(ASTContext &Context, 107 SourceLocation ColonColonLoc) { 108 Builder.MakeGlobal(Context, ColonColonLoc); 109 110 Range = SourceRange(ColonColonLoc); 111 112 assert(Range == Builder.getSourceRange() && 113 "NestedNameSpecifierLoc range computation incorrect"); 114} 115 116void CXXScopeSpec::MakeTrivial(ASTContext &Context, 117 NestedNameSpecifier *Qualifier, SourceRange R) { 118 Builder.MakeTrivial(Context, Qualifier, R); 119 Range = R; 120} 121 122void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) { 123 if (!Other) { 124 Range = SourceRange(); 125 Builder.Clear(); 126 return; 127 } 128 129 Range = Other.getSourceRange(); 130 Builder.Adopt(Other); 131} 132 133SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const { 134 if (!Builder.getRepresentation()) 135 return SourceLocation(); 136 return Builder.getTemporary().getLocalBeginLoc(); 137} 138 139NestedNameSpecifierLoc 140CXXScopeSpec::getWithLocInContext(ASTContext &Context) const { 141 if (!Builder.getRepresentation()) 142 return NestedNameSpecifierLoc(); 143 144 return Builder.getWithLocInContext(Context); 145} 146 147/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. 148/// "TheDeclarator" is the declarator that this will be added to. 149DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, 150 bool isAmbiguous, 151 SourceLocation LParenLoc, 152 ParamInfo *ArgInfo, 153 unsigned NumArgs, 154 SourceLocation EllipsisLoc, 155 SourceLocation RParenLoc, 156 unsigned TypeQuals, 157 bool RefQualifierIsLvalueRef, 158 SourceLocation RefQualifierLoc, 159 SourceLocation ConstQualifierLoc, 160 SourceLocation 161 VolatileQualifierLoc, 162 SourceLocation MutableLoc, 163 ExceptionSpecificationType 164 ESpecType, 165 SourceLocation ESpecLoc, 166 ParsedType *Exceptions, 167 SourceRange *ExceptionRanges, 168 unsigned NumExceptions, 169 Expr *NoexceptExpr, 170 SourceLocation LocalRangeBegin, 171 SourceLocation LocalRangeEnd, 172 Declarator &TheDeclarator, 173 TypeResult TrailingReturnType) { 174 assert(!(TypeQuals & DeclSpec::TQ_atomic) && 175 "function cannot have _Atomic qualifier"); 176 177 DeclaratorChunk I; 178 I.Kind = Function; 179 I.Loc = LocalRangeBegin; 180 I.EndLoc = LocalRangeEnd; 181 I.Fun.AttrList = 0; 182 I.Fun.hasPrototype = hasProto; 183 I.Fun.isVariadic = EllipsisLoc.isValid(); 184 I.Fun.isAmbiguous = isAmbiguous; 185 I.Fun.LParenLoc = LParenLoc.getRawEncoding(); 186 I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); 187 I.Fun.RParenLoc = RParenLoc.getRawEncoding(); 188 I.Fun.DeleteArgInfo = false; 189 I.Fun.TypeQuals = TypeQuals; 190 I.Fun.NumArgs = NumArgs; 191 I.Fun.ArgInfo = 0; 192 I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; 193 I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); 194 I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding(); 195 I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding(); 196 I.Fun.MutableLoc = MutableLoc.getRawEncoding(); 197 I.Fun.ExceptionSpecType = ESpecType; 198 I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); 199 I.Fun.NumExceptions = 0; 200 I.Fun.Exceptions = 0; 201 I.Fun.NoexceptExpr = 0; 202 I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() || 203 TrailingReturnType.isInvalid(); 204 I.Fun.TrailingReturnType = TrailingReturnType.get(); 205 206 // new[] an argument array if needed. 207 if (NumArgs) { 208 // If the 'InlineParams' in Declarator is unused and big enough, put our 209 // parameter list there (in an effort to avoid new/delete traffic). If it 210 // is already used (consider a function returning a function pointer) or too 211 // small (function taking too many arguments), go to the heap. 212 if (!TheDeclarator.InlineParamsUsed && 213 NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) { 214 I.Fun.ArgInfo = TheDeclarator.InlineParams; 215 I.Fun.DeleteArgInfo = false; 216 TheDeclarator.InlineParamsUsed = true; 217 } else { 218 I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs]; 219 I.Fun.DeleteArgInfo = true; 220 } 221 memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs); 222 } 223 224 // Check what exception specification information we should actually store. 225 switch (ESpecType) { 226 default: break; // By default, save nothing. 227 case EST_Dynamic: 228 // new[] an exception array if needed 229 if (NumExceptions) { 230 I.Fun.NumExceptions = NumExceptions; 231 I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions]; 232 for (unsigned i = 0; i != NumExceptions; ++i) { 233 I.Fun.Exceptions[i].Ty = Exceptions[i]; 234 I.Fun.Exceptions[i].Range = ExceptionRanges[i]; 235 } 236 } 237 break; 238 239 case EST_ComputedNoexcept: 240 I.Fun.NoexceptExpr = NoexceptExpr; 241 break; 242 } 243 return I; 244} 245 246bool Declarator::isDeclarationOfFunction() const { 247 for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { 248 switch (DeclTypeInfo[i].Kind) { 249 case DeclaratorChunk::Function: 250 return true; 251 case DeclaratorChunk::Paren: 252 continue; 253 case DeclaratorChunk::Pointer: 254 case DeclaratorChunk::Reference: 255 case DeclaratorChunk::Array: 256 case DeclaratorChunk::BlockPointer: 257 case DeclaratorChunk::MemberPointer: 258 return false; 259 } 260 llvm_unreachable("Invalid type chunk"); 261 } 262 263 switch (DS.getTypeSpecType()) { 264 case TST_atomic: 265 case TST_auto: 266 case TST_bool: 267 case TST_char: 268 case TST_char16: 269 case TST_char32: 270 case TST_class: 271 case TST_decimal128: 272 case TST_decimal32: 273 case TST_decimal64: 274 case TST_double: 275 case TST_enum: 276 case TST_error: 277 case TST_float: 278 case TST_half: 279 case TST_int: 280 case TST_int128: 281 case TST_struct: 282 case TST_interface: 283 case TST_union: 284 case TST_unknown_anytype: 285 case TST_unspecified: 286 case TST_void: 287 case TST_wchar: 288 case TST_image1d_t: 289 case TST_image1d_array_t: 290 case TST_image1d_buffer_t: 291 case TST_image2d_t: 292 case TST_image2d_array_t: 293 case TST_image3d_t: 294 case TST_sampler_t: 295 case TST_event_t: 296 return false; 297 298 case TST_decltype_auto: 299 // This must have an initializer, so can't be a function declaration, 300 // even if the initializer has function type. 301 return false; 302 303 case TST_decltype: 304 case TST_typeofExpr: 305 if (Expr *E = DS.getRepAsExpr()) 306 return E->getType()->isFunctionType(); 307 return false; 308 309 case TST_underlyingType: 310 case TST_typename: 311 case TST_typeofType: { 312 QualType QT = DS.getRepAsType().get(); 313 if (QT.isNull()) 314 return false; 315 316 if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) 317 QT = LIT->getType(); 318 319 if (QT.isNull()) 320 return false; 321 322 return QT->isFunctionType(); 323 } 324 } 325 326 llvm_unreachable("Invalid TypeSpecType!"); 327} 328 329bool Declarator::isStaticMember() { 330 assert(getContext() == MemberContext); 331 return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || 332 CXXMethodDecl::isStaticOverloadedOperator( 333 getName().OperatorFunctionId.Operator); 334} 335 336bool DeclSpec::hasTagDefinition() const { 337 if (!TypeSpecOwned) 338 return false; 339 return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition(); 340} 341 342/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this 343/// declaration specifier includes. 344/// 345unsigned DeclSpec::getParsedSpecifiers() const { 346 unsigned Res = 0; 347 if (StorageClassSpec != SCS_unspecified || 348 ThreadStorageClassSpec != TSCS_unspecified) 349 Res |= PQ_StorageClassSpecifier; 350 351 if (TypeQualifiers != TQ_unspecified) 352 Res |= PQ_TypeQualifier; 353 354 if (hasTypeSpecifier()) 355 Res |= PQ_TypeSpecifier; 356 357 if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified || 358 FS_noreturn_specified || FS_forceinline_specified) 359 Res |= PQ_FunctionSpecifier; 360 return Res; 361} 362 363template <class T> static bool BadSpecifier(T TNew, T TPrev, 364 const char *&PrevSpec, 365 unsigned &DiagID, 366 bool IsExtension = true) { 367 PrevSpec = DeclSpec::getSpecifierName(TPrev); 368 if (TNew != TPrev) 369 DiagID = diag::err_invalid_decl_spec_combination; 370 else 371 DiagID = IsExtension ? diag::ext_duplicate_declspec : 372 diag::warn_duplicate_declspec; 373 return true; 374} 375 376const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) { 377 switch (S) { 378 case DeclSpec::SCS_unspecified: return "unspecified"; 379 case DeclSpec::SCS_typedef: return "typedef"; 380 case DeclSpec::SCS_extern: return "extern"; 381 case DeclSpec::SCS_static: return "static"; 382 case DeclSpec::SCS_auto: return "auto"; 383 case DeclSpec::SCS_register: return "register"; 384 case DeclSpec::SCS_private_extern: return "__private_extern__"; 385 case DeclSpec::SCS_mutable: return "mutable"; 386 } 387 llvm_unreachable("Unknown typespec!"); 388} 389 390const char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) { 391 switch (S) { 392 case DeclSpec::TSCS_unspecified: return "unspecified"; 393 case DeclSpec::TSCS___thread: return "__thread"; 394 case DeclSpec::TSCS_thread_local: return "thread_local"; 395 case DeclSpec::TSCS__Thread_local: return "_Thread_local"; 396 } 397 llvm_unreachable("Unknown typespec!"); 398} 399 400const char *DeclSpec::getSpecifierName(TSW W) { 401 switch (W) { 402 case TSW_unspecified: return "unspecified"; 403 case TSW_short: return "short"; 404 case TSW_long: return "long"; 405 case TSW_longlong: return "long long"; 406 } 407 llvm_unreachable("Unknown typespec!"); 408} 409 410const char *DeclSpec::getSpecifierName(TSC C) { 411 switch (C) { 412 case TSC_unspecified: return "unspecified"; 413 case TSC_imaginary: return "imaginary"; 414 case TSC_complex: return "complex"; 415 } 416 llvm_unreachable("Unknown typespec!"); 417} 418 419 420const char *DeclSpec::getSpecifierName(TSS S) { 421 switch (S) { 422 case TSS_unspecified: return "unspecified"; 423 case TSS_signed: return "signed"; 424 case TSS_unsigned: return "unsigned"; 425 } 426 llvm_unreachable("Unknown typespec!"); 427} 428 429const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { 430 switch (T) { 431 case DeclSpec::TST_unspecified: return "unspecified"; 432 case DeclSpec::TST_void: return "void"; 433 case DeclSpec::TST_char: return "char"; 434 case DeclSpec::TST_wchar: return "wchar_t"; 435 case DeclSpec::TST_char16: return "char16_t"; 436 case DeclSpec::TST_char32: return "char32_t"; 437 case DeclSpec::TST_int: return "int"; 438 case DeclSpec::TST_int128: return "__int128"; 439 case DeclSpec::TST_half: return "half"; 440 case DeclSpec::TST_float: return "float"; 441 case DeclSpec::TST_double: return "double"; 442 case DeclSpec::TST_bool: return "_Bool"; 443 case DeclSpec::TST_decimal32: return "_Decimal32"; 444 case DeclSpec::TST_decimal64: return "_Decimal64"; 445 case DeclSpec::TST_decimal128: return "_Decimal128"; 446 case DeclSpec::TST_enum: return "enum"; 447 case DeclSpec::TST_class: return "class"; 448 case DeclSpec::TST_union: return "union"; 449 case DeclSpec::TST_struct: return "struct"; 450 case DeclSpec::TST_interface: return "__interface"; 451 case DeclSpec::TST_typename: return "type-name"; 452 case DeclSpec::TST_typeofType: 453 case DeclSpec::TST_typeofExpr: return "typeof"; 454 case DeclSpec::TST_auto: return "auto"; 455 case DeclSpec::TST_decltype: return "(decltype)"; 456 case DeclSpec::TST_decltype_auto: return "decltype(auto)"; 457 case DeclSpec::TST_underlyingType: return "__underlying_type"; 458 case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; 459 case DeclSpec::TST_atomic: return "_Atomic"; 460 case DeclSpec::TST_image1d_t: return "image1d_t"; 461 case DeclSpec::TST_image1d_array_t: return "image1d_array_t"; 462 case DeclSpec::TST_image1d_buffer_t: return "image1d_buffer_t"; 463 case DeclSpec::TST_image2d_t: return "image2d_t"; 464 case DeclSpec::TST_image2d_array_t: return "image2d_array_t"; 465 case DeclSpec::TST_image3d_t: return "image3d_t"; 466 case DeclSpec::TST_sampler_t: return "sampler_t"; 467 case DeclSpec::TST_event_t: return "event_t"; 468 case DeclSpec::TST_error: return "(error)"; 469 } 470 llvm_unreachable("Unknown typespec!"); 471} 472 473const char *DeclSpec::getSpecifierName(TQ T) { 474 switch (T) { 475 case DeclSpec::TQ_unspecified: return "unspecified"; 476 case DeclSpec::TQ_const: return "const"; 477 case DeclSpec::TQ_restrict: return "restrict"; 478 case DeclSpec::TQ_volatile: return "volatile"; 479 case DeclSpec::TQ_atomic: return "_Atomic"; 480 } 481 llvm_unreachable("Unknown typespec!"); 482} 483 484bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, 485 const char *&PrevSpec, 486 unsigned &DiagID) { 487 // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class 488 // specifiers are not supported. 489 // It seems sensible to prohibit private_extern too 490 // The cl_clang_storage_class_specifiers extension enables support for 491 // these storage-class specifiers. 492 // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class 493 // specifiers are not supported." 494 if (S.getLangOpts().OpenCL && 495 !S.getOpenCLOptions().cl_clang_storage_class_specifiers) { 496 switch (SC) { 497 case SCS_extern: 498 case SCS_private_extern: 499 case SCS_static: 500 if (S.getLangOpts().OpenCLVersion < 120) { 501 DiagID = diag::err_not_opencl_storage_class_specifier; 502 PrevSpec = getSpecifierName(SC); 503 return true; 504 } 505 break; 506 case SCS_auto: 507 case SCS_register: 508 DiagID = diag::err_not_opencl_storage_class_specifier; 509 PrevSpec = getSpecifierName(SC); 510 return true; 511 default: 512 break; 513 } 514 } 515 516 if (StorageClassSpec != SCS_unspecified) { 517 // Maybe this is an attempt to use C++11 'auto' outside of C++11 mode. 518 bool isInvalid = true; 519 if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) { 520 if (SC == SCS_auto) 521 return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID); 522 if (StorageClassSpec == SCS_auto) { 523 isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc, 524 PrevSpec, DiagID); 525 assert(!isInvalid && "auto SCS -> TST recovery failed"); 526 } 527 } 528 529 // Changing storage class is allowed only if the previous one 530 // was the 'extern' that is part of a linkage specification and 531 // the new storage class is 'typedef'. 532 if (isInvalid && 533 !(SCS_extern_in_linkage_spec && 534 StorageClassSpec == SCS_extern && 535 SC == SCS_typedef)) 536 return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID); 537 } 538 StorageClassSpec = SC; 539 StorageClassSpecLoc = Loc; 540 assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield"); 541 return false; 542} 543 544bool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, 545 const char *&PrevSpec, 546 unsigned &DiagID) { 547 if (ThreadStorageClassSpec != TSCS_unspecified) 548 return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID); 549 550 ThreadStorageClassSpec = TSC; 551 ThreadStorageClassSpecLoc = Loc; 552 return false; 553} 554 555/// These methods set the specified attribute of the DeclSpec, but return true 556/// and ignore the request if invalid (e.g. "extern" then "auto" is 557/// specified). 558bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, 559 const char *&PrevSpec, 560 unsigned &DiagID) { 561 // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that 562 // for 'long long' we will keep the source location of the first 'long'. 563 if (TypeSpecWidth == TSW_unspecified) 564 TSWLoc = Loc; 565 // Allow turning long -> long long. 566 else if (W != TSW_longlong || TypeSpecWidth != TSW_long) 567 return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); 568 TypeSpecWidth = W; 569 if (TypeAltiVecVector && !TypeAltiVecBool && 570 ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { 571 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 572 DiagID = diag::warn_vector_long_decl_spec_combination; 573 return true; 574 } 575 return false; 576} 577 578bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, 579 const char *&PrevSpec, 580 unsigned &DiagID) { 581 if (TypeSpecComplex != TSC_unspecified) 582 return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); 583 TypeSpecComplex = C; 584 TSCLoc = Loc; 585 return false; 586} 587 588bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, 589 const char *&PrevSpec, 590 unsigned &DiagID) { 591 if (TypeSpecSign != TSS_unspecified) 592 return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); 593 TypeSpecSign = S; 594 TSSLoc = Loc; 595 return false; 596} 597 598bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 599 const char *&PrevSpec, 600 unsigned &DiagID, 601 ParsedType Rep) { 602 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep); 603} 604 605bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 606 SourceLocation TagNameLoc, 607 const char *&PrevSpec, 608 unsigned &DiagID, 609 ParsedType Rep) { 610 assert(isTypeRep(T) && "T does not store a type"); 611 assert(Rep && "no type provided!"); 612 if (TypeSpecType != TST_unspecified) { 613 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 614 DiagID = diag::err_invalid_decl_spec_combination; 615 return true; 616 } 617 TypeSpecType = T; 618 TypeRep = Rep; 619 TSTLoc = TagKwLoc; 620 TSTNameLoc = TagNameLoc; 621 TypeSpecOwned = false; 622 return false; 623} 624 625bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 626 const char *&PrevSpec, 627 unsigned &DiagID, 628 Expr *Rep) { 629 assert(isExprRep(T) && "T does not store an expr"); 630 assert(Rep && "no expression provided!"); 631 if (TypeSpecType != TST_unspecified) { 632 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 633 DiagID = diag::err_invalid_decl_spec_combination; 634 return true; 635 } 636 TypeSpecType = T; 637 ExprRep = Rep; 638 TSTLoc = Loc; 639 TSTNameLoc = Loc; 640 TypeSpecOwned = false; 641 return false; 642} 643 644bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 645 const char *&PrevSpec, 646 unsigned &DiagID, 647 Decl *Rep, bool Owned) { 648 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned); 649} 650 651bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 652 SourceLocation TagNameLoc, 653 const char *&PrevSpec, 654 unsigned &DiagID, 655 Decl *Rep, bool Owned) { 656 assert(isDeclRep(T) && "T does not store a decl"); 657 // Unlike the other cases, we don't assert that we actually get a decl. 658 659 if (TypeSpecType != TST_unspecified) { 660 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 661 DiagID = diag::err_invalid_decl_spec_combination; 662 return true; 663 } 664 TypeSpecType = T; 665 DeclRep = Rep; 666 TSTLoc = TagKwLoc; 667 TSTNameLoc = TagNameLoc; 668 TypeSpecOwned = Owned && Rep != 0; 669 return false; 670} 671 672bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 673 const char *&PrevSpec, 674 unsigned &DiagID) { 675 assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && 676 "rep required for these type-spec kinds!"); 677 if (TypeSpecType != TST_unspecified) { 678 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 679 DiagID = diag::err_invalid_decl_spec_combination; 680 return true; 681 } 682 TSTLoc = Loc; 683 TSTNameLoc = Loc; 684 if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { 685 TypeAltiVecBool = true; 686 return false; 687 } 688 TypeSpecType = T; 689 TypeSpecOwned = false; 690 if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { 691 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 692 DiagID = diag::err_invalid_vector_decl_spec; 693 return true; 694 } 695 return false; 696} 697 698bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 699 const char *&PrevSpec, unsigned &DiagID) { 700 if (TypeSpecType != TST_unspecified) { 701 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 702 DiagID = diag::err_invalid_vector_decl_spec_combination; 703 return true; 704 } 705 TypeAltiVecVector = isAltiVecVector; 706 AltiVecLoc = Loc; 707 return false; 708} 709 710bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 711 const char *&PrevSpec, unsigned &DiagID) { 712 if (!TypeAltiVecVector || TypeAltiVecPixel || 713 (TypeSpecType != TST_unspecified)) { 714 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 715 DiagID = diag::err_invalid_pixel_decl_spec_combination; 716 return true; 717 } 718 TypeAltiVecPixel = isAltiVecPixel; 719 TSTLoc = Loc; 720 TSTNameLoc = Loc; 721 return false; 722} 723 724bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, 725 const char *&PrevSpec, unsigned &DiagID) { 726 if (!TypeAltiVecVector || TypeAltiVecBool || 727 (TypeSpecType != TST_unspecified)) { 728 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 729 DiagID = diag::err_invalid_vector_bool_decl_spec; 730 return true; 731 } 732 TypeAltiVecBool = isAltiVecBool; 733 TSTLoc = Loc; 734 TSTNameLoc = Loc; 735 return false; 736} 737 738bool DeclSpec::SetTypeSpecError() { 739 TypeSpecType = TST_error; 740 TypeSpecOwned = false; 741 TSTLoc = SourceLocation(); 742 TSTNameLoc = SourceLocation(); 743 return false; 744} 745 746bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 747 unsigned &DiagID, const LangOptions &Lang) { 748 // Duplicates are permitted in C99 onwards, but are not permitted in C89 or 749 // C++. However, since this is likely not what the user intended, we will 750 // always warn. We do not need to set the qualifier's location since we 751 // already have it. 752 if (TypeQualifiers & T) { 753 bool IsExtension = true; 754 if (Lang.C99) 755 IsExtension = false; 756 return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension); 757 } 758 TypeQualifiers |= T; 759 760 switch (T) { 761 case TQ_unspecified: break; 762 case TQ_const: TQ_constLoc = Loc; return false; 763 case TQ_restrict: TQ_restrictLoc = Loc; return false; 764 case TQ_volatile: TQ_volatileLoc = Loc; return false; 765 case TQ_atomic: TQ_atomicLoc = Loc; return false; 766 } 767 768 llvm_unreachable("Unknown type qualifier!"); 769} 770 771bool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, 772 unsigned &DiagID) { 773 // 'inline inline' is ok. However, since this is likely not what the user 774 // intended, we will always warn, similar to duplicates of type qualifiers. 775 if (FS_inline_specified) { 776 DiagID = diag::warn_duplicate_declspec; 777 PrevSpec = "inline"; 778 return true; 779 } 780 FS_inline_specified = true; 781 FS_inlineLoc = Loc; 782 return false; 783} 784 785bool DeclSpec::setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, 786 unsigned &DiagID) { 787 if (FS_forceinline_specified) { 788 DiagID = diag::warn_duplicate_declspec; 789 PrevSpec = "__forceinline"; 790 return true; 791 } 792 FS_forceinline_specified = true; 793 FS_forceinlineLoc = Loc; 794 return false; 795} 796 797bool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc, 798 const char *&PrevSpec, 799 unsigned &DiagID) { 800 // 'virtual virtual' is ok, but warn as this is likely not what the user 801 // intended. 802 if (FS_virtual_specified) { 803 DiagID = diag::warn_duplicate_declspec; 804 PrevSpec = "virtual"; 805 return true; 806 } 807 FS_virtual_specified = true; 808 FS_virtualLoc = Loc; 809 return false; 810} 811 812bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc, 813 const char *&PrevSpec, 814 unsigned &DiagID) { 815 // 'explicit explicit' is ok, but warn as this is likely not what the user 816 // intended. 817 if (FS_explicit_specified) { 818 DiagID = diag::warn_duplicate_declspec; 819 PrevSpec = "explicit"; 820 return true; 821 } 822 FS_explicit_specified = true; 823 FS_explicitLoc = Loc; 824 return false; 825} 826 827bool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc, 828 const char *&PrevSpec, 829 unsigned &DiagID) { 830 // '_Noreturn _Noreturn' is ok, but warn as this is likely not what the user 831 // intended. 832 if (FS_noreturn_specified) { 833 DiagID = diag::warn_duplicate_declspec; 834 PrevSpec = "_Noreturn"; 835 return true; 836 } 837 FS_noreturn_specified = true; 838 FS_noreturnLoc = Loc; 839 return false; 840} 841 842bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 843 unsigned &DiagID) { 844 if (Friend_specified) { 845 PrevSpec = "friend"; 846 DiagID = diag::ext_duplicate_declspec; 847 return true; 848 } 849 850 Friend_specified = true; 851 FriendLoc = Loc; 852 return false; 853} 854 855bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, 856 unsigned &DiagID) { 857 if (isModulePrivateSpecified()) { 858 PrevSpec = "__module_private__"; 859 DiagID = diag::ext_duplicate_declspec; 860 return true; 861 } 862 863 ModulePrivateLoc = Loc; 864 return false; 865} 866 867bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, 868 unsigned &DiagID) { 869 // 'constexpr constexpr' is ok. 870 Constexpr_specified = true; 871 ConstexprLoc = Loc; 872 return false; 873} 874 875void DeclSpec::setProtocolQualifiers(Decl * const *Protos, 876 unsigned NP, 877 SourceLocation *ProtoLocs, 878 SourceLocation LAngleLoc) { 879 if (NP == 0) return; 880 Decl **ProtoQuals = new Decl*[NP]; 881 memcpy(ProtoQuals, Protos, sizeof(Decl*)*NP); 882 ProtocolQualifiers = ProtoQuals; 883 ProtocolLocs = new SourceLocation[NP]; 884 memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); 885 NumProtocolQualifiers = NP; 886 ProtocolLAngleLoc = LAngleLoc; 887} 888 889void DeclSpec::SaveWrittenBuiltinSpecs() { 890 writtenBS.Sign = getTypeSpecSign(); 891 writtenBS.Width = getTypeSpecWidth(); 892 writtenBS.Type = getTypeSpecType(); 893 // Search the list of attributes for the presence of a mode attribute. 894 writtenBS.ModeAttr = false; 895 AttributeList* attrs = getAttributes().getList(); 896 while (attrs) { 897 if (attrs->getKind() == AttributeList::AT_Mode) { 898 writtenBS.ModeAttr = true; 899 break; 900 } 901 attrs = attrs->getNext(); 902 } 903} 904 905/// Finish - This does final analysis of the declspec, rejecting things like 906/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or 907/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, 908/// DeclSpec is guaranteed self-consistent, even if an error occurred. 909void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { 910 // Before possibly changing their values, save specs as written. 911 SaveWrittenBuiltinSpecs(); 912 913 // Check the type specifier components first. 914 915 // If decltype(auto) is used, no other type specifiers are permitted. 916 if (TypeSpecType == TST_decltype_auto && 917 (TypeSpecWidth != TSW_unspecified || 918 TypeSpecComplex != TSC_unspecified || 919 TypeSpecSign != TSS_unspecified || 920 TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool || 921 TypeQualifiers)) { 922 const unsigned NumLocs = 8; 923 SourceLocation ExtraLocs[NumLocs] = { 924 TSWLoc, TSCLoc, TSSLoc, AltiVecLoc, 925 TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc 926 }; 927 FixItHint Hints[NumLocs]; 928 SourceLocation FirstLoc; 929 for (unsigned I = 0; I != NumLocs; ++I) { 930 if (!ExtraLocs[I].isInvalid()) { 931 if (FirstLoc.isInvalid() || 932 PP.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I], 933 FirstLoc)) 934 FirstLoc = ExtraLocs[I]; 935 Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]); 936 } 937 } 938 TypeSpecWidth = TSW_unspecified; 939 TypeSpecComplex = TSC_unspecified; 940 TypeSpecSign = TSS_unspecified; 941 TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false; 942 TypeQualifiers = 0; 943 Diag(D, TSTLoc, diag::err_decltype_auto_cannot_be_combined) 944 << Hints[0] << Hints[1] << Hints[2] << Hints[3] 945 << Hints[4] << Hints[5] << Hints[6] << Hints[7]; 946 } 947 948 // Validate and finalize AltiVec vector declspec. 949 if (TypeAltiVecVector) { 950 if (TypeAltiVecBool) { 951 // Sign specifiers are not allowed with vector bool. (PIM 2.1) 952 if (TypeSpecSign != TSS_unspecified) { 953 Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec) 954 << getSpecifierName((TSS)TypeSpecSign); 955 } 956 957 // Only char/int are valid with vector bool. (PIM 2.1) 958 if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && 959 (TypeSpecType != TST_int)) || TypeAltiVecPixel) { 960 Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec) 961 << (TypeAltiVecPixel ? "__pixel" : 962 getSpecifierName((TST)TypeSpecType)); 963 } 964 965 // Only 'short' is valid with vector bool. (PIM 2.1) 966 if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) 967 Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) 968 << getSpecifierName((TSW)TypeSpecWidth); 969 970 // Elements of vector bool are interpreted as unsigned. (PIM 2.1) 971 if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || 972 (TypeSpecWidth != TSW_unspecified)) 973 TypeSpecSign = TSS_unsigned; 974 } 975 976 if (TypeAltiVecPixel) { 977 //TODO: perform validation 978 TypeSpecType = TST_int; 979 TypeSpecSign = TSS_unsigned; 980 TypeSpecWidth = TSW_short; 981 TypeSpecOwned = false; 982 } 983 } 984 985 // signed/unsigned are only valid with int/char/wchar_t. 986 if (TypeSpecSign != TSS_unspecified) { 987 if (TypeSpecType == TST_unspecified) 988 TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. 989 else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && 990 TypeSpecType != TST_char && TypeSpecType != TST_wchar) { 991 Diag(D, TSSLoc, diag::err_invalid_sign_spec) 992 << getSpecifierName((TST)TypeSpecType); 993 // signed double -> double. 994 TypeSpecSign = TSS_unspecified; 995 } 996 } 997 998 // Validate the width of the type. 999 switch (TypeSpecWidth) { 1000 case TSW_unspecified: break; 1001 case TSW_short: // short int 1002 case TSW_longlong: // long long int 1003 if (TypeSpecType == TST_unspecified) 1004 TypeSpecType = TST_int; // short -> short int, long long -> long long int. 1005 else if (TypeSpecType != TST_int) { 1006 Diag(D, TSWLoc, 1007 TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec 1008 : diag::err_invalid_longlong_spec) 1009 << getSpecifierName((TST)TypeSpecType); 1010 TypeSpecType = TST_int; 1011 TypeSpecOwned = false; 1012 } 1013 break; 1014 case TSW_long: // long double, long int 1015 if (TypeSpecType == TST_unspecified) 1016 TypeSpecType = TST_int; // long -> long int. 1017 else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { 1018 Diag(D, TSWLoc, diag::err_invalid_long_spec) 1019 << getSpecifierName((TST)TypeSpecType); 1020 TypeSpecType = TST_int; 1021 TypeSpecOwned = false; 1022 } 1023 break; 1024 } 1025 1026 // TODO: if the implementation does not implement _Complex or _Imaginary, 1027 // disallow their use. Need information about the backend. 1028 if (TypeSpecComplex != TSC_unspecified) { 1029 if (TypeSpecType == TST_unspecified) { 1030 Diag(D, TSCLoc, diag::ext_plain_complex) 1031 << FixItHint::CreateInsertion( 1032 PP.getLocForEndOfToken(getTypeSpecComplexLoc()), 1033 " double"); 1034 TypeSpecType = TST_double; // _Complex -> _Complex double. 1035 } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { 1036 // Note that this intentionally doesn't include _Complex _Bool. 1037 if (!PP.getLangOpts().CPlusPlus) 1038 Diag(D, TSTLoc, diag::ext_integer_complex); 1039 } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { 1040 Diag(D, TSCLoc, diag::err_invalid_complex_spec) 1041 << getSpecifierName((TST)TypeSpecType); 1042 TypeSpecComplex = TSC_unspecified; 1043 } 1044 } 1045 1046 // C11 6.7.1/3, C++11 [dcl.stc]p1, GNU TLS: __thread, thread_local and 1047 // _Thread_local can only appear with the 'static' and 'extern' storage class 1048 // specifiers. We also allow __private_extern__ as an extension. 1049 if (ThreadStorageClassSpec != TSCS_unspecified) { 1050 switch (StorageClassSpec) { 1051 case SCS_unspecified: 1052 case SCS_extern: 1053 case SCS_private_extern: 1054 case SCS_static: 1055 break; 1056 default: 1057 if (PP.getSourceManager().isBeforeInTranslationUnit( 1058 getThreadStorageClassSpecLoc(), getStorageClassSpecLoc())) 1059 Diag(D, getStorageClassSpecLoc(), 1060 diag::err_invalid_decl_spec_combination) 1061 << DeclSpec::getSpecifierName(getThreadStorageClassSpec()) 1062 << SourceRange(getThreadStorageClassSpecLoc()); 1063 else 1064 Diag(D, getThreadStorageClassSpecLoc(), 1065 diag::err_invalid_decl_spec_combination) 1066 << DeclSpec::getSpecifierName(getStorageClassSpec()) 1067 << SourceRange(getStorageClassSpecLoc()); 1068 // Discard the thread storage class specifier to recover. 1069 ThreadStorageClassSpec = TSCS_unspecified; 1070 ThreadStorageClassSpecLoc = SourceLocation(); 1071 } 1072 } 1073 1074 // If no type specifier was provided and we're parsing a language where 1075 // the type specifier is not optional, but we got 'auto' as a storage 1076 // class specifier, then assume this is an attempt to use C++0x's 'auto' 1077 // type specifier. 1078 if (PP.getLangOpts().CPlusPlus && 1079 TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) { 1080 TypeSpecType = TST_auto; 1081 StorageClassSpec = SCS_unspecified; 1082 TSTLoc = TSTNameLoc = StorageClassSpecLoc; 1083 StorageClassSpecLoc = SourceLocation(); 1084 } 1085 // Diagnose if we've recovered from an ill-formed 'auto' storage class 1086 // specifier in a pre-C++11 dialect of C++. 1087 if (!PP.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto) 1088 Diag(D, TSTLoc, diag::ext_auto_type_specifier); 1089 if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus11 && 1090 StorageClassSpec == SCS_auto) 1091 Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class) 1092 << FixItHint::CreateRemoval(StorageClassSpecLoc); 1093 if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) 1094 Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type) 1095 << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); 1096 if (Constexpr_specified) 1097 Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr); 1098 1099 // C++ [class.friend]p6: 1100 // No storage-class-specifier shall appear in the decl-specifier-seq 1101 // of a friend declaration. 1102 if (isFriendSpecified() && 1103 (getStorageClassSpec() || getThreadStorageClassSpec())) { 1104 SmallString<32> SpecName; 1105 SourceLocation SCLoc; 1106 FixItHint StorageHint, ThreadHint; 1107 1108 if (DeclSpec::SCS SC = getStorageClassSpec()) { 1109 SpecName = getSpecifierName(SC); 1110 SCLoc = getStorageClassSpecLoc(); 1111 StorageHint = FixItHint::CreateRemoval(SCLoc); 1112 } 1113 1114 if (DeclSpec::TSCS TSC = getThreadStorageClassSpec()) { 1115 if (!SpecName.empty()) SpecName += " "; 1116 SpecName += getSpecifierName(TSC); 1117 SCLoc = getThreadStorageClassSpecLoc(); 1118 ThreadHint = FixItHint::CreateRemoval(SCLoc); 1119 } 1120 1121 Diag(D, SCLoc, diag::err_friend_storage_spec) 1122 << SpecName << StorageHint << ThreadHint; 1123 1124 ClearStorageClassSpecs(); 1125 } 1126 1127 assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType)); 1128 1129 // Okay, now we can infer the real type. 1130 1131 // TODO: return "auto function" and other bad things based on the real type. 1132 1133 // 'data definition has no type or storage class'? 1134} 1135 1136bool DeclSpec::isMissingDeclaratorOk() { 1137 TST tst = getTypeSpecType(); 1138 return isDeclRep(tst) && getRepAsDecl() != 0 && 1139 StorageClassSpec != DeclSpec::SCS_typedef; 1140} 1141 1142void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 1143 OverloadedOperatorKind Op, 1144 SourceLocation SymbolLocations[3]) { 1145 Kind = IK_OperatorFunctionId; 1146 StartLocation = OperatorLoc; 1147 EndLocation = OperatorLoc; 1148 OperatorFunctionId.Operator = Op; 1149 for (unsigned I = 0; I != 3; ++I) { 1150 OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); 1151 1152 if (SymbolLocations[I].isValid()) 1153 EndLocation = SymbolLocations[I]; 1154 } 1155} 1156 1157bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, 1158 const char *&PrevSpec) { 1159 LastLocation = Loc; 1160 1161 if (Specifiers & VS) { 1162 PrevSpec = getSpecifierName(VS); 1163 return true; 1164 } 1165 1166 Specifiers |= VS; 1167 1168 switch (VS) { 1169 default: llvm_unreachable("Unknown specifier!"); 1170 case VS_Override: VS_overrideLoc = Loc; break; 1171 case VS_Sealed: 1172 case VS_Final: VS_finalLoc = Loc; break; 1173 } 1174 1175 return false; 1176} 1177 1178const char *VirtSpecifiers::getSpecifierName(Specifier VS) { 1179 switch (VS) { 1180 default: llvm_unreachable("Unknown specifier"); 1181 case VS_Override: return "override"; 1182 case VS_Final: return "final"; 1183 case VS_Sealed: return "sealed"; 1184 } 1185} 1186