1f4a2713aSLionel Sambuc //===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file implements semantic analysis for declaration specifiers.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "clang/Sema/DeclSpec.h"
15f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
16f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
17f4a2713aSLionel Sambuc #include "clang/AST/Expr.h"
18f4a2713aSLionel Sambuc #include "clang/AST/NestedNameSpecifier.h"
19f4a2713aSLionel Sambuc #include "clang/AST/TypeLoc.h"
20f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.h"
21*0a6a1f1dSLionel Sambuc #include "clang/Basic/TargetInfo.h"
22f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
23f4a2713aSLionel Sambuc #include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
24f4a2713aSLionel Sambuc #include "clang/Sema/LocInfoType.h"
25f4a2713aSLionel Sambuc #include "clang/Sema/ParsedTemplate.h"
26f4a2713aSLionel Sambuc #include "clang/Sema/Sema.h"
27f4a2713aSLionel Sambuc #include "clang/Sema/SemaDiagnostic.h"
28f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
29f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
30f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
31f4a2713aSLionel Sambuc #include <cstring>
32f4a2713aSLionel Sambuc using namespace clang;
33f4a2713aSLionel Sambuc 
34f4a2713aSLionel Sambuc 
Diag(DiagnosticsEngine & D,SourceLocation Loc,unsigned DiagID)35f4a2713aSLionel Sambuc static DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc,
36f4a2713aSLionel Sambuc                               unsigned DiagID) {
37f4a2713aSLionel Sambuc   return D.Report(Loc, DiagID);
38f4a2713aSLionel Sambuc }
39f4a2713aSLionel Sambuc 
40f4a2713aSLionel Sambuc 
setTemplateId(TemplateIdAnnotation * TemplateId)41f4a2713aSLionel Sambuc void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
42f4a2713aSLionel Sambuc   assert(TemplateId && "NULL template-id annotation?");
43f4a2713aSLionel Sambuc   Kind = IK_TemplateId;
44f4a2713aSLionel Sambuc   this->TemplateId = TemplateId;
45f4a2713aSLionel Sambuc   StartLocation = TemplateId->TemplateNameLoc;
46f4a2713aSLionel Sambuc   EndLocation = TemplateId->RAngleLoc;
47f4a2713aSLionel Sambuc }
48f4a2713aSLionel Sambuc 
setConstructorTemplateId(TemplateIdAnnotation * TemplateId)49f4a2713aSLionel Sambuc void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
50f4a2713aSLionel Sambuc   assert(TemplateId && "NULL template-id annotation?");
51f4a2713aSLionel Sambuc   Kind = IK_ConstructorTemplateId;
52f4a2713aSLionel Sambuc   this->TemplateId = TemplateId;
53f4a2713aSLionel Sambuc   StartLocation = TemplateId->TemplateNameLoc;
54f4a2713aSLionel Sambuc   EndLocation = TemplateId->RAngleLoc;
55f4a2713aSLionel Sambuc }
56f4a2713aSLionel Sambuc 
Extend(ASTContext & Context,SourceLocation TemplateKWLoc,TypeLoc TL,SourceLocation ColonColonLoc)57f4a2713aSLionel Sambuc void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,
58f4a2713aSLionel Sambuc                           TypeLoc TL, SourceLocation ColonColonLoc) {
59f4a2713aSLionel Sambuc   Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);
60f4a2713aSLionel Sambuc   if (Range.getBegin().isInvalid())
61f4a2713aSLionel Sambuc     Range.setBegin(TL.getBeginLoc());
62f4a2713aSLionel Sambuc   Range.setEnd(ColonColonLoc);
63f4a2713aSLionel Sambuc 
64f4a2713aSLionel Sambuc   assert(Range == Builder.getSourceRange() &&
65f4a2713aSLionel Sambuc          "NestedNameSpecifierLoc range computation incorrect");
66f4a2713aSLionel Sambuc }
67f4a2713aSLionel Sambuc 
Extend(ASTContext & Context,IdentifierInfo * Identifier,SourceLocation IdentifierLoc,SourceLocation ColonColonLoc)68f4a2713aSLionel Sambuc void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
69f4a2713aSLionel Sambuc                           SourceLocation IdentifierLoc,
70f4a2713aSLionel Sambuc                           SourceLocation ColonColonLoc) {
71f4a2713aSLionel Sambuc   Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
72f4a2713aSLionel Sambuc 
73f4a2713aSLionel Sambuc   if (Range.getBegin().isInvalid())
74f4a2713aSLionel Sambuc     Range.setBegin(IdentifierLoc);
75f4a2713aSLionel Sambuc   Range.setEnd(ColonColonLoc);
76f4a2713aSLionel Sambuc 
77f4a2713aSLionel Sambuc   assert(Range == Builder.getSourceRange() &&
78f4a2713aSLionel Sambuc          "NestedNameSpecifierLoc range computation incorrect");
79f4a2713aSLionel Sambuc }
80f4a2713aSLionel Sambuc 
Extend(ASTContext & Context,NamespaceDecl * Namespace,SourceLocation NamespaceLoc,SourceLocation ColonColonLoc)81f4a2713aSLionel Sambuc void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
82f4a2713aSLionel Sambuc                           SourceLocation NamespaceLoc,
83f4a2713aSLionel Sambuc                           SourceLocation ColonColonLoc) {
84f4a2713aSLionel Sambuc   Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
85f4a2713aSLionel Sambuc 
86f4a2713aSLionel Sambuc   if (Range.getBegin().isInvalid())
87f4a2713aSLionel Sambuc     Range.setBegin(NamespaceLoc);
88f4a2713aSLionel Sambuc   Range.setEnd(ColonColonLoc);
89f4a2713aSLionel Sambuc 
90f4a2713aSLionel Sambuc   assert(Range == Builder.getSourceRange() &&
91f4a2713aSLionel Sambuc          "NestedNameSpecifierLoc range computation incorrect");
92f4a2713aSLionel Sambuc }
93f4a2713aSLionel Sambuc 
Extend(ASTContext & Context,NamespaceAliasDecl * Alias,SourceLocation AliasLoc,SourceLocation ColonColonLoc)94f4a2713aSLionel Sambuc void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
95f4a2713aSLionel Sambuc                           SourceLocation AliasLoc,
96f4a2713aSLionel Sambuc                           SourceLocation ColonColonLoc) {
97f4a2713aSLionel Sambuc   Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
98f4a2713aSLionel Sambuc 
99f4a2713aSLionel Sambuc   if (Range.getBegin().isInvalid())
100f4a2713aSLionel Sambuc     Range.setBegin(AliasLoc);
101f4a2713aSLionel Sambuc   Range.setEnd(ColonColonLoc);
102f4a2713aSLionel Sambuc 
103f4a2713aSLionel Sambuc   assert(Range == Builder.getSourceRange() &&
104f4a2713aSLionel Sambuc          "NestedNameSpecifierLoc range computation incorrect");
105f4a2713aSLionel Sambuc }
106f4a2713aSLionel Sambuc 
MakeGlobal(ASTContext & Context,SourceLocation ColonColonLoc)107f4a2713aSLionel Sambuc void CXXScopeSpec::MakeGlobal(ASTContext &Context,
108f4a2713aSLionel Sambuc                               SourceLocation ColonColonLoc) {
109f4a2713aSLionel Sambuc   Builder.MakeGlobal(Context, ColonColonLoc);
110f4a2713aSLionel Sambuc 
111f4a2713aSLionel Sambuc   Range = SourceRange(ColonColonLoc);
112f4a2713aSLionel Sambuc 
113f4a2713aSLionel Sambuc   assert(Range == Builder.getSourceRange() &&
114f4a2713aSLionel Sambuc          "NestedNameSpecifierLoc range computation incorrect");
115f4a2713aSLionel Sambuc }
116f4a2713aSLionel Sambuc 
MakeSuper(ASTContext & Context,CXXRecordDecl * RD,SourceLocation SuperLoc,SourceLocation ColonColonLoc)117*0a6a1f1dSLionel Sambuc void CXXScopeSpec::MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
118*0a6a1f1dSLionel Sambuc                              SourceLocation SuperLoc,
119*0a6a1f1dSLionel Sambuc                              SourceLocation ColonColonLoc) {
120*0a6a1f1dSLionel Sambuc   Builder.MakeSuper(Context, RD, SuperLoc, ColonColonLoc);
121*0a6a1f1dSLionel Sambuc 
122*0a6a1f1dSLionel Sambuc   Range.setBegin(SuperLoc);
123*0a6a1f1dSLionel Sambuc   Range.setEnd(ColonColonLoc);
124*0a6a1f1dSLionel Sambuc 
125*0a6a1f1dSLionel Sambuc   assert(Range == Builder.getSourceRange() &&
126*0a6a1f1dSLionel Sambuc   "NestedNameSpecifierLoc range computation incorrect");
127*0a6a1f1dSLionel Sambuc }
128*0a6a1f1dSLionel Sambuc 
MakeTrivial(ASTContext & Context,NestedNameSpecifier * Qualifier,SourceRange R)129f4a2713aSLionel Sambuc void CXXScopeSpec::MakeTrivial(ASTContext &Context,
130f4a2713aSLionel Sambuc                                NestedNameSpecifier *Qualifier, SourceRange R) {
131f4a2713aSLionel Sambuc   Builder.MakeTrivial(Context, Qualifier, R);
132f4a2713aSLionel Sambuc   Range = R;
133f4a2713aSLionel Sambuc }
134f4a2713aSLionel Sambuc 
Adopt(NestedNameSpecifierLoc Other)135f4a2713aSLionel Sambuc void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
136f4a2713aSLionel Sambuc   if (!Other) {
137f4a2713aSLionel Sambuc     Range = SourceRange();
138f4a2713aSLionel Sambuc     Builder.Clear();
139f4a2713aSLionel Sambuc     return;
140f4a2713aSLionel Sambuc   }
141f4a2713aSLionel Sambuc 
142f4a2713aSLionel Sambuc   Range = Other.getSourceRange();
143f4a2713aSLionel Sambuc   Builder.Adopt(Other);
144f4a2713aSLionel Sambuc }
145f4a2713aSLionel Sambuc 
getLastQualifierNameLoc() const146f4a2713aSLionel Sambuc SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const {
147f4a2713aSLionel Sambuc   if (!Builder.getRepresentation())
148f4a2713aSLionel Sambuc     return SourceLocation();
149f4a2713aSLionel Sambuc   return Builder.getTemporary().getLocalBeginLoc();
150f4a2713aSLionel Sambuc }
151f4a2713aSLionel Sambuc 
152f4a2713aSLionel Sambuc NestedNameSpecifierLoc
getWithLocInContext(ASTContext & Context) const153f4a2713aSLionel Sambuc CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
154f4a2713aSLionel Sambuc   if (!Builder.getRepresentation())
155f4a2713aSLionel Sambuc     return NestedNameSpecifierLoc();
156f4a2713aSLionel Sambuc 
157f4a2713aSLionel Sambuc   return Builder.getWithLocInContext(Context);
158f4a2713aSLionel Sambuc }
159f4a2713aSLionel Sambuc 
160f4a2713aSLionel Sambuc /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
161f4a2713aSLionel Sambuc /// "TheDeclarator" is the declarator that this will be added to.
getFunction(bool hasProto,bool isAmbiguous,SourceLocation LParenLoc,ParamInfo * Params,unsigned NumParams,SourceLocation EllipsisLoc,SourceLocation RParenLoc,unsigned TypeQuals,bool RefQualifierIsLvalueRef,SourceLocation RefQualifierLoc,SourceLocation ConstQualifierLoc,SourceLocation VolatileQualifierLoc,SourceLocation RestrictQualifierLoc,SourceLocation MutableLoc,ExceptionSpecificationType ESpecType,SourceLocation ESpecLoc,ParsedType * Exceptions,SourceRange * ExceptionRanges,unsigned NumExceptions,Expr * NoexceptExpr,CachedTokens * ExceptionSpecTokens,SourceLocation LocalRangeBegin,SourceLocation LocalRangeEnd,Declarator & TheDeclarator,TypeResult TrailingReturnType)162f4a2713aSLionel Sambuc DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
163f4a2713aSLionel Sambuc                                              bool isAmbiguous,
164f4a2713aSLionel Sambuc                                              SourceLocation LParenLoc,
165*0a6a1f1dSLionel Sambuc                                              ParamInfo *Params,
166*0a6a1f1dSLionel Sambuc                                              unsigned NumParams,
167f4a2713aSLionel Sambuc                                              SourceLocation EllipsisLoc,
168f4a2713aSLionel Sambuc                                              SourceLocation RParenLoc,
169f4a2713aSLionel Sambuc                                              unsigned TypeQuals,
170f4a2713aSLionel Sambuc                                              bool RefQualifierIsLvalueRef,
171f4a2713aSLionel Sambuc                                              SourceLocation RefQualifierLoc,
172f4a2713aSLionel Sambuc                                              SourceLocation ConstQualifierLoc,
173f4a2713aSLionel Sambuc                                              SourceLocation
174f4a2713aSLionel Sambuc                                                  VolatileQualifierLoc,
175*0a6a1f1dSLionel Sambuc                                              SourceLocation
176*0a6a1f1dSLionel Sambuc                                                  RestrictQualifierLoc,
177f4a2713aSLionel Sambuc                                              SourceLocation MutableLoc,
178f4a2713aSLionel Sambuc                                              ExceptionSpecificationType
179f4a2713aSLionel Sambuc                                                  ESpecType,
180f4a2713aSLionel Sambuc                                              SourceLocation ESpecLoc,
181f4a2713aSLionel Sambuc                                              ParsedType *Exceptions,
182f4a2713aSLionel Sambuc                                              SourceRange *ExceptionRanges,
183f4a2713aSLionel Sambuc                                              unsigned NumExceptions,
184f4a2713aSLionel Sambuc                                              Expr *NoexceptExpr,
185*0a6a1f1dSLionel Sambuc                                              CachedTokens *ExceptionSpecTokens,
186f4a2713aSLionel Sambuc                                              SourceLocation LocalRangeBegin,
187f4a2713aSLionel Sambuc                                              SourceLocation LocalRangeEnd,
188f4a2713aSLionel Sambuc                                              Declarator &TheDeclarator,
189f4a2713aSLionel Sambuc                                              TypeResult TrailingReturnType) {
190f4a2713aSLionel Sambuc   assert(!(TypeQuals & DeclSpec::TQ_atomic) &&
191f4a2713aSLionel Sambuc          "function cannot have _Atomic qualifier");
192f4a2713aSLionel Sambuc 
193f4a2713aSLionel Sambuc   DeclaratorChunk I;
194f4a2713aSLionel Sambuc   I.Kind                        = Function;
195f4a2713aSLionel Sambuc   I.Loc                         = LocalRangeBegin;
196f4a2713aSLionel Sambuc   I.EndLoc                      = LocalRangeEnd;
197*0a6a1f1dSLionel Sambuc   I.Fun.AttrList                = nullptr;
198f4a2713aSLionel Sambuc   I.Fun.hasPrototype            = hasProto;
199f4a2713aSLionel Sambuc   I.Fun.isVariadic              = EllipsisLoc.isValid();
200f4a2713aSLionel Sambuc   I.Fun.isAmbiguous             = isAmbiguous;
201f4a2713aSLionel Sambuc   I.Fun.LParenLoc               = LParenLoc.getRawEncoding();
202f4a2713aSLionel Sambuc   I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
203f4a2713aSLionel Sambuc   I.Fun.RParenLoc               = RParenLoc.getRawEncoding();
204*0a6a1f1dSLionel Sambuc   I.Fun.DeleteParams            = false;
205f4a2713aSLionel Sambuc   I.Fun.TypeQuals               = TypeQuals;
206*0a6a1f1dSLionel Sambuc   I.Fun.NumParams               = NumParams;
207*0a6a1f1dSLionel Sambuc   I.Fun.Params                  = nullptr;
208f4a2713aSLionel Sambuc   I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
209f4a2713aSLionel Sambuc   I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
210f4a2713aSLionel Sambuc   I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
211f4a2713aSLionel Sambuc   I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding();
212*0a6a1f1dSLionel Sambuc   I.Fun.RestrictQualifierLoc    = RestrictQualifierLoc.getRawEncoding();
213f4a2713aSLionel Sambuc   I.Fun.MutableLoc              = MutableLoc.getRawEncoding();
214f4a2713aSLionel Sambuc   I.Fun.ExceptionSpecType       = ESpecType;
215f4a2713aSLionel Sambuc   I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
216f4a2713aSLionel Sambuc   I.Fun.NumExceptions           = 0;
217*0a6a1f1dSLionel Sambuc   I.Fun.Exceptions              = nullptr;
218*0a6a1f1dSLionel Sambuc   I.Fun.NoexceptExpr            = nullptr;
219f4a2713aSLionel Sambuc   I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
220f4a2713aSLionel Sambuc                                   TrailingReturnType.isInvalid();
221f4a2713aSLionel Sambuc   I.Fun.TrailingReturnType      = TrailingReturnType.get();
222f4a2713aSLionel Sambuc 
223*0a6a1f1dSLionel Sambuc   assert(I.Fun.TypeQuals == TypeQuals && "bitfield overflow");
224*0a6a1f1dSLionel Sambuc   assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow");
225*0a6a1f1dSLionel Sambuc 
226*0a6a1f1dSLionel Sambuc   // new[] a parameter array if needed.
227*0a6a1f1dSLionel Sambuc   if (NumParams) {
228f4a2713aSLionel Sambuc     // If the 'InlineParams' in Declarator is unused and big enough, put our
229f4a2713aSLionel Sambuc     // parameter list there (in an effort to avoid new/delete traffic).  If it
230f4a2713aSLionel Sambuc     // is already used (consider a function returning a function pointer) or too
231*0a6a1f1dSLionel Sambuc     // small (function with too many parameters), go to the heap.
232f4a2713aSLionel Sambuc     if (!TheDeclarator.InlineParamsUsed &&
233*0a6a1f1dSLionel Sambuc         NumParams <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
234*0a6a1f1dSLionel Sambuc       I.Fun.Params = TheDeclarator.InlineParams;
235*0a6a1f1dSLionel Sambuc       I.Fun.DeleteParams = false;
236f4a2713aSLionel Sambuc       TheDeclarator.InlineParamsUsed = true;
237f4a2713aSLionel Sambuc     } else {
238*0a6a1f1dSLionel Sambuc       I.Fun.Params = new DeclaratorChunk::ParamInfo[NumParams];
239*0a6a1f1dSLionel Sambuc       I.Fun.DeleteParams = true;
240f4a2713aSLionel Sambuc     }
241*0a6a1f1dSLionel Sambuc     memcpy(I.Fun.Params, Params, sizeof(Params[0]) * NumParams);
242f4a2713aSLionel Sambuc   }
243f4a2713aSLionel Sambuc 
244f4a2713aSLionel Sambuc   // Check what exception specification information we should actually store.
245f4a2713aSLionel Sambuc   switch (ESpecType) {
246f4a2713aSLionel Sambuc   default: break; // By default, save nothing.
247f4a2713aSLionel Sambuc   case EST_Dynamic:
248f4a2713aSLionel Sambuc     // new[] an exception array if needed
249f4a2713aSLionel Sambuc     if (NumExceptions) {
250f4a2713aSLionel Sambuc       I.Fun.NumExceptions = NumExceptions;
251f4a2713aSLionel Sambuc       I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
252f4a2713aSLionel Sambuc       for (unsigned i = 0; i != NumExceptions; ++i) {
253f4a2713aSLionel Sambuc         I.Fun.Exceptions[i].Ty = Exceptions[i];
254f4a2713aSLionel Sambuc         I.Fun.Exceptions[i].Range = ExceptionRanges[i];
255f4a2713aSLionel Sambuc       }
256f4a2713aSLionel Sambuc     }
257f4a2713aSLionel Sambuc     break;
258f4a2713aSLionel Sambuc 
259f4a2713aSLionel Sambuc   case EST_ComputedNoexcept:
260f4a2713aSLionel Sambuc     I.Fun.NoexceptExpr = NoexceptExpr;
261f4a2713aSLionel Sambuc     break;
262*0a6a1f1dSLionel Sambuc 
263*0a6a1f1dSLionel Sambuc   case EST_Unparsed:
264*0a6a1f1dSLionel Sambuc     I.Fun.ExceptionSpecTokens = ExceptionSpecTokens;
265*0a6a1f1dSLionel Sambuc     break;
266f4a2713aSLionel Sambuc   }
267f4a2713aSLionel Sambuc   return I;
268f4a2713aSLionel Sambuc }
269f4a2713aSLionel Sambuc 
isDeclarationOfFunction() const270f4a2713aSLionel Sambuc bool Declarator::isDeclarationOfFunction() const {
271f4a2713aSLionel Sambuc   for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
272f4a2713aSLionel Sambuc     switch (DeclTypeInfo[i].Kind) {
273f4a2713aSLionel Sambuc     case DeclaratorChunk::Function:
274f4a2713aSLionel Sambuc       return true;
275f4a2713aSLionel Sambuc     case DeclaratorChunk::Paren:
276f4a2713aSLionel Sambuc       continue;
277f4a2713aSLionel Sambuc     case DeclaratorChunk::Pointer:
278f4a2713aSLionel Sambuc     case DeclaratorChunk::Reference:
279f4a2713aSLionel Sambuc     case DeclaratorChunk::Array:
280f4a2713aSLionel Sambuc     case DeclaratorChunk::BlockPointer:
281f4a2713aSLionel Sambuc     case DeclaratorChunk::MemberPointer:
282f4a2713aSLionel Sambuc       return false;
283f4a2713aSLionel Sambuc     }
284f4a2713aSLionel Sambuc     llvm_unreachable("Invalid type chunk");
285f4a2713aSLionel Sambuc   }
286f4a2713aSLionel Sambuc 
287f4a2713aSLionel Sambuc   switch (DS.getTypeSpecType()) {
288f4a2713aSLionel Sambuc     case TST_atomic:
289f4a2713aSLionel Sambuc     case TST_auto:
290f4a2713aSLionel Sambuc     case TST_bool:
291f4a2713aSLionel Sambuc     case TST_char:
292f4a2713aSLionel Sambuc     case TST_char16:
293f4a2713aSLionel Sambuc     case TST_char32:
294f4a2713aSLionel Sambuc     case TST_class:
295f4a2713aSLionel Sambuc     case TST_decimal128:
296f4a2713aSLionel Sambuc     case TST_decimal32:
297f4a2713aSLionel Sambuc     case TST_decimal64:
298f4a2713aSLionel Sambuc     case TST_double:
299f4a2713aSLionel Sambuc     case TST_enum:
300f4a2713aSLionel Sambuc     case TST_error:
301f4a2713aSLionel Sambuc     case TST_float:
302f4a2713aSLionel Sambuc     case TST_half:
303f4a2713aSLionel Sambuc     case TST_int:
304f4a2713aSLionel Sambuc     case TST_int128:
305f4a2713aSLionel Sambuc     case TST_struct:
306f4a2713aSLionel Sambuc     case TST_interface:
307f4a2713aSLionel Sambuc     case TST_union:
308f4a2713aSLionel Sambuc     case TST_unknown_anytype:
309f4a2713aSLionel Sambuc     case TST_unspecified:
310f4a2713aSLionel Sambuc     case TST_void:
311f4a2713aSLionel Sambuc     case TST_wchar:
312f4a2713aSLionel Sambuc       return false;
313f4a2713aSLionel Sambuc 
314f4a2713aSLionel Sambuc     case TST_decltype_auto:
315f4a2713aSLionel Sambuc       // This must have an initializer, so can't be a function declaration,
316f4a2713aSLionel Sambuc       // even if the initializer has function type.
317f4a2713aSLionel Sambuc       return false;
318f4a2713aSLionel Sambuc 
319f4a2713aSLionel Sambuc     case TST_decltype:
320f4a2713aSLionel Sambuc     case TST_typeofExpr:
321f4a2713aSLionel Sambuc       if (Expr *E = DS.getRepAsExpr())
322f4a2713aSLionel Sambuc         return E->getType()->isFunctionType();
323f4a2713aSLionel Sambuc       return false;
324f4a2713aSLionel Sambuc 
325f4a2713aSLionel Sambuc     case TST_underlyingType:
326f4a2713aSLionel Sambuc     case TST_typename:
327f4a2713aSLionel Sambuc     case TST_typeofType: {
328f4a2713aSLionel Sambuc       QualType QT = DS.getRepAsType().get();
329f4a2713aSLionel Sambuc       if (QT.isNull())
330f4a2713aSLionel Sambuc         return false;
331f4a2713aSLionel Sambuc 
332f4a2713aSLionel Sambuc       if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
333f4a2713aSLionel Sambuc         QT = LIT->getType();
334f4a2713aSLionel Sambuc 
335f4a2713aSLionel Sambuc       if (QT.isNull())
336f4a2713aSLionel Sambuc         return false;
337f4a2713aSLionel Sambuc 
338f4a2713aSLionel Sambuc       return QT->isFunctionType();
339f4a2713aSLionel Sambuc     }
340f4a2713aSLionel Sambuc   }
341f4a2713aSLionel Sambuc 
342f4a2713aSLionel Sambuc   llvm_unreachable("Invalid TypeSpecType!");
343f4a2713aSLionel Sambuc }
344f4a2713aSLionel Sambuc 
isStaticMember()345f4a2713aSLionel Sambuc bool Declarator::isStaticMember() {
346f4a2713aSLionel Sambuc   assert(getContext() == MemberContext);
347f4a2713aSLionel Sambuc   return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
348*0a6a1f1dSLionel Sambuc          (getName().Kind == UnqualifiedId::IK_OperatorFunctionId &&
349f4a2713aSLionel Sambuc           CXXMethodDecl::isStaticOverloadedOperator(
350*0a6a1f1dSLionel Sambuc               getName().OperatorFunctionId.Operator));
351f4a2713aSLionel Sambuc }
352f4a2713aSLionel Sambuc 
hasTagDefinition() const353f4a2713aSLionel Sambuc bool DeclSpec::hasTagDefinition() const {
354f4a2713aSLionel Sambuc   if (!TypeSpecOwned)
355f4a2713aSLionel Sambuc     return false;
356f4a2713aSLionel Sambuc   return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition();
357f4a2713aSLionel Sambuc }
358f4a2713aSLionel Sambuc 
359f4a2713aSLionel Sambuc /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
360f4a2713aSLionel Sambuc /// declaration specifier includes.
361f4a2713aSLionel Sambuc ///
getParsedSpecifiers() const362f4a2713aSLionel Sambuc unsigned DeclSpec::getParsedSpecifiers() const {
363f4a2713aSLionel Sambuc   unsigned Res = 0;
364f4a2713aSLionel Sambuc   if (StorageClassSpec != SCS_unspecified ||
365f4a2713aSLionel Sambuc       ThreadStorageClassSpec != TSCS_unspecified)
366f4a2713aSLionel Sambuc     Res |= PQ_StorageClassSpecifier;
367f4a2713aSLionel Sambuc 
368f4a2713aSLionel Sambuc   if (TypeQualifiers != TQ_unspecified)
369f4a2713aSLionel Sambuc     Res |= PQ_TypeQualifier;
370f4a2713aSLionel Sambuc 
371f4a2713aSLionel Sambuc   if (hasTypeSpecifier())
372f4a2713aSLionel Sambuc     Res |= PQ_TypeSpecifier;
373f4a2713aSLionel Sambuc 
374f4a2713aSLionel Sambuc   if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified ||
375f4a2713aSLionel Sambuc       FS_noreturn_specified || FS_forceinline_specified)
376f4a2713aSLionel Sambuc     Res |= PQ_FunctionSpecifier;
377f4a2713aSLionel Sambuc   return Res;
378f4a2713aSLionel Sambuc }
379f4a2713aSLionel Sambuc 
BadSpecifier(T TNew,T TPrev,const char * & PrevSpec,unsigned & DiagID,bool IsExtension=true)380f4a2713aSLionel Sambuc template <class T> static bool BadSpecifier(T TNew, T TPrev,
381f4a2713aSLionel Sambuc                                             const char *&PrevSpec,
382f4a2713aSLionel Sambuc                                             unsigned &DiagID,
383f4a2713aSLionel Sambuc                                             bool IsExtension = true) {
384f4a2713aSLionel Sambuc   PrevSpec = DeclSpec::getSpecifierName(TPrev);
385f4a2713aSLionel Sambuc   if (TNew != TPrev)
386f4a2713aSLionel Sambuc     DiagID = diag::err_invalid_decl_spec_combination;
387f4a2713aSLionel Sambuc   else
388f4a2713aSLionel Sambuc     DiagID = IsExtension ? diag::ext_duplicate_declspec :
389f4a2713aSLionel Sambuc                            diag::warn_duplicate_declspec;
390f4a2713aSLionel Sambuc   return true;
391f4a2713aSLionel Sambuc }
392f4a2713aSLionel Sambuc 
getSpecifierName(DeclSpec::SCS S)393f4a2713aSLionel Sambuc const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
394f4a2713aSLionel Sambuc   switch (S) {
395f4a2713aSLionel Sambuc   case DeclSpec::SCS_unspecified: return "unspecified";
396f4a2713aSLionel Sambuc   case DeclSpec::SCS_typedef:     return "typedef";
397f4a2713aSLionel Sambuc   case DeclSpec::SCS_extern:      return "extern";
398f4a2713aSLionel Sambuc   case DeclSpec::SCS_static:      return "static";
399f4a2713aSLionel Sambuc   case DeclSpec::SCS_auto:        return "auto";
400f4a2713aSLionel Sambuc   case DeclSpec::SCS_register:    return "register";
401f4a2713aSLionel Sambuc   case DeclSpec::SCS_private_extern: return "__private_extern__";
402f4a2713aSLionel Sambuc   case DeclSpec::SCS_mutable:     return "mutable";
403f4a2713aSLionel Sambuc   }
404f4a2713aSLionel Sambuc   llvm_unreachable("Unknown typespec!");
405f4a2713aSLionel Sambuc }
406f4a2713aSLionel Sambuc 
getSpecifierName(DeclSpec::TSCS S)407f4a2713aSLionel Sambuc const char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) {
408f4a2713aSLionel Sambuc   switch (S) {
409f4a2713aSLionel Sambuc   case DeclSpec::TSCS_unspecified:   return "unspecified";
410f4a2713aSLionel Sambuc   case DeclSpec::TSCS___thread:      return "__thread";
411f4a2713aSLionel Sambuc   case DeclSpec::TSCS_thread_local:  return "thread_local";
412f4a2713aSLionel Sambuc   case DeclSpec::TSCS__Thread_local: return "_Thread_local";
413f4a2713aSLionel Sambuc   }
414f4a2713aSLionel Sambuc   llvm_unreachable("Unknown typespec!");
415f4a2713aSLionel Sambuc }
416f4a2713aSLionel Sambuc 
getSpecifierName(TSW W)417f4a2713aSLionel Sambuc const char *DeclSpec::getSpecifierName(TSW W) {
418f4a2713aSLionel Sambuc   switch (W) {
419f4a2713aSLionel Sambuc   case TSW_unspecified: return "unspecified";
420f4a2713aSLionel Sambuc   case TSW_short:       return "short";
421f4a2713aSLionel Sambuc   case TSW_long:        return "long";
422f4a2713aSLionel Sambuc   case TSW_longlong:    return "long long";
423f4a2713aSLionel Sambuc   }
424f4a2713aSLionel Sambuc   llvm_unreachable("Unknown typespec!");
425f4a2713aSLionel Sambuc }
426f4a2713aSLionel Sambuc 
getSpecifierName(TSC C)427f4a2713aSLionel Sambuc const char *DeclSpec::getSpecifierName(TSC C) {
428f4a2713aSLionel Sambuc   switch (C) {
429f4a2713aSLionel Sambuc   case TSC_unspecified: return "unspecified";
430f4a2713aSLionel Sambuc   case TSC_imaginary:   return "imaginary";
431f4a2713aSLionel Sambuc   case TSC_complex:     return "complex";
432f4a2713aSLionel Sambuc   }
433f4a2713aSLionel Sambuc   llvm_unreachable("Unknown typespec!");
434f4a2713aSLionel Sambuc }
435f4a2713aSLionel Sambuc 
436f4a2713aSLionel Sambuc 
getSpecifierName(TSS S)437f4a2713aSLionel Sambuc const char *DeclSpec::getSpecifierName(TSS S) {
438f4a2713aSLionel Sambuc   switch (S) {
439f4a2713aSLionel Sambuc   case TSS_unspecified: return "unspecified";
440f4a2713aSLionel Sambuc   case TSS_signed:      return "signed";
441f4a2713aSLionel Sambuc   case TSS_unsigned:    return "unsigned";
442f4a2713aSLionel Sambuc   }
443f4a2713aSLionel Sambuc   llvm_unreachable("Unknown typespec!");
444f4a2713aSLionel Sambuc }
445f4a2713aSLionel Sambuc 
getSpecifierName(DeclSpec::TST T,const PrintingPolicy & Policy)446*0a6a1f1dSLionel Sambuc const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
447*0a6a1f1dSLionel Sambuc                                        const PrintingPolicy &Policy) {
448f4a2713aSLionel Sambuc   switch (T) {
449f4a2713aSLionel Sambuc   case DeclSpec::TST_unspecified: return "unspecified";
450f4a2713aSLionel Sambuc   case DeclSpec::TST_void:        return "void";
451f4a2713aSLionel Sambuc   case DeclSpec::TST_char:        return "char";
452*0a6a1f1dSLionel Sambuc   case DeclSpec::TST_wchar:       return Policy.MSWChar ? "__wchar_t" : "wchar_t";
453f4a2713aSLionel Sambuc   case DeclSpec::TST_char16:      return "char16_t";
454f4a2713aSLionel Sambuc   case DeclSpec::TST_char32:      return "char32_t";
455f4a2713aSLionel Sambuc   case DeclSpec::TST_int:         return "int";
456f4a2713aSLionel Sambuc   case DeclSpec::TST_int128:      return "__int128";
457f4a2713aSLionel Sambuc   case DeclSpec::TST_half:        return "half";
458f4a2713aSLionel Sambuc   case DeclSpec::TST_float:       return "float";
459f4a2713aSLionel Sambuc   case DeclSpec::TST_double:      return "double";
460*0a6a1f1dSLionel Sambuc   case DeclSpec::TST_bool:        return Policy.Bool ? "bool" : "_Bool";
461f4a2713aSLionel Sambuc   case DeclSpec::TST_decimal32:   return "_Decimal32";
462f4a2713aSLionel Sambuc   case DeclSpec::TST_decimal64:   return "_Decimal64";
463f4a2713aSLionel Sambuc   case DeclSpec::TST_decimal128:  return "_Decimal128";
464f4a2713aSLionel Sambuc   case DeclSpec::TST_enum:        return "enum";
465f4a2713aSLionel Sambuc   case DeclSpec::TST_class:       return "class";
466f4a2713aSLionel Sambuc   case DeclSpec::TST_union:       return "union";
467f4a2713aSLionel Sambuc   case DeclSpec::TST_struct:      return "struct";
468f4a2713aSLionel Sambuc   case DeclSpec::TST_interface:   return "__interface";
469f4a2713aSLionel Sambuc   case DeclSpec::TST_typename:    return "type-name";
470f4a2713aSLionel Sambuc   case DeclSpec::TST_typeofType:
471f4a2713aSLionel Sambuc   case DeclSpec::TST_typeofExpr:  return "typeof";
472f4a2713aSLionel Sambuc   case DeclSpec::TST_auto:        return "auto";
473f4a2713aSLionel Sambuc   case DeclSpec::TST_decltype:    return "(decltype)";
474f4a2713aSLionel Sambuc   case DeclSpec::TST_decltype_auto: return "decltype(auto)";
475f4a2713aSLionel Sambuc   case DeclSpec::TST_underlyingType: return "__underlying_type";
476f4a2713aSLionel Sambuc   case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
477f4a2713aSLionel Sambuc   case DeclSpec::TST_atomic: return "_Atomic";
478f4a2713aSLionel Sambuc   case DeclSpec::TST_error:       return "(error)";
479f4a2713aSLionel Sambuc   }
480f4a2713aSLionel Sambuc   llvm_unreachable("Unknown typespec!");
481f4a2713aSLionel Sambuc }
482f4a2713aSLionel Sambuc 
getSpecifierName(TQ T)483f4a2713aSLionel Sambuc const char *DeclSpec::getSpecifierName(TQ T) {
484f4a2713aSLionel Sambuc   switch (T) {
485f4a2713aSLionel Sambuc   case DeclSpec::TQ_unspecified: return "unspecified";
486f4a2713aSLionel Sambuc   case DeclSpec::TQ_const:       return "const";
487f4a2713aSLionel Sambuc   case DeclSpec::TQ_restrict:    return "restrict";
488f4a2713aSLionel Sambuc   case DeclSpec::TQ_volatile:    return "volatile";
489f4a2713aSLionel Sambuc   case DeclSpec::TQ_atomic:      return "_Atomic";
490f4a2713aSLionel Sambuc   }
491f4a2713aSLionel Sambuc   llvm_unreachable("Unknown typespec!");
492f4a2713aSLionel Sambuc }
493f4a2713aSLionel Sambuc 
SetStorageClassSpec(Sema & S,SCS SC,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,const PrintingPolicy & Policy)494f4a2713aSLionel Sambuc bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
495f4a2713aSLionel Sambuc                                    const char *&PrevSpec,
496*0a6a1f1dSLionel Sambuc                                    unsigned &DiagID,
497*0a6a1f1dSLionel Sambuc                                    const PrintingPolicy &Policy) {
498f4a2713aSLionel Sambuc   // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
499f4a2713aSLionel Sambuc   // specifiers are not supported.
500f4a2713aSLionel Sambuc   // It seems sensible to prohibit private_extern too
501f4a2713aSLionel Sambuc   // The cl_clang_storage_class_specifiers extension enables support for
502f4a2713aSLionel Sambuc   // these storage-class specifiers.
503f4a2713aSLionel Sambuc   // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
504f4a2713aSLionel Sambuc   // specifiers are not supported."
505f4a2713aSLionel Sambuc   if (S.getLangOpts().OpenCL &&
506f4a2713aSLionel Sambuc       !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
507f4a2713aSLionel Sambuc     switch (SC) {
508f4a2713aSLionel Sambuc     case SCS_extern:
509f4a2713aSLionel Sambuc     case SCS_private_extern:
510f4a2713aSLionel Sambuc     case SCS_static:
511f4a2713aSLionel Sambuc         if (S.getLangOpts().OpenCLVersion < 120) {
512*0a6a1f1dSLionel Sambuc           DiagID   = diag::err_opencl_unknown_type_specifier;
513f4a2713aSLionel Sambuc           PrevSpec = getSpecifierName(SC);
514f4a2713aSLionel Sambuc           return true;
515f4a2713aSLionel Sambuc         }
516f4a2713aSLionel Sambuc         break;
517f4a2713aSLionel Sambuc     case SCS_auto:
518f4a2713aSLionel Sambuc     case SCS_register:
519*0a6a1f1dSLionel Sambuc       DiagID   = diag::err_opencl_unknown_type_specifier;
520f4a2713aSLionel Sambuc       PrevSpec = getSpecifierName(SC);
521f4a2713aSLionel Sambuc       return true;
522f4a2713aSLionel Sambuc     default:
523f4a2713aSLionel Sambuc       break;
524f4a2713aSLionel Sambuc     }
525f4a2713aSLionel Sambuc   }
526f4a2713aSLionel Sambuc 
527f4a2713aSLionel Sambuc   if (StorageClassSpec != SCS_unspecified) {
528f4a2713aSLionel Sambuc     // Maybe this is an attempt to use C++11 'auto' outside of C++11 mode.
529f4a2713aSLionel Sambuc     bool isInvalid = true;
530f4a2713aSLionel Sambuc     if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
531f4a2713aSLionel Sambuc       if (SC == SCS_auto)
532*0a6a1f1dSLionel Sambuc         return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID, Policy);
533f4a2713aSLionel Sambuc       if (StorageClassSpec == SCS_auto) {
534f4a2713aSLionel Sambuc         isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
535*0a6a1f1dSLionel Sambuc                                     PrevSpec, DiagID, Policy);
536f4a2713aSLionel Sambuc         assert(!isInvalid && "auto SCS -> TST recovery failed");
537f4a2713aSLionel Sambuc       }
538f4a2713aSLionel Sambuc     }
539f4a2713aSLionel Sambuc 
540f4a2713aSLionel Sambuc     // Changing storage class is allowed only if the previous one
541f4a2713aSLionel Sambuc     // was the 'extern' that is part of a linkage specification and
542f4a2713aSLionel Sambuc     // the new storage class is 'typedef'.
543f4a2713aSLionel Sambuc     if (isInvalid &&
544f4a2713aSLionel Sambuc         !(SCS_extern_in_linkage_spec &&
545f4a2713aSLionel Sambuc           StorageClassSpec == SCS_extern &&
546f4a2713aSLionel Sambuc           SC == SCS_typedef))
547f4a2713aSLionel Sambuc       return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
548f4a2713aSLionel Sambuc   }
549f4a2713aSLionel Sambuc   StorageClassSpec = SC;
550f4a2713aSLionel Sambuc   StorageClassSpecLoc = Loc;
551f4a2713aSLionel Sambuc   assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
552f4a2713aSLionel Sambuc   return false;
553f4a2713aSLionel Sambuc }
554f4a2713aSLionel Sambuc 
SetStorageClassSpecThread(TSCS TSC,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)555f4a2713aSLionel Sambuc bool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,
556f4a2713aSLionel Sambuc                                          const char *&PrevSpec,
557f4a2713aSLionel Sambuc                                          unsigned &DiagID) {
558f4a2713aSLionel Sambuc   if (ThreadStorageClassSpec != TSCS_unspecified)
559f4a2713aSLionel Sambuc     return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID);
560f4a2713aSLionel Sambuc 
561f4a2713aSLionel Sambuc   ThreadStorageClassSpec = TSC;
562f4a2713aSLionel Sambuc   ThreadStorageClassSpecLoc = Loc;
563f4a2713aSLionel Sambuc   return false;
564f4a2713aSLionel Sambuc }
565f4a2713aSLionel Sambuc 
566f4a2713aSLionel Sambuc /// These methods set the specified attribute of the DeclSpec, but return true
567f4a2713aSLionel Sambuc /// and ignore the request if invalid (e.g. "extern" then "auto" is
568f4a2713aSLionel Sambuc /// specified).
SetTypeSpecWidth(TSW W,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,const PrintingPolicy & Policy)569f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
570f4a2713aSLionel Sambuc                                 const char *&PrevSpec,
571*0a6a1f1dSLionel Sambuc                                 unsigned &DiagID,
572*0a6a1f1dSLionel Sambuc                                 const PrintingPolicy &Policy) {
573f4a2713aSLionel Sambuc   // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
574f4a2713aSLionel Sambuc   // for 'long long' we will keep the source location of the first 'long'.
575f4a2713aSLionel Sambuc   if (TypeSpecWidth == TSW_unspecified)
576f4a2713aSLionel Sambuc     TSWLoc = Loc;
577f4a2713aSLionel Sambuc   // Allow turning long -> long long.
578f4a2713aSLionel Sambuc   else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
579f4a2713aSLionel Sambuc     return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
580f4a2713aSLionel Sambuc   TypeSpecWidth = W;
581f4a2713aSLionel Sambuc   return false;
582f4a2713aSLionel Sambuc }
583f4a2713aSLionel Sambuc 
SetTypeSpecComplex(TSC C,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)584f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
585f4a2713aSLionel Sambuc                                   const char *&PrevSpec,
586f4a2713aSLionel Sambuc                                   unsigned &DiagID) {
587f4a2713aSLionel Sambuc   if (TypeSpecComplex != TSC_unspecified)
588f4a2713aSLionel Sambuc     return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
589f4a2713aSLionel Sambuc   TypeSpecComplex = C;
590f4a2713aSLionel Sambuc   TSCLoc = Loc;
591f4a2713aSLionel Sambuc   return false;
592f4a2713aSLionel Sambuc }
593f4a2713aSLionel Sambuc 
SetTypeSpecSign(TSS S,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)594f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
595f4a2713aSLionel Sambuc                                const char *&PrevSpec,
596f4a2713aSLionel Sambuc                                unsigned &DiagID) {
597f4a2713aSLionel Sambuc   if (TypeSpecSign != TSS_unspecified)
598f4a2713aSLionel Sambuc     return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
599f4a2713aSLionel Sambuc   TypeSpecSign = S;
600f4a2713aSLionel Sambuc   TSSLoc = Loc;
601f4a2713aSLionel Sambuc   return false;
602f4a2713aSLionel Sambuc }
603f4a2713aSLionel Sambuc 
SetTypeSpecType(TST T,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,ParsedType Rep,const PrintingPolicy & Policy)604f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
605f4a2713aSLionel Sambuc                                const char *&PrevSpec,
606f4a2713aSLionel Sambuc                                unsigned &DiagID,
607*0a6a1f1dSLionel Sambuc                                ParsedType Rep,
608*0a6a1f1dSLionel Sambuc                                const PrintingPolicy &Policy) {
609*0a6a1f1dSLionel Sambuc   return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Policy);
610f4a2713aSLionel Sambuc }
611f4a2713aSLionel Sambuc 
SetTypeSpecType(TST T,SourceLocation TagKwLoc,SourceLocation TagNameLoc,const char * & PrevSpec,unsigned & DiagID,ParsedType Rep,const PrintingPolicy & Policy)612f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
613f4a2713aSLionel Sambuc                                SourceLocation TagNameLoc,
614f4a2713aSLionel Sambuc                                const char *&PrevSpec,
615f4a2713aSLionel Sambuc                                unsigned &DiagID,
616*0a6a1f1dSLionel Sambuc                                ParsedType Rep,
617*0a6a1f1dSLionel Sambuc                                const PrintingPolicy &Policy) {
618f4a2713aSLionel Sambuc   assert(isTypeRep(T) && "T does not store a type");
619f4a2713aSLionel Sambuc   assert(Rep && "no type provided!");
620f4a2713aSLionel Sambuc   if (TypeSpecType != TST_unspecified) {
621*0a6a1f1dSLionel Sambuc     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
622f4a2713aSLionel Sambuc     DiagID = diag::err_invalid_decl_spec_combination;
623f4a2713aSLionel Sambuc     return true;
624f4a2713aSLionel Sambuc   }
625f4a2713aSLionel Sambuc   TypeSpecType = T;
626f4a2713aSLionel Sambuc   TypeRep = Rep;
627f4a2713aSLionel Sambuc   TSTLoc = TagKwLoc;
628f4a2713aSLionel Sambuc   TSTNameLoc = TagNameLoc;
629f4a2713aSLionel Sambuc   TypeSpecOwned = false;
630f4a2713aSLionel Sambuc   return false;
631f4a2713aSLionel Sambuc }
632f4a2713aSLionel Sambuc 
SetTypeSpecType(TST T,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,Expr * Rep,const PrintingPolicy & Policy)633f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
634f4a2713aSLionel Sambuc                                const char *&PrevSpec,
635f4a2713aSLionel Sambuc                                unsigned &DiagID,
636*0a6a1f1dSLionel Sambuc                                Expr *Rep,
637*0a6a1f1dSLionel Sambuc                                const PrintingPolicy &Policy) {
638f4a2713aSLionel Sambuc   assert(isExprRep(T) && "T does not store an expr");
639f4a2713aSLionel Sambuc   assert(Rep && "no expression provided!");
640f4a2713aSLionel Sambuc   if (TypeSpecType != TST_unspecified) {
641*0a6a1f1dSLionel Sambuc     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
642f4a2713aSLionel Sambuc     DiagID = diag::err_invalid_decl_spec_combination;
643f4a2713aSLionel Sambuc     return true;
644f4a2713aSLionel Sambuc   }
645f4a2713aSLionel Sambuc   TypeSpecType = T;
646f4a2713aSLionel Sambuc   ExprRep = Rep;
647f4a2713aSLionel Sambuc   TSTLoc = Loc;
648f4a2713aSLionel Sambuc   TSTNameLoc = Loc;
649f4a2713aSLionel Sambuc   TypeSpecOwned = false;
650f4a2713aSLionel Sambuc   return false;
651f4a2713aSLionel Sambuc }
652f4a2713aSLionel Sambuc 
SetTypeSpecType(TST T,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,Decl * Rep,bool Owned,const PrintingPolicy & Policy)653f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
654f4a2713aSLionel Sambuc                                const char *&PrevSpec,
655f4a2713aSLionel Sambuc                                unsigned &DiagID,
656*0a6a1f1dSLionel Sambuc                                Decl *Rep, bool Owned,
657*0a6a1f1dSLionel Sambuc                                const PrintingPolicy &Policy) {
658*0a6a1f1dSLionel Sambuc   return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned, Policy);
659f4a2713aSLionel Sambuc }
660f4a2713aSLionel Sambuc 
SetTypeSpecType(TST T,SourceLocation TagKwLoc,SourceLocation TagNameLoc,const char * & PrevSpec,unsigned & DiagID,Decl * Rep,bool Owned,const PrintingPolicy & Policy)661f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
662f4a2713aSLionel Sambuc                                SourceLocation TagNameLoc,
663f4a2713aSLionel Sambuc                                const char *&PrevSpec,
664f4a2713aSLionel Sambuc                                unsigned &DiagID,
665*0a6a1f1dSLionel Sambuc                                Decl *Rep, bool Owned,
666*0a6a1f1dSLionel Sambuc                                const PrintingPolicy &Policy) {
667f4a2713aSLionel Sambuc   assert(isDeclRep(T) && "T does not store a decl");
668f4a2713aSLionel Sambuc   // Unlike the other cases, we don't assert that we actually get a decl.
669f4a2713aSLionel Sambuc 
670f4a2713aSLionel Sambuc   if (TypeSpecType != TST_unspecified) {
671*0a6a1f1dSLionel Sambuc     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
672f4a2713aSLionel Sambuc     DiagID = diag::err_invalid_decl_spec_combination;
673f4a2713aSLionel Sambuc     return true;
674f4a2713aSLionel Sambuc   }
675f4a2713aSLionel Sambuc   TypeSpecType = T;
676f4a2713aSLionel Sambuc   DeclRep = Rep;
677f4a2713aSLionel Sambuc   TSTLoc = TagKwLoc;
678f4a2713aSLionel Sambuc   TSTNameLoc = TagNameLoc;
679*0a6a1f1dSLionel Sambuc   TypeSpecOwned = Owned && Rep != nullptr;
680f4a2713aSLionel Sambuc   return false;
681f4a2713aSLionel Sambuc }
682f4a2713aSLionel Sambuc 
SetTypeSpecType(TST T,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,const PrintingPolicy & Policy)683f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
684f4a2713aSLionel Sambuc                                const char *&PrevSpec,
685*0a6a1f1dSLionel Sambuc                                unsigned &DiagID,
686*0a6a1f1dSLionel Sambuc                                const PrintingPolicy &Policy) {
687f4a2713aSLionel Sambuc   assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
688f4a2713aSLionel Sambuc          "rep required for these type-spec kinds!");
689f4a2713aSLionel Sambuc   if (TypeSpecType != TST_unspecified) {
690*0a6a1f1dSLionel Sambuc     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
691f4a2713aSLionel Sambuc     DiagID = diag::err_invalid_decl_spec_combination;
692f4a2713aSLionel Sambuc     return true;
693f4a2713aSLionel Sambuc   }
694f4a2713aSLionel Sambuc   TSTLoc = Loc;
695f4a2713aSLionel Sambuc   TSTNameLoc = Loc;
696f4a2713aSLionel Sambuc   if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
697f4a2713aSLionel Sambuc     TypeAltiVecBool = true;
698f4a2713aSLionel Sambuc     return false;
699f4a2713aSLionel Sambuc   }
700f4a2713aSLionel Sambuc   TypeSpecType = T;
701f4a2713aSLionel Sambuc   TypeSpecOwned = false;
702f4a2713aSLionel Sambuc   return false;
703f4a2713aSLionel Sambuc }
704f4a2713aSLionel Sambuc 
SetTypeAltiVecVector(bool isAltiVecVector,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,const PrintingPolicy & Policy)705f4a2713aSLionel Sambuc bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
706*0a6a1f1dSLionel Sambuc                           const char *&PrevSpec, unsigned &DiagID,
707*0a6a1f1dSLionel Sambuc                           const PrintingPolicy &Policy) {
708f4a2713aSLionel Sambuc   if (TypeSpecType != TST_unspecified) {
709*0a6a1f1dSLionel Sambuc     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
710f4a2713aSLionel Sambuc     DiagID = diag::err_invalid_vector_decl_spec_combination;
711f4a2713aSLionel Sambuc     return true;
712f4a2713aSLionel Sambuc   }
713f4a2713aSLionel Sambuc   TypeAltiVecVector = isAltiVecVector;
714f4a2713aSLionel Sambuc   AltiVecLoc = Loc;
715f4a2713aSLionel Sambuc   return false;
716f4a2713aSLionel Sambuc }
717f4a2713aSLionel Sambuc 
SetTypeAltiVecPixel(bool isAltiVecPixel,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,const PrintingPolicy & Policy)718f4a2713aSLionel Sambuc bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
719*0a6a1f1dSLionel Sambuc                           const char *&PrevSpec, unsigned &DiagID,
720*0a6a1f1dSLionel Sambuc                           const PrintingPolicy &Policy) {
721f4a2713aSLionel Sambuc   if (!TypeAltiVecVector || TypeAltiVecPixel ||
722f4a2713aSLionel Sambuc       (TypeSpecType != TST_unspecified)) {
723*0a6a1f1dSLionel Sambuc     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
724f4a2713aSLionel Sambuc     DiagID = diag::err_invalid_pixel_decl_spec_combination;
725f4a2713aSLionel Sambuc     return true;
726f4a2713aSLionel Sambuc   }
727f4a2713aSLionel Sambuc   TypeAltiVecPixel = isAltiVecPixel;
728f4a2713aSLionel Sambuc   TSTLoc = Loc;
729f4a2713aSLionel Sambuc   TSTNameLoc = Loc;
730f4a2713aSLionel Sambuc   return false;
731f4a2713aSLionel Sambuc }
732f4a2713aSLionel Sambuc 
SetTypeAltiVecBool(bool isAltiVecBool,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,const PrintingPolicy & Policy)733f4a2713aSLionel Sambuc bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
734*0a6a1f1dSLionel Sambuc                                   const char *&PrevSpec, unsigned &DiagID,
735*0a6a1f1dSLionel Sambuc                                   const PrintingPolicy &Policy) {
736f4a2713aSLionel Sambuc   if (!TypeAltiVecVector || TypeAltiVecBool ||
737f4a2713aSLionel Sambuc       (TypeSpecType != TST_unspecified)) {
738*0a6a1f1dSLionel Sambuc     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
739f4a2713aSLionel Sambuc     DiagID = diag::err_invalid_vector_bool_decl_spec;
740f4a2713aSLionel Sambuc     return true;
741f4a2713aSLionel Sambuc   }
742f4a2713aSLionel Sambuc   TypeAltiVecBool = isAltiVecBool;
743f4a2713aSLionel Sambuc   TSTLoc = Loc;
744f4a2713aSLionel Sambuc   TSTNameLoc = Loc;
745f4a2713aSLionel Sambuc   return false;
746f4a2713aSLionel Sambuc }
747f4a2713aSLionel Sambuc 
SetTypeSpecError()748f4a2713aSLionel Sambuc bool DeclSpec::SetTypeSpecError() {
749f4a2713aSLionel Sambuc   TypeSpecType = TST_error;
750f4a2713aSLionel Sambuc   TypeSpecOwned = false;
751f4a2713aSLionel Sambuc   TSTLoc = SourceLocation();
752f4a2713aSLionel Sambuc   TSTNameLoc = SourceLocation();
753f4a2713aSLionel Sambuc   return false;
754f4a2713aSLionel Sambuc }
755f4a2713aSLionel Sambuc 
SetTypeQual(TQ T,SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID,const LangOptions & Lang)756f4a2713aSLionel Sambuc bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
757f4a2713aSLionel Sambuc                            unsigned &DiagID, const LangOptions &Lang) {
758f4a2713aSLionel Sambuc   // Duplicates are permitted in C99 onwards, but are not permitted in C89 or
759f4a2713aSLionel Sambuc   // C++.  However, since this is likely not what the user intended, we will
760f4a2713aSLionel Sambuc   // always warn.  We do not need to set the qualifier's location since we
761f4a2713aSLionel Sambuc   // already have it.
762f4a2713aSLionel Sambuc   if (TypeQualifiers & T) {
763f4a2713aSLionel Sambuc     bool IsExtension = true;
764f4a2713aSLionel Sambuc     if (Lang.C99)
765f4a2713aSLionel Sambuc       IsExtension = false;
766f4a2713aSLionel Sambuc     return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
767f4a2713aSLionel Sambuc   }
768f4a2713aSLionel Sambuc   TypeQualifiers |= T;
769f4a2713aSLionel Sambuc 
770f4a2713aSLionel Sambuc   switch (T) {
771f4a2713aSLionel Sambuc   case TQ_unspecified: break;
772f4a2713aSLionel Sambuc   case TQ_const:    TQ_constLoc = Loc; return false;
773f4a2713aSLionel Sambuc   case TQ_restrict: TQ_restrictLoc = Loc; return false;
774f4a2713aSLionel Sambuc   case TQ_volatile: TQ_volatileLoc = Loc; return false;
775f4a2713aSLionel Sambuc   case TQ_atomic:   TQ_atomicLoc = Loc; return false;
776f4a2713aSLionel Sambuc   }
777f4a2713aSLionel Sambuc 
778f4a2713aSLionel Sambuc   llvm_unreachable("Unknown type qualifier!");
779f4a2713aSLionel Sambuc }
780f4a2713aSLionel Sambuc 
setFunctionSpecInline(SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)781f4a2713aSLionel Sambuc bool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
782f4a2713aSLionel Sambuc                                      unsigned &DiagID) {
783f4a2713aSLionel Sambuc   // 'inline inline' is ok.  However, since this is likely not what the user
784f4a2713aSLionel Sambuc   // intended, we will always warn, similar to duplicates of type qualifiers.
785f4a2713aSLionel Sambuc   if (FS_inline_specified) {
786f4a2713aSLionel Sambuc     DiagID = diag::warn_duplicate_declspec;
787f4a2713aSLionel Sambuc     PrevSpec = "inline";
788f4a2713aSLionel Sambuc     return true;
789f4a2713aSLionel Sambuc   }
790f4a2713aSLionel Sambuc   FS_inline_specified = true;
791f4a2713aSLionel Sambuc   FS_inlineLoc = Loc;
792f4a2713aSLionel Sambuc   return false;
793f4a2713aSLionel Sambuc }
794f4a2713aSLionel Sambuc 
setFunctionSpecForceInline(SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)795f4a2713aSLionel Sambuc bool DeclSpec::setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec,
796f4a2713aSLionel Sambuc                                           unsigned &DiagID) {
797f4a2713aSLionel Sambuc   if (FS_forceinline_specified) {
798f4a2713aSLionel Sambuc     DiagID = diag::warn_duplicate_declspec;
799f4a2713aSLionel Sambuc     PrevSpec = "__forceinline";
800f4a2713aSLionel Sambuc     return true;
801f4a2713aSLionel Sambuc   }
802f4a2713aSLionel Sambuc   FS_forceinline_specified = true;
803f4a2713aSLionel Sambuc   FS_forceinlineLoc = Loc;
804f4a2713aSLionel Sambuc   return false;
805f4a2713aSLionel Sambuc }
806f4a2713aSLionel Sambuc 
setFunctionSpecVirtual(SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)807f4a2713aSLionel Sambuc bool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc,
808f4a2713aSLionel Sambuc                                       const char *&PrevSpec,
809f4a2713aSLionel Sambuc                                       unsigned &DiagID) {
810f4a2713aSLionel Sambuc   // 'virtual virtual' is ok, but warn as this is likely not what the user
811f4a2713aSLionel Sambuc   // intended.
812f4a2713aSLionel Sambuc   if (FS_virtual_specified) {
813f4a2713aSLionel Sambuc     DiagID = diag::warn_duplicate_declspec;
814f4a2713aSLionel Sambuc     PrevSpec = "virtual";
815f4a2713aSLionel Sambuc     return true;
816f4a2713aSLionel Sambuc   }
817f4a2713aSLionel Sambuc   FS_virtual_specified = true;
818f4a2713aSLionel Sambuc   FS_virtualLoc = Loc;
819f4a2713aSLionel Sambuc   return false;
820f4a2713aSLionel Sambuc }
821f4a2713aSLionel Sambuc 
setFunctionSpecExplicit(SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)822f4a2713aSLionel Sambuc bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc,
823f4a2713aSLionel Sambuc                                        const char *&PrevSpec,
824f4a2713aSLionel Sambuc                                        unsigned &DiagID) {
825f4a2713aSLionel Sambuc   // 'explicit explicit' is ok, but warn as this is likely not what the user
826f4a2713aSLionel Sambuc   // intended.
827f4a2713aSLionel Sambuc   if (FS_explicit_specified) {
828f4a2713aSLionel Sambuc     DiagID = diag::warn_duplicate_declspec;
829f4a2713aSLionel Sambuc     PrevSpec = "explicit";
830f4a2713aSLionel Sambuc     return true;
831f4a2713aSLionel Sambuc   }
832f4a2713aSLionel Sambuc   FS_explicit_specified = true;
833f4a2713aSLionel Sambuc   FS_explicitLoc = Loc;
834f4a2713aSLionel Sambuc   return false;
835f4a2713aSLionel Sambuc }
836f4a2713aSLionel Sambuc 
setFunctionSpecNoreturn(SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)837f4a2713aSLionel Sambuc bool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc,
838f4a2713aSLionel Sambuc                                        const char *&PrevSpec,
839f4a2713aSLionel Sambuc                                        unsigned &DiagID) {
840f4a2713aSLionel Sambuc   // '_Noreturn _Noreturn' is ok, but warn as this is likely not what the user
841f4a2713aSLionel Sambuc   // intended.
842f4a2713aSLionel Sambuc   if (FS_noreturn_specified) {
843f4a2713aSLionel Sambuc     DiagID = diag::warn_duplicate_declspec;
844f4a2713aSLionel Sambuc     PrevSpec = "_Noreturn";
845f4a2713aSLionel Sambuc     return true;
846f4a2713aSLionel Sambuc   }
847f4a2713aSLionel Sambuc   FS_noreturn_specified = true;
848f4a2713aSLionel Sambuc   FS_noreturnLoc = Loc;
849f4a2713aSLionel Sambuc   return false;
850f4a2713aSLionel Sambuc }
851f4a2713aSLionel Sambuc 
SetFriendSpec(SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)852f4a2713aSLionel Sambuc bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
853f4a2713aSLionel Sambuc                              unsigned &DiagID) {
854f4a2713aSLionel Sambuc   if (Friend_specified) {
855f4a2713aSLionel Sambuc     PrevSpec = "friend";
856*0a6a1f1dSLionel Sambuc     // Keep the later location, so that we can later diagnose ill-formed
857*0a6a1f1dSLionel Sambuc     // declarations like 'friend class X friend;'. Per [class.friend]p3,
858*0a6a1f1dSLionel Sambuc     // 'friend' must be the first token in a friend declaration that is
859*0a6a1f1dSLionel Sambuc     // not a function declaration.
860*0a6a1f1dSLionel Sambuc     FriendLoc = Loc;
861*0a6a1f1dSLionel Sambuc     DiagID = diag::warn_duplicate_declspec;
862f4a2713aSLionel Sambuc     return true;
863f4a2713aSLionel Sambuc   }
864f4a2713aSLionel Sambuc 
865f4a2713aSLionel Sambuc   Friend_specified = true;
866f4a2713aSLionel Sambuc   FriendLoc = Loc;
867f4a2713aSLionel Sambuc   return false;
868f4a2713aSLionel Sambuc }
869f4a2713aSLionel Sambuc 
setModulePrivateSpec(SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)870f4a2713aSLionel Sambuc bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
871f4a2713aSLionel Sambuc                                     unsigned &DiagID) {
872f4a2713aSLionel Sambuc   if (isModulePrivateSpecified()) {
873f4a2713aSLionel Sambuc     PrevSpec = "__module_private__";
874f4a2713aSLionel Sambuc     DiagID = diag::ext_duplicate_declspec;
875f4a2713aSLionel Sambuc     return true;
876f4a2713aSLionel Sambuc   }
877f4a2713aSLionel Sambuc 
878f4a2713aSLionel Sambuc   ModulePrivateLoc = Loc;
879f4a2713aSLionel Sambuc   return false;
880f4a2713aSLionel Sambuc }
881f4a2713aSLionel Sambuc 
SetConstexprSpec(SourceLocation Loc,const char * & PrevSpec,unsigned & DiagID)882f4a2713aSLionel Sambuc bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
883f4a2713aSLionel Sambuc                                 unsigned &DiagID) {
884*0a6a1f1dSLionel Sambuc   // 'constexpr constexpr' is ok, but warn as this is likely not what the user
885*0a6a1f1dSLionel Sambuc   // intended.
886*0a6a1f1dSLionel Sambuc   if (Constexpr_specified) {
887*0a6a1f1dSLionel Sambuc     DiagID = diag::warn_duplicate_declspec;
888*0a6a1f1dSLionel Sambuc     PrevSpec = "constexpr";
889*0a6a1f1dSLionel Sambuc     return true;
890*0a6a1f1dSLionel Sambuc   }
891f4a2713aSLionel Sambuc   Constexpr_specified = true;
892f4a2713aSLionel Sambuc   ConstexprLoc = Loc;
893f4a2713aSLionel Sambuc   return false;
894f4a2713aSLionel Sambuc }
895f4a2713aSLionel Sambuc 
setProtocolQualifiers(Decl * const * Protos,unsigned NP,SourceLocation * ProtoLocs,SourceLocation LAngleLoc)896f4a2713aSLionel Sambuc void DeclSpec::setProtocolQualifiers(Decl * const *Protos,
897f4a2713aSLionel Sambuc                                      unsigned NP,
898f4a2713aSLionel Sambuc                                      SourceLocation *ProtoLocs,
899f4a2713aSLionel Sambuc                                      SourceLocation LAngleLoc) {
900f4a2713aSLionel Sambuc   if (NP == 0) return;
901f4a2713aSLionel Sambuc   Decl **ProtoQuals = new Decl*[NP];
902f4a2713aSLionel Sambuc   memcpy(ProtoQuals, Protos, sizeof(Decl*)*NP);
903f4a2713aSLionel Sambuc   ProtocolQualifiers = ProtoQuals;
904f4a2713aSLionel Sambuc   ProtocolLocs = new SourceLocation[NP];
905f4a2713aSLionel Sambuc   memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
906f4a2713aSLionel Sambuc   NumProtocolQualifiers = NP;
907f4a2713aSLionel Sambuc   ProtocolLAngleLoc = LAngleLoc;
908f4a2713aSLionel Sambuc }
909f4a2713aSLionel Sambuc 
SaveWrittenBuiltinSpecs()910f4a2713aSLionel Sambuc void DeclSpec::SaveWrittenBuiltinSpecs() {
911f4a2713aSLionel Sambuc   writtenBS.Sign = getTypeSpecSign();
912f4a2713aSLionel Sambuc   writtenBS.Width = getTypeSpecWidth();
913f4a2713aSLionel Sambuc   writtenBS.Type = getTypeSpecType();
914f4a2713aSLionel Sambuc   // Search the list of attributes for the presence of a mode attribute.
915f4a2713aSLionel Sambuc   writtenBS.ModeAttr = false;
916f4a2713aSLionel Sambuc   AttributeList* attrs = getAttributes().getList();
917f4a2713aSLionel Sambuc   while (attrs) {
918f4a2713aSLionel Sambuc     if (attrs->getKind() == AttributeList::AT_Mode) {
919f4a2713aSLionel Sambuc       writtenBS.ModeAttr = true;
920f4a2713aSLionel Sambuc       break;
921f4a2713aSLionel Sambuc     }
922f4a2713aSLionel Sambuc     attrs = attrs->getNext();
923f4a2713aSLionel Sambuc   }
924f4a2713aSLionel Sambuc }
925f4a2713aSLionel Sambuc 
926f4a2713aSLionel Sambuc /// Finish - This does final analysis of the declspec, rejecting things like
927f4a2713aSLionel Sambuc /// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
928f4a2713aSLionel Sambuc /// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
929f4a2713aSLionel Sambuc /// DeclSpec is guaranteed self-consistent, even if an error occurred.
Finish(DiagnosticsEngine & D,Preprocessor & PP,const PrintingPolicy & Policy)930*0a6a1f1dSLionel Sambuc void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPolicy &Policy) {
931f4a2713aSLionel Sambuc   // Before possibly changing their values, save specs as written.
932f4a2713aSLionel Sambuc   SaveWrittenBuiltinSpecs();
933f4a2713aSLionel Sambuc 
934f4a2713aSLionel Sambuc   // Check the type specifier components first.
935f4a2713aSLionel Sambuc 
936f4a2713aSLionel Sambuc   // If decltype(auto) is used, no other type specifiers are permitted.
937f4a2713aSLionel Sambuc   if (TypeSpecType == TST_decltype_auto &&
938f4a2713aSLionel Sambuc       (TypeSpecWidth != TSW_unspecified ||
939f4a2713aSLionel Sambuc        TypeSpecComplex != TSC_unspecified ||
940f4a2713aSLionel Sambuc        TypeSpecSign != TSS_unspecified ||
941f4a2713aSLionel Sambuc        TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool ||
942f4a2713aSLionel Sambuc        TypeQualifiers)) {
943f4a2713aSLionel Sambuc     const unsigned NumLocs = 8;
944f4a2713aSLionel Sambuc     SourceLocation ExtraLocs[NumLocs] = {
945f4a2713aSLionel Sambuc       TSWLoc, TSCLoc, TSSLoc, AltiVecLoc,
946f4a2713aSLionel Sambuc       TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc
947f4a2713aSLionel Sambuc     };
948f4a2713aSLionel Sambuc     FixItHint Hints[NumLocs];
949f4a2713aSLionel Sambuc     SourceLocation FirstLoc;
950f4a2713aSLionel Sambuc     for (unsigned I = 0; I != NumLocs; ++I) {
951f4a2713aSLionel Sambuc       if (!ExtraLocs[I].isInvalid()) {
952f4a2713aSLionel Sambuc         if (FirstLoc.isInvalid() ||
953f4a2713aSLionel Sambuc             PP.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I],
954f4a2713aSLionel Sambuc                                                             FirstLoc))
955f4a2713aSLionel Sambuc           FirstLoc = ExtraLocs[I];
956f4a2713aSLionel Sambuc         Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]);
957f4a2713aSLionel Sambuc       }
958f4a2713aSLionel Sambuc     }
959f4a2713aSLionel Sambuc     TypeSpecWidth = TSW_unspecified;
960f4a2713aSLionel Sambuc     TypeSpecComplex = TSC_unspecified;
961f4a2713aSLionel Sambuc     TypeSpecSign = TSS_unspecified;
962f4a2713aSLionel Sambuc     TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false;
963f4a2713aSLionel Sambuc     TypeQualifiers = 0;
964f4a2713aSLionel Sambuc     Diag(D, TSTLoc, diag::err_decltype_auto_cannot_be_combined)
965f4a2713aSLionel Sambuc       << Hints[0] << Hints[1] << Hints[2] << Hints[3]
966f4a2713aSLionel Sambuc       << Hints[4] << Hints[5] << Hints[6] << Hints[7];
967f4a2713aSLionel Sambuc   }
968f4a2713aSLionel Sambuc 
969f4a2713aSLionel Sambuc   // Validate and finalize AltiVec vector declspec.
970f4a2713aSLionel Sambuc   if (TypeAltiVecVector) {
971f4a2713aSLionel Sambuc     if (TypeAltiVecBool) {
972f4a2713aSLionel Sambuc       // Sign specifiers are not allowed with vector bool. (PIM 2.1)
973f4a2713aSLionel Sambuc       if (TypeSpecSign != TSS_unspecified) {
974f4a2713aSLionel Sambuc         Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
975f4a2713aSLionel Sambuc           << getSpecifierName((TSS)TypeSpecSign);
976f4a2713aSLionel Sambuc       }
977f4a2713aSLionel Sambuc 
978f4a2713aSLionel Sambuc       // Only char/int are valid with vector bool. (PIM 2.1)
979f4a2713aSLionel Sambuc       if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
980f4a2713aSLionel Sambuc            (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
981f4a2713aSLionel Sambuc         Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
982f4a2713aSLionel Sambuc           << (TypeAltiVecPixel ? "__pixel" :
983*0a6a1f1dSLionel Sambuc                                  getSpecifierName((TST)TypeSpecType, Policy));
984f4a2713aSLionel Sambuc       }
985f4a2713aSLionel Sambuc 
986f4a2713aSLionel Sambuc       // Only 'short' is valid with vector bool. (PIM 2.1)
987f4a2713aSLionel Sambuc       if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
988f4a2713aSLionel Sambuc         Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
989f4a2713aSLionel Sambuc           << getSpecifierName((TSW)TypeSpecWidth);
990f4a2713aSLionel Sambuc 
991f4a2713aSLionel Sambuc       // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
992f4a2713aSLionel Sambuc       if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
993f4a2713aSLionel Sambuc           (TypeSpecWidth != TSW_unspecified))
994f4a2713aSLionel Sambuc         TypeSpecSign = TSS_unsigned;
995*0a6a1f1dSLionel Sambuc     } else if (TypeSpecType == TST_double) {
996*0a6a1f1dSLionel Sambuc       // vector long double and vector long long double are never allowed.
997*0a6a1f1dSLionel Sambuc       // vector double is OK for Power7 and later.
998*0a6a1f1dSLionel Sambuc       if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong)
999*0a6a1f1dSLionel Sambuc         Diag(D, TSWLoc, diag::err_invalid_vector_long_double_decl_spec);
1000*0a6a1f1dSLionel Sambuc       else if (!PP.getTargetInfo().hasFeature("vsx"))
1001*0a6a1f1dSLionel Sambuc         Diag(D, TSTLoc, diag::err_invalid_vector_double_decl_spec);
1002*0a6a1f1dSLionel Sambuc     } else if (TypeSpecWidth == TSW_long) {
1003*0a6a1f1dSLionel Sambuc       Diag(D, TSWLoc, diag::warn_vector_long_decl_spec_combination)
1004*0a6a1f1dSLionel Sambuc         << getSpecifierName((TST)TypeSpecType, Policy);
1005f4a2713aSLionel Sambuc     }
1006f4a2713aSLionel Sambuc 
1007f4a2713aSLionel Sambuc     if (TypeAltiVecPixel) {
1008f4a2713aSLionel Sambuc       //TODO: perform validation
1009f4a2713aSLionel Sambuc       TypeSpecType = TST_int;
1010f4a2713aSLionel Sambuc       TypeSpecSign = TSS_unsigned;
1011f4a2713aSLionel Sambuc       TypeSpecWidth = TSW_short;
1012f4a2713aSLionel Sambuc       TypeSpecOwned = false;
1013f4a2713aSLionel Sambuc     }
1014f4a2713aSLionel Sambuc   }
1015f4a2713aSLionel Sambuc 
1016f4a2713aSLionel Sambuc   // signed/unsigned are only valid with int/char/wchar_t.
1017f4a2713aSLionel Sambuc   if (TypeSpecSign != TSS_unspecified) {
1018f4a2713aSLionel Sambuc     if (TypeSpecType == TST_unspecified)
1019f4a2713aSLionel Sambuc       TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
1020f4a2713aSLionel Sambuc     else if (TypeSpecType != TST_int  && TypeSpecType != TST_int128 &&
1021f4a2713aSLionel Sambuc              TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
1022f4a2713aSLionel Sambuc       Diag(D, TSSLoc, diag::err_invalid_sign_spec)
1023*0a6a1f1dSLionel Sambuc         << getSpecifierName((TST)TypeSpecType, Policy);
1024f4a2713aSLionel Sambuc       // signed double -> double.
1025f4a2713aSLionel Sambuc       TypeSpecSign = TSS_unspecified;
1026f4a2713aSLionel Sambuc     }
1027f4a2713aSLionel Sambuc   }
1028f4a2713aSLionel Sambuc 
1029f4a2713aSLionel Sambuc   // Validate the width of the type.
1030f4a2713aSLionel Sambuc   switch (TypeSpecWidth) {
1031f4a2713aSLionel Sambuc   case TSW_unspecified: break;
1032f4a2713aSLionel Sambuc   case TSW_short:    // short int
1033f4a2713aSLionel Sambuc   case TSW_longlong: // long long int
1034f4a2713aSLionel Sambuc     if (TypeSpecType == TST_unspecified)
1035f4a2713aSLionel Sambuc       TypeSpecType = TST_int; // short -> short int, long long -> long long int.
1036f4a2713aSLionel Sambuc     else if (TypeSpecType != TST_int) {
1037f4a2713aSLionel Sambuc       Diag(D, TSWLoc,
1038f4a2713aSLionel Sambuc            TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
1039f4a2713aSLionel Sambuc                                       : diag::err_invalid_longlong_spec)
1040*0a6a1f1dSLionel Sambuc         <<  getSpecifierName((TST)TypeSpecType, Policy);
1041f4a2713aSLionel Sambuc       TypeSpecType = TST_int;
1042f4a2713aSLionel Sambuc       TypeSpecOwned = false;
1043f4a2713aSLionel Sambuc     }
1044f4a2713aSLionel Sambuc     break;
1045f4a2713aSLionel Sambuc   case TSW_long:  // long double, long int
1046f4a2713aSLionel Sambuc     if (TypeSpecType == TST_unspecified)
1047f4a2713aSLionel Sambuc       TypeSpecType = TST_int;  // long -> long int.
1048f4a2713aSLionel Sambuc     else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
1049f4a2713aSLionel Sambuc       Diag(D, TSWLoc, diag::err_invalid_long_spec)
1050*0a6a1f1dSLionel Sambuc         << getSpecifierName((TST)TypeSpecType, Policy);
1051f4a2713aSLionel Sambuc       TypeSpecType = TST_int;
1052f4a2713aSLionel Sambuc       TypeSpecOwned = false;
1053f4a2713aSLionel Sambuc     }
1054f4a2713aSLionel Sambuc     break;
1055f4a2713aSLionel Sambuc   }
1056f4a2713aSLionel Sambuc 
1057f4a2713aSLionel Sambuc   // TODO: if the implementation does not implement _Complex or _Imaginary,
1058f4a2713aSLionel Sambuc   // disallow their use.  Need information about the backend.
1059f4a2713aSLionel Sambuc   if (TypeSpecComplex != TSC_unspecified) {
1060f4a2713aSLionel Sambuc     if (TypeSpecType == TST_unspecified) {
1061f4a2713aSLionel Sambuc       Diag(D, TSCLoc, diag::ext_plain_complex)
1062f4a2713aSLionel Sambuc         << FixItHint::CreateInsertion(
1063f4a2713aSLionel Sambuc                               PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
1064f4a2713aSLionel Sambuc                                                  " double");
1065f4a2713aSLionel Sambuc       TypeSpecType = TST_double;   // _Complex -> _Complex double.
1066f4a2713aSLionel Sambuc     } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
1067f4a2713aSLionel Sambuc       // Note that this intentionally doesn't include _Complex _Bool.
1068f4a2713aSLionel Sambuc       if (!PP.getLangOpts().CPlusPlus)
1069f4a2713aSLionel Sambuc         Diag(D, TSTLoc, diag::ext_integer_complex);
1070f4a2713aSLionel Sambuc     } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
1071f4a2713aSLionel Sambuc       Diag(D, TSCLoc, diag::err_invalid_complex_spec)
1072*0a6a1f1dSLionel Sambuc         << getSpecifierName((TST)TypeSpecType, Policy);
1073f4a2713aSLionel Sambuc       TypeSpecComplex = TSC_unspecified;
1074f4a2713aSLionel Sambuc     }
1075f4a2713aSLionel Sambuc   }
1076f4a2713aSLionel Sambuc 
1077f4a2713aSLionel Sambuc   // C11 6.7.1/3, C++11 [dcl.stc]p1, GNU TLS: __thread, thread_local and
1078f4a2713aSLionel Sambuc   // _Thread_local can only appear with the 'static' and 'extern' storage class
1079f4a2713aSLionel Sambuc   // specifiers. We also allow __private_extern__ as an extension.
1080f4a2713aSLionel Sambuc   if (ThreadStorageClassSpec != TSCS_unspecified) {
1081f4a2713aSLionel Sambuc     switch (StorageClassSpec) {
1082f4a2713aSLionel Sambuc     case SCS_unspecified:
1083f4a2713aSLionel Sambuc     case SCS_extern:
1084f4a2713aSLionel Sambuc     case SCS_private_extern:
1085f4a2713aSLionel Sambuc     case SCS_static:
1086f4a2713aSLionel Sambuc       break;
1087f4a2713aSLionel Sambuc     default:
1088f4a2713aSLionel Sambuc       if (PP.getSourceManager().isBeforeInTranslationUnit(
1089f4a2713aSLionel Sambuc             getThreadStorageClassSpecLoc(), getStorageClassSpecLoc()))
1090f4a2713aSLionel Sambuc         Diag(D, getStorageClassSpecLoc(),
1091f4a2713aSLionel Sambuc              diag::err_invalid_decl_spec_combination)
1092f4a2713aSLionel Sambuc           << DeclSpec::getSpecifierName(getThreadStorageClassSpec())
1093f4a2713aSLionel Sambuc           << SourceRange(getThreadStorageClassSpecLoc());
1094f4a2713aSLionel Sambuc       else
1095f4a2713aSLionel Sambuc         Diag(D, getThreadStorageClassSpecLoc(),
1096f4a2713aSLionel Sambuc              diag::err_invalid_decl_spec_combination)
1097f4a2713aSLionel Sambuc           << DeclSpec::getSpecifierName(getStorageClassSpec())
1098f4a2713aSLionel Sambuc           << SourceRange(getStorageClassSpecLoc());
1099f4a2713aSLionel Sambuc       // Discard the thread storage class specifier to recover.
1100f4a2713aSLionel Sambuc       ThreadStorageClassSpec = TSCS_unspecified;
1101f4a2713aSLionel Sambuc       ThreadStorageClassSpecLoc = SourceLocation();
1102f4a2713aSLionel Sambuc     }
1103f4a2713aSLionel Sambuc   }
1104f4a2713aSLionel Sambuc 
1105f4a2713aSLionel Sambuc   // If no type specifier was provided and we're parsing a language where
1106f4a2713aSLionel Sambuc   // the type specifier is not optional, but we got 'auto' as a storage
1107f4a2713aSLionel Sambuc   // class specifier, then assume this is an attempt to use C++0x's 'auto'
1108f4a2713aSLionel Sambuc   // type specifier.
1109f4a2713aSLionel Sambuc   if (PP.getLangOpts().CPlusPlus &&
1110f4a2713aSLionel Sambuc       TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
1111f4a2713aSLionel Sambuc     TypeSpecType = TST_auto;
1112f4a2713aSLionel Sambuc     StorageClassSpec = SCS_unspecified;
1113f4a2713aSLionel Sambuc     TSTLoc = TSTNameLoc = StorageClassSpecLoc;
1114f4a2713aSLionel Sambuc     StorageClassSpecLoc = SourceLocation();
1115f4a2713aSLionel Sambuc   }
1116f4a2713aSLionel Sambuc   // Diagnose if we've recovered from an ill-formed 'auto' storage class
1117f4a2713aSLionel Sambuc   // specifier in a pre-C++11 dialect of C++.
1118f4a2713aSLionel Sambuc   if (!PP.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto)
1119f4a2713aSLionel Sambuc     Diag(D, TSTLoc, diag::ext_auto_type_specifier);
1120f4a2713aSLionel Sambuc   if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus11 &&
1121f4a2713aSLionel Sambuc       StorageClassSpec == SCS_auto)
1122f4a2713aSLionel Sambuc     Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
1123f4a2713aSLionel Sambuc       << FixItHint::CreateRemoval(StorageClassSpecLoc);
1124f4a2713aSLionel Sambuc   if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
1125f4a2713aSLionel Sambuc     Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
1126f4a2713aSLionel Sambuc       << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
1127f4a2713aSLionel Sambuc   if (Constexpr_specified)
1128f4a2713aSLionel Sambuc     Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
1129f4a2713aSLionel Sambuc 
1130f4a2713aSLionel Sambuc   // C++ [class.friend]p6:
1131f4a2713aSLionel Sambuc   //   No storage-class-specifier shall appear in the decl-specifier-seq
1132f4a2713aSLionel Sambuc   //   of a friend declaration.
1133f4a2713aSLionel Sambuc   if (isFriendSpecified() &&
1134f4a2713aSLionel Sambuc       (getStorageClassSpec() || getThreadStorageClassSpec())) {
1135f4a2713aSLionel Sambuc     SmallString<32> SpecName;
1136f4a2713aSLionel Sambuc     SourceLocation SCLoc;
1137f4a2713aSLionel Sambuc     FixItHint StorageHint, ThreadHint;
1138f4a2713aSLionel Sambuc 
1139f4a2713aSLionel Sambuc     if (DeclSpec::SCS SC = getStorageClassSpec()) {
1140f4a2713aSLionel Sambuc       SpecName = getSpecifierName(SC);
1141f4a2713aSLionel Sambuc       SCLoc = getStorageClassSpecLoc();
1142f4a2713aSLionel Sambuc       StorageHint = FixItHint::CreateRemoval(SCLoc);
1143f4a2713aSLionel Sambuc     }
1144f4a2713aSLionel Sambuc 
1145f4a2713aSLionel Sambuc     if (DeclSpec::TSCS TSC = getThreadStorageClassSpec()) {
1146f4a2713aSLionel Sambuc       if (!SpecName.empty()) SpecName += " ";
1147f4a2713aSLionel Sambuc       SpecName += getSpecifierName(TSC);
1148f4a2713aSLionel Sambuc       SCLoc = getThreadStorageClassSpecLoc();
1149f4a2713aSLionel Sambuc       ThreadHint = FixItHint::CreateRemoval(SCLoc);
1150f4a2713aSLionel Sambuc     }
1151f4a2713aSLionel Sambuc 
1152*0a6a1f1dSLionel Sambuc     Diag(D, SCLoc, diag::err_friend_decl_spec)
1153f4a2713aSLionel Sambuc       << SpecName << StorageHint << ThreadHint;
1154f4a2713aSLionel Sambuc 
1155f4a2713aSLionel Sambuc     ClearStorageClassSpecs();
1156f4a2713aSLionel Sambuc   }
1157f4a2713aSLionel Sambuc 
1158*0a6a1f1dSLionel Sambuc   // C++11 [dcl.fct.spec]p5:
1159*0a6a1f1dSLionel Sambuc   //   The virtual specifier shall be used only in the initial
1160*0a6a1f1dSLionel Sambuc   //   declaration of a non-static class member function;
1161*0a6a1f1dSLionel Sambuc   // C++11 [dcl.fct.spec]p6:
1162*0a6a1f1dSLionel Sambuc   //   The explicit specifier shall be used only in the declaration of
1163*0a6a1f1dSLionel Sambuc   //   a constructor or conversion function within its class
1164*0a6a1f1dSLionel Sambuc   //   definition;
1165*0a6a1f1dSLionel Sambuc   if (isFriendSpecified() && (isVirtualSpecified() || isExplicitSpecified())) {
1166*0a6a1f1dSLionel Sambuc     StringRef Keyword;
1167*0a6a1f1dSLionel Sambuc     SourceLocation SCLoc;
1168*0a6a1f1dSLionel Sambuc 
1169*0a6a1f1dSLionel Sambuc     if (isVirtualSpecified()) {
1170*0a6a1f1dSLionel Sambuc       Keyword = "virtual";
1171*0a6a1f1dSLionel Sambuc       SCLoc = getVirtualSpecLoc();
1172*0a6a1f1dSLionel Sambuc     } else {
1173*0a6a1f1dSLionel Sambuc       Keyword = "explicit";
1174*0a6a1f1dSLionel Sambuc       SCLoc = getExplicitSpecLoc();
1175*0a6a1f1dSLionel Sambuc     }
1176*0a6a1f1dSLionel Sambuc 
1177*0a6a1f1dSLionel Sambuc     FixItHint Hint = FixItHint::CreateRemoval(SCLoc);
1178*0a6a1f1dSLionel Sambuc     Diag(D, SCLoc, diag::err_friend_decl_spec)
1179*0a6a1f1dSLionel Sambuc       << Keyword << Hint;
1180*0a6a1f1dSLionel Sambuc 
1181*0a6a1f1dSLionel Sambuc     FS_virtual_specified = FS_explicit_specified = false;
1182*0a6a1f1dSLionel Sambuc     FS_virtualLoc = FS_explicitLoc = SourceLocation();
1183*0a6a1f1dSLionel Sambuc   }
1184*0a6a1f1dSLionel Sambuc 
1185f4a2713aSLionel Sambuc   assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
1186f4a2713aSLionel Sambuc 
1187f4a2713aSLionel Sambuc   // Okay, now we can infer the real type.
1188f4a2713aSLionel Sambuc 
1189f4a2713aSLionel Sambuc   // TODO: return "auto function" and other bad things based on the real type.
1190f4a2713aSLionel Sambuc 
1191f4a2713aSLionel Sambuc   // 'data definition has no type or storage class'?
1192f4a2713aSLionel Sambuc }
1193f4a2713aSLionel Sambuc 
isMissingDeclaratorOk()1194f4a2713aSLionel Sambuc bool DeclSpec::isMissingDeclaratorOk() {
1195f4a2713aSLionel Sambuc   TST tst = getTypeSpecType();
1196*0a6a1f1dSLionel Sambuc   return isDeclRep(tst) && getRepAsDecl() != nullptr &&
1197f4a2713aSLionel Sambuc     StorageClassSpec != DeclSpec::SCS_typedef;
1198f4a2713aSLionel Sambuc }
1199f4a2713aSLionel Sambuc 
setOperatorFunctionId(SourceLocation OperatorLoc,OverloadedOperatorKind Op,SourceLocation SymbolLocations[3])1200f4a2713aSLionel Sambuc void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
1201f4a2713aSLionel Sambuc                                           OverloadedOperatorKind Op,
1202f4a2713aSLionel Sambuc                                           SourceLocation SymbolLocations[3]) {
1203f4a2713aSLionel Sambuc   Kind = IK_OperatorFunctionId;
1204f4a2713aSLionel Sambuc   StartLocation = OperatorLoc;
1205f4a2713aSLionel Sambuc   EndLocation = OperatorLoc;
1206f4a2713aSLionel Sambuc   OperatorFunctionId.Operator = Op;
1207f4a2713aSLionel Sambuc   for (unsigned I = 0; I != 3; ++I) {
1208f4a2713aSLionel Sambuc     OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
1209f4a2713aSLionel Sambuc 
1210f4a2713aSLionel Sambuc     if (SymbolLocations[I].isValid())
1211f4a2713aSLionel Sambuc       EndLocation = SymbolLocations[I];
1212f4a2713aSLionel Sambuc   }
1213f4a2713aSLionel Sambuc }
1214f4a2713aSLionel Sambuc 
SetSpecifier(Specifier VS,SourceLocation Loc,const char * & PrevSpec)1215f4a2713aSLionel Sambuc bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
1216f4a2713aSLionel Sambuc                                   const char *&PrevSpec) {
1217f4a2713aSLionel Sambuc   LastLocation = Loc;
1218f4a2713aSLionel Sambuc 
1219f4a2713aSLionel Sambuc   if (Specifiers & VS) {
1220f4a2713aSLionel Sambuc     PrevSpec = getSpecifierName(VS);
1221f4a2713aSLionel Sambuc     return true;
1222f4a2713aSLionel Sambuc   }
1223f4a2713aSLionel Sambuc 
1224f4a2713aSLionel Sambuc   Specifiers |= VS;
1225f4a2713aSLionel Sambuc 
1226f4a2713aSLionel Sambuc   switch (VS) {
1227f4a2713aSLionel Sambuc   default: llvm_unreachable("Unknown specifier!");
1228f4a2713aSLionel Sambuc   case VS_Override: VS_overrideLoc = Loc; break;
1229f4a2713aSLionel Sambuc   case VS_Sealed:
1230f4a2713aSLionel Sambuc   case VS_Final:    VS_finalLoc = Loc; break;
1231f4a2713aSLionel Sambuc   }
1232f4a2713aSLionel Sambuc 
1233f4a2713aSLionel Sambuc   return false;
1234f4a2713aSLionel Sambuc }
1235f4a2713aSLionel Sambuc 
getSpecifierName(Specifier VS)1236f4a2713aSLionel Sambuc const char *VirtSpecifiers::getSpecifierName(Specifier VS) {
1237f4a2713aSLionel Sambuc   switch (VS) {
1238f4a2713aSLionel Sambuc   default: llvm_unreachable("Unknown specifier");
1239f4a2713aSLionel Sambuc   case VS_Override: return "override";
1240f4a2713aSLionel Sambuc   case VS_Final: return "final";
1241f4a2713aSLionel Sambuc   case VS_Sealed: return "sealed";
1242f4a2713aSLionel Sambuc   }
1243f4a2713aSLionel Sambuc }
1244