DeclSpec.cpp revision 249423
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"
16224145Sdim#include "clang/AST/Expr.h"
17219077Sdim#include "clang/AST/NestedNameSpecifier.h"
18219077Sdim#include "clang/AST/TypeLoc.h"
19249423Sdim#include "clang/Basic/LangOptions.h"
20212795Sdim#include "clang/Lex/Preprocessor.h"
21249423Sdim#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
22249423Sdim#include "clang/Sema/LocInfoType.h"
23249423Sdim#include "clang/Sema/ParsedTemplate.h"
24249423Sdim#include "clang/Sema/Sema.h"
25249423Sdim#include "clang/Sema/SemaDiagnostic.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.
147243830SdimDeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
148239462Sdim                                             bool isAmbiguous,
149243830Sdim                                             SourceLocation LParenLoc,
150212795Sdim                                             ParamInfo *ArgInfo,
151212795Sdim                                             unsigned NumArgs,
152243830Sdim                                             SourceLocation EllipsisLoc,
153243830Sdim                                             SourceLocation RParenLoc,
154212795Sdim                                             unsigned TypeQuals,
155218893Sdim                                             bool RefQualifierIsLvalueRef,
156218893Sdim                                             SourceLocation RefQualifierLoc,
157234353Sdim                                             SourceLocation ConstQualifierLoc,
158234353Sdim                                             SourceLocation
159234353Sdim                                                 VolatileQualifierLoc,
160224145Sdim                                             SourceLocation MutableLoc,
161221345Sdim                                             ExceptionSpecificationType
162221345Sdim                                                 ESpecType,
163221345Sdim                                             SourceLocation ESpecLoc,
164212795Sdim                                             ParsedType *Exceptions,
165212795Sdim                                             SourceRange *ExceptionRanges,
166212795Sdim                                             unsigned NumExceptions,
167221345Sdim                                             Expr *NoexceptExpr,
168221345Sdim                                             SourceLocation LocalRangeBegin,
169221345Sdim                                             SourceLocation LocalRangeEnd,
170218893Sdim                                             Declarator &TheDeclarator,
171239462Sdim                                             TypeResult TrailingReturnType) {
172249423Sdim  assert(!(TypeQuals & DeclSpec::TQ_atomic) &&
173249423Sdim         "function cannot have _Atomic qualifier");
174249423Sdim
175212795Sdim  DeclaratorChunk I;
176221345Sdim  I.Kind                        = Function;
177221345Sdim  I.Loc                         = LocalRangeBegin;
178221345Sdim  I.EndLoc                      = LocalRangeEnd;
179221345Sdim  I.Fun.AttrList                = 0;
180221345Sdim  I.Fun.hasPrototype            = hasProto;
181243830Sdim  I.Fun.isVariadic              = EllipsisLoc.isValid();
182239462Sdim  I.Fun.isAmbiguous             = isAmbiguous;
183243830Sdim  I.Fun.LParenLoc               = LParenLoc.getRawEncoding();
184221345Sdim  I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
185243830Sdim  I.Fun.RParenLoc               = RParenLoc.getRawEncoding();
186221345Sdim  I.Fun.DeleteArgInfo           = false;
187221345Sdim  I.Fun.TypeQuals               = TypeQuals;
188221345Sdim  I.Fun.NumArgs                 = NumArgs;
189221345Sdim  I.Fun.ArgInfo                 = 0;
190218893Sdim  I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
191221345Sdim  I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
192234353Sdim  I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
193234353Sdim  I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding();
194224145Sdim  I.Fun.MutableLoc              = MutableLoc.getRawEncoding();
195221345Sdim  I.Fun.ExceptionSpecType       = ESpecType;
196221345Sdim  I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
197221345Sdim  I.Fun.NumExceptions           = 0;
198221345Sdim  I.Fun.Exceptions              = 0;
199221345Sdim  I.Fun.NoexceptExpr            = 0;
200239462Sdim  I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
201239462Sdim                                  TrailingReturnType.isInvalid();
202239462Sdim  I.Fun.TrailingReturnType      = TrailingReturnType.get();
203212795Sdim
204212795Sdim  // new[] an argument array if needed.
205212795Sdim  if (NumArgs) {
206212795Sdim    // If the 'InlineParams' in Declarator is unused and big enough, put our
207212795Sdim    // parameter list there (in an effort to avoid new/delete traffic).  If it
208212795Sdim    // is already used (consider a function returning a function pointer) or too
209212795Sdim    // small (function taking too many arguments), go to the heap.
210212795Sdim    if (!TheDeclarator.InlineParamsUsed &&
211212795Sdim        NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
212212795Sdim      I.Fun.ArgInfo = TheDeclarator.InlineParams;
213212795Sdim      I.Fun.DeleteArgInfo = false;
214212795Sdim      TheDeclarator.InlineParamsUsed = true;
215212795Sdim    } else {
216212795Sdim      I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
217212795Sdim      I.Fun.DeleteArgInfo = true;
218212795Sdim    }
219212795Sdim    memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
220212795Sdim  }
221221345Sdim
222221345Sdim  // Check what exception specification information we should actually store.
223221345Sdim  switch (ESpecType) {
224221345Sdim  default: break; // By default, save nothing.
225221345Sdim  case EST_Dynamic:
226221345Sdim    // new[] an exception array if needed
227221345Sdim    if (NumExceptions) {
228221345Sdim      I.Fun.NumExceptions = NumExceptions;
229221345Sdim      I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
230221345Sdim      for (unsigned i = 0; i != NumExceptions; ++i) {
231221345Sdim        I.Fun.Exceptions[i].Ty = Exceptions[i];
232221345Sdim        I.Fun.Exceptions[i].Range = ExceptionRanges[i];
233221345Sdim      }
234212795Sdim    }
235221345Sdim    break;
236221345Sdim
237221345Sdim  case EST_ComputedNoexcept:
238221345Sdim    I.Fun.NoexceptExpr = NoexceptExpr;
239221345Sdim    break;
240212795Sdim  }
241212795Sdim  return I;
242212795Sdim}
243212795Sdim
244224145Sdimbool Declarator::isDeclarationOfFunction() const {
245224145Sdim  for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
246224145Sdim    switch (DeclTypeInfo[i].Kind) {
247224145Sdim    case DeclaratorChunk::Function:
248224145Sdim      return true;
249224145Sdim    case DeclaratorChunk::Paren:
250224145Sdim      continue;
251224145Sdim    case DeclaratorChunk::Pointer:
252224145Sdim    case DeclaratorChunk::Reference:
253224145Sdim    case DeclaratorChunk::Array:
254224145Sdim    case DeclaratorChunk::BlockPointer:
255224145Sdim    case DeclaratorChunk::MemberPointer:
256224145Sdim      return false;
257224145Sdim    }
258224145Sdim    llvm_unreachable("Invalid type chunk");
259224145Sdim  }
260224145Sdim
261224145Sdim  switch (DS.getTypeSpecType()) {
262226633Sdim    case TST_atomic:
263224145Sdim    case TST_auto:
264224145Sdim    case TST_bool:
265224145Sdim    case TST_char:
266224145Sdim    case TST_char16:
267224145Sdim    case TST_char32:
268224145Sdim    case TST_class:
269224145Sdim    case TST_decimal128:
270224145Sdim    case TST_decimal32:
271224145Sdim    case TST_decimal64:
272224145Sdim    case TST_double:
273224145Sdim    case TST_enum:
274224145Sdim    case TST_error:
275224145Sdim    case TST_float:
276226633Sdim    case TST_half:
277224145Sdim    case TST_int:
278234353Sdim    case TST_int128:
279224145Sdim    case TST_struct:
280243830Sdim    case TST_interface:
281224145Sdim    case TST_union:
282224145Sdim    case TST_unknown_anytype:
283224145Sdim    case TST_unspecified:
284224145Sdim    case TST_void:
285224145Sdim    case TST_wchar:
286249423Sdim    case TST_image1d_t:
287249423Sdim    case TST_image1d_array_t:
288249423Sdim    case TST_image1d_buffer_t:
289249423Sdim    case TST_image2d_t:
290249423Sdim    case TST_image2d_array_t:
291249423Sdim    case TST_image3d_t:
292249423Sdim    case TST_sampler_t:
293249423Sdim    case TST_event_t:
294224145Sdim      return false;
295224145Sdim
296224145Sdim    case TST_decltype:
297224145Sdim    case TST_typeofExpr:
298224145Sdim      if (Expr *E = DS.getRepAsExpr())
299224145Sdim        return E->getType()->isFunctionType();
300224145Sdim      return false;
301224145Sdim
302224145Sdim    case TST_underlyingType:
303224145Sdim    case TST_typename:
304224145Sdim    case TST_typeofType: {
305224145Sdim      QualType QT = DS.getRepAsType().get();
306224145Sdim      if (QT.isNull())
307224145Sdim        return false;
308224145Sdim
309224145Sdim      if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
310224145Sdim        QT = LIT->getType();
311224145Sdim
312224145Sdim      if (QT.isNull())
313224145Sdim        return false;
314224145Sdim
315224145Sdim      return QT->isFunctionType();
316224145Sdim    }
317224145Sdim  }
318234353Sdim
319234353Sdim  llvm_unreachable("Invalid TypeSpecType!");
320224145Sdim}
321224145Sdim
322212795Sdim/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
323212795Sdim/// declaration specifier includes.
324212795Sdim///
325212795Sdimunsigned DeclSpec::getParsedSpecifiers() const {
326212795Sdim  unsigned Res = 0;
327212795Sdim  if (StorageClassSpec != SCS_unspecified ||
328212795Sdim      SCS_thread_specified)
329212795Sdim    Res |= PQ_StorageClassSpecifier;
330212795Sdim
331212795Sdim  if (TypeQualifiers != TQ_unspecified)
332212795Sdim    Res |= PQ_TypeQualifier;
333212795Sdim
334212795Sdim  if (hasTypeSpecifier())
335212795Sdim    Res |= PQ_TypeSpecifier;
336212795Sdim
337249423Sdim  if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified ||
338249423Sdim      FS_noreturn_specified)
339212795Sdim    Res |= PQ_FunctionSpecifier;
340212795Sdim  return Res;
341212795Sdim}
342212795Sdim
343212795Sdimtemplate <class T> static bool BadSpecifier(T TNew, T TPrev,
344212795Sdim                                            const char *&PrevSpec,
345243830Sdim                                            unsigned &DiagID,
346243830Sdim                                            bool IsExtension = true) {
347212795Sdim  PrevSpec = DeclSpec::getSpecifierName(TPrev);
348243830Sdim  if (TNew != TPrev)
349243830Sdim    DiagID = diag::err_invalid_decl_spec_combination;
350243830Sdim  else
351243830Sdim    DiagID = IsExtension ? diag::ext_duplicate_declspec :
352243830Sdim                           diag::warn_duplicate_declspec;
353212795Sdim  return true;
354212795Sdim}
355212795Sdim
356212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
357212795Sdim  switch (S) {
358212795Sdim  case DeclSpec::SCS_unspecified: return "unspecified";
359212795Sdim  case DeclSpec::SCS_typedef:     return "typedef";
360212795Sdim  case DeclSpec::SCS_extern:      return "extern";
361212795Sdim  case DeclSpec::SCS_static:      return "static";
362212795Sdim  case DeclSpec::SCS_auto:        return "auto";
363212795Sdim  case DeclSpec::SCS_register:    return "register";
364212795Sdim  case DeclSpec::SCS_private_extern: return "__private_extern__";
365212795Sdim  case DeclSpec::SCS_mutable:     return "mutable";
366212795Sdim  }
367212795Sdim  llvm_unreachable("Unknown typespec!");
368212795Sdim}
369212795Sdim
370212795Sdimconst char *DeclSpec::getSpecifierName(TSW W) {
371212795Sdim  switch (W) {
372212795Sdim  case TSW_unspecified: return "unspecified";
373212795Sdim  case TSW_short:       return "short";
374212795Sdim  case TSW_long:        return "long";
375212795Sdim  case TSW_longlong:    return "long long";
376212795Sdim  }
377212795Sdim  llvm_unreachable("Unknown typespec!");
378212795Sdim}
379212795Sdim
380212795Sdimconst char *DeclSpec::getSpecifierName(TSC C) {
381212795Sdim  switch (C) {
382212795Sdim  case TSC_unspecified: return "unspecified";
383212795Sdim  case TSC_imaginary:   return "imaginary";
384212795Sdim  case TSC_complex:     return "complex";
385212795Sdim  }
386212795Sdim  llvm_unreachable("Unknown typespec!");
387212795Sdim}
388212795Sdim
389212795Sdim
390212795Sdimconst char *DeclSpec::getSpecifierName(TSS S) {
391212795Sdim  switch (S) {
392212795Sdim  case TSS_unspecified: return "unspecified";
393212795Sdim  case TSS_signed:      return "signed";
394212795Sdim  case TSS_unsigned:    return "unsigned";
395212795Sdim  }
396212795Sdim  llvm_unreachable("Unknown typespec!");
397212795Sdim}
398212795Sdim
399212795Sdimconst char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
400212795Sdim  switch (T) {
401212795Sdim  case DeclSpec::TST_unspecified: return "unspecified";
402212795Sdim  case DeclSpec::TST_void:        return "void";
403212795Sdim  case DeclSpec::TST_char:        return "char";
404212795Sdim  case DeclSpec::TST_wchar:       return "wchar_t";
405212795Sdim  case DeclSpec::TST_char16:      return "char16_t";
406212795Sdim  case DeclSpec::TST_char32:      return "char32_t";
407212795Sdim  case DeclSpec::TST_int:         return "int";
408234353Sdim  case DeclSpec::TST_int128:      return "__int128";
409226633Sdim  case DeclSpec::TST_half:        return "half";
410212795Sdim  case DeclSpec::TST_float:       return "float";
411212795Sdim  case DeclSpec::TST_double:      return "double";
412212795Sdim  case DeclSpec::TST_bool:        return "_Bool";
413212795Sdim  case DeclSpec::TST_decimal32:   return "_Decimal32";
414212795Sdim  case DeclSpec::TST_decimal64:   return "_Decimal64";
415212795Sdim  case DeclSpec::TST_decimal128:  return "_Decimal128";
416212795Sdim  case DeclSpec::TST_enum:        return "enum";
417212795Sdim  case DeclSpec::TST_class:       return "class";
418212795Sdim  case DeclSpec::TST_union:       return "union";
419212795Sdim  case DeclSpec::TST_struct:      return "struct";
420243830Sdim  case DeclSpec::TST_interface:   return "__interface";
421212795Sdim  case DeclSpec::TST_typename:    return "type-name";
422212795Sdim  case DeclSpec::TST_typeofType:
423212795Sdim  case DeclSpec::TST_typeofExpr:  return "typeof";
424212795Sdim  case DeclSpec::TST_auto:        return "auto";
425212795Sdim  case DeclSpec::TST_decltype:    return "(decltype)";
426223017Sdim  case DeclSpec::TST_underlyingType: return "__underlying_type";
427221345Sdim  case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
428226633Sdim  case DeclSpec::TST_atomic: return "_Atomic";
429249423Sdim  case DeclSpec::TST_image1d_t:   return "image1d_t";
430249423Sdim  case DeclSpec::TST_image1d_array_t: return "image1d_array_t";
431249423Sdim  case DeclSpec::TST_image1d_buffer_t: return "image1d_buffer_t";
432249423Sdim  case DeclSpec::TST_image2d_t:   return "image2d_t";
433249423Sdim  case DeclSpec::TST_image2d_array_t: return "image2d_array_t";
434249423Sdim  case DeclSpec::TST_image3d_t:   return "image3d_t";
435249423Sdim  case DeclSpec::TST_sampler_t:   return "sampler_t";
436249423Sdim  case DeclSpec::TST_event_t:     return "event_t";
437212795Sdim  case DeclSpec::TST_error:       return "(error)";
438212795Sdim  }
439212795Sdim  llvm_unreachable("Unknown typespec!");
440212795Sdim}
441212795Sdim
442212795Sdimconst char *DeclSpec::getSpecifierName(TQ T) {
443212795Sdim  switch (T) {
444212795Sdim  case DeclSpec::TQ_unspecified: return "unspecified";
445212795Sdim  case DeclSpec::TQ_const:       return "const";
446212795Sdim  case DeclSpec::TQ_restrict:    return "restrict";
447212795Sdim  case DeclSpec::TQ_volatile:    return "volatile";
448249423Sdim  case DeclSpec::TQ_atomic:      return "_Atomic";
449212795Sdim  }
450212795Sdim  llvm_unreachable("Unknown typespec!");
451212795Sdim}
452212795Sdim
453226633Sdimbool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
454212795Sdim                                   const char *&PrevSpec,
455226633Sdim                                   unsigned &DiagID) {
456239462Sdim  // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
457239462Sdim  // specifiers are not supported.
458218893Sdim  // It seems sensible to prohibit private_extern too
459226633Sdim  // The cl_clang_storage_class_specifiers extension enables support for
460226633Sdim  // these storage-class specifiers.
461239462Sdim  // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
462239462Sdim  // specifiers are not supported."
463234353Sdim  if (S.getLangOpts().OpenCL &&
464226633Sdim      !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
465226633Sdim    switch (SC) {
466218893Sdim    case SCS_extern:
467218893Sdim    case SCS_private_extern:
468239462Sdim    case SCS_static:
469239462Sdim        if (S.getLangOpts().OpenCLVersion < 120) {
470239462Sdim          DiagID   = diag::err_not_opencl_storage_class_specifier;
471239462Sdim          PrevSpec = getSpecifierName(SC);
472239462Sdim          return true;
473239462Sdim        }
474239462Sdim        break;
475218893Sdim    case SCS_auto:
476218893Sdim    case SCS_register:
477218893Sdim      DiagID   = diag::err_not_opencl_storage_class_specifier;
478226633Sdim      PrevSpec = getSpecifierName(SC);
479218893Sdim      return true;
480218893Sdim    default:
481218893Sdim      break;
482218893Sdim    }
483218893Sdim  }
484218893Sdim
485212795Sdim  if (StorageClassSpec != SCS_unspecified) {
486226633Sdim    // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
487226633Sdim    bool isInvalid = true;
488234353Sdim    if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
489226633Sdim      if (SC == SCS_auto)
490226633Sdim        return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
491226633Sdim      if (StorageClassSpec == SCS_auto) {
492226633Sdim        isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
493226633Sdim                                    PrevSpec, DiagID);
494226633Sdim        assert(!isInvalid && "auto SCS -> TST recovery failed");
495226633Sdim      }
496226633Sdim    }
497226633Sdim
498212795Sdim    // Changing storage class is allowed only if the previous one
499212795Sdim    // was the 'extern' that is part of a linkage specification and
500212795Sdim    // the new storage class is 'typedef'.
501226633Sdim    if (isInvalid &&
502226633Sdim        !(SCS_extern_in_linkage_spec &&
503212795Sdim          StorageClassSpec == SCS_extern &&
504226633Sdim          SC == SCS_typedef))
505226633Sdim      return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
506212795Sdim  }
507226633Sdim  StorageClassSpec = SC;
508212795Sdim  StorageClassSpecLoc = Loc;
509226633Sdim  assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
510212795Sdim  return false;
511212795Sdim}
512212795Sdim
513212795Sdimbool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
514212795Sdim                                         const char *&PrevSpec,
515212795Sdim                                         unsigned &DiagID) {
516212795Sdim  if (SCS_thread_specified) {
517212795Sdim    PrevSpec = "__thread";
518212795Sdim    DiagID = diag::ext_duplicate_declspec;
519212795Sdim    return true;
520212795Sdim  }
521212795Sdim  SCS_thread_specified = true;
522212795Sdim  SCS_threadLoc = Loc;
523212795Sdim  return false;
524212795Sdim}
525212795Sdim
526212795Sdim/// These methods set the specified attribute of the DeclSpec, but return true
527212795Sdim/// and ignore the request if invalid (e.g. "extern" then "auto" is
528212795Sdim/// specified).
529212795Sdimbool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
530212795Sdim                                const char *&PrevSpec,
531212795Sdim                                unsigned &DiagID) {
532221345Sdim  // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
533221345Sdim  // for 'long long' we will keep the source location of the first 'long'.
534221345Sdim  if (TypeSpecWidth == TSW_unspecified)
535221345Sdim    TSWLoc = Loc;
536221345Sdim  // Allow turning long -> long long.
537221345Sdim  else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
538212795Sdim    return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
539212795Sdim  TypeSpecWidth = W;
540212795Sdim  if (TypeAltiVecVector && !TypeAltiVecBool &&
541212795Sdim      ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
542212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
543212795Sdim    DiagID = diag::warn_vector_long_decl_spec_combination;
544212795Sdim    return true;
545212795Sdim  }
546212795Sdim  return false;
547212795Sdim}
548212795Sdim
549212795Sdimbool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
550212795Sdim                                  const char *&PrevSpec,
551212795Sdim                                  unsigned &DiagID) {
552212795Sdim  if (TypeSpecComplex != TSC_unspecified)
553212795Sdim    return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
554212795Sdim  TypeSpecComplex = C;
555212795Sdim  TSCLoc = Loc;
556212795Sdim  return false;
557212795Sdim}
558212795Sdim
559212795Sdimbool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
560212795Sdim                               const char *&PrevSpec,
561212795Sdim                               unsigned &DiagID) {
562212795Sdim  if (TypeSpecSign != TSS_unspecified)
563212795Sdim    return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
564212795Sdim  TypeSpecSign = S;
565212795Sdim  TSSLoc = Loc;
566212795Sdim  return false;
567212795Sdim}
568212795Sdim
569212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
570212795Sdim                               const char *&PrevSpec,
571212795Sdim                               unsigned &DiagID,
572212795Sdim                               ParsedType Rep) {
573221345Sdim  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep);
574221345Sdim}
575221345Sdim
576221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
577221345Sdim                               SourceLocation TagNameLoc,
578221345Sdim                               const char *&PrevSpec,
579221345Sdim                               unsigned &DiagID,
580221345Sdim                               ParsedType Rep) {
581212795Sdim  assert(isTypeRep(T) && "T does not store a type");
582212795Sdim  assert(Rep && "no type provided!");
583212795Sdim  if (TypeSpecType != TST_unspecified) {
584212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
585212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
586212795Sdim    return true;
587212795Sdim  }
588212795Sdim  TypeSpecType = T;
589212795Sdim  TypeRep = Rep;
590221345Sdim  TSTLoc = TagKwLoc;
591221345Sdim  TSTNameLoc = TagNameLoc;
592212795Sdim  TypeSpecOwned = false;
593212795Sdim  return false;
594212795Sdim}
595212795Sdim
596212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
597212795Sdim                               const char *&PrevSpec,
598212795Sdim                               unsigned &DiagID,
599212795Sdim                               Expr *Rep) {
600212795Sdim  assert(isExprRep(T) && "T does not store an expr");
601212795Sdim  assert(Rep && "no expression provided!");
602212795Sdim  if (TypeSpecType != TST_unspecified) {
603212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
604212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
605212795Sdim    return true;
606212795Sdim  }
607212795Sdim  TypeSpecType = T;
608212795Sdim  ExprRep = Rep;
609212795Sdim  TSTLoc = Loc;
610221345Sdim  TSTNameLoc = Loc;
611212795Sdim  TypeSpecOwned = false;
612212795Sdim  return false;
613212795Sdim}
614212795Sdim
615212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
616212795Sdim                               const char *&PrevSpec,
617212795Sdim                               unsigned &DiagID,
618212795Sdim                               Decl *Rep, bool Owned) {
619221345Sdim  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned);
620221345Sdim}
621221345Sdim
622221345Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
623221345Sdim                               SourceLocation TagNameLoc,
624221345Sdim                               const char *&PrevSpec,
625221345Sdim                               unsigned &DiagID,
626221345Sdim                               Decl *Rep, bool Owned) {
627212795Sdim  assert(isDeclRep(T) && "T does not store a decl");
628212795Sdim  // Unlike the other cases, we don't assert that we actually get a decl.
629212795Sdim
630212795Sdim  if (TypeSpecType != TST_unspecified) {
631212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
632212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
633212795Sdim    return true;
634212795Sdim  }
635212795Sdim  TypeSpecType = T;
636212795Sdim  DeclRep = Rep;
637221345Sdim  TSTLoc = TagKwLoc;
638221345Sdim  TSTNameLoc = TagNameLoc;
639212795Sdim  TypeSpecOwned = Owned;
640212795Sdim  return false;
641212795Sdim}
642212795Sdim
643212795Sdimbool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
644212795Sdim                               const char *&PrevSpec,
645212795Sdim                               unsigned &DiagID) {
646212795Sdim  assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
647212795Sdim         "rep required for these type-spec kinds!");
648212795Sdim  if (TypeSpecType != TST_unspecified) {
649212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
650212795Sdim    DiagID = diag::err_invalid_decl_spec_combination;
651212795Sdim    return true;
652212795Sdim  }
653221345Sdim  TSTLoc = Loc;
654221345Sdim  TSTNameLoc = Loc;
655212795Sdim  if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
656212795Sdim    TypeAltiVecBool = true;
657212795Sdim    return false;
658212795Sdim  }
659212795Sdim  TypeSpecType = T;
660212795Sdim  TypeSpecOwned = false;
661212795Sdim  if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
662212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
663212795Sdim    DiagID = diag::err_invalid_vector_decl_spec;
664212795Sdim    return true;
665212795Sdim  }
666212795Sdim  return false;
667212795Sdim}
668212795Sdim
669212795Sdimbool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
670212795Sdim                          const char *&PrevSpec, unsigned &DiagID) {
671212795Sdim  if (TypeSpecType != TST_unspecified) {
672212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
673212795Sdim    DiagID = diag::err_invalid_vector_decl_spec_combination;
674212795Sdim    return true;
675212795Sdim  }
676212795Sdim  TypeAltiVecVector = isAltiVecVector;
677212795Sdim  AltiVecLoc = Loc;
678212795Sdim  return false;
679212795Sdim}
680212795Sdim
681212795Sdimbool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
682212795Sdim                          const char *&PrevSpec, unsigned &DiagID) {
683212795Sdim  if (!TypeAltiVecVector || TypeAltiVecPixel ||
684212795Sdim      (TypeSpecType != TST_unspecified)) {
685212795Sdim    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
686212795Sdim    DiagID = diag::err_invalid_pixel_decl_spec_combination;
687212795Sdim    return true;
688212795Sdim  }
689212795Sdim  TypeAltiVecPixel = isAltiVecPixel;
690212795Sdim  TSTLoc = Loc;
691221345Sdim  TSTNameLoc = Loc;
692212795Sdim  return false;
693212795Sdim}
694212795Sdim
695212795Sdimbool DeclSpec::SetTypeSpecError() {
696212795Sdim  TypeSpecType = TST_error;
697212795Sdim  TypeSpecOwned = false;
698212795Sdim  TSTLoc = SourceLocation();
699221345Sdim  TSTNameLoc = SourceLocation();
700212795Sdim  return false;
701212795Sdim}
702212795Sdim
703212795Sdimbool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
704243830Sdim                           unsigned &DiagID, const LangOptions &Lang) {
705243830Sdim  // Duplicates are permitted in C99, but are not permitted in C++. However,
706243830Sdim  // since this is likely not what the user intended, we will always warn.  We
707243830Sdim  // do not need to set the qualifier's location since we already have it.
708243830Sdim  if (TypeQualifiers & T) {
709243830Sdim    bool IsExtension = true;
710243830Sdim    if (Lang.C99)
711243830Sdim      IsExtension = false;
712243830Sdim    return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
713243830Sdim  }
714212795Sdim  TypeQualifiers |= T;
715212795Sdim
716212795Sdim  switch (T) {
717249423Sdim  case TQ_unspecified: break;
718249423Sdim  case TQ_const:    TQ_constLoc = Loc; return false;
719249423Sdim  case TQ_restrict: TQ_restrictLoc = Loc; return false;
720249423Sdim  case TQ_volatile: TQ_volatileLoc = Loc; return false;
721249423Sdim  case TQ_atomic:   TQ_atomicLoc = Loc; return false;
722212795Sdim  }
723249423Sdim
724249423Sdim  llvm_unreachable("Unknown type qualifier!");
725212795Sdim}
726212795Sdim
727249423Sdimbool DeclSpec::setFunctionSpecInline(SourceLocation Loc) {
728212795Sdim  // 'inline inline' is ok.
729212795Sdim  FS_inline_specified = true;
730212795Sdim  FS_inlineLoc = Loc;
731212795Sdim  return false;
732212795Sdim}
733212795Sdim
734249423Sdimbool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc) {
735212795Sdim  // 'virtual virtual' is ok.
736212795Sdim  FS_virtual_specified = true;
737212795Sdim  FS_virtualLoc = Loc;
738212795Sdim  return false;
739212795Sdim}
740212795Sdim
741249423Sdimbool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc) {
742212795Sdim  // 'explicit explicit' is ok.
743212795Sdim  FS_explicit_specified = true;
744212795Sdim  FS_explicitLoc = Loc;
745212795Sdim  return false;
746212795Sdim}
747212795Sdim
748249423Sdimbool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc) {
749249423Sdim  // '_Noreturn _Noreturn' is ok.
750249423Sdim  FS_noreturn_specified = true;
751249423Sdim  FS_noreturnLoc = Loc;
752249423Sdim  return false;
753249423Sdim}
754249423Sdim
755212795Sdimbool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
756212795Sdim                             unsigned &DiagID) {
757212795Sdim  if (Friend_specified) {
758212795Sdim    PrevSpec = "friend";
759212795Sdim    DiagID = diag::ext_duplicate_declspec;
760212795Sdim    return true;
761212795Sdim  }
762212795Sdim
763212795Sdim  Friend_specified = true;
764212795Sdim  FriendLoc = Loc;
765212795Sdim  return false;
766212795Sdim}
767212795Sdim
768226633Sdimbool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
769226633Sdim                                    unsigned &DiagID) {
770226633Sdim  if (isModulePrivateSpecified()) {
771226633Sdim    PrevSpec = "__module_private__";
772226633Sdim    DiagID = diag::ext_duplicate_declspec;
773226633Sdim    return true;
774226633Sdim  }
775226633Sdim
776226633Sdim  ModulePrivateLoc = Loc;
777226633Sdim  return false;
778226633Sdim}
779226633Sdim
780212795Sdimbool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
781212795Sdim                                unsigned &DiagID) {
782212795Sdim  // 'constexpr constexpr' is ok.
783212795Sdim  Constexpr_specified = true;
784212795Sdim  ConstexprLoc = Loc;
785212795Sdim  return false;
786212795Sdim}
787212795Sdim
788212795Sdimvoid DeclSpec::setProtocolQualifiers(Decl * const *Protos,
789212795Sdim                                     unsigned NP,
790212795Sdim                                     SourceLocation *ProtoLocs,
791212795Sdim                                     SourceLocation LAngleLoc) {
792212795Sdim  if (NP == 0) return;
793249423Sdim  Decl **ProtoQuals = new Decl*[NP];
794249423Sdim  memcpy(ProtoQuals, Protos, sizeof(Decl*)*NP);
795249423Sdim  ProtocolQualifiers = ProtoQuals;
796212795Sdim  ProtocolLocs = new SourceLocation[NP];
797212795Sdim  memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
798212795Sdim  NumProtocolQualifiers = NP;
799212795Sdim  ProtocolLAngleLoc = LAngleLoc;
800212795Sdim}
801212795Sdim
802212795Sdimvoid DeclSpec::SaveWrittenBuiltinSpecs() {
803212795Sdim  writtenBS.Sign = getTypeSpecSign();
804212795Sdim  writtenBS.Width = getTypeSpecWidth();
805212795Sdim  writtenBS.Type = getTypeSpecType();
806212795Sdim  // Search the list of attributes for the presence of a mode attribute.
807212795Sdim  writtenBS.ModeAttr = false;
808218893Sdim  AttributeList* attrs = getAttributes().getList();
809212795Sdim  while (attrs) {
810239462Sdim    if (attrs->getKind() == AttributeList::AT_Mode) {
811212795Sdim      writtenBS.ModeAttr = true;
812212795Sdim      break;
813212795Sdim    }
814212795Sdim    attrs = attrs->getNext();
815212795Sdim  }
816212795Sdim}
817212795Sdim
818212795Sdim/// Finish - This does final analysis of the declspec, rejecting things like
819212795Sdim/// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
820212795Sdim/// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
821212795Sdim/// DeclSpec is guaranteed self-consistent, even if an error occurred.
822226633Sdimvoid DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
823212795Sdim  // Before possibly changing their values, save specs as written.
824212795Sdim  SaveWrittenBuiltinSpecs();
825212795Sdim
826212795Sdim  // Check the type specifier components first.
827212795Sdim
828212795Sdim  // Validate and finalize AltiVec vector declspec.
829212795Sdim  if (TypeAltiVecVector) {
830212795Sdim    if (TypeAltiVecBool) {
831212795Sdim      // Sign specifiers are not allowed with vector bool. (PIM 2.1)
832212795Sdim      if (TypeSpecSign != TSS_unspecified) {
833218893Sdim        Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
834212795Sdim          << getSpecifierName((TSS)TypeSpecSign);
835212795Sdim      }
836212795Sdim
837212795Sdim      // Only char/int are valid with vector bool. (PIM 2.1)
838212795Sdim      if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
839212795Sdim           (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
840218893Sdim        Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
841212795Sdim          << (TypeAltiVecPixel ? "__pixel" :
842212795Sdim                                 getSpecifierName((TST)TypeSpecType));
843212795Sdim      }
844212795Sdim
845212795Sdim      // Only 'short' is valid with vector bool. (PIM 2.1)
846212795Sdim      if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
847218893Sdim        Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
848212795Sdim          << getSpecifierName((TSW)TypeSpecWidth);
849212795Sdim
850212795Sdim      // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
851212795Sdim      if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
852212795Sdim          (TypeSpecWidth != TSW_unspecified))
853212795Sdim        TypeSpecSign = TSS_unsigned;
854212795Sdim    }
855212795Sdim
856212795Sdim    if (TypeAltiVecPixel) {
857212795Sdim      //TODO: perform validation
858212795Sdim      TypeSpecType = TST_int;
859212795Sdim      TypeSpecSign = TSS_unsigned;
860212795Sdim      TypeSpecWidth = TSW_short;
861212795Sdim      TypeSpecOwned = false;
862212795Sdim    }
863212795Sdim  }
864212795Sdim
865212795Sdim  // signed/unsigned are only valid with int/char/wchar_t.
866212795Sdim  if (TypeSpecSign != TSS_unspecified) {
867212795Sdim    if (TypeSpecType == TST_unspecified)
868212795Sdim      TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
869234353Sdim    else if (TypeSpecType != TST_int  && TypeSpecType != TST_int128 &&
870212795Sdim             TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
871218893Sdim      Diag(D, TSSLoc, diag::err_invalid_sign_spec)
872212795Sdim        << getSpecifierName((TST)TypeSpecType);
873212795Sdim      // signed double -> double.
874212795Sdim      TypeSpecSign = TSS_unspecified;
875212795Sdim    }
876212795Sdim  }
877212795Sdim
878212795Sdim  // Validate the width of the type.
879212795Sdim  switch (TypeSpecWidth) {
880212795Sdim  case TSW_unspecified: break;
881212795Sdim  case TSW_short:    // short int
882212795Sdim  case TSW_longlong: // long long int
883212795Sdim    if (TypeSpecType == TST_unspecified)
884212795Sdim      TypeSpecType = TST_int; // short -> short int, long long -> long long int.
885212795Sdim    else if (TypeSpecType != TST_int) {
886218893Sdim      Diag(D, TSWLoc,
887212795Sdim           TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
888212795Sdim                                      : diag::err_invalid_longlong_spec)
889212795Sdim        <<  getSpecifierName((TST)TypeSpecType);
890212795Sdim      TypeSpecType = TST_int;
891212795Sdim      TypeSpecOwned = false;
892212795Sdim    }
893212795Sdim    break;
894212795Sdim  case TSW_long:  // long double, long int
895212795Sdim    if (TypeSpecType == TST_unspecified)
896212795Sdim      TypeSpecType = TST_int;  // long -> long int.
897212795Sdim    else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
898218893Sdim      Diag(D, TSWLoc, diag::err_invalid_long_spec)
899212795Sdim        << getSpecifierName((TST)TypeSpecType);
900212795Sdim      TypeSpecType = TST_int;
901212795Sdim      TypeSpecOwned = false;
902212795Sdim    }
903212795Sdim    break;
904212795Sdim  }
905212795Sdim
906212795Sdim  // TODO: if the implementation does not implement _Complex or _Imaginary,
907212795Sdim  // disallow their use.  Need information about the backend.
908212795Sdim  if (TypeSpecComplex != TSC_unspecified) {
909212795Sdim    if (TypeSpecType == TST_unspecified) {
910218893Sdim      Diag(D, TSCLoc, diag::ext_plain_complex)
911212795Sdim        << FixItHint::CreateInsertion(
912212795Sdim                              PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
913212795Sdim                                                 " double");
914212795Sdim      TypeSpecType = TST_double;   // _Complex -> _Complex double.
915212795Sdim    } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
916212795Sdim      // Note that this intentionally doesn't include _Complex _Bool.
917234353Sdim      if (!PP.getLangOpts().CPlusPlus)
918234353Sdim        Diag(D, TSTLoc, diag::ext_integer_complex);
919212795Sdim    } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
920218893Sdim      Diag(D, TSCLoc, diag::err_invalid_complex_spec)
921212795Sdim        << getSpecifierName((TST)TypeSpecType);
922212795Sdim      TypeSpecComplex = TSC_unspecified;
923212795Sdim    }
924212795Sdim  }
925212795Sdim
926226633Sdim  // If no type specifier was provided and we're parsing a language where
927226633Sdim  // the type specifier is not optional, but we got 'auto' as a storage
928226633Sdim  // class specifier, then assume this is an attempt to use C++0x's 'auto'
929226633Sdim  // type specifier.
930226633Sdim  // FIXME: Does Microsoft really support implicit int in C++?
931234353Sdim  if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt &&
932226633Sdim      TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
933226633Sdim    TypeSpecType = TST_auto;
934249423Sdim    StorageClassSpec = SCS_unspecified;
935226633Sdim    TSTLoc = TSTNameLoc = StorageClassSpecLoc;
936226633Sdim    StorageClassSpecLoc = SourceLocation();
937226633Sdim  }
938226633Sdim  // Diagnose if we've recovered from an ill-formed 'auto' storage class
939226633Sdim  // specifier in a pre-C++0x dialect of C++.
940249423Sdim  if (!PP.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto)
941226633Sdim    Diag(D, TSTLoc, diag::ext_auto_type_specifier);
942249423Sdim  if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus11 &&
943226633Sdim      StorageClassSpec == SCS_auto)
944226633Sdim    Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
945226633Sdim      << FixItHint::CreateRemoval(StorageClassSpecLoc);
946234353Sdim  if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
947234353Sdim    Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
948234353Sdim      << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
949234353Sdim  if (Constexpr_specified)
950234353Sdim    Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
951226633Sdim
952212795Sdim  // C++ [class.friend]p6:
953212795Sdim  //   No storage-class-specifier shall appear in the decl-specifier-seq
954212795Sdim  //   of a friend declaration.
955212795Sdim  if (isFriendSpecified() && getStorageClassSpec()) {
956212795Sdim    DeclSpec::SCS SC = getStorageClassSpec();
957212795Sdim    const char *SpecName = getSpecifierName(SC);
958212795Sdim
959212795Sdim    SourceLocation SCLoc = getStorageClassSpecLoc();
960226633Sdim    SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName));
961212795Sdim
962218893Sdim    Diag(D, SCLoc, diag::err_friend_storage_spec)
963212795Sdim      << SpecName
964212795Sdim      << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
965212795Sdim
966212795Sdim    ClearStorageClassSpecs();
967212795Sdim  }
968212795Sdim
969212795Sdim  assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
970226633Sdim
971212795Sdim  // Okay, now we can infer the real type.
972212795Sdim
973212795Sdim  // TODO: return "auto function" and other bad things based on the real type.
974212795Sdim
975212795Sdim  // 'data definition has no type or storage class'?
976212795Sdim}
977212795Sdim
978212795Sdimbool DeclSpec::isMissingDeclaratorOk() {
979212795Sdim  TST tst = getTypeSpecType();
980212795Sdim  return isDeclRep(tst) && getRepAsDecl() != 0 &&
981212795Sdim    StorageClassSpec != DeclSpec::SCS_typedef;
982212795Sdim}
983212795Sdim
984212795Sdimvoid UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
985212795Sdim                                          OverloadedOperatorKind Op,
986212795Sdim                                          SourceLocation SymbolLocations[3]) {
987212795Sdim  Kind = IK_OperatorFunctionId;
988212795Sdim  StartLocation = OperatorLoc;
989212795Sdim  EndLocation = OperatorLoc;
990212795Sdim  OperatorFunctionId.Operator = Op;
991212795Sdim  for (unsigned I = 0; I != 3; ++I) {
992212795Sdim    OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
993212795Sdim
994212795Sdim    if (SymbolLocations[I].isValid())
995212795Sdim      EndLocation = SymbolLocations[I];
996212795Sdim  }
997212795Sdim}
998218893Sdim
999218893Sdimbool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
1000218893Sdim                                  const char *&PrevSpec) {
1001221345Sdim  LastLocation = Loc;
1002221345Sdim
1003218893Sdim  if (Specifiers & VS) {
1004218893Sdim    PrevSpec = getSpecifierName(VS);
1005218893Sdim    return true;
1006218893Sdim  }
1007218893Sdim
1008218893Sdim  Specifiers |= VS;
1009218893Sdim
1010218893Sdim  switch (VS) {
1011226633Sdim  default: llvm_unreachable("Unknown specifier!");
1012218893Sdim  case VS_Override: VS_overrideLoc = Loc; break;
1013218893Sdim  case VS_Final:    VS_finalLoc = Loc; break;
1014218893Sdim  }
1015218893Sdim
1016218893Sdim  return false;
1017218893Sdim}
1018218893Sdim
1019218893Sdimconst char *VirtSpecifiers::getSpecifierName(Specifier VS) {
1020218893Sdim  switch (VS) {
1021226633Sdim  default: llvm_unreachable("Unknown specifier");
1022218893Sdim  case VS_Override: return "override";
1023218893Sdim  case VS_Final: return "final";
1024218893Sdim  }
1025218893Sdim}
1026