DeclSpec.cpp revision b1f39680a2e3bce508dba0600665860e5ba5fb70
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_error: return "(error)"; 313 } 314 llvm_unreachable("Unknown typespec!"); 315} 316 317const char *DeclSpec::getSpecifierName(TQ T) { 318 switch (T) { 319 case DeclSpec::TQ_unspecified: return "unspecified"; 320 case DeclSpec::TQ_const: return "const"; 321 case DeclSpec::TQ_restrict: return "restrict"; 322 case DeclSpec::TQ_volatile: return "volatile"; 323 } 324 llvm_unreachable("Unknown typespec!"); 325} 326 327bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc, 328 const char *&PrevSpec, 329 unsigned &DiagID, 330 const LangOptions &Lang) { 331 // OpenCL prohibits extern, auto, register, and static 332 // It seems sensible to prohibit private_extern too 333 if (Lang.OpenCL) { 334 switch (S) { 335 case SCS_extern: 336 case SCS_private_extern: 337 case SCS_auto: 338 case SCS_register: 339 case SCS_static: 340 DiagID = diag::err_not_opencl_storage_class_specifier; 341 PrevSpec = getSpecifierName(S); 342 return true; 343 default: 344 break; 345 } 346 } 347 348 if (StorageClassSpec != SCS_unspecified) { 349 // Changing storage class is allowed only if the previous one 350 // was the 'extern' that is part of a linkage specification and 351 // the new storage class is 'typedef'. 352 if (!(SCS_extern_in_linkage_spec && 353 StorageClassSpec == SCS_extern && 354 S == SCS_typedef)) 355 return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID); 356 } 357 StorageClassSpec = S; 358 StorageClassSpecLoc = Loc; 359 assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield"); 360 return false; 361} 362 363bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc, 364 const char *&PrevSpec, 365 unsigned &DiagID) { 366 if (SCS_thread_specified) { 367 PrevSpec = "__thread"; 368 DiagID = diag::ext_duplicate_declspec; 369 return true; 370 } 371 SCS_thread_specified = true; 372 SCS_threadLoc = Loc; 373 return false; 374} 375 376/// These methods set the specified attribute of the DeclSpec, but return true 377/// and ignore the request if invalid (e.g. "extern" then "auto" is 378/// specified). 379bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, 380 const char *&PrevSpec, 381 unsigned &DiagID) { 382 // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that 383 // for 'long long' we will keep the source location of the first 'long'. 384 if (TypeSpecWidth == TSW_unspecified) 385 TSWLoc = Loc; 386 // Allow turning long -> long long. 387 else if (W != TSW_longlong || TypeSpecWidth != TSW_long) 388 return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); 389 TypeSpecWidth = W; 390 if (TypeAltiVecVector && !TypeAltiVecBool && 391 ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { 392 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 393 DiagID = diag::warn_vector_long_decl_spec_combination; 394 return true; 395 } 396 return false; 397} 398 399bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, 400 const char *&PrevSpec, 401 unsigned &DiagID) { 402 if (TypeSpecComplex != TSC_unspecified) 403 return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); 404 TypeSpecComplex = C; 405 TSCLoc = Loc; 406 return false; 407} 408 409bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, 410 const char *&PrevSpec, 411 unsigned &DiagID) { 412 if (TypeSpecSign != TSS_unspecified) 413 return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); 414 TypeSpecSign = S; 415 TSSLoc = Loc; 416 return false; 417} 418 419bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 420 const char *&PrevSpec, 421 unsigned &DiagID, 422 ParsedType Rep) { 423 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep); 424} 425 426bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 427 SourceLocation TagNameLoc, 428 const char *&PrevSpec, 429 unsigned &DiagID, 430 ParsedType Rep) { 431 assert(isTypeRep(T) && "T does not store a type"); 432 assert(Rep && "no type provided!"); 433 if (TypeSpecType != TST_unspecified) { 434 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 435 DiagID = diag::err_invalid_decl_spec_combination; 436 return true; 437 } 438 TypeSpecType = T; 439 TypeRep = Rep; 440 TSTLoc = TagKwLoc; 441 TSTNameLoc = TagNameLoc; 442 TypeSpecOwned = false; 443 return false; 444} 445 446bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 447 const char *&PrevSpec, 448 unsigned &DiagID, 449 Expr *Rep) { 450 assert(isExprRep(T) && "T does not store an expr"); 451 assert(Rep && "no expression provided!"); 452 if (TypeSpecType != TST_unspecified) { 453 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 454 DiagID = diag::err_invalid_decl_spec_combination; 455 return true; 456 } 457 TypeSpecType = T; 458 ExprRep = Rep; 459 TSTLoc = Loc; 460 TSTNameLoc = Loc; 461 TypeSpecOwned = false; 462 return false; 463} 464 465bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 466 const char *&PrevSpec, 467 unsigned &DiagID, 468 Decl *Rep, bool Owned) { 469 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned); 470} 471 472bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 473 SourceLocation TagNameLoc, 474 const char *&PrevSpec, 475 unsigned &DiagID, 476 Decl *Rep, bool Owned) { 477 assert(isDeclRep(T) && "T does not store a decl"); 478 // Unlike the other cases, we don't assert that we actually get a decl. 479 480 if (TypeSpecType != TST_unspecified) { 481 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 482 DiagID = diag::err_invalid_decl_spec_combination; 483 return true; 484 } 485 TypeSpecType = T; 486 DeclRep = Rep; 487 TSTLoc = TagKwLoc; 488 TSTNameLoc = TagNameLoc; 489 TypeSpecOwned = Owned; 490 return false; 491} 492 493bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 494 const char *&PrevSpec, 495 unsigned &DiagID) { 496 assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && 497 "rep required for these type-spec kinds!"); 498 if (TypeSpecType != TST_unspecified) { 499 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 500 DiagID = diag::err_invalid_decl_spec_combination; 501 return true; 502 } 503 TSTLoc = Loc; 504 TSTNameLoc = Loc; 505 if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { 506 TypeAltiVecBool = true; 507 return false; 508 } 509 TypeSpecType = T; 510 TypeSpecOwned = false; 511 if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { 512 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 513 DiagID = diag::err_invalid_vector_decl_spec; 514 return true; 515 } 516 return false; 517} 518 519bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 520 const char *&PrevSpec, unsigned &DiagID) { 521 if (TypeSpecType != TST_unspecified) { 522 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 523 DiagID = diag::err_invalid_vector_decl_spec_combination; 524 return true; 525 } 526 TypeAltiVecVector = isAltiVecVector; 527 AltiVecLoc = Loc; 528 return false; 529} 530 531bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 532 const char *&PrevSpec, unsigned &DiagID) { 533 if (!TypeAltiVecVector || TypeAltiVecPixel || 534 (TypeSpecType != TST_unspecified)) { 535 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 536 DiagID = diag::err_invalid_pixel_decl_spec_combination; 537 return true; 538 } 539 TypeAltiVecPixel = isAltiVecPixel; 540 TSTLoc = Loc; 541 TSTNameLoc = Loc; 542 return false; 543} 544 545bool DeclSpec::SetTypeSpecError() { 546 TypeSpecType = TST_error; 547 TypeSpecOwned = false; 548 TSTLoc = SourceLocation(); 549 TSTNameLoc = SourceLocation(); 550 return false; 551} 552 553bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 554 unsigned &DiagID, const LangOptions &Lang) { 555 // Duplicates turn into warnings pre-C99. 556 if ((TypeQualifiers & T) && !Lang.C99) 557 return BadSpecifier(T, T, PrevSpec, DiagID); 558 TypeQualifiers |= T; 559 560 switch (T) { 561 default: assert(0 && "Unknown type qualifier!"); 562 case TQ_const: TQ_constLoc = Loc; break; 563 case TQ_restrict: TQ_restrictLoc = Loc; break; 564 case TQ_volatile: TQ_volatileLoc = Loc; break; 565 } 566 return false; 567} 568 569bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, 570 unsigned &DiagID) { 571 // 'inline inline' is ok. 572 FS_inline_specified = true; 573 FS_inlineLoc = Loc; 574 return false; 575} 576 577bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, 578 unsigned &DiagID) { 579 // 'virtual virtual' is ok. 580 FS_virtual_specified = true; 581 FS_virtualLoc = Loc; 582 return false; 583} 584 585bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, 586 unsigned &DiagID) { 587 // 'explicit explicit' is ok. 588 FS_explicit_specified = true; 589 FS_explicitLoc = Loc; 590 return false; 591} 592 593bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 594 unsigned &DiagID) { 595 if (Friend_specified) { 596 PrevSpec = "friend"; 597 DiagID = diag::ext_duplicate_declspec; 598 return true; 599 } 600 601 Friend_specified = true; 602 FriendLoc = Loc; 603 return false; 604} 605 606bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, 607 unsigned &DiagID) { 608 // 'constexpr constexpr' is ok. 609 Constexpr_specified = true; 610 ConstexprLoc = Loc; 611 return false; 612} 613 614void DeclSpec::setProtocolQualifiers(Decl * const *Protos, 615 unsigned NP, 616 SourceLocation *ProtoLocs, 617 SourceLocation LAngleLoc) { 618 if (NP == 0) return; 619 ProtocolQualifiers = new Decl*[NP]; 620 ProtocolLocs = new SourceLocation[NP]; 621 memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP); 622 memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); 623 NumProtocolQualifiers = NP; 624 ProtocolLAngleLoc = LAngleLoc; 625} 626 627void DeclSpec::SaveWrittenBuiltinSpecs() { 628 writtenBS.Sign = getTypeSpecSign(); 629 writtenBS.Width = getTypeSpecWidth(); 630 writtenBS.Type = getTypeSpecType(); 631 // Search the list of attributes for the presence of a mode attribute. 632 writtenBS.ModeAttr = false; 633 AttributeList* attrs = getAttributes().getList(); 634 while (attrs) { 635 if (attrs->getKind() == AttributeList::AT_mode) { 636 writtenBS.ModeAttr = true; 637 break; 638 } 639 attrs = attrs->getNext(); 640 } 641} 642 643void DeclSpec::SaveStorageSpecifierAsWritten() { 644 if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern) 645 // If 'extern' is part of a linkage specification, 646 // then it is not a storage class "as written". 647 StorageClassSpecAsWritten = SCS_unspecified; 648 else 649 StorageClassSpecAsWritten = StorageClassSpec; 650} 651 652/// Finish - This does final analysis of the declspec, rejecting things like 653/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or 654/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, 655/// DeclSpec is guaranteed self-consistent, even if an error occurred. 656void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { 657 // Before possibly changing their values, save specs as written. 658 SaveWrittenBuiltinSpecs(); 659 SaveStorageSpecifierAsWritten(); 660 661 // Check the type specifier components first. 662 663 // Validate and finalize AltiVec vector declspec. 664 if (TypeAltiVecVector) { 665 if (TypeAltiVecBool) { 666 // Sign specifiers are not allowed with vector bool. (PIM 2.1) 667 if (TypeSpecSign != TSS_unspecified) { 668 Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec) 669 << getSpecifierName((TSS)TypeSpecSign); 670 } 671 672 // Only char/int are valid with vector bool. (PIM 2.1) 673 if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && 674 (TypeSpecType != TST_int)) || TypeAltiVecPixel) { 675 Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec) 676 << (TypeAltiVecPixel ? "__pixel" : 677 getSpecifierName((TST)TypeSpecType)); 678 } 679 680 // Only 'short' is valid with vector bool. (PIM 2.1) 681 if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) 682 Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) 683 << getSpecifierName((TSW)TypeSpecWidth); 684 685 // Elements of vector bool are interpreted as unsigned. (PIM 2.1) 686 if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || 687 (TypeSpecWidth != TSW_unspecified)) 688 TypeSpecSign = TSS_unsigned; 689 } 690 691 if (TypeAltiVecPixel) { 692 //TODO: perform validation 693 TypeSpecType = TST_int; 694 TypeSpecSign = TSS_unsigned; 695 TypeSpecWidth = TSW_short; 696 TypeSpecOwned = false; 697 } 698 } 699 700 // signed/unsigned are only valid with int/char/wchar_t. 701 if (TypeSpecSign != TSS_unspecified) { 702 if (TypeSpecType == TST_unspecified) 703 TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. 704 else if (TypeSpecType != TST_int && 705 TypeSpecType != TST_char && TypeSpecType != TST_wchar) { 706 Diag(D, TSSLoc, diag::err_invalid_sign_spec) 707 << getSpecifierName((TST)TypeSpecType); 708 // signed double -> double. 709 TypeSpecSign = TSS_unspecified; 710 } 711 } 712 713 // Validate the width of the type. 714 switch (TypeSpecWidth) { 715 case TSW_unspecified: break; 716 case TSW_short: // short int 717 case TSW_longlong: // long long int 718 if (TypeSpecType == TST_unspecified) 719 TypeSpecType = TST_int; // short -> short int, long long -> long long int. 720 else if (TypeSpecType != TST_int) { 721 Diag(D, TSWLoc, 722 TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec 723 : diag::err_invalid_longlong_spec) 724 << getSpecifierName((TST)TypeSpecType); 725 TypeSpecType = TST_int; 726 TypeSpecOwned = false; 727 } 728 break; 729 case TSW_long: // long double, long int 730 if (TypeSpecType == TST_unspecified) 731 TypeSpecType = TST_int; // long -> long int. 732 else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { 733 Diag(D, TSWLoc, diag::err_invalid_long_spec) 734 << getSpecifierName((TST)TypeSpecType); 735 TypeSpecType = TST_int; 736 TypeSpecOwned = false; 737 } 738 break; 739 } 740 741 // TODO: if the implementation does not implement _Complex or _Imaginary, 742 // disallow their use. Need information about the backend. 743 if (TypeSpecComplex != TSC_unspecified) { 744 if (TypeSpecType == TST_unspecified) { 745 Diag(D, TSCLoc, diag::ext_plain_complex) 746 << FixItHint::CreateInsertion( 747 PP.getLocForEndOfToken(getTypeSpecComplexLoc()), 748 " double"); 749 TypeSpecType = TST_double; // _Complex -> _Complex double. 750 } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { 751 // Note that this intentionally doesn't include _Complex _Bool. 752 Diag(D, TSTLoc, diag::ext_integer_complex); 753 } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { 754 Diag(D, TSCLoc, diag::err_invalid_complex_spec) 755 << getSpecifierName((TST)TypeSpecType); 756 TypeSpecComplex = TSC_unspecified; 757 } 758 } 759 760 // C++ [class.friend]p6: 761 // No storage-class-specifier shall appear in the decl-specifier-seq 762 // of a friend declaration. 763 if (isFriendSpecified() && getStorageClassSpec()) { 764 DeclSpec::SCS SC = getStorageClassSpec(); 765 const char *SpecName = getSpecifierName(SC); 766 767 SourceLocation SCLoc = getStorageClassSpecLoc(); 768 SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName)); 769 770 Diag(D, SCLoc, diag::err_friend_storage_spec) 771 << SpecName 772 << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc)); 773 774 ClearStorageClassSpecs(); 775 } 776 777 assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType)); 778 779 // Okay, now we can infer the real type. 780 781 // TODO: return "auto function" and other bad things based on the real type. 782 783 // 'data definition has no type or storage class'? 784} 785 786bool DeclSpec::isMissingDeclaratorOk() { 787 TST tst = getTypeSpecType(); 788 return isDeclRep(tst) && getRepAsDecl() != 0 && 789 StorageClassSpec != DeclSpec::SCS_typedef; 790} 791 792void UnqualifiedId::clear() { 793 if (Kind == IK_TemplateId) 794 TemplateId->Destroy(); 795 796 Kind = IK_Identifier; 797 Identifier = 0; 798 StartLocation = SourceLocation(); 799 EndLocation = SourceLocation(); 800} 801 802void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 803 OverloadedOperatorKind Op, 804 SourceLocation SymbolLocations[3]) { 805 Kind = IK_OperatorFunctionId; 806 StartLocation = OperatorLoc; 807 EndLocation = OperatorLoc; 808 OperatorFunctionId.Operator = Op; 809 for (unsigned I = 0; I != 3; ++I) { 810 OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); 811 812 if (SymbolLocations[I].isValid()) 813 EndLocation = SymbolLocations[I]; 814 } 815} 816 817bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, 818 const char *&PrevSpec) { 819 LastLocation = Loc; 820 821 if (Specifiers & VS) { 822 PrevSpec = getSpecifierName(VS); 823 return true; 824 } 825 826 Specifiers |= VS; 827 828 switch (VS) { 829 default: assert(0 && "Unknown specifier!"); 830 case VS_Override: VS_overrideLoc = Loc; break; 831 case VS_Final: VS_finalLoc = Loc; break; 832 } 833 834 return false; 835} 836 837const char *VirtSpecifiers::getSpecifierName(Specifier VS) { 838 switch (VS) { 839 default: assert(0 && "Unknown specifier"); 840 case VS_Override: return "override"; 841 case VS_Final: return "final"; 842 } 843} 844 845bool ClassVirtSpecifiers::SetSpecifier(Specifier CVS, SourceLocation Loc, 846 const char *&PrevSpec) { 847 if (Specifiers & CVS) { 848 PrevSpec = getSpecifierName(CVS); 849 return true; 850 } 851 852 Specifiers |= CVS; 853 854 switch (CVS) { 855 default: assert(0 && "Unknown specifier!"); 856 case CVS_Final: CVS_finalLoc = Loc; break; 857 case CVS_Explicit: CVS_explicitLoc = Loc; break; 858 } 859 860 return false; 861} 862 863const char *ClassVirtSpecifiers::getSpecifierName(Specifier CVS) { 864 switch (CVS) { 865 default: assert(0 && "Unknown specifier"); 866 case CVS_Final: return "final"; 867 case CVS_Explicit: return "explicit"; 868 } 869} 870 871