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