1 //===--- DeclSpec.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/Sema/DeclSpec.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/AST/LocInfoType.h"
19 #include "clang/AST/TypeLoc.h"
20 #include "clang/Basic/LangOptions.h"
21 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Sema/ParsedTemplate.h"
23 #include "clang/Sema/Sema.h"
24 #include "clang/Sema/SemaDiagnostic.h"
25 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/ADT/SmallString.h"
28 using namespace clang;
31 void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
32 assert(TemplateId && "NULL template-id annotation?");
34 this->TemplateId = TemplateId;
35 StartLocation = TemplateId->TemplateNameLoc;
36 EndLocation = TemplateId->RAngleLoc;
39 void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
40 assert(TemplateId && "NULL template-id annotation?");
41 Kind = IK_ConstructorTemplateId;
42 this->TemplateId = TemplateId;
43 StartLocation = TemplateId->TemplateNameLoc;
44 EndLocation = TemplateId->RAngleLoc;
47 void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,
48 TypeLoc TL, SourceLocation ColonColonLoc) {
49 Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);
50 if (Range.getBegin().isInvalid())
51 Range.setBegin(TL.getBeginLoc());
52 Range.setEnd(ColonColonLoc);
54 assert(Range == Builder.getSourceRange() &&
55 "NestedNameSpecifierLoc range computation incorrect");
58 void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
59 SourceLocation IdentifierLoc,
60 SourceLocation ColonColonLoc) {
61 Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
63 if (Range.getBegin().isInvalid())
64 Range.setBegin(IdentifierLoc);
65 Range.setEnd(ColonColonLoc);
67 assert(Range == Builder.getSourceRange() &&
68 "NestedNameSpecifierLoc range computation incorrect");
71 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
72 SourceLocation NamespaceLoc,
73 SourceLocation ColonColonLoc) {
74 Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
76 if (Range.getBegin().isInvalid())
77 Range.setBegin(NamespaceLoc);
78 Range.setEnd(ColonColonLoc);
80 assert(Range == Builder.getSourceRange() &&
81 "NestedNameSpecifierLoc range computation incorrect");
84 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
85 SourceLocation AliasLoc,
86 SourceLocation ColonColonLoc) {
87 Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
89 if (Range.getBegin().isInvalid())
90 Range.setBegin(AliasLoc);
91 Range.setEnd(ColonColonLoc);
93 assert(Range == Builder.getSourceRange() &&
94 "NestedNameSpecifierLoc range computation incorrect");
97 void CXXScopeSpec::MakeGlobal(ASTContext &Context,
98 SourceLocation ColonColonLoc) {
99 Builder.MakeGlobal(Context, ColonColonLoc);
101 Range = SourceRange(ColonColonLoc);
103 assert(Range == Builder.getSourceRange() &&
104 "NestedNameSpecifierLoc range computation incorrect");
107 void CXXScopeSpec::MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
108 SourceLocation SuperLoc,
109 SourceLocation ColonColonLoc) {
110 Builder.MakeSuper(Context, RD, SuperLoc, ColonColonLoc);
112 Range.setBegin(SuperLoc);
113 Range.setEnd(ColonColonLoc);
115 assert(Range == Builder.getSourceRange() &&
116 "NestedNameSpecifierLoc range computation incorrect");
119 void CXXScopeSpec::MakeTrivial(ASTContext &Context,
120 NestedNameSpecifier *Qualifier, SourceRange R) {
121 Builder.MakeTrivial(Context, Qualifier, R);
125 void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
127 Range = SourceRange();
132 Range = Other.getSourceRange();
133 Builder.Adopt(Other);
136 SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const {
137 if (!Builder.getRepresentation())
138 return SourceLocation();
139 return Builder.getTemporary().getLocalBeginLoc();
142 NestedNameSpecifierLoc
143 CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
144 if (!Builder.getRepresentation())
145 return NestedNameSpecifierLoc();
147 return Builder.getWithLocInContext(Context);
150 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
151 /// "TheDeclarator" is the declarator that this will be added to.
152 DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
154 SourceLocation LParenLoc,
157 SourceLocation EllipsisLoc,
158 SourceLocation RParenLoc,
160 bool RefQualifierIsLvalueRef,
161 SourceLocation RefQualifierLoc,
162 SourceLocation ConstQualifierLoc,
164 VolatileQualifierLoc,
166 RestrictQualifierLoc,
167 SourceLocation MutableLoc,
168 ExceptionSpecificationType
170 SourceRange ESpecRange,
171 ParsedType *Exceptions,
172 SourceRange *ExceptionRanges,
173 unsigned NumExceptions,
175 CachedTokens *ExceptionSpecTokens,
178 SourceLocation LocalRangeBegin,
179 SourceLocation LocalRangeEnd,
180 Declarator &TheDeclarator,
181 TypeResult TrailingReturnType) {
182 assert(!(TypeQuals & DeclSpec::TQ_atomic) &&
183 "function cannot have _Atomic qualifier");
187 I.Loc = LocalRangeBegin;
188 I.EndLoc = LocalRangeEnd;
189 I.Fun.AttrList = nullptr;
190 I.Fun.hasPrototype = hasProto;
191 I.Fun.isVariadic = EllipsisLoc.isValid();
192 I.Fun.isAmbiguous = isAmbiguous;
193 I.Fun.LParenLoc = LParenLoc.getRawEncoding();
194 I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
195 I.Fun.RParenLoc = RParenLoc.getRawEncoding();
196 I.Fun.DeleteParams = false;
197 I.Fun.TypeQuals = TypeQuals;
198 I.Fun.NumParams = NumParams;
199 I.Fun.Params = nullptr;
200 I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
201 I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
202 I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding();
203 I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding();
204 I.Fun.RestrictQualifierLoc = RestrictQualifierLoc.getRawEncoding();
205 I.Fun.MutableLoc = MutableLoc.getRawEncoding();
206 I.Fun.ExceptionSpecType = ESpecType;
207 I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin().getRawEncoding();
208 I.Fun.ExceptionSpecLocEnd = ESpecRange.getEnd().getRawEncoding();
209 I.Fun.NumExceptionsOrDecls = 0;
210 I.Fun.Exceptions = nullptr;
211 I.Fun.NoexceptExpr = nullptr;
212 I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() ||
213 TrailingReturnType.isInvalid();
214 I.Fun.TrailingReturnType = TrailingReturnType.get();
216 assert(I.Fun.TypeQuals == TypeQuals && "bitfield overflow");
217 assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow");
219 // new[] a parameter array if needed.
221 // If the 'InlineParams' in Declarator is unused and big enough, put our
222 // parameter list there (in an effort to avoid new/delete traffic). If it
223 // is already used (consider a function returning a function pointer) or too
224 // small (function with too many parameters), go to the heap.
225 if (!TheDeclarator.InlineStorageUsed &&
226 NumParams <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
227 I.Fun.Params = TheDeclarator.InlineParams;
228 new (I.Fun.Params) ParamInfo[NumParams];
229 I.Fun.DeleteParams = false;
230 TheDeclarator.InlineStorageUsed = true;
232 I.Fun.Params = new DeclaratorChunk::ParamInfo[NumParams];
233 I.Fun.DeleteParams = true;
235 for (unsigned i = 0; i < NumParams; i++)
236 I.Fun.Params[i] = std::move(Params[i]);
239 // Check what exception specification information we should actually store.
241 default: break; // By default, save nothing.
243 // new[] an exception array if needed
245 I.Fun.NumExceptionsOrDecls = NumExceptions;
246 I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
247 for (unsigned i = 0; i != NumExceptions; ++i) {
248 I.Fun.Exceptions[i].Ty = Exceptions[i];
249 I.Fun.Exceptions[i].Range = ExceptionRanges[i];
254 case EST_ComputedNoexcept:
255 I.Fun.NoexceptExpr = NoexceptExpr;
259 I.Fun.ExceptionSpecTokens = ExceptionSpecTokens;
263 if (!DeclsInPrototype.empty()) {
264 assert(ESpecType == EST_None && NumExceptions == 0 &&
265 "cannot have exception specifiers and decls in prototype");
266 I.Fun.NumExceptionsOrDecls = DeclsInPrototype.size();
267 // Copy the array of decls into stable heap storage.
268 I.Fun.DeclsInPrototype = new NamedDecl *[DeclsInPrototype.size()];
269 for (size_t J = 0; J < DeclsInPrototype.size(); ++J)
270 I.Fun.DeclsInPrototype[J] = DeclsInPrototype[J];
276 void Declarator::setDecompositionBindings(
277 SourceLocation LSquareLoc,
278 ArrayRef<DecompositionDeclarator::Binding> Bindings,
279 SourceLocation RSquareLoc) {
280 assert(!hasName() && "declarator given multiple names!");
282 BindingGroup.LSquareLoc = LSquareLoc;
283 BindingGroup.RSquareLoc = RSquareLoc;
284 BindingGroup.NumBindings = Bindings.size();
285 Range.setEnd(RSquareLoc);
287 // We're now past the identifier.
288 SetIdentifier(nullptr, LSquareLoc);
289 Name.EndLocation = RSquareLoc;
291 // Allocate storage for bindings and stash them away.
292 if (Bindings.size()) {
293 if (!InlineStorageUsed &&
294 Bindings.size() <= llvm::array_lengthof(InlineBindings)) {
295 BindingGroup.Bindings = InlineBindings;
296 BindingGroup.DeleteBindings = false;
297 InlineStorageUsed = true;
299 BindingGroup.Bindings =
300 new DecompositionDeclarator::Binding[Bindings.size()];
301 BindingGroup.DeleteBindings = true;
303 std::uninitialized_copy(Bindings.begin(), Bindings.end(),
304 BindingGroup.Bindings);
308 bool Declarator::isDeclarationOfFunction() const {
309 for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
310 switch (DeclTypeInfo[i].Kind) {
311 case DeclaratorChunk::Function:
313 case DeclaratorChunk::Paren:
315 case DeclaratorChunk::Pointer:
316 case DeclaratorChunk::Reference:
317 case DeclaratorChunk::Array:
318 case DeclaratorChunk::BlockPointer:
319 case DeclaratorChunk::MemberPointer:
320 case DeclaratorChunk::Pipe:
323 llvm_unreachable("Invalid type chunk");
326 switch (DS.getTypeSpecType()) {
350 case TST_unknown_anytype:
351 case TST_unspecified:
354 #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:
355 #include "clang/Basic/OpenCLImageTypes.def"
358 case TST_decltype_auto:
359 // This must have an initializer, so can't be a function declaration,
360 // even if the initializer has function type.
365 if (Expr *E = DS.getRepAsExpr())
366 return E->getType()->isFunctionType();
369 case TST_underlyingType:
371 case TST_typeofType: {
372 QualType QT = DS.getRepAsType().get();
376 if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
382 return QT->isFunctionType();
386 llvm_unreachable("Invalid TypeSpecType!");
389 bool Declarator::isStaticMember() {
390 assert(getContext() == MemberContext);
391 return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
392 (getName().Kind == UnqualifiedId::IK_OperatorFunctionId &&
393 CXXMethodDecl::isStaticOverloadedOperator(
394 getName().OperatorFunctionId.Operator));
397 bool Declarator::isCtorOrDtor() {
398 return (getName().getKind() == UnqualifiedId::IK_ConstructorName) ||
399 (getName().getKind() == UnqualifiedId::IK_DestructorName);
402 bool DeclSpec::hasTagDefinition() const {
405 return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition();
408 /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
409 /// declaration specifier includes.
411 unsigned DeclSpec::getParsedSpecifiers() const {
413 if (StorageClassSpec != SCS_unspecified ||
414 ThreadStorageClassSpec != TSCS_unspecified)
415 Res |= PQ_StorageClassSpecifier;
417 if (TypeQualifiers != TQ_unspecified)
418 Res |= PQ_TypeQualifier;
420 if (hasTypeSpecifier())
421 Res |= PQ_TypeSpecifier;
423 if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified ||
424 FS_noreturn_specified || FS_forceinline_specified)
425 Res |= PQ_FunctionSpecifier;
429 template <class T> static bool BadSpecifier(T TNew, T TPrev,
430 const char *&PrevSpec,
432 bool IsExtension = true) {
433 PrevSpec = DeclSpec::getSpecifierName(TPrev);
435 DiagID = diag::err_invalid_decl_spec_combination;
437 DiagID = IsExtension ? diag::ext_duplicate_declspec :
438 diag::warn_duplicate_declspec;
442 const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
444 case DeclSpec::SCS_unspecified: return "unspecified";
445 case DeclSpec::SCS_typedef: return "typedef";
446 case DeclSpec::SCS_extern: return "extern";
447 case DeclSpec::SCS_static: return "static";
448 case DeclSpec::SCS_auto: return "auto";
449 case DeclSpec::SCS_register: return "register";
450 case DeclSpec::SCS_private_extern: return "__private_extern__";
451 case DeclSpec::SCS_mutable: return "mutable";
453 llvm_unreachable("Unknown typespec!");
456 const char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) {
458 case DeclSpec::TSCS_unspecified: return "unspecified";
459 case DeclSpec::TSCS___thread: return "__thread";
460 case DeclSpec::TSCS_thread_local: return "thread_local";
461 case DeclSpec::TSCS__Thread_local: return "_Thread_local";
463 llvm_unreachable("Unknown typespec!");
466 const char *DeclSpec::getSpecifierName(TSW W) {
468 case TSW_unspecified: return "unspecified";
469 case TSW_short: return "short";
470 case TSW_long: return "long";
471 case TSW_longlong: return "long long";
473 llvm_unreachable("Unknown typespec!");
476 const char *DeclSpec::getSpecifierName(TSC C) {
478 case TSC_unspecified: return "unspecified";
479 case TSC_imaginary: return "imaginary";
480 case TSC_complex: return "complex";
482 llvm_unreachable("Unknown typespec!");
486 const char *DeclSpec::getSpecifierName(TSS S) {
488 case TSS_unspecified: return "unspecified";
489 case TSS_signed: return "signed";
490 case TSS_unsigned: return "unsigned";
492 llvm_unreachable("Unknown typespec!");
495 const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
496 const PrintingPolicy &Policy) {
498 case DeclSpec::TST_unspecified: return "unspecified";
499 case DeclSpec::TST_void: return "void";
500 case DeclSpec::TST_char: return "char";
501 case DeclSpec::TST_wchar: return Policy.MSWChar ? "__wchar_t" : "wchar_t";
502 case DeclSpec::TST_char16: return "char16_t";
503 case DeclSpec::TST_char32: return "char32_t";
504 case DeclSpec::TST_int: return "int";
505 case DeclSpec::TST_int128: return "__int128";
506 case DeclSpec::TST_half: return "half";
507 case DeclSpec::TST_float: return "float";
508 case DeclSpec::TST_double: return "double";
509 case DeclSpec::TST_float16: return "_Float16";
510 case DeclSpec::TST_float128: return "__float128";
511 case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
512 case DeclSpec::TST_decimal32: return "_Decimal32";
513 case DeclSpec::TST_decimal64: return "_Decimal64";
514 case DeclSpec::TST_decimal128: return "_Decimal128";
515 case DeclSpec::TST_enum: return "enum";
516 case DeclSpec::TST_class: return "class";
517 case DeclSpec::TST_union: return "union";
518 case DeclSpec::TST_struct: return "struct";
519 case DeclSpec::TST_interface: return "__interface";
520 case DeclSpec::TST_typename: return "type-name";
521 case DeclSpec::TST_typeofType:
522 case DeclSpec::TST_typeofExpr: return "typeof";
523 case DeclSpec::TST_auto: return "auto";
524 case DeclSpec::TST_auto_type: return "__auto_type";
525 case DeclSpec::TST_decltype: return "(decltype)";
526 case DeclSpec::TST_decltype_auto: return "decltype(auto)";
527 case DeclSpec::TST_underlyingType: return "__underlying_type";
528 case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
529 case DeclSpec::TST_atomic: return "_Atomic";
530 #define GENERIC_IMAGE_TYPE(ImgType, Id) \
531 case DeclSpec::TST_##ImgType##_t: \
532 return #ImgType "_t";
533 #include "clang/Basic/OpenCLImageTypes.def"
534 case DeclSpec::TST_error: return "(error)";
536 llvm_unreachable("Unknown typespec!");
539 const char *DeclSpec::getSpecifierName(TQ T) {
541 case DeclSpec::TQ_unspecified: return "unspecified";
542 case DeclSpec::TQ_const: return "const";
543 case DeclSpec::TQ_restrict: return "restrict";
544 case DeclSpec::TQ_volatile: return "volatile";
545 case DeclSpec::TQ_atomic: return "_Atomic";
546 case DeclSpec::TQ_unaligned: return "__unaligned";
548 llvm_unreachable("Unknown typespec!");
551 bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
552 const char *&PrevSpec,
554 const PrintingPolicy &Policy) {
555 // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
556 // specifiers are not supported.
557 // It seems sensible to prohibit private_extern too
558 // The cl_clang_storage_class_specifiers extension enables support for
559 // these storage-class specifiers.
560 // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
561 // specifiers are not supported."
562 if (S.getLangOpts().OpenCL &&
563 !S.getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers")) {
566 case SCS_private_extern:
568 if (S.getLangOpts().OpenCLVersion < 120) {
569 DiagID = diag::err_opencl_unknown_type_specifier;
570 PrevSpec = getSpecifierName(SC);
576 DiagID = diag::err_opencl_unknown_type_specifier;
577 PrevSpec = getSpecifierName(SC);
584 if (StorageClassSpec != SCS_unspecified) {
585 // Maybe this is an attempt to use C++11 'auto' outside of C++11 mode.
586 bool isInvalid = true;
587 if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
589 return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID, Policy);
590 if (StorageClassSpec == SCS_auto) {
591 isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
592 PrevSpec, DiagID, Policy);
593 assert(!isInvalid && "auto SCS -> TST recovery failed");
597 // Changing storage class is allowed only if the previous one
598 // was the 'extern' that is part of a linkage specification and
599 // the new storage class is 'typedef'.
601 !(SCS_extern_in_linkage_spec &&
602 StorageClassSpec == SCS_extern &&
604 return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
606 StorageClassSpec = SC;
607 StorageClassSpecLoc = Loc;
608 assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
612 bool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,
613 const char *&PrevSpec,
615 if (ThreadStorageClassSpec != TSCS_unspecified)
616 return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID);
618 ThreadStorageClassSpec = TSC;
619 ThreadStorageClassSpecLoc = Loc;
623 /// These methods set the specified attribute of the DeclSpec, but return true
624 /// and ignore the request if invalid (e.g. "extern" then "auto" is
626 bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
627 const char *&PrevSpec,
629 const PrintingPolicy &Policy) {
630 // Overwrite TSWRange.Begin only if TypeSpecWidth was unspecified, so that
631 // for 'long long' we will keep the source location of the first 'long'.
632 if (TypeSpecWidth == TSW_unspecified)
633 TSWRange.setBegin(Loc);
634 // Allow turning long -> long long.
635 else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
636 return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
638 // Remember location of the last 'long'
639 TSWRange.setEnd(Loc);
643 bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
644 const char *&PrevSpec,
646 if (TypeSpecComplex != TSC_unspecified)
647 return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
653 bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
654 const char *&PrevSpec,
656 if (TypeSpecSign != TSS_unspecified)
657 return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
663 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
664 const char *&PrevSpec,
667 const PrintingPolicy &Policy) {
668 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Policy);
671 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
672 SourceLocation TagNameLoc,
673 const char *&PrevSpec,
676 const PrintingPolicy &Policy) {
677 assert(isTypeRep(T) && "T does not store a type");
678 assert(Rep && "no type provided!");
679 if (TypeSpecType != TST_unspecified) {
680 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
681 DiagID = diag::err_invalid_decl_spec_combination;
687 TSTNameLoc = TagNameLoc;
688 TypeSpecOwned = false;
692 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
693 const char *&PrevSpec,
696 const PrintingPolicy &Policy) {
697 assert(isExprRep(T) && "T does not store an expr");
698 assert(Rep && "no expression provided!");
699 if (TypeSpecType != TST_unspecified) {
700 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
701 DiagID = diag::err_invalid_decl_spec_combination;
708 TypeSpecOwned = false;
712 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
713 const char *&PrevSpec,
715 Decl *Rep, bool Owned,
716 const PrintingPolicy &Policy) {
717 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned, Policy);
720 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
721 SourceLocation TagNameLoc,
722 const char *&PrevSpec,
724 Decl *Rep, bool Owned,
725 const PrintingPolicy &Policy) {
726 assert(isDeclRep(T) && "T does not store a decl");
727 // Unlike the other cases, we don't assert that we actually get a decl.
729 if (TypeSpecType != TST_unspecified) {
730 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
731 DiagID = diag::err_invalid_decl_spec_combination;
737 TSTNameLoc = TagNameLoc;
738 TypeSpecOwned = Owned && Rep != nullptr;
742 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
743 const char *&PrevSpec,
745 const PrintingPolicy &Policy) {
746 assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
747 "rep required for these type-spec kinds!");
748 if (TypeSpecType != TST_unspecified) {
749 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
750 DiagID = diag::err_invalid_decl_spec_combination;
755 if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
756 TypeAltiVecBool = true;
760 TypeSpecOwned = false;
764 bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
765 const char *&PrevSpec, unsigned &DiagID,
766 const PrintingPolicy &Policy) {
767 if (TypeSpecType != TST_unspecified) {
768 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
769 DiagID = diag::err_invalid_vector_decl_spec_combination;
772 TypeAltiVecVector = isAltiVecVector;
777 bool DeclSpec::SetTypePipe(bool isPipe, SourceLocation Loc,
778 const char *&PrevSpec, unsigned &DiagID,
779 const PrintingPolicy &Policy) {
781 if (TypeSpecType != TST_unspecified) {
782 PrevSpec = DeclSpec::getSpecifierName((TST)TypeSpecType, Policy);
783 DiagID = diag::err_invalid_decl_spec_combination;
788 TypeSpecPipe = TSP_pipe;
793 bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
794 const char *&PrevSpec, unsigned &DiagID,
795 const PrintingPolicy &Policy) {
796 if (!TypeAltiVecVector || TypeAltiVecPixel ||
797 (TypeSpecType != TST_unspecified)) {
798 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
799 DiagID = diag::err_invalid_pixel_decl_spec_combination;
802 TypeAltiVecPixel = isAltiVecPixel;
808 bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
809 const char *&PrevSpec, unsigned &DiagID,
810 const PrintingPolicy &Policy) {
811 if (!TypeAltiVecVector || TypeAltiVecBool ||
812 (TypeSpecType != TST_unspecified)) {
813 PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
814 DiagID = diag::err_invalid_vector_bool_decl_spec;
817 TypeAltiVecBool = isAltiVecBool;
823 bool DeclSpec::SetTypeSpecError() {
824 TypeSpecType = TST_error;
825 TypeSpecOwned = false;
826 TSTLoc = SourceLocation();
827 TSTNameLoc = SourceLocation();
831 bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
832 unsigned &DiagID, const LangOptions &Lang) {
833 // Duplicates are permitted in C99 onwards, but are not permitted in C89 or
834 // C++. However, since this is likely not what the user intended, we will
835 // always warn. We do not need to set the qualifier's location since we
837 if (TypeQualifiers & T) {
838 bool IsExtension = true;
841 return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
846 case TQ_unspecified: break;
847 case TQ_const: TQ_constLoc = Loc; return false;
848 case TQ_restrict: TQ_restrictLoc = Loc; return false;
849 case TQ_volatile: TQ_volatileLoc = Loc; return false;
850 case TQ_unaligned: TQ_unalignedLoc = Loc; return false;
851 case TQ_atomic: TQ_atomicLoc = Loc; return false;
854 llvm_unreachable("Unknown type qualifier!");
857 bool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
859 // 'inline inline' is ok. However, since this is likely not what the user
860 // intended, we will always warn, similar to duplicates of type qualifiers.
861 if (FS_inline_specified) {
862 DiagID = diag::warn_duplicate_declspec;
866 FS_inline_specified = true;
871 bool DeclSpec::setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec,
873 if (FS_forceinline_specified) {
874 DiagID = diag::warn_duplicate_declspec;
875 PrevSpec = "__forceinline";
878 FS_forceinline_specified = true;
879 FS_forceinlineLoc = Loc;
883 bool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc,
884 const char *&PrevSpec,
886 // 'virtual virtual' is ok, but warn as this is likely not what the user
888 if (FS_virtual_specified) {
889 DiagID = diag::warn_duplicate_declspec;
890 PrevSpec = "virtual";
893 FS_virtual_specified = true;
898 bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc,
899 const char *&PrevSpec,
901 // 'explicit explicit' is ok, but warn as this is likely not what the user
903 if (FS_explicit_specified) {
904 DiagID = diag::warn_duplicate_declspec;
905 PrevSpec = "explicit";
908 FS_explicit_specified = true;
909 FS_explicitLoc = Loc;
913 bool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc,
914 const char *&PrevSpec,
916 // '_Noreturn _Noreturn' is ok, but warn as this is likely not what the user
918 if (FS_noreturn_specified) {
919 DiagID = diag::warn_duplicate_declspec;
920 PrevSpec = "_Noreturn";
923 FS_noreturn_specified = true;
924 FS_noreturnLoc = Loc;
928 bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
930 if (Friend_specified) {
932 // Keep the later location, so that we can later diagnose ill-formed
933 // declarations like 'friend class X friend;'. Per [class.friend]p3,
934 // 'friend' must be the first token in a friend declaration that is
935 // not a function declaration.
937 DiagID = diag::warn_duplicate_declspec;
941 Friend_specified = true;
946 bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
948 if (isModulePrivateSpecified()) {
949 PrevSpec = "__module_private__";
950 DiagID = diag::ext_duplicate_declspec;
954 ModulePrivateLoc = Loc;
958 bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
960 // 'constexpr constexpr' is ok, but warn as this is likely not what the user
962 if (Constexpr_specified) {
963 DiagID = diag::warn_duplicate_declspec;
964 PrevSpec = "constexpr";
967 Constexpr_specified = true;
972 void DeclSpec::SaveWrittenBuiltinSpecs() {
973 writtenBS.Sign = getTypeSpecSign();
974 writtenBS.Width = getTypeSpecWidth();
975 writtenBS.Type = getTypeSpecType();
976 // Search the list of attributes for the presence of a mode attribute.
977 writtenBS.ModeAttr = false;
978 AttributeList* attrs = getAttributes().getList();
980 if (attrs->getKind() == AttributeList::AT_Mode) {
981 writtenBS.ModeAttr = true;
984 attrs = attrs->getNext();
988 /// Finish - This does final analysis of the declspec, rejecting things like
989 /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
990 /// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
991 /// DeclSpec is guaranteed self-consistent, even if an error occurred.
992 void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
993 // Before possibly changing their values, save specs as written.
994 SaveWrittenBuiltinSpecs();
996 // Check the type specifier components first.
998 // If decltype(auto) is used, no other type specifiers are permitted.
999 if (TypeSpecType == TST_decltype_auto &&
1000 (TypeSpecWidth != TSW_unspecified ||
1001 TypeSpecComplex != TSC_unspecified ||
1002 TypeSpecSign != TSS_unspecified ||
1003 TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool ||
1005 const unsigned NumLocs = 9;
1006 SourceLocation ExtraLocs[NumLocs] = {
1007 TSWRange.getBegin(), TSCLoc, TSSLoc,
1008 AltiVecLoc, TQ_constLoc, TQ_restrictLoc,
1009 TQ_volatileLoc, TQ_atomicLoc, TQ_unalignedLoc};
1010 FixItHint Hints[NumLocs];
1011 SourceLocation FirstLoc;
1012 for (unsigned I = 0; I != NumLocs; ++I) {
1013 if (ExtraLocs[I].isValid()) {
1014 if (FirstLoc.isInvalid() ||
1015 S.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I],
1017 FirstLoc = ExtraLocs[I];
1018 Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]);
1021 TypeSpecWidth = TSW_unspecified;
1022 TypeSpecComplex = TSC_unspecified;
1023 TypeSpecSign = TSS_unspecified;
1024 TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false;
1026 S.Diag(TSTLoc, diag::err_decltype_auto_cannot_be_combined)
1027 << Hints[0] << Hints[1] << Hints[2] << Hints[3]
1028 << Hints[4] << Hints[5] << Hints[6] << Hints[7];
1031 // Validate and finalize AltiVec vector declspec.
1032 if (TypeAltiVecVector) {
1033 if (TypeAltiVecBool) {
1034 // Sign specifiers are not allowed with vector bool. (PIM 2.1)
1035 if (TypeSpecSign != TSS_unspecified) {
1036 S.Diag(TSSLoc, diag::err_invalid_vector_bool_decl_spec)
1037 << getSpecifierName((TSS)TypeSpecSign);
1040 // Only char/int are valid with vector bool. (PIM 2.1)
1041 if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
1042 (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
1043 S.Diag(TSTLoc, diag::err_invalid_vector_bool_decl_spec)
1044 << (TypeAltiVecPixel ? "__pixel" :
1045 getSpecifierName((TST)TypeSpecType, Policy));
1048 // Only 'short' and 'long long' are valid with vector bool. (PIM 2.1)
1049 if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short) &&
1050 (TypeSpecWidth != TSW_longlong))
1051 S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_bool_decl_spec)
1052 << getSpecifierName((TSW)TypeSpecWidth);
1054 // vector bool long long requires VSX support or ZVector.
1055 if ((TypeSpecWidth == TSW_longlong) &&
1056 (!S.Context.getTargetInfo().hasFeature("vsx")) &&
1057 (!S.Context.getTargetInfo().hasFeature("power8-vector")) &&
1058 !S.getLangOpts().ZVector)
1059 S.Diag(TSTLoc, diag::err_invalid_vector_long_long_decl_spec);
1061 // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
1062 if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
1063 (TypeSpecWidth != TSW_unspecified))
1064 TypeSpecSign = TSS_unsigned;
1065 } else if (TypeSpecType == TST_double) {
1066 // vector long double and vector long long double are never allowed.
1067 // vector double is OK for Power7 and later, and ZVector.
1068 if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong)
1069 S.Diag(TSWRange.getBegin(),
1070 diag::err_invalid_vector_long_double_decl_spec);
1071 else if (!S.Context.getTargetInfo().hasFeature("vsx") &&
1072 !S.getLangOpts().ZVector)
1073 S.Diag(TSTLoc, diag::err_invalid_vector_double_decl_spec);
1074 } else if (TypeSpecType == TST_float) {
1075 // vector float is unsupported for ZVector unless we have the
1076 // vector-enhancements facility 1 (ISA revision 12).
1077 if (S.getLangOpts().ZVector &&
1078 !S.Context.getTargetInfo().hasFeature("arch12"))
1079 S.Diag(TSTLoc, diag::err_invalid_vector_float_decl_spec);
1080 } else if (TypeSpecWidth == TSW_long) {
1081 // vector long is unsupported for ZVector and deprecated for AltiVec.
1082 if (S.getLangOpts().ZVector)
1083 S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_decl_spec);
1085 S.Diag(TSWRange.getBegin(),
1086 diag::warn_vector_long_decl_spec_combination)
1087 << getSpecifierName((TST)TypeSpecType, Policy);
1090 if (TypeAltiVecPixel) {
1091 //TODO: perform validation
1092 TypeSpecType = TST_int;
1093 TypeSpecSign = TSS_unsigned;
1094 TypeSpecWidth = TSW_short;
1095 TypeSpecOwned = false;
1099 // signed/unsigned are only valid with int/char/wchar_t.
1100 if (TypeSpecSign != TSS_unspecified) {
1101 if (TypeSpecType == TST_unspecified)
1102 TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
1103 else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&
1104 TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
1105 S.Diag(TSSLoc, diag::err_invalid_sign_spec)
1106 << getSpecifierName((TST)TypeSpecType, Policy);
1107 // signed double -> double.
1108 TypeSpecSign = TSS_unspecified;
1112 // Validate the width of the type.
1113 switch (TypeSpecWidth) {
1114 case TSW_unspecified: break;
1115 case TSW_short: // short int
1116 case TSW_longlong: // long long int
1117 if (TypeSpecType == TST_unspecified)
1118 TypeSpecType = TST_int; // short -> short int, long long -> long long int.
1119 else if (TypeSpecType != TST_int) {
1120 S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
1121 << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);
1122 TypeSpecType = TST_int;
1123 TypeSpecOwned = false;
1126 case TSW_long: // long double, long int
1127 if (TypeSpecType == TST_unspecified)
1128 TypeSpecType = TST_int; // long -> long int.
1129 else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
1130 S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
1131 << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);
1132 TypeSpecType = TST_int;
1133 TypeSpecOwned = false;
1138 // TODO: if the implementation does not implement _Complex or _Imaginary,
1139 // disallow their use. Need information about the backend.
1140 if (TypeSpecComplex != TSC_unspecified) {
1141 if (TypeSpecType == TST_unspecified) {
1142 S.Diag(TSCLoc, diag::ext_plain_complex)
1143 << FixItHint::CreateInsertion(
1144 S.getLocForEndOfToken(getTypeSpecComplexLoc()),
1146 TypeSpecType = TST_double; // _Complex -> _Complex double.
1147 } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
1148 // Note that this intentionally doesn't include _Complex _Bool.
1149 if (!S.getLangOpts().CPlusPlus)
1150 S.Diag(TSTLoc, diag::ext_integer_complex);
1151 } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
1152 S.Diag(TSCLoc, diag::err_invalid_complex_spec)
1153 << getSpecifierName((TST)TypeSpecType, Policy);
1154 TypeSpecComplex = TSC_unspecified;
1158 // C11 6.7.1/3, C++11 [dcl.stc]p1, GNU TLS: __thread, thread_local and
1159 // _Thread_local can only appear with the 'static' and 'extern' storage class
1160 // specifiers. We also allow __private_extern__ as an extension.
1161 if (ThreadStorageClassSpec != TSCS_unspecified) {
1162 switch (StorageClassSpec) {
1163 case SCS_unspecified:
1165 case SCS_private_extern:
1169 if (S.getSourceManager().isBeforeInTranslationUnit(
1170 getThreadStorageClassSpecLoc(), getStorageClassSpecLoc()))
1171 S.Diag(getStorageClassSpecLoc(),
1172 diag::err_invalid_decl_spec_combination)
1173 << DeclSpec::getSpecifierName(getThreadStorageClassSpec())
1174 << SourceRange(getThreadStorageClassSpecLoc());
1176 S.Diag(getThreadStorageClassSpecLoc(),
1177 diag::err_invalid_decl_spec_combination)
1178 << DeclSpec::getSpecifierName(getStorageClassSpec())
1179 << SourceRange(getStorageClassSpecLoc());
1180 // Discard the thread storage class specifier to recover.
1181 ThreadStorageClassSpec = TSCS_unspecified;
1182 ThreadStorageClassSpecLoc = SourceLocation();
1186 // If no type specifier was provided and we're parsing a language where
1187 // the type specifier is not optional, but we got 'auto' as a storage
1188 // class specifier, then assume this is an attempt to use C++0x's 'auto'
1190 if (S.getLangOpts().CPlusPlus &&
1191 TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
1192 TypeSpecType = TST_auto;
1193 StorageClassSpec = SCS_unspecified;
1194 TSTLoc = TSTNameLoc = StorageClassSpecLoc;
1195 StorageClassSpecLoc = SourceLocation();
1197 // Diagnose if we've recovered from an ill-formed 'auto' storage class
1198 // specifier in a pre-C++11 dialect of C++.
1199 if (!S.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto)
1200 S.Diag(TSTLoc, diag::ext_auto_type_specifier);
1201 if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11 &&
1202 StorageClassSpec == SCS_auto)
1203 S.Diag(StorageClassSpecLoc, diag::warn_auto_storage_class)
1204 << FixItHint::CreateRemoval(StorageClassSpecLoc);
1205 if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
1206 S.Diag(TSTLoc, diag::warn_cxx98_compat_unicode_type)
1207 << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
1208 if (Constexpr_specified)
1209 S.Diag(ConstexprLoc, diag::warn_cxx98_compat_constexpr);
1211 // C++ [class.friend]p6:
1212 // No storage-class-specifier shall appear in the decl-specifier-seq
1213 // of a friend declaration.
1214 if (isFriendSpecified() &&
1215 (getStorageClassSpec() || getThreadStorageClassSpec())) {
1216 SmallString<32> SpecName;
1217 SourceLocation SCLoc;
1218 FixItHint StorageHint, ThreadHint;
1220 if (DeclSpec::SCS SC = getStorageClassSpec()) {
1221 SpecName = getSpecifierName(SC);
1222 SCLoc = getStorageClassSpecLoc();
1223 StorageHint = FixItHint::CreateRemoval(SCLoc);
1226 if (DeclSpec::TSCS TSC = getThreadStorageClassSpec()) {
1227 if (!SpecName.empty()) SpecName += " ";
1228 SpecName += getSpecifierName(TSC);
1229 SCLoc = getThreadStorageClassSpecLoc();
1230 ThreadHint = FixItHint::CreateRemoval(SCLoc);
1233 S.Diag(SCLoc, diag::err_friend_decl_spec)
1234 << SpecName << StorageHint << ThreadHint;
1236 ClearStorageClassSpecs();
1239 // C++11 [dcl.fct.spec]p5:
1240 // The virtual specifier shall be used only in the initial
1241 // declaration of a non-static class member function;
1242 // C++11 [dcl.fct.spec]p6:
1243 // The explicit specifier shall be used only in the declaration of
1244 // a constructor or conversion function within its class
1246 if (isFriendSpecified() && (isVirtualSpecified() || isExplicitSpecified())) {
1248 SourceLocation SCLoc;
1250 if (isVirtualSpecified()) {
1251 Keyword = "virtual";
1252 SCLoc = getVirtualSpecLoc();
1254 Keyword = "explicit";
1255 SCLoc = getExplicitSpecLoc();
1258 FixItHint Hint = FixItHint::CreateRemoval(SCLoc);
1259 S.Diag(SCLoc, diag::err_friend_decl_spec)
1262 FS_virtual_specified = FS_explicit_specified = false;
1263 FS_virtualLoc = FS_explicitLoc = SourceLocation();
1266 assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
1268 // Okay, now we can infer the real type.
1270 // TODO: return "auto function" and other bad things based on the real type.
1272 // 'data definition has no type or storage class'?
1275 bool DeclSpec::isMissingDeclaratorOk() {
1276 TST tst = getTypeSpecType();
1277 return isDeclRep(tst) && getRepAsDecl() != nullptr &&
1278 StorageClassSpec != DeclSpec::SCS_typedef;
1281 void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
1282 OverloadedOperatorKind Op,
1283 SourceLocation SymbolLocations[3]) {
1284 Kind = IK_OperatorFunctionId;
1285 StartLocation = OperatorLoc;
1286 EndLocation = OperatorLoc;
1287 OperatorFunctionId.Operator = Op;
1288 for (unsigned I = 0; I != 3; ++I) {
1289 OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
1291 if (SymbolLocations[I].isValid())
1292 EndLocation = SymbolLocations[I];
1296 bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
1297 const char *&PrevSpec) {
1298 if (!FirstLocation.isValid())
1299 FirstLocation = Loc;
1303 if (Specifiers & VS) {
1304 PrevSpec = getSpecifierName(VS);
1311 default: llvm_unreachable("Unknown specifier!");
1312 case VS_Override: VS_overrideLoc = Loc; break;
1315 case VS_Final: VS_finalLoc = Loc; break;
1321 const char *VirtSpecifiers::getSpecifierName(Specifier VS) {
1323 default: llvm_unreachable("Unknown specifier");
1324 case VS_Override: return "override";
1325 case VS_Final: return "final";
1326 case VS_GNU_Final: return "__final";
1327 case VS_Sealed: return "sealed";