1 //===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements semantic analysis for declaration specifiers.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
15 #include "clang/Sema/DeclSpec.h"
16 #include "clang/Sema/LocInfoType.h"
17 #include "clang/Sema/ParsedTemplate.h"
18 #include "clang/Sema/SemaDiagnostic.h"
19 #include "clang/Sema/Sema.h"
20 #include "clang/AST/ASTContext.h"
21 #include "clang/AST/Expr.h"
22 #include "clang/AST/NestedNameSpecifier.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/Lex/Preprocessor.h"
25 #include "clang/Basic/LangOptions.h"
26 #include "llvm/ADT/STLExtras.h"
27 #include "llvm/Support/ErrorHandling.h"
29 using namespace clang;
32 static DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc,
34 return D.Report(Loc, DiagID);
38 void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
39 assert(TemplateId && "NULL template-id annotation?");
41 this->TemplateId = TemplateId;
42 StartLocation = TemplateId->TemplateNameLoc;
43 EndLocation = TemplateId->RAngleLoc;
46 void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
47 assert(TemplateId && "NULL template-id annotation?");
48 Kind = IK_ConstructorTemplateId;
49 this->TemplateId = TemplateId;
50 StartLocation = TemplateId->TemplateNameLoc;
51 EndLocation = TemplateId->RAngleLoc;
54 void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,
55 TypeLoc TL, SourceLocation ColonColonLoc) {
56 Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);
57 if (Range.getBegin().isInvalid())
58 Range.setBegin(TL.getBeginLoc());
59 Range.setEnd(ColonColonLoc);
61 assert(Range == Builder.getSourceRange() &&
62 "NestedNameSpecifierLoc range computation incorrect");
65 void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
66 SourceLocation IdentifierLoc,
67 SourceLocation ColonColonLoc) {
68 Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
70 if (Range.getBegin().isInvalid())
71 Range.setBegin(IdentifierLoc);
72 Range.setEnd(ColonColonLoc);
74 assert(Range == Builder.getSourceRange() &&
75 "NestedNameSpecifierLoc range computation incorrect");
78 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
79 SourceLocation NamespaceLoc,
80 SourceLocation ColonColonLoc) {
81 Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
83 if (Range.getBegin().isInvalid())
84 Range.setBegin(NamespaceLoc);
85 Range.setEnd(ColonColonLoc);
87 assert(Range == Builder.getSourceRange() &&
88 "NestedNameSpecifierLoc range computation incorrect");
91 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
92 SourceLocation AliasLoc,
93 SourceLocation ColonColonLoc) {
94 Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
96 if (Range.getBegin().isInvalid())
97 Range.setBegin(AliasLoc);
98 Range.setEnd(ColonColonLoc);
100 assert(Range == Builder.getSourceRange() &&
101 "NestedNameSpecifierLoc range computation incorrect");
104 void CXXScopeSpec::MakeGlobal(ASTContext &Context,
105 SourceLocation ColonColonLoc) {
106 Builder.MakeGlobal(Context, ColonColonLoc);
108 Range = SourceRange(ColonColonLoc);
110 assert(Range == Builder.getSourceRange() &&
111 "NestedNameSpecifierLoc range computation incorrect");
114 void CXXScopeSpec::MakeTrivial(ASTContext &Context,
115 NestedNameSpecifier *Qualifier, SourceRange R) {
116 Builder.MakeTrivial(Context, Qualifier, R);
120 void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
122 Range = SourceRange();
127 Range = Other.getSourceRange();
128 Builder.Adopt(Other);
131 SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const {
132 if (!Builder.getRepresentation())
133 return SourceLocation();
134 return Builder.getTemporary().getLocalBeginLoc();
137 NestedNameSpecifierLoc
138 CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
139 if (!Builder.getRepresentation())
140 return NestedNameSpecifierLoc();
142 return Builder.getWithLocInContext(Context);
145 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
146 /// "TheDeclarator" is the declarator that this will be added to.
147 DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
149 SourceLocation LParenLoc,
152 SourceLocation EllipsisLoc,
153 SourceLocation RParenLoc,
155 bool RefQualifierIsLvalueRef,
156 SourceLocation RefQualifierLoc,
157 SourceLocation ConstQualifierLoc,
159 VolatileQualifierLoc,
160 SourceLocation MutableLoc,
161 ExceptionSpecificationType
163 SourceLocation ESpecLoc,
164 ParsedType *Exceptions,
165 SourceRange *ExceptionRanges,
166 unsigned NumExceptions,
168 SourceLocation LocalRangeBegin,
169 SourceLocation LocalRangeEnd,
170 Declarator &TheDeclarator,
171 TypeResult TrailingReturnType) {
174 I.Loc = LocalRangeBegin;
175 I.EndLoc = LocalRangeEnd;
177 I.Fun.hasPrototype = hasProto;
178 I.Fun.isVariadic = EllipsisLoc.isValid();
179 I.Fun.isAmbiguous = isAmbiguous;
180 I.Fun.LParenLoc = LParenLoc.getRawEncoding();
181 I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
182 I.Fun.RParenLoc = RParenLoc.getRawEncoding();
183 I.Fun.DeleteArgInfo = false;
184 I.Fun.TypeQuals = TypeQuals;
185 I.Fun.NumArgs = NumArgs;
187 I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
188 I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
189 I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding();
190 I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding();
191 I.Fun.MutableLoc = MutableLoc.getRawEncoding();
192 I.Fun.ExceptionSpecType = ESpecType;
193 I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding();
194 I.Fun.NumExceptions = 0;
195 I.Fun.Exceptions = 0;
196 I.Fun.NoexceptExpr = 0;
197 I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() ||
198 TrailingReturnType.isInvalid();
199 I.Fun.TrailingReturnType = TrailingReturnType.get();
201 // new[] an argument array if needed.
203 // If the 'InlineParams' in Declarator is unused and big enough, put our
204 // parameter list there (in an effort to avoid new/delete traffic). If it
205 // is already used (consider a function returning a function pointer) or too
206 // small (function taking too many arguments), go to the heap.
207 if (!TheDeclarator.InlineParamsUsed &&
208 NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
209 I.Fun.ArgInfo = TheDeclarator.InlineParams;
210 I.Fun.DeleteArgInfo = false;
211 TheDeclarator.InlineParamsUsed = true;
213 I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
214 I.Fun.DeleteArgInfo = true;
216 memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
219 // Check what exception specification information we should actually store.
221 default: break; // By default, save nothing.
223 // new[] an exception array if needed
225 I.Fun.NumExceptions = NumExceptions;
226 I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
227 for (unsigned i = 0; i != NumExceptions; ++i) {
228 I.Fun.Exceptions[i].Ty = Exceptions[i];
229 I.Fun.Exceptions[i].Range = ExceptionRanges[i];
234 case EST_ComputedNoexcept:
235 I.Fun.NoexceptExpr = NoexceptExpr;
241 bool Declarator::isDeclarationOfFunction() const {
242 for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
243 switch (DeclTypeInfo[i].Kind) {
244 case DeclaratorChunk::Function:
246 case DeclaratorChunk::Paren:
248 case DeclaratorChunk::Pointer:
249 case DeclaratorChunk::Reference:
250 case DeclaratorChunk::Array:
251 case DeclaratorChunk::BlockPointer:
252 case DeclaratorChunk::MemberPointer:
255 llvm_unreachable("Invalid type chunk");
258 switch (DS.getTypeSpecType()) {
279 case TST_unknown_anytype:
280 case TST_unspecified:
287 if (Expr *E = DS.getRepAsExpr())
288 return E->getType()->isFunctionType();
291 case TST_underlyingType:
293 case TST_typeofType: {
294 QualType QT = DS.getRepAsType().get();
298 if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
304 return QT->isFunctionType();
308 llvm_unreachable("Invalid TypeSpecType!");
311 /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
312 /// declaration specifier includes.
314 unsigned DeclSpec::getParsedSpecifiers() const {
316 if (StorageClassSpec != SCS_unspecified ||
317 SCS_thread_specified)
318 Res |= PQ_StorageClassSpecifier;
320 if (TypeQualifiers != TQ_unspecified)
321 Res |= PQ_TypeQualifier;
323 if (hasTypeSpecifier())
324 Res |= PQ_TypeSpecifier;
326 if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
327 Res |= PQ_FunctionSpecifier;
331 template <class T> static bool BadSpecifier(T TNew, T TPrev,
332 const char *&PrevSpec,
334 bool IsExtension = true) {
335 PrevSpec = DeclSpec::getSpecifierName(TPrev);
337 DiagID = diag::err_invalid_decl_spec_combination;
339 DiagID = IsExtension ? diag::ext_duplicate_declspec :
340 diag::warn_duplicate_declspec;
344 const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
346 case DeclSpec::SCS_unspecified: return "unspecified";
347 case DeclSpec::SCS_typedef: return "typedef";
348 case DeclSpec::SCS_extern: return "extern";
349 case DeclSpec::SCS_static: return "static";
350 case DeclSpec::SCS_auto: return "auto";
351 case DeclSpec::SCS_register: return "register";
352 case DeclSpec::SCS_private_extern: return "__private_extern__";
353 case DeclSpec::SCS_mutable: return "mutable";
355 llvm_unreachable("Unknown typespec!");
358 const char *DeclSpec::getSpecifierName(TSW W) {
360 case TSW_unspecified: return "unspecified";
361 case TSW_short: return "short";
362 case TSW_long: return "long";
363 case TSW_longlong: return "long long";
365 llvm_unreachable("Unknown typespec!");
368 const char *DeclSpec::getSpecifierName(TSC C) {
370 case TSC_unspecified: return "unspecified";
371 case TSC_imaginary: return "imaginary";
372 case TSC_complex: return "complex";
374 llvm_unreachable("Unknown typespec!");
378 const char *DeclSpec::getSpecifierName(TSS S) {
380 case TSS_unspecified: return "unspecified";
381 case TSS_signed: return "signed";
382 case TSS_unsigned: return "unsigned";
384 llvm_unreachable("Unknown typespec!");
387 const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
389 case DeclSpec::TST_unspecified: return "unspecified";
390 case DeclSpec::TST_void: return "void";
391 case DeclSpec::TST_char: return "char";
392 case DeclSpec::TST_wchar: return "wchar_t";
393 case DeclSpec::TST_char16: return "char16_t";
394 case DeclSpec::TST_char32: return "char32_t";
395 case DeclSpec::TST_int: return "int";
396 case DeclSpec::TST_int128: return "__int128";
397 case DeclSpec::TST_half: return "half";
398 case DeclSpec::TST_float: return "float";
399 case DeclSpec::TST_double: return "double";
400 case DeclSpec::TST_bool: return "_Bool";
401 case DeclSpec::TST_decimal32: return "_Decimal32";
402 case DeclSpec::TST_decimal64: return "_Decimal64";
403 case DeclSpec::TST_decimal128: return "_Decimal128";
404 case DeclSpec::TST_enum: return "enum";
405 case DeclSpec::TST_class: return "class";
406 case DeclSpec::TST_union: return "union";
407 case DeclSpec::TST_struct: return "struct";
408 case DeclSpec::TST_interface: return "__interface";
409 case DeclSpec::TST_typename: return "type-name";
410 case DeclSpec::TST_typeofType:
411 case DeclSpec::TST_typeofExpr: return "typeof";
412 case DeclSpec::TST_auto: return "auto";
413 case DeclSpec::TST_decltype: return "(decltype)";
414 case DeclSpec::TST_underlyingType: return "__underlying_type";
415 case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
416 case DeclSpec::TST_atomic: return "_Atomic";
417 case DeclSpec::TST_error: return "(error)";
419 llvm_unreachable("Unknown typespec!");
422 const char *DeclSpec::getSpecifierName(TQ T) {
424 case DeclSpec::TQ_unspecified: return "unspecified";
425 case DeclSpec::TQ_const: return "const";
426 case DeclSpec::TQ_restrict: return "restrict";
427 case DeclSpec::TQ_volatile: return "volatile";
429 llvm_unreachable("Unknown typespec!");
432 bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
433 const char *&PrevSpec,
435 // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
436 // specifiers are not supported.
437 // It seems sensible to prohibit private_extern too
438 // The cl_clang_storage_class_specifiers extension enables support for
439 // these storage-class specifiers.
440 // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
441 // specifiers are not supported."
442 if (S.getLangOpts().OpenCL &&
443 !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
446 case SCS_private_extern:
448 if (S.getLangOpts().OpenCLVersion < 120) {
449 DiagID = diag::err_not_opencl_storage_class_specifier;
450 PrevSpec = getSpecifierName(SC);
456 DiagID = diag::err_not_opencl_storage_class_specifier;
457 PrevSpec = getSpecifierName(SC);
464 if (StorageClassSpec != SCS_unspecified) {
465 // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
466 bool isInvalid = true;
467 if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
469 return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
470 if (StorageClassSpec == SCS_auto) {
471 isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
473 assert(!isInvalid && "auto SCS -> TST recovery failed");
477 // Changing storage class is allowed only if the previous one
478 // was the 'extern' that is part of a linkage specification and
479 // the new storage class is 'typedef'.
481 !(SCS_extern_in_linkage_spec &&
482 StorageClassSpec == SCS_extern &&
484 return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
486 StorageClassSpec = SC;
487 StorageClassSpecLoc = Loc;
488 assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
492 bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
493 const char *&PrevSpec,
495 if (SCS_thread_specified) {
496 PrevSpec = "__thread";
497 DiagID = diag::ext_duplicate_declspec;
500 SCS_thread_specified = true;
505 /// These methods set the specified attribute of the DeclSpec, but return true
506 /// and ignore the request if invalid (e.g. "extern" then "auto" is
508 bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
509 const char *&PrevSpec,
511 // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
512 // for 'long long' we will keep the source location of the first 'long'.
513 if (TypeSpecWidth == TSW_unspecified)
515 // Allow turning long -> long long.
516 else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
517 return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
519 if (TypeAltiVecVector && !TypeAltiVecBool &&
520 ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
521 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
522 DiagID = diag::warn_vector_long_decl_spec_combination;
528 bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
529 const char *&PrevSpec,
531 if (TypeSpecComplex != TSC_unspecified)
532 return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
538 bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
539 const char *&PrevSpec,
541 if (TypeSpecSign != TSS_unspecified)
542 return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
548 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
549 const char *&PrevSpec,
552 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep);
555 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
556 SourceLocation TagNameLoc,
557 const char *&PrevSpec,
560 assert(isTypeRep(T) && "T does not store a type");
561 assert(Rep && "no type provided!");
562 if (TypeSpecType != TST_unspecified) {
563 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
564 DiagID = diag::err_invalid_decl_spec_combination;
570 TSTNameLoc = TagNameLoc;
571 TypeSpecOwned = false;
575 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
576 const char *&PrevSpec,
579 assert(isExprRep(T) && "T does not store an expr");
580 assert(Rep && "no expression provided!");
581 if (TypeSpecType != TST_unspecified) {
582 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
583 DiagID = diag::err_invalid_decl_spec_combination;
590 TypeSpecOwned = false;
594 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
595 const char *&PrevSpec,
597 Decl *Rep, bool Owned) {
598 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned);
601 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
602 SourceLocation TagNameLoc,
603 const char *&PrevSpec,
605 Decl *Rep, bool Owned) {
606 assert(isDeclRep(T) && "T does not store a decl");
607 // Unlike the other cases, we don't assert that we actually get a decl.
609 if (TypeSpecType != TST_unspecified) {
610 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
611 DiagID = diag::err_invalid_decl_spec_combination;
617 TSTNameLoc = TagNameLoc;
618 TypeSpecOwned = Owned;
622 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
623 const char *&PrevSpec,
625 assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
626 "rep required for these type-spec kinds!");
627 if (TypeSpecType != TST_unspecified) {
628 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
629 DiagID = diag::err_invalid_decl_spec_combination;
634 if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
635 TypeAltiVecBool = true;
639 TypeSpecOwned = false;
640 if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
641 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
642 DiagID = diag::err_invalid_vector_decl_spec;
648 bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
649 const char *&PrevSpec, unsigned &DiagID) {
650 if (TypeSpecType != TST_unspecified) {
651 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
652 DiagID = diag::err_invalid_vector_decl_spec_combination;
655 TypeAltiVecVector = isAltiVecVector;
660 bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
661 const char *&PrevSpec, unsigned &DiagID) {
662 if (!TypeAltiVecVector || TypeAltiVecPixel ||
663 (TypeSpecType != TST_unspecified)) {
664 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
665 DiagID = diag::err_invalid_pixel_decl_spec_combination;
668 TypeAltiVecPixel = isAltiVecPixel;
674 bool DeclSpec::SetTypeSpecError() {
675 TypeSpecType = TST_error;
676 TypeSpecOwned = false;
677 TSTLoc = SourceLocation();
678 TSTNameLoc = SourceLocation();
682 bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
683 unsigned &DiagID, const LangOptions &Lang) {
684 // Duplicates are permitted in C99, but are not permitted in C++. However,
685 // since this is likely not what the user intended, we will always warn. We
686 // do not need to set the qualifier's location since we already have it.
687 if (TypeQualifiers & T) {
688 bool IsExtension = true;
691 return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
696 default: llvm_unreachable("Unknown type qualifier!");
697 case TQ_const: TQ_constLoc = Loc; break;
698 case TQ_restrict: TQ_restrictLoc = Loc; break;
699 case TQ_volatile: TQ_volatileLoc = Loc; break;
704 bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
706 // 'inline inline' is ok.
707 FS_inline_specified = true;
712 bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
714 // 'virtual virtual' is ok.
715 FS_virtual_specified = true;
720 bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
722 // 'explicit explicit' is ok.
723 FS_explicit_specified = true;
724 FS_explicitLoc = Loc;
728 bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
730 if (Friend_specified) {
732 DiagID = diag::ext_duplicate_declspec;
736 Friend_specified = true;
741 bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
743 if (isModulePrivateSpecified()) {
744 PrevSpec = "__module_private__";
745 DiagID = diag::ext_duplicate_declspec;
749 ModulePrivateLoc = Loc;
753 bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
755 // 'constexpr constexpr' is ok.
756 Constexpr_specified = true;
761 void DeclSpec::setProtocolQualifiers(Decl * const *Protos,
763 SourceLocation *ProtoLocs,
764 SourceLocation LAngleLoc) {
766 ProtocolQualifiers = new Decl*[NP];
767 ProtocolLocs = new SourceLocation[NP];
768 memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP);
769 memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
770 NumProtocolQualifiers = NP;
771 ProtocolLAngleLoc = LAngleLoc;
774 void DeclSpec::SaveWrittenBuiltinSpecs() {
775 writtenBS.Sign = getTypeSpecSign();
776 writtenBS.Width = getTypeSpecWidth();
777 writtenBS.Type = getTypeSpecType();
778 // Search the list of attributes for the presence of a mode attribute.
779 writtenBS.ModeAttr = false;
780 AttributeList* attrs = getAttributes().getList();
782 if (attrs->getKind() == AttributeList::AT_Mode) {
783 writtenBS.ModeAttr = true;
786 attrs = attrs->getNext();
790 void DeclSpec::SaveStorageSpecifierAsWritten() {
791 if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern)
792 // If 'extern' is part of a linkage specification,
793 // then it is not a storage class "as written".
794 StorageClassSpecAsWritten = SCS_unspecified;
796 StorageClassSpecAsWritten = StorageClassSpec;
799 /// Finish - This does final analysis of the declspec, rejecting things like
800 /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
801 /// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
802 /// DeclSpec is guaranteed self-consistent, even if an error occurred.
803 void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
804 // Before possibly changing their values, save specs as written.
805 SaveWrittenBuiltinSpecs();
806 SaveStorageSpecifierAsWritten();
808 // Check the type specifier components first.
810 // Validate and finalize AltiVec vector declspec.
811 if (TypeAltiVecVector) {
812 if (TypeAltiVecBool) {
813 // Sign specifiers are not allowed with vector bool. (PIM 2.1)
814 if (TypeSpecSign != TSS_unspecified) {
815 Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
816 << getSpecifierName((TSS)TypeSpecSign);
819 // Only char/int are valid with vector bool. (PIM 2.1)
820 if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
821 (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
822 Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
823 << (TypeAltiVecPixel ? "__pixel" :
824 getSpecifierName((TST)TypeSpecType));
827 // Only 'short' is valid with vector bool. (PIM 2.1)
828 if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
829 Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
830 << getSpecifierName((TSW)TypeSpecWidth);
832 // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
833 if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
834 (TypeSpecWidth != TSW_unspecified))
835 TypeSpecSign = TSS_unsigned;
838 if (TypeAltiVecPixel) {
839 //TODO: perform validation
840 TypeSpecType = TST_int;
841 TypeSpecSign = TSS_unsigned;
842 TypeSpecWidth = TSW_short;
843 TypeSpecOwned = false;
847 // signed/unsigned are only valid with int/char/wchar_t.
848 if (TypeSpecSign != TSS_unspecified) {
849 if (TypeSpecType == TST_unspecified)
850 TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
851 else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&
852 TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
853 Diag(D, TSSLoc, diag::err_invalid_sign_spec)
854 << getSpecifierName((TST)TypeSpecType);
855 // signed double -> double.
856 TypeSpecSign = TSS_unspecified;
860 // Validate the width of the type.
861 switch (TypeSpecWidth) {
862 case TSW_unspecified: break;
863 case TSW_short: // short int
864 case TSW_longlong: // long long int
865 if (TypeSpecType == TST_unspecified)
866 TypeSpecType = TST_int; // short -> short int, long long -> long long int.
867 else if (TypeSpecType != TST_int) {
869 TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
870 : diag::err_invalid_longlong_spec)
871 << getSpecifierName((TST)TypeSpecType);
872 TypeSpecType = TST_int;
873 TypeSpecOwned = false;
876 case TSW_long: // long double, long int
877 if (TypeSpecType == TST_unspecified)
878 TypeSpecType = TST_int; // long -> long int.
879 else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
880 Diag(D, TSWLoc, diag::err_invalid_long_spec)
881 << getSpecifierName((TST)TypeSpecType);
882 TypeSpecType = TST_int;
883 TypeSpecOwned = false;
888 // TODO: if the implementation does not implement _Complex or _Imaginary,
889 // disallow their use. Need information about the backend.
890 if (TypeSpecComplex != TSC_unspecified) {
891 if (TypeSpecType == TST_unspecified) {
892 Diag(D, TSCLoc, diag::ext_plain_complex)
893 << FixItHint::CreateInsertion(
894 PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
896 TypeSpecType = TST_double; // _Complex -> _Complex double.
897 } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
898 // Note that this intentionally doesn't include _Complex _Bool.
899 if (!PP.getLangOpts().CPlusPlus)
900 Diag(D, TSTLoc, diag::ext_integer_complex);
901 } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
902 Diag(D, TSCLoc, diag::err_invalid_complex_spec)
903 << getSpecifierName((TST)TypeSpecType);
904 TypeSpecComplex = TSC_unspecified;
908 // If no type specifier was provided and we're parsing a language where
909 // the type specifier is not optional, but we got 'auto' as a storage
910 // class specifier, then assume this is an attempt to use C++0x's 'auto'
912 // FIXME: Does Microsoft really support implicit int in C++?
913 if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt &&
914 TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
915 TypeSpecType = TST_auto;
916 StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified;
917 TSTLoc = TSTNameLoc = StorageClassSpecLoc;
918 StorageClassSpecLoc = SourceLocation();
920 // Diagnose if we've recovered from an ill-formed 'auto' storage class
921 // specifier in a pre-C++0x dialect of C++.
922 if (!PP.getLangOpts().CPlusPlus0x && TypeSpecType == TST_auto)
923 Diag(D, TSTLoc, diag::ext_auto_type_specifier);
924 if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus0x &&
925 StorageClassSpec == SCS_auto)
926 Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
927 << FixItHint::CreateRemoval(StorageClassSpecLoc);
928 if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
929 Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
930 << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
931 if (Constexpr_specified)
932 Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
934 // C++ [class.friend]p6:
935 // No storage-class-specifier shall appear in the decl-specifier-seq
936 // of a friend declaration.
937 if (isFriendSpecified() && getStorageClassSpec()) {
938 DeclSpec::SCS SC = getStorageClassSpec();
939 const char *SpecName = getSpecifierName(SC);
941 SourceLocation SCLoc = getStorageClassSpecLoc();
942 SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName));
944 Diag(D, SCLoc, diag::err_friend_storage_spec)
946 << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
948 ClearStorageClassSpecs();
951 assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
953 // Okay, now we can infer the real type.
955 // TODO: return "auto function" and other bad things based on the real type.
957 // 'data definition has no type or storage class'?
960 bool DeclSpec::isMissingDeclaratorOk() {
961 TST tst = getTypeSpecType();
962 return isDeclRep(tst) && getRepAsDecl() != 0 &&
963 StorageClassSpec != DeclSpec::SCS_typedef;
966 void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
967 OverloadedOperatorKind Op,
968 SourceLocation SymbolLocations[3]) {
969 Kind = IK_OperatorFunctionId;
970 StartLocation = OperatorLoc;
971 EndLocation = OperatorLoc;
972 OperatorFunctionId.Operator = Op;
973 for (unsigned I = 0; I != 3; ++I) {
974 OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
976 if (SymbolLocations[I].isValid())
977 EndLocation = SymbolLocations[I];
981 bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
982 const char *&PrevSpec) {
985 if (Specifiers & VS) {
986 PrevSpec = getSpecifierName(VS);
993 default: llvm_unreachable("Unknown specifier!");
994 case VS_Override: VS_overrideLoc = Loc; break;
995 case VS_Final: VS_finalLoc = Loc; break;
1001 const char *VirtSpecifiers::getSpecifierName(Specifier VS) {
1003 default: llvm_unreachable("Unknown specifier");
1004 case VS_Override: return "override";
1005 case VS_Final: return "final";