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