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/ParsedTemplate.h"
17 #include "clang/Lex/Preprocessor.h"
18 #include "clang/Basic/LangOptions.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/Support/ErrorHandling.h"
22 using namespace clang
;
25 static DiagnosticBuilder
Diag(Diagnostic
&D
, SourceLocation Loc
,
27 return D
.Report(Loc
, DiagID
);
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 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
48 /// "TheDeclarator" is the declarator that this will be added to.
49 DeclaratorChunk
DeclaratorChunk::getFunction(const ParsedAttributes
&attrs
,
50 bool hasProto
, bool isVariadic
,
51 SourceLocation EllipsisLoc
,
55 bool RefQualifierIsLvalueRef
,
56 SourceLocation RefQualifierLoc
,
57 bool hasExceptionSpec
,
58 SourceLocation ThrowLoc
,
59 bool hasAnyExceptionSpec
,
60 ParsedType
*Exceptions
,
61 SourceRange
*ExceptionRanges
,
62 unsigned NumExceptions
,
65 Declarator
&TheDeclarator
,
66 ParsedType TrailingReturnType
) {
71 I
.Fun
.AttrList
= attrs
.getList();
72 I
.Fun
.hasPrototype
= hasProto
;
73 I
.Fun
.isVariadic
= isVariadic
;
74 I
.Fun
.EllipsisLoc
= EllipsisLoc
.getRawEncoding();
75 I
.Fun
.DeleteArgInfo
= false;
76 I
.Fun
.TypeQuals
= TypeQuals
;
77 I
.Fun
.NumArgs
= NumArgs
;
79 I
.Fun
.RefQualifierIsLValueRef
= RefQualifierIsLvalueRef
;
80 I
.Fun
.RefQualifierLoc
= RefQualifierLoc
.getRawEncoding();
81 I
.Fun
.hasExceptionSpec
= hasExceptionSpec
;
82 I
.Fun
.ThrowLoc
= ThrowLoc
.getRawEncoding();
83 I
.Fun
.hasAnyExceptionSpec
= hasAnyExceptionSpec
;
84 I
.Fun
.NumExceptions
= NumExceptions
;
86 I
.Fun
.TrailingReturnType
= TrailingReturnType
.getAsOpaquePtr();
88 // new[] an argument array if needed.
90 // If the 'InlineParams' in Declarator is unused and big enough, put our
91 // parameter list there (in an effort to avoid new/delete traffic). If it
92 // is already used (consider a function returning a function pointer) or too
93 // small (function taking too many arguments), go to the heap.
94 if (!TheDeclarator
.InlineParamsUsed
&&
95 NumArgs
<= llvm::array_lengthof(TheDeclarator
.InlineParams
)) {
96 I
.Fun
.ArgInfo
= TheDeclarator
.InlineParams
;
97 I
.Fun
.DeleteArgInfo
= false;
98 TheDeclarator
.InlineParamsUsed
= true;
100 I
.Fun
.ArgInfo
= new DeclaratorChunk::ParamInfo
[NumArgs
];
101 I
.Fun
.DeleteArgInfo
= true;
103 memcpy(I
.Fun
.ArgInfo
, ArgInfo
, sizeof(ArgInfo
[0])*NumArgs
);
105 // new[] an exception array if needed
107 I
.Fun
.Exceptions
= new DeclaratorChunk::TypeAndRange
[NumExceptions
];
108 for (unsigned i
= 0; i
!= NumExceptions
; ++i
) {
109 I
.Fun
.Exceptions
[i
].Ty
= Exceptions
[i
];
110 I
.Fun
.Exceptions
[i
].Range
= ExceptionRanges
[i
];
116 /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
117 /// declaration specifier includes.
119 unsigned DeclSpec::getParsedSpecifiers() const {
121 if (StorageClassSpec
!= SCS_unspecified
||
122 SCS_thread_specified
)
123 Res
|= PQ_StorageClassSpecifier
;
125 if (TypeQualifiers
!= TQ_unspecified
)
126 Res
|= PQ_TypeQualifier
;
128 if (hasTypeSpecifier())
129 Res
|= PQ_TypeSpecifier
;
131 if (FS_inline_specified
|| FS_virtual_specified
|| FS_explicit_specified
)
132 Res
|= PQ_FunctionSpecifier
;
136 template <class T
> static bool BadSpecifier(T TNew
, T TPrev
,
137 const char *&PrevSpec
,
139 PrevSpec
= DeclSpec::getSpecifierName(TPrev
);
140 DiagID
= (TNew
== TPrev
? diag::ext_duplicate_declspec
141 : diag::err_invalid_decl_spec_combination
);
145 const char *DeclSpec::getSpecifierName(DeclSpec::SCS S
) {
147 case DeclSpec::SCS_unspecified
: return "unspecified";
148 case DeclSpec::SCS_typedef
: return "typedef";
149 case DeclSpec::SCS_extern
: return "extern";
150 case DeclSpec::SCS_static
: return "static";
151 case DeclSpec::SCS_auto
: return "auto";
152 case DeclSpec::SCS_register
: return "register";
153 case DeclSpec::SCS_private_extern
: return "__private_extern__";
154 case DeclSpec::SCS_mutable
: return "mutable";
156 llvm_unreachable("Unknown typespec!");
159 const char *DeclSpec::getSpecifierName(TSW W
) {
161 case TSW_unspecified
: return "unspecified";
162 case TSW_short
: return "short";
163 case TSW_long
: return "long";
164 case TSW_longlong
: return "long long";
166 llvm_unreachable("Unknown typespec!");
169 const char *DeclSpec::getSpecifierName(TSC C
) {
171 case TSC_unspecified
: return "unspecified";
172 case TSC_imaginary
: return "imaginary";
173 case TSC_complex
: return "complex";
175 llvm_unreachable("Unknown typespec!");
179 const char *DeclSpec::getSpecifierName(TSS S
) {
181 case TSS_unspecified
: return "unspecified";
182 case TSS_signed
: return "signed";
183 case TSS_unsigned
: return "unsigned";
185 llvm_unreachable("Unknown typespec!");
188 const char *DeclSpec::getSpecifierName(DeclSpec::TST T
) {
190 case DeclSpec::TST_unspecified
: return "unspecified";
191 case DeclSpec::TST_void
: return "void";
192 case DeclSpec::TST_char
: return "char";
193 case DeclSpec::TST_wchar
: return "wchar_t";
194 case DeclSpec::TST_char16
: return "char16_t";
195 case DeclSpec::TST_char32
: return "char32_t";
196 case DeclSpec::TST_int
: return "int";
197 case DeclSpec::TST_float
: return "float";
198 case DeclSpec::TST_double
: return "double";
199 case DeclSpec::TST_bool
: return "_Bool";
200 case DeclSpec::TST_decimal32
: return "_Decimal32";
201 case DeclSpec::TST_decimal64
: return "_Decimal64";
202 case DeclSpec::TST_decimal128
: return "_Decimal128";
203 case DeclSpec::TST_enum
: return "enum";
204 case DeclSpec::TST_class
: return "class";
205 case DeclSpec::TST_union
: return "union";
206 case DeclSpec::TST_struct
: return "struct";
207 case DeclSpec::TST_typename
: return "type-name";
208 case DeclSpec::TST_typeofType
:
209 case DeclSpec::TST_typeofExpr
: return "typeof";
210 case DeclSpec::TST_auto
: return "auto";
211 case DeclSpec::TST_decltype
: return "(decltype)";
212 case DeclSpec::TST_error
: return "(error)";
214 llvm_unreachable("Unknown typespec!");
217 const char *DeclSpec::getSpecifierName(TQ T
) {
219 case DeclSpec::TQ_unspecified
: return "unspecified";
220 case DeclSpec::TQ_const
: return "const";
221 case DeclSpec::TQ_restrict
: return "restrict";
222 case DeclSpec::TQ_volatile
: return "volatile";
224 llvm_unreachable("Unknown typespec!");
227 bool DeclSpec::SetStorageClassSpec(SCS S
, SourceLocation Loc
,
228 const char *&PrevSpec
,
230 const LangOptions
&Lang
) {
231 // OpenCL prohibits extern, auto, register, and static
232 // It seems sensible to prohibit private_extern too
236 case SCS_private_extern
:
240 DiagID
= diag::err_not_opencl_storage_class_specifier
;
241 PrevSpec
= getSpecifierName(S
);
248 if (StorageClassSpec
!= SCS_unspecified
) {
249 // Changing storage class is allowed only if the previous one
250 // was the 'extern' that is part of a linkage specification and
251 // the new storage class is 'typedef'.
252 if (!(SCS_extern_in_linkage_spec
&&
253 StorageClassSpec
== SCS_extern
&&
255 return BadSpecifier(S
, (SCS
)StorageClassSpec
, PrevSpec
, DiagID
);
257 StorageClassSpec
= S
;
258 StorageClassSpecLoc
= Loc
;
259 assert((unsigned)S
== StorageClassSpec
&& "SCS constants overflow bitfield");
263 bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc
,
264 const char *&PrevSpec
,
266 if (SCS_thread_specified
) {
267 PrevSpec
= "__thread";
268 DiagID
= diag::ext_duplicate_declspec
;
271 SCS_thread_specified
= true;
276 /// These methods set the specified attribute of the DeclSpec, but return true
277 /// and ignore the request if invalid (e.g. "extern" then "auto" is
279 bool DeclSpec::SetTypeSpecWidth(TSW W
, SourceLocation Loc
,
280 const char *&PrevSpec
,
282 if (TypeSpecWidth
!= TSW_unspecified
&&
283 // Allow turning long -> long long.
284 (W
!= TSW_longlong
|| TypeSpecWidth
!= TSW_long
))
285 return BadSpecifier(W
, (TSW
)TypeSpecWidth
, PrevSpec
, DiagID
);
288 if (TypeAltiVecVector
&& !TypeAltiVecBool
&&
289 ((TypeSpecWidth
== TSW_long
) || (TypeSpecWidth
== TSW_longlong
))) {
290 PrevSpec
= DeclSpec::getSpecifierName((TST
) TypeSpecType
);
291 DiagID
= diag::warn_vector_long_decl_spec_combination
;
297 bool DeclSpec::SetTypeSpecComplex(TSC C
, SourceLocation Loc
,
298 const char *&PrevSpec
,
300 if (TypeSpecComplex
!= TSC_unspecified
)
301 return BadSpecifier(C
, (TSC
)TypeSpecComplex
, PrevSpec
, DiagID
);
307 bool DeclSpec::SetTypeSpecSign(TSS S
, SourceLocation Loc
,
308 const char *&PrevSpec
,
310 if (TypeSpecSign
!= TSS_unspecified
)
311 return BadSpecifier(S
, (TSS
)TypeSpecSign
, PrevSpec
, DiagID
);
317 bool DeclSpec::SetTypeSpecType(TST T
, SourceLocation Loc
,
318 const char *&PrevSpec
,
321 assert(isTypeRep(T
) && "T does not store a type");
322 assert(Rep
&& "no type provided!");
323 if (TypeSpecType
!= TST_unspecified
) {
324 PrevSpec
= DeclSpec::getSpecifierName((TST
) TypeSpecType
);
325 DiagID
= diag::err_invalid_decl_spec_combination
;
331 TypeSpecOwned
= false;
335 bool DeclSpec::SetTypeSpecType(TST T
, SourceLocation Loc
,
336 const char *&PrevSpec
,
339 assert(isExprRep(T
) && "T does not store an expr");
340 assert(Rep
&& "no expression provided!");
341 if (TypeSpecType
!= TST_unspecified
) {
342 PrevSpec
= DeclSpec::getSpecifierName((TST
) TypeSpecType
);
343 DiagID
= diag::err_invalid_decl_spec_combination
;
349 TypeSpecOwned
= false;
353 bool DeclSpec::SetTypeSpecType(TST T
, SourceLocation Loc
,
354 const char *&PrevSpec
,
356 Decl
*Rep
, bool Owned
) {
357 assert(isDeclRep(T
) && "T does not store a decl");
358 // Unlike the other cases, we don't assert that we actually get a decl.
360 if (TypeSpecType
!= TST_unspecified
) {
361 PrevSpec
= DeclSpec::getSpecifierName((TST
) TypeSpecType
);
362 DiagID
= diag::err_invalid_decl_spec_combination
;
368 TypeSpecOwned
= Owned
;
372 bool DeclSpec::SetTypeSpecType(TST T
, SourceLocation Loc
,
373 const char *&PrevSpec
,
375 assert(!isDeclRep(T
) && !isTypeRep(T
) && !isExprRep(T
) &&
376 "rep required for these type-spec kinds!");
377 if (TypeSpecType
!= TST_unspecified
) {
378 PrevSpec
= DeclSpec::getSpecifierName((TST
) TypeSpecType
);
379 DiagID
= diag::err_invalid_decl_spec_combination
;
382 if (TypeAltiVecVector
&& (T
== TST_bool
) && !TypeAltiVecBool
) {
383 TypeAltiVecBool
= true;
389 TypeSpecOwned
= false;
390 if (TypeAltiVecVector
&& !TypeAltiVecBool
&& (TypeSpecType
== TST_double
)) {
391 PrevSpec
= DeclSpec::getSpecifierName((TST
) TypeSpecType
);
392 DiagID
= diag::err_invalid_vector_decl_spec
;
398 bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector
, SourceLocation Loc
,
399 const char *&PrevSpec
, unsigned &DiagID
) {
400 if (TypeSpecType
!= TST_unspecified
) {
401 PrevSpec
= DeclSpec::getSpecifierName((TST
) TypeSpecType
);
402 DiagID
= diag::err_invalid_vector_decl_spec_combination
;
405 TypeAltiVecVector
= isAltiVecVector
;
410 bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel
, SourceLocation Loc
,
411 const char *&PrevSpec
, unsigned &DiagID
) {
412 if (!TypeAltiVecVector
|| TypeAltiVecPixel
||
413 (TypeSpecType
!= TST_unspecified
)) {
414 PrevSpec
= DeclSpec::getSpecifierName((TST
) TypeSpecType
);
415 DiagID
= diag::err_invalid_pixel_decl_spec_combination
;
418 TypeAltiVecPixel
= isAltiVecPixel
;
423 bool DeclSpec::SetTypeSpecError() {
424 TypeSpecType
= TST_error
;
425 TypeSpecOwned
= false;
426 TSTLoc
= SourceLocation();
430 bool DeclSpec::SetTypeQual(TQ T
, SourceLocation Loc
, const char *&PrevSpec
,
431 unsigned &DiagID
, const LangOptions
&Lang
) {
432 // Duplicates turn into warnings pre-C99.
433 if ((TypeQualifiers
& T
) && !Lang
.C99
)
434 return BadSpecifier(T
, T
, PrevSpec
, DiagID
);
438 default: assert(0 && "Unknown type qualifier!");
439 case TQ_const
: TQ_constLoc
= Loc
; break;
440 case TQ_restrict
: TQ_restrictLoc
= Loc
; break;
441 case TQ_volatile
: TQ_volatileLoc
= Loc
; break;
446 bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc
, const char *&PrevSpec
,
448 // 'inline inline' is ok.
449 FS_inline_specified
= true;
454 bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc
, const char *&PrevSpec
,
456 // 'virtual virtual' is ok.
457 FS_virtual_specified
= true;
462 bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc
, const char *&PrevSpec
,
464 // 'explicit explicit' is ok.
465 FS_explicit_specified
= true;
466 FS_explicitLoc
= Loc
;
470 bool DeclSpec::SetFriendSpec(SourceLocation Loc
, const char *&PrevSpec
,
472 if (Friend_specified
) {
474 DiagID
= diag::ext_duplicate_declspec
;
478 Friend_specified
= true;
483 bool DeclSpec::SetConstexprSpec(SourceLocation Loc
, const char *&PrevSpec
,
485 // 'constexpr constexpr' is ok.
486 Constexpr_specified
= true;
491 void DeclSpec::setProtocolQualifiers(Decl
* const *Protos
,
493 SourceLocation
*ProtoLocs
,
494 SourceLocation LAngleLoc
) {
496 ProtocolQualifiers
= new Decl
*[NP
];
497 ProtocolLocs
= new SourceLocation
[NP
];
498 memcpy((void*)ProtocolQualifiers
, Protos
, sizeof(Decl
*)*NP
);
499 memcpy(ProtocolLocs
, ProtoLocs
, sizeof(SourceLocation
)*NP
);
500 NumProtocolQualifiers
= NP
;
501 ProtocolLAngleLoc
= LAngleLoc
;
504 void DeclSpec::SaveWrittenBuiltinSpecs() {
505 writtenBS
.Sign
= getTypeSpecSign();
506 writtenBS
.Width
= getTypeSpecWidth();
507 writtenBS
.Type
= getTypeSpecType();
508 // Search the list of attributes for the presence of a mode attribute.
509 writtenBS
.ModeAttr
= false;
510 AttributeList
* attrs
= getAttributes().getList();
512 if (attrs
->getKind() == AttributeList::AT_mode
) {
513 writtenBS
.ModeAttr
= true;
516 attrs
= attrs
->getNext();
520 void DeclSpec::SaveStorageSpecifierAsWritten() {
521 if (SCS_extern_in_linkage_spec
&& StorageClassSpec
== SCS_extern
)
522 // If 'extern' is part of a linkage specification,
523 // then it is not a storage class "as written".
524 StorageClassSpecAsWritten
= SCS_unspecified
;
526 StorageClassSpecAsWritten
= StorageClassSpec
;
529 /// Finish - This does final analysis of the declspec, rejecting things like
530 /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
531 /// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
532 /// DeclSpec is guaranteed self-consistent, even if an error occurred.
533 void DeclSpec::Finish(Diagnostic
&D
, Preprocessor
&PP
) {
534 // Before possibly changing their values, save specs as written.
535 SaveWrittenBuiltinSpecs();
536 SaveStorageSpecifierAsWritten();
538 // Check the type specifier components first.
540 // Validate and finalize AltiVec vector declspec.
541 if (TypeAltiVecVector
) {
542 if (TypeAltiVecBool
) {
543 // Sign specifiers are not allowed with vector bool. (PIM 2.1)
544 if (TypeSpecSign
!= TSS_unspecified
) {
545 Diag(D
, TSSLoc
, diag::err_invalid_vector_bool_decl_spec
)
546 << getSpecifierName((TSS
)TypeSpecSign
);
549 // Only char/int are valid with vector bool. (PIM 2.1)
550 if (((TypeSpecType
!= TST_unspecified
) && (TypeSpecType
!= TST_char
) &&
551 (TypeSpecType
!= TST_int
)) || TypeAltiVecPixel
) {
552 Diag(D
, TSTLoc
, diag::err_invalid_vector_bool_decl_spec
)
553 << (TypeAltiVecPixel
? "__pixel" :
554 getSpecifierName((TST
)TypeSpecType
));
557 // Only 'short' is valid with vector bool. (PIM 2.1)
558 if ((TypeSpecWidth
!= TSW_unspecified
) && (TypeSpecWidth
!= TSW_short
))
559 Diag(D
, TSWLoc
, diag::err_invalid_vector_bool_decl_spec
)
560 << getSpecifierName((TSW
)TypeSpecWidth
);
562 // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
563 if ((TypeSpecType
== TST_char
) || (TypeSpecType
== TST_int
) ||
564 (TypeSpecWidth
!= TSW_unspecified
))
565 TypeSpecSign
= TSS_unsigned
;
568 if (TypeAltiVecPixel
) {
569 //TODO: perform validation
570 TypeSpecType
= TST_int
;
571 TypeSpecSign
= TSS_unsigned
;
572 TypeSpecWidth
= TSW_short
;
573 TypeSpecOwned
= false;
577 // signed/unsigned are only valid with int/char/wchar_t.
578 if (TypeSpecSign
!= TSS_unspecified
) {
579 if (TypeSpecType
== TST_unspecified
)
580 TypeSpecType
= TST_int
; // unsigned -> unsigned int, signed -> signed int.
581 else if (TypeSpecType
!= TST_int
&&
582 TypeSpecType
!= TST_char
&& TypeSpecType
!= TST_wchar
) {
583 Diag(D
, TSSLoc
, diag::err_invalid_sign_spec
)
584 << getSpecifierName((TST
)TypeSpecType
);
585 // signed double -> double.
586 TypeSpecSign
= TSS_unspecified
;
590 // Validate the width of the type.
591 switch (TypeSpecWidth
) {
592 case TSW_unspecified
: break;
593 case TSW_short
: // short int
594 case TSW_longlong
: // long long int
595 if (TypeSpecType
== TST_unspecified
)
596 TypeSpecType
= TST_int
; // short -> short int, long long -> long long int.
597 else if (TypeSpecType
!= TST_int
) {
599 TypeSpecWidth
== TSW_short
? diag::err_invalid_short_spec
600 : diag::err_invalid_longlong_spec
)
601 << getSpecifierName((TST
)TypeSpecType
);
602 TypeSpecType
= TST_int
;
603 TypeSpecOwned
= false;
606 case TSW_long
: // long double, long int
607 if (TypeSpecType
== TST_unspecified
)
608 TypeSpecType
= TST_int
; // long -> long int.
609 else if (TypeSpecType
!= TST_int
&& TypeSpecType
!= TST_double
) {
610 Diag(D
, TSWLoc
, diag::err_invalid_long_spec
)
611 << getSpecifierName((TST
)TypeSpecType
);
612 TypeSpecType
= TST_int
;
613 TypeSpecOwned
= false;
618 // TODO: if the implementation does not implement _Complex or _Imaginary,
619 // disallow their use. Need information about the backend.
620 if (TypeSpecComplex
!= TSC_unspecified
) {
621 if (TypeSpecType
== TST_unspecified
) {
622 Diag(D
, TSCLoc
, diag::ext_plain_complex
)
623 << FixItHint::CreateInsertion(
624 PP
.getLocForEndOfToken(getTypeSpecComplexLoc()),
626 TypeSpecType
= TST_double
; // _Complex -> _Complex double.
627 } else if (TypeSpecType
== TST_int
|| TypeSpecType
== TST_char
) {
628 // Note that this intentionally doesn't include _Complex _Bool.
629 Diag(D
, TSTLoc
, diag::ext_integer_complex
);
630 } else if (TypeSpecType
!= TST_float
&& TypeSpecType
!= TST_double
) {
631 Diag(D
, TSCLoc
, diag::err_invalid_complex_spec
)
632 << getSpecifierName((TST
)TypeSpecType
);
633 TypeSpecComplex
= TSC_unspecified
;
637 // C++ [class.friend]p6:
638 // No storage-class-specifier shall appear in the decl-specifier-seq
639 // of a friend declaration.
640 if (isFriendSpecified() && getStorageClassSpec()) {
641 DeclSpec::SCS SC
= getStorageClassSpec();
642 const char *SpecName
= getSpecifierName(SC
);
644 SourceLocation SCLoc
= getStorageClassSpecLoc();
645 SourceLocation SCEndLoc
= SCLoc
.getFileLocWithOffset(strlen(SpecName
));
647 Diag(D
, SCLoc
, diag::err_friend_storage_spec
)
649 << FixItHint::CreateRemoval(SourceRange(SCLoc
, SCEndLoc
));
651 ClearStorageClassSpecs();
654 assert(!TypeSpecOwned
|| isDeclRep((TST
) TypeSpecType
));
656 // Okay, now we can infer the real type.
658 // TODO: return "auto function" and other bad things based on the real type.
660 // 'data definition has no type or storage class'?
663 bool DeclSpec::isMissingDeclaratorOk() {
664 TST tst
= getTypeSpecType();
665 return isDeclRep(tst
) && getRepAsDecl() != 0 &&
666 StorageClassSpec
!= DeclSpec::SCS_typedef
;
669 void UnqualifiedId::clear() {
670 if (Kind
== IK_TemplateId
)
671 TemplateId
->Destroy();
673 Kind
= IK_Identifier
;
675 StartLocation
= SourceLocation();
676 EndLocation
= SourceLocation();
679 void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc
,
680 OverloadedOperatorKind Op
,
681 SourceLocation SymbolLocations
[3]) {
682 Kind
= IK_OperatorFunctionId
;
683 StartLocation
= OperatorLoc
;
684 EndLocation
= OperatorLoc
;
685 OperatorFunctionId
.Operator
= Op
;
686 for (unsigned I
= 0; I
!= 3; ++I
) {
687 OperatorFunctionId
.SymbolLocations
[I
] = SymbolLocations
[I
].getRawEncoding();
689 if (SymbolLocations
[I
].isValid())
690 EndLocation
= SymbolLocations
[I
];
694 bool VirtSpecifiers::SetSpecifier(Specifier VS
, SourceLocation Loc
,
695 const char *&PrevSpec
) {
696 if (Specifiers
& VS
) {
697 PrevSpec
= getSpecifierName(VS
);
704 default: assert(0 && "Unknown specifier!");
705 case VS_Override
: VS_overrideLoc
= Loc
; break;
706 case VS_Final
: VS_finalLoc
= Loc
; break;
707 case VS_New
: VS_newLoc
= Loc
; break;
713 const char *VirtSpecifiers::getSpecifierName(Specifier VS
) {
715 default: assert(0 && "Unknown specifier");
716 case VS_Override
: return "override";
717 case VS_Final
: return "final";
718 case VS_New
: return "new";
722 bool ClassVirtSpecifiers::SetSpecifier(Specifier CVS
, SourceLocation Loc
,
723 const char *&PrevSpec
) {
724 if (Specifiers
& CVS
) {
725 PrevSpec
= getSpecifierName(CVS
);
732 default: assert(0 && "Unknown specifier!");
733 case CVS_Final
: CVS_finalLoc
= Loc
; break;
734 case CVS_Explicit
: CVS_explicitLoc
= Loc
; break;
740 const char *ClassVirtSpecifiers::getSpecifierName(Specifier CVS
) {
742 default: assert(0 && "Unknown specifier");
743 case CVS_Final
: return "final";
744 case CVS_Explicit
: return "explicit";