DeclSpec.cpp revision 43f5103f8051bbac19022e6edaf7d9138b0f3c0f
1//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file implements semantic analysis for declaration specifiers.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
15#include "clang/Sema/DeclSpec.h"
16#include "clang/Sema/LocInfoType.h"
17#include "clang/Sema/ParsedTemplate.h"
18#include "clang/Sema/SemaDiagnostic.h"
19#include "clang/Sema/Sema.h"
20#include "clang/AST/ASTContext.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/NestedNameSpecifier.h"
23#include "clang/AST/TypeLoc.h"
24#include "clang/Lex/Preprocessor.h"
25#include "clang/Basic/LangOptions.h"
26#include "llvm/ADT/STLExtras.h"
27#include "llvm/Support/ErrorHandling.h"
28#include <cstring>
29using namespace clang;
30
31
32static DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc,
33                              unsigned DiagID) {
34  return D.Report(Loc, DiagID);
35}
36
37
38void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
39  assert(TemplateId && "NULL template-id annotation?");
40  Kind = IK_TemplateId;
41  this->TemplateId = TemplateId;
42  StartLocation = TemplateId->TemplateNameLoc;
43  EndLocation = TemplateId->RAngleLoc;
44}
45
46void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
47  assert(TemplateId && "NULL template-id annotation?");
48  Kind = IK_ConstructorTemplateId;
49  this->TemplateId = TemplateId;
50  StartLocation = TemplateId->TemplateNameLoc;
51  EndLocation = TemplateId->RAngleLoc;
52}
53
54void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,
55                          TypeLoc TL, SourceLocation ColonColonLoc) {
56  Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);
57  if (Range.getBegin().isInvalid())
58    Range.setBegin(TL.getBeginLoc());
59  Range.setEnd(ColonColonLoc);
60
61  assert(Range == Builder.getSourceRange() &&
62         "NestedNameSpecifierLoc range computation incorrect");
63}
64
65void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
66                          SourceLocation IdentifierLoc,
67                          SourceLocation ColonColonLoc) {
68  Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
69
70  if (Range.getBegin().isInvalid())
71    Range.setBegin(IdentifierLoc);
72  Range.setEnd(ColonColonLoc);
73
74  assert(Range == Builder.getSourceRange() &&
75         "NestedNameSpecifierLoc range computation incorrect");
76}
77
78void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
79                          SourceLocation NamespaceLoc,
80                          SourceLocation ColonColonLoc) {
81  Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
82
83  if (Range.getBegin().isInvalid())
84    Range.setBegin(NamespaceLoc);
85  Range.setEnd(ColonColonLoc);
86
87  assert(Range == Builder.getSourceRange() &&
88         "NestedNameSpecifierLoc range computation incorrect");
89}
90
91void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
92                          SourceLocation AliasLoc,
93                          SourceLocation ColonColonLoc) {
94  Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
95
96  if (Range.getBegin().isInvalid())
97    Range.setBegin(AliasLoc);
98  Range.setEnd(ColonColonLoc);
99
100  assert(Range == Builder.getSourceRange() &&
101         "NestedNameSpecifierLoc range computation incorrect");
102}
103
104void CXXScopeSpec::MakeGlobal(ASTContext &Context,
105                              SourceLocation ColonColonLoc) {
106  Builder.MakeGlobal(Context, ColonColonLoc);
107
108  Range = SourceRange(ColonColonLoc);
109
110  assert(Range == Builder.getSourceRange() &&
111         "NestedNameSpecifierLoc range computation incorrect");
112}
113
114void CXXScopeSpec::MakeTrivial(ASTContext &Context,
115                               NestedNameSpecifier *Qualifier, SourceRange R) {
116  Builder.MakeTrivial(Context, Qualifier, R);
117  Range = R;
118}
119
120void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
121  if (!Other) {
122    Range = SourceRange();
123    Builder.Clear();
124    return;
125  }
126
127  Range = Other.getSourceRange();
128  Builder.Adopt(Other);
129}
130
131SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const {
132  if (!Builder.getRepresentation())
133    return SourceLocation();
134  return Builder.getTemporary().getLocalBeginLoc();
135}
136
137NestedNameSpecifierLoc
138CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
139  if (!Builder.getRepresentation())
140    return NestedNameSpecifierLoc();
141
142  return Builder.getWithLocInContext(Context);
143}
144
145/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
146/// "TheDeclarator" is the declarator that this will be added to.
147DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
148                                             SourceLocation EllipsisLoc,
149                                             ParamInfo *ArgInfo,
150                                             unsigned NumArgs,
151                                             unsigned TypeQuals,
152                                             bool RefQualifierIsLvalueRef,
153                                             SourceLocation RefQualifierLoc,
154                                             SourceLocation ConstQualifierLoc,
155                                             SourceLocation
156                                                 VolatileQualifierLoc,
157                                             SourceLocation MutableLoc,
158                                             ExceptionSpecificationType
159                                                 ESpecType,
160                                             SourceLocation ESpecLoc,
161                                             ParsedType *Exceptions,
162                                             SourceRange *ExceptionRanges,
163                                             unsigned NumExceptions,
164                                             Expr *NoexceptExpr,
165                                             SourceLocation LocalRangeBegin,
166                                             SourceLocation LocalRangeEnd,
167                                             Declarator &TheDeclarator,
168                                             ParsedType TrailingReturnType) {
169  DeclaratorChunk I;
170  I.Kind                        = Function;
171  I.Loc                         = LocalRangeBegin;
172  I.EndLoc                      = LocalRangeEnd;
173  I.Fun.AttrList                = 0;
174  I.Fun.hasPrototype            = hasProto;
175  I.Fun.isVariadic              = isVariadic;
176  I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
177  I.Fun.DeleteArgInfo           = false;
178  I.Fun.TypeQuals               = TypeQuals;
179  I.Fun.NumArgs                 = NumArgs;
180  I.Fun.ArgInfo                 = 0;
181  I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
182  I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
183  I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
184  I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding();
185  I.Fun.MutableLoc              = MutableLoc.getRawEncoding();
186  I.Fun.ExceptionSpecType       = ESpecType;
187  I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
188  I.Fun.NumExceptions           = 0;
189  I.Fun.Exceptions              = 0;
190  I.Fun.NoexceptExpr            = 0;
191  I.Fun.TrailingReturnType   = TrailingReturnType.getAsOpaquePtr();
192
193  // new[] an argument array if needed.
194  if (NumArgs) {
195    // If the 'InlineParams' in Declarator is unused and big enough, put our
196    // parameter list there (in an effort to avoid new/delete traffic).  If it
197    // is already used (consider a function returning a function pointer) or too
198    // small (function taking too many arguments), go to the heap.
199    if (!TheDeclarator.InlineParamsUsed &&
200        NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
201      I.Fun.ArgInfo = TheDeclarator.InlineParams;
202      I.Fun.DeleteArgInfo = false;
203      TheDeclarator.InlineParamsUsed = true;
204    } else {
205      I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
206      I.Fun.DeleteArgInfo = true;
207    }
208    memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
209  }
210
211  // Check what exception specification information we should actually store.
212  switch (ESpecType) {
213  default: break; // By default, save nothing.
214  case EST_Dynamic:
215    // new[] an exception array if needed
216    if (NumExceptions) {
217      I.Fun.NumExceptions = NumExceptions;
218      I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
219      for (unsigned i = 0; i != NumExceptions; ++i) {
220        I.Fun.Exceptions[i].Ty = Exceptions[i];
221        I.Fun.Exceptions[i].Range = ExceptionRanges[i];
222      }
223    }
224    break;
225
226  case EST_ComputedNoexcept:
227    I.Fun.NoexceptExpr = NoexceptExpr;
228    break;
229  }
230  return I;
231}
232
233bool Declarator::isDeclarationOfFunction() const {
234  for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
235    switch (DeclTypeInfo[i].Kind) {
236    case DeclaratorChunk::Function:
237      return true;
238    case DeclaratorChunk::Paren:
239      continue;
240    case DeclaratorChunk::Pointer:
241    case DeclaratorChunk::Reference:
242    case DeclaratorChunk::Array:
243    case DeclaratorChunk::BlockPointer:
244    case DeclaratorChunk::MemberPointer:
245      return false;
246    }
247    llvm_unreachable("Invalid type chunk");
248    return false;
249  }
250
251  switch (DS.getTypeSpecType()) {
252    case TST_atomic:
253    case TST_auto:
254    case TST_bool:
255    case TST_char:
256    case TST_char16:
257    case TST_char32:
258    case TST_class:
259    case TST_decimal128:
260    case TST_decimal32:
261    case TST_decimal64:
262    case TST_double:
263    case TST_enum:
264    case TST_error:
265    case TST_float:
266    case TST_half:
267    case TST_int:
268    case TST_struct:
269    case TST_union:
270    case TST_unknown_anytype:
271    case TST_unspecified:
272    case TST_void:
273    case TST_wchar:
274      return false;
275
276    case TST_decltype:
277    case TST_typeofExpr:
278      if (Expr *E = DS.getRepAsExpr())
279        return E->getType()->isFunctionType();
280      return false;
281
282    case TST_underlyingType:
283    case TST_typename:
284    case TST_typeofType: {
285      QualType QT = DS.getRepAsType().get();
286      if (QT.isNull())
287        return false;
288
289      if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
290        QT = LIT->getType();
291
292      if (QT.isNull())
293        return false;
294
295      return QT->isFunctionType();
296    }
297  }
298
299  return false;
300}
301
302/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
303/// declaration specifier includes.
304///
305unsigned DeclSpec::getParsedSpecifiers() const {
306  unsigned Res = 0;
307  if (StorageClassSpec != SCS_unspecified ||
308      SCS_thread_specified)
309    Res |= PQ_StorageClassSpecifier;
310
311  if (TypeQualifiers != TQ_unspecified)
312    Res |= PQ_TypeQualifier;
313
314  if (hasTypeSpecifier())
315    Res |= PQ_TypeSpecifier;
316
317  if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
318    Res |= PQ_FunctionSpecifier;
319  return Res;
320}
321
322template <class T> static bool BadSpecifier(T TNew, T TPrev,
323                                            const char *&PrevSpec,
324                                            unsigned &DiagID) {
325  PrevSpec = DeclSpec::getSpecifierName(TPrev);
326  DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
327            : diag::err_invalid_decl_spec_combination);
328  return true;
329}
330
331const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
332  switch (S) {
333  case DeclSpec::SCS_unspecified: return "unspecified";
334  case DeclSpec::SCS_typedef:     return "typedef";
335  case DeclSpec::SCS_extern:      return "extern";
336  case DeclSpec::SCS_static:      return "static";
337  case DeclSpec::SCS_auto:        return "auto";
338  case DeclSpec::SCS_register:    return "register";
339  case DeclSpec::SCS_private_extern: return "__private_extern__";
340  case DeclSpec::SCS_mutable:     return "mutable";
341  }
342  llvm_unreachable("Unknown typespec!");
343}
344
345const char *DeclSpec::getSpecifierName(TSW W) {
346  switch (W) {
347  case TSW_unspecified: return "unspecified";
348  case TSW_short:       return "short";
349  case TSW_long:        return "long";
350  case TSW_longlong:    return "long long";
351  }
352  llvm_unreachable("Unknown typespec!");
353}
354
355const char *DeclSpec::getSpecifierName(TSC C) {
356  switch (C) {
357  case TSC_unspecified: return "unspecified";
358  case TSC_imaginary:   return "imaginary";
359  case TSC_complex:     return "complex";
360  }
361  llvm_unreachable("Unknown typespec!");
362}
363
364
365const char *DeclSpec::getSpecifierName(TSS S) {
366  switch (S) {
367  case TSS_unspecified: return "unspecified";
368  case TSS_signed:      return "signed";
369  case TSS_unsigned:    return "unsigned";
370  }
371  llvm_unreachable("Unknown typespec!");
372}
373
374const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
375  switch (T) {
376  case DeclSpec::TST_unspecified: return "unspecified";
377  case DeclSpec::TST_void:        return "void";
378  case DeclSpec::TST_char:        return "char";
379  case DeclSpec::TST_wchar:       return "wchar_t";
380  case DeclSpec::TST_char16:      return "char16_t";
381  case DeclSpec::TST_char32:      return "char32_t";
382  case DeclSpec::TST_int:         return "int";
383  case DeclSpec::TST_half:        return "half";
384  case DeclSpec::TST_float:       return "float";
385  case DeclSpec::TST_double:      return "double";
386  case DeclSpec::TST_bool:        return "_Bool";
387  case DeclSpec::TST_decimal32:   return "_Decimal32";
388  case DeclSpec::TST_decimal64:   return "_Decimal64";
389  case DeclSpec::TST_decimal128:  return "_Decimal128";
390  case DeclSpec::TST_enum:        return "enum";
391  case DeclSpec::TST_class:       return "class";
392  case DeclSpec::TST_union:       return "union";
393  case DeclSpec::TST_struct:      return "struct";
394  case DeclSpec::TST_typename:    return "type-name";
395  case DeclSpec::TST_typeofType:
396  case DeclSpec::TST_typeofExpr:  return "typeof";
397  case DeclSpec::TST_auto:        return "auto";
398  case DeclSpec::TST_decltype:    return "(decltype)";
399  case DeclSpec::TST_underlyingType: return "__underlying_type";
400  case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
401  case DeclSpec::TST_atomic: return "_Atomic";
402  case DeclSpec::TST_error:       return "(error)";
403  }
404  llvm_unreachable("Unknown typespec!");
405}
406
407const char *DeclSpec::getSpecifierName(TQ T) {
408  switch (T) {
409  case DeclSpec::TQ_unspecified: return "unspecified";
410  case DeclSpec::TQ_const:       return "const";
411  case DeclSpec::TQ_restrict:    return "restrict";
412  case DeclSpec::TQ_volatile:    return "volatile";
413  }
414  llvm_unreachable("Unknown typespec!");
415}
416
417bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
418                                   const char *&PrevSpec,
419                                   unsigned &DiagID) {
420  // OpenCL 1.1 6.8g: "The extern, static, auto and register storage-class
421  // specifiers are not supported."
422  // It seems sensible to prohibit private_extern too
423  // The cl_clang_storage_class_specifiers extension enables support for
424  // these storage-class specifiers.
425  if (S.getLangOptions().OpenCL &&
426      !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
427    switch (SC) {
428    case SCS_extern:
429    case SCS_private_extern:
430    case SCS_auto:
431    case SCS_register:
432    case SCS_static:
433      DiagID   = diag::err_not_opencl_storage_class_specifier;
434      PrevSpec = getSpecifierName(SC);
435      return true;
436    default:
437      break;
438    }
439  }
440
441  if (StorageClassSpec != SCS_unspecified) {
442    // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
443    bool isInvalid = true;
444    if (TypeSpecType == TST_unspecified && S.getLangOptions().CPlusPlus) {
445      if (SC == SCS_auto)
446        return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
447      if (StorageClassSpec == SCS_auto) {
448        isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
449                                    PrevSpec, DiagID);
450        assert(!isInvalid && "auto SCS -> TST recovery failed");
451      }
452    }
453
454    // Changing storage class is allowed only if the previous one
455    // was the 'extern' that is part of a linkage specification and
456    // the new storage class is 'typedef'.
457    if (isInvalid &&
458        !(SCS_extern_in_linkage_spec &&
459          StorageClassSpec == SCS_extern &&
460          SC == SCS_typedef))
461      return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
462  }
463  StorageClassSpec = SC;
464  StorageClassSpecLoc = Loc;
465  assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
466  return false;
467}
468
469bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
470                                         const char *&PrevSpec,
471                                         unsigned &DiagID) {
472  if (SCS_thread_specified) {
473    PrevSpec = "__thread";
474    DiagID = diag::ext_duplicate_declspec;
475    return true;
476  }
477  SCS_thread_specified = true;
478  SCS_threadLoc = Loc;
479  return false;
480}
481
482/// These methods set the specified attribute of the DeclSpec, but return true
483/// and ignore the request if invalid (e.g. "extern" then "auto" is
484/// specified).
485bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
486                                const char *&PrevSpec,
487                                unsigned &DiagID) {
488  // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
489  // for 'long long' we will keep the source location of the first 'long'.
490  if (TypeSpecWidth == TSW_unspecified)
491    TSWLoc = Loc;
492  // Allow turning long -> long long.
493  else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
494    return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
495  TypeSpecWidth = W;
496  if (TypeAltiVecVector && !TypeAltiVecBool &&
497      ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
498    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
499    DiagID = diag::warn_vector_long_decl_spec_combination;
500    return true;
501  }
502  return false;
503}
504
505bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
506                                  const char *&PrevSpec,
507                                  unsigned &DiagID) {
508  if (TypeSpecComplex != TSC_unspecified)
509    return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
510  TypeSpecComplex = C;
511  TSCLoc = Loc;
512  return false;
513}
514
515bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
516                               const char *&PrevSpec,
517                               unsigned &DiagID) {
518  if (TypeSpecSign != TSS_unspecified)
519    return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
520  TypeSpecSign = S;
521  TSSLoc = Loc;
522  return false;
523}
524
525bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
526                               const char *&PrevSpec,
527                               unsigned &DiagID,
528                               ParsedType Rep) {
529  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep);
530}
531
532bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
533                               SourceLocation TagNameLoc,
534                               const char *&PrevSpec,
535                               unsigned &DiagID,
536                               ParsedType Rep) {
537  assert(isTypeRep(T) && "T does not store a type");
538  assert(Rep && "no type provided!");
539  if (TypeSpecType != TST_unspecified) {
540    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
541    DiagID = diag::err_invalid_decl_spec_combination;
542    return true;
543  }
544  TypeSpecType = T;
545  TypeRep = Rep;
546  TSTLoc = TagKwLoc;
547  TSTNameLoc = TagNameLoc;
548  TypeSpecOwned = false;
549  return false;
550}
551
552bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
553                               const char *&PrevSpec,
554                               unsigned &DiagID,
555                               Expr *Rep) {
556  assert(isExprRep(T) && "T does not store an expr");
557  assert(Rep && "no expression provided!");
558  if (TypeSpecType != TST_unspecified) {
559    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
560    DiagID = diag::err_invalid_decl_spec_combination;
561    return true;
562  }
563  TypeSpecType = T;
564  ExprRep = Rep;
565  TSTLoc = Loc;
566  TSTNameLoc = Loc;
567  TypeSpecOwned = false;
568  return false;
569}
570
571bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
572                               const char *&PrevSpec,
573                               unsigned &DiagID,
574                               Decl *Rep, bool Owned) {
575  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned);
576}
577
578bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
579                               SourceLocation TagNameLoc,
580                               const char *&PrevSpec,
581                               unsigned &DiagID,
582                               Decl *Rep, bool Owned) {
583  assert(isDeclRep(T) && "T does not store a decl");
584  // Unlike the other cases, we don't assert that we actually get a decl.
585
586  if (TypeSpecType != TST_unspecified) {
587    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
588    DiagID = diag::err_invalid_decl_spec_combination;
589    return true;
590  }
591  TypeSpecType = T;
592  DeclRep = Rep;
593  TSTLoc = TagKwLoc;
594  TSTNameLoc = TagNameLoc;
595  TypeSpecOwned = Owned;
596  return false;
597}
598
599bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
600                               const char *&PrevSpec,
601                               unsigned &DiagID) {
602  assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
603         "rep required for these type-spec kinds!");
604  if (TypeSpecType != TST_unspecified) {
605    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
606    DiagID = diag::err_invalid_decl_spec_combination;
607    return true;
608  }
609  TSTLoc = Loc;
610  TSTNameLoc = Loc;
611  if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
612    TypeAltiVecBool = true;
613    return false;
614  }
615  TypeSpecType = T;
616  TypeSpecOwned = false;
617  if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
618    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
619    DiagID = diag::err_invalid_vector_decl_spec;
620    return true;
621  }
622  return false;
623}
624
625bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
626                          const char *&PrevSpec, unsigned &DiagID) {
627  if (TypeSpecType != TST_unspecified) {
628    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
629    DiagID = diag::err_invalid_vector_decl_spec_combination;
630    return true;
631  }
632  TypeAltiVecVector = isAltiVecVector;
633  AltiVecLoc = Loc;
634  return false;
635}
636
637bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
638                          const char *&PrevSpec, unsigned &DiagID) {
639  if (!TypeAltiVecVector || TypeAltiVecPixel ||
640      (TypeSpecType != TST_unspecified)) {
641    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
642    DiagID = diag::err_invalid_pixel_decl_spec_combination;
643    return true;
644  }
645  TypeAltiVecPixel = isAltiVecPixel;
646  TSTLoc = Loc;
647  TSTNameLoc = Loc;
648  return false;
649}
650
651bool DeclSpec::SetTypeSpecError() {
652  TypeSpecType = TST_error;
653  TypeSpecOwned = false;
654  TSTLoc = SourceLocation();
655  TSTNameLoc = SourceLocation();
656  return false;
657}
658
659bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
660                           unsigned &DiagID, const LangOptions &Lang) {
661  // Duplicates turn into warnings pre-C99.
662  if ((TypeQualifiers & T) && !Lang.C99)
663    return BadSpecifier(T, T, PrevSpec, DiagID);
664  TypeQualifiers |= T;
665
666  switch (T) {
667  default: llvm_unreachable("Unknown type qualifier!");
668  case TQ_const:    TQ_constLoc = Loc; break;
669  case TQ_restrict: TQ_restrictLoc = Loc; break;
670  case TQ_volatile: TQ_volatileLoc = Loc; break;
671  }
672  return false;
673}
674
675bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
676                                     unsigned &DiagID) {
677  // 'inline inline' is ok.
678  FS_inline_specified = true;
679  FS_inlineLoc = Loc;
680  return false;
681}
682
683bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
684                                      unsigned &DiagID) {
685  // 'virtual virtual' is ok.
686  FS_virtual_specified = true;
687  FS_virtualLoc = Loc;
688  return false;
689}
690
691bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
692                                       unsigned &DiagID) {
693  // 'explicit explicit' is ok.
694  FS_explicit_specified = true;
695  FS_explicitLoc = Loc;
696  return false;
697}
698
699bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
700                             unsigned &DiagID) {
701  if (Friend_specified) {
702    PrevSpec = "friend";
703    DiagID = diag::ext_duplicate_declspec;
704    return true;
705  }
706
707  Friend_specified = true;
708  FriendLoc = Loc;
709  return false;
710}
711
712bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
713                                    unsigned &DiagID) {
714  if (isModulePrivateSpecified()) {
715    PrevSpec = "__module_private__";
716    DiagID = diag::ext_duplicate_declspec;
717    return true;
718  }
719
720  ModulePrivateLoc = Loc;
721  return false;
722}
723
724bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
725                                unsigned &DiagID) {
726  // 'constexpr constexpr' is ok.
727  Constexpr_specified = true;
728  ConstexprLoc = Loc;
729  return false;
730}
731
732void DeclSpec::setProtocolQualifiers(Decl * const *Protos,
733                                     unsigned NP,
734                                     SourceLocation *ProtoLocs,
735                                     SourceLocation LAngleLoc) {
736  if (NP == 0) return;
737  ProtocolQualifiers = new Decl*[NP];
738  ProtocolLocs = new SourceLocation[NP];
739  memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP);
740  memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
741  NumProtocolQualifiers = NP;
742  ProtocolLAngleLoc = LAngleLoc;
743}
744
745void DeclSpec::SaveWrittenBuiltinSpecs() {
746  writtenBS.Sign = getTypeSpecSign();
747  writtenBS.Width = getTypeSpecWidth();
748  writtenBS.Type = getTypeSpecType();
749  // Search the list of attributes for the presence of a mode attribute.
750  writtenBS.ModeAttr = false;
751  AttributeList* attrs = getAttributes().getList();
752  while (attrs) {
753    if (attrs->getKind() == AttributeList::AT_mode) {
754      writtenBS.ModeAttr = true;
755      break;
756    }
757    attrs = attrs->getNext();
758  }
759}
760
761void DeclSpec::SaveStorageSpecifierAsWritten() {
762  if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern)
763    // If 'extern' is part of a linkage specification,
764    // then it is not a storage class "as written".
765    StorageClassSpecAsWritten = SCS_unspecified;
766  else
767    StorageClassSpecAsWritten = StorageClassSpec;
768}
769
770/// Finish - This does final analysis of the declspec, rejecting things like
771/// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
772/// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
773/// DeclSpec is guaranteed self-consistent, even if an error occurred.
774void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
775  // Before possibly changing their values, save specs as written.
776  SaveWrittenBuiltinSpecs();
777  SaveStorageSpecifierAsWritten();
778
779  // Check the type specifier components first.
780
781  // Validate and finalize AltiVec vector declspec.
782  if (TypeAltiVecVector) {
783    if (TypeAltiVecBool) {
784      // Sign specifiers are not allowed with vector bool. (PIM 2.1)
785      if (TypeSpecSign != TSS_unspecified) {
786        Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
787          << getSpecifierName((TSS)TypeSpecSign);
788      }
789
790      // Only char/int are valid with vector bool. (PIM 2.1)
791      if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
792           (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
793        Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
794          << (TypeAltiVecPixel ? "__pixel" :
795                                 getSpecifierName((TST)TypeSpecType));
796      }
797
798      // Only 'short' is valid with vector bool. (PIM 2.1)
799      if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
800        Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
801          << getSpecifierName((TSW)TypeSpecWidth);
802
803      // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
804      if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
805          (TypeSpecWidth != TSW_unspecified))
806        TypeSpecSign = TSS_unsigned;
807    }
808
809    if (TypeAltiVecPixel) {
810      //TODO: perform validation
811      TypeSpecType = TST_int;
812      TypeSpecSign = TSS_unsigned;
813      TypeSpecWidth = TSW_short;
814      TypeSpecOwned = false;
815    }
816  }
817
818  // signed/unsigned are only valid with int/char/wchar_t.
819  if (TypeSpecSign != TSS_unspecified) {
820    if (TypeSpecType == TST_unspecified)
821      TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
822    else if (TypeSpecType != TST_int  &&
823             TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
824      Diag(D, TSSLoc, diag::err_invalid_sign_spec)
825        << getSpecifierName((TST)TypeSpecType);
826      // signed double -> double.
827      TypeSpecSign = TSS_unspecified;
828    }
829  }
830
831  // Validate the width of the type.
832  switch (TypeSpecWidth) {
833  case TSW_unspecified: break;
834  case TSW_short:    // short int
835  case TSW_longlong: // long long int
836    if (TypeSpecType == TST_unspecified)
837      TypeSpecType = TST_int; // short -> short int, long long -> long long int.
838    else if (TypeSpecType != TST_int) {
839      Diag(D, TSWLoc,
840           TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
841                                      : diag::err_invalid_longlong_spec)
842        <<  getSpecifierName((TST)TypeSpecType);
843      TypeSpecType = TST_int;
844      TypeSpecOwned = false;
845    }
846    break;
847  case TSW_long:  // long double, long int
848    if (TypeSpecType == TST_unspecified)
849      TypeSpecType = TST_int;  // long -> long int.
850    else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
851      Diag(D, TSWLoc, diag::err_invalid_long_spec)
852        << getSpecifierName((TST)TypeSpecType);
853      TypeSpecType = TST_int;
854      TypeSpecOwned = false;
855    }
856    break;
857  }
858
859  // TODO: if the implementation does not implement _Complex or _Imaginary,
860  // disallow their use.  Need information about the backend.
861  if (TypeSpecComplex != TSC_unspecified) {
862    if (TypeSpecType == TST_unspecified) {
863      Diag(D, TSCLoc, diag::ext_plain_complex)
864        << FixItHint::CreateInsertion(
865                              PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
866                                                 " double");
867      TypeSpecType = TST_double;   // _Complex -> _Complex double.
868    } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
869      // Note that this intentionally doesn't include _Complex _Bool.
870      Diag(D, TSTLoc, diag::ext_integer_complex);
871    } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
872      Diag(D, TSCLoc, diag::err_invalid_complex_spec)
873        << getSpecifierName((TST)TypeSpecType);
874      TypeSpecComplex = TSC_unspecified;
875    }
876  }
877
878  // If no type specifier was provided and we're parsing a language where
879  // the type specifier is not optional, but we got 'auto' as a storage
880  // class specifier, then assume this is an attempt to use C++0x's 'auto'
881  // type specifier.
882  // FIXME: Does Microsoft really support implicit int in C++?
883  if (PP.getLangOptions().CPlusPlus && !PP.getLangOptions().MicrosoftExt &&
884      TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
885    TypeSpecType = TST_auto;
886    StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified;
887    TSTLoc = TSTNameLoc = StorageClassSpecLoc;
888    StorageClassSpecLoc = SourceLocation();
889  }
890  // Diagnose if we've recovered from an ill-formed 'auto' storage class
891  // specifier in a pre-C++0x dialect of C++.
892  if (!PP.getLangOptions().CPlusPlus0x && TypeSpecType == TST_auto)
893    Diag(D, TSTLoc, diag::ext_auto_type_specifier);
894  if (PP.getLangOptions().CPlusPlus && !PP.getLangOptions().CPlusPlus0x &&
895      StorageClassSpec == SCS_auto)
896    Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
897      << FixItHint::CreateRemoval(StorageClassSpecLoc);
898  if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
899    Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
900      << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
901  if (TypeSpecType == TST_decltype)
902    Diag(D, TSTLoc, diag::warn_cxx98_compat_decltype);
903  if (Constexpr_specified)
904    Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
905
906  // C++ [class.friend]p6:
907  //   No storage-class-specifier shall appear in the decl-specifier-seq
908  //   of a friend declaration.
909  if (isFriendSpecified() && getStorageClassSpec()) {
910    DeclSpec::SCS SC = getStorageClassSpec();
911    const char *SpecName = getSpecifierName(SC);
912
913    SourceLocation SCLoc = getStorageClassSpecLoc();
914    SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName));
915
916    Diag(D, SCLoc, diag::err_friend_storage_spec)
917      << SpecName
918      << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
919
920    ClearStorageClassSpecs();
921  }
922
923  assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
924
925  // Okay, now we can infer the real type.
926
927  // TODO: return "auto function" and other bad things based on the real type.
928
929  // 'data definition has no type or storage class'?
930}
931
932bool DeclSpec::isMissingDeclaratorOk() {
933  TST tst = getTypeSpecType();
934  return isDeclRep(tst) && getRepAsDecl() != 0 &&
935    StorageClassSpec != DeclSpec::SCS_typedef;
936}
937
938void UnqualifiedId::clear() {
939  Kind = IK_Identifier;
940  Identifier = 0;
941  StartLocation = SourceLocation();
942  EndLocation = SourceLocation();
943}
944
945void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
946                                          OverloadedOperatorKind Op,
947                                          SourceLocation SymbolLocations[3]) {
948  Kind = IK_OperatorFunctionId;
949  StartLocation = OperatorLoc;
950  EndLocation = OperatorLoc;
951  OperatorFunctionId.Operator = Op;
952  for (unsigned I = 0; I != 3; ++I) {
953    OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
954
955    if (SymbolLocations[I].isValid())
956      EndLocation = SymbolLocations[I];
957  }
958}
959
960bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
961                                  const char *&PrevSpec) {
962  LastLocation = Loc;
963
964  if (Specifiers & VS) {
965    PrevSpec = getSpecifierName(VS);
966    return true;
967  }
968
969  Specifiers |= VS;
970
971  switch (VS) {
972  default: llvm_unreachable("Unknown specifier!");
973  case VS_Override: VS_overrideLoc = Loc; break;
974  case VS_Final:    VS_finalLoc = Loc; break;
975  }
976
977  return false;
978}
979
980const char *VirtSpecifiers::getSpecifierName(Specifier VS) {
981  switch (VS) {
982  default: llvm_unreachable("Unknown specifier");
983  case VS_Override: return "override";
984  case VS_Final: return "final";
985  }
986}
987