1212795Sdim//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
2212795Sdim//
3212795Sdim//                     The LLVM Compiler Infrastructure
4212795Sdim//
5212795Sdim// This file is distributed under the University of Illinois Open Source
6212795Sdim// License. See LICENSE.TXT for details.
7212795Sdim//
8212795Sdim//===----------------------------------------------------------------------===//
9212795Sdim//
10212795Sdim//  This file implements semantic analysis for declaration specifiers.
11212795Sdim//
12212795Sdim//===----------------------------------------------------------------------===//
13212795Sdim
14212795Sdim#include "clang/Sema/DeclSpec.h"
15219077Sdim#include "clang/AST/ASTContext.h"
16263508Sdim#include "clang/AST/DeclCXX.h"
17224145Sdim#include "clang/AST/Expr.h"
18219077Sdim#include "clang/AST/NestedNameSpecifier.h"
19219077Sdim#include "clang/AST/TypeLoc.h"
20249423Sdim#include "clang/Basic/LangOptions.h"
21212795Sdim#include "clang/Lex/Preprocessor.h"
22249423Sdim#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
23249423Sdim#include "clang/Sema/LocInfoType.h"
24249423Sdim#include "clang/Sema/ParsedTemplate.h"
25249423Sdim#include "clang/Sema/Sema.h"
26249423Sdim#include "clang/Sema/SemaDiagnostic.h"
27212795Sdim#include "llvm/ADT/STLExtras.h"
28251662Sdim#include "llvm/ADT/SmallString.h"
29212795Sdim#include "llvm/Support/ErrorHandling.h"
30212795Sdim#include <cstring>
31212795Sdimusing namespace clang;
32212795Sdim
33212795Sdim
34226633Sdimstatic DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc,
35218893Sdim                              unsigned DiagID) {
36218893Sdim  return D.Report(Loc, DiagID);
37212795Sdim}
38212795Sdim
39212795Sdim
40212795Sdimvoid UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
41212795Sdim  assert(TemplateId && "NULL template-id annotation?");
42212795Sdim  Kind = IK_TemplateId;
43212795Sdim  this->TemplateId = TemplateId;
44212795Sdim  StartLocation = TemplateId->TemplateNameLoc;
45212795Sdim  EndLocation = TemplateId->RAngleLoc;
46212795Sdim}
47212795Sdim
48212795Sdimvoid UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
49212795Sdim  assert(TemplateId && "NULL template-id annotation?");
50212795Sdim  Kind = IK_ConstructorTemplateId;
51212795Sdim  this->TemplateId = TemplateId;
52212795Sdim  StartLocation = TemplateId->TemplateNameLoc;
53212795Sdim  EndLocation = TemplateId->RAngleLoc;
54212795Sdim}
55212795Sdim
56219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,
57219077Sdim                          TypeLoc TL, SourceLocation ColonColonLoc) {
58221345Sdim  Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);
59219077Sdim  if (Range.getBegin().isInvalid())
60219077Sdim    Range.setBegin(TL.getBeginLoc());
61219077Sdim  Range.setEnd(ColonColonLoc);
62219077Sdim
63221345Sdim  assert(Range == Builder.getSourceRange() &&
64219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
65219077Sdim}
66219077Sdim
67219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
68219077Sdim                          SourceLocation IdentifierLoc,
69219077Sdim                          SourceLocation ColonColonLoc) {
70221345Sdim  Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
71221345Sdim
72219077Sdim  if (Range.getBegin().isInvalid())
73219077Sdim    Range.setBegin(IdentifierLoc);
74219077Sdim  Range.setEnd(ColonColonLoc);
75219077Sdim
76221345Sdim  assert(Range == Builder.getSourceRange() &&
77219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
78219077Sdim}
79219077Sdim
80219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
81219077Sdim                          SourceLocation NamespaceLoc,
82219077Sdim                          SourceLocation ColonColonLoc) {
83221345Sdim  Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
84221345Sdim
85219077Sdim  if (Range.getBegin().isInvalid())
86219077Sdim    Range.setBegin(NamespaceLoc);
87219077Sdim  Range.setEnd(ColonColonLoc);
88219077Sdim
89221345Sdim  assert(Range == Builder.getSourceRange() &&
90219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
91219077Sdim}
92219077Sdim
93219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
94219077Sdim                          SourceLocation AliasLoc,
95219077Sdim                          SourceLocation ColonColonLoc) {
96221345Sdim  Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
97221345Sdim
98219077Sdim  if (Range.getBegin().isInvalid())
99219077Sdim    Range.setBegin(AliasLoc);
100219077Sdim  Range.setEnd(ColonColonLoc);
101219077Sdim
102221345Sdim  assert(Range == Builder.getSourceRange() &&
103219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
104219077Sdim}
105219077Sdim
106219077Sdimvoid CXXScopeSpec::MakeGlobal(ASTContext &Context,
107219077Sdim                              SourceLocation ColonColonLoc) {
108221345Sdim  Builder.MakeGlobal(Context, ColonColonLoc);
109221345Sdim
110219077Sdim  Range = SourceRange(ColonColonLoc);
111219077Sdim
112221345Sdim  assert(Range == Builder.getSourceRange() &&
113219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
114219077Sdim}
115219077Sdim
116219077Sdimvoid CXXScopeSpec::MakeTrivial(ASTContext &Context,
117219077Sdim                               NestedNameSpecifier *Qualifier, SourceRange R) {
118221345Sdim  Builder.MakeTrivial(Context, Qualifier, R);
119219077Sdim  Range = R;
120219077Sdim}
121219077Sdim
122219077Sdimvoid CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
123219077Sdim  if (!Other) {
124219077Sdim    Range = SourceRange();
125221345Sdim    Builder.Clear();
126219077Sdim    return;
127219077Sdim  }
128221345Sdim
129219077Sdim  Range = Other.getSourceRange();
130221345Sdim  Builder.Adopt(Other);
131219077Sdim}
132219077Sdim
133224145SdimSourceLocation CXXScopeSpec::getLastQualifierNameLoc() const {
134224145Sdim  if (!Builder.getRepresentation())
135224145Sdim    return SourceLocation();
136224145Sdim  return Builder.getTemporary().getLocalBeginLoc();
137224145Sdim}
138224145Sdim
139219077SdimNestedNameSpecifierLoc
140219077SdimCXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
141221345Sdim  if (!Builder.getRepresentation())
142219077Sdim    return NestedNameSpecifierLoc();
143219077Sdim
144221345Sdim  return Builder.getWithLocInContext(Context);
145219077Sdim}
146219077Sdim
147212795Sdim/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
148212795Sdim/// "TheDeclarator" is the declarator that this will be added to.
149243830SdimDeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
150239462Sdim                                             bool isAmbiguous,
151243830Sdim                                             SourceLocation LParenLoc,
152212795Sdim                                             ParamInfo *ArgInfo,
153212795Sdim                                             unsigned NumArgs,
154243830Sdim                                             SourceLocation EllipsisLoc,
155243830Sdim                                             SourceLocation RParenLoc,
156212795Sdim                                             unsigned TypeQuals,
157218893Sdim                                             bool RefQualifierIsLvalueRef,
158218893Sdim                                             SourceLocation RefQualifierLoc,
159234353Sdim                                             SourceLocation ConstQualifierLoc,
160234353Sdim                                             SourceLocation
161234353Sdim                                                 VolatileQualifierLoc,
162224145Sdim                                             SourceLocation MutableLoc,
163221345Sdim                                             ExceptionSpecificationType
164221345Sdim                                                 ESpecType,
165221345Sdim                                             SourceLocation ESpecLoc,
166212795Sdim                                             ParsedType *Exceptions,
167212795Sdim                                             SourceRange *ExceptionRanges,
168212795Sdim                                             unsigned NumExceptions,
169221345Sdim                                             Expr *NoexceptExpr,
170221345Sdim                                             SourceLocation LocalRangeBegin,
171221345Sdim                                             SourceLocation LocalRangeEnd,
172218893Sdim                                             Declarator &TheDeclarator,
173239462Sdim                                             TypeResult TrailingReturnType) {
174249423Sdim  assert(!(TypeQuals & DeclSpec::TQ_atomic) &&
175249423Sdim         "function cannot have _Atomic qualifier");
176249423Sdim
177212795Sdim  DeclaratorChunk I;
178221345Sdim  I.Kind                        = Function;
179221345Sdim  I.Loc                         = LocalRangeBegin;
180221345Sdim  I.EndLoc                      = LocalRangeEnd;
181221345Sdim  I.Fun.AttrList                = 0;
182221345Sdim  I.Fun.hasPrototype            = hasProto;
183243830Sdim  I.Fun.isVariadic              = EllipsisLoc.isValid();
184239462Sdim  I.Fun.isAmbiguous             = isAmbiguous;
185243830Sdim  I.Fun.LParenLoc               = LParenLoc.getRawEncoding();
186221345Sdim  I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
187243830Sdim  I.Fun.RParenLoc               = RParenLoc.getRawEncoding();
188221345Sdim  I.Fun.DeleteArgInfo           = false;
189221345Sdim  I.Fun.TypeQuals               = TypeQuals;
190221345Sdim  I.Fun.NumArgs                 = NumArgs;
191221345Sdim  I.Fun.ArgInfo                 = 0;
192218893Sdim  I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
193221345Sdim  I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
194234353Sdim  I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
195234353Sdim  I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding();
196224145Sdim  I.Fun.MutableLoc              = MutableLoc.getRawEncoding();
197221345Sdim  I.Fun.ExceptionSpecType       = ESpecType;
198221345Sdim  I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
199221345Sdim  I.Fun.NumExceptions           = 0;
200221345Sdim  I.Fun.Exceptions              = 0;
201221345Sdim  I.Fun.NoexceptExpr            = 0;
202239462Sdim  I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
203239462Sdim                                  TrailingReturnType.isInvalid();
204239462Sdim  I.Fun.TrailingReturnType      = TrailingReturnType.get();
205212795Sdim
206212795Sdim  // new[] an argument array if needed.
207212795Sdim  if (NumArgs) {
208212795Sdim    // If the 'InlineParams' in Declarator is unused and big enough, put our
209212795Sdim    // parameter list there (in an effort to avoid new/delete traffic).  If it
210212795Sdim    // is already used (consider a function returning a function pointer) or too
211212795Sdim    // small (function taking too many arguments), go to the heap.
212212795Sdim    if (!TheDeclarator.InlineParamsUsed &&
213212795Sdim        NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
214212795Sdim      I.Fun.ArgInfo = TheDeclarator.InlineParams;
215212795Sdim      I.Fun.DeleteArgInfo = false;
216212795Sdim      TheDeclarator.InlineParamsUsed = true;
217212795Sdim    } else {
218212795Sdim      I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
219212795Sdim      I.Fun.DeleteArgInfo = true;
220212795Sdim    }
221212795Sdim    memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
222212795Sdim  }
223221345Sdim
224221345Sdim  // Check what exception specification information we should actually store.
225221345Sdim  switch (ESpecType) {
226221345Sdim  default: break; // By default, save nothing.
227221345Sdim  case EST_Dynamic:
228221345Sdim    // new[] an exception array if needed
229221345Sdim    if (NumExceptions) {
230221345Sdim      I.Fun.NumExceptions = NumExceptions;
231221345Sdim      I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
232221345Sdim      for (unsigned i = 0; i != NumExceptions; ++i) {
233221345Sdim        I.Fun.Exceptions[i].Ty = Exceptions[i];
234221345Sdim        I.Fun.Exceptions[i].Range = ExceptionRanges[i];
235221345Sdim      }
236212795Sdim    }
237221345Sdim    break;
238221345Sdim
239221345Sdim  case EST_ComputedNoexcept:
240221345Sdim    I.Fun.NoexceptExpr = NoexceptExpr;
241221345Sdim    break;
242212795Sdim  }
243212795Sdim  return I;
244212795Sdim}
245212795Sdim
246224145Sdimbool Declarator::isDeclarationOfFunction() const {
247224145Sdim  for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
248224145Sdim    switch (DeclTypeInfo[i].Kind) {
249224145Sdim    case DeclaratorChunk::Function:
250224145Sdim      return true;
251224145Sdim    case DeclaratorChunk::Paren:
252224145Sdim      continue;
253224145Sdim    case DeclaratorChunk::Pointer:
254224145Sdim    case DeclaratorChunk::Reference:
255224145Sdim    case DeclaratorChunk::Array:
256224145Sdim    case DeclaratorChunk::BlockPointer:
257224145Sdim    case DeclaratorChunk::MemberPointer:
258224145Sdim      return false;
259224145Sdim    }
260224145Sdim    llvm_unreachable("Invalid type chunk");
261224145Sdim  }
262224145Sdim
263224145Sdim  switch (DS.getTypeSpecType()) {
264226633Sdim    case TST_atomic:
265224145Sdim    case TST_auto:
266224145Sdim    case TST_bool:
267224145Sdim    case TST_char:
268224145Sdim    case TST_char16:
269224145Sdim    case TST_char32:
270224145Sdim    case TST_class:
271224145Sdim    case TST_decimal128:
272224145Sdim    case TST_decimal32:
273224145Sdim    case TST_decimal64:
274224145Sdim    case TST_double:
275224145Sdim    case TST_enum:
276224145Sdim    case TST_error:
277224145Sdim    case TST_float:
278226633Sdim    case TST_half:
279224145Sdim    case TST_int:
280234353Sdim    case TST_int128:
281224145Sdim    case TST_struct:
282243830Sdim    case TST_interface:
283224145Sdim    case TST_union:
284224145Sdim    case TST_unknown_anytype:
285224145Sdim    case TST_unspecified:
286224145Sdim    case TST_void:
287224145Sdim    case TST_wchar:
288249423Sdim    case TST_image1d_t:
289249423Sdim    case TST_image1d_array_t:
290249423Sdim    case TST_image1d_buffer_t:
291249423Sdim    case TST_image2d_t:
292249423Sdim    case TST_image2d_array_t:
293249423Sdim    case TST_image3d_t:
294249423Sdim    case TST_sampler_t:
295249423Sdim    case TST_event_t:
296224145Sdim      return false;
297224145Sdim
298251662Sdim    case TST_decltype_auto:
299251662Sdim      // This must have an initializer, so can't be a function declaration,
300251662Sdim      // even if the initializer has function type.
301251662Sdim      return false;
302251662Sdim
303224145Sdim    case TST_decltype:
304224145Sdim    case TST_typeofExpr:
305224145Sdim      if (Expr *E = DS.getRepAsExpr())
306224145Sdim        return E->getType()->isFunctionType();
307224145Sdim      return false;
308224145Sdim
309224145Sdim    case TST_underlyingType:
310224145Sdim    case TST_typename:
311224145Sdim    case TST_typeofType: {
312224145Sdim      QualType QT = DS.getRepAsType().get();
313224145Sdim      if (QT.isNull())
314224145Sdim        return false;
315224145Sdim
316224145Sdim      if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
317224145Sdim        QT = LIT->getType();
318224145Sdim
319224145Sdim      if (QT.isNull())
320224145Sdim        return false;
321224145Sdim
322224145Sdim      return QT->isFunctionType();
323224145Sdim    }
324224145Sdim  }
325234353Sdim
326234353Sdim  llvm_unreachable("Invalid TypeSpecType!");
327224145Sdim}
328224145Sdim
329263508Sdimbool Declarator::isStaticMember() {
330263508Sdim  assert(getContext() == MemberContext);
331263508Sdim  return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
332263508Sdim         CXXMethodDecl::isStaticOverloadedOperator(
333263508Sdim             getName().OperatorFunctionId.Operator);
334263508Sdim}
335263508Sdim
336263508Sdimbool DeclSpec::hasTagDefinition() const {
337263508Sdim  if (!TypeSpecOwned)
338263508Sdim    return false;
339263508Sdim  return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition();
340263508Sdim}
341263508Sdim
342212795Sdim/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
343212795Sdim/// declaration specifier includes.
344212795Sdim///
345212795Sdimunsigned DeclSpec::getParsedSpecifiers() const {
346212795Sdim  unsigned Res = 0;
347212795Sdim  if (StorageClassSpec != SCS_unspecified ||
348251662Sdim      ThreadStorageClassSpec != TSCS_unspecified)
349212795Sdim    Res |= PQ_StorageClassSpecifier;
350212795Sdim
351212795Sdim  if (TypeQualifiers != TQ_unspecified)
352212795Sdim    Res |= PQ_TypeQualifier;
353212795Sdim
354212795Sdim  if (hasTypeSpecifier())
355212795Sdim    Res |= PQ_TypeSpecifier;
356212795Sdim
357249423Sdim  if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified ||
358263508Sdim      FS_noreturn_specified || FS_forceinline_specified)
359212795Sdim    Res |= PQ_FunctionSpecifier;
360212795Sdim  return Res;
361212795Sdim}
362212795Sdim
363212795Sdimtemplate <class T> static bool BadSpecifier(T TNew, T TPrev,
364212795Sdim                                            const char *&PrevSpec,
365243830Sdim                                            unsigned &DiagID,
366243830Sdim                                            bool IsExtension = true) {
367212795Sdim  PrevSpec = DeclSpec::getSpecifierName(TPrev);
368243830Sdim  if (TNew != TPrev)
369243830Sdim    DiagID = diag::err_invalid_decl_spec_combination;
370243830Sdim  else
371243830Sdim    DiagID = IsExtension ? diag::ext_duplicate_declspec :
372243830Sdim                           diag::warn_duplicate_declspec;
373212795Sdim  return true;
374212795Sdim}
375212795Sdim
376212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
377212795Sdim  switch (S) {
378212795Sdim  case DeclSpec::SCS_unspecified: return "unspecified";
379212795Sdim  case DeclSpec::SCS_typedef:     return "typedef";
380212795Sdim  case DeclSpec::SCS_extern:      return "extern";
381212795Sdim  case DeclSpec::SCS_static:      return "static";
382212795Sdim  case DeclSpec::SCS_auto:        return "auto";
383212795Sdim  case DeclSpec::SCS_register:    return "register";
384212795Sdim  case DeclSpec::SCS_private_extern: return "__private_extern__";
385212795Sdim  case DeclSpec::SCS_mutable:     return "mutable";
386212795Sdim  }
387212795Sdim  llvm_unreachable("Unknown typespec!");
388212795Sdim}
389212795Sdim
390251662Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) {
391251662Sdim  switch (S) {
392251662Sdim  case DeclSpec::TSCS_unspecified:   return "unspecified";
393251662Sdim  case DeclSpec::TSCS___thread:      return "__thread";
394251662Sdim  case DeclSpec::TSCS_thread_local:  return "thread_local";
395251662Sdim  case DeclSpec::TSCS__Thread_local: return "_Thread_local";
396251662Sdim  }
397251662Sdim  llvm_unreachable("Unknown typespec!");
398251662Sdim}
399251662Sdim
400212795Sdimconst char *DeclSpec::getSpecifierName(TSW W) {
401212795Sdim  switch (W) {
402212795Sdim  case TSW_unspecified: return "unspecified";
403212795Sdim  case TSW_short:       return "short";
404212795Sdim  case TSW_long:        return "long";
405212795Sdim  case TSW_longlong:    return "long long";
406212795Sdim  }
407212795Sdim  llvm_unreachable("Unknown typespec!");
408212795Sdim}
409212795Sdim
410212795Sdimconst char *DeclSpec::getSpecifierName(TSC C) {
411212795Sdim  switch (C) {
412212795Sdim  case TSC_unspecified: return "unspecified";
413212795Sdim  case TSC_imaginary:   return "imaginary";
414212795Sdim  case TSC_complex:     return "complex";
415212795Sdim  }
416212795Sdim  llvm_unreachable("Unknown typespec!");
417212795Sdim}
418212795Sdim
419212795Sdim
420212795Sdimconst char *DeclSpec::getSpecifierName(TSS S) {
421212795Sdim  switch (S) {
422212795Sdim  case TSS_unspecified: return "unspecified";
423212795Sdim  case TSS_signed:      return "signed";
424212795Sdim  case TSS_unsigned:    return "unsigned";
425212795Sdim  }
426212795Sdim  llvm_unreachable("Unknown typespec!");
427212795Sdim}
428212795Sdim
429212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
430212795Sdim  switch (T) {
431212795Sdim  case DeclSpec::TST_unspecified: return "unspecified";
432212795Sdim  case DeclSpec::TST_void:        return "void";
433212795Sdim  case DeclSpec::TST_char:        return "char";
434212795Sdim  case DeclSpec::TST_wchar:       return "wchar_t";
435212795Sdim  case DeclSpec::TST_char16:      return "char16_t";
436212795Sdim  case DeclSpec::TST_char32:      return "char32_t";
437212795Sdim  case DeclSpec::TST_int:         return "int";
438234353Sdim  case DeclSpec::TST_int128:      return "__int128";
439226633Sdim  case DeclSpec::TST_half:        return "half";
440212795Sdim  case DeclSpec::TST_float:       return "float";
441212795Sdim  case DeclSpec::TST_double:      return "double";
442212795Sdim  case DeclSpec::TST_bool:        return "_Bool";
443212795Sdim  case DeclSpec::TST_decimal32:   return "_Decimal32";
444212795Sdim  case DeclSpec::TST_decimal64:   return "_Decimal64";
445212795Sdim  case DeclSpec::TST_decimal128:  return "_Decimal128";
446212795Sdim  case DeclSpec::TST_enum:        return "enum";
447212795Sdim  case DeclSpec::TST_class:       return "class";
448212795Sdim  case DeclSpec::TST_union:       return "union";
449212795Sdim  case DeclSpec::TST_struct:      return "struct";
450243830Sdim  case DeclSpec::TST_interface:   return "__interface";
451212795Sdim  case DeclSpec::TST_typename:    return "type-name";
452212795Sdim  case DeclSpec::TST_typeofType:
453212795Sdim  case DeclSpec::TST_typeofExpr:  return "typeof";
454212795Sdim  case DeclSpec::TST_auto:        return "auto";
455212795Sdim  case DeclSpec::TST_decltype:    return "(decltype)";
456251662Sdim  case DeclSpec::TST_decltype_auto: return "decltype(auto)";
457223017Sdim  case DeclSpec::TST_underlyingType: return "__underlying_type";
458221345Sdim  case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
459226633Sdim  case DeclSpec::TST_atomic: return "_Atomic";
460249423Sdim  case DeclSpec::TST_image1d_t:   return "image1d_t";
461249423Sdim  case DeclSpec::TST_image1d_array_t: return "image1d_array_t";
462249423Sdim  case DeclSpec::TST_image1d_buffer_t: return "image1d_buffer_t";
463249423Sdim  case DeclSpec::TST_image2d_t:   return "image2d_t";
464249423Sdim  case DeclSpec::TST_image2d_array_t: return "image2d_array_t";
465249423Sdim  case DeclSpec::TST_image3d_t:   return "image3d_t";
466249423Sdim  case DeclSpec::TST_sampler_t:   return "sampler_t";
467249423Sdim  case DeclSpec::TST_event_t:     return "event_t";
468212795Sdim  case DeclSpec::TST_error:       return "(error)";
469212795Sdim  }
470212795Sdim  llvm_unreachable("Unknown typespec!");
471212795Sdim}
472212795Sdim
473212795Sdimconst char *DeclSpec::getSpecifierName(TQ T) {
474212795Sdim  switch (T) {
475212795Sdim  case DeclSpec::TQ_unspecified: return "unspecified";
476212795Sdim  case DeclSpec::TQ_const:       return "const";
477212795Sdim  case DeclSpec::TQ_restrict:    return "restrict";
478212795Sdim  case DeclSpec::TQ_volatile:    return "volatile";
479249423Sdim  case DeclSpec::TQ_atomic:      return "_Atomic";
480212795Sdim  }
481212795Sdim  llvm_unreachable("Unknown typespec!");
482212795Sdim}
483212795Sdim
484226633Sdimbool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
485212795Sdim                                   const char *&PrevSpec,
486226633Sdim                                   unsigned &DiagID) {
487239462Sdim  // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
488239462Sdim  // specifiers are not supported.
489218893Sdim  // It seems sensible to prohibit private_extern too
490226633Sdim  // The cl_clang_storage_class_specifiers extension enables support for
491226633Sdim  // these storage-class specifiers.
492239462Sdim  // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
493239462Sdim  // specifiers are not supported."
494234353Sdim  if (S.getLangOpts().OpenCL &&
495226633Sdim      !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
496226633Sdim    switch (SC) {
497218893Sdim    case SCS_extern:
498218893Sdim    case SCS_private_extern:
499239462Sdim    case SCS_static:
500239462Sdim        if (S.getLangOpts().OpenCLVersion < 120) {
501239462Sdim          DiagID   = diag::err_not_opencl_storage_class_specifier;
502239462Sdim          PrevSpec = getSpecifierName(SC);
503239462Sdim          return true;
504239462Sdim        }
505239462Sdim        break;
506218893Sdim    case SCS_auto:
507218893Sdim    case SCS_register:
508218893Sdim      DiagID   = diag::err_not_opencl_storage_class_specifier;
509226633Sdim      PrevSpec = getSpecifierName(SC);
510218893Sdim      return true;
511218893Sdim    default:
512218893Sdim      break;
513218893Sdim    }
514218893Sdim  }
515218893Sdim
516212795Sdim  if (StorageClassSpec != SCS_unspecified) {
517251662Sdim    // Maybe this is an attempt to use C++11 'auto' outside of C++11 mode.
518226633Sdim    bool isInvalid = true;
519234353Sdim    if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
520226633Sdim      if (SC == SCS_auto)
521226633Sdim        return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
522226633Sdim      if (StorageClassSpec == SCS_auto) {
523226633Sdim        isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
524226633Sdim                                    PrevSpec, DiagID);
525226633Sdim        assert(!isInvalid && "auto SCS -> TST recovery failed");
526226633Sdim      }
527226633Sdim    }
528226633Sdim
529212795Sdim    // Changing storage class is allowed only if the previous one
530212795Sdim    // was the 'extern' that is part of a linkage specification and
531212795Sdim    // the new storage class is 'typedef'.
532226633Sdim    if (isInvalid &&
533226633Sdim        !(SCS_extern_in_linkage_spec &&
534212795Sdim          StorageClassSpec == SCS_extern &&
535226633Sdim          SC == SCS_typedef))
536226633Sdim      return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
537212795Sdim  }
538226633Sdim  StorageClassSpec = SC;
539212795Sdim  StorageClassSpecLoc = Loc;
540226633Sdim  assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
541212795Sdim  return false;
542212795Sdim}
543212795Sdim
544251662Sdimbool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,
545212795Sdim                                         const char *&PrevSpec,
546212795Sdim                                         unsigned &DiagID) {
547251662Sdim  if (ThreadStorageClassSpec != TSCS_unspecified)
548251662Sdim    return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID);
549251662Sdim
550251662Sdim  ThreadStorageClassSpec = TSC;
551251662Sdim  ThreadStorageClassSpecLoc = Loc;
552212795Sdim  return false;
553212795Sdim}
554212795Sdim
555212795Sdim/// These methods set the specified attribute of the DeclSpec, but return true
556212795Sdim/// and ignore the request if invalid (e.g. "extern" then "auto" is
557212795Sdim/// specified).
558212795Sdimbool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
559212795Sdim                                const char *&PrevSpec,
560212795Sdim                                unsigned &DiagID) {
561221345Sdim  // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
562221345Sdim  // for 'long long' we will keep the source location of the first 'long'.
563221345Sdim  if (TypeSpecWidth == TSW_unspecified)
564221345Sdim    TSWLoc = Loc;
565221345Sdim  // Allow turning long -> long long.
566221345Sdim  else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
567212795Sdim    return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
568212795Sdim  TypeSpecWidth = W;
569212795Sdim  if (TypeAltiVecVector && !TypeAltiVecBool &&
570212795Sdim      ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
571212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
572212795Sdim    DiagID = diag::warn_vector_long_decl_spec_combination;
573212795Sdim    return true;
574212795Sdim  }
575212795Sdim  return false;
576212795Sdim}
577212795Sdim
578212795Sdimbool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
579212795Sdim                                  const char *&PrevSpec,
580212795Sdim                                  unsigned &DiagID) {
581212795Sdim  if (TypeSpecComplex != TSC_unspecified)
582212795Sdim    return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
583212795Sdim  TypeSpecComplex = C;
584212795Sdim  TSCLoc = Loc;
585212795Sdim  return false;
586212795Sdim}
587212795Sdim
588212795Sdimbool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
589212795Sdim                               const char *&PrevSpec,
590212795Sdim                               unsigned &DiagID) {
591212795Sdim  if (TypeSpecSign != TSS_unspecified)
592212795Sdim    return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
593212795Sdim  TypeSpecSign = S;
594212795Sdim  TSSLoc = Loc;
595212795Sdim  return false;
596212795Sdim}
597212795Sdim
598212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
599212795Sdim                               const char *&PrevSpec,
600212795Sdim                               unsigned &DiagID,
601212795Sdim                               ParsedType Rep) {
602221345Sdim  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep);
603221345Sdim}
604221345Sdim
605221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
606221345Sdim                               SourceLocation TagNameLoc,
607221345Sdim                               const char *&PrevSpec,
608221345Sdim                               unsigned &DiagID,
609221345Sdim                               ParsedType Rep) {
610212795Sdim  assert(isTypeRep(T) && "T does not store a type");
611212795Sdim  assert(Rep && "no type provided!");
612212795Sdim  if (TypeSpecType != TST_unspecified) {
613212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
614212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
615212795Sdim    return true;
616212795Sdim  }
617212795Sdim  TypeSpecType = T;
618212795Sdim  TypeRep = Rep;
619221345Sdim  TSTLoc = TagKwLoc;
620221345Sdim  TSTNameLoc = TagNameLoc;
621212795Sdim  TypeSpecOwned = false;
622212795Sdim  return false;
623212795Sdim}
624212795Sdim
625212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
626212795Sdim                               const char *&PrevSpec,
627212795Sdim                               unsigned &DiagID,
628212795Sdim                               Expr *Rep) {
629212795Sdim  assert(isExprRep(T) && "T does not store an expr");
630212795Sdim  assert(Rep && "no expression provided!");
631212795Sdim  if (TypeSpecType != TST_unspecified) {
632212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
633212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
634212795Sdim    return true;
635212795Sdim  }
636212795Sdim  TypeSpecType = T;
637212795Sdim  ExprRep = Rep;
638212795Sdim  TSTLoc = Loc;
639221345Sdim  TSTNameLoc = Loc;
640212795Sdim  TypeSpecOwned = false;
641212795Sdim  return false;
642212795Sdim}
643212795Sdim
644212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
645212795Sdim                               const char *&PrevSpec,
646212795Sdim                               unsigned &DiagID,
647212795Sdim                               Decl *Rep, bool Owned) {
648221345Sdim  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned);
649221345Sdim}
650221345Sdim
651221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
652221345Sdim                               SourceLocation TagNameLoc,
653221345Sdim                               const char *&PrevSpec,
654221345Sdim                               unsigned &DiagID,
655221345Sdim                               Decl *Rep, bool Owned) {
656212795Sdim  assert(isDeclRep(T) && "T does not store a decl");
657212795Sdim  // Unlike the other cases, we don't assert that we actually get a decl.
658212795Sdim
659212795Sdim  if (TypeSpecType != TST_unspecified) {
660212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
661212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
662212795Sdim    return true;
663212795Sdim  }
664212795Sdim  TypeSpecType = T;
665212795Sdim  DeclRep = Rep;
666221345Sdim  TSTLoc = TagKwLoc;
667221345Sdim  TSTNameLoc = TagNameLoc;
668263508Sdim  TypeSpecOwned = Owned && Rep != 0;
669212795Sdim  return false;
670212795Sdim}
671212795Sdim
672212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
673212795Sdim                               const char *&PrevSpec,
674212795Sdim                               unsigned &DiagID) {
675212795Sdim  assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
676212795Sdim         "rep required for these type-spec kinds!");
677212795Sdim  if (TypeSpecType != TST_unspecified) {
678212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
679212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
680212795Sdim    return true;
681212795Sdim  }
682221345Sdim  TSTLoc = Loc;
683221345Sdim  TSTNameLoc = Loc;
684212795Sdim  if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
685212795Sdim    TypeAltiVecBool = true;
686212795Sdim    return false;
687212795Sdim  }
688212795Sdim  TypeSpecType = T;
689212795Sdim  TypeSpecOwned = false;
690212795Sdim  if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
691212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
692212795Sdim    DiagID = diag::err_invalid_vector_decl_spec;
693212795Sdim    return true;
694212795Sdim  }
695212795Sdim  return false;
696212795Sdim}
697212795Sdim
698212795Sdimbool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
699212795Sdim                          const char *&PrevSpec, unsigned &DiagID) {
700212795Sdim  if (TypeSpecType != TST_unspecified) {
701212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
702212795Sdim    DiagID = diag::err_invalid_vector_decl_spec_combination;
703212795Sdim    return true;
704212795Sdim  }
705212795Sdim  TypeAltiVecVector = isAltiVecVector;
706212795Sdim  AltiVecLoc = Loc;
707212795Sdim  return false;
708212795Sdim}
709212795Sdim
710212795Sdimbool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
711212795Sdim                          const char *&PrevSpec, unsigned &DiagID) {
712212795Sdim  if (!TypeAltiVecVector || TypeAltiVecPixel ||
713212795Sdim      (TypeSpecType != TST_unspecified)) {
714212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
715212795Sdim    DiagID = diag::err_invalid_pixel_decl_spec_combination;
716212795Sdim    return true;
717212795Sdim  }
718212795Sdim  TypeAltiVecPixel = isAltiVecPixel;
719212795Sdim  TSTLoc = Loc;
720221345Sdim  TSTNameLoc = Loc;
721212795Sdim  return false;
722212795Sdim}
723212795Sdim
724263508Sdimbool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
725263508Sdim                          const char *&PrevSpec, unsigned &DiagID) {
726263508Sdim  if (!TypeAltiVecVector || TypeAltiVecBool ||
727263508Sdim      (TypeSpecType != TST_unspecified)) {
728263508Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
729263508Sdim    DiagID = diag::err_invalid_vector_bool_decl_spec;
730263508Sdim    return true;
731263508Sdim  }
732263508Sdim  TypeAltiVecBool = isAltiVecBool;
733263508Sdim  TSTLoc = Loc;
734263508Sdim  TSTNameLoc = Loc;
735263508Sdim  return false;
736263508Sdim}
737263508Sdim
738212795Sdimbool DeclSpec::SetTypeSpecError() {
739212795Sdim  TypeSpecType = TST_error;
740212795Sdim  TypeSpecOwned = false;
741212795Sdim  TSTLoc = SourceLocation();
742221345Sdim  TSTNameLoc = SourceLocation();
743212795Sdim  return false;
744212795Sdim}
745212795Sdim
746212795Sdimbool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
747243830Sdim                           unsigned &DiagID, const LangOptions &Lang) {
748263508Sdim  // Duplicates are permitted in C99 onwards, but are not permitted in C89 or
749263508Sdim  // C++.  However, since this is likely not what the user intended, we will
750263508Sdim  // always warn.  We do not need to set the qualifier's location since we
751263508Sdim  // already have it.
752243830Sdim  if (TypeQualifiers & T) {
753243830Sdim    bool IsExtension = true;
754243830Sdim    if (Lang.C99)
755243830Sdim      IsExtension = false;
756243830Sdim    return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
757243830Sdim  }
758212795Sdim  TypeQualifiers |= T;
759212795Sdim
760212795Sdim  switch (T) {
761249423Sdim  case TQ_unspecified: break;
762249423Sdim  case TQ_const:    TQ_constLoc = Loc; return false;
763249423Sdim  case TQ_restrict: TQ_restrictLoc = Loc; return false;
764249423Sdim  case TQ_volatile: TQ_volatileLoc = Loc; return false;
765249423Sdim  case TQ_atomic:   TQ_atomicLoc = Loc; return false;
766212795Sdim  }
767249423Sdim
768249423Sdim  llvm_unreachable("Unknown type qualifier!");
769212795Sdim}
770212795Sdim
771263508Sdimbool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
772263508Sdim                                     unsigned &DiagID) {
773263508Sdim  // 'inline inline' is ok.  However, since this is likely not what the user
774263508Sdim  // intended, we will always warn, similar to duplicates of type qualifiers.
775263508Sdim  if (FS_inline_specified) {
776263508Sdim    DiagID = diag::warn_duplicate_declspec;
777263508Sdim    PrevSpec = "inline";
778263508Sdim    return true;
779263508Sdim  }
780212795Sdim  FS_inline_specified = true;
781212795Sdim  FS_inlineLoc = Loc;
782212795Sdim  return false;
783212795Sdim}
784212795Sdim
785263508Sdimbool DeclSpec::setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec,
786263508Sdim                                          unsigned &DiagID) {
787263508Sdim  if (FS_forceinline_specified) {
788263508Sdim    DiagID = diag::warn_duplicate_declspec;
789263508Sdim    PrevSpec = "__forceinline";
790263508Sdim    return true;
791263508Sdim  }
792263508Sdim  FS_forceinline_specified = true;
793263508Sdim  FS_forceinlineLoc = Loc;
794263508Sdim  return false;
795263508Sdim}
796263508Sdim
797263508Sdimbool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc,
798263508Sdim                                      const char *&PrevSpec,
799263508Sdim                                      unsigned &DiagID) {
800263508Sdim  // 'virtual virtual' is ok, but warn as this is likely not what the user
801263508Sdim  // intended.
802263508Sdim  if (FS_virtual_specified) {
803263508Sdim    DiagID = diag::warn_duplicate_declspec;
804263508Sdim    PrevSpec = "virtual";
805263508Sdim    return true;
806263508Sdim  }
807212795Sdim  FS_virtual_specified = true;
808212795Sdim  FS_virtualLoc = Loc;
809212795Sdim  return false;
810212795Sdim}
811212795Sdim
812263508Sdimbool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc,
813263508Sdim                                       const char *&PrevSpec,
814263508Sdim                                       unsigned &DiagID) {
815263508Sdim  // 'explicit explicit' is ok, but warn as this is likely not what the user
816263508Sdim  // intended.
817263508Sdim  if (FS_explicit_specified) {
818263508Sdim    DiagID = diag::warn_duplicate_declspec;
819263508Sdim    PrevSpec = "explicit";
820263508Sdim    return true;
821263508Sdim  }
822212795Sdim  FS_explicit_specified = true;
823212795Sdim  FS_explicitLoc = Loc;
824212795Sdim  return false;
825212795Sdim}
826212795Sdim
827263508Sdimbool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc,
828263508Sdim                                       const char *&PrevSpec,
829263508Sdim                                       unsigned &DiagID) {
830263508Sdim  // '_Noreturn _Noreturn' is ok, but warn as this is likely not what the user
831263508Sdim  // intended.
832263508Sdim  if (FS_noreturn_specified) {
833263508Sdim    DiagID = diag::warn_duplicate_declspec;
834263508Sdim    PrevSpec = "_Noreturn";
835263508Sdim    return true;
836263508Sdim  }
837249423Sdim  FS_noreturn_specified = true;
838249423Sdim  FS_noreturnLoc = Loc;
839249423Sdim  return false;
840249423Sdim}
841249423Sdim
842212795Sdimbool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
843212795Sdim                             unsigned &DiagID) {
844212795Sdim  if (Friend_specified) {
845212795Sdim    PrevSpec = "friend";
846212795Sdim    DiagID = diag::ext_duplicate_declspec;
847212795Sdim    return true;
848212795Sdim  }
849212795Sdim
850212795Sdim  Friend_specified = true;
851212795Sdim  FriendLoc = Loc;
852212795Sdim  return false;
853212795Sdim}
854212795Sdim
855226633Sdimbool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
856226633Sdim                                    unsigned &DiagID) {
857226633Sdim  if (isModulePrivateSpecified()) {
858226633Sdim    PrevSpec = "__module_private__";
859226633Sdim    DiagID = diag::ext_duplicate_declspec;
860226633Sdim    return true;
861226633Sdim  }
862226633Sdim
863226633Sdim  ModulePrivateLoc = Loc;
864226633Sdim  return false;
865226633Sdim}
866226633Sdim
867212795Sdimbool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
868212795Sdim                                unsigned &DiagID) {
869212795Sdim  // 'constexpr constexpr' is ok.
870212795Sdim  Constexpr_specified = true;
871212795Sdim  ConstexprLoc = Loc;
872212795Sdim  return false;
873212795Sdim}
874212795Sdim
875212795Sdimvoid DeclSpec::setProtocolQualifiers(Decl * const *Protos,
876212795Sdim                                     unsigned NP,
877212795Sdim                                     SourceLocation *ProtoLocs,
878212795Sdim                                     SourceLocation LAngleLoc) {
879212795Sdim  if (NP == 0) return;
880249423Sdim  Decl **ProtoQuals = new Decl*[NP];
881249423Sdim  memcpy(ProtoQuals, Protos, sizeof(Decl*)*NP);
882249423Sdim  ProtocolQualifiers = ProtoQuals;
883212795Sdim  ProtocolLocs = new SourceLocation[NP];
884212795Sdim  memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
885212795Sdim  NumProtocolQualifiers = NP;
886212795Sdim  ProtocolLAngleLoc = LAngleLoc;
887212795Sdim}
888212795Sdim
889212795Sdimvoid DeclSpec::SaveWrittenBuiltinSpecs() {
890212795Sdim  writtenBS.Sign = getTypeSpecSign();
891212795Sdim  writtenBS.Width = getTypeSpecWidth();
892212795Sdim  writtenBS.Type = getTypeSpecType();
893212795Sdim  // Search the list of attributes for the presence of a mode attribute.
894212795Sdim  writtenBS.ModeAttr = false;
895218893Sdim  AttributeList* attrs = getAttributes().getList();
896212795Sdim  while (attrs) {
897239462Sdim    if (attrs->getKind() == AttributeList::AT_Mode) {
898212795Sdim      writtenBS.ModeAttr = true;
899212795Sdim      break;
900212795Sdim    }
901212795Sdim    attrs = attrs->getNext();
902212795Sdim  }
903212795Sdim}
904212795Sdim
905212795Sdim/// Finish - This does final analysis of the declspec, rejecting things like
906212795Sdim/// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
907212795Sdim/// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
908212795Sdim/// DeclSpec is guaranteed self-consistent, even if an error occurred.
909226633Sdimvoid DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
910212795Sdim  // Before possibly changing their values, save specs as written.
911212795Sdim  SaveWrittenBuiltinSpecs();
912212795Sdim
913212795Sdim  // Check the type specifier components first.
914212795Sdim
915251662Sdim  // If decltype(auto) is used, no other type specifiers are permitted.
916251662Sdim  if (TypeSpecType == TST_decltype_auto &&
917251662Sdim      (TypeSpecWidth != TSW_unspecified ||
918251662Sdim       TypeSpecComplex != TSC_unspecified ||
919251662Sdim       TypeSpecSign != TSS_unspecified ||
920251662Sdim       TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool ||
921251662Sdim       TypeQualifiers)) {
922251662Sdim    const unsigned NumLocs = 8;
923251662Sdim    SourceLocation ExtraLocs[NumLocs] = {
924251662Sdim      TSWLoc, TSCLoc, TSSLoc, AltiVecLoc,
925251662Sdim      TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc
926251662Sdim    };
927251662Sdim    FixItHint Hints[NumLocs];
928251662Sdim    SourceLocation FirstLoc;
929251662Sdim    for (unsigned I = 0; I != NumLocs; ++I) {
930251662Sdim      if (!ExtraLocs[I].isInvalid()) {
931251662Sdim        if (FirstLoc.isInvalid() ||
932251662Sdim            PP.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I],
933251662Sdim                                                            FirstLoc))
934251662Sdim          FirstLoc = ExtraLocs[I];
935251662Sdim        Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]);
936251662Sdim      }
937251662Sdim    }
938251662Sdim    TypeSpecWidth = TSW_unspecified;
939251662Sdim    TypeSpecComplex = TSC_unspecified;
940251662Sdim    TypeSpecSign = TSS_unspecified;
941251662Sdim    TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false;
942251662Sdim    TypeQualifiers = 0;
943251662Sdim    Diag(D, TSTLoc, diag::err_decltype_auto_cannot_be_combined)
944251662Sdim      << Hints[0] << Hints[1] << Hints[2] << Hints[3]
945251662Sdim      << Hints[4] << Hints[5] << Hints[6] << Hints[7];
946251662Sdim  }
947251662Sdim
948212795Sdim  // Validate and finalize AltiVec vector declspec.
949212795Sdim  if (TypeAltiVecVector) {
950212795Sdim    if (TypeAltiVecBool) {
951212795Sdim      // Sign specifiers are not allowed with vector bool. (PIM 2.1)
952212795Sdim      if (TypeSpecSign != TSS_unspecified) {
953218893Sdim        Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
954212795Sdim          << getSpecifierName((TSS)TypeSpecSign);
955212795Sdim      }
956212795Sdim
957212795Sdim      // Only char/int are valid with vector bool. (PIM 2.1)
958212795Sdim      if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
959212795Sdim           (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
960218893Sdim        Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
961212795Sdim          << (TypeAltiVecPixel ? "__pixel" :
962212795Sdim                                 getSpecifierName((TST)TypeSpecType));
963212795Sdim      }
964212795Sdim
965212795Sdim      // Only 'short' is valid with vector bool. (PIM 2.1)
966212795Sdim      if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
967218893Sdim        Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
968212795Sdim          << getSpecifierName((TSW)TypeSpecWidth);
969212795Sdim
970212795Sdim      // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
971212795Sdim      if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
972212795Sdim          (TypeSpecWidth != TSW_unspecified))
973212795Sdim        TypeSpecSign = TSS_unsigned;
974212795Sdim    }
975212795Sdim
976212795Sdim    if (TypeAltiVecPixel) {
977212795Sdim      //TODO: perform validation
978212795Sdim      TypeSpecType = TST_int;
979212795Sdim      TypeSpecSign = TSS_unsigned;
980212795Sdim      TypeSpecWidth = TSW_short;
981212795Sdim      TypeSpecOwned = false;
982212795Sdim    }
983212795Sdim  }
984212795Sdim
985212795Sdim  // signed/unsigned are only valid with int/char/wchar_t.
986212795Sdim  if (TypeSpecSign != TSS_unspecified) {
987212795Sdim    if (TypeSpecType == TST_unspecified)
988212795Sdim      TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
989234353Sdim    else if (TypeSpecType != TST_int  && TypeSpecType != TST_int128 &&
990212795Sdim             TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
991218893Sdim      Diag(D, TSSLoc, diag::err_invalid_sign_spec)
992212795Sdim        << getSpecifierName((TST)TypeSpecType);
993212795Sdim      // signed double -> double.
994212795Sdim      TypeSpecSign = TSS_unspecified;
995212795Sdim    }
996212795Sdim  }
997212795Sdim
998212795Sdim  // Validate the width of the type.
999212795Sdim  switch (TypeSpecWidth) {
1000212795Sdim  case TSW_unspecified: break;
1001212795Sdim  case TSW_short:    // short int
1002212795Sdim  case TSW_longlong: // long long int
1003212795Sdim    if (TypeSpecType == TST_unspecified)
1004212795Sdim      TypeSpecType = TST_int; // short -> short int, long long -> long long int.
1005212795Sdim    else if (TypeSpecType != TST_int) {
1006218893Sdim      Diag(D, TSWLoc,
1007212795Sdim           TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
1008212795Sdim                                      : diag::err_invalid_longlong_spec)
1009212795Sdim        <<  getSpecifierName((TST)TypeSpecType);
1010212795Sdim      TypeSpecType = TST_int;
1011212795Sdim      TypeSpecOwned = false;
1012212795Sdim    }
1013212795Sdim    break;
1014212795Sdim  case TSW_long:  // long double, long int
1015212795Sdim    if (TypeSpecType == TST_unspecified)
1016212795Sdim      TypeSpecType = TST_int;  // long -> long int.
1017212795Sdim    else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
1018218893Sdim      Diag(D, TSWLoc, diag::err_invalid_long_spec)
1019212795Sdim        << getSpecifierName((TST)TypeSpecType);
1020212795Sdim      TypeSpecType = TST_int;
1021212795Sdim      TypeSpecOwned = false;
1022212795Sdim    }
1023212795Sdim    break;
1024212795Sdim  }
1025212795Sdim
1026212795Sdim  // TODO: if the implementation does not implement _Complex or _Imaginary,
1027212795Sdim  // disallow their use.  Need information about the backend.
1028212795Sdim  if (TypeSpecComplex != TSC_unspecified) {
1029212795Sdim    if (TypeSpecType == TST_unspecified) {
1030218893Sdim      Diag(D, TSCLoc, diag::ext_plain_complex)
1031212795Sdim        << FixItHint::CreateInsertion(
1032212795Sdim                              PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
1033212795Sdim                                                 " double");
1034212795Sdim      TypeSpecType = TST_double;   // _Complex -> _Complex double.
1035212795Sdim    } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
1036212795Sdim      // Note that this intentionally doesn't include _Complex _Bool.
1037234353Sdim      if (!PP.getLangOpts().CPlusPlus)
1038234353Sdim        Diag(D, TSTLoc, diag::ext_integer_complex);
1039212795Sdim    } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
1040218893Sdim      Diag(D, TSCLoc, diag::err_invalid_complex_spec)
1041212795Sdim        << getSpecifierName((TST)TypeSpecType);
1042212795Sdim      TypeSpecComplex = TSC_unspecified;
1043212795Sdim    }
1044212795Sdim  }
1045212795Sdim
1046251662Sdim  // C11 6.7.1/3, C++11 [dcl.stc]p1, GNU TLS: __thread, thread_local and
1047251662Sdim  // _Thread_local can only appear with the 'static' and 'extern' storage class
1048251662Sdim  // specifiers. We also allow __private_extern__ as an extension.
1049251662Sdim  if (ThreadStorageClassSpec != TSCS_unspecified) {
1050251662Sdim    switch (StorageClassSpec) {
1051251662Sdim    case SCS_unspecified:
1052251662Sdim    case SCS_extern:
1053251662Sdim    case SCS_private_extern:
1054251662Sdim    case SCS_static:
1055251662Sdim      break;
1056251662Sdim    default:
1057251662Sdim      if (PP.getSourceManager().isBeforeInTranslationUnit(
1058251662Sdim            getThreadStorageClassSpecLoc(), getStorageClassSpecLoc()))
1059251662Sdim        Diag(D, getStorageClassSpecLoc(),
1060251662Sdim             diag::err_invalid_decl_spec_combination)
1061251662Sdim          << DeclSpec::getSpecifierName(getThreadStorageClassSpec())
1062251662Sdim          << SourceRange(getThreadStorageClassSpecLoc());
1063251662Sdim      else
1064251662Sdim        Diag(D, getThreadStorageClassSpecLoc(),
1065251662Sdim             diag::err_invalid_decl_spec_combination)
1066251662Sdim          << DeclSpec::getSpecifierName(getStorageClassSpec())
1067251662Sdim          << SourceRange(getStorageClassSpecLoc());
1068251662Sdim      // Discard the thread storage class specifier to recover.
1069251662Sdim      ThreadStorageClassSpec = TSCS_unspecified;
1070251662Sdim      ThreadStorageClassSpecLoc = SourceLocation();
1071251662Sdim    }
1072251662Sdim  }
1073251662Sdim
1074226633Sdim  // If no type specifier was provided and we're parsing a language where
1075226633Sdim  // the type specifier is not optional, but we got 'auto' as a storage
1076226633Sdim  // class specifier, then assume this is an attempt to use C++0x's 'auto'
1077226633Sdim  // type specifier.
1078251662Sdim  if (PP.getLangOpts().CPlusPlus &&
1079226633Sdim      TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
1080226633Sdim    TypeSpecType = TST_auto;
1081249423Sdim    StorageClassSpec = SCS_unspecified;
1082226633Sdim    TSTLoc = TSTNameLoc = StorageClassSpecLoc;
1083226633Sdim    StorageClassSpecLoc = SourceLocation();
1084226633Sdim  }
1085226633Sdim  // Diagnose if we've recovered from an ill-formed 'auto' storage class
1086251662Sdim  // specifier in a pre-C++11 dialect of C++.
1087249423Sdim  if (!PP.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto)
1088226633Sdim    Diag(D, TSTLoc, diag::ext_auto_type_specifier);
1089249423Sdim  if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus11 &&
1090226633Sdim      StorageClassSpec == SCS_auto)
1091226633Sdim    Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
1092226633Sdim      << FixItHint::CreateRemoval(StorageClassSpecLoc);
1093234353Sdim  if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
1094234353Sdim    Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
1095234353Sdim      << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
1096234353Sdim  if (Constexpr_specified)
1097234353Sdim    Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
1098226633Sdim
1099212795Sdim  // C++ [class.friend]p6:
1100212795Sdim  //   No storage-class-specifier shall appear in the decl-specifier-seq
1101212795Sdim  //   of a friend declaration.
1102251662Sdim  if (isFriendSpecified() &&
1103251662Sdim      (getStorageClassSpec() || getThreadStorageClassSpec())) {
1104251662Sdim    SmallString<32> SpecName;
1105251662Sdim    SourceLocation SCLoc;
1106251662Sdim    FixItHint StorageHint, ThreadHint;
1107212795Sdim
1108251662Sdim    if (DeclSpec::SCS SC = getStorageClassSpec()) {
1109251662Sdim      SpecName = getSpecifierName(SC);
1110251662Sdim      SCLoc = getStorageClassSpecLoc();
1111251662Sdim      StorageHint = FixItHint::CreateRemoval(SCLoc);
1112251662Sdim    }
1113212795Sdim
1114251662Sdim    if (DeclSpec::TSCS TSC = getThreadStorageClassSpec()) {
1115251662Sdim      if (!SpecName.empty()) SpecName += " ";
1116251662Sdim      SpecName += getSpecifierName(TSC);
1117251662Sdim      SCLoc = getThreadStorageClassSpecLoc();
1118251662Sdim      ThreadHint = FixItHint::CreateRemoval(SCLoc);
1119251662Sdim    }
1120251662Sdim
1121218893Sdim    Diag(D, SCLoc, diag::err_friend_storage_spec)
1122251662Sdim      << SpecName << StorageHint << ThreadHint;
1123212795Sdim
1124212795Sdim    ClearStorageClassSpecs();
1125212795Sdim  }
1126212795Sdim
1127212795Sdim  assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
1128226633Sdim
1129212795Sdim  // Okay, now we can infer the real type.
1130212795Sdim
1131212795Sdim  // TODO: return "auto function" and other bad things based on the real type.
1132212795Sdim
1133212795Sdim  // 'data definition has no type or storage class'?
1134212795Sdim}
1135212795Sdim
1136212795Sdimbool DeclSpec::isMissingDeclaratorOk() {
1137212795Sdim  TST tst = getTypeSpecType();
1138212795Sdim  return isDeclRep(tst) && getRepAsDecl() != 0 &&
1139212795Sdim    StorageClassSpec != DeclSpec::SCS_typedef;
1140212795Sdim}
1141212795Sdim
1142212795Sdimvoid UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
1143212795Sdim                                          OverloadedOperatorKind Op,
1144212795Sdim                                          SourceLocation SymbolLocations[3]) {
1145212795Sdim  Kind = IK_OperatorFunctionId;
1146212795Sdim  StartLocation = OperatorLoc;
1147212795Sdim  EndLocation = OperatorLoc;
1148212795Sdim  OperatorFunctionId.Operator = Op;
1149212795Sdim  for (unsigned I = 0; I != 3; ++I) {
1150212795Sdim    OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
1151212795Sdim
1152212795Sdim    if (SymbolLocations[I].isValid())
1153212795Sdim      EndLocation = SymbolLocations[I];
1154212795Sdim  }
1155212795Sdim}
1156218893Sdim
1157218893Sdimbool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
1158218893Sdim                                  const char *&PrevSpec) {
1159221345Sdim  LastLocation = Loc;
1160221345Sdim
1161218893Sdim  if (Specifiers & VS) {
1162218893Sdim    PrevSpec = getSpecifierName(VS);
1163218893Sdim    return true;
1164218893Sdim  }
1165218893Sdim
1166218893Sdim  Specifiers |= VS;
1167218893Sdim
1168218893Sdim  switch (VS) {
1169226633Sdim  default: llvm_unreachable("Unknown specifier!");
1170218893Sdim  case VS_Override: VS_overrideLoc = Loc; break;
1171263508Sdim  case VS_Sealed:
1172218893Sdim  case VS_Final:    VS_finalLoc = Loc; break;
1173218893Sdim  }
1174218893Sdim
1175218893Sdim  return false;
1176218893Sdim}
1177218893Sdim
1178218893Sdimconst char *VirtSpecifiers::getSpecifierName(Specifier VS) {
1179218893Sdim  switch (VS) {
1180226633Sdim  default: llvm_unreachable("Unknown specifier");
1181218893Sdim  case VS_Override: return "override";
1182218893Sdim  case VS_Final: return "final";
1183263508Sdim  case VS_Sealed: return "sealed";
1184218893Sdim  }
1185218893Sdim}
1186