DeclSpec.cpp revision ca63c200346c0ca9e00194ec6e34a5a7b0ed9321
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/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency! 15#include "clang/Sema/DeclSpec.h" 16#include "clang/Sema/ParsedTemplate.h" 17#include "clang/AST/ASTContext.h" 18#include "clang/AST/NestedNameSpecifier.h" 19#include "clang/AST/TypeLoc.h" 20#include "clang/Lex/Preprocessor.h" 21#include "clang/Basic/LangOptions.h" 22#include "llvm/ADT/STLExtras.h" 23#include "llvm/Support/ErrorHandling.h" 24#include <cstring> 25using namespace clang; 26 27 28static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc, 29 unsigned DiagID) { 30 return D.Report(Loc, DiagID); 31} 32 33 34void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { 35 assert(TemplateId && "NULL template-id annotation?"); 36 Kind = IK_TemplateId; 37 this->TemplateId = TemplateId; 38 StartLocation = TemplateId->TemplateNameLoc; 39 EndLocation = TemplateId->RAngleLoc; 40} 41 42void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { 43 assert(TemplateId && "NULL template-id annotation?"); 44 Kind = IK_ConstructorTemplateId; 45 this->TemplateId = TemplateId; 46 StartLocation = TemplateId->TemplateNameLoc; 47 EndLocation = TemplateId->RAngleLoc; 48} 49 50void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc, 51 TypeLoc TL, SourceLocation ColonColonLoc) { 52 Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc); 53 if (Range.getBegin().isInvalid()) 54 Range.setBegin(TL.getBeginLoc()); 55 Range.setEnd(ColonColonLoc); 56 57 assert(Range == Builder.getSourceRange() && 58 "NestedNameSpecifierLoc range computation incorrect"); 59} 60 61void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier, 62 SourceLocation IdentifierLoc, 63 SourceLocation ColonColonLoc) { 64 Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc); 65 66 if (Range.getBegin().isInvalid()) 67 Range.setBegin(IdentifierLoc); 68 Range.setEnd(ColonColonLoc); 69 70 assert(Range == Builder.getSourceRange() && 71 "NestedNameSpecifierLoc range computation incorrect"); 72} 73 74void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace, 75 SourceLocation NamespaceLoc, 76 SourceLocation ColonColonLoc) { 77 Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc); 78 79 if (Range.getBegin().isInvalid()) 80 Range.setBegin(NamespaceLoc); 81 Range.setEnd(ColonColonLoc); 82 83 assert(Range == Builder.getSourceRange() && 84 "NestedNameSpecifierLoc range computation incorrect"); 85} 86 87void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 88 SourceLocation AliasLoc, 89 SourceLocation ColonColonLoc) { 90 Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc); 91 92 if (Range.getBegin().isInvalid()) 93 Range.setBegin(AliasLoc); 94 Range.setEnd(ColonColonLoc); 95 96 assert(Range == Builder.getSourceRange() && 97 "NestedNameSpecifierLoc range computation incorrect"); 98} 99 100void CXXScopeSpec::MakeGlobal(ASTContext &Context, 101 SourceLocation ColonColonLoc) { 102 Builder.MakeGlobal(Context, ColonColonLoc); 103 104 Range = SourceRange(ColonColonLoc); 105 106 assert(Range == Builder.getSourceRange() && 107 "NestedNameSpecifierLoc range computation incorrect"); 108} 109 110void CXXScopeSpec::MakeTrivial(ASTContext &Context, 111 NestedNameSpecifier *Qualifier, SourceRange R) { 112 Builder.MakeTrivial(Context, Qualifier, R); 113 Range = R; 114} 115 116void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) { 117 if (!Other) { 118 Range = SourceRange(); 119 Builder.Clear(); 120 return; 121 } 122 123 Range = Other.getSourceRange(); 124 Builder.Adopt(Other); 125} 126 127NestedNameSpecifierLoc 128CXXScopeSpec::getWithLocInContext(ASTContext &Context) const { 129 if (!Builder.getRepresentation()) 130 return NestedNameSpecifierLoc(); 131 132 return Builder.getWithLocInContext(Context); 133} 134 135/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. 136/// "TheDeclarator" is the declarator that this will be added to. 137DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, 138 SourceLocation EllipsisLoc, 139 ParamInfo *ArgInfo, 140 unsigned NumArgs, 141 unsigned TypeQuals, 142 bool RefQualifierIsLvalueRef, 143 SourceLocation RefQualifierLoc, 144 ExceptionSpecificationType 145 ESpecType, 146 SourceLocation ESpecLoc, 147 ParsedType *Exceptions, 148 SourceRange *ExceptionRanges, 149 unsigned NumExceptions, 150 Expr *NoexceptExpr, 151 SourceLocation LocalRangeBegin, 152 SourceLocation LocalRangeEnd, 153 Declarator &TheDeclarator, 154 ParsedType TrailingReturnType) { 155 DeclaratorChunk I; 156 I.Kind = Function; 157 I.Loc = LocalRangeBegin; 158 I.EndLoc = LocalRangeEnd; 159 I.Fun.AttrList = 0; 160 I.Fun.hasPrototype = hasProto; 161 I.Fun.isVariadic = isVariadic; 162 I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); 163 I.Fun.DeleteArgInfo = false; 164 I.Fun.TypeQuals = TypeQuals; 165 I.Fun.NumArgs = NumArgs; 166 I.Fun.ArgInfo = 0; 167 I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; 168 I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); 169 I.Fun.ExceptionSpecType = ESpecType; 170 I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); 171 I.Fun.NumExceptions = 0; 172 I.Fun.Exceptions = 0; 173 I.Fun.NoexceptExpr = 0; 174 I.Fun.TrailingReturnType = TrailingReturnType.getAsOpaquePtr(); 175 176 // new[] an argument array if needed. 177 if (NumArgs) { 178 // If the 'InlineParams' in Declarator is unused and big enough, put our 179 // parameter list there (in an effort to avoid new/delete traffic). If it 180 // is already used (consider a function returning a function pointer) or too 181 // small (function taking too many arguments), go to the heap. 182 if (!TheDeclarator.InlineParamsUsed && 183 NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) { 184 I.Fun.ArgInfo = TheDeclarator.InlineParams; 185 I.Fun.DeleteArgInfo = false; 186 TheDeclarator.InlineParamsUsed = true; 187 } else { 188 I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs]; 189 I.Fun.DeleteArgInfo = true; 190 } 191 memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs); 192 } 193 194 // Check what exception specification information we should actually store. 195 switch (ESpecType) { 196 default: break; // By default, save nothing. 197 case EST_Dynamic: 198 // new[] an exception array if needed 199 if (NumExceptions) { 200 I.Fun.NumExceptions = NumExceptions; 201 I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions]; 202 for (unsigned i = 0; i != NumExceptions; ++i) { 203 I.Fun.Exceptions[i].Ty = Exceptions[i]; 204 I.Fun.Exceptions[i].Range = ExceptionRanges[i]; 205 } 206 } 207 break; 208 209 case EST_ComputedNoexcept: 210 I.Fun.NoexceptExpr = NoexceptExpr; 211 break; 212 } 213 return I; 214} 215 216/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this 217/// declaration specifier includes. 218/// 219unsigned DeclSpec::getParsedSpecifiers() const { 220 unsigned Res = 0; 221 if (StorageClassSpec != SCS_unspecified || 222 SCS_thread_specified) 223 Res |= PQ_StorageClassSpecifier; 224 225 if (TypeQualifiers != TQ_unspecified) 226 Res |= PQ_TypeQualifier; 227 228 if (hasTypeSpecifier()) 229 Res |= PQ_TypeSpecifier; 230 231 if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified) 232 Res |= PQ_FunctionSpecifier; 233 return Res; 234} 235 236template <class T> static bool BadSpecifier(T TNew, T TPrev, 237 const char *&PrevSpec, 238 unsigned &DiagID) { 239 PrevSpec = DeclSpec::getSpecifierName(TPrev); 240 DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec 241 : diag::err_invalid_decl_spec_combination); 242 return true; 243} 244 245const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) { 246 switch (S) { 247 case DeclSpec::SCS_unspecified: return "unspecified"; 248 case DeclSpec::SCS_typedef: return "typedef"; 249 case DeclSpec::SCS_extern: return "extern"; 250 case DeclSpec::SCS_static: return "static"; 251 case DeclSpec::SCS_auto: return "auto"; 252 case DeclSpec::SCS_register: return "register"; 253 case DeclSpec::SCS_private_extern: return "__private_extern__"; 254 case DeclSpec::SCS_mutable: return "mutable"; 255 } 256 llvm_unreachable("Unknown typespec!"); 257} 258 259const char *DeclSpec::getSpecifierName(TSW W) { 260 switch (W) { 261 case TSW_unspecified: return "unspecified"; 262 case TSW_short: return "short"; 263 case TSW_long: return "long"; 264 case TSW_longlong: return "long long"; 265 } 266 llvm_unreachable("Unknown typespec!"); 267} 268 269const char *DeclSpec::getSpecifierName(TSC C) { 270 switch (C) { 271 case TSC_unspecified: return "unspecified"; 272 case TSC_imaginary: return "imaginary"; 273 case TSC_complex: return "complex"; 274 } 275 llvm_unreachable("Unknown typespec!"); 276} 277 278 279const char *DeclSpec::getSpecifierName(TSS S) { 280 switch (S) { 281 case TSS_unspecified: return "unspecified"; 282 case TSS_signed: return "signed"; 283 case TSS_unsigned: return "unsigned"; 284 } 285 llvm_unreachable("Unknown typespec!"); 286} 287 288const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { 289 switch (T) { 290 case DeclSpec::TST_unspecified: return "unspecified"; 291 case DeclSpec::TST_void: return "void"; 292 case DeclSpec::TST_char: return "char"; 293 case DeclSpec::TST_wchar: return "wchar_t"; 294 case DeclSpec::TST_char16: return "char16_t"; 295 case DeclSpec::TST_char32: return "char32_t"; 296 case DeclSpec::TST_int: return "int"; 297 case DeclSpec::TST_float: return "float"; 298 case DeclSpec::TST_double: return "double"; 299 case DeclSpec::TST_bool: return "_Bool"; 300 case DeclSpec::TST_decimal32: return "_Decimal32"; 301 case DeclSpec::TST_decimal64: return "_Decimal64"; 302 case DeclSpec::TST_decimal128: return "_Decimal128"; 303 case DeclSpec::TST_enum: return "enum"; 304 case DeclSpec::TST_class: return "class"; 305 case DeclSpec::TST_union: return "union"; 306 case DeclSpec::TST_struct: return "struct"; 307 case DeclSpec::TST_typename: return "type-name"; 308 case DeclSpec::TST_typeofType: 309 case DeclSpec::TST_typeofExpr: return "typeof"; 310 case DeclSpec::TST_auto: return "auto"; 311 case DeclSpec::TST_decltype: return "(decltype)"; 312 case DeclSpec::TST_underlyingType: return "__underlying_type"; 313 case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; 314 case DeclSpec::TST_error: return "(error)"; 315 } 316 llvm_unreachable("Unknown typespec!"); 317} 318 319const char *DeclSpec::getSpecifierName(TQ T) { 320 switch (T) { 321 case DeclSpec::TQ_unspecified: return "unspecified"; 322 case DeclSpec::TQ_const: return "const"; 323 case DeclSpec::TQ_restrict: return "restrict"; 324 case DeclSpec::TQ_volatile: return "volatile"; 325 } 326 llvm_unreachable("Unknown typespec!"); 327} 328 329bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc, 330 const char *&PrevSpec, 331 unsigned &DiagID, 332 const LangOptions &Lang) { 333 // OpenCL prohibits extern, auto, register, and static 334 // It seems sensible to prohibit private_extern too 335 if (Lang.OpenCL) { 336 switch (S) { 337 case SCS_extern: 338 case SCS_private_extern: 339 case SCS_auto: 340 case SCS_register: 341 case SCS_static: 342 DiagID = diag::err_not_opencl_storage_class_specifier; 343 PrevSpec = getSpecifierName(S); 344 return true; 345 default: 346 break; 347 } 348 } 349 350 if (StorageClassSpec != SCS_unspecified) { 351 // Changing storage class is allowed only if the previous one 352 // was the 'extern' that is part of a linkage specification and 353 // the new storage class is 'typedef'. 354 if (!(SCS_extern_in_linkage_spec && 355 StorageClassSpec == SCS_extern && 356 S == SCS_typedef)) 357 return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID); 358 } 359 StorageClassSpec = S; 360 StorageClassSpecLoc = Loc; 361 assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield"); 362 return false; 363} 364 365bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc, 366 const char *&PrevSpec, 367 unsigned &DiagID) { 368 if (SCS_thread_specified) { 369 PrevSpec = "__thread"; 370 DiagID = diag::ext_duplicate_declspec; 371 return true; 372 } 373 SCS_thread_specified = true; 374 SCS_threadLoc = Loc; 375 return false; 376} 377 378/// These methods set the specified attribute of the DeclSpec, but return true 379/// and ignore the request if invalid (e.g. "extern" then "auto" is 380/// specified). 381bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, 382 const char *&PrevSpec, 383 unsigned &DiagID) { 384 // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that 385 // for 'long long' we will keep the source location of the first 'long'. 386 if (TypeSpecWidth == TSW_unspecified) 387 TSWLoc = Loc; 388 // Allow turning long -> long long. 389 else if (W != TSW_longlong || TypeSpecWidth != TSW_long) 390 return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); 391 TypeSpecWidth = W; 392 if (TypeAltiVecVector && !TypeAltiVecBool && 393 ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { 394 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 395 DiagID = diag::warn_vector_long_decl_spec_combination; 396 return true; 397 } 398 return false; 399} 400 401bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, 402 const char *&PrevSpec, 403 unsigned &DiagID) { 404 if (TypeSpecComplex != TSC_unspecified) 405 return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); 406 TypeSpecComplex = C; 407 TSCLoc = Loc; 408 return false; 409} 410 411bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, 412 const char *&PrevSpec, 413 unsigned &DiagID) { 414 if (TypeSpecSign != TSS_unspecified) 415 return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); 416 TypeSpecSign = S; 417 TSSLoc = Loc; 418 return false; 419} 420 421bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 422 const char *&PrevSpec, 423 unsigned &DiagID, 424 ParsedType Rep) { 425 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep); 426} 427 428bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 429 SourceLocation TagNameLoc, 430 const char *&PrevSpec, 431 unsigned &DiagID, 432 ParsedType Rep) { 433 assert(isTypeRep(T) && "T does not store a type"); 434 assert(Rep && "no type provided!"); 435 if (TypeSpecType != TST_unspecified) { 436 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 437 DiagID = diag::err_invalid_decl_spec_combination; 438 return true; 439 } 440 TypeSpecType = T; 441 TypeRep = Rep; 442 TSTLoc = TagKwLoc; 443 TSTNameLoc = TagNameLoc; 444 TypeSpecOwned = false; 445 return false; 446} 447 448bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 449 const char *&PrevSpec, 450 unsigned &DiagID, 451 Expr *Rep) { 452 assert(isExprRep(T) && "T does not store an expr"); 453 assert(Rep && "no expression provided!"); 454 if (TypeSpecType != TST_unspecified) { 455 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 456 DiagID = diag::err_invalid_decl_spec_combination; 457 return true; 458 } 459 TypeSpecType = T; 460 ExprRep = Rep; 461 TSTLoc = Loc; 462 TSTNameLoc = Loc; 463 TypeSpecOwned = false; 464 return false; 465} 466 467bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 468 const char *&PrevSpec, 469 unsigned &DiagID, 470 Decl *Rep, bool Owned) { 471 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned); 472} 473 474bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 475 SourceLocation TagNameLoc, 476 const char *&PrevSpec, 477 unsigned &DiagID, 478 Decl *Rep, bool Owned) { 479 assert(isDeclRep(T) && "T does not store a decl"); 480 // Unlike the other cases, we don't assert that we actually get a decl. 481 482 if (TypeSpecType != TST_unspecified) { 483 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 484 DiagID = diag::err_invalid_decl_spec_combination; 485 return true; 486 } 487 TypeSpecType = T; 488 DeclRep = Rep; 489 TSTLoc = TagKwLoc; 490 TSTNameLoc = TagNameLoc; 491 TypeSpecOwned = Owned; 492 return false; 493} 494 495bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 496 const char *&PrevSpec, 497 unsigned &DiagID) { 498 assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && 499 "rep required for these type-spec kinds!"); 500 if (TypeSpecType != TST_unspecified) { 501 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 502 DiagID = diag::err_invalid_decl_spec_combination; 503 return true; 504 } 505 TSTLoc = Loc; 506 TSTNameLoc = Loc; 507 if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { 508 TypeAltiVecBool = true; 509 return false; 510 } 511 TypeSpecType = T; 512 TypeSpecOwned = false; 513 if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { 514 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 515 DiagID = diag::err_invalid_vector_decl_spec; 516 return true; 517 } 518 return false; 519} 520 521bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 522 const char *&PrevSpec, unsigned &DiagID) { 523 if (TypeSpecType != TST_unspecified) { 524 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 525 DiagID = diag::err_invalid_vector_decl_spec_combination; 526 return true; 527 } 528 TypeAltiVecVector = isAltiVecVector; 529 AltiVecLoc = Loc; 530 return false; 531} 532 533bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 534 const char *&PrevSpec, unsigned &DiagID) { 535 if (!TypeAltiVecVector || TypeAltiVecPixel || 536 (TypeSpecType != TST_unspecified)) { 537 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 538 DiagID = diag::err_invalid_pixel_decl_spec_combination; 539 return true; 540 } 541 TypeAltiVecPixel = isAltiVecPixel; 542 TSTLoc = Loc; 543 TSTNameLoc = Loc; 544 return false; 545} 546 547bool DeclSpec::SetTypeSpecError() { 548 TypeSpecType = TST_error; 549 TypeSpecOwned = false; 550 TSTLoc = SourceLocation(); 551 TSTNameLoc = SourceLocation(); 552 return false; 553} 554 555bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 556 unsigned &DiagID, const LangOptions &Lang) { 557 // Duplicates turn into warnings pre-C99. 558 if ((TypeQualifiers & T) && !Lang.C99) 559 return BadSpecifier(T, T, PrevSpec, DiagID); 560 TypeQualifiers |= T; 561 562 switch (T) { 563 default: assert(0 && "Unknown type qualifier!"); 564 case TQ_const: TQ_constLoc = Loc; break; 565 case TQ_restrict: TQ_restrictLoc = Loc; break; 566 case TQ_volatile: TQ_volatileLoc = Loc; break; 567 } 568 return false; 569} 570 571bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, 572 unsigned &DiagID) { 573 // 'inline inline' is ok. 574 FS_inline_specified = true; 575 FS_inlineLoc = Loc; 576 return false; 577} 578 579bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, 580 unsigned &DiagID) { 581 // 'virtual virtual' is ok. 582 FS_virtual_specified = true; 583 FS_virtualLoc = Loc; 584 return false; 585} 586 587bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, 588 unsigned &DiagID) { 589 // 'explicit explicit' is ok. 590 FS_explicit_specified = true; 591 FS_explicitLoc = Loc; 592 return false; 593} 594 595bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 596 unsigned &DiagID) { 597 if (Friend_specified) { 598 PrevSpec = "friend"; 599 DiagID = diag::ext_duplicate_declspec; 600 return true; 601 } 602 603 Friend_specified = true; 604 FriendLoc = Loc; 605 return false; 606} 607 608bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, 609 unsigned &DiagID) { 610 // 'constexpr constexpr' is ok. 611 Constexpr_specified = true; 612 ConstexprLoc = Loc; 613 return false; 614} 615 616void DeclSpec::setProtocolQualifiers(Decl * const *Protos, 617 unsigned NP, 618 SourceLocation *ProtoLocs, 619 SourceLocation LAngleLoc) { 620 if (NP == 0) return; 621 ProtocolQualifiers = new Decl*[NP]; 622 ProtocolLocs = new SourceLocation[NP]; 623 memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP); 624 memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); 625 NumProtocolQualifiers = NP; 626 ProtocolLAngleLoc = LAngleLoc; 627} 628 629void DeclSpec::SaveWrittenBuiltinSpecs() { 630 writtenBS.Sign = getTypeSpecSign(); 631 writtenBS.Width = getTypeSpecWidth(); 632 writtenBS.Type = getTypeSpecType(); 633 // Search the list of attributes for the presence of a mode attribute. 634 writtenBS.ModeAttr = false; 635 AttributeList* attrs = getAttributes().getList(); 636 while (attrs) { 637 if (attrs->getKind() == AttributeList::AT_mode) { 638 writtenBS.ModeAttr = true; 639 break; 640 } 641 attrs = attrs->getNext(); 642 } 643} 644 645void DeclSpec::SaveStorageSpecifierAsWritten() { 646 if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern) 647 // If 'extern' is part of a linkage specification, 648 // then it is not a storage class "as written". 649 StorageClassSpecAsWritten = SCS_unspecified; 650 else 651 StorageClassSpecAsWritten = StorageClassSpec; 652} 653 654/// Finish - This does final analysis of the declspec, rejecting things like 655/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or 656/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, 657/// DeclSpec is guaranteed self-consistent, even if an error occurred. 658void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { 659 // Before possibly changing their values, save specs as written. 660 SaveWrittenBuiltinSpecs(); 661 SaveStorageSpecifierAsWritten(); 662 663 // Check the type specifier components first. 664 665 // Validate and finalize AltiVec vector declspec. 666 if (TypeAltiVecVector) { 667 if (TypeAltiVecBool) { 668 // Sign specifiers are not allowed with vector bool. (PIM 2.1) 669 if (TypeSpecSign != TSS_unspecified) { 670 Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec) 671 << getSpecifierName((TSS)TypeSpecSign); 672 } 673 674 // Only char/int are valid with vector bool. (PIM 2.1) 675 if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && 676 (TypeSpecType != TST_int)) || TypeAltiVecPixel) { 677 Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec) 678 << (TypeAltiVecPixel ? "__pixel" : 679 getSpecifierName((TST)TypeSpecType)); 680 } 681 682 // Only 'short' is valid with vector bool. (PIM 2.1) 683 if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) 684 Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) 685 << getSpecifierName((TSW)TypeSpecWidth); 686 687 // Elements of vector bool are interpreted as unsigned. (PIM 2.1) 688 if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || 689 (TypeSpecWidth != TSW_unspecified)) 690 TypeSpecSign = TSS_unsigned; 691 } 692 693 if (TypeAltiVecPixel) { 694 //TODO: perform validation 695 TypeSpecType = TST_int; 696 TypeSpecSign = TSS_unsigned; 697 TypeSpecWidth = TSW_short; 698 TypeSpecOwned = false; 699 } 700 } 701 702 // signed/unsigned are only valid with int/char/wchar_t. 703 if (TypeSpecSign != TSS_unspecified) { 704 if (TypeSpecType == TST_unspecified) 705 TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. 706 else if (TypeSpecType != TST_int && 707 TypeSpecType != TST_char && TypeSpecType != TST_wchar) { 708 Diag(D, TSSLoc, diag::err_invalid_sign_spec) 709 << getSpecifierName((TST)TypeSpecType); 710 // signed double -> double. 711 TypeSpecSign = TSS_unspecified; 712 } 713 } 714 715 // Validate the width of the type. 716 switch (TypeSpecWidth) { 717 case TSW_unspecified: break; 718 case TSW_short: // short int 719 case TSW_longlong: // long long int 720 if (TypeSpecType == TST_unspecified) 721 TypeSpecType = TST_int; // short -> short int, long long -> long long int. 722 else if (TypeSpecType != TST_int) { 723 Diag(D, TSWLoc, 724 TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec 725 : diag::err_invalid_longlong_spec) 726 << getSpecifierName((TST)TypeSpecType); 727 TypeSpecType = TST_int; 728 TypeSpecOwned = false; 729 } 730 break; 731 case TSW_long: // long double, long int 732 if (TypeSpecType == TST_unspecified) 733 TypeSpecType = TST_int; // long -> long int. 734 else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { 735 Diag(D, TSWLoc, diag::err_invalid_long_spec) 736 << getSpecifierName((TST)TypeSpecType); 737 TypeSpecType = TST_int; 738 TypeSpecOwned = false; 739 } 740 break; 741 } 742 743 // TODO: if the implementation does not implement _Complex or _Imaginary, 744 // disallow their use. Need information about the backend. 745 if (TypeSpecComplex != TSC_unspecified) { 746 if (TypeSpecType == TST_unspecified) { 747 Diag(D, TSCLoc, diag::ext_plain_complex) 748 << FixItHint::CreateInsertion( 749 PP.getLocForEndOfToken(getTypeSpecComplexLoc()), 750 " double"); 751 TypeSpecType = TST_double; // _Complex -> _Complex double. 752 } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { 753 // Note that this intentionally doesn't include _Complex _Bool. 754 Diag(D, TSTLoc, diag::ext_integer_complex); 755 } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { 756 Diag(D, TSCLoc, diag::err_invalid_complex_spec) 757 << getSpecifierName((TST)TypeSpecType); 758 TypeSpecComplex = TSC_unspecified; 759 } 760 } 761 762 // C++ [class.friend]p6: 763 // No storage-class-specifier shall appear in the decl-specifier-seq 764 // of a friend declaration. 765 if (isFriendSpecified() && getStorageClassSpec()) { 766 DeclSpec::SCS SC = getStorageClassSpec(); 767 const char *SpecName = getSpecifierName(SC); 768 769 SourceLocation SCLoc = getStorageClassSpecLoc(); 770 SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName)); 771 772 Diag(D, SCLoc, diag::err_friend_storage_spec) 773 << SpecName 774 << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc)); 775 776 ClearStorageClassSpecs(); 777 } 778 779 assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType)); 780 781 // Okay, now we can infer the real type. 782 783 // TODO: return "auto function" and other bad things based on the real type. 784 785 // 'data definition has no type or storage class'? 786} 787 788bool DeclSpec::isMissingDeclaratorOk() { 789 TST tst = getTypeSpecType(); 790 return isDeclRep(tst) && getRepAsDecl() != 0 && 791 StorageClassSpec != DeclSpec::SCS_typedef; 792} 793 794void UnqualifiedId::clear() { 795 if (Kind == IK_TemplateId) 796 TemplateId->Destroy(); 797 798 Kind = IK_Identifier; 799 Identifier = 0; 800 StartLocation = SourceLocation(); 801 EndLocation = SourceLocation(); 802} 803 804void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 805 OverloadedOperatorKind Op, 806 SourceLocation SymbolLocations[3]) { 807 Kind = IK_OperatorFunctionId; 808 StartLocation = OperatorLoc; 809 EndLocation = OperatorLoc; 810 OperatorFunctionId.Operator = Op; 811 for (unsigned I = 0; I != 3; ++I) { 812 OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); 813 814 if (SymbolLocations[I].isValid()) 815 EndLocation = SymbolLocations[I]; 816 } 817} 818 819bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, 820 const char *&PrevSpec) { 821 LastLocation = Loc; 822 823 if (Specifiers & VS) { 824 PrevSpec = getSpecifierName(VS); 825 return true; 826 } 827 828 Specifiers |= VS; 829 830 switch (VS) { 831 default: assert(0 && "Unknown specifier!"); 832 case VS_Override: VS_overrideLoc = Loc; break; 833 case VS_Final: VS_finalLoc = Loc; break; 834 } 835 836 return false; 837} 838 839const char *VirtSpecifiers::getSpecifierName(Specifier VS) { 840 switch (VS) { 841 default: assert(0 && "Unknown specifier"); 842 case VS_Override: return "override"; 843 case VS_Final: return "final"; 844 } 845} 846