clang API Documentation

DeclSpec.cpp
Go to the documentation of this file.
00001 //===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements semantic analysis for declaration specifiers.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
00015 #include "clang/Sema/DeclSpec.h"
00016 #include "clang/Sema/LocInfoType.h"
00017 #include "clang/Sema/ParsedTemplate.h"
00018 #include "clang/Sema/SemaDiagnostic.h"
00019 #include "clang/Sema/Sema.h"
00020 #include "clang/AST/ASTContext.h"
00021 #include "clang/AST/Expr.h"
00022 #include "clang/AST/NestedNameSpecifier.h"
00023 #include "clang/AST/TypeLoc.h"
00024 #include "clang/Lex/Preprocessor.h"
00025 #include "clang/Basic/LangOptions.h"
00026 #include "llvm/ADT/STLExtras.h"
00027 #include "llvm/Support/ErrorHandling.h"
00028 #include <cstring>
00029 using namespace clang;
00030 
00031 
00032 static DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc,
00033                               unsigned DiagID) {
00034   return D.Report(Loc, DiagID);
00035 }
00036 
00037 
00038 void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
00039   assert(TemplateId && "NULL template-id annotation?");
00040   Kind = IK_TemplateId;
00041   this->TemplateId = TemplateId;
00042   StartLocation = TemplateId->TemplateNameLoc;
00043   EndLocation = TemplateId->RAngleLoc;
00044 }
00045 
00046 void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
00047   assert(TemplateId && "NULL template-id annotation?");
00048   Kind = IK_ConstructorTemplateId;
00049   this->TemplateId = TemplateId;
00050   StartLocation = TemplateId->TemplateNameLoc;
00051   EndLocation = TemplateId->RAngleLoc;
00052 }
00053 
00054 void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc, 
00055                           TypeLoc TL, SourceLocation ColonColonLoc) {
00056   Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);
00057   if (Range.getBegin().isInvalid())
00058     Range.setBegin(TL.getBeginLoc());
00059   Range.setEnd(ColonColonLoc);
00060 
00061   assert(Range == Builder.getSourceRange() &&
00062          "NestedNameSpecifierLoc range computation incorrect");
00063 }
00064 
00065 void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
00066                           SourceLocation IdentifierLoc, 
00067                           SourceLocation ColonColonLoc) {
00068   Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
00069   
00070   if (Range.getBegin().isInvalid())
00071     Range.setBegin(IdentifierLoc);
00072   Range.setEnd(ColonColonLoc);
00073   
00074   assert(Range == Builder.getSourceRange() &&
00075          "NestedNameSpecifierLoc range computation incorrect");
00076 }
00077 
00078 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
00079                           SourceLocation NamespaceLoc, 
00080                           SourceLocation ColonColonLoc) {
00081   Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
00082   
00083   if (Range.getBegin().isInvalid())
00084     Range.setBegin(NamespaceLoc);
00085   Range.setEnd(ColonColonLoc);
00086 
00087   assert(Range == Builder.getSourceRange() &&
00088          "NestedNameSpecifierLoc range computation incorrect");
00089 }
00090 
00091 void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
00092                           SourceLocation AliasLoc, 
00093                           SourceLocation ColonColonLoc) {
00094   Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
00095   
00096   if (Range.getBegin().isInvalid())
00097     Range.setBegin(AliasLoc);
00098   Range.setEnd(ColonColonLoc);
00099 
00100   assert(Range == Builder.getSourceRange() &&
00101          "NestedNameSpecifierLoc range computation incorrect");
00102 }
00103 
00104 void CXXScopeSpec::MakeGlobal(ASTContext &Context, 
00105                               SourceLocation ColonColonLoc) {
00106   Builder.MakeGlobal(Context, ColonColonLoc);
00107   
00108   Range = SourceRange(ColonColonLoc);
00109   
00110   assert(Range == Builder.getSourceRange() &&
00111          "NestedNameSpecifierLoc range computation incorrect");
00112 }
00113 
00114 void CXXScopeSpec::MakeTrivial(ASTContext &Context, 
00115                                NestedNameSpecifier *Qualifier, SourceRange R) {
00116   Builder.MakeTrivial(Context, Qualifier, R);
00117   Range = R;
00118 }
00119 
00120 void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
00121   if (!Other) {
00122     Range = SourceRange();
00123     Builder.Clear();
00124     return;
00125   }
00126 
00127   Range = Other.getSourceRange();
00128   Builder.Adopt(Other);
00129 }
00130 
00131 SourceLocation CXXScopeSpec::getLastQualifierNameLoc() const {
00132   if (!Builder.getRepresentation())
00133     return SourceLocation();
00134   return Builder.getTemporary().getLocalBeginLoc();
00135 }
00136 
00137 NestedNameSpecifierLoc 
00138 CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
00139   if (!Builder.getRepresentation())
00140     return NestedNameSpecifierLoc();
00141   
00142   return Builder.getWithLocInContext(Context);
00143 }
00144 
00145 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
00146 /// "TheDeclarator" is the declarator that this will be added to.
00147 DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
00148                                              SourceLocation EllipsisLoc,
00149                                              ParamInfo *ArgInfo,
00150                                              unsigned NumArgs,
00151                                              unsigned TypeQuals,
00152                                              bool RefQualifierIsLvalueRef,
00153                                              SourceLocation RefQualifierLoc,
00154                                              SourceLocation ConstQualifierLoc,
00155                                              SourceLocation
00156                                                  VolatileQualifierLoc,
00157                                              SourceLocation MutableLoc,
00158                                              ExceptionSpecificationType
00159                                                  ESpecType,
00160                                              SourceLocation ESpecLoc,
00161                                              ParsedType *Exceptions,
00162                                              SourceRange *ExceptionRanges,
00163                                              unsigned NumExceptions,
00164                                              Expr *NoexceptExpr,
00165                                              SourceLocation LocalRangeBegin,
00166                                              SourceLocation LocalRangeEnd,
00167                                              Declarator &TheDeclarator,
00168                                              ParsedType TrailingReturnType) {
00169   DeclaratorChunk I;
00170   I.Kind                        = Function;
00171   I.Loc                         = LocalRangeBegin;
00172   I.EndLoc                      = LocalRangeEnd;
00173   I.Fun.AttrList                = 0;
00174   I.Fun.hasPrototype            = hasProto;
00175   I.Fun.isVariadic              = isVariadic;
00176   I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
00177   I.Fun.DeleteArgInfo           = false;
00178   I.Fun.TypeQuals               = TypeQuals;
00179   I.Fun.NumArgs                 = NumArgs;
00180   I.Fun.ArgInfo                 = 0;
00181   I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
00182   I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
00183   I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
00184   I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding();
00185   I.Fun.MutableLoc              = MutableLoc.getRawEncoding();
00186   I.Fun.ExceptionSpecType       = ESpecType;
00187   I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
00188   I.Fun.NumExceptions           = 0;
00189   I.Fun.Exceptions              = 0;
00190   I.Fun.NoexceptExpr            = 0;
00191   I.Fun.TrailingReturnType   = TrailingReturnType.getAsOpaquePtr();
00192 
00193   // new[] an argument array if needed.
00194   if (NumArgs) {
00195     // If the 'InlineParams' in Declarator is unused and big enough, put our
00196     // parameter list there (in an effort to avoid new/delete traffic).  If it
00197     // is already used (consider a function returning a function pointer) or too
00198     // small (function taking too many arguments), go to the heap.
00199     if (!TheDeclarator.InlineParamsUsed &&
00200         NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
00201       I.Fun.ArgInfo = TheDeclarator.InlineParams;
00202       I.Fun.DeleteArgInfo = false;
00203       TheDeclarator.InlineParamsUsed = true;
00204     } else {
00205       I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
00206       I.Fun.DeleteArgInfo = true;
00207     }
00208     memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
00209   }
00210 
00211   // Check what exception specification information we should actually store.
00212   switch (ESpecType) {
00213   default: break; // By default, save nothing.
00214   case EST_Dynamic:
00215     // new[] an exception array if needed
00216     if (NumExceptions) {
00217       I.Fun.NumExceptions = NumExceptions;
00218       I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
00219       for (unsigned i = 0; i != NumExceptions; ++i) {
00220         I.Fun.Exceptions[i].Ty = Exceptions[i];
00221         I.Fun.Exceptions[i].Range = ExceptionRanges[i];
00222       }
00223     }
00224     break;
00225 
00226   case EST_ComputedNoexcept:
00227     I.Fun.NoexceptExpr = NoexceptExpr;
00228     break;
00229   }
00230   return I;
00231 }
00232 
00233 bool Declarator::isDeclarationOfFunction() const {
00234   for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
00235     switch (DeclTypeInfo[i].Kind) {
00236     case DeclaratorChunk::Function:
00237       return true;
00238     case DeclaratorChunk::Paren:
00239       continue;
00240     case DeclaratorChunk::Pointer:
00241     case DeclaratorChunk::Reference:
00242     case DeclaratorChunk::Array:
00243     case DeclaratorChunk::BlockPointer:
00244     case DeclaratorChunk::MemberPointer:
00245       return false;
00246     }
00247     llvm_unreachable("Invalid type chunk");
00248   }
00249   
00250   switch (DS.getTypeSpecType()) {
00251     case TST_atomic:
00252     case TST_auto:
00253     case TST_bool:
00254     case TST_char:
00255     case TST_char16:
00256     case TST_char32:
00257     case TST_class:
00258     case TST_decimal128:
00259     case TST_decimal32:
00260     case TST_decimal64:
00261     case TST_double:
00262     case TST_enum:
00263     case TST_error:
00264     case TST_float:
00265     case TST_half:
00266     case TST_int:
00267     case TST_int128:
00268     case TST_struct:
00269     case TST_union:
00270     case TST_unknown_anytype:
00271     case TST_unspecified:
00272     case TST_void:
00273     case TST_wchar:
00274       return false;
00275 
00276     case TST_decltype:
00277     case TST_typeofExpr:
00278       if (Expr *E = DS.getRepAsExpr())
00279         return E->getType()->isFunctionType();
00280       return false;
00281      
00282     case TST_underlyingType:
00283     case TST_typename:
00284     case TST_typeofType: {
00285       QualType QT = DS.getRepAsType().get();
00286       if (QT.isNull())
00287         return false;
00288       
00289       if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
00290         QT = LIT->getType();
00291 
00292       if (QT.isNull())
00293         return false;
00294         
00295       return QT->isFunctionType();
00296     }
00297   }
00298 
00299   llvm_unreachable("Invalid TypeSpecType!");
00300 }
00301 
00302 /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
00303 /// declaration specifier includes.
00304 ///
00305 unsigned DeclSpec::getParsedSpecifiers() const {
00306   unsigned Res = 0;
00307   if (StorageClassSpec != SCS_unspecified ||
00308       SCS_thread_specified)
00309     Res |= PQ_StorageClassSpecifier;
00310 
00311   if (TypeQualifiers != TQ_unspecified)
00312     Res |= PQ_TypeQualifier;
00313 
00314   if (hasTypeSpecifier())
00315     Res |= PQ_TypeSpecifier;
00316 
00317   if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
00318     Res |= PQ_FunctionSpecifier;
00319   return Res;
00320 }
00321 
00322 template <class T> static bool BadSpecifier(T TNew, T TPrev,
00323                                             const char *&PrevSpec,
00324                                             unsigned &DiagID) {
00325   PrevSpec = DeclSpec::getSpecifierName(TPrev);
00326   DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
00327             : diag::err_invalid_decl_spec_combination);
00328   return true;
00329 }
00330 
00331 const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
00332   switch (S) {
00333   case DeclSpec::SCS_unspecified: return "unspecified";
00334   case DeclSpec::SCS_typedef:     return "typedef";
00335   case DeclSpec::SCS_extern:      return "extern";
00336   case DeclSpec::SCS_static:      return "static";
00337   case DeclSpec::SCS_auto:        return "auto";
00338   case DeclSpec::SCS_register:    return "register";
00339   case DeclSpec::SCS_private_extern: return "__private_extern__";
00340   case DeclSpec::SCS_mutable:     return "mutable";
00341   }
00342   llvm_unreachable("Unknown typespec!");
00343 }
00344 
00345 const char *DeclSpec::getSpecifierName(TSW W) {
00346   switch (W) {
00347   case TSW_unspecified: return "unspecified";
00348   case TSW_short:       return "short";
00349   case TSW_long:        return "long";
00350   case TSW_longlong:    return "long long";
00351   }
00352   llvm_unreachable("Unknown typespec!");
00353 }
00354 
00355 const char *DeclSpec::getSpecifierName(TSC C) {
00356   switch (C) {
00357   case TSC_unspecified: return "unspecified";
00358   case TSC_imaginary:   return "imaginary";
00359   case TSC_complex:     return "complex";
00360   }
00361   llvm_unreachable("Unknown typespec!");
00362 }
00363 
00364 
00365 const char *DeclSpec::getSpecifierName(TSS S) {
00366   switch (S) {
00367   case TSS_unspecified: return "unspecified";
00368   case TSS_signed:      return "signed";
00369   case TSS_unsigned:    return "unsigned";
00370   }
00371   llvm_unreachable("Unknown typespec!");
00372 }
00373 
00374 const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
00375   switch (T) {
00376   case DeclSpec::TST_unspecified: return "unspecified";
00377   case DeclSpec::TST_void:        return "void";
00378   case DeclSpec::TST_char:        return "char";
00379   case DeclSpec::TST_wchar:       return "wchar_t";
00380   case DeclSpec::TST_char16:      return "char16_t";
00381   case DeclSpec::TST_char32:      return "char32_t";
00382   case DeclSpec::TST_int:         return "int";
00383   case DeclSpec::TST_int128:      return "__int128";
00384   case DeclSpec::TST_half:        return "half";
00385   case DeclSpec::TST_float:       return "float";
00386   case DeclSpec::TST_double:      return "double";
00387   case DeclSpec::TST_bool:        return "_Bool";
00388   case DeclSpec::TST_decimal32:   return "_Decimal32";
00389   case DeclSpec::TST_decimal64:   return "_Decimal64";
00390   case DeclSpec::TST_decimal128:  return "_Decimal128";
00391   case DeclSpec::TST_enum:        return "enum";
00392   case DeclSpec::TST_class:       return "class";
00393   case DeclSpec::TST_union:       return "union";
00394   case DeclSpec::TST_struct:      return "struct";
00395   case DeclSpec::TST_typename:    return "type-name";
00396   case DeclSpec::TST_typeofType:
00397   case DeclSpec::TST_typeofExpr:  return "typeof";
00398   case DeclSpec::TST_auto:        return "auto";
00399   case DeclSpec::TST_decltype:    return "(decltype)";
00400   case DeclSpec::TST_underlyingType: return "__underlying_type";
00401   case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
00402   case DeclSpec::TST_atomic: return "_Atomic";
00403   case DeclSpec::TST_error:       return "(error)";
00404   }
00405   llvm_unreachable("Unknown typespec!");
00406 }
00407 
00408 const char *DeclSpec::getSpecifierName(TQ T) {
00409   switch (T) {
00410   case DeclSpec::TQ_unspecified: return "unspecified";
00411   case DeclSpec::TQ_const:       return "const";
00412   case DeclSpec::TQ_restrict:    return "restrict";
00413   case DeclSpec::TQ_volatile:    return "volatile";
00414   }
00415   llvm_unreachable("Unknown typespec!");
00416 }
00417 
00418 bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
00419                                    const char *&PrevSpec,
00420                                    unsigned &DiagID) {
00421   // OpenCL 1.1 6.8g: "The extern, static, auto and register storage-class
00422   // specifiers are not supported."
00423   // It seems sensible to prohibit private_extern too
00424   // The cl_clang_storage_class_specifiers extension enables support for
00425   // these storage-class specifiers.
00426   if (S.getLangOpts().OpenCL &&
00427       !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
00428     switch (SC) {
00429     case SCS_extern:
00430     case SCS_private_extern:
00431     case SCS_auto:
00432     case SCS_register:
00433     case SCS_static:
00434       DiagID   = diag::err_not_opencl_storage_class_specifier;
00435       PrevSpec = getSpecifierName(SC);
00436       return true;
00437     default:
00438       break;
00439     }
00440   }
00441 
00442   if (StorageClassSpec != SCS_unspecified) {
00443     // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
00444     bool isInvalid = true;
00445     if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
00446       if (SC == SCS_auto)
00447         return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
00448       if (StorageClassSpec == SCS_auto) {
00449         isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
00450                                     PrevSpec, DiagID);
00451         assert(!isInvalid && "auto SCS -> TST recovery failed");
00452       }
00453     }
00454 
00455     // Changing storage class is allowed only if the previous one
00456     // was the 'extern' that is part of a linkage specification and
00457     // the new storage class is 'typedef'.
00458     if (isInvalid &&
00459         !(SCS_extern_in_linkage_spec &&
00460           StorageClassSpec == SCS_extern &&
00461           SC == SCS_typedef))
00462       return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
00463   }
00464   StorageClassSpec = SC;
00465   StorageClassSpecLoc = Loc;
00466   assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
00467   return false;
00468 }
00469 
00470 bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
00471                                          const char *&PrevSpec,
00472                                          unsigned &DiagID) {
00473   if (SCS_thread_specified) {
00474     PrevSpec = "__thread";
00475     DiagID = diag::ext_duplicate_declspec;
00476     return true;
00477   }
00478   SCS_thread_specified = true;
00479   SCS_threadLoc = Loc;
00480   return false;
00481 }
00482 
00483 /// These methods set the specified attribute of the DeclSpec, but return true
00484 /// and ignore the request if invalid (e.g. "extern" then "auto" is
00485 /// specified).
00486 bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
00487                                 const char *&PrevSpec,
00488                                 unsigned &DiagID) {
00489   // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
00490   // for 'long long' we will keep the source location of the first 'long'.
00491   if (TypeSpecWidth == TSW_unspecified)
00492     TSWLoc = Loc;
00493   // Allow turning long -> long long.
00494   else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
00495     return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
00496   TypeSpecWidth = W;
00497   if (TypeAltiVecVector && !TypeAltiVecBool &&
00498       ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
00499     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
00500     DiagID = diag::warn_vector_long_decl_spec_combination;
00501     return true;
00502   }
00503   return false;
00504 }
00505 
00506 bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
00507                                   const char *&PrevSpec,
00508                                   unsigned &DiagID) {
00509   if (TypeSpecComplex != TSC_unspecified)
00510     return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
00511   TypeSpecComplex = C;
00512   TSCLoc = Loc;
00513   return false;
00514 }
00515 
00516 bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
00517                                const char *&PrevSpec,
00518                                unsigned &DiagID) {
00519   if (TypeSpecSign != TSS_unspecified)
00520     return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
00521   TypeSpecSign = S;
00522   TSSLoc = Loc;
00523   return false;
00524 }
00525 
00526 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
00527                                const char *&PrevSpec,
00528                                unsigned &DiagID,
00529                                ParsedType Rep) {
00530   return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep);
00531 }
00532 
00533 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
00534                                SourceLocation TagNameLoc,
00535                                const char *&PrevSpec,
00536                                unsigned &DiagID,
00537                                ParsedType Rep) {
00538   assert(isTypeRep(T) && "T does not store a type");
00539   assert(Rep && "no type provided!");
00540   if (TypeSpecType != TST_unspecified) {
00541     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
00542     DiagID = diag::err_invalid_decl_spec_combination;
00543     return true;
00544   }
00545   TypeSpecType = T;
00546   TypeRep = Rep;
00547   TSTLoc = TagKwLoc;
00548   TSTNameLoc = TagNameLoc;
00549   TypeSpecOwned = false;
00550   return false;
00551 }
00552 
00553 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
00554                                const char *&PrevSpec,
00555                                unsigned &DiagID,
00556                                Expr *Rep) {
00557   assert(isExprRep(T) && "T does not store an expr");
00558   assert(Rep && "no expression provided!");
00559   if (TypeSpecType != TST_unspecified) {
00560     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
00561     DiagID = diag::err_invalid_decl_spec_combination;
00562     return true;
00563   }
00564   TypeSpecType = T;
00565   ExprRep = Rep;
00566   TSTLoc = Loc;
00567   TSTNameLoc = Loc;
00568   TypeSpecOwned = false;
00569   return false;
00570 }
00571 
00572 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
00573                                const char *&PrevSpec,
00574                                unsigned &DiagID,
00575                                Decl *Rep, bool Owned) {
00576   return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned);
00577 }
00578 
00579 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
00580                                SourceLocation TagNameLoc,
00581                                const char *&PrevSpec,
00582                                unsigned &DiagID,
00583                                Decl *Rep, bool Owned) {
00584   assert(isDeclRep(T) && "T does not store a decl");
00585   // Unlike the other cases, we don't assert that we actually get a decl.
00586 
00587   if (TypeSpecType != TST_unspecified) {
00588     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
00589     DiagID = diag::err_invalid_decl_spec_combination;
00590     return true;
00591   }
00592   TypeSpecType = T;
00593   DeclRep = Rep;
00594   TSTLoc = TagKwLoc;
00595   TSTNameLoc = TagNameLoc;
00596   TypeSpecOwned = Owned;
00597   return false;
00598 }
00599 
00600 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
00601                                const char *&PrevSpec,
00602                                unsigned &DiagID) {
00603   assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
00604          "rep required for these type-spec kinds!");
00605   if (TypeSpecType != TST_unspecified) {
00606     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
00607     DiagID = diag::err_invalid_decl_spec_combination;
00608     return true;
00609   }
00610   TSTLoc = Loc;
00611   TSTNameLoc = Loc;
00612   if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
00613     TypeAltiVecBool = true;
00614     return false;
00615   }
00616   TypeSpecType = T;
00617   TypeSpecOwned = false;
00618   if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
00619     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
00620     DiagID = diag::err_invalid_vector_decl_spec;
00621     return true;
00622   }
00623   return false;
00624 }
00625 
00626 bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
00627                           const char *&PrevSpec, unsigned &DiagID) {
00628   if (TypeSpecType != TST_unspecified) {
00629     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
00630     DiagID = diag::err_invalid_vector_decl_spec_combination;
00631     return true;
00632   }
00633   TypeAltiVecVector = isAltiVecVector;
00634   AltiVecLoc = Loc;
00635   return false;
00636 }
00637 
00638 bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
00639                           const char *&PrevSpec, unsigned &DiagID) {
00640   if (!TypeAltiVecVector || TypeAltiVecPixel ||
00641       (TypeSpecType != TST_unspecified)) {
00642     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
00643     DiagID = diag::err_invalid_pixel_decl_spec_combination;
00644     return true;
00645   }
00646   TypeAltiVecPixel = isAltiVecPixel;
00647   TSTLoc = Loc;
00648   TSTNameLoc = Loc;
00649   return false;
00650 }
00651 
00652 bool DeclSpec::SetTypeSpecError() {
00653   TypeSpecType = TST_error;
00654   TypeSpecOwned = false;
00655   TSTLoc = SourceLocation();
00656   TSTNameLoc = SourceLocation();
00657   return false;
00658 }
00659 
00660 bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
00661                            unsigned &DiagID, const LangOptions &Lang) {
00662   // Duplicates turn into warnings pre-C99.
00663   if ((TypeQualifiers & T) && !Lang.C99)
00664     return BadSpecifier(T, T, PrevSpec, DiagID);
00665   TypeQualifiers |= T;
00666 
00667   switch (T) {
00668   default: llvm_unreachable("Unknown type qualifier!");
00669   case TQ_const:    TQ_constLoc = Loc; break;
00670   case TQ_restrict: TQ_restrictLoc = Loc; break;
00671   case TQ_volatile: TQ_volatileLoc = Loc; break;
00672   }
00673   return false;
00674 }
00675 
00676 bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
00677                                      unsigned &DiagID) {
00678   // 'inline inline' is ok.
00679   FS_inline_specified = true;
00680   FS_inlineLoc = Loc;
00681   return false;
00682 }
00683 
00684 bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
00685                                       unsigned &DiagID) {
00686   // 'virtual virtual' is ok.
00687   FS_virtual_specified = true;
00688   FS_virtualLoc = Loc;
00689   return false;
00690 }
00691 
00692 bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
00693                                        unsigned &DiagID) {
00694   // 'explicit explicit' is ok.
00695   FS_explicit_specified = true;
00696   FS_explicitLoc = Loc;
00697   return false;
00698 }
00699 
00700 bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
00701                              unsigned &DiagID) {
00702   if (Friend_specified) {
00703     PrevSpec = "friend";
00704     DiagID = diag::ext_duplicate_declspec;
00705     return true;
00706   }
00707 
00708   Friend_specified = true;
00709   FriendLoc = Loc;
00710   return false;
00711 }
00712 
00713 bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
00714                                     unsigned &DiagID) {
00715   if (isModulePrivateSpecified()) {
00716     PrevSpec = "__module_private__";
00717     DiagID = diag::ext_duplicate_declspec;
00718     return true;
00719   }
00720   
00721   ModulePrivateLoc = Loc;
00722   return false;
00723 }
00724 
00725 bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
00726                                 unsigned &DiagID) {
00727   // 'constexpr constexpr' is ok.
00728   Constexpr_specified = true;
00729   ConstexprLoc = Loc;
00730   return false;
00731 }
00732 
00733 void DeclSpec::setProtocolQualifiers(Decl * const *Protos,
00734                                      unsigned NP,
00735                                      SourceLocation *ProtoLocs,
00736                                      SourceLocation LAngleLoc) {
00737   if (NP == 0) return;
00738   ProtocolQualifiers = new Decl*[NP];
00739   ProtocolLocs = new SourceLocation[NP];
00740   memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP);
00741   memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
00742   NumProtocolQualifiers = NP;
00743   ProtocolLAngleLoc = LAngleLoc;
00744 }
00745 
00746 void DeclSpec::SaveWrittenBuiltinSpecs() {
00747   writtenBS.Sign = getTypeSpecSign();
00748   writtenBS.Width = getTypeSpecWidth();
00749   writtenBS.Type = getTypeSpecType();
00750   // Search the list of attributes for the presence of a mode attribute.
00751   writtenBS.ModeAttr = false;
00752   AttributeList* attrs = getAttributes().getList();
00753   while (attrs) {
00754     if (attrs->getKind() == AttributeList::AT_mode) {
00755       writtenBS.ModeAttr = true;
00756       break;
00757     }
00758     attrs = attrs->getNext();
00759   }
00760 }
00761 
00762 void DeclSpec::SaveStorageSpecifierAsWritten() {
00763   if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern)
00764     // If 'extern' is part of a linkage specification,
00765     // then it is not a storage class "as written".
00766     StorageClassSpecAsWritten = SCS_unspecified;
00767   else
00768     StorageClassSpecAsWritten = StorageClassSpec;
00769 }
00770 
00771 /// Finish - This does final analysis of the declspec, rejecting things like
00772 /// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
00773 /// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
00774 /// DeclSpec is guaranteed self-consistent, even if an error occurred.
00775 void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
00776   // Before possibly changing their values, save specs as written.
00777   SaveWrittenBuiltinSpecs();
00778   SaveStorageSpecifierAsWritten();
00779 
00780   // Check the type specifier components first.
00781 
00782   // Validate and finalize AltiVec vector declspec.
00783   if (TypeAltiVecVector) {
00784     if (TypeAltiVecBool) {
00785       // Sign specifiers are not allowed with vector bool. (PIM 2.1)
00786       if (TypeSpecSign != TSS_unspecified) {
00787         Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
00788           << getSpecifierName((TSS)TypeSpecSign);
00789       }
00790 
00791       // Only char/int are valid with vector bool. (PIM 2.1)
00792       if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
00793            (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
00794         Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
00795           << (TypeAltiVecPixel ? "__pixel" :
00796                                  getSpecifierName((TST)TypeSpecType));
00797       }
00798 
00799       // Only 'short' is valid with vector bool. (PIM 2.1)
00800       if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
00801         Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
00802           << getSpecifierName((TSW)TypeSpecWidth);
00803 
00804       // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
00805       if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
00806           (TypeSpecWidth != TSW_unspecified))
00807         TypeSpecSign = TSS_unsigned;
00808     }
00809 
00810     if (TypeAltiVecPixel) {
00811       //TODO: perform validation
00812       TypeSpecType = TST_int;
00813       TypeSpecSign = TSS_unsigned;
00814       TypeSpecWidth = TSW_short;
00815       TypeSpecOwned = false;
00816     }
00817   }
00818 
00819   // signed/unsigned are only valid with int/char/wchar_t.
00820   if (TypeSpecSign != TSS_unspecified) {
00821     if (TypeSpecType == TST_unspecified)
00822       TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
00823     else if (TypeSpecType != TST_int  && TypeSpecType != TST_int128 &&
00824              TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
00825       Diag(D, TSSLoc, diag::err_invalid_sign_spec)
00826         << getSpecifierName((TST)TypeSpecType);
00827       // signed double -> double.
00828       TypeSpecSign = TSS_unspecified;
00829     }
00830   }
00831 
00832   // Validate the width of the type.
00833   switch (TypeSpecWidth) {
00834   case TSW_unspecified: break;
00835   case TSW_short:    // short int
00836   case TSW_longlong: // long long int
00837     if (TypeSpecType == TST_unspecified)
00838       TypeSpecType = TST_int; // short -> short int, long long -> long long int.
00839     else if (TypeSpecType != TST_int) {
00840       Diag(D, TSWLoc,
00841            TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
00842                                       : diag::err_invalid_longlong_spec)
00843         <<  getSpecifierName((TST)TypeSpecType);
00844       TypeSpecType = TST_int;
00845       TypeSpecOwned = false;
00846     }
00847     break;
00848   case TSW_long:  // long double, long int
00849     if (TypeSpecType == TST_unspecified)
00850       TypeSpecType = TST_int;  // long -> long int.
00851     else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
00852       Diag(D, TSWLoc, diag::err_invalid_long_spec)
00853         << getSpecifierName((TST)TypeSpecType);
00854       TypeSpecType = TST_int;
00855       TypeSpecOwned = false;
00856     }
00857     break;
00858   }
00859 
00860   // TODO: if the implementation does not implement _Complex or _Imaginary,
00861   // disallow their use.  Need information about the backend.
00862   if (TypeSpecComplex != TSC_unspecified) {
00863     if (TypeSpecType == TST_unspecified) {
00864       Diag(D, TSCLoc, diag::ext_plain_complex)
00865         << FixItHint::CreateInsertion(
00866                               PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
00867                                                  " double");
00868       TypeSpecType = TST_double;   // _Complex -> _Complex double.
00869     } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
00870       // Note that this intentionally doesn't include _Complex _Bool.
00871       if (!PP.getLangOpts().CPlusPlus)
00872         Diag(D, TSTLoc, diag::ext_integer_complex);
00873     } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
00874       Diag(D, TSCLoc, diag::err_invalid_complex_spec)
00875         << getSpecifierName((TST)TypeSpecType);
00876       TypeSpecComplex = TSC_unspecified;
00877     }
00878   }
00879 
00880   // If no type specifier was provided and we're parsing a language where
00881   // the type specifier is not optional, but we got 'auto' as a storage
00882   // class specifier, then assume this is an attempt to use C++0x's 'auto'
00883   // type specifier.
00884   // FIXME: Does Microsoft really support implicit int in C++?
00885   if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt &&
00886       TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
00887     TypeSpecType = TST_auto;
00888     StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified;
00889     TSTLoc = TSTNameLoc = StorageClassSpecLoc;
00890     StorageClassSpecLoc = SourceLocation();
00891   }
00892   // Diagnose if we've recovered from an ill-formed 'auto' storage class
00893   // specifier in a pre-C++0x dialect of C++.
00894   if (!PP.getLangOpts().CPlusPlus0x && TypeSpecType == TST_auto)
00895     Diag(D, TSTLoc, diag::ext_auto_type_specifier);
00896   if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus0x &&
00897       StorageClassSpec == SCS_auto)
00898     Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
00899       << FixItHint::CreateRemoval(StorageClassSpecLoc);
00900   if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
00901     Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
00902       << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
00903   if (Constexpr_specified)
00904     Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
00905 
00906   // C++ [class.friend]p6:
00907   //   No storage-class-specifier shall appear in the decl-specifier-seq
00908   //   of a friend declaration.
00909   if (isFriendSpecified() && getStorageClassSpec()) {
00910     DeclSpec::SCS SC = getStorageClassSpec();
00911     const char *SpecName = getSpecifierName(SC);
00912 
00913     SourceLocation SCLoc = getStorageClassSpecLoc();
00914     SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName));
00915 
00916     Diag(D, SCLoc, diag::err_friend_storage_spec)
00917       << SpecName
00918       << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
00919 
00920     ClearStorageClassSpecs();
00921   }
00922 
00923   assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
00924  
00925   // Okay, now we can infer the real type.
00926 
00927   // TODO: return "auto function" and other bad things based on the real type.
00928 
00929   // 'data definition has no type or storage class'?
00930 }
00931 
00932 bool DeclSpec::isMissingDeclaratorOk() {
00933   TST tst = getTypeSpecType();
00934   return isDeclRep(tst) && getRepAsDecl() != 0 &&
00935     StorageClassSpec != DeclSpec::SCS_typedef;
00936 }
00937 
00938 void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 
00939                                           OverloadedOperatorKind Op,
00940                                           SourceLocation SymbolLocations[3]) {
00941   Kind = IK_OperatorFunctionId;
00942   StartLocation = OperatorLoc;
00943   EndLocation = OperatorLoc;
00944   OperatorFunctionId.Operator = Op;
00945   for (unsigned I = 0; I != 3; ++I) {
00946     OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
00947     
00948     if (SymbolLocations[I].isValid())
00949       EndLocation = SymbolLocations[I];
00950   }
00951 }
00952 
00953 bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
00954                                   const char *&PrevSpec) {
00955   LastLocation = Loc;
00956   
00957   if (Specifiers & VS) {
00958     PrevSpec = getSpecifierName(VS);
00959     return true;
00960   }
00961 
00962   Specifiers |= VS;
00963 
00964   switch (VS) {
00965   default: llvm_unreachable("Unknown specifier!");
00966   case VS_Override: VS_overrideLoc = Loc; break;
00967   case VS_Final:    VS_finalLoc = Loc; break;
00968   }
00969 
00970   return false;
00971 }
00972 
00973 const char *VirtSpecifiers::getSpecifierName(Specifier VS) {
00974   switch (VS) {
00975   default: llvm_unreachable("Unknown specifier");
00976   case VS_Override: return "override";
00977   case VS_Final: return "final";
00978   }
00979 }