clang API Documentation
00001 //===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements semantic analysis for declaration specifiers. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency! 00015 #include "clang/Sema/DeclSpec.h" 00016 #include "clang/Sema/LocInfoType.h" 00017 #include "clang/Sema/ParsedTemplate.h" 00018 #include "clang/Sema/SemaDiagnostic.h" 00019 #include "clang/Sema/Sema.h" 00020 #include "clang/AST/ASTContext.h" 00021 #include "clang/AST/Expr.h" 00022 #include "clang/AST/NestedNameSpecifier.h" 00023 #include "clang/AST/TypeLoc.h" 00024 #include "clang/Lex/Preprocessor.h" 00025 #include "clang/Basic/LangOptions.h" 00026 #include "llvm/ADT/STLExtras.h" 00027 #include "llvm/Support/ErrorHandling.h" 00028 #include <cstring> 00029 using namespace clang; 00030 00031 00032 static DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc, 00033 unsigned DiagID) { 00034 return D.Report(Loc, DiagID); 00035 } 00036 00037 00038 void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { 00039 assert(TemplateId && "NULL template-id annotation?"); 00040 Kind = IK_TemplateId; 00041 this->TemplateId = TemplateId; 00042 StartLocation = TemplateId->TemplateNameLoc; 00043 EndLocation = TemplateId->RAngleLoc; 00044 } 00045 00046 void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { 00047 assert(TemplateId && "NULL template-id annotation?"); 00048 Kind = IK_ConstructorTemplateId; 00049 this->TemplateId = TemplateId; 00050 StartLocation = TemplateId->TemplateNameLoc; 00051 EndLocation = TemplateId->RAngleLoc; 00052 } 00053 00054 void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc, 00055 TypeLoc TL, SourceLocation ColonColonLoc) { 00056 Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc); 00057 if (Range.getBegin().isInvalid()) 00058 Range.setBegin(TL.getBeginLoc()); 00059 Range.setEnd(ColonColonLoc); 00060 00061 assert(Range == Builder.getSourceRange() && 00062 "NestedNameSpecifierLoc range computation incorrect"); 00063 } 00064 00065 void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier, 00066 SourceLocation IdentifierLoc, 00067 SourceLocation ColonColonLoc) { 00068 Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc); 00069 00070 if (Range.getBegin().isInvalid()) 00071 Range.setBegin(IdentifierLoc); 00072 Range.setEnd(ColonColonLoc); 00073 00074 assert(Range == Builder.getSourceRange() && 00075 "NestedNameSpecifierLoc range computation incorrect"); 00076 } 00077 00078 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace, 00079 SourceLocation NamespaceLoc, 00080 SourceLocation ColonColonLoc) { 00081 Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc); 00082 00083 if (Range.getBegin().isInvalid()) 00084 Range.setBegin(NamespaceLoc); 00085 Range.setEnd(ColonColonLoc); 00086 00087 assert(Range == Builder.getSourceRange() && 00088 "NestedNameSpecifierLoc range computation incorrect"); 00089 } 00090 00091 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 00092 SourceLocation AliasLoc, 00093 SourceLocation ColonColonLoc) { 00094 Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc); 00095 00096 if (Range.getBegin().isInvalid()) 00097 Range.setBegin(AliasLoc); 00098 Range.setEnd(ColonColonLoc); 00099 00100 assert(Range == Builder.getSourceRange() && 00101 "NestedNameSpecifierLoc range computation incorrect"); 00102 } 00103 00104 void CXXScopeSpec::MakeGlobal(ASTContext &Context, 00105 SourceLocation ColonColonLoc) { 00106 Builder.MakeGlobal(Context, ColonColonLoc); 00107 00108 Range = SourceRange(ColonColonLoc); 00109 00110 assert(Range == Builder.getSourceRange() && 00111 "NestedNameSpecifierLoc range computation incorrect"); 00112 } 00113 00114 void CXXScopeSpec::MakeTrivial(ASTContext &Context, 00115 NestedNameSpecifier *Qualifier, SourceRange R) { 00116 Builder.MakeTrivial(Context, Qualifier, R); 00117 Range = R; 00118 } 00119 00120 void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) { 00121 if (!Other) { 00122 Range = SourceRange(); 00123 Builder.Clear(); 00124 return; 00125 } 00126 00127 Range = Other.getSourceRange(); 00128 Builder.Adopt(Other); 00129 } 00130 00131 SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const { 00132 if (!Builder.getRepresentation()) 00133 return SourceLocation(); 00134 return Builder.getTemporary().getLocalBeginLoc(); 00135 } 00136 00137 NestedNameSpecifierLoc 00138 CXXScopeSpec::getWithLocInContext(ASTContext &Context) const { 00139 if (!Builder.getRepresentation()) 00140 return NestedNameSpecifierLoc(); 00141 00142 return Builder.getWithLocInContext(Context); 00143 } 00144 00145 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. 00146 /// "TheDeclarator" is the declarator that this will be added to. 00147 DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, 00148 SourceLocation EllipsisLoc, 00149 ParamInfo *ArgInfo, 00150 unsigned NumArgs, 00151 unsigned TypeQuals, 00152 bool RefQualifierIsLvalueRef, 00153 SourceLocation RefQualifierLoc, 00154 SourceLocation ConstQualifierLoc, 00155 SourceLocation 00156 VolatileQualifierLoc, 00157 SourceLocation MutableLoc, 00158 ExceptionSpecificationType 00159 ESpecType, 00160 SourceLocation ESpecLoc, 00161 ParsedType *Exceptions, 00162 SourceRange *ExceptionRanges, 00163 unsigned NumExceptions, 00164 Expr *NoexceptExpr, 00165 SourceLocation LocalRangeBegin, 00166 SourceLocation LocalRangeEnd, 00167 Declarator &TheDeclarator, 00168 ParsedType TrailingReturnType) { 00169 DeclaratorChunk I; 00170 I.Kind = Function; 00171 I.Loc = LocalRangeBegin; 00172 I.EndLoc = LocalRangeEnd; 00173 I.Fun.AttrList = 0; 00174 I.Fun.hasPrototype = hasProto; 00175 I.Fun.isVariadic = isVariadic; 00176 I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); 00177 I.Fun.DeleteArgInfo = false; 00178 I.Fun.TypeQuals = TypeQuals; 00179 I.Fun.NumArgs = NumArgs; 00180 I.Fun.ArgInfo = 0; 00181 I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; 00182 I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); 00183 I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding(); 00184 I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding(); 00185 I.Fun.MutableLoc = MutableLoc.getRawEncoding(); 00186 I.Fun.ExceptionSpecType = ESpecType; 00187 I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); 00188 I.Fun.NumExceptions = 0; 00189 I.Fun.Exceptions = 0; 00190 I.Fun.NoexceptExpr = 0; 00191 I.Fun.TrailingReturnType = TrailingReturnType.getAsOpaquePtr(); 00192 00193 // new[] an argument array if needed. 00194 if (NumArgs) { 00195 // If the 'InlineParams' in Declarator is unused and big enough, put our 00196 // parameter list there (in an effort to avoid new/delete traffic). If it 00197 // is already used (consider a function returning a function pointer) or too 00198 // small (function taking too many arguments), go to the heap. 00199 if (!TheDeclarator.InlineParamsUsed && 00200 NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) { 00201 I.Fun.ArgInfo = TheDeclarator.InlineParams; 00202 I.Fun.DeleteArgInfo = false; 00203 TheDeclarator.InlineParamsUsed = true; 00204 } else { 00205 I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs]; 00206 I.Fun.DeleteArgInfo = true; 00207 } 00208 memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs); 00209 } 00210 00211 // Check what exception specification information we should actually store. 00212 switch (ESpecType) { 00213 default: break; // By default, save nothing. 00214 case EST_Dynamic: 00215 // new[] an exception array if needed 00216 if (NumExceptions) { 00217 I.Fun.NumExceptions = NumExceptions; 00218 I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions]; 00219 for (unsigned i = 0; i != NumExceptions; ++i) { 00220 I.Fun.Exceptions[i].Ty = Exceptions[i]; 00221 I.Fun.Exceptions[i].Range = ExceptionRanges[i]; 00222 } 00223 } 00224 break; 00225 00226 case EST_ComputedNoexcept: 00227 I.Fun.NoexceptExpr = NoexceptExpr; 00228 break; 00229 } 00230 return I; 00231 } 00232 00233 bool Declarator::isDeclarationOfFunction() const { 00234 for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { 00235 switch (DeclTypeInfo[i].Kind) { 00236 case DeclaratorChunk::Function: 00237 return true; 00238 case DeclaratorChunk::Paren: 00239 continue; 00240 case DeclaratorChunk::Pointer: 00241 case DeclaratorChunk::Reference: 00242 case DeclaratorChunk::Array: 00243 case DeclaratorChunk::BlockPointer: 00244 case DeclaratorChunk::MemberPointer: 00245 return false; 00246 } 00247 llvm_unreachable("Invalid type chunk"); 00248 } 00249 00250 switch (DS.getTypeSpecType()) { 00251 case TST_atomic: 00252 case TST_auto: 00253 case TST_bool: 00254 case TST_char: 00255 case TST_char16: 00256 case TST_char32: 00257 case TST_class: 00258 case TST_decimal128: 00259 case TST_decimal32: 00260 case TST_decimal64: 00261 case TST_double: 00262 case TST_enum: 00263 case TST_error: 00264 case TST_float: 00265 case TST_half: 00266 case TST_int: 00267 case TST_int128: 00268 case TST_struct: 00269 case TST_union: 00270 case TST_unknown_anytype: 00271 case TST_unspecified: 00272 case TST_void: 00273 case TST_wchar: 00274 return false; 00275 00276 case TST_decltype: 00277 case TST_typeofExpr: 00278 if (Expr *E = DS.getRepAsExpr()) 00279 return E->getType()->isFunctionType(); 00280 return false; 00281 00282 case TST_underlyingType: 00283 case TST_typename: 00284 case TST_typeofType: { 00285 QualType QT = DS.getRepAsType().get(); 00286 if (QT.isNull()) 00287 return false; 00288 00289 if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) 00290 QT = LIT->getType(); 00291 00292 if (QT.isNull()) 00293 return false; 00294 00295 return QT->isFunctionType(); 00296 } 00297 } 00298 00299 llvm_unreachable("Invalid TypeSpecType!"); 00300 } 00301 00302 /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this 00303 /// declaration specifier includes. 00304 /// 00305 unsigned DeclSpec::getParsedSpecifiers() const { 00306 unsigned Res = 0; 00307 if (StorageClassSpec != SCS_unspecified || 00308 SCS_thread_specified) 00309 Res |= PQ_StorageClassSpecifier; 00310 00311 if (TypeQualifiers != TQ_unspecified) 00312 Res |= PQ_TypeQualifier; 00313 00314 if (hasTypeSpecifier()) 00315 Res |= PQ_TypeSpecifier; 00316 00317 if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified) 00318 Res |= PQ_FunctionSpecifier; 00319 return Res; 00320 } 00321 00322 template <class T> static bool BadSpecifier(T TNew, T TPrev, 00323 const char *&PrevSpec, 00324 unsigned &DiagID) { 00325 PrevSpec = DeclSpec::getSpecifierName(TPrev); 00326 DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec 00327 : diag::err_invalid_decl_spec_combination); 00328 return true; 00329 } 00330 00331 const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) { 00332 switch (S) { 00333 case DeclSpec::SCS_unspecified: return "unspecified"; 00334 case DeclSpec::SCS_typedef: return "typedef"; 00335 case DeclSpec::SCS_extern: return "extern"; 00336 case DeclSpec::SCS_static: return "static"; 00337 case DeclSpec::SCS_auto: return "auto"; 00338 case DeclSpec::SCS_register: return "register"; 00339 case DeclSpec::SCS_private_extern: return "__private_extern__"; 00340 case DeclSpec::SCS_mutable: return "mutable"; 00341 } 00342 llvm_unreachable("Unknown typespec!"); 00343 } 00344 00345 const char *DeclSpec::getSpecifierName(TSW W) { 00346 switch (W) { 00347 case TSW_unspecified: return "unspecified"; 00348 case TSW_short: return "short"; 00349 case TSW_long: return "long"; 00350 case TSW_longlong: return "long long"; 00351 } 00352 llvm_unreachable("Unknown typespec!"); 00353 } 00354 00355 const char *DeclSpec::getSpecifierName(TSC C) { 00356 switch (C) { 00357 case TSC_unspecified: return "unspecified"; 00358 case TSC_imaginary: return "imaginary"; 00359 case TSC_complex: return "complex"; 00360 } 00361 llvm_unreachable("Unknown typespec!"); 00362 } 00363 00364 00365 const char *DeclSpec::getSpecifierName(TSS S) { 00366 switch (S) { 00367 case TSS_unspecified: return "unspecified"; 00368 case TSS_signed: return "signed"; 00369 case TSS_unsigned: return "unsigned"; 00370 } 00371 llvm_unreachable("Unknown typespec!"); 00372 } 00373 00374 const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { 00375 switch (T) { 00376 case DeclSpec::TST_unspecified: return "unspecified"; 00377 case DeclSpec::TST_void: return "void"; 00378 case DeclSpec::TST_char: return "char"; 00379 case DeclSpec::TST_wchar: return "wchar_t"; 00380 case DeclSpec::TST_char16: return "char16_t"; 00381 case DeclSpec::TST_char32: return "char32_t"; 00382 case DeclSpec::TST_int: return "int"; 00383 case DeclSpec::TST_int128: return "__int128"; 00384 case DeclSpec::TST_half: return "half"; 00385 case DeclSpec::TST_float: return "float"; 00386 case DeclSpec::TST_double: return "double"; 00387 case DeclSpec::TST_bool: return "_Bool"; 00388 case DeclSpec::TST_decimal32: return "_Decimal32"; 00389 case DeclSpec::TST_decimal64: return "_Decimal64"; 00390 case DeclSpec::TST_decimal128: return "_Decimal128"; 00391 case DeclSpec::TST_enum: return "enum"; 00392 case DeclSpec::TST_class: return "class"; 00393 case DeclSpec::TST_union: return "union"; 00394 case DeclSpec::TST_struct: return "struct"; 00395 case DeclSpec::TST_typename: return "type-name"; 00396 case DeclSpec::TST_typeofType: 00397 case DeclSpec::TST_typeofExpr: return "typeof"; 00398 case DeclSpec::TST_auto: return "auto"; 00399 case DeclSpec::TST_decltype: return "(decltype)"; 00400 case DeclSpec::TST_underlyingType: return "__underlying_type"; 00401 case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; 00402 case DeclSpec::TST_atomic: return "_Atomic"; 00403 case DeclSpec::TST_error: return "(error)"; 00404 } 00405 llvm_unreachable("Unknown typespec!"); 00406 } 00407 00408 const char *DeclSpec::getSpecifierName(TQ T) { 00409 switch (T) { 00410 case DeclSpec::TQ_unspecified: return "unspecified"; 00411 case DeclSpec::TQ_const: return "const"; 00412 case DeclSpec::TQ_restrict: return "restrict"; 00413 case DeclSpec::TQ_volatile: return "volatile"; 00414 } 00415 llvm_unreachable("Unknown typespec!"); 00416 } 00417 00418 bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, 00419 const char *&PrevSpec, 00420 unsigned &DiagID) { 00421 // OpenCL 1.1 6.8g: "The extern, static, auto and register storage-class 00422 // specifiers are not supported." 00423 // It seems sensible to prohibit private_extern too 00424 // The cl_clang_storage_class_specifiers extension enables support for 00425 // these storage-class specifiers. 00426 if (S.getLangOpts().OpenCL && 00427 !S.getOpenCLOptions().cl_clang_storage_class_specifiers) { 00428 switch (SC) { 00429 case SCS_extern: 00430 case SCS_private_extern: 00431 case SCS_auto: 00432 case SCS_register: 00433 case SCS_static: 00434 DiagID = diag::err_not_opencl_storage_class_specifier; 00435 PrevSpec = getSpecifierName(SC); 00436 return true; 00437 default: 00438 break; 00439 } 00440 } 00441 00442 if (StorageClassSpec != SCS_unspecified) { 00443 // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode. 00444 bool isInvalid = true; 00445 if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) { 00446 if (SC == SCS_auto) 00447 return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID); 00448 if (StorageClassSpec == SCS_auto) { 00449 isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc, 00450 PrevSpec, DiagID); 00451 assert(!isInvalid && "auto SCS -> TST recovery failed"); 00452 } 00453 } 00454 00455 // Changing storage class is allowed only if the previous one 00456 // was the 'extern' that is part of a linkage specification and 00457 // the new storage class is 'typedef'. 00458 if (isInvalid && 00459 !(SCS_extern_in_linkage_spec && 00460 StorageClassSpec == SCS_extern && 00461 SC == SCS_typedef)) 00462 return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID); 00463 } 00464 StorageClassSpec = SC; 00465 StorageClassSpecLoc = Loc; 00466 assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield"); 00467 return false; 00468 } 00469 00470 bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc, 00471 const char *&PrevSpec, 00472 unsigned &DiagID) { 00473 if (SCS_thread_specified) { 00474 PrevSpec = "__thread"; 00475 DiagID = diag::ext_duplicate_declspec; 00476 return true; 00477 } 00478 SCS_thread_specified = true; 00479 SCS_threadLoc = Loc; 00480 return false; 00481 } 00482 00483 /// These methods set the specified attribute of the DeclSpec, but return true 00484 /// and ignore the request if invalid (e.g. "extern" then "auto" is 00485 /// specified). 00486 bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, 00487 const char *&PrevSpec, 00488 unsigned &DiagID) { 00489 // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that 00490 // for 'long long' we will keep the source location of the first 'long'. 00491 if (TypeSpecWidth == TSW_unspecified) 00492 TSWLoc = Loc; 00493 // Allow turning long -> long long. 00494 else if (W != TSW_longlong || TypeSpecWidth != TSW_long) 00495 return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); 00496 TypeSpecWidth = W; 00497 if (TypeAltiVecVector && !TypeAltiVecBool && 00498 ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { 00499 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 00500 DiagID = diag::warn_vector_long_decl_spec_combination; 00501 return true; 00502 } 00503 return false; 00504 } 00505 00506 bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, 00507 const char *&PrevSpec, 00508 unsigned &DiagID) { 00509 if (TypeSpecComplex != TSC_unspecified) 00510 return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); 00511 TypeSpecComplex = C; 00512 TSCLoc = Loc; 00513 return false; 00514 } 00515 00516 bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, 00517 const char *&PrevSpec, 00518 unsigned &DiagID) { 00519 if (TypeSpecSign != TSS_unspecified) 00520 return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); 00521 TypeSpecSign = S; 00522 TSSLoc = Loc; 00523 return false; 00524 } 00525 00526 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 00527 const char *&PrevSpec, 00528 unsigned &DiagID, 00529 ParsedType Rep) { 00530 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep); 00531 } 00532 00533 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 00534 SourceLocation TagNameLoc, 00535 const char *&PrevSpec, 00536 unsigned &DiagID, 00537 ParsedType Rep) { 00538 assert(isTypeRep(T) && "T does not store a type"); 00539 assert(Rep && "no type provided!"); 00540 if (TypeSpecType != TST_unspecified) { 00541 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 00542 DiagID = diag::err_invalid_decl_spec_combination; 00543 return true; 00544 } 00545 TypeSpecType = T; 00546 TypeRep = Rep; 00547 TSTLoc = TagKwLoc; 00548 TSTNameLoc = TagNameLoc; 00549 TypeSpecOwned = false; 00550 return false; 00551 } 00552 00553 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 00554 const char *&PrevSpec, 00555 unsigned &DiagID, 00556 Expr *Rep) { 00557 assert(isExprRep(T) && "T does not store an expr"); 00558 assert(Rep && "no expression provided!"); 00559 if (TypeSpecType != TST_unspecified) { 00560 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 00561 DiagID = diag::err_invalid_decl_spec_combination; 00562 return true; 00563 } 00564 TypeSpecType = T; 00565 ExprRep = Rep; 00566 TSTLoc = Loc; 00567 TSTNameLoc = Loc; 00568 TypeSpecOwned = false; 00569 return false; 00570 } 00571 00572 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 00573 const char *&PrevSpec, 00574 unsigned &DiagID, 00575 Decl *Rep, bool Owned) { 00576 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned); 00577 } 00578 00579 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, 00580 SourceLocation TagNameLoc, 00581 const char *&PrevSpec, 00582 unsigned &DiagID, 00583 Decl *Rep, bool Owned) { 00584 assert(isDeclRep(T) && "T does not store a decl"); 00585 // Unlike the other cases, we don't assert that we actually get a decl. 00586 00587 if (TypeSpecType != TST_unspecified) { 00588 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 00589 DiagID = diag::err_invalid_decl_spec_combination; 00590 return true; 00591 } 00592 TypeSpecType = T; 00593 DeclRep = Rep; 00594 TSTLoc = TagKwLoc; 00595 TSTNameLoc = TagNameLoc; 00596 TypeSpecOwned = Owned; 00597 return false; 00598 } 00599 00600 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, 00601 const char *&PrevSpec, 00602 unsigned &DiagID) { 00603 assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) && 00604 "rep required for these type-spec kinds!"); 00605 if (TypeSpecType != TST_unspecified) { 00606 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 00607 DiagID = diag::err_invalid_decl_spec_combination; 00608 return true; 00609 } 00610 TSTLoc = Loc; 00611 TSTNameLoc = Loc; 00612 if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { 00613 TypeAltiVecBool = true; 00614 return false; 00615 } 00616 TypeSpecType = T; 00617 TypeSpecOwned = false; 00618 if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { 00619 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 00620 DiagID = diag::err_invalid_vector_decl_spec; 00621 return true; 00622 } 00623 return false; 00624 } 00625 00626 bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 00627 const char *&PrevSpec, unsigned &DiagID) { 00628 if (TypeSpecType != TST_unspecified) { 00629 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 00630 DiagID = diag::err_invalid_vector_decl_spec_combination; 00631 return true; 00632 } 00633 TypeAltiVecVector = isAltiVecVector; 00634 AltiVecLoc = Loc; 00635 return false; 00636 } 00637 00638 bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 00639 const char *&PrevSpec, unsigned &DiagID) { 00640 if (!TypeAltiVecVector || TypeAltiVecPixel || 00641 (TypeSpecType != TST_unspecified)) { 00642 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); 00643 DiagID = diag::err_invalid_pixel_decl_spec_combination; 00644 return true; 00645 } 00646 TypeAltiVecPixel = isAltiVecPixel; 00647 TSTLoc = Loc; 00648 TSTNameLoc = Loc; 00649 return false; 00650 } 00651 00652 bool DeclSpec::SetTypeSpecError() { 00653 TypeSpecType = TST_error; 00654 TypeSpecOwned = false; 00655 TSTLoc = SourceLocation(); 00656 TSTNameLoc = SourceLocation(); 00657 return false; 00658 } 00659 00660 bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 00661 unsigned &DiagID, const LangOptions &Lang) { 00662 // Duplicates turn into warnings pre-C99. 00663 if ((TypeQualifiers & T) && !Lang.C99) 00664 return BadSpecifier(T, T, PrevSpec, DiagID); 00665 TypeQualifiers |= T; 00666 00667 switch (T) { 00668 default: llvm_unreachable("Unknown type qualifier!"); 00669 case TQ_const: TQ_constLoc = Loc; break; 00670 case TQ_restrict: TQ_restrictLoc = Loc; break; 00671 case TQ_volatile: TQ_volatileLoc = Loc; break; 00672 } 00673 return false; 00674 } 00675 00676 bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, 00677 unsigned &DiagID) { 00678 // 'inline inline' is ok. 00679 FS_inline_specified = true; 00680 FS_inlineLoc = Loc; 00681 return false; 00682 } 00683 00684 bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, 00685 unsigned &DiagID) { 00686 // 'virtual virtual' is ok. 00687 FS_virtual_specified = true; 00688 FS_virtualLoc = Loc; 00689 return false; 00690 } 00691 00692 bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, 00693 unsigned &DiagID) { 00694 // 'explicit explicit' is ok. 00695 FS_explicit_specified = true; 00696 FS_explicitLoc = Loc; 00697 return false; 00698 } 00699 00700 bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 00701 unsigned &DiagID) { 00702 if (Friend_specified) { 00703 PrevSpec = "friend"; 00704 DiagID = diag::ext_duplicate_declspec; 00705 return true; 00706 } 00707 00708 Friend_specified = true; 00709 FriendLoc = Loc; 00710 return false; 00711 } 00712 00713 bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, 00714 unsigned &DiagID) { 00715 if (isModulePrivateSpecified()) { 00716 PrevSpec = "__module_private__"; 00717 DiagID = diag::ext_duplicate_declspec; 00718 return true; 00719 } 00720 00721 ModulePrivateLoc = Loc; 00722 return false; 00723 } 00724 00725 bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, 00726 unsigned &DiagID) { 00727 // 'constexpr constexpr' is ok. 00728 Constexpr_specified = true; 00729 ConstexprLoc = Loc; 00730 return false; 00731 } 00732 00733 void DeclSpec::setProtocolQualifiers(Decl * const *Protos, 00734 unsigned NP, 00735 SourceLocation *ProtoLocs, 00736 SourceLocation LAngleLoc) { 00737 if (NP == 0) return; 00738 ProtocolQualifiers = new Decl*[NP]; 00739 ProtocolLocs = new SourceLocation[NP]; 00740 memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP); 00741 memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); 00742 NumProtocolQualifiers = NP; 00743 ProtocolLAngleLoc = LAngleLoc; 00744 } 00745 00746 void DeclSpec::SaveWrittenBuiltinSpecs() { 00747 writtenBS.Sign = getTypeSpecSign(); 00748 writtenBS.Width = getTypeSpecWidth(); 00749 writtenBS.Type = getTypeSpecType(); 00750 // Search the list of attributes for the presence of a mode attribute. 00751 writtenBS.ModeAttr = false; 00752 AttributeList* attrs = getAttributes().getList(); 00753 while (attrs) { 00754 if (attrs->getKind() == AttributeList::AT_mode) { 00755 writtenBS.ModeAttr = true; 00756 break; 00757 } 00758 attrs = attrs->getNext(); 00759 } 00760 } 00761 00762 void DeclSpec::SaveStorageSpecifierAsWritten() { 00763 if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern) 00764 // If 'extern' is part of a linkage specification, 00765 // then it is not a storage class "as written". 00766 StorageClassSpecAsWritten = SCS_unspecified; 00767 else 00768 StorageClassSpecAsWritten = StorageClassSpec; 00769 } 00770 00771 /// Finish - This does final analysis of the declspec, rejecting things like 00772 /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or 00773 /// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, 00774 /// DeclSpec is guaranteed self-consistent, even if an error occurred. 00775 void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { 00776 // Before possibly changing their values, save specs as written. 00777 SaveWrittenBuiltinSpecs(); 00778 SaveStorageSpecifierAsWritten(); 00779 00780 // Check the type specifier components first. 00781 00782 // Validate and finalize AltiVec vector declspec. 00783 if (TypeAltiVecVector) { 00784 if (TypeAltiVecBool) { 00785 // Sign specifiers are not allowed with vector bool. (PIM 2.1) 00786 if (TypeSpecSign != TSS_unspecified) { 00787 Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec) 00788 << getSpecifierName((TSS)TypeSpecSign); 00789 } 00790 00791 // Only char/int are valid with vector bool. (PIM 2.1) 00792 if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && 00793 (TypeSpecType != TST_int)) || TypeAltiVecPixel) { 00794 Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec) 00795 << (TypeAltiVecPixel ? "__pixel" : 00796 getSpecifierName((TST)TypeSpecType)); 00797 } 00798 00799 // Only 'short' is valid with vector bool. (PIM 2.1) 00800 if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) 00801 Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) 00802 << getSpecifierName((TSW)TypeSpecWidth); 00803 00804 // Elements of vector bool are interpreted as unsigned. (PIM 2.1) 00805 if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || 00806 (TypeSpecWidth != TSW_unspecified)) 00807 TypeSpecSign = TSS_unsigned; 00808 } 00809 00810 if (TypeAltiVecPixel) { 00811 //TODO: perform validation 00812 TypeSpecType = TST_int; 00813 TypeSpecSign = TSS_unsigned; 00814 TypeSpecWidth = TSW_short; 00815 TypeSpecOwned = false; 00816 } 00817 } 00818 00819 // signed/unsigned are only valid with int/char/wchar_t. 00820 if (TypeSpecSign != TSS_unspecified) { 00821 if (TypeSpecType == TST_unspecified) 00822 TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. 00823 else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && 00824 TypeSpecType != TST_char && TypeSpecType != TST_wchar) { 00825 Diag(D, TSSLoc, diag::err_invalid_sign_spec) 00826 << getSpecifierName((TST)TypeSpecType); 00827 // signed double -> double. 00828 TypeSpecSign = TSS_unspecified; 00829 } 00830 } 00831 00832 // Validate the width of the type. 00833 switch (TypeSpecWidth) { 00834 case TSW_unspecified: break; 00835 case TSW_short: // short int 00836 case TSW_longlong: // long long int 00837 if (TypeSpecType == TST_unspecified) 00838 TypeSpecType = TST_int; // short -> short int, long long -> long long int. 00839 else if (TypeSpecType != TST_int) { 00840 Diag(D, TSWLoc, 00841 TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec 00842 : diag::err_invalid_longlong_spec) 00843 << getSpecifierName((TST)TypeSpecType); 00844 TypeSpecType = TST_int; 00845 TypeSpecOwned = false; 00846 } 00847 break; 00848 case TSW_long: // long double, long int 00849 if (TypeSpecType == TST_unspecified) 00850 TypeSpecType = TST_int; // long -> long int. 00851 else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { 00852 Diag(D, TSWLoc, diag::err_invalid_long_spec) 00853 << getSpecifierName((TST)TypeSpecType); 00854 TypeSpecType = TST_int; 00855 TypeSpecOwned = false; 00856 } 00857 break; 00858 } 00859 00860 // TODO: if the implementation does not implement _Complex or _Imaginary, 00861 // disallow their use. Need information about the backend. 00862 if (TypeSpecComplex != TSC_unspecified) { 00863 if (TypeSpecType == TST_unspecified) { 00864 Diag(D, TSCLoc, diag::ext_plain_complex) 00865 << FixItHint::CreateInsertion( 00866 PP.getLocForEndOfToken(getTypeSpecComplexLoc()), 00867 " double"); 00868 TypeSpecType = TST_double; // _Complex -> _Complex double. 00869 } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { 00870 // Note that this intentionally doesn't include _Complex _Bool. 00871 if (!PP.getLangOpts().CPlusPlus) 00872 Diag(D, TSTLoc, diag::ext_integer_complex); 00873 } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { 00874 Diag(D, TSCLoc, diag::err_invalid_complex_spec) 00875 << getSpecifierName((TST)TypeSpecType); 00876 TypeSpecComplex = TSC_unspecified; 00877 } 00878 } 00879 00880 // If no type specifier was provided and we're parsing a language where 00881 // the type specifier is not optional, but we got 'auto' as a storage 00882 // class specifier, then assume this is an attempt to use C++0x's 'auto' 00883 // type specifier. 00884 // FIXME: Does Microsoft really support implicit int in C++? 00885 if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt && 00886 TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) { 00887 TypeSpecType = TST_auto; 00888 StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified; 00889 TSTLoc = TSTNameLoc = StorageClassSpecLoc; 00890 StorageClassSpecLoc = SourceLocation(); 00891 } 00892 // Diagnose if we've recovered from an ill-formed 'auto' storage class 00893 // specifier in a pre-C++0x dialect of C++. 00894 if (!PP.getLangOpts().CPlusPlus0x && TypeSpecType == TST_auto) 00895 Diag(D, TSTLoc, diag::ext_auto_type_specifier); 00896 if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus0x && 00897 StorageClassSpec == SCS_auto) 00898 Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class) 00899 << FixItHint::CreateRemoval(StorageClassSpecLoc); 00900 if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) 00901 Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type) 00902 << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); 00903 if (Constexpr_specified) 00904 Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr); 00905 00906 // C++ [class.friend]p6: 00907 // No storage-class-specifier shall appear in the decl-specifier-seq 00908 // of a friend declaration. 00909 if (isFriendSpecified() && getStorageClassSpec()) { 00910 DeclSpec::SCS SC = getStorageClassSpec(); 00911 const char *SpecName = getSpecifierName(SC); 00912 00913 SourceLocation SCLoc = getStorageClassSpecLoc(); 00914 SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName)); 00915 00916 Diag(D, SCLoc, diag::err_friend_storage_spec) 00917 << SpecName 00918 << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc)); 00919 00920 ClearStorageClassSpecs(); 00921 } 00922 00923 assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType)); 00924 00925 // Okay, now we can infer the real type. 00926 00927 // TODO: return "auto function" and other bad things based on the real type. 00928 00929 // 'data definition has no type or storage class'? 00930 } 00931 00932 bool DeclSpec::isMissingDeclaratorOk() { 00933 TST tst = getTypeSpecType(); 00934 return isDeclRep(tst) && getRepAsDecl() != 0 && 00935 StorageClassSpec != DeclSpec::SCS_typedef; 00936 } 00937 00938 void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 00939 OverloadedOperatorKind Op, 00940 SourceLocation SymbolLocations[3]) { 00941 Kind = IK_OperatorFunctionId; 00942 StartLocation = OperatorLoc; 00943 EndLocation = OperatorLoc; 00944 OperatorFunctionId.Operator = Op; 00945 for (unsigned I = 0; I != 3; ++I) { 00946 OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); 00947 00948 if (SymbolLocations[I].isValid()) 00949 EndLocation = SymbolLocations[I]; 00950 } 00951 } 00952 00953 bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, 00954 const char *&PrevSpec) { 00955 LastLocation = Loc; 00956 00957 if (Specifiers & VS) { 00958 PrevSpec = getSpecifierName(VS); 00959 return true; 00960 } 00961 00962 Specifiers |= VS; 00963 00964 switch (VS) { 00965 default: llvm_unreachable("Unknown specifier!"); 00966 case VS_Override: VS_overrideLoc = Loc; break; 00967 case VS_Final: VS_finalLoc = Loc; break; 00968 } 00969 00970 return false; 00971 } 00972 00973 const char *VirtSpecifiers::getSpecifierName(Specifier VS) { 00974 switch (VS) { 00975 default: llvm_unreachable("Unknown specifier"); 00976 case VS_Override: return "override"; 00977 case VS_Final: return "final"; 00978 } 00979 }