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