DeclSpec.cpp revision 239462
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/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
15212795Sdim#include "clang/Sema/DeclSpec.h"
16224145Sdim#include "clang/Sema/LocInfoType.h"
17212795Sdim#include "clang/Sema/ParsedTemplate.h"
18234353Sdim#include "clang/Sema/SemaDiagnostic.h"
19226633Sdim#include "clang/Sema/Sema.h"
20219077Sdim#include "clang/AST/ASTContext.h"
21224145Sdim#include "clang/AST/Expr.h"
22219077Sdim#include "clang/AST/NestedNameSpecifier.h"
23219077Sdim#include "clang/AST/TypeLoc.h"
24212795Sdim#include "clang/Lex/Preprocessor.h"
25212795Sdim#include "clang/Basic/LangOptions.h"
26212795Sdim#include "llvm/ADT/STLExtras.h"
27212795Sdim#include "llvm/Support/ErrorHandling.h"
28212795Sdim#include <cstring>
29212795Sdimusing namespace clang;
30212795Sdim
31212795Sdim
32226633Sdimstatic DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc,
33218893Sdim                              unsigned DiagID) {
34218893Sdim  return D.Report(Loc, DiagID);
35212795Sdim}
36212795Sdim
37212795Sdim
38212795Sdimvoid UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
39212795Sdim  assert(TemplateId && "NULL template-id annotation?");
40212795Sdim  Kind = IK_TemplateId;
41212795Sdim  this->TemplateId = TemplateId;
42212795Sdim  StartLocation = TemplateId->TemplateNameLoc;
43212795Sdim  EndLocation = TemplateId->RAngleLoc;
44212795Sdim}
45212795Sdim
46212795Sdimvoid UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
47212795Sdim  assert(TemplateId && "NULL template-id annotation?");
48212795Sdim  Kind = IK_ConstructorTemplateId;
49212795Sdim  this->TemplateId = TemplateId;
50212795Sdim  StartLocation = TemplateId->TemplateNameLoc;
51212795Sdim  EndLocation = TemplateId->RAngleLoc;
52212795Sdim}
53212795Sdim
54219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,
55219077Sdim                          TypeLoc TL, SourceLocation ColonColonLoc) {
56221345Sdim  Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);
57219077Sdim  if (Range.getBegin().isInvalid())
58219077Sdim    Range.setBegin(TL.getBeginLoc());
59219077Sdim  Range.setEnd(ColonColonLoc);
60219077Sdim
61221345Sdim  assert(Range == Builder.getSourceRange() &&
62219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
63219077Sdim}
64219077Sdim
65219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
66219077Sdim                          SourceLocation IdentifierLoc,
67219077Sdim                          SourceLocation ColonColonLoc) {
68221345Sdim  Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
69221345Sdim
70219077Sdim  if (Range.getBegin().isInvalid())
71219077Sdim    Range.setBegin(IdentifierLoc);
72219077Sdim  Range.setEnd(ColonColonLoc);
73219077Sdim
74221345Sdim  assert(Range == Builder.getSourceRange() &&
75219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
76219077Sdim}
77219077Sdim
78219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
79219077Sdim                          SourceLocation NamespaceLoc,
80219077Sdim                          SourceLocation ColonColonLoc) {
81221345Sdim  Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
82221345Sdim
83219077Sdim  if (Range.getBegin().isInvalid())
84219077Sdim    Range.setBegin(NamespaceLoc);
85219077Sdim  Range.setEnd(ColonColonLoc);
86219077Sdim
87221345Sdim  assert(Range == Builder.getSourceRange() &&
88219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
89219077Sdim}
90219077Sdim
91219077Sdimvoid CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
92219077Sdim                          SourceLocation AliasLoc,
93219077Sdim                          SourceLocation ColonColonLoc) {
94221345Sdim  Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
95221345Sdim
96219077Sdim  if (Range.getBegin().isInvalid())
97219077Sdim    Range.setBegin(AliasLoc);
98219077Sdim  Range.setEnd(ColonColonLoc);
99219077Sdim
100221345Sdim  assert(Range == Builder.getSourceRange() &&
101219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
102219077Sdim}
103219077Sdim
104219077Sdimvoid CXXScopeSpec::MakeGlobal(ASTContext &Context,
105219077Sdim                              SourceLocation ColonColonLoc) {
106221345Sdim  Builder.MakeGlobal(Context, ColonColonLoc);
107221345Sdim
108219077Sdim  Range = SourceRange(ColonColonLoc);
109219077Sdim
110221345Sdim  assert(Range == Builder.getSourceRange() &&
111219077Sdim         "NestedNameSpecifierLoc range computation incorrect");
112219077Sdim}
113219077Sdim
114219077Sdimvoid CXXScopeSpec::MakeTrivial(ASTContext &Context,
115219077Sdim                               NestedNameSpecifier *Qualifier, SourceRange R) {
116221345Sdim  Builder.MakeTrivial(Context, Qualifier, R);
117219077Sdim  Range = R;
118219077Sdim}
119219077Sdim
120219077Sdimvoid CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
121219077Sdim  if (!Other) {
122219077Sdim    Range = SourceRange();
123221345Sdim    Builder.Clear();
124219077Sdim    return;
125219077Sdim  }
126221345Sdim
127219077Sdim  Range = Other.getSourceRange();
128221345Sdim  Builder.Adopt(Other);
129219077Sdim}
130219077Sdim
131224145SdimSourceLocation CXXScopeSpec::getLastQualifierNameLoc() const {
132224145Sdim  if (!Builder.getRepresentation())
133224145Sdim    return SourceLocation();
134224145Sdim  return Builder.getTemporary().getLocalBeginLoc();
135224145Sdim}
136224145Sdim
137219077SdimNestedNameSpecifierLoc
138219077SdimCXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
139221345Sdim  if (!Builder.getRepresentation())
140219077Sdim    return NestedNameSpecifierLoc();
141219077Sdim
142221345Sdim  return Builder.getWithLocInContext(Context);
143219077Sdim}
144219077Sdim
145212795Sdim/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
146212795Sdim/// "TheDeclarator" is the declarator that this will be added to.
147221345SdimDeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
148239462Sdim                                             bool isAmbiguous,
149212795Sdim                                             SourceLocation EllipsisLoc,
150212795Sdim                                             ParamInfo *ArgInfo,
151212795Sdim                                             unsigned NumArgs,
152212795Sdim                                             unsigned TypeQuals,
153218893Sdim                                             bool RefQualifierIsLvalueRef,
154218893Sdim                                             SourceLocation RefQualifierLoc,
155234353Sdim                                             SourceLocation ConstQualifierLoc,
156234353Sdim                                             SourceLocation
157234353Sdim                                                 VolatileQualifierLoc,
158224145Sdim                                             SourceLocation MutableLoc,
159221345Sdim                                             ExceptionSpecificationType
160221345Sdim                                                 ESpecType,
161221345Sdim                                             SourceLocation ESpecLoc,
162212795Sdim                                             ParsedType *Exceptions,
163212795Sdim                                             SourceRange *ExceptionRanges,
164212795Sdim                                             unsigned NumExceptions,
165221345Sdim                                             Expr *NoexceptExpr,
166221345Sdim                                             SourceLocation LocalRangeBegin,
167221345Sdim                                             SourceLocation LocalRangeEnd,
168218893Sdim                                             Declarator &TheDeclarator,
169239462Sdim                                             TypeResult TrailingReturnType) {
170212795Sdim  DeclaratorChunk I;
171221345Sdim  I.Kind                        = Function;
172221345Sdim  I.Loc                         = LocalRangeBegin;
173221345Sdim  I.EndLoc                      = LocalRangeEnd;
174221345Sdim  I.Fun.AttrList                = 0;
175221345Sdim  I.Fun.hasPrototype            = hasProto;
176221345Sdim  I.Fun.isVariadic              = isVariadic;
177239462Sdim  I.Fun.isAmbiguous             = isAmbiguous;
178221345Sdim  I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
179221345Sdim  I.Fun.DeleteArgInfo           = false;
180221345Sdim  I.Fun.TypeQuals               = TypeQuals;
181221345Sdim  I.Fun.NumArgs                 = NumArgs;
182221345Sdim  I.Fun.ArgInfo                 = 0;
183218893Sdim  I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
184221345Sdim  I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
185234353Sdim  I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
186234353Sdim  I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding();
187224145Sdim  I.Fun.MutableLoc              = MutableLoc.getRawEncoding();
188221345Sdim  I.Fun.ExceptionSpecType       = ESpecType;
189221345Sdim  I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
190221345Sdim  I.Fun.NumExceptions           = 0;
191221345Sdim  I.Fun.Exceptions              = 0;
192221345Sdim  I.Fun.NoexceptExpr            = 0;
193239462Sdim  I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
194239462Sdim                                  TrailingReturnType.isInvalid();
195239462Sdim  I.Fun.TrailingReturnType      = TrailingReturnType.get();
196212795Sdim
197212795Sdim  // new[] an argument array if needed.
198212795Sdim  if (NumArgs) {
199212795Sdim    // If the 'InlineParams' in Declarator is unused and big enough, put our
200212795Sdim    // parameter list there (in an effort to avoid new/delete traffic).  If it
201212795Sdim    // is already used (consider a function returning a function pointer) or too
202212795Sdim    // small (function taking too many arguments), go to the heap.
203212795Sdim    if (!TheDeclarator.InlineParamsUsed &&
204212795Sdim        NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
205212795Sdim      I.Fun.ArgInfo = TheDeclarator.InlineParams;
206212795Sdim      I.Fun.DeleteArgInfo = false;
207212795Sdim      TheDeclarator.InlineParamsUsed = true;
208212795Sdim    } else {
209212795Sdim      I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
210212795Sdim      I.Fun.DeleteArgInfo = true;
211212795Sdim    }
212212795Sdim    memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
213212795Sdim  }
214221345Sdim
215221345Sdim  // Check what exception specification information we should actually store.
216221345Sdim  switch (ESpecType) {
217221345Sdim  default: break; // By default, save nothing.
218221345Sdim  case EST_Dynamic:
219221345Sdim    // new[] an exception array if needed
220221345Sdim    if (NumExceptions) {
221221345Sdim      I.Fun.NumExceptions = NumExceptions;
222221345Sdim      I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
223221345Sdim      for (unsigned i = 0; i != NumExceptions; ++i) {
224221345Sdim        I.Fun.Exceptions[i].Ty = Exceptions[i];
225221345Sdim        I.Fun.Exceptions[i].Range = ExceptionRanges[i];
226221345Sdim      }
227212795Sdim    }
228221345Sdim    break;
229221345Sdim
230221345Sdim  case EST_ComputedNoexcept:
231221345Sdim    I.Fun.NoexceptExpr = NoexceptExpr;
232221345Sdim    break;
233212795Sdim  }
234212795Sdim  return I;
235212795Sdim}
236212795Sdim
237224145Sdimbool Declarator::isDeclarationOfFunction() const {
238224145Sdim  for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
239224145Sdim    switch (DeclTypeInfo[i].Kind) {
240224145Sdim    case DeclaratorChunk::Function:
241224145Sdim      return true;
242224145Sdim    case DeclaratorChunk::Paren:
243224145Sdim      continue;
244224145Sdim    case DeclaratorChunk::Pointer:
245224145Sdim    case DeclaratorChunk::Reference:
246224145Sdim    case DeclaratorChunk::Array:
247224145Sdim    case DeclaratorChunk::BlockPointer:
248224145Sdim    case DeclaratorChunk::MemberPointer:
249224145Sdim      return false;
250224145Sdim    }
251224145Sdim    llvm_unreachable("Invalid type chunk");
252224145Sdim  }
253224145Sdim
254224145Sdim  switch (DS.getTypeSpecType()) {
255226633Sdim    case TST_atomic:
256224145Sdim    case TST_auto:
257224145Sdim    case TST_bool:
258224145Sdim    case TST_char:
259224145Sdim    case TST_char16:
260224145Sdim    case TST_char32:
261224145Sdim    case TST_class:
262224145Sdim    case TST_decimal128:
263224145Sdim    case TST_decimal32:
264224145Sdim    case TST_decimal64:
265224145Sdim    case TST_double:
266224145Sdim    case TST_enum:
267224145Sdim    case TST_error:
268224145Sdim    case TST_float:
269226633Sdim    case TST_half:
270224145Sdim    case TST_int:
271234353Sdim    case TST_int128:
272224145Sdim    case TST_struct:
273224145Sdim    case TST_union:
274224145Sdim    case TST_unknown_anytype:
275224145Sdim    case TST_unspecified:
276224145Sdim    case TST_void:
277224145Sdim    case TST_wchar:
278224145Sdim      return false;
279224145Sdim
280224145Sdim    case TST_decltype:
281224145Sdim    case TST_typeofExpr:
282224145Sdim      if (Expr *E = DS.getRepAsExpr())
283224145Sdim        return E->getType()->isFunctionType();
284224145Sdim      return false;
285224145Sdim
286224145Sdim    case TST_underlyingType:
287224145Sdim    case TST_typename:
288224145Sdim    case TST_typeofType: {
289224145Sdim      QualType QT = DS.getRepAsType().get();
290224145Sdim      if (QT.isNull())
291224145Sdim        return false;
292224145Sdim
293224145Sdim      if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
294224145Sdim        QT = LIT->getType();
295224145Sdim
296224145Sdim      if (QT.isNull())
297224145Sdim        return false;
298224145Sdim
299224145Sdim      return QT->isFunctionType();
300224145Sdim    }
301224145Sdim  }
302234353Sdim
303234353Sdim  llvm_unreachable("Invalid TypeSpecType!");
304224145Sdim}
305224145Sdim
306212795Sdim/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
307212795Sdim/// declaration specifier includes.
308212795Sdim///
309212795Sdimunsigned DeclSpec::getParsedSpecifiers() const {
310212795Sdim  unsigned Res = 0;
311212795Sdim  if (StorageClassSpec != SCS_unspecified ||
312212795Sdim      SCS_thread_specified)
313212795Sdim    Res |= PQ_StorageClassSpecifier;
314212795Sdim
315212795Sdim  if (TypeQualifiers != TQ_unspecified)
316212795Sdim    Res |= PQ_TypeQualifier;
317212795Sdim
318212795Sdim  if (hasTypeSpecifier())
319212795Sdim    Res |= PQ_TypeSpecifier;
320212795Sdim
321212795Sdim  if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
322212795Sdim    Res |= PQ_FunctionSpecifier;
323212795Sdim  return Res;
324212795Sdim}
325212795Sdim
326212795Sdimtemplate <class T> static bool BadSpecifier(T TNew, T TPrev,
327212795Sdim                                            const char *&PrevSpec,
328212795Sdim                                            unsigned &DiagID) {
329212795Sdim  PrevSpec = DeclSpec::getSpecifierName(TPrev);
330212795Sdim  DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
331212795Sdim            : diag::err_invalid_decl_spec_combination);
332212795Sdim  return true;
333212795Sdim}
334212795Sdim
335212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
336212795Sdim  switch (S) {
337212795Sdim  case DeclSpec::SCS_unspecified: return "unspecified";
338212795Sdim  case DeclSpec::SCS_typedef:     return "typedef";
339212795Sdim  case DeclSpec::SCS_extern:      return "extern";
340212795Sdim  case DeclSpec::SCS_static:      return "static";
341212795Sdim  case DeclSpec::SCS_auto:        return "auto";
342212795Sdim  case DeclSpec::SCS_register:    return "register";
343212795Sdim  case DeclSpec::SCS_private_extern: return "__private_extern__";
344212795Sdim  case DeclSpec::SCS_mutable:     return "mutable";
345212795Sdim  }
346212795Sdim  llvm_unreachable("Unknown typespec!");
347212795Sdim}
348212795Sdim
349212795Sdimconst char *DeclSpec::getSpecifierName(TSW W) {
350212795Sdim  switch (W) {
351212795Sdim  case TSW_unspecified: return "unspecified";
352212795Sdim  case TSW_short:       return "short";
353212795Sdim  case TSW_long:        return "long";
354212795Sdim  case TSW_longlong:    return "long long";
355212795Sdim  }
356212795Sdim  llvm_unreachable("Unknown typespec!");
357212795Sdim}
358212795Sdim
359212795Sdimconst char *DeclSpec::getSpecifierName(TSC C) {
360212795Sdim  switch (C) {
361212795Sdim  case TSC_unspecified: return "unspecified";
362212795Sdim  case TSC_imaginary:   return "imaginary";
363212795Sdim  case TSC_complex:     return "complex";
364212795Sdim  }
365212795Sdim  llvm_unreachable("Unknown typespec!");
366212795Sdim}
367212795Sdim
368212795Sdim
369212795Sdimconst char *DeclSpec::getSpecifierName(TSS S) {
370212795Sdim  switch (S) {
371212795Sdim  case TSS_unspecified: return "unspecified";
372212795Sdim  case TSS_signed:      return "signed";
373212795Sdim  case TSS_unsigned:    return "unsigned";
374212795Sdim  }
375212795Sdim  llvm_unreachable("Unknown typespec!");
376212795Sdim}
377212795Sdim
378212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
379212795Sdim  switch (T) {
380212795Sdim  case DeclSpec::TST_unspecified: return "unspecified";
381212795Sdim  case DeclSpec::TST_void:        return "void";
382212795Sdim  case DeclSpec::TST_char:        return "char";
383212795Sdim  case DeclSpec::TST_wchar:       return "wchar_t";
384212795Sdim  case DeclSpec::TST_char16:      return "char16_t";
385212795Sdim  case DeclSpec::TST_char32:      return "char32_t";
386212795Sdim  case DeclSpec::TST_int:         return "int";
387234353Sdim  case DeclSpec::TST_int128:      return "__int128";
388226633Sdim  case DeclSpec::TST_half:        return "half";
389212795Sdim  case DeclSpec::TST_float:       return "float";
390212795Sdim  case DeclSpec::TST_double:      return "double";
391212795Sdim  case DeclSpec::TST_bool:        return "_Bool";
392212795Sdim  case DeclSpec::TST_decimal32:   return "_Decimal32";
393212795Sdim  case DeclSpec::TST_decimal64:   return "_Decimal64";
394212795Sdim  case DeclSpec::TST_decimal128:  return "_Decimal128";
395212795Sdim  case DeclSpec::TST_enum:        return "enum";
396212795Sdim  case DeclSpec::TST_class:       return "class";
397212795Sdim  case DeclSpec::TST_union:       return "union";
398212795Sdim  case DeclSpec::TST_struct:      return "struct";
399212795Sdim  case DeclSpec::TST_typename:    return "type-name";
400212795Sdim  case DeclSpec::TST_typeofType:
401212795Sdim  case DeclSpec::TST_typeofExpr:  return "typeof";
402212795Sdim  case DeclSpec::TST_auto:        return "auto";
403212795Sdim  case DeclSpec::TST_decltype:    return "(decltype)";
404223017Sdim  case DeclSpec::TST_underlyingType: return "__underlying_type";
405221345Sdim  case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
406226633Sdim  case DeclSpec::TST_atomic: return "_Atomic";
407212795Sdim  case DeclSpec::TST_error:       return "(error)";
408212795Sdim  }
409212795Sdim  llvm_unreachable("Unknown typespec!");
410212795Sdim}
411212795Sdim
412212795Sdimconst char *DeclSpec::getSpecifierName(TQ T) {
413212795Sdim  switch (T) {
414212795Sdim  case DeclSpec::TQ_unspecified: return "unspecified";
415212795Sdim  case DeclSpec::TQ_const:       return "const";
416212795Sdim  case DeclSpec::TQ_restrict:    return "restrict";
417212795Sdim  case DeclSpec::TQ_volatile:    return "volatile";
418212795Sdim  }
419212795Sdim  llvm_unreachable("Unknown typespec!");
420212795Sdim}
421212795Sdim
422226633Sdimbool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
423212795Sdim                                   const char *&PrevSpec,
424226633Sdim                                   unsigned &DiagID) {
425239462Sdim  // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
426239462Sdim  // specifiers are not supported.
427218893Sdim  // It seems sensible to prohibit private_extern too
428226633Sdim  // The cl_clang_storage_class_specifiers extension enables support for
429226633Sdim  // these storage-class specifiers.
430239462Sdim  // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
431239462Sdim  // specifiers are not supported."
432234353Sdim  if (S.getLangOpts().OpenCL &&
433226633Sdim      !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
434226633Sdim    switch (SC) {
435218893Sdim    case SCS_extern:
436218893Sdim    case SCS_private_extern:
437239462Sdim    case SCS_static:
438239462Sdim        if (S.getLangOpts().OpenCLVersion < 120) {
439239462Sdim          DiagID   = diag::err_not_opencl_storage_class_specifier;
440239462Sdim          PrevSpec = getSpecifierName(SC);
441239462Sdim          return true;
442239462Sdim        }
443239462Sdim        break;
444218893Sdim    case SCS_auto:
445218893Sdim    case SCS_register:
446218893Sdim      DiagID   = diag::err_not_opencl_storage_class_specifier;
447226633Sdim      PrevSpec = getSpecifierName(SC);
448218893Sdim      return true;
449218893Sdim    default:
450218893Sdim      break;
451218893Sdim    }
452218893Sdim  }
453218893Sdim
454212795Sdim  if (StorageClassSpec != SCS_unspecified) {
455226633Sdim    // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
456226633Sdim    bool isInvalid = true;
457234353Sdim    if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
458226633Sdim      if (SC == SCS_auto)
459226633Sdim        return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
460226633Sdim      if (StorageClassSpec == SCS_auto) {
461226633Sdim        isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
462226633Sdim                                    PrevSpec, DiagID);
463226633Sdim        assert(!isInvalid && "auto SCS -> TST recovery failed");
464226633Sdim      }
465226633Sdim    }
466226633Sdim
467212795Sdim    // Changing storage class is allowed only if the previous one
468212795Sdim    // was the 'extern' that is part of a linkage specification and
469212795Sdim    // the new storage class is 'typedef'.
470226633Sdim    if (isInvalid &&
471226633Sdim        !(SCS_extern_in_linkage_spec &&
472212795Sdim          StorageClassSpec == SCS_extern &&
473226633Sdim          SC == SCS_typedef))
474226633Sdim      return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
475212795Sdim  }
476226633Sdim  StorageClassSpec = SC;
477212795Sdim  StorageClassSpecLoc = Loc;
478226633Sdim  assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
479212795Sdim  return false;
480212795Sdim}
481212795Sdim
482212795Sdimbool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
483212795Sdim                                         const char *&PrevSpec,
484212795Sdim                                         unsigned &DiagID) {
485212795Sdim  if (SCS_thread_specified) {
486212795Sdim    PrevSpec = "__thread";
487212795Sdim    DiagID = diag::ext_duplicate_declspec;
488212795Sdim    return true;
489212795Sdim  }
490212795Sdim  SCS_thread_specified = true;
491212795Sdim  SCS_threadLoc = Loc;
492212795Sdim  return false;
493212795Sdim}
494212795Sdim
495212795Sdim/// These methods set the specified attribute of the DeclSpec, but return true
496212795Sdim/// and ignore the request if invalid (e.g. "extern" then "auto" is
497212795Sdim/// specified).
498212795Sdimbool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
499212795Sdim                                const char *&PrevSpec,
500212795Sdim                                unsigned &DiagID) {
501221345Sdim  // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
502221345Sdim  // for 'long long' we will keep the source location of the first 'long'.
503221345Sdim  if (TypeSpecWidth == TSW_unspecified)
504221345Sdim    TSWLoc = Loc;
505221345Sdim  // Allow turning long -> long long.
506221345Sdim  else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
507212795Sdim    return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
508212795Sdim  TypeSpecWidth = W;
509212795Sdim  if (TypeAltiVecVector && !TypeAltiVecBool &&
510212795Sdim      ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
511212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
512212795Sdim    DiagID = diag::warn_vector_long_decl_spec_combination;
513212795Sdim    return true;
514212795Sdim  }
515212795Sdim  return false;
516212795Sdim}
517212795Sdim
518212795Sdimbool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
519212795Sdim                                  const char *&PrevSpec,
520212795Sdim                                  unsigned &DiagID) {
521212795Sdim  if (TypeSpecComplex != TSC_unspecified)
522212795Sdim    return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
523212795Sdim  TypeSpecComplex = C;
524212795Sdim  TSCLoc = Loc;
525212795Sdim  return false;
526212795Sdim}
527212795Sdim
528212795Sdimbool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
529212795Sdim                               const char *&PrevSpec,
530212795Sdim                               unsigned &DiagID) {
531212795Sdim  if (TypeSpecSign != TSS_unspecified)
532212795Sdim    return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
533212795Sdim  TypeSpecSign = S;
534212795Sdim  TSSLoc = Loc;
535212795Sdim  return false;
536212795Sdim}
537212795Sdim
538212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
539212795Sdim                               const char *&PrevSpec,
540212795Sdim                               unsigned &DiagID,
541212795Sdim                               ParsedType Rep) {
542221345Sdim  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep);
543221345Sdim}
544221345Sdim
545221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
546221345Sdim                               SourceLocation TagNameLoc,
547221345Sdim                               const char *&PrevSpec,
548221345Sdim                               unsigned &DiagID,
549221345Sdim                               ParsedType Rep) {
550212795Sdim  assert(isTypeRep(T) && "T does not store a type");
551212795Sdim  assert(Rep && "no type provided!");
552212795Sdim  if (TypeSpecType != TST_unspecified) {
553212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
554212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
555212795Sdim    return true;
556212795Sdim  }
557212795Sdim  TypeSpecType = T;
558212795Sdim  TypeRep = Rep;
559221345Sdim  TSTLoc = TagKwLoc;
560221345Sdim  TSTNameLoc = TagNameLoc;
561212795Sdim  TypeSpecOwned = false;
562212795Sdim  return false;
563212795Sdim}
564212795Sdim
565212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
566212795Sdim                               const char *&PrevSpec,
567212795Sdim                               unsigned &DiagID,
568212795Sdim                               Expr *Rep) {
569212795Sdim  assert(isExprRep(T) && "T does not store an expr");
570212795Sdim  assert(Rep && "no expression provided!");
571212795Sdim  if (TypeSpecType != TST_unspecified) {
572212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
573212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
574212795Sdim    return true;
575212795Sdim  }
576212795Sdim  TypeSpecType = T;
577212795Sdim  ExprRep = Rep;
578212795Sdim  TSTLoc = Loc;
579221345Sdim  TSTNameLoc = Loc;
580212795Sdim  TypeSpecOwned = false;
581212795Sdim  return false;
582212795Sdim}
583212795Sdim
584212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
585212795Sdim                               const char *&PrevSpec,
586212795Sdim                               unsigned &DiagID,
587212795Sdim                               Decl *Rep, bool Owned) {
588221345Sdim  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned);
589221345Sdim}
590221345Sdim
591221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
592221345Sdim                               SourceLocation TagNameLoc,
593221345Sdim                               const char *&PrevSpec,
594221345Sdim                               unsigned &DiagID,
595221345Sdim                               Decl *Rep, bool Owned) {
596212795Sdim  assert(isDeclRep(T) && "T does not store a decl");
597212795Sdim  // Unlike the other cases, we don't assert that we actually get a decl.
598212795Sdim
599212795Sdim  if (TypeSpecType != TST_unspecified) {
600212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
601212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
602212795Sdim    return true;
603212795Sdim  }
604212795Sdim  TypeSpecType = T;
605212795Sdim  DeclRep = Rep;
606221345Sdim  TSTLoc = TagKwLoc;
607221345Sdim  TSTNameLoc = TagNameLoc;
608212795Sdim  TypeSpecOwned = Owned;
609212795Sdim  return false;
610212795Sdim}
611212795Sdim
612212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
613212795Sdim                               const char *&PrevSpec,
614212795Sdim                               unsigned &DiagID) {
615212795Sdim  assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
616212795Sdim         "rep required for these type-spec kinds!");
617212795Sdim  if (TypeSpecType != TST_unspecified) {
618212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
619212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
620212795Sdim    return true;
621212795Sdim  }
622221345Sdim  TSTLoc = Loc;
623221345Sdim  TSTNameLoc = Loc;
624212795Sdim  if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
625212795Sdim    TypeAltiVecBool = true;
626212795Sdim    return false;
627212795Sdim  }
628212795Sdim  TypeSpecType = T;
629212795Sdim  TypeSpecOwned = false;
630212795Sdim  if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
631212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
632212795Sdim    DiagID = diag::err_invalid_vector_decl_spec;
633212795Sdim    return true;
634212795Sdim  }
635212795Sdim  return false;
636212795Sdim}
637212795Sdim
638212795Sdimbool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
639212795Sdim                          const char *&PrevSpec, unsigned &DiagID) {
640212795Sdim  if (TypeSpecType != TST_unspecified) {
641212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
642212795Sdim    DiagID = diag::err_invalid_vector_decl_spec_combination;
643212795Sdim    return true;
644212795Sdim  }
645212795Sdim  TypeAltiVecVector = isAltiVecVector;
646212795Sdim  AltiVecLoc = Loc;
647212795Sdim  return false;
648212795Sdim}
649212795Sdim
650212795Sdimbool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
651212795Sdim                          const char *&PrevSpec, unsigned &DiagID) {
652212795Sdim  if (!TypeAltiVecVector || TypeAltiVecPixel ||
653212795Sdim      (TypeSpecType != TST_unspecified)) {
654212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
655212795Sdim    DiagID = diag::err_invalid_pixel_decl_spec_combination;
656212795Sdim    return true;
657212795Sdim  }
658212795Sdim  TypeAltiVecPixel = isAltiVecPixel;
659212795Sdim  TSTLoc = Loc;
660221345Sdim  TSTNameLoc = Loc;
661212795Sdim  return false;
662212795Sdim}
663212795Sdim
664212795Sdimbool DeclSpec::SetTypeSpecError() {
665212795Sdim  TypeSpecType = TST_error;
666212795Sdim  TypeSpecOwned = false;
667212795Sdim  TSTLoc = SourceLocation();
668221345Sdim  TSTNameLoc = SourceLocation();
669212795Sdim  return false;
670212795Sdim}
671212795Sdim
672212795Sdimbool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
673239462Sdim                           unsigned &DiagID, const LangOptions &Lang,
674239462Sdim                           bool IsTypeSpec) {
675239462Sdim  // Duplicates are permitted in C99, and are permitted in C++11 unless the
676239462Sdim  // cv-qualifier appears as a type-specifier.
677239462Sdim  if ((TypeQualifiers & T) && !Lang.C99 && (!Lang.CPlusPlus0x || IsTypeSpec))
678212795Sdim    return BadSpecifier(T, T, PrevSpec, DiagID);
679212795Sdim  TypeQualifiers |= T;
680212795Sdim
681212795Sdim  switch (T) {
682226633Sdim  default: llvm_unreachable("Unknown type qualifier!");
683212795Sdim  case TQ_const:    TQ_constLoc = Loc; break;
684212795Sdim  case TQ_restrict: TQ_restrictLoc = Loc; break;
685212795Sdim  case TQ_volatile: TQ_volatileLoc = Loc; break;
686212795Sdim  }
687212795Sdim  return false;
688212795Sdim}
689212795Sdim
690212795Sdimbool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
691212795Sdim                                     unsigned &DiagID) {
692212795Sdim  // 'inline inline' is ok.
693212795Sdim  FS_inline_specified = true;
694212795Sdim  FS_inlineLoc = Loc;
695212795Sdim  return false;
696212795Sdim}
697212795Sdim
698212795Sdimbool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
699212795Sdim                                      unsigned &DiagID) {
700212795Sdim  // 'virtual virtual' is ok.
701212795Sdim  FS_virtual_specified = true;
702212795Sdim  FS_virtualLoc = Loc;
703212795Sdim  return false;
704212795Sdim}
705212795Sdim
706212795Sdimbool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
707212795Sdim                                       unsigned &DiagID) {
708212795Sdim  // 'explicit explicit' is ok.
709212795Sdim  FS_explicit_specified = true;
710212795Sdim  FS_explicitLoc = Loc;
711212795Sdim  return false;
712212795Sdim}
713212795Sdim
714212795Sdimbool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
715212795Sdim                             unsigned &DiagID) {
716212795Sdim  if (Friend_specified) {
717212795Sdim    PrevSpec = "friend";
718212795Sdim    DiagID = diag::ext_duplicate_declspec;
719212795Sdim    return true;
720212795Sdim  }
721212795Sdim
722212795Sdim  Friend_specified = true;
723212795Sdim  FriendLoc = Loc;
724212795Sdim  return false;
725212795Sdim}
726212795Sdim
727226633Sdimbool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
728226633Sdim                                    unsigned &DiagID) {
729226633Sdim  if (isModulePrivateSpecified()) {
730226633Sdim    PrevSpec = "__module_private__";
731226633Sdim    DiagID = diag::ext_duplicate_declspec;
732226633Sdim    return true;
733226633Sdim  }
734226633Sdim
735226633Sdim  ModulePrivateLoc = Loc;
736226633Sdim  return false;
737226633Sdim}
738226633Sdim
739212795Sdimbool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
740212795Sdim                                unsigned &DiagID) {
741212795Sdim  // 'constexpr constexpr' is ok.
742212795Sdim  Constexpr_specified = true;
743212795Sdim  ConstexprLoc = Loc;
744212795Sdim  return false;
745212795Sdim}
746212795Sdim
747212795Sdimvoid DeclSpec::setProtocolQualifiers(Decl * const *Protos,
748212795Sdim                                     unsigned NP,
749212795Sdim                                     SourceLocation *ProtoLocs,
750212795Sdim                                     SourceLocation LAngleLoc) {
751212795Sdim  if (NP == 0) return;
752212795Sdim  ProtocolQualifiers = new Decl*[NP];
753212795Sdim  ProtocolLocs = new SourceLocation[NP];
754212795Sdim  memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP);
755212795Sdim  memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
756212795Sdim  NumProtocolQualifiers = NP;
757212795Sdim  ProtocolLAngleLoc = LAngleLoc;
758212795Sdim}
759212795Sdim
760212795Sdimvoid DeclSpec::SaveWrittenBuiltinSpecs() {
761212795Sdim  writtenBS.Sign = getTypeSpecSign();
762212795Sdim  writtenBS.Width = getTypeSpecWidth();
763212795Sdim  writtenBS.Type = getTypeSpecType();
764212795Sdim  // Search the list of attributes for the presence of a mode attribute.
765212795Sdim  writtenBS.ModeAttr = false;
766218893Sdim  AttributeList* attrs = getAttributes().getList();
767212795Sdim  while (attrs) {
768239462Sdim    if (attrs->getKind() == AttributeList::AT_Mode) {
769212795Sdim      writtenBS.ModeAttr = true;
770212795Sdim      break;
771212795Sdim    }
772212795Sdim    attrs = attrs->getNext();
773212795Sdim  }
774212795Sdim}
775212795Sdim
776212795Sdimvoid DeclSpec::SaveStorageSpecifierAsWritten() {
777212795Sdim  if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern)
778212795Sdim    // If 'extern' is part of a linkage specification,
779212795Sdim    // then it is not a storage class "as written".
780212795Sdim    StorageClassSpecAsWritten = SCS_unspecified;
781212795Sdim  else
782212795Sdim    StorageClassSpecAsWritten = StorageClassSpec;
783212795Sdim}
784212795Sdim
785212795Sdim/// Finish - This does final analysis of the declspec, rejecting things like
786212795Sdim/// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
787212795Sdim/// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
788212795Sdim/// DeclSpec is guaranteed self-consistent, even if an error occurred.
789226633Sdimvoid DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
790212795Sdim  // Before possibly changing their values, save specs as written.
791212795Sdim  SaveWrittenBuiltinSpecs();
792212795Sdim  SaveStorageSpecifierAsWritten();
793212795Sdim
794212795Sdim  // Check the type specifier components first.
795212795Sdim
796212795Sdim  // Validate and finalize AltiVec vector declspec.
797212795Sdim  if (TypeAltiVecVector) {
798212795Sdim    if (TypeAltiVecBool) {
799212795Sdim      // Sign specifiers are not allowed with vector bool. (PIM 2.1)
800212795Sdim      if (TypeSpecSign != TSS_unspecified) {
801218893Sdim        Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
802212795Sdim          << getSpecifierName((TSS)TypeSpecSign);
803212795Sdim      }
804212795Sdim
805212795Sdim      // Only char/int are valid with vector bool. (PIM 2.1)
806212795Sdim      if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
807212795Sdim           (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
808218893Sdim        Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
809212795Sdim          << (TypeAltiVecPixel ? "__pixel" :
810212795Sdim                                 getSpecifierName((TST)TypeSpecType));
811212795Sdim      }
812212795Sdim
813212795Sdim      // Only 'short' is valid with vector bool. (PIM 2.1)
814212795Sdim      if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
815218893Sdim        Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
816212795Sdim          << getSpecifierName((TSW)TypeSpecWidth);
817212795Sdim
818212795Sdim      // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
819212795Sdim      if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
820212795Sdim          (TypeSpecWidth != TSW_unspecified))
821212795Sdim        TypeSpecSign = TSS_unsigned;
822212795Sdim    }
823212795Sdim
824212795Sdim    if (TypeAltiVecPixel) {
825212795Sdim      //TODO: perform validation
826212795Sdim      TypeSpecType = TST_int;
827212795Sdim      TypeSpecSign = TSS_unsigned;
828212795Sdim      TypeSpecWidth = TSW_short;
829212795Sdim      TypeSpecOwned = false;
830212795Sdim    }
831212795Sdim  }
832212795Sdim
833212795Sdim  // signed/unsigned are only valid with int/char/wchar_t.
834212795Sdim  if (TypeSpecSign != TSS_unspecified) {
835212795Sdim    if (TypeSpecType == TST_unspecified)
836212795Sdim      TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
837234353Sdim    else if (TypeSpecType != TST_int  && TypeSpecType != TST_int128 &&
838212795Sdim             TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
839218893Sdim      Diag(D, TSSLoc, diag::err_invalid_sign_spec)
840212795Sdim        << getSpecifierName((TST)TypeSpecType);
841212795Sdim      // signed double -> double.
842212795Sdim      TypeSpecSign = TSS_unspecified;
843212795Sdim    }
844212795Sdim  }
845212795Sdim
846212795Sdim  // Validate the width of the type.
847212795Sdim  switch (TypeSpecWidth) {
848212795Sdim  case TSW_unspecified: break;
849212795Sdim  case TSW_short:    // short int
850212795Sdim  case TSW_longlong: // long long int
851212795Sdim    if (TypeSpecType == TST_unspecified)
852212795Sdim      TypeSpecType = TST_int; // short -> short int, long long -> long long int.
853212795Sdim    else if (TypeSpecType != TST_int) {
854218893Sdim      Diag(D, TSWLoc,
855212795Sdim           TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
856212795Sdim                                      : diag::err_invalid_longlong_spec)
857212795Sdim        <<  getSpecifierName((TST)TypeSpecType);
858212795Sdim      TypeSpecType = TST_int;
859212795Sdim      TypeSpecOwned = false;
860212795Sdim    }
861212795Sdim    break;
862212795Sdim  case TSW_long:  // long double, long int
863212795Sdim    if (TypeSpecType == TST_unspecified)
864212795Sdim      TypeSpecType = TST_int;  // long -> long int.
865212795Sdim    else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
866218893Sdim      Diag(D, TSWLoc, diag::err_invalid_long_spec)
867212795Sdim        << getSpecifierName((TST)TypeSpecType);
868212795Sdim      TypeSpecType = TST_int;
869212795Sdim      TypeSpecOwned = false;
870212795Sdim    }
871212795Sdim    break;
872212795Sdim  }
873212795Sdim
874212795Sdim  // TODO: if the implementation does not implement _Complex or _Imaginary,
875212795Sdim  // disallow their use.  Need information about the backend.
876212795Sdim  if (TypeSpecComplex != TSC_unspecified) {
877212795Sdim    if (TypeSpecType == TST_unspecified) {
878218893Sdim      Diag(D, TSCLoc, diag::ext_plain_complex)
879212795Sdim        << FixItHint::CreateInsertion(
880212795Sdim                              PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
881212795Sdim                                                 " double");
882212795Sdim      TypeSpecType = TST_double;   // _Complex -> _Complex double.
883212795Sdim    } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
884212795Sdim      // Note that this intentionally doesn't include _Complex _Bool.
885234353Sdim      if (!PP.getLangOpts().CPlusPlus)
886234353Sdim        Diag(D, TSTLoc, diag::ext_integer_complex);
887212795Sdim    } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
888218893Sdim      Diag(D, TSCLoc, diag::err_invalid_complex_spec)
889212795Sdim        << getSpecifierName((TST)TypeSpecType);
890212795Sdim      TypeSpecComplex = TSC_unspecified;
891212795Sdim    }
892212795Sdim  }
893212795Sdim
894226633Sdim  // If no type specifier was provided and we're parsing a language where
895226633Sdim  // the type specifier is not optional, but we got 'auto' as a storage
896226633Sdim  // class specifier, then assume this is an attempt to use C++0x's 'auto'
897226633Sdim  // type specifier.
898226633Sdim  // FIXME: Does Microsoft really support implicit int in C++?
899234353Sdim  if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt &&
900226633Sdim      TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
901226633Sdim    TypeSpecType = TST_auto;
902226633Sdim    StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified;
903226633Sdim    TSTLoc = TSTNameLoc = StorageClassSpecLoc;
904226633Sdim    StorageClassSpecLoc = SourceLocation();
905226633Sdim  }
906226633Sdim  // Diagnose if we've recovered from an ill-formed 'auto' storage class
907226633Sdim  // specifier in a pre-C++0x dialect of C++.
908234353Sdim  if (!PP.getLangOpts().CPlusPlus0x && TypeSpecType == TST_auto)
909226633Sdim    Diag(D, TSTLoc, diag::ext_auto_type_specifier);
910234353Sdim  if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus0x &&
911226633Sdim      StorageClassSpec == SCS_auto)
912226633Sdim    Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
913226633Sdim      << FixItHint::CreateRemoval(StorageClassSpecLoc);
914234353Sdim  if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
915234353Sdim    Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
916234353Sdim      << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
917234353Sdim  if (Constexpr_specified)
918234353Sdim    Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
919226633Sdim
920212795Sdim  // C++ [class.friend]p6:
921212795Sdim  //   No storage-class-specifier shall appear in the decl-specifier-seq
922212795Sdim  //   of a friend declaration.
923212795Sdim  if (isFriendSpecified() && getStorageClassSpec()) {
924212795Sdim    DeclSpec::SCS SC = getStorageClassSpec();
925212795Sdim    const char *SpecName = getSpecifierName(SC);
926212795Sdim
927212795Sdim    SourceLocation SCLoc = getStorageClassSpecLoc();
928226633Sdim    SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName));
929212795Sdim
930218893Sdim    Diag(D, SCLoc, diag::err_friend_storage_spec)
931212795Sdim      << SpecName
932212795Sdim      << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
933212795Sdim
934212795Sdim    ClearStorageClassSpecs();
935212795Sdim  }
936212795Sdim
937212795Sdim  assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
938226633Sdim
939212795Sdim  // Okay, now we can infer the real type.
940212795Sdim
941212795Sdim  // TODO: return "auto function" and other bad things based on the real type.
942212795Sdim
943212795Sdim  // 'data definition has no type or storage class'?
944212795Sdim}
945212795Sdim
946212795Sdimbool DeclSpec::isMissingDeclaratorOk() {
947212795Sdim  TST tst = getTypeSpecType();
948212795Sdim  return isDeclRep(tst) && getRepAsDecl() != 0 &&
949212795Sdim    StorageClassSpec != DeclSpec::SCS_typedef;
950212795Sdim}
951212795Sdim
952212795Sdimvoid UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
953212795Sdim                                          OverloadedOperatorKind Op,
954212795Sdim                                          SourceLocation SymbolLocations[3]) {
955212795Sdim  Kind = IK_OperatorFunctionId;
956212795Sdim  StartLocation = OperatorLoc;
957212795Sdim  EndLocation = OperatorLoc;
958212795Sdim  OperatorFunctionId.Operator = Op;
959212795Sdim  for (unsigned I = 0; I != 3; ++I) {
960212795Sdim    OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
961212795Sdim
962212795Sdim    if (SymbolLocations[I].isValid())
963212795Sdim      EndLocation = SymbolLocations[I];
964212795Sdim  }
965212795Sdim}
966218893Sdim
967218893Sdimbool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
968218893Sdim                                  const char *&PrevSpec) {
969221345Sdim  LastLocation = Loc;
970221345Sdim
971218893Sdim  if (Specifiers & VS) {
972218893Sdim    PrevSpec = getSpecifierName(VS);
973218893Sdim    return true;
974218893Sdim  }
975218893Sdim
976218893Sdim  Specifiers |= VS;
977218893Sdim
978218893Sdim  switch (VS) {
979226633Sdim  default: llvm_unreachable("Unknown specifier!");
980218893Sdim  case VS_Override: VS_overrideLoc = Loc; break;
981218893Sdim  case VS_Final:    VS_finalLoc = Loc; break;
982218893Sdim  }
983218893Sdim
984218893Sdim  return false;
985218893Sdim}
986218893Sdim
987218893Sdimconst char *VirtSpecifiers::getSpecifierName(Specifier VS) {
988218893Sdim  switch (VS) {
989226633Sdim  default: llvm_unreachable("Unknown specifier");
990218893Sdim  case VS_Override: return "override";
991218893Sdim  case VS_Final: return "final";
992218893Sdim  }
993218893Sdim}
994