zcov: / lib/Parse/DeclSpec.cpp


Files: 1 Branches Taken: 72.4% 152 / 210
Generated: 2010-02-10 01:31 Branches Executed: 86.7% 182 / 210
Line Coverage: 77.9% 243 / 312


Programs: 2 Runs 3018


       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/DeclSpec.h"
      15                 : #include "clang/Parse/ParseDiagnostic.h"
      16                 : #include "clang/Parse/Template.h"
      17                 : #include "clang/Lex/Preprocessor.h"
      18                 : #include "clang/Basic/LangOptions.h"
      19                 : #include "llvm/ADT/STLExtras.h"
      20                 : #include "llvm/Support/ErrorHandling.h"
      21                 : #include <cstring>
      22                 : using namespace clang;
      23                 : 
      24                 : 
      25                 : static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
      26               61:                               SourceManager &SrcMgr, unsigned DiagID) {
      27               61:   return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
      28                 : }
      29                 : 
      30                 : 
      31              230: void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
                        0: branch 0 not taken
                      230: branch 1 taken
      32              230:   assert(TemplateId && "NULL template-id annotation?");
      33              230:   Kind = IK_TemplateId;
      34              230:   this->TemplateId = TemplateId;
      35              230:   StartLocation = TemplateId->TemplateNameLoc;
      36              230:   EndLocation = TemplateId->RAngleLoc;
      37              230: }
      38                 : 
      39                5: void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
                        0: branch 0 not taken
                        5: branch 1 taken
      40                5:   assert(TemplateId && "NULL template-id annotation?");
      41                5:   Kind = IK_ConstructorTemplateId;
      42                5:   this->TemplateId = TemplateId;
      43                5:   StartLocation = TemplateId->TemplateNameLoc;
      44                5:   EndLocation = TemplateId->RAngleLoc;
      45                5: }
      46                 : 
      47                 : /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
      48                 : /// "TheDeclarator" is the declarator that this will be added to.
      49                 : DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
      50                 :                                              SourceLocation EllipsisLoc,
      51                 :                                              ParamInfo *ArgInfo,
      52                 :                                              unsigned NumArgs,
      53                 :                                              unsigned TypeQuals,
      54                 :                                              bool hasExceptionSpec,
      55                 :                                              SourceLocation ThrowLoc,
      56                 :                                              bool hasAnyExceptionSpec,
      57                 :                                              ActionBase::TypeTy **Exceptions,
      58                 :                                              SourceRange *ExceptionRanges,
      59                 :                                              unsigned NumExceptions,
      60                 :                                              SourceLocation LPLoc,
      61                 :                                              SourceLocation RPLoc,
      62            14754:                                              Declarator &TheDeclarator) {
      63            14754:   DeclaratorChunk I;
      64            14754:   I.Kind                 = Function;
      65            14754:   I.Loc                  = LPLoc;
      66            14754:   I.EndLoc               = RPLoc;
      67            14754:   I.Fun.hasPrototype     = hasProto;
      68            14754:   I.Fun.isVariadic       = isVariadic;
      69            14754:   I.Fun.EllipsisLoc      = EllipsisLoc.getRawEncoding();
      70            14754:   I.Fun.DeleteArgInfo    = false;
      71            14754:   I.Fun.TypeQuals        = TypeQuals;
      72            14754:   I.Fun.NumArgs          = NumArgs;
      73            14754:   I.Fun.ArgInfo          = 0;
      74            14754:   I.Fun.hasExceptionSpec = hasExceptionSpec;
      75            14754:   I.Fun.ThrowLoc         = ThrowLoc.getRawEncoding();
      76            14754:   I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
      77            14754:   I.Fun.NumExceptions    = NumExceptions;
      78            14754:   I.Fun.Exceptions       = 0;
      79                 : 
      80                 :   // new[] an argument array if needed.
                     9231: branch 0 taken
                     5523: branch 1 taken
      81            14754:   if (NumArgs) {
      82                 :     // If the 'InlineParams' in Declarator is unused and big enough, put our
      83                 :     // parameter list there (in an effort to avoid new/delete traffic).  If it
      84                 :     // is already used (consider a function returning a function pointer) or too
      85                 :     // small (function taking too many arguments), go to the heap.
                     9225: branch 0 taken
                        6: branch 1 taken
                     9224: branch 3 taken
                        1: branch 4 taken
                     9224: branch 5 taken
                        7: branch 6 taken
      86             9231:     if (!TheDeclarator.InlineParamsUsed &&
      87                 :         NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
      88             9224:       I.Fun.ArgInfo = TheDeclarator.InlineParams;
      89             9224:       I.Fun.DeleteArgInfo = false;
      90             9224:       TheDeclarator.InlineParamsUsed = true;
      91                 :     } else {
                       49: branch 2 taken
                        7: branch 3 taken
      92                7:       I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
      93                7:       I.Fun.DeleteArgInfo = true;
      94                 :     }
      95             9231:     memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
      96                 :   }
      97                 :   // new[] an exception array if needed
                       82: branch 0 taken
                    14672: branch 1 taken
      98            14754:   if (NumExceptions) {
                      102: branch 2 taken
                       82: branch 3 taken
      99               82:     I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
                      102: branch 0 taken
                       82: branch 1 taken
     100              184:     for (unsigned i = 0; i != NumExceptions; ++i) {
     101              102:       I.Fun.Exceptions[i].Ty = Exceptions[i];
     102              102:       I.Fun.Exceptions[i].Range = ExceptionRanges[i];
     103                 :     }
     104                 :   }
     105                 :   return I;
     106                 : }
     107                 : 
     108                 : /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
     109                 : /// declaration specifier includes.
     110                 : ///
     111            31527: unsigned DeclSpec::getParsedSpecifiers() const {
     112            31527:   unsigned Res = 0;
                    31403: branch 0 taken
                      124: branch 1 taken
                        2: branch 2 taken
                    31401: branch 3 taken
     113            31527:   if (StorageClassSpec != SCS_unspecified ||
     114                 :       SCS_thread_specified)
     115              126:     Res |= PQ_StorageClassSpecifier;
     116                 : 
                     1496: branch 0 taken
                    30031: branch 1 taken
     117            31527:   if (TypeQualifiers != TQ_unspecified)
     118             1496:     Res |= PQ_TypeQualifier;
     119                 : 
                    31373: branch 1 taken
                      154: branch 2 taken
     120            31527:   if (hasTypeSpecifier())
     121            31373:     Res |= PQ_TypeSpecifier;
     122                 : 
                    31508: branch 0 taken
                       19: branch 1 taken
                    31508: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                    31508: branch 5 taken
     123            31527:   if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
     124               19:     Res |= PQ_FunctionSpecifier;
     125            31527:   return Res;
     126                 : }
     127                 : 
     128                 : template <class T> static bool BadSpecifier(T TNew, T TPrev,
     129                 :                                             const char *&PrevSpec,
     130                1:                                             unsigned &DiagID) {
     131                1:   PrevSpec = DeclSpec::getSpecifierName(TPrev);
                        1: branch 0 taken
                        1: branch 1 taken
                        1: branch 2 taken
                        1: branch 3 taken
                        1: branch 4 taken
                        1: branch 5 taken
                        1: branch 6 taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     132                1:   DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
     133                 :             : diag::err_invalid_decl_spec_combination);
     134                1:   return true;
     135                 : }
     136                 : 
     137                7: const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
                        0: branch 0 not taken
                        1: branch 1 taken
                        1: branch 2 taken
                        1: branch 3 taken
                        1: branch 4 taken
                        1: branch 5 taken
                        0: branch 6 not taken
                        2: branch 7 taken
                        0: branch 8 not taken
     138                7:   switch (S) {
     139                0:   case DeclSpec::SCS_unspecified: return "unspecified";
     140                1:   case DeclSpec::SCS_typedef:     return "typedef";
     141                1:   case DeclSpec::SCS_extern:      return "extern";
     142                1:   case DeclSpec::SCS_static:      return "static";
     143                1:   case DeclSpec::SCS_auto:        return "auto";
     144                1:   case DeclSpec::SCS_register:    return "register";
     145                0:   case DeclSpec::SCS_private_extern: return "__private_extern__";
     146                2:   case DeclSpec::SCS_mutable:     return "mutable";
     147                 :   }
     148                0:   llvm_unreachable("Unknown typespec!");
     149                 : }
     150                 : 
     151                0: const char *DeclSpec::getSpecifierName(TSW W) {
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
     152                0:   switch (W) {
     153                0:   case TSW_unspecified: return "unspecified";
     154                0:   case TSW_short:       return "short";
     155                0:   case TSW_long:        return "long";
     156                0:   case TSW_longlong:    return "long long";
     157                 :   }
     158                0:   llvm_unreachable("Unknown typespec!");
     159                 : }
     160                 : 
     161                0: const char *DeclSpec::getSpecifierName(TSC C) {
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
     162                0:   switch (C) {
     163                0:   case TSC_unspecified: return "unspecified";
     164                0:   case TSC_imaginary:   return "imaginary";
     165                0:   case TSC_complex:     return "complex";
     166                 :   }
     167                0:   llvm_unreachable("Unknown typespec!");
     168                 : }
     169                 : 
     170                 : 
     171                0: const char *DeclSpec::getSpecifierName(TSS S) {
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
     172                0:   switch (S) {
     173                0:   case TSS_unspecified: return "unspecified";
     174                0:   case TSS_signed:      return "signed";
     175                0:   case TSS_unsigned:    return "unsigned";
     176                 :   }
     177                0:   llvm_unreachable("Unknown typespec!");
     178                 : }
     179                 : 
     180              234: const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
                       32: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        2: branch 3 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        4: branch 6 taken
                        0: branch 7 not taken
                       14: branch 8 taken
                        0: branch 9 not taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                        0: branch 13 not taken
                        1: branch 14 taken
                        6: branch 15 taken
                      172: branch 16 taken
                        1: branch 17 taken
                        1: branch 18 taken
                        1: branch 19 taken
                        0: branch 20 not taken
                        0: branch 21 not taken
                        0: branch 22 not taken
     181              234:   switch (T) {
     182               32:   case DeclSpec::TST_unspecified: return "unspecified";
     183                0:   case DeclSpec::TST_void:        return "void";
     184                0:   case DeclSpec::TST_char:        return "char";
     185                2:   case DeclSpec::TST_wchar:       return "wchar_t";
     186                0:   case DeclSpec::TST_char16:      return "char16_t";
     187                0:   case DeclSpec::TST_char32:      return "char32_t";
     188                4:   case DeclSpec::TST_int:         return "int";
     189                0:   case DeclSpec::TST_float:       return "float";
     190               14:   case DeclSpec::TST_double:      return "double";
     191                0:   case DeclSpec::TST_bool:        return "_Bool";
     192                0:   case DeclSpec::TST_decimal32:   return "_Decimal32";
     193                0:   case DeclSpec::TST_decimal64:   return "_Decimal64";
     194                0:   case DeclSpec::TST_decimal128:  return "_Decimal128";
     195                0:   case DeclSpec::TST_enum:        return "enum";
     196                1:   case DeclSpec::TST_class:       return "class";
     197                6:   case DeclSpec::TST_union:       return "union";
     198              172:   case DeclSpec::TST_struct:      return "struct";
     199                1:   case DeclSpec::TST_typename:    return "type-name";
     200                 :   case DeclSpec::TST_typeofType:
     201                1:   case DeclSpec::TST_typeofExpr:  return "typeof";
     202                1:   case DeclSpec::TST_auto:        return "auto";
     203                0:   case DeclSpec::TST_decltype:    return "(decltype)";
     204                0:   case DeclSpec::TST_error:       return "(error)";
     205                 :   }
     206                0:   llvm_unreachable("Unknown typespec!");
     207                 : }
     208                 : 
     209                0: const char *DeclSpec::getSpecifierName(TQ T) {
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
     210                0:   switch (T) {
     211                0:   case DeclSpec::TQ_unspecified: return "unspecified";
     212                0:   case DeclSpec::TQ_const:       return "const";
     213                0:   case DeclSpec::TQ_restrict:    return "restrict";
     214                0:   case DeclSpec::TQ_volatile:    return "volatile";
     215                 :   }
     216                0:   llvm_unreachable("Unknown typespec!");
     217                 : }
     218                 : 
     219                 : bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
     220                 :                                    const char *&PrevSpec,
     221            10373:                                    unsigned &DiagID) {
                        1: branch 0 taken
                    10372: branch 1 taken
     222            10373:   if (StorageClassSpec != SCS_unspecified)
     223                1:     return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID);
     224            10372:   StorageClassSpec = S;
     225            10372:   StorageClassSpecLoc = Loc;
                        0: branch 0 not taken
                    10372: branch 1 taken
     226            10372:   assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield");
     227            10372:   return false;
     228                 : }
     229                 : 
     230                 : bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
     231                 :                                          const char *&PrevSpec,
     232               20:                                          unsigned &DiagID) {
                        0: branch 0 not taken
                       20: branch 1 taken
     233               20:   if (SCS_thread_specified) {
     234                0:     PrevSpec = "__thread";
     235                0:     DiagID = diag::ext_duplicate_declspec;
     236                0:     return true;
     237                 :   }
     238               20:   SCS_thread_specified = true;
     239               20:   SCS_threadLoc = Loc;
     240               20:   return false;
     241                 : }
     242                 : 
     243                 : 
     244                 : /// These methods set the specified attribute of the DeclSpec, but return true
     245                 : /// and ignore the request if invalid (e.g. "extern" then "auto" is
     246                 : /// specified).
     247                 : bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
     248                 :                                 const char *&PrevSpec,
     249             2837:                                 unsigned &DiagID) {
                      520: branch 0 taken
                     2317: branch 1 taken
                      520: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                      520: branch 5 taken
     250             2837:   if (TypeSpecWidth != TSW_unspecified &&
     251                 :       // Allow turning long -> long long.
     252                 :       (W != TSW_longlong || TypeSpecWidth != TSW_long))
     253                0:     return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
     254             2837:   TypeSpecWidth = W;
     255             2837:   TSWLoc = Loc;
                       56: branch 0 taken
                     2781: branch 1 taken
                       24: branch 2 taken
                       32: branch 3 taken
                        0: branch 4 not taken
                       24: branch 5 taken
     256             2837:   if (TypeAltiVecVector && ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
     257               32:     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
     258               32:     DiagID = diag::warn_vector_long_decl_spec_combination;
     259               32:     return true;
     260                 :   }
     261             2805:   return false;
     262                 : }
     263                 : 
     264                 : bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
     265                 :                                   const char *&PrevSpec,
     266              196:                                   unsigned &DiagID) {
                        0: branch 0 not taken
                      196: branch 1 taken
     267              196:   if (TypeSpecComplex != TSC_unspecified)
     268                0:     return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
     269              196:   TypeSpecComplex = C;
     270              196:   TSCLoc = Loc;
     271              196:   return false;
     272                 : }
     273                 : 
     274                 : bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
     275                 :                                const char *&PrevSpec,
     276             3073:                                unsigned &DiagID) {
                        0: branch 0 not taken
                     3073: branch 1 taken
     277             3073:   if (TypeSpecSign != TSS_unspecified)
     278                0:     return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
     279             3073:   TypeSpecSign = S;
     280             3073:   TSSLoc = Loc;
     281             3073:   return false;
     282                 : }
     283                 : 
     284                 : bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
     285                 :                                const char *&PrevSpec,
     286                 :                                unsigned &DiagID,
     287            65422:                                void *Rep, bool Owned) {
                        5: branch 0 taken
                    65417: branch 1 taken
     288            65422:   if (TypeSpecType != TST_unspecified) {
     289                5:     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
     290                5:     DiagID = diag::err_invalid_decl_spec_combination;
     291                5:     return true;
     292                 :   }
     293            65417:   TypeSpecType = T;
     294            65417:   TypeRep = Rep;
     295            65417:   TSTLoc = Loc;
     296            65417:   TypeSpecOwned = Owned;
                      112: branch 0 taken
                    65305: branch 1 taken
                       14: branch 2 taken
                       98: branch 3 taken
     297            65417:   if (TypeAltiVecVector && (TypeSpecType == TST_double)) {
     298               14:     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
     299               14:     DiagID = diag::err_invalid_vector_double_decl_spec_combination;
     300               14:     return true;
     301                 :   }
     302            65403:   return false;
     303                 : }
     304                 : 
     305                 : bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
     306              144:                           const char *&PrevSpec, unsigned &DiagID) {
                        0: branch 0 not taken
                      144: branch 1 taken
     307              144:   if (TypeSpecType != TST_unspecified) {
     308                0:     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
     309                0:     DiagID = diag::err_invalid_vector_decl_spec_combination;
     310                0:     return true;
     311                 :   }
     312              144:   TypeAltiVecVector = isAltiVecVector;
     313              144:   AltiVecLoc = Loc;
     314              144:   return false;
     315                 : }
     316                 : 
     317                 : bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
     318                8:                           const char *&PrevSpec, unsigned &DiagID) {
                        8: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        8: branch 3 taken
     319                8:   if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) {
     320                0:     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
     321                0:     DiagID = diag::err_invalid_pixel_decl_spec_combination;
     322                0:     return true;
     323                 :   }
     324                8:   TypeSpecType = TST_int;
     325                8:   TypeSpecSign = TSS_unsigned;
     326                8:   TypeSpecWidth = TSW_short;
     327                8:   TypeAltiVecPixel = isAltiVecPixel;
     328                8:   TSTLoc = Loc;
     329                8:   return false;
     330                 : }
     331                 : 
     332               74: bool DeclSpec::SetTypeSpecError() {
     333               74:   TypeSpecType = TST_error;
     334               74:   TypeRep = 0;
     335               74:   TSTLoc = SourceLocation();
     336               74:   return false;
     337                 : }
     338                 : 
     339                 : bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
     340             3583:                            unsigned &DiagID, const LangOptions &Lang) {
     341                 :   // Duplicates turn into warnings pre-C99.
                        0: branch 0 not taken
                     3583: branch 1 taken
                     3583: branch 2 taken
                     3583: branch 3 taken
     342             3583:   if ((TypeQualifiers & T) && !Lang.C99)
     343                0:     return BadSpecifier(T, T, PrevSpec, DiagID);
     344             3583:   TypeQualifiers |= T;
     345                 : 
                        0: branch 0 not taken
                     2736: branch 1 taken
                      643: branch 2 taken
                      204: branch 3 taken
     346             3583:   switch (T) {
     347                0:   default: assert(0 && "Unknown type qualifier!");
     348             2736:   case TQ_const:    TQ_constLoc = Loc; break;
     349              643:   case TQ_restrict: TQ_restrictLoc = Loc; break;
     350              204:   case TQ_volatile: TQ_volatileLoc = Loc; break;
     351                 :   }
     352             3583:   return false;
     353                 : }
     354                 : 
     355                 : bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
     356             1407:                                      unsigned &DiagID) {
     357                 :   // 'inline inline' is ok.
     358             1407:   FS_inline_specified = true;
     359             1407:   FS_inlineLoc = Loc;
     360             1407:   return false;
     361                 : }
     362                 : 
     363                 : bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
     364              557:                                       unsigned &DiagID) {
     365                 :   // 'virtual virtual' is ok.
     366              557:   FS_virtual_specified = true;
     367              557:   FS_virtualLoc = Loc;
     368              557:   return false;
     369                 : }
     370                 : 
     371                 : bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
     372               31:                                        unsigned &DiagID) {
     373                 :   // 'explicit explicit' is ok.
     374               31:   FS_explicit_specified = true;
     375               31:   FS_explicitLoc = Loc;
     376               31:   return false;
     377                 : }
     378                 : 
     379                 : bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
     380               91:                              unsigned &DiagID) {
                        0: branch 0 not taken
                       91: branch 1 taken
     381               91:   if (Friend_specified) {
     382                0:     PrevSpec = "friend";
     383                0:     DiagID = diag::ext_duplicate_declspec;
     384                0:     return true;
     385                 :   }
     386                 : 
     387               91:   Friend_specified = true;
     388               91:   FriendLoc = Loc;
     389               91:   return false;
     390                 : }
     391                 : 
     392                 : bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
     393                0:                                 unsigned &DiagID) {
     394                 :   // 'constexpr constexpr' is ok.
     395                0:   Constexpr_specified = true;
     396                0:   ConstexprLoc = Loc;
     397                0:   return false;
     398                 : }
     399                 : 
     400                 : void DeclSpec::setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos,
     401                 :                                      unsigned NP,
     402                 :                                      SourceLocation *ProtoLocs,
     403              337:                                      SourceLocation LAngleLoc) {
                      333: branch 0 taken
                        4: branch 1 taken
     404              337:   if (NP == 0) return;
                      423: branch 2 taken
                      333: branch 3 taken
     405              333:   ProtocolQualifiers = new ActionBase::DeclPtrTy[NP];
                      423: branch 2 taken
                      333: branch 3 taken
     406              333:   ProtocolLocs = new SourceLocation[NP];
     407              333:   memcpy((void*)ProtocolQualifiers, Protos, sizeof(ActionBase::DeclPtrTy)*NP);
     408              333:   memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
     409              333:   NumProtocolQualifiers = NP;
     410              333:   ProtocolLAngleLoc = LAngleLoc;
     411                 : }
     412                 : 
     413            93368: void DeclSpec::SaveWrittenBuiltinSpecs() {
     414            93368:   writtenBS.Sign = getTypeSpecSign();
     415            93368:   writtenBS.Width = getTypeSpecWidth();
     416            93368:   writtenBS.Type = getTypeSpecType();
     417                 :   // Search the list of attributes for the presence of a mode attribute.
     418            93368:   writtenBS.ModeAttr = false;
     419            93368:   AttributeList* attrs = getAttributes();
                     3070: branch 0 taken
                    93366: branch 1 taken
     420           189804:   while (attrs) {
                        2: branch 1 taken
                     3068: branch 2 taken
     421             3070:     if (attrs->getKind() == AttributeList::AT_mode) {
     422                2:       writtenBS.ModeAttr = true;
     423                2:       break;
     424                 :     }
     425             3068:     attrs = attrs->getNext();
     426                 :   }
     427            93368: }
     428                 : 
     429                 : /// Finish - This does final analysis of the declspec, rejecting things like
     430                 : /// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
     431                 : /// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
     432                 : /// DeclSpec is guaranteed self-consistent, even if an error occurred.
     433            93368: void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
     434                 :   // Before possibly changing their values, save specs as written.
     435            93368:   SaveWrittenBuiltinSpecs();
     436                 : 
     437                 :   // Check the type specifier components first.
     438            93368:   SourceManager &SrcMgr = PP.getSourceManager();
     439                 : 
     440                 :   // signed/unsigned are only valid with int/char/wchar_t.
                     3077: branch 0 taken
                    90291: branch 1 taken
     441            93368:   if (TypeSpecSign != TSS_unspecified) {
                     1387: branch 0 taken
                     1690: branch 1 taken
     442             3077:     if (TypeSpecType == TST_unspecified)
     443             1387:       TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
                      604: branch 0 taken
                     1086: branch 1 taken
                        2: branch 2 taken
                      602: branch 3 taken
                        0: branch 4 not taken
                        2: branch 5 taken
     444             1690:     else if (TypeSpecType != TST_int  &&
     445                 :              TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
     446                 :       Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec)
     447                0:         << getSpecifierName((TST)TypeSpecType);
     448                 :       // signed double -> double.
     449                0:       TypeSpecSign = TSS_unspecified;
     450                 :     }
     451                 :   }
     452                 : 
     453                 :   // Validate the width of the type.
                    91053: branch 0 taken
                     1270: branch 1 taken
                     1045: branch 2 taken
                        0: branch 3 not taken
     454            93368:   switch (TypeSpecWidth) {
     455            91053:   case TSW_unspecified: break;
     456                 :   case TSW_short:    // short int
     457                 :   case TSW_longlong: // long long int
                      601: branch 0 taken
                      669: branch 1 taken
     458             1270:     if (TypeSpecType == TST_unspecified)
     459              601:       TypeSpecType = TST_int; // short -> short int, long long -> long long int.
                        2: branch 0 taken
                      667: branch 1 taken
     460              669:     else if (TypeSpecType != TST_int) {
     461                 :       Diag(D, TSWLoc, SrcMgr,
     462                 :            TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
     463                 :                                       : diag::err_invalid_longlong_spec)
                        2: branch 1 taken
                        0: branch 2 not taken
     464                2:         <<  getSpecifierName((TST)TypeSpecType);
     465                2:       TypeSpecType = TST_int;
     466                 :     }
     467             1270:     break;
     468                 :   case TSW_long:  // long double, long int
                      377: branch 0 taken
                      668: branch 1 taken
     469             1045:     if (TypeSpecType == TST_unspecified)
     470              377:       TypeSpecType = TST_int;  // long -> long int.
                      116: branch 0 taken
                      552: branch 1 taken
                        0: branch 2 not taken
                      116: branch 3 taken
     471              668:     else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
     472                 :       Diag(D, TSWLoc, SrcMgr, diag::err_invalid_long_spec)
     473                0:         << getSpecifierName((TST)TypeSpecType);
     474                0:       TypeSpecType = TST_int;
     475                 :     }
     476                 :     break;
     477                 :   }
     478                 : 
     479                 :   // TODO: if the implementation does not implement _Complex or _Imaginary,
     480                 :   // disallow their use.  Need information about the backend.
                      195: branch 0 taken
                    93173: branch 1 taken
     481            93368:   if (TypeSpecComplex != TSC_unspecified) {
                        2: branch 0 taken
                      193: branch 1 taken
     482              195:     if (TypeSpecType == TST_unspecified) {
     483                 :       Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex)
     484                 :         << CodeModificationHint::CreateInsertion(
     485                 :                               PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
     486                2:                                                  " double");
     487                2:       TypeSpecType = TST_double;   // _Complex -> _Complex double.
                      147: branch 0 taken
                       46: branch 1 taken
                        5: branch 2 taken
                      142: branch 3 taken
     488              244:     } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
     489                 :       // Note that this intentionally doesn't include _Complex _Bool.
     490               51:       Diag(D, TSTLoc, SrcMgr, diag::ext_integer_complex);
                       53: branch 0 taken
                       89: branch 1 taken
                        0: branch 2 not taken
                       53: branch 3 taken
     491              142:     } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
     492                 :       Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec)
     493                0:         << getSpecifierName((TST)TypeSpecType);
     494                0:       TypeSpecComplex = TSC_unspecified;
     495                 :     }
     496                 :   }
     497                 : 
     498                 :   // C++ [class.friend]p6:
     499                 :   //   No storage-class-specifier shall appear in the decl-specifier-seq
     500                 :   //   of a friend declaration.
                       91: branch 1 taken
                    93277: branch 2 taken
                        6: branch 4 taken
                       85: branch 5 taken
                        6: branch 6 taken
                    93362: branch 7 taken
     501            93368:   if (isFriendSpecified() && getStorageClassSpec()) {
     502                6:     DeclSpec::SCS SC = getStorageClassSpec();
     503                6:     const char *SpecName = getSpecifierName(SC);
     504                 : 
     505                6:     SourceLocation SCLoc = getStorageClassSpecLoc();
     506                6:     SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName));
     507                 : 
     508                 :     Diag(D, SCLoc, SrcMgr, diag::err_friend_storage_spec)
     509                 :       << SpecName
     510                6:       << CodeModificationHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
     511                 : 
     512                6:     ClearStorageClassSpecs();
     513                 :   }
     514                 : 
     515                 : 
     516                 :   // Okay, now we can infer the real type.
     517                 : 
     518                 :   // TODO: return "auto function" and other bad things based on the real type.
     519                 : 
     520                 :   // 'data definition has no type or storage class'?
     521            93368: }
     522                 : 
     523             4621: bool DeclSpec::isMissingDeclaratorOk() {
     524             4621:   TST tst = getTypeSpecType();
     525                 :   return (tst == TST_union
     526                 :        || tst == TST_struct
     527                 :        || tst == TST_class
     528                 :        || tst == TST_enum
                     4559: branch 0 taken
                       62: branch 1 taken
                     1126: branch 2 taken
                     3433: branch 3 taken
                      310: branch 4 taken
                      816: branch 5 taken
                      281: branch 6 taken
                       29: branch 7 taken
                     4592: branch 9 taken
                        0: branch 10 not taken
                     4588: branch 11 taken
                        4: branch 12 taken
     529             4621:           ) && getTypeRep() != 0 && StorageClassSpec != DeclSpec::SCS_typedef;
     530                 : }
     531                 : 
     532           165291: void UnqualifiedId::clear() {
                      230: branch 0 taken
                   165061: branch 1 taken
     533           165291:   if (Kind == IK_TemplateId)
     534              230:     TemplateId->Destroy();
     535                 :   
     536           165291:   Kind = IK_Identifier;
     537           165291:   Identifier = 0;
     538           165291:   StartLocation = SourceLocation();
     539           165291:   EndLocation = SourceLocation();
     540           165291: }
     541                 : 
     542                 : void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 
     543                 :                                           OverloadedOperatorKind Op,
     544              299:                                           SourceLocation SymbolLocations[3]) {
     545              299:   Kind = IK_OperatorFunctionId;
     546              299:   StartLocation = OperatorLoc;
     547              299:   EndLocation = OperatorLoc;
     548              299:   OperatorFunctionId.Operator = Op;
                      897: branch 0 taken
                      299: branch 1 taken
     549             1196:   for (unsigned I = 0; I != 3; ++I) {
     550              897:     OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
     551                 :     
                      353: branch 1 taken
                      544: branch 2 taken
     552              897:     if (SymbolLocations[I].isValid())
     553              353:       EndLocation = SymbolLocations[I];
     554                 :   }
     555              299: }

Generated: 2010-02-10 01:31 by zcov