DeclSpec.cpp revision 239462
1212795Sdim//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===// 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim// 8212795Sdim//===----------------------------------------------------------------------===// 9212795Sdim// 10212795Sdim// This file implements semantic analysis for declaration specifiers. 11212795Sdim// 12212795Sdim//===----------------------------------------------------------------------===// 13212795Sdim 14212795Sdim#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency! 15212795Sdim#include "clang/Sema/DeclSpec.h" 16224145Sdim#include "clang/Sema/LocInfoType.h" 17212795Sdim#include "clang/Sema/ParsedTemplate.h" 18234353Sdim#include "clang/Sema/SemaDiagnostic.h" 19226633Sdim#include "clang/Sema/Sema.h" 20219077Sdim#include "clang/AST/ASTContext.h" 21224145Sdim#include "clang/AST/Expr.h" 22219077Sdim#include "clang/AST/NestedNameSpecifier.h" 23219077Sdim#include "clang/AST/TypeLoc.h" 24212795Sdim#include "clang/Lex/Preprocessor.h" 25212795Sdim#include "clang/Basic/LangOptions.h" 26212795Sdim#include "llvm/ADT/STLExtras.h" 27212795Sdim#include "llvm/Support/ErrorHandling.h" 28212795Sdim#include <cstring> 29212795Sdimusing namespace clang; 30212795Sdim 31212795Sdim 32226633Sdimstatic DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc, 33218893Sdim unsigned DiagID) { 34218893Sdim return D.Report(Loc, DiagID); 35212795Sdim} 36212795Sdim 37212795Sdim 38212795Sdimvoid UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { 39212795Sdim assert(TemplateId && "NULL template-id annotation?"); 40212795Sdim Kind = IK_TemplateId; 41212795Sdim this->TemplateId = TemplateId; 42212795Sdim StartLocation = TemplateId->TemplateNameLoc; 43212795Sdim EndLocation = TemplateId->RAngleLoc; 44212795Sdim} 45212795Sdim 46212795Sdimvoid UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { 47212795Sdim assert(TemplateId && "NULL template-id annotation?"); 48212795Sdim Kind = IK_ConstructorTemplateId; 49212795Sdim this->TemplateId = TemplateId; 50212795Sdim StartLocation = TemplateId->TemplateNameLoc; 51212795Sdim EndLocation = TemplateId->RAngleLoc; 52212795Sdim} 53212795Sdim 54219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc, 55219077Sdim TypeLoc TL, SourceLocation ColonColonLoc) { 56221345Sdim Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc); 57219077Sdim if (Range.getBegin().isInvalid()) 58219077Sdim Range.setBegin(TL.getBeginLoc()); 59219077Sdim Range.setEnd(ColonColonLoc); 60219077Sdim 61221345Sdim assert(Range == Builder.getSourceRange() && 62219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 63219077Sdim} 64219077Sdim 65219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier, 66219077Sdim SourceLocation IdentifierLoc, 67219077Sdim SourceLocation ColonColonLoc) { 68221345Sdim Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc); 69221345Sdim 70219077Sdim if (Range.getBegin().isInvalid()) 71219077Sdim Range.setBegin(IdentifierLoc); 72219077Sdim Range.setEnd(ColonColonLoc); 73219077Sdim 74221345Sdim assert(Range == Builder.getSourceRange() && 75219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 76219077Sdim} 77219077Sdim 78219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace, 79219077Sdim SourceLocation NamespaceLoc, 80219077Sdim SourceLocation ColonColonLoc) { 81221345Sdim Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc); 82221345Sdim 83219077Sdim if (Range.getBegin().isInvalid()) 84219077Sdim Range.setBegin(NamespaceLoc); 85219077Sdim Range.setEnd(ColonColonLoc); 86219077Sdim 87221345Sdim assert(Range == Builder.getSourceRange() && 88219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 89219077Sdim} 90219077Sdim 91219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 92219077Sdim SourceLocation AliasLoc, 93219077Sdim SourceLocation ColonColonLoc) { 94221345Sdim Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc); 95221345Sdim 96219077Sdim if (Range.getBegin().isInvalid()) 97219077Sdim Range.setBegin(AliasLoc); 98219077Sdim Range.setEnd(ColonColonLoc); 99219077Sdim 100221345Sdim assert(Range == Builder.getSourceRange() && 101219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 102219077Sdim} 103219077Sdim 104219077Sdimvoid CXXScopeSpec::MakeGlobal(ASTContext &Context, 105219077Sdim SourceLocation ColonColonLoc) { 106221345Sdim Builder.MakeGlobal(Context, ColonColonLoc); 107221345Sdim 108219077Sdim Range = SourceRange(ColonColonLoc); 109219077Sdim 110221345Sdim assert(Range == Builder.getSourceRange() && 111219077Sdim "NestedNameSpecifierLoc range computation incorrect"); 112219077Sdim} 113219077Sdim 114219077Sdimvoid CXXScopeSpec::MakeTrivial(ASTContext &Context, 115219077Sdim NestedNameSpecifier *Qualifier, SourceRange R) { 116221345Sdim Builder.MakeTrivial(Context, Qualifier, R); 117219077Sdim Range = R; 118219077Sdim} 119219077Sdim 120219077Sdimvoid CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) { 121219077Sdim if (!Other) { 122219077Sdim Range = SourceRange(); 123221345Sdim Builder.Clear(); 124219077Sdim return; 125219077Sdim } 126221345Sdim 127219077Sdim Range = Other.getSourceRange(); 128221345Sdim Builder.Adopt(Other); 129219077Sdim} 130219077Sdim 131224145SdimSourceLocation CXXScopeSpec::getLastQualifierNameLoc() const { 132224145Sdim if (!Builder.getRepresentation()) 133224145Sdim return SourceLocation(); 134224145Sdim return Builder.getTemporary().getLocalBeginLoc(); 135224145Sdim} 136224145Sdim 137219077SdimNestedNameSpecifierLoc 138219077SdimCXXScopeSpec::getWithLocInContext(ASTContext &Context) const { 139221345Sdim if (!Builder.getRepresentation()) 140219077Sdim return NestedNameSpecifierLoc(); 141219077Sdim 142221345Sdim return Builder.getWithLocInContext(Context); 143219077Sdim} 144219077Sdim 145212795Sdim/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. 146212795Sdim/// "TheDeclarator" is the declarator that this will be added to. 147221345SdimDeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, 148239462Sdim bool isAmbiguous, 149212795Sdim SourceLocation EllipsisLoc, 150212795Sdim ParamInfo *ArgInfo, 151212795Sdim unsigned NumArgs, 152212795Sdim unsigned TypeQuals, 153218893Sdim bool RefQualifierIsLvalueRef, 154218893Sdim SourceLocation RefQualifierLoc, 155234353Sdim SourceLocation ConstQualifierLoc, 156234353Sdim SourceLocation 157234353Sdim VolatileQualifierLoc, 158224145Sdim SourceLocation MutableLoc, 159221345Sdim ExceptionSpecificationType 160221345Sdim ESpecType, 161221345Sdim SourceLocation ESpecLoc, 162212795Sdim ParsedType *Exceptions, 163212795Sdim SourceRange *ExceptionRanges, 164212795Sdim unsigned NumExceptions, 165221345Sdim Expr *NoexceptExpr, 166221345Sdim SourceLocation LocalRangeBegin, 167221345Sdim SourceLocation LocalRangeEnd, 168218893Sdim Declarator &TheDeclarator, 169239462Sdim TypeResult TrailingReturnType) { 170212795Sdim DeclaratorChunk I; 171221345Sdim I.Kind = Function; 172221345Sdim I.Loc = LocalRangeBegin; 173221345Sdim I.EndLoc = LocalRangeEnd; 174221345Sdim I.Fun.AttrList = 0; 175221345Sdim I.Fun.hasPrototype = hasProto; 176221345Sdim I.Fun.isVariadic = isVariadic; 177239462Sdim I.Fun.isAmbiguous = isAmbiguous; 178221345Sdim I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); 179221345Sdim I.Fun.DeleteArgInfo = false; 180221345Sdim I.Fun.TypeQuals = TypeQuals; 181221345Sdim I.Fun.NumArgs = NumArgs; 182221345Sdim I.Fun.ArgInfo = 0; 183218893Sdim I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; 184221345Sdim I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); 185234353Sdim I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding(); 186234353Sdim I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding(); 187224145Sdim I.Fun.MutableLoc = MutableLoc.getRawEncoding(); 188221345Sdim I.Fun.ExceptionSpecType = ESpecType; 189221345Sdim I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); 190221345Sdim I.Fun.NumExceptions = 0; 191221345Sdim I.Fun.Exceptions = 0; 192221345Sdim I.Fun.NoexceptExpr = 0; 193239462Sdim I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() || 194239462Sdim TrailingReturnType.isInvalid(); 195239462Sdim I.Fun.TrailingReturnType = TrailingReturnType.get(); 196212795Sdim 197212795Sdim // new[] an argument array if needed. 198212795Sdim if (NumArgs) { 199212795Sdim // If the 'InlineParams' in Declarator is unused and big enough, put our 200212795Sdim // parameter list there (in an effort to avoid new/delete traffic). If it 201212795Sdim // is already used (consider a function returning a function pointer) or too 202212795Sdim // small (function taking too many arguments), go to the heap. 203212795Sdim if (!TheDeclarator.InlineParamsUsed && 204212795Sdim NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) { 205212795Sdim I.Fun.ArgInfo = TheDeclarator.InlineParams; 206212795Sdim I.Fun.DeleteArgInfo = false; 207212795Sdim TheDeclarator.InlineParamsUsed = true; 208212795Sdim } else { 209212795Sdim I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs]; 210212795Sdim I.Fun.DeleteArgInfo = true; 211212795Sdim } 212212795Sdim memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs); 213212795Sdim } 214221345Sdim 215221345Sdim // Check what exception specification information we should actually store. 216221345Sdim switch (ESpecType) { 217221345Sdim default: break; // By default, save nothing. 218221345Sdim case EST_Dynamic: 219221345Sdim // new[] an exception array if needed 220221345Sdim if (NumExceptions) { 221221345Sdim I.Fun.NumExceptions = NumExceptions; 222221345Sdim I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions]; 223221345Sdim for (unsigned i = 0; i != NumExceptions; ++i) { 224221345Sdim I.Fun.Exceptions[i].Ty = Exceptions[i]; 225221345Sdim I.Fun.Exceptions[i].Range = ExceptionRanges[i]; 226221345Sdim } 227212795Sdim } 228221345Sdim break; 229221345Sdim 230221345Sdim case EST_ComputedNoexcept: 231221345Sdim I.Fun.NoexceptExpr = NoexceptExpr; 232221345Sdim break; 233212795Sdim } 234212795Sdim return I; 235212795Sdim} 236212795Sdim 237224145Sdimbool Declarator::isDeclarationOfFunction() const { 238224145Sdim for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { 239224145Sdim switch (DeclTypeInfo[i].Kind) { 240224145Sdim case DeclaratorChunk::Function: 241224145Sdim return true; 242224145Sdim case DeclaratorChunk::Paren: 243224145Sdim continue; 244224145Sdim case DeclaratorChunk::Pointer: 245224145Sdim case DeclaratorChunk::Reference: 246224145Sdim case DeclaratorChunk::Array: 247224145Sdim case DeclaratorChunk::BlockPointer: 248224145Sdim case DeclaratorChunk::MemberPointer: 249224145Sdim return false; 250224145Sdim } 251224145Sdim llvm_unreachable("Invalid type chunk"); 252224145Sdim } 253224145Sdim 254224145Sdim switch (DS.getTypeSpecType()) { 255226633Sdim case TST_atomic: 256224145Sdim case TST_auto: 257224145Sdim case TST_bool: 258224145Sdim case TST_char: 259224145Sdim case TST_char16: 260224145Sdim case TST_char32: 261224145Sdim case TST_class: 262224145Sdim case TST_decimal128: 263224145Sdim case TST_decimal32: 264224145Sdim case TST_decimal64: 265224145Sdim case TST_double: 266224145Sdim case TST_enum: 267224145Sdim case TST_error: 268224145Sdim case TST_float: 269226633Sdim case TST_half: 270224145Sdim case TST_int: 271234353Sdim case TST_int128: 272224145Sdim case TST_struct: 273224145Sdim case TST_union: 274224145Sdim case TST_unknown_anytype: 275224145Sdim case TST_unspecified: 276224145Sdim case TST_void: 277224145Sdim case TST_wchar: 278224145Sdim return false; 279224145Sdim 280224145Sdim case TST_decltype: 281224145Sdim case TST_typeofExpr: 282224145Sdim if (Expr *E = DS.getRepAsExpr()) 283224145Sdim return E->getType()->isFunctionType(); 284224145Sdim return false; 285224145Sdim 286224145Sdim case TST_underlyingType: 287224145Sdim case TST_typename: 288224145Sdim case TST_typeofType: { 289224145Sdim QualType QT = DS.getRepAsType().get(); 290224145Sdim if (QT.isNull()) 291224145Sdim return false; 292224145Sdim 293224145Sdim if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) 294224145Sdim QT = LIT->getType(); 295224145Sdim 296224145Sdim if (QT.isNull()) 297224145Sdim return false; 298224145Sdim 299224145Sdim return QT->isFunctionType(); 300224145Sdim } 301224145Sdim } 302234353Sdim 303234353Sdim llvm_unreachable("Invalid TypeSpecType!"); 304224145Sdim} 305224145Sdim 306212795Sdim/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this 307212795Sdim/// declaration specifier includes. 308212795Sdim/// 309212795Sdimunsigned DeclSpec::getParsedSpecifiers() const { 310212795Sdim unsigned Res = 0; 311212795Sdim if (StorageClassSpec != SCS_unspecified || 312212795Sdim SCS_thread_specified) 313212795Sdim Res |= PQ_StorageClassSpecifier; 314212795Sdim 315212795Sdim if (TypeQualifiers != TQ_unspecified) 316212795Sdim Res |= PQ_TypeQualifier; 317212795Sdim 318212795Sdim if (hasTypeSpecifier()) 319212795Sdim Res |= PQ_TypeSpecifier; 320212795Sdim 321212795Sdim if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified) 322212795Sdim Res |= PQ_FunctionSpecifier; 323212795Sdim return Res; 324212795Sdim} 325212795Sdim 326212795Sdimtemplate <class T> static bool BadSpecifier(T TNew, T TPrev, 327212795Sdim const char *&PrevSpec, 328212795Sdim unsigned &DiagID) { 329212795Sdim PrevSpec = DeclSpec::getSpecifierName(TPrev); 330212795Sdim DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec 331212795Sdim : diag::err_invalid_decl_spec_combination); 332212795Sdim return true; 333212795Sdim} 334212795Sdim 335212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::SCS S) { 336212795Sdim switch (S) { 337212795Sdim case DeclSpec::SCS_unspecified: return "unspecified"; 338212795Sdim case DeclSpec::SCS_typedef: return "typedef"; 339212795Sdim case DeclSpec::SCS_extern: return "extern"; 340212795Sdim case DeclSpec::SCS_static: return "static"; 341212795Sdim case DeclSpec::SCS_auto: return "auto"; 342212795Sdim case DeclSpec::SCS_register: return "register"; 343212795Sdim case DeclSpec::SCS_private_extern: return "__private_extern__"; 344212795Sdim case DeclSpec::SCS_mutable: return "mutable"; 345212795Sdim } 346212795Sdim llvm_unreachable("Unknown typespec!"); 347212795Sdim} 348212795Sdim 349212795Sdimconst char *DeclSpec::getSpecifierName(TSW W) { 350212795Sdim switch (W) { 351212795Sdim case TSW_unspecified: return "unspecified"; 352212795Sdim case TSW_short: return "short"; 353212795Sdim case TSW_long: return "long"; 354212795Sdim case TSW_longlong: return "long long"; 355212795Sdim } 356212795Sdim llvm_unreachable("Unknown typespec!"); 357212795Sdim} 358212795Sdim 359212795Sdimconst char *DeclSpec::getSpecifierName(TSC C) { 360212795Sdim switch (C) { 361212795Sdim case TSC_unspecified: return "unspecified"; 362212795Sdim case TSC_imaginary: return "imaginary"; 363212795Sdim case TSC_complex: return "complex"; 364212795Sdim } 365212795Sdim llvm_unreachable("Unknown typespec!"); 366212795Sdim} 367212795Sdim 368212795Sdim 369212795Sdimconst char *DeclSpec::getSpecifierName(TSS S) { 370212795Sdim switch (S) { 371212795Sdim case TSS_unspecified: return "unspecified"; 372212795Sdim case TSS_signed: return "signed"; 373212795Sdim case TSS_unsigned: return "unsigned"; 374212795Sdim } 375212795Sdim llvm_unreachable("Unknown typespec!"); 376212795Sdim} 377212795Sdim 378212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::TST T) { 379212795Sdim switch (T) { 380212795Sdim case DeclSpec::TST_unspecified: return "unspecified"; 381212795Sdim case DeclSpec::TST_void: return "void"; 382212795Sdim case DeclSpec::TST_char: return "char"; 383212795Sdim case DeclSpec::TST_wchar: return "wchar_t"; 384212795Sdim case DeclSpec::TST_char16: return "char16_t"; 385212795Sdim case DeclSpec::TST_char32: return "char32_t"; 386212795Sdim case DeclSpec::TST_int: return "int"; 387234353Sdim case DeclSpec::TST_int128: return "__int128"; 388226633Sdim case DeclSpec::TST_half: return "half"; 389212795Sdim case DeclSpec::TST_float: return "float"; 390212795Sdim case DeclSpec::TST_double: return "double"; 391212795Sdim case DeclSpec::TST_bool: return "_Bool"; 392212795Sdim case DeclSpec::TST_decimal32: return "_Decimal32"; 393212795Sdim case DeclSpec::TST_decimal64: return "_Decimal64"; 394212795Sdim case DeclSpec::TST_decimal128: return "_Decimal128"; 395212795Sdim case DeclSpec::TST_enum: return "enum"; 396212795Sdim case DeclSpec::TST_class: return "class"; 397212795Sdim case DeclSpec::TST_union: return "union"; 398212795Sdim case DeclSpec::TST_struct: return "struct"; 399212795Sdim case DeclSpec::TST_typename: return "type-name"; 400212795Sdim case DeclSpec::TST_typeofType: 401212795Sdim case DeclSpec::TST_typeofExpr: return "typeof"; 402212795Sdim case DeclSpec::TST_auto: return "auto"; 403212795Sdim case DeclSpec::TST_decltype: return "(decltype)"; 404223017Sdim case DeclSpec::TST_underlyingType: return "__underlying_type"; 405221345Sdim case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; 406226633Sdim case DeclSpec::TST_atomic: return "_Atomic"; 407212795Sdim case DeclSpec::TST_error: return "(error)"; 408212795Sdim } 409212795Sdim llvm_unreachable("Unknown typespec!"); 410212795Sdim} 411212795Sdim 412212795Sdimconst char *DeclSpec::getSpecifierName(TQ T) { 413212795Sdim switch (T) { 414212795Sdim case DeclSpec::TQ_unspecified: return "unspecified"; 415212795Sdim case DeclSpec::TQ_const: return "const"; 416212795Sdim case DeclSpec::TQ_restrict: return "restrict"; 417212795Sdim case DeclSpec::TQ_volatile: return "volatile"; 418212795Sdim } 419212795Sdim llvm_unreachable("Unknown typespec!"); 420212795Sdim} 421212795Sdim 422226633Sdimbool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, 423212795Sdim const char *&PrevSpec, 424226633Sdim unsigned &DiagID) { 425239462Sdim // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class 426239462Sdim // specifiers are not supported. 427218893Sdim // It seems sensible to prohibit private_extern too 428226633Sdim // The cl_clang_storage_class_specifiers extension enables support for 429226633Sdim // these storage-class specifiers. 430239462Sdim // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class 431239462Sdim // specifiers are not supported." 432234353Sdim if (S.getLangOpts().OpenCL && 433226633Sdim !S.getOpenCLOptions().cl_clang_storage_class_specifiers) { 434226633Sdim switch (SC) { 435218893Sdim case SCS_extern: 436218893Sdim case SCS_private_extern: 437239462Sdim case SCS_static: 438239462Sdim if (S.getLangOpts().OpenCLVersion < 120) { 439239462Sdim DiagID = diag::err_not_opencl_storage_class_specifier; 440239462Sdim PrevSpec = getSpecifierName(SC); 441239462Sdim return true; 442239462Sdim } 443239462Sdim break; 444218893Sdim case SCS_auto: 445218893Sdim case SCS_register: 446218893Sdim DiagID = diag::err_not_opencl_storage_class_specifier; 447226633Sdim PrevSpec = getSpecifierName(SC); 448218893Sdim return true; 449218893Sdim default: 450218893Sdim break; 451218893Sdim } 452218893Sdim } 453218893Sdim 454212795Sdim if (StorageClassSpec != SCS_unspecified) { 455226633Sdim // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode. 456226633Sdim bool isInvalid = true; 457234353Sdim if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) { 458226633Sdim if (SC == SCS_auto) 459226633Sdim return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID); 460226633Sdim if (StorageClassSpec == SCS_auto) { 461226633Sdim isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc, 462226633Sdim PrevSpec, DiagID); 463226633Sdim assert(!isInvalid && "auto SCS -> TST recovery failed"); 464226633Sdim } 465226633Sdim } 466226633Sdim 467212795Sdim // Changing storage class is allowed only if the previous one 468212795Sdim // was the 'extern' that is part of a linkage specification and 469212795Sdim // the new storage class is 'typedef'. 470226633Sdim if (isInvalid && 471226633Sdim !(SCS_extern_in_linkage_spec && 472212795Sdim StorageClassSpec == SCS_extern && 473226633Sdim SC == SCS_typedef)) 474226633Sdim return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID); 475212795Sdim } 476226633Sdim StorageClassSpec = SC; 477212795Sdim StorageClassSpecLoc = Loc; 478226633Sdim assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield"); 479212795Sdim return false; 480212795Sdim} 481212795Sdim 482212795Sdimbool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc, 483212795Sdim const char *&PrevSpec, 484212795Sdim unsigned &DiagID) { 485212795Sdim if (SCS_thread_specified) { 486212795Sdim PrevSpec = "__thread"; 487212795Sdim DiagID = diag::ext_duplicate_declspec; 488212795Sdim return true; 489212795Sdim } 490212795Sdim SCS_thread_specified = true; 491212795Sdim SCS_threadLoc = Loc; 492212795Sdim return false; 493212795Sdim} 494212795Sdim 495212795Sdim/// These methods set the specified attribute of the DeclSpec, but return true 496212795Sdim/// and ignore the request if invalid (e.g. "extern" then "auto" is 497212795Sdim/// specified). 498212795Sdimbool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, 499212795Sdim const char *&PrevSpec, 500212795Sdim unsigned &DiagID) { 501221345Sdim // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that 502221345Sdim // for 'long long' we will keep the source location of the first 'long'. 503221345Sdim if (TypeSpecWidth == TSW_unspecified) 504221345Sdim TSWLoc = Loc; 505221345Sdim // Allow turning long -> long long. 506221345Sdim else if (W != TSW_longlong || TypeSpecWidth != TSW_long) 507212795Sdim return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); 508212795Sdim TypeSpecWidth = W; 509212795Sdim if (TypeAltiVecVector && !TypeAltiVecBool && 510212795Sdim ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { 511212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 512212795Sdim DiagID = diag::warn_vector_long_decl_spec_combination; 513212795Sdim return true; 514212795Sdim } 515212795Sdim return false; 516212795Sdim} 517212795Sdim 518212795Sdimbool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, 519212795Sdim const char *&PrevSpec, 520212795Sdim unsigned &DiagID) { 521212795Sdim if (TypeSpecComplex != TSC_unspecified) 522212795Sdim return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); 523212795Sdim TypeSpecComplex = C; 524212795Sdim TSCLoc = Loc; 525212795Sdim return false; 526212795Sdim} 527212795Sdim 528212795Sdimbool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, 529212795Sdim const char *&PrevSpec, 530212795Sdim unsigned &DiagID) { 531212795Sdim if (TypeSpecSign != TSS_unspecified) 532212795Sdim return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); 533212795Sdim TypeSpecSign = S; 534212795Sdim TSSLoc = Loc; 535212795Sdim return false; 536212795Sdim} 537212795Sdim 538212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 539212795Sdim const char *&PrevSpec, 540212795Sdim unsigned &DiagID, 541212795Sdim ParsedType Rep) { 542221345Sdim return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep); 543221345Sdim} 544221345Sdim 545221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 546221345Sdim SourceLocation TagNameLoc, 547221345Sdim const char *&PrevSpec, 548221345Sdim unsigned &DiagID, 549221345Sdim ParsedType Rep) { 550212795Sdim assert(isTypeRep(T) && "T does not store a type"); 551212795Sdim assert(Rep && "no type provided!"); 552212795Sdim if (TypeSpecType != TST_unspecified) { 553212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 554212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 555212795Sdim return true; 556212795Sdim } 557212795Sdim TypeSpecType = T; 558212795Sdim TypeRep = Rep; 559221345Sdim TSTLoc = TagKwLoc; 560221345Sdim TSTNameLoc = TagNameLoc; 561212795Sdim TypeSpecOwned = false; 562212795Sdim return false; 563212795Sdim} 564212795Sdim 565212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 566212795Sdim const char *&PrevSpec, 567212795Sdim unsigned &DiagID, 568212795Sdim Expr *Rep) { 569212795Sdim assert(isExprRep(T) && "T does not store an expr"); 570212795Sdim assert(Rep && "no expression provided!"); 571212795Sdim if (TypeSpecType != TST_unspecified) { 572212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 573212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 574212795Sdim return true; 575212795Sdim } 576212795Sdim TypeSpecType = T; 577212795Sdim ExprRep = Rep; 578212795Sdim TSTLoc = Loc; 579221345Sdim TSTNameLoc = Loc; 580212795Sdim TypeSpecOwned = false; 581212795Sdim return false; 582212795Sdim} 583212795Sdim 584212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 585212795Sdim const char *&PrevSpec, 586212795Sdim unsigned &DiagID, 587212795Sdim Decl *Rep, bool Owned) { 588221345Sdim return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned); 589221345Sdim} 590221345Sdim 591221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 592221345Sdim SourceLocation TagNameLoc, 593221345Sdim const char *&PrevSpec, 594221345Sdim unsigned &DiagID, 595221345Sdim Decl *Rep, bool Owned) { 596212795Sdim assert(isDeclRep(T) && "T does not store a decl"); 597212795Sdim // Unlike the other cases, we don't assert that we actually get a decl. 598212795Sdim 599212795Sdim if (TypeSpecType != TST_unspecified) { 600212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 601212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 602212795Sdim return true; 603212795Sdim } 604212795Sdim TypeSpecType = T; 605212795Sdim DeclRep = Rep; 606221345Sdim TSTLoc = TagKwLoc; 607221345Sdim TSTNameLoc = TagNameLoc; 608212795Sdim TypeSpecOwned = Owned; 609212795Sdim return false; 610212795Sdim} 611212795Sdim 612212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 613212795Sdim const char *&PrevSpec, 614212795Sdim unsigned &DiagID) { 615212795Sdim assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && 616212795Sdim "rep required for these type-spec kinds!"); 617212795Sdim if (TypeSpecType != TST_unspecified) { 618212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 619212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 620212795Sdim return true; 621212795Sdim } 622221345Sdim TSTLoc = Loc; 623221345Sdim TSTNameLoc = Loc; 624212795Sdim if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { 625212795Sdim TypeAltiVecBool = true; 626212795Sdim return false; 627212795Sdim } 628212795Sdim TypeSpecType = T; 629212795Sdim TypeSpecOwned = false; 630212795Sdim if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { 631212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 632212795Sdim DiagID = diag::err_invalid_vector_decl_spec; 633212795Sdim return true; 634212795Sdim } 635212795Sdim return false; 636212795Sdim} 637212795Sdim 638212795Sdimbool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 639212795Sdim const char *&PrevSpec, unsigned &DiagID) { 640212795Sdim if (TypeSpecType != TST_unspecified) { 641212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 642212795Sdim DiagID = diag::err_invalid_vector_decl_spec_combination; 643212795Sdim return true; 644212795Sdim } 645212795Sdim TypeAltiVecVector = isAltiVecVector; 646212795Sdim AltiVecLoc = Loc; 647212795Sdim return false; 648212795Sdim} 649212795Sdim 650212795Sdimbool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 651212795Sdim const char *&PrevSpec, unsigned &DiagID) { 652212795Sdim if (!TypeAltiVecVector || TypeAltiVecPixel || 653212795Sdim (TypeSpecType != TST_unspecified)) { 654212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 655212795Sdim DiagID = diag::err_invalid_pixel_decl_spec_combination; 656212795Sdim return true; 657212795Sdim } 658212795Sdim TypeAltiVecPixel = isAltiVecPixel; 659212795Sdim TSTLoc = Loc; 660221345Sdim TSTNameLoc = Loc; 661212795Sdim return false; 662212795Sdim} 663212795Sdim 664212795Sdimbool DeclSpec::SetTypeSpecError() { 665212795Sdim TypeSpecType = TST_error; 666212795Sdim TypeSpecOwned = false; 667212795Sdim TSTLoc = SourceLocation(); 668221345Sdim TSTNameLoc = SourceLocation(); 669212795Sdim return false; 670212795Sdim} 671212795Sdim 672212795Sdimbool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 673239462Sdim unsigned &DiagID, const LangOptions &Lang, 674239462Sdim bool IsTypeSpec) { 675239462Sdim // Duplicates are permitted in C99, and are permitted in C++11 unless the 676239462Sdim // cv-qualifier appears as a type-specifier. 677239462Sdim if ((TypeQualifiers & T) && !Lang.C99 && (!Lang.CPlusPlus0x || IsTypeSpec)) 678212795Sdim return BadSpecifier(T, T, PrevSpec, DiagID); 679212795Sdim TypeQualifiers |= T; 680212795Sdim 681212795Sdim switch (T) { 682226633Sdim default: llvm_unreachable("Unknown type qualifier!"); 683212795Sdim case TQ_const: TQ_constLoc = Loc; break; 684212795Sdim case TQ_restrict: TQ_restrictLoc = Loc; break; 685212795Sdim case TQ_volatile: TQ_volatileLoc = Loc; break; 686212795Sdim } 687212795Sdim return false; 688212795Sdim} 689212795Sdim 690212795Sdimbool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, 691212795Sdim unsigned &DiagID) { 692212795Sdim // 'inline inline' is ok. 693212795Sdim FS_inline_specified = true; 694212795Sdim FS_inlineLoc = Loc; 695212795Sdim return false; 696212795Sdim} 697212795Sdim 698212795Sdimbool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, 699212795Sdim unsigned &DiagID) { 700212795Sdim // 'virtual virtual' is ok. 701212795Sdim FS_virtual_specified = true; 702212795Sdim FS_virtualLoc = Loc; 703212795Sdim return false; 704212795Sdim} 705212795Sdim 706212795Sdimbool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, 707212795Sdim unsigned &DiagID) { 708212795Sdim // 'explicit explicit' is ok. 709212795Sdim FS_explicit_specified = true; 710212795Sdim FS_explicitLoc = Loc; 711212795Sdim return false; 712212795Sdim} 713212795Sdim 714212795Sdimbool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 715212795Sdim unsigned &DiagID) { 716212795Sdim if (Friend_specified) { 717212795Sdim PrevSpec = "friend"; 718212795Sdim DiagID = diag::ext_duplicate_declspec; 719212795Sdim return true; 720212795Sdim } 721212795Sdim 722212795Sdim Friend_specified = true; 723212795Sdim FriendLoc = Loc; 724212795Sdim return false; 725212795Sdim} 726212795Sdim 727226633Sdimbool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, 728226633Sdim unsigned &DiagID) { 729226633Sdim if (isModulePrivateSpecified()) { 730226633Sdim PrevSpec = "__module_private__"; 731226633Sdim DiagID = diag::ext_duplicate_declspec; 732226633Sdim return true; 733226633Sdim } 734226633Sdim 735226633Sdim ModulePrivateLoc = Loc; 736226633Sdim return false; 737226633Sdim} 738226633Sdim 739212795Sdimbool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, 740212795Sdim unsigned &DiagID) { 741212795Sdim // 'constexpr constexpr' is ok. 742212795Sdim Constexpr_specified = true; 743212795Sdim ConstexprLoc = Loc; 744212795Sdim return false; 745212795Sdim} 746212795Sdim 747212795Sdimvoid DeclSpec::setProtocolQualifiers(Decl * const *Protos, 748212795Sdim unsigned NP, 749212795Sdim SourceLocation *ProtoLocs, 750212795Sdim SourceLocation LAngleLoc) { 751212795Sdim if (NP == 0) return; 752212795Sdim ProtocolQualifiers = new Decl*[NP]; 753212795Sdim ProtocolLocs = new SourceLocation[NP]; 754212795Sdim memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP); 755212795Sdim memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); 756212795Sdim NumProtocolQualifiers = NP; 757212795Sdim ProtocolLAngleLoc = LAngleLoc; 758212795Sdim} 759212795Sdim 760212795Sdimvoid DeclSpec::SaveWrittenBuiltinSpecs() { 761212795Sdim writtenBS.Sign = getTypeSpecSign(); 762212795Sdim writtenBS.Width = getTypeSpecWidth(); 763212795Sdim writtenBS.Type = getTypeSpecType(); 764212795Sdim // Search the list of attributes for the presence of a mode attribute. 765212795Sdim writtenBS.ModeAttr = false; 766218893Sdim AttributeList* attrs = getAttributes().getList(); 767212795Sdim while (attrs) { 768239462Sdim if (attrs->getKind() == AttributeList::AT_Mode) { 769212795Sdim writtenBS.ModeAttr = true; 770212795Sdim break; 771212795Sdim } 772212795Sdim attrs = attrs->getNext(); 773212795Sdim } 774212795Sdim} 775212795Sdim 776212795Sdimvoid DeclSpec::SaveStorageSpecifierAsWritten() { 777212795Sdim if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern) 778212795Sdim // If 'extern' is part of a linkage specification, 779212795Sdim // then it is not a storage class "as written". 780212795Sdim StorageClassSpecAsWritten = SCS_unspecified; 781212795Sdim else 782212795Sdim StorageClassSpecAsWritten = StorageClassSpec; 783212795Sdim} 784212795Sdim 785212795Sdim/// Finish - This does final analysis of the declspec, rejecting things like 786212795Sdim/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or 787212795Sdim/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, 788212795Sdim/// DeclSpec is guaranteed self-consistent, even if an error occurred. 789226633Sdimvoid DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { 790212795Sdim // Before possibly changing their values, save specs as written. 791212795Sdim SaveWrittenBuiltinSpecs(); 792212795Sdim SaveStorageSpecifierAsWritten(); 793212795Sdim 794212795Sdim // Check the type specifier components first. 795212795Sdim 796212795Sdim // Validate and finalize AltiVec vector declspec. 797212795Sdim if (TypeAltiVecVector) { 798212795Sdim if (TypeAltiVecBool) { 799212795Sdim // Sign specifiers are not allowed with vector bool. (PIM 2.1) 800212795Sdim if (TypeSpecSign != TSS_unspecified) { 801218893Sdim Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec) 802212795Sdim << getSpecifierName((TSS)TypeSpecSign); 803212795Sdim } 804212795Sdim 805212795Sdim // Only char/int are valid with vector bool. (PIM 2.1) 806212795Sdim if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && 807212795Sdim (TypeSpecType != TST_int)) || TypeAltiVecPixel) { 808218893Sdim Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec) 809212795Sdim << (TypeAltiVecPixel ? "__pixel" : 810212795Sdim getSpecifierName((TST)TypeSpecType)); 811212795Sdim } 812212795Sdim 813212795Sdim // Only 'short' is valid with vector bool. (PIM 2.1) 814212795Sdim if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) 815218893Sdim Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) 816212795Sdim << getSpecifierName((TSW)TypeSpecWidth); 817212795Sdim 818212795Sdim // Elements of vector bool are interpreted as unsigned. (PIM 2.1) 819212795Sdim if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || 820212795Sdim (TypeSpecWidth != TSW_unspecified)) 821212795Sdim TypeSpecSign = TSS_unsigned; 822212795Sdim } 823212795Sdim 824212795Sdim if (TypeAltiVecPixel) { 825212795Sdim //TODO: perform validation 826212795Sdim TypeSpecType = TST_int; 827212795Sdim TypeSpecSign = TSS_unsigned; 828212795Sdim TypeSpecWidth = TSW_short; 829212795Sdim TypeSpecOwned = false; 830212795Sdim } 831212795Sdim } 832212795Sdim 833212795Sdim // signed/unsigned are only valid with int/char/wchar_t. 834212795Sdim if (TypeSpecSign != TSS_unspecified) { 835212795Sdim if (TypeSpecType == TST_unspecified) 836212795Sdim TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. 837234353Sdim else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && 838212795Sdim TypeSpecType != TST_char && TypeSpecType != TST_wchar) { 839218893Sdim Diag(D, TSSLoc, diag::err_invalid_sign_spec) 840212795Sdim << getSpecifierName((TST)TypeSpecType); 841212795Sdim // signed double -> double. 842212795Sdim TypeSpecSign = TSS_unspecified; 843212795Sdim } 844212795Sdim } 845212795Sdim 846212795Sdim // Validate the width of the type. 847212795Sdim switch (TypeSpecWidth) { 848212795Sdim case TSW_unspecified: break; 849212795Sdim case TSW_short: // short int 850212795Sdim case TSW_longlong: // long long int 851212795Sdim if (TypeSpecType == TST_unspecified) 852212795Sdim TypeSpecType = TST_int; // short -> short int, long long -> long long int. 853212795Sdim else if (TypeSpecType != TST_int) { 854218893Sdim Diag(D, TSWLoc, 855212795Sdim TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec 856212795Sdim : diag::err_invalid_longlong_spec) 857212795Sdim << getSpecifierName((TST)TypeSpecType); 858212795Sdim TypeSpecType = TST_int; 859212795Sdim TypeSpecOwned = false; 860212795Sdim } 861212795Sdim break; 862212795Sdim case TSW_long: // long double, long int 863212795Sdim if (TypeSpecType == TST_unspecified) 864212795Sdim TypeSpecType = TST_int; // long -> long int. 865212795Sdim else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { 866218893Sdim Diag(D, TSWLoc, diag::err_invalid_long_spec) 867212795Sdim << getSpecifierName((TST)TypeSpecType); 868212795Sdim TypeSpecType = TST_int; 869212795Sdim TypeSpecOwned = false; 870212795Sdim } 871212795Sdim break; 872212795Sdim } 873212795Sdim 874212795Sdim // TODO: if the implementation does not implement _Complex or _Imaginary, 875212795Sdim // disallow their use. Need information about the backend. 876212795Sdim if (TypeSpecComplex != TSC_unspecified) { 877212795Sdim if (TypeSpecType == TST_unspecified) { 878218893Sdim Diag(D, TSCLoc, diag::ext_plain_complex) 879212795Sdim << FixItHint::CreateInsertion( 880212795Sdim PP.getLocForEndOfToken(getTypeSpecComplexLoc()), 881212795Sdim " double"); 882212795Sdim TypeSpecType = TST_double; // _Complex -> _Complex double. 883212795Sdim } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { 884212795Sdim // Note that this intentionally doesn't include _Complex _Bool. 885234353Sdim if (!PP.getLangOpts().CPlusPlus) 886234353Sdim Diag(D, TSTLoc, diag::ext_integer_complex); 887212795Sdim } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { 888218893Sdim Diag(D, TSCLoc, diag::err_invalid_complex_spec) 889212795Sdim << getSpecifierName((TST)TypeSpecType); 890212795Sdim TypeSpecComplex = TSC_unspecified; 891212795Sdim } 892212795Sdim } 893212795Sdim 894226633Sdim // If no type specifier was provided and we're parsing a language where 895226633Sdim // the type specifier is not optional, but we got 'auto' as a storage 896226633Sdim // class specifier, then assume this is an attempt to use C++0x's 'auto' 897226633Sdim // type specifier. 898226633Sdim // FIXME: Does Microsoft really support implicit int in C++? 899234353Sdim if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt && 900226633Sdim TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) { 901226633Sdim TypeSpecType = TST_auto; 902226633Sdim StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified; 903226633Sdim TSTLoc = TSTNameLoc = StorageClassSpecLoc; 904226633Sdim StorageClassSpecLoc = SourceLocation(); 905226633Sdim } 906226633Sdim // Diagnose if we've recovered from an ill-formed 'auto' storage class 907226633Sdim // specifier in a pre-C++0x dialect of C++. 908234353Sdim if (!PP.getLangOpts().CPlusPlus0x && TypeSpecType == TST_auto) 909226633Sdim Diag(D, TSTLoc, diag::ext_auto_type_specifier); 910234353Sdim if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus0x && 911226633Sdim StorageClassSpec == SCS_auto) 912226633Sdim Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class) 913226633Sdim << FixItHint::CreateRemoval(StorageClassSpecLoc); 914234353Sdim if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) 915234353Sdim Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type) 916234353Sdim << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); 917234353Sdim if (Constexpr_specified) 918234353Sdim Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr); 919226633Sdim 920212795Sdim // C++ [class.friend]p6: 921212795Sdim // No storage-class-specifier shall appear in the decl-specifier-seq 922212795Sdim // of a friend declaration. 923212795Sdim if (isFriendSpecified() && getStorageClassSpec()) { 924212795Sdim DeclSpec::SCS SC = getStorageClassSpec(); 925212795Sdim const char *SpecName = getSpecifierName(SC); 926212795Sdim 927212795Sdim SourceLocation SCLoc = getStorageClassSpecLoc(); 928226633Sdim SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName)); 929212795Sdim 930218893Sdim Diag(D, SCLoc, diag::err_friend_storage_spec) 931212795Sdim << SpecName 932212795Sdim << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc)); 933212795Sdim 934212795Sdim ClearStorageClassSpecs(); 935212795Sdim } 936212795Sdim 937212795Sdim assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType)); 938226633Sdim 939212795Sdim // Okay, now we can infer the real type. 940212795Sdim 941212795Sdim // TODO: return "auto function" and other bad things based on the real type. 942212795Sdim 943212795Sdim // 'data definition has no type or storage class'? 944212795Sdim} 945212795Sdim 946212795Sdimbool DeclSpec::isMissingDeclaratorOk() { 947212795Sdim TST tst = getTypeSpecType(); 948212795Sdim return isDeclRep(tst) && getRepAsDecl() != 0 && 949212795Sdim StorageClassSpec != DeclSpec::SCS_typedef; 950212795Sdim} 951212795Sdim 952212795Sdimvoid UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 953212795Sdim OverloadedOperatorKind Op, 954212795Sdim SourceLocation SymbolLocations[3]) { 955212795Sdim Kind = IK_OperatorFunctionId; 956212795Sdim StartLocation = OperatorLoc; 957212795Sdim EndLocation = OperatorLoc; 958212795Sdim OperatorFunctionId.Operator = Op; 959212795Sdim for (unsigned I = 0; I != 3; ++I) { 960212795Sdim OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); 961212795Sdim 962212795Sdim if (SymbolLocations[I].isValid()) 963212795Sdim EndLocation = SymbolLocations[I]; 964212795Sdim } 965212795Sdim} 966218893Sdim 967218893Sdimbool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, 968218893Sdim const char *&PrevSpec) { 969221345Sdim LastLocation = Loc; 970221345Sdim 971218893Sdim if (Specifiers & VS) { 972218893Sdim PrevSpec = getSpecifierName(VS); 973218893Sdim return true; 974218893Sdim } 975218893Sdim 976218893Sdim Specifiers |= VS; 977218893Sdim 978218893Sdim switch (VS) { 979226633Sdim default: llvm_unreachable("Unknown specifier!"); 980218893Sdim case VS_Override: VS_overrideLoc = Loc; break; 981218893Sdim case VS_Final: VS_finalLoc = Loc; break; 982218893Sdim } 983218893Sdim 984218893Sdim return false; 985218893Sdim} 986218893Sdim 987218893Sdimconst char *VirtSpecifiers::getSpecifierName(Specifier VS) { 988218893Sdim switch (VS) { 989226633Sdim default: llvm_unreachable("Unknown specifier"); 990218893Sdim case VS_Override: return "override"; 991218893Sdim case VS_Final: return "final"; 992218893Sdim } 993218893Sdim} 994