DeclSpec.cpp revision 249423
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/Sema/DeclSpec.h" 15219077Sdim#include "clang/AST/ASTContext.h" 16224145Sdim#include "clang/AST/Expr.h" 17219077Sdim#include "clang/AST/NestedNameSpecifier.h" 18219077Sdim#include "clang/AST/TypeLoc.h" 19249423Sdim#include "clang/Basic/LangOptions.h" 20212795Sdim#include "clang/Lex/Preprocessor.h" 21249423Sdim#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency! 22249423Sdim#include "clang/Sema/LocInfoType.h" 23249423Sdim#include "clang/Sema/ParsedTemplate.h" 24249423Sdim#include "clang/Sema/Sema.h" 25249423Sdim#include "clang/Sema/SemaDiagnostic.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. 147243830SdimDeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, 148239462Sdim bool isAmbiguous, 149243830Sdim SourceLocation LParenLoc, 150212795Sdim ParamInfo *ArgInfo, 151212795Sdim unsigned NumArgs, 152243830Sdim SourceLocation EllipsisLoc, 153243830Sdim SourceLocation RParenLoc, 154212795Sdim unsigned TypeQuals, 155218893Sdim bool RefQualifierIsLvalueRef, 156218893Sdim SourceLocation RefQualifierLoc, 157234353Sdim SourceLocation ConstQualifierLoc, 158234353Sdim SourceLocation 159234353Sdim VolatileQualifierLoc, 160224145Sdim SourceLocation MutableLoc, 161221345Sdim ExceptionSpecificationType 162221345Sdim ESpecType, 163221345Sdim SourceLocation ESpecLoc, 164212795Sdim ParsedType *Exceptions, 165212795Sdim SourceRange *ExceptionRanges, 166212795Sdim unsigned NumExceptions, 167221345Sdim Expr *NoexceptExpr, 168221345Sdim SourceLocation LocalRangeBegin, 169221345Sdim SourceLocation LocalRangeEnd, 170218893Sdim Declarator &TheDeclarator, 171239462Sdim TypeResult TrailingReturnType) { 172249423Sdim assert(!(TypeQuals & DeclSpec::TQ_atomic) && 173249423Sdim "function cannot have _Atomic qualifier"); 174249423Sdim 175212795Sdim DeclaratorChunk I; 176221345Sdim I.Kind = Function; 177221345Sdim I.Loc = LocalRangeBegin; 178221345Sdim I.EndLoc = LocalRangeEnd; 179221345Sdim I.Fun.AttrList = 0; 180221345Sdim I.Fun.hasPrototype = hasProto; 181243830Sdim I.Fun.isVariadic = EllipsisLoc.isValid(); 182239462Sdim I.Fun.isAmbiguous = isAmbiguous; 183243830Sdim I.Fun.LParenLoc = LParenLoc.getRawEncoding(); 184221345Sdim I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); 185243830Sdim I.Fun.RParenLoc = RParenLoc.getRawEncoding(); 186221345Sdim I.Fun.DeleteArgInfo = false; 187221345Sdim I.Fun.TypeQuals = TypeQuals; 188221345Sdim I.Fun.NumArgs = NumArgs; 189221345Sdim I.Fun.ArgInfo = 0; 190218893Sdim I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; 191221345Sdim I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); 192234353Sdim I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding(); 193234353Sdim I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding(); 194224145Sdim I.Fun.MutableLoc = MutableLoc.getRawEncoding(); 195221345Sdim I.Fun.ExceptionSpecType = ESpecType; 196221345Sdim I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); 197221345Sdim I.Fun.NumExceptions = 0; 198221345Sdim I.Fun.Exceptions = 0; 199221345Sdim I.Fun.NoexceptExpr = 0; 200239462Sdim I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() || 201239462Sdim TrailingReturnType.isInvalid(); 202239462Sdim I.Fun.TrailingReturnType = TrailingReturnType.get(); 203212795Sdim 204212795Sdim // new[] an argument array if needed. 205212795Sdim if (NumArgs) { 206212795Sdim // If the 'InlineParams' in Declarator is unused and big enough, put our 207212795Sdim // parameter list there (in an effort to avoid new/delete traffic). If it 208212795Sdim // is already used (consider a function returning a function pointer) or too 209212795Sdim // small (function taking too many arguments), go to the heap. 210212795Sdim if (!TheDeclarator.InlineParamsUsed && 211212795Sdim NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) { 212212795Sdim I.Fun.ArgInfo = TheDeclarator.InlineParams; 213212795Sdim I.Fun.DeleteArgInfo = false; 214212795Sdim TheDeclarator.InlineParamsUsed = true; 215212795Sdim } else { 216212795Sdim I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs]; 217212795Sdim I.Fun.DeleteArgInfo = true; 218212795Sdim } 219212795Sdim memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs); 220212795Sdim } 221221345Sdim 222221345Sdim // Check what exception specification information we should actually store. 223221345Sdim switch (ESpecType) { 224221345Sdim default: break; // By default, save nothing. 225221345Sdim case EST_Dynamic: 226221345Sdim // new[] an exception array if needed 227221345Sdim if (NumExceptions) { 228221345Sdim I.Fun.NumExceptions = NumExceptions; 229221345Sdim I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions]; 230221345Sdim for (unsigned i = 0; i != NumExceptions; ++i) { 231221345Sdim I.Fun.Exceptions[i].Ty = Exceptions[i]; 232221345Sdim I.Fun.Exceptions[i].Range = ExceptionRanges[i]; 233221345Sdim } 234212795Sdim } 235221345Sdim break; 236221345Sdim 237221345Sdim case EST_ComputedNoexcept: 238221345Sdim I.Fun.NoexceptExpr = NoexceptExpr; 239221345Sdim break; 240212795Sdim } 241212795Sdim return I; 242212795Sdim} 243212795Sdim 244224145Sdimbool Declarator::isDeclarationOfFunction() const { 245224145Sdim for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { 246224145Sdim switch (DeclTypeInfo[i].Kind) { 247224145Sdim case DeclaratorChunk::Function: 248224145Sdim return true; 249224145Sdim case DeclaratorChunk::Paren: 250224145Sdim continue; 251224145Sdim case DeclaratorChunk::Pointer: 252224145Sdim case DeclaratorChunk::Reference: 253224145Sdim case DeclaratorChunk::Array: 254224145Sdim case DeclaratorChunk::BlockPointer: 255224145Sdim case DeclaratorChunk::MemberPointer: 256224145Sdim return false; 257224145Sdim } 258224145Sdim llvm_unreachable("Invalid type chunk"); 259224145Sdim } 260224145Sdim 261224145Sdim switch (DS.getTypeSpecType()) { 262226633Sdim case TST_atomic: 263224145Sdim case TST_auto: 264224145Sdim case TST_bool: 265224145Sdim case TST_char: 266224145Sdim case TST_char16: 267224145Sdim case TST_char32: 268224145Sdim case TST_class: 269224145Sdim case TST_decimal128: 270224145Sdim case TST_decimal32: 271224145Sdim case TST_decimal64: 272224145Sdim case TST_double: 273224145Sdim case TST_enum: 274224145Sdim case TST_error: 275224145Sdim case TST_float: 276226633Sdim case TST_half: 277224145Sdim case TST_int: 278234353Sdim case TST_int128: 279224145Sdim case TST_struct: 280243830Sdim case TST_interface: 281224145Sdim case TST_union: 282224145Sdim case TST_unknown_anytype: 283224145Sdim case TST_unspecified: 284224145Sdim case TST_void: 285224145Sdim case TST_wchar: 286249423Sdim case TST_image1d_t: 287249423Sdim case TST_image1d_array_t: 288249423Sdim case TST_image1d_buffer_t: 289249423Sdim case TST_image2d_t: 290249423Sdim case TST_image2d_array_t: 291249423Sdim case TST_image3d_t: 292249423Sdim case TST_sampler_t: 293249423Sdim case TST_event_t: 294224145Sdim return false; 295224145Sdim 296224145Sdim case TST_decltype: 297224145Sdim case TST_typeofExpr: 298224145Sdim if (Expr *E = DS.getRepAsExpr()) 299224145Sdim return E->getType()->isFunctionType(); 300224145Sdim return false; 301224145Sdim 302224145Sdim case TST_underlyingType: 303224145Sdim case TST_typename: 304224145Sdim case TST_typeofType: { 305224145Sdim QualType QT = DS.getRepAsType().get(); 306224145Sdim if (QT.isNull()) 307224145Sdim return false; 308224145Sdim 309224145Sdim if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) 310224145Sdim QT = LIT->getType(); 311224145Sdim 312224145Sdim if (QT.isNull()) 313224145Sdim return false; 314224145Sdim 315224145Sdim return QT->isFunctionType(); 316224145Sdim } 317224145Sdim } 318234353Sdim 319234353Sdim llvm_unreachable("Invalid TypeSpecType!"); 320224145Sdim} 321224145Sdim 322212795Sdim/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this 323212795Sdim/// declaration specifier includes. 324212795Sdim/// 325212795Sdimunsigned DeclSpec::getParsedSpecifiers() const { 326212795Sdim unsigned Res = 0; 327212795Sdim if (StorageClassSpec != SCS_unspecified || 328212795Sdim SCS_thread_specified) 329212795Sdim Res |= PQ_StorageClassSpecifier; 330212795Sdim 331212795Sdim if (TypeQualifiers != TQ_unspecified) 332212795Sdim Res |= PQ_TypeQualifier; 333212795Sdim 334212795Sdim if (hasTypeSpecifier()) 335212795Sdim Res |= PQ_TypeSpecifier; 336212795Sdim 337249423Sdim if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified || 338249423Sdim FS_noreturn_specified) 339212795Sdim Res |= PQ_FunctionSpecifier; 340212795Sdim return Res; 341212795Sdim} 342212795Sdim 343212795Sdimtemplate <class T> static bool BadSpecifier(T TNew, T TPrev, 344212795Sdim const char *&PrevSpec, 345243830Sdim unsigned &DiagID, 346243830Sdim bool IsExtension = true) { 347212795Sdim PrevSpec = DeclSpec::getSpecifierName(TPrev); 348243830Sdim if (TNew != TPrev) 349243830Sdim DiagID = diag::err_invalid_decl_spec_combination; 350243830Sdim else 351243830Sdim DiagID = IsExtension ? diag::ext_duplicate_declspec : 352243830Sdim diag::warn_duplicate_declspec; 353212795Sdim return true; 354212795Sdim} 355212795Sdim 356212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::SCS S) { 357212795Sdim switch (S) { 358212795Sdim case DeclSpec::SCS_unspecified: return "unspecified"; 359212795Sdim case DeclSpec::SCS_typedef: return "typedef"; 360212795Sdim case DeclSpec::SCS_extern: return "extern"; 361212795Sdim case DeclSpec::SCS_static: return "static"; 362212795Sdim case DeclSpec::SCS_auto: return "auto"; 363212795Sdim case DeclSpec::SCS_register: return "register"; 364212795Sdim case DeclSpec::SCS_private_extern: return "__private_extern__"; 365212795Sdim case DeclSpec::SCS_mutable: return "mutable"; 366212795Sdim } 367212795Sdim llvm_unreachable("Unknown typespec!"); 368212795Sdim} 369212795Sdim 370212795Sdimconst char *DeclSpec::getSpecifierName(TSW W) { 371212795Sdim switch (W) { 372212795Sdim case TSW_unspecified: return "unspecified"; 373212795Sdim case TSW_short: return "short"; 374212795Sdim case TSW_long: return "long"; 375212795Sdim case TSW_longlong: return "long long"; 376212795Sdim } 377212795Sdim llvm_unreachable("Unknown typespec!"); 378212795Sdim} 379212795Sdim 380212795Sdimconst char *DeclSpec::getSpecifierName(TSC C) { 381212795Sdim switch (C) { 382212795Sdim case TSC_unspecified: return "unspecified"; 383212795Sdim case TSC_imaginary: return "imaginary"; 384212795Sdim case TSC_complex: return "complex"; 385212795Sdim } 386212795Sdim llvm_unreachable("Unknown typespec!"); 387212795Sdim} 388212795Sdim 389212795Sdim 390212795Sdimconst char *DeclSpec::getSpecifierName(TSS S) { 391212795Sdim switch (S) { 392212795Sdim case TSS_unspecified: return "unspecified"; 393212795Sdim case TSS_signed: return "signed"; 394212795Sdim case TSS_unsigned: return "unsigned"; 395212795Sdim } 396212795Sdim llvm_unreachable("Unknown typespec!"); 397212795Sdim} 398212795Sdim 399212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::TST T) { 400212795Sdim switch (T) { 401212795Sdim case DeclSpec::TST_unspecified: return "unspecified"; 402212795Sdim case DeclSpec::TST_void: return "void"; 403212795Sdim case DeclSpec::TST_char: return "char"; 404212795Sdim case DeclSpec::TST_wchar: return "wchar_t"; 405212795Sdim case DeclSpec::TST_char16: return "char16_t"; 406212795Sdim case DeclSpec::TST_char32: return "char32_t"; 407212795Sdim case DeclSpec::TST_int: return "int"; 408234353Sdim case DeclSpec::TST_int128: return "__int128"; 409226633Sdim case DeclSpec::TST_half: return "half"; 410212795Sdim case DeclSpec::TST_float: return "float"; 411212795Sdim case DeclSpec::TST_double: return "double"; 412212795Sdim case DeclSpec::TST_bool: return "_Bool"; 413212795Sdim case DeclSpec::TST_decimal32: return "_Decimal32"; 414212795Sdim case DeclSpec::TST_decimal64: return "_Decimal64"; 415212795Sdim case DeclSpec::TST_decimal128: return "_Decimal128"; 416212795Sdim case DeclSpec::TST_enum: return "enum"; 417212795Sdim case DeclSpec::TST_class: return "class"; 418212795Sdim case DeclSpec::TST_union: return "union"; 419212795Sdim case DeclSpec::TST_struct: return "struct"; 420243830Sdim case DeclSpec::TST_interface: return "__interface"; 421212795Sdim case DeclSpec::TST_typename: return "type-name"; 422212795Sdim case DeclSpec::TST_typeofType: 423212795Sdim case DeclSpec::TST_typeofExpr: return "typeof"; 424212795Sdim case DeclSpec::TST_auto: return "auto"; 425212795Sdim case DeclSpec::TST_decltype: return "(decltype)"; 426223017Sdim case DeclSpec::TST_underlyingType: return "__underlying_type"; 427221345Sdim case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; 428226633Sdim case DeclSpec::TST_atomic: return "_Atomic"; 429249423Sdim case DeclSpec::TST_image1d_t: return "image1d_t"; 430249423Sdim case DeclSpec::TST_image1d_array_t: return "image1d_array_t"; 431249423Sdim case DeclSpec::TST_image1d_buffer_t: return "image1d_buffer_t"; 432249423Sdim case DeclSpec::TST_image2d_t: return "image2d_t"; 433249423Sdim case DeclSpec::TST_image2d_array_t: return "image2d_array_t"; 434249423Sdim case DeclSpec::TST_image3d_t: return "image3d_t"; 435249423Sdim case DeclSpec::TST_sampler_t: return "sampler_t"; 436249423Sdim case DeclSpec::TST_event_t: return "event_t"; 437212795Sdim case DeclSpec::TST_error: return "(error)"; 438212795Sdim } 439212795Sdim llvm_unreachable("Unknown typespec!"); 440212795Sdim} 441212795Sdim 442212795Sdimconst char *DeclSpec::getSpecifierName(TQ T) { 443212795Sdim switch (T) { 444212795Sdim case DeclSpec::TQ_unspecified: return "unspecified"; 445212795Sdim case DeclSpec::TQ_const: return "const"; 446212795Sdim case DeclSpec::TQ_restrict: return "restrict"; 447212795Sdim case DeclSpec::TQ_volatile: return "volatile"; 448249423Sdim case DeclSpec::TQ_atomic: return "_Atomic"; 449212795Sdim } 450212795Sdim llvm_unreachable("Unknown typespec!"); 451212795Sdim} 452212795Sdim 453226633Sdimbool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, 454212795Sdim const char *&PrevSpec, 455226633Sdim unsigned &DiagID) { 456239462Sdim // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class 457239462Sdim // specifiers are not supported. 458218893Sdim // It seems sensible to prohibit private_extern too 459226633Sdim // The cl_clang_storage_class_specifiers extension enables support for 460226633Sdim // these storage-class specifiers. 461239462Sdim // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class 462239462Sdim // specifiers are not supported." 463234353Sdim if (S.getLangOpts().OpenCL && 464226633Sdim !S.getOpenCLOptions().cl_clang_storage_class_specifiers) { 465226633Sdim switch (SC) { 466218893Sdim case SCS_extern: 467218893Sdim case SCS_private_extern: 468239462Sdim case SCS_static: 469239462Sdim if (S.getLangOpts().OpenCLVersion < 120) { 470239462Sdim DiagID = diag::err_not_opencl_storage_class_specifier; 471239462Sdim PrevSpec = getSpecifierName(SC); 472239462Sdim return true; 473239462Sdim } 474239462Sdim break; 475218893Sdim case SCS_auto: 476218893Sdim case SCS_register: 477218893Sdim DiagID = diag::err_not_opencl_storage_class_specifier; 478226633Sdim PrevSpec = getSpecifierName(SC); 479218893Sdim return true; 480218893Sdim default: 481218893Sdim break; 482218893Sdim } 483218893Sdim } 484218893Sdim 485212795Sdim if (StorageClassSpec != SCS_unspecified) { 486226633Sdim // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode. 487226633Sdim bool isInvalid = true; 488234353Sdim if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) { 489226633Sdim if (SC == SCS_auto) 490226633Sdim return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID); 491226633Sdim if (StorageClassSpec == SCS_auto) { 492226633Sdim isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc, 493226633Sdim PrevSpec, DiagID); 494226633Sdim assert(!isInvalid && "auto SCS -> TST recovery failed"); 495226633Sdim } 496226633Sdim } 497226633Sdim 498212795Sdim // Changing storage class is allowed only if the previous one 499212795Sdim // was the 'extern' that is part of a linkage specification and 500212795Sdim // the new storage class is 'typedef'. 501226633Sdim if (isInvalid && 502226633Sdim !(SCS_extern_in_linkage_spec && 503212795Sdim StorageClassSpec == SCS_extern && 504226633Sdim SC == SCS_typedef)) 505226633Sdim return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID); 506212795Sdim } 507226633Sdim StorageClassSpec = SC; 508212795Sdim StorageClassSpecLoc = Loc; 509226633Sdim assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield"); 510212795Sdim return false; 511212795Sdim} 512212795Sdim 513212795Sdimbool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc, 514212795Sdim const char *&PrevSpec, 515212795Sdim unsigned &DiagID) { 516212795Sdim if (SCS_thread_specified) { 517212795Sdim PrevSpec = "__thread"; 518212795Sdim DiagID = diag::ext_duplicate_declspec; 519212795Sdim return true; 520212795Sdim } 521212795Sdim SCS_thread_specified = true; 522212795Sdim SCS_threadLoc = Loc; 523212795Sdim return false; 524212795Sdim} 525212795Sdim 526212795Sdim/// These methods set the specified attribute of the DeclSpec, but return true 527212795Sdim/// and ignore the request if invalid (e.g. "extern" then "auto" is 528212795Sdim/// specified). 529212795Sdimbool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, 530212795Sdim const char *&PrevSpec, 531212795Sdim unsigned &DiagID) { 532221345Sdim // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that 533221345Sdim // for 'long long' we will keep the source location of the first 'long'. 534221345Sdim if (TypeSpecWidth == TSW_unspecified) 535221345Sdim TSWLoc = Loc; 536221345Sdim // Allow turning long -> long long. 537221345Sdim else if (W != TSW_longlong || TypeSpecWidth != TSW_long) 538212795Sdim return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); 539212795Sdim TypeSpecWidth = W; 540212795Sdim if (TypeAltiVecVector && !TypeAltiVecBool && 541212795Sdim ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { 542212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 543212795Sdim DiagID = diag::warn_vector_long_decl_spec_combination; 544212795Sdim return true; 545212795Sdim } 546212795Sdim return false; 547212795Sdim} 548212795Sdim 549212795Sdimbool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, 550212795Sdim const char *&PrevSpec, 551212795Sdim unsigned &DiagID) { 552212795Sdim if (TypeSpecComplex != TSC_unspecified) 553212795Sdim return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); 554212795Sdim TypeSpecComplex = C; 555212795Sdim TSCLoc = Loc; 556212795Sdim return false; 557212795Sdim} 558212795Sdim 559212795Sdimbool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, 560212795Sdim const char *&PrevSpec, 561212795Sdim unsigned &DiagID) { 562212795Sdim if (TypeSpecSign != TSS_unspecified) 563212795Sdim return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); 564212795Sdim TypeSpecSign = S; 565212795Sdim TSSLoc = Loc; 566212795Sdim return false; 567212795Sdim} 568212795Sdim 569212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 570212795Sdim const char *&PrevSpec, 571212795Sdim unsigned &DiagID, 572212795Sdim ParsedType Rep) { 573221345Sdim return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep); 574221345Sdim} 575221345Sdim 576221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 577221345Sdim SourceLocation TagNameLoc, 578221345Sdim const char *&PrevSpec, 579221345Sdim unsigned &DiagID, 580221345Sdim ParsedType Rep) { 581212795Sdim assert(isTypeRep(T) && "T does not store a type"); 582212795Sdim assert(Rep && "no type provided!"); 583212795Sdim if (TypeSpecType != TST_unspecified) { 584212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 585212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 586212795Sdim return true; 587212795Sdim } 588212795Sdim TypeSpecType = T; 589212795Sdim TypeRep = Rep; 590221345Sdim TSTLoc = TagKwLoc; 591221345Sdim TSTNameLoc = TagNameLoc; 592212795Sdim TypeSpecOwned = false; 593212795Sdim return false; 594212795Sdim} 595212795Sdim 596212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 597212795Sdim const char *&PrevSpec, 598212795Sdim unsigned &DiagID, 599212795Sdim Expr *Rep) { 600212795Sdim assert(isExprRep(T) && "T does not store an expr"); 601212795Sdim assert(Rep && "no expression provided!"); 602212795Sdim if (TypeSpecType != TST_unspecified) { 603212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 604212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 605212795Sdim return true; 606212795Sdim } 607212795Sdim TypeSpecType = T; 608212795Sdim ExprRep = Rep; 609212795Sdim TSTLoc = Loc; 610221345Sdim TSTNameLoc = Loc; 611212795Sdim TypeSpecOwned = false; 612212795Sdim return false; 613212795Sdim} 614212795Sdim 615212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 616212795Sdim const char *&PrevSpec, 617212795Sdim unsigned &DiagID, 618212795Sdim Decl *Rep, bool Owned) { 619221345Sdim return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned); 620221345Sdim} 621221345Sdim 622221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 623221345Sdim SourceLocation TagNameLoc, 624221345Sdim const char *&PrevSpec, 625221345Sdim unsigned &DiagID, 626221345Sdim Decl *Rep, bool Owned) { 627212795Sdim assert(isDeclRep(T) && "T does not store a decl"); 628212795Sdim // Unlike the other cases, we don't assert that we actually get a decl. 629212795Sdim 630212795Sdim if (TypeSpecType != TST_unspecified) { 631212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 632212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 633212795Sdim return true; 634212795Sdim } 635212795Sdim TypeSpecType = T; 636212795Sdim DeclRep = Rep; 637221345Sdim TSTLoc = TagKwLoc; 638221345Sdim TSTNameLoc = TagNameLoc; 639212795Sdim TypeSpecOwned = Owned; 640212795Sdim return false; 641212795Sdim} 642212795Sdim 643212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 644212795Sdim const char *&PrevSpec, 645212795Sdim unsigned &DiagID) { 646212795Sdim assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && 647212795Sdim "rep required for these type-spec kinds!"); 648212795Sdim if (TypeSpecType != TST_unspecified) { 649212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 650212795Sdim DiagID = diag::err_invalid_decl_spec_combination; 651212795Sdim return true; 652212795Sdim } 653221345Sdim TSTLoc = Loc; 654221345Sdim TSTNameLoc = Loc; 655212795Sdim if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { 656212795Sdim TypeAltiVecBool = true; 657212795Sdim return false; 658212795Sdim } 659212795Sdim TypeSpecType = T; 660212795Sdim TypeSpecOwned = false; 661212795Sdim if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { 662212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 663212795Sdim DiagID = diag::err_invalid_vector_decl_spec; 664212795Sdim return true; 665212795Sdim } 666212795Sdim return false; 667212795Sdim} 668212795Sdim 669212795Sdimbool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 670212795Sdim const char *&PrevSpec, unsigned &DiagID) { 671212795Sdim if (TypeSpecType != TST_unspecified) { 672212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 673212795Sdim DiagID = diag::err_invalid_vector_decl_spec_combination; 674212795Sdim return true; 675212795Sdim } 676212795Sdim TypeAltiVecVector = isAltiVecVector; 677212795Sdim AltiVecLoc = Loc; 678212795Sdim return false; 679212795Sdim} 680212795Sdim 681212795Sdimbool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 682212795Sdim const char *&PrevSpec, unsigned &DiagID) { 683212795Sdim if (!TypeAltiVecVector || TypeAltiVecPixel || 684212795Sdim (TypeSpecType != TST_unspecified)) { 685212795Sdim PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 686212795Sdim DiagID = diag::err_invalid_pixel_decl_spec_combination; 687212795Sdim return true; 688212795Sdim } 689212795Sdim TypeAltiVecPixel = isAltiVecPixel; 690212795Sdim TSTLoc = Loc; 691221345Sdim TSTNameLoc = Loc; 692212795Sdim return false; 693212795Sdim} 694212795Sdim 695212795Sdimbool DeclSpec::SetTypeSpecError() { 696212795Sdim TypeSpecType = TST_error; 697212795Sdim TypeSpecOwned = false; 698212795Sdim TSTLoc = SourceLocation(); 699221345Sdim TSTNameLoc = SourceLocation(); 700212795Sdim return false; 701212795Sdim} 702212795Sdim 703212795Sdimbool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 704243830Sdim unsigned &DiagID, const LangOptions &Lang) { 705243830Sdim // Duplicates are permitted in C99, but are not permitted in C++. However, 706243830Sdim // since this is likely not what the user intended, we will always warn. We 707243830Sdim // do not need to set the qualifier's location since we already have it. 708243830Sdim if (TypeQualifiers & T) { 709243830Sdim bool IsExtension = true; 710243830Sdim if (Lang.C99) 711243830Sdim IsExtension = false; 712243830Sdim return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension); 713243830Sdim } 714212795Sdim TypeQualifiers |= T; 715212795Sdim 716212795Sdim switch (T) { 717249423Sdim case TQ_unspecified: break; 718249423Sdim case TQ_const: TQ_constLoc = Loc; return false; 719249423Sdim case TQ_restrict: TQ_restrictLoc = Loc; return false; 720249423Sdim case TQ_volatile: TQ_volatileLoc = Loc; return false; 721249423Sdim case TQ_atomic: TQ_atomicLoc = Loc; return false; 722212795Sdim } 723249423Sdim 724249423Sdim llvm_unreachable("Unknown type qualifier!"); 725212795Sdim} 726212795Sdim 727249423Sdimbool DeclSpec::setFunctionSpecInline(SourceLocation Loc) { 728212795Sdim // 'inline inline' is ok. 729212795Sdim FS_inline_specified = true; 730212795Sdim FS_inlineLoc = Loc; 731212795Sdim return false; 732212795Sdim} 733212795Sdim 734249423Sdimbool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc) { 735212795Sdim // 'virtual virtual' is ok. 736212795Sdim FS_virtual_specified = true; 737212795Sdim FS_virtualLoc = Loc; 738212795Sdim return false; 739212795Sdim} 740212795Sdim 741249423Sdimbool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc) { 742212795Sdim // 'explicit explicit' is ok. 743212795Sdim FS_explicit_specified = true; 744212795Sdim FS_explicitLoc = Loc; 745212795Sdim return false; 746212795Sdim} 747212795Sdim 748249423Sdimbool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc) { 749249423Sdim // '_Noreturn _Noreturn' is ok. 750249423Sdim FS_noreturn_specified = true; 751249423Sdim FS_noreturnLoc = Loc; 752249423Sdim return false; 753249423Sdim} 754249423Sdim 755212795Sdimbool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 756212795Sdim unsigned &DiagID) { 757212795Sdim if (Friend_specified) { 758212795Sdim PrevSpec = "friend"; 759212795Sdim DiagID = diag::ext_duplicate_declspec; 760212795Sdim return true; 761212795Sdim } 762212795Sdim 763212795Sdim Friend_specified = true; 764212795Sdim FriendLoc = Loc; 765212795Sdim return false; 766212795Sdim} 767212795Sdim 768226633Sdimbool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, 769226633Sdim unsigned &DiagID) { 770226633Sdim if (isModulePrivateSpecified()) { 771226633Sdim PrevSpec = "__module_private__"; 772226633Sdim DiagID = diag::ext_duplicate_declspec; 773226633Sdim return true; 774226633Sdim } 775226633Sdim 776226633Sdim ModulePrivateLoc = Loc; 777226633Sdim return false; 778226633Sdim} 779226633Sdim 780212795Sdimbool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, 781212795Sdim unsigned &DiagID) { 782212795Sdim // 'constexpr constexpr' is ok. 783212795Sdim Constexpr_specified = true; 784212795Sdim ConstexprLoc = Loc; 785212795Sdim return false; 786212795Sdim} 787212795Sdim 788212795Sdimvoid DeclSpec::setProtocolQualifiers(Decl * const *Protos, 789212795Sdim unsigned NP, 790212795Sdim SourceLocation *ProtoLocs, 791212795Sdim SourceLocation LAngleLoc) { 792212795Sdim if (NP == 0) return; 793249423Sdim Decl **ProtoQuals = new Decl*[NP]; 794249423Sdim memcpy(ProtoQuals, Protos, sizeof(Decl*)*NP); 795249423Sdim ProtocolQualifiers = ProtoQuals; 796212795Sdim ProtocolLocs = new SourceLocation[NP]; 797212795Sdim memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); 798212795Sdim NumProtocolQualifiers = NP; 799212795Sdim ProtocolLAngleLoc = LAngleLoc; 800212795Sdim} 801212795Sdim 802212795Sdimvoid DeclSpec::SaveWrittenBuiltinSpecs() { 803212795Sdim writtenBS.Sign = getTypeSpecSign(); 804212795Sdim writtenBS.Width = getTypeSpecWidth(); 805212795Sdim writtenBS.Type = getTypeSpecType(); 806212795Sdim // Search the list of attributes for the presence of a mode attribute. 807212795Sdim writtenBS.ModeAttr = false; 808218893Sdim AttributeList* attrs = getAttributes().getList(); 809212795Sdim while (attrs) { 810239462Sdim if (attrs->getKind() == AttributeList::AT_Mode) { 811212795Sdim writtenBS.ModeAttr = true; 812212795Sdim break; 813212795Sdim } 814212795Sdim attrs = attrs->getNext(); 815212795Sdim } 816212795Sdim} 817212795Sdim 818212795Sdim/// Finish - This does final analysis of the declspec, rejecting things like 819212795Sdim/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or 820212795Sdim/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, 821212795Sdim/// DeclSpec is guaranteed self-consistent, even if an error occurred. 822226633Sdimvoid DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { 823212795Sdim // Before possibly changing their values, save specs as written. 824212795Sdim SaveWrittenBuiltinSpecs(); 825212795Sdim 826212795Sdim // Check the type specifier components first. 827212795Sdim 828212795Sdim // Validate and finalize AltiVec vector declspec. 829212795Sdim if (TypeAltiVecVector) { 830212795Sdim if (TypeAltiVecBool) { 831212795Sdim // Sign specifiers are not allowed with vector bool. (PIM 2.1) 832212795Sdim if (TypeSpecSign != TSS_unspecified) { 833218893Sdim Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec) 834212795Sdim << getSpecifierName((TSS)TypeSpecSign); 835212795Sdim } 836212795Sdim 837212795Sdim // Only char/int are valid with vector bool. (PIM 2.1) 838212795Sdim if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && 839212795Sdim (TypeSpecType != TST_int)) || TypeAltiVecPixel) { 840218893Sdim Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec) 841212795Sdim << (TypeAltiVecPixel ? "__pixel" : 842212795Sdim getSpecifierName((TST)TypeSpecType)); 843212795Sdim } 844212795Sdim 845212795Sdim // Only 'short' is valid with vector bool. (PIM 2.1) 846212795Sdim if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) 847218893Sdim Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) 848212795Sdim << getSpecifierName((TSW)TypeSpecWidth); 849212795Sdim 850212795Sdim // Elements of vector bool are interpreted as unsigned. (PIM 2.1) 851212795Sdim if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || 852212795Sdim (TypeSpecWidth != TSW_unspecified)) 853212795Sdim TypeSpecSign = TSS_unsigned; 854212795Sdim } 855212795Sdim 856212795Sdim if (TypeAltiVecPixel) { 857212795Sdim //TODO: perform validation 858212795Sdim TypeSpecType = TST_int; 859212795Sdim TypeSpecSign = TSS_unsigned; 860212795Sdim TypeSpecWidth = TSW_short; 861212795Sdim TypeSpecOwned = false; 862212795Sdim } 863212795Sdim } 864212795Sdim 865212795Sdim // signed/unsigned are only valid with int/char/wchar_t. 866212795Sdim if (TypeSpecSign != TSS_unspecified) { 867212795Sdim if (TypeSpecType == TST_unspecified) 868212795Sdim TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. 869234353Sdim else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && 870212795Sdim TypeSpecType != TST_char && TypeSpecType != TST_wchar) { 871218893Sdim Diag(D, TSSLoc, diag::err_invalid_sign_spec) 872212795Sdim << getSpecifierName((TST)TypeSpecType); 873212795Sdim // signed double -> double. 874212795Sdim TypeSpecSign = TSS_unspecified; 875212795Sdim } 876212795Sdim } 877212795Sdim 878212795Sdim // Validate the width of the type. 879212795Sdim switch (TypeSpecWidth) { 880212795Sdim case TSW_unspecified: break; 881212795Sdim case TSW_short: // short int 882212795Sdim case TSW_longlong: // long long int 883212795Sdim if (TypeSpecType == TST_unspecified) 884212795Sdim TypeSpecType = TST_int; // short -> short int, long long -> long long int. 885212795Sdim else if (TypeSpecType != TST_int) { 886218893Sdim Diag(D, TSWLoc, 887212795Sdim TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec 888212795Sdim : diag::err_invalid_longlong_spec) 889212795Sdim << getSpecifierName((TST)TypeSpecType); 890212795Sdim TypeSpecType = TST_int; 891212795Sdim TypeSpecOwned = false; 892212795Sdim } 893212795Sdim break; 894212795Sdim case TSW_long: // long double, long int 895212795Sdim if (TypeSpecType == TST_unspecified) 896212795Sdim TypeSpecType = TST_int; // long -> long int. 897212795Sdim else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { 898218893Sdim Diag(D, TSWLoc, diag::err_invalid_long_spec) 899212795Sdim << getSpecifierName((TST)TypeSpecType); 900212795Sdim TypeSpecType = TST_int; 901212795Sdim TypeSpecOwned = false; 902212795Sdim } 903212795Sdim break; 904212795Sdim } 905212795Sdim 906212795Sdim // TODO: if the implementation does not implement _Complex or _Imaginary, 907212795Sdim // disallow their use. Need information about the backend. 908212795Sdim if (TypeSpecComplex != TSC_unspecified) { 909212795Sdim if (TypeSpecType == TST_unspecified) { 910218893Sdim Diag(D, TSCLoc, diag::ext_plain_complex) 911212795Sdim << FixItHint::CreateInsertion( 912212795Sdim PP.getLocForEndOfToken(getTypeSpecComplexLoc()), 913212795Sdim " double"); 914212795Sdim TypeSpecType = TST_double; // _Complex -> _Complex double. 915212795Sdim } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { 916212795Sdim // Note that this intentionally doesn't include _Complex _Bool. 917234353Sdim if (!PP.getLangOpts().CPlusPlus) 918234353Sdim Diag(D, TSTLoc, diag::ext_integer_complex); 919212795Sdim } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { 920218893Sdim Diag(D, TSCLoc, diag::err_invalid_complex_spec) 921212795Sdim << getSpecifierName((TST)TypeSpecType); 922212795Sdim TypeSpecComplex = TSC_unspecified; 923212795Sdim } 924212795Sdim } 925212795Sdim 926226633Sdim // If no type specifier was provided and we're parsing a language where 927226633Sdim // the type specifier is not optional, but we got 'auto' as a storage 928226633Sdim // class specifier, then assume this is an attempt to use C++0x's 'auto' 929226633Sdim // type specifier. 930226633Sdim // FIXME: Does Microsoft really support implicit int in C++? 931234353Sdim if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt && 932226633Sdim TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) { 933226633Sdim TypeSpecType = TST_auto; 934249423Sdim StorageClassSpec = SCS_unspecified; 935226633Sdim TSTLoc = TSTNameLoc = StorageClassSpecLoc; 936226633Sdim StorageClassSpecLoc = SourceLocation(); 937226633Sdim } 938226633Sdim // Diagnose if we've recovered from an ill-formed 'auto' storage class 939226633Sdim // specifier in a pre-C++0x dialect of C++. 940249423Sdim if (!PP.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto) 941226633Sdim Diag(D, TSTLoc, diag::ext_auto_type_specifier); 942249423Sdim if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus11 && 943226633Sdim StorageClassSpec == SCS_auto) 944226633Sdim Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class) 945226633Sdim << FixItHint::CreateRemoval(StorageClassSpecLoc); 946234353Sdim if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) 947234353Sdim Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type) 948234353Sdim << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); 949234353Sdim if (Constexpr_specified) 950234353Sdim Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr); 951226633Sdim 952212795Sdim // C++ [class.friend]p6: 953212795Sdim // No storage-class-specifier shall appear in the decl-specifier-seq 954212795Sdim // of a friend declaration. 955212795Sdim if (isFriendSpecified() && getStorageClassSpec()) { 956212795Sdim DeclSpec::SCS SC = getStorageClassSpec(); 957212795Sdim const char *SpecName = getSpecifierName(SC); 958212795Sdim 959212795Sdim SourceLocation SCLoc = getStorageClassSpecLoc(); 960226633Sdim SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName)); 961212795Sdim 962218893Sdim Diag(D, SCLoc, diag::err_friend_storage_spec) 963212795Sdim << SpecName 964212795Sdim << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc)); 965212795Sdim 966212795Sdim ClearStorageClassSpecs(); 967212795Sdim } 968212795Sdim 969212795Sdim assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType)); 970226633Sdim 971212795Sdim // Okay, now we can infer the real type. 972212795Sdim 973212795Sdim // TODO: return "auto function" and other bad things based on the real type. 974212795Sdim 975212795Sdim // 'data definition has no type or storage class'? 976212795Sdim} 977212795Sdim 978212795Sdimbool DeclSpec::isMissingDeclaratorOk() { 979212795Sdim TST tst = getTypeSpecType(); 980212795Sdim return isDeclRep(tst) && getRepAsDecl() != 0 && 981212795Sdim StorageClassSpec != DeclSpec::SCS_typedef; 982212795Sdim} 983212795Sdim 984212795Sdimvoid UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 985212795Sdim OverloadedOperatorKind Op, 986212795Sdim SourceLocation SymbolLocations[3]) { 987212795Sdim Kind = IK_OperatorFunctionId; 988212795Sdim StartLocation = OperatorLoc; 989212795Sdim EndLocation = OperatorLoc; 990212795Sdim OperatorFunctionId.Operator = Op; 991212795Sdim for (unsigned I = 0; I != 3; ++I) { 992212795Sdim OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); 993212795Sdim 994212795Sdim if (SymbolLocations[I].isValid()) 995212795Sdim EndLocation = SymbolLocations[I]; 996212795Sdim } 997212795Sdim} 998218893Sdim 999218893Sdimbool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, 1000218893Sdim const char *&PrevSpec) { 1001221345Sdim LastLocation = Loc; 1002221345Sdim 1003218893Sdim if (Specifiers & VS) { 1004218893Sdim PrevSpec = getSpecifierName(VS); 1005218893Sdim return true; 1006218893Sdim } 1007218893Sdim 1008218893Sdim Specifiers |= VS; 1009218893Sdim 1010218893Sdim switch (VS) { 1011226633Sdim default: llvm_unreachable("Unknown specifier!"); 1012218893Sdim case VS_Override: VS_overrideLoc = Loc; break; 1013218893Sdim case VS_Final: VS_finalLoc = Loc; break; 1014218893Sdim } 1015218893Sdim 1016218893Sdim return false; 1017218893Sdim} 1018218893Sdim 1019218893Sdimconst char *VirtSpecifiers::getSpecifierName(Specifier VS) { 1020218893Sdim switch (VS) { 1021226633Sdim default: llvm_unreachable("Unknown specifier"); 1022218893Sdim case VS_Override: return "override"; 1023218893Sdim case VS_Final: return "final"; 1024218893Sdim } 1025218893Sdim} 1026