zcov: / lib/Parse/ParseDecl.cpp


Files: 1 Branches Taken: 80.2% 855 / 1066
Generated: 2010-02-10 01:31 Branches Executed: 94.6% 1008 / 1066
Line Coverage: 86.7% 1068 / 1232


Programs: 2 Runs 3018


       1                 : //===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
       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 the Declaration portions of the Parser interfaces.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/Parse/Parser.h"
      15                 : #include "clang/Parse/ParseDiagnostic.h"
      16                 : #include "clang/Parse/Scope.h"
      17                 : #include "clang/Parse/Template.h"
      18                 : #include "RAIIObjectsForParser.h"
      19                 : #include "llvm/ADT/SmallSet.h"
      20                 : using namespace clang;
      21                 : 
      22                 : //===----------------------------------------------------------------------===//
      23                 : // C99 6.7: Declarations.
      24                 : //===----------------------------------------------------------------------===//
      25                 : 
      26                 : /// ParseTypeName
      27                 : ///       type-name: [C99 6.7.6]
      28                 : ///         specifier-qualifier-list abstract-declarator[opt]
      29                 : ///
      30                 : /// Called type-id in C++.
      31            13818: Action::TypeResult Parser::ParseTypeName(SourceRange *Range) {
      32                 :   // Parse the common declaration-specifiers piece.
      33            13818:   DeclSpec DS;
      34            13818:   ParseSpecifierQualifierList(DS);
      35                 : 
      36                 :   // Parse the abstract-declarator, if present.
      37            13818:   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
      38            13818:   ParseDeclarator(DeclaratorInfo);
                      102: branch 0 taken
                    13716: branch 1 taken
      39            13818:   if (Range)
      40              102:     *Range = DeclaratorInfo.getSourceRange();
      41                 : 
                        1: branch 1 taken
                    13817: branch 2 taken
      42            13818:   if (DeclaratorInfo.isInvalidType())
      43                1:     return true;
      44                 : 
      45            13817:   return Actions.ActOnTypeName(CurScope, DeclaratorInfo);
      46                 : }
      47                 : 
      48                 : /// ParseGNUAttributes - Parse a non-empty attributes list.
      49                 : ///
      50                 : /// [GNU] attributes:
      51                 : ///         attribute
      52                 : ///         attributes attribute
      53                 : ///
      54                 : /// [GNU]  attribute:
      55                 : ///          '__attribute__' '(' '(' attribute-list ')' ')'
      56                 : ///
      57                 : /// [GNU]  attribute-list:
      58                 : ///          attrib
      59                 : ///          attribute_list ',' attrib
      60                 : ///
      61                 : /// [GNU]  attrib:
      62                 : ///          empty
      63                 : ///          attrib-name
      64                 : ///          attrib-name '(' identifier ')'
      65                 : ///          attrib-name '(' identifier ',' nonempty-expr-list ')'
      66                 : ///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
      67                 : ///
      68                 : /// [GNU]  attrib-name:
      69                 : ///          identifier
      70                 : ///          typespec
      71                 : ///          typequal
      72                 : ///          storageclass
      73                 : ///
      74                 : /// FIXME: The GCC grammar/code for this construct implies we need two
      75                 : /// token lookahead. Comment from gcc: "If they start with an identifier
      76                 : /// which is followed by a comma or close parenthesis, then the arguments
      77                 : /// start with that identifier; otherwise they are an expression list."
      78                 : ///
      79                 : /// At the moment, I am not doing 2 token lookahead. I am also unaware of
      80                 : /// any attributes that don't work (based on my limited testing). Most
      81                 : /// attributes are very simple in practice. Until we find a bug, I don't see
      82                 : /// a pressing need to implement the 2 token lookahead.
      83                 : 
      84             3261: AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
                     3261: branch 1 taken
                        0: branch 2 not taken
      85             3261:   assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
      86                 : 
      87             3261:   AttributeList *CurrAttr = 0;
      88                 : 
                     3592: branch 1 taken
                     3261: branch 2 taken
      89            10114:   while (Tok.is(tok::kw___attribute)) {
      90             3592:     ConsumeToken();
                        0: branch 1 not taken
                     3592: branch 2 taken
      91             3592:     if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
      92                 :                          "attribute")) {
      93                0:       SkipUntil(tok::r_paren, true); // skip until ) or ;
      94                0:       return CurrAttr;
      95                 :     }
                        0: branch 1 not taken
                     3592: branch 2 taken
      96             3592:     if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
      97                0:       SkipUntil(tok::r_paren, true); // skip until ) or ;
      98                0:       return CurrAttr;
      99                 :     }
     100                 :     // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
                     4914: branch 1 taken
                     4802: branch 2 taken
                     4865: branch 4 taken
                       49: branch 5 taken
                     1273: branch 7 taken
                     3592: branch 8 taken
                     6124: branch 9 taken
                     3592: branch 10 taken
     101            13308:     while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
     102                 :            Tok.is(tok::comma)) {
     103                 : 
                     1273: branch 1 taken
                     4851: branch 2 taken
     104             6124:       if (Tok.is(tok::comma)) {
     105                 :         // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
     106             1273:         ConsumeToken();
     107             1273:         continue;
     108                 :       }
     109                 :       // we have an identifier or declaration specifier (const, int, etc.)
     110             4851:       IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     111             4851:       SourceLocation AttrNameLoc = ConsumeToken();
     112                 : 
     113                 :       // check if we have a "paramterized" attribute
                     1239: branch 1 taken
                     3612: branch 2 taken
     114             4851:       if (Tok.is(tok::l_paren)) {
     115             1239:         ConsumeParen(); // ignore the left paren loc for now
     116                 : 
                      400: branch 1 taken
                      839: branch 2 taken
     117             1239:         if (Tok.is(tok::identifier)) {
     118              400:           IdentifierInfo *ParmName = Tok.getIdentifierInfo();
     119              400:           SourceLocation ParmLoc = ConsumeToken();
     120                 : 
                      324: branch 1 taken
                       76: branch 2 taken
     121              400:           if (Tok.is(tok::r_paren)) {
     122                 :             // __attribute__(( mode(byte) ))
     123              324:             ConsumeParen(); // ignore the right paren loc for now
     124                 :             CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
     125              324:                                          ParmName, ParmLoc, 0, 0, CurrAttr);
                       76: branch 1 taken
                        0: branch 2 not taken
     126               76:           } else if (Tok.is(tok::comma)) {
     127               76:             ConsumeToken();
     128                 :             // __attribute__(( format(printf, 1, 2) ))
     129               76:             ExprVector ArgExprs(Actions);
     130               76:             bool ArgExprsOk = true;
     131                 : 
     132                 :             // now parse the non-empty comma separated list of expressions
                       75: branch 1 taken
                       76: branch 2 taken
     133              151:             while (1) {
     134              151:               OwningExprResult ArgExpr(ParseAssignmentExpression());
                        0: branch 1 not taken
                      151: branch 2 taken
     135              151:               if (ArgExpr.isInvalid()) {
     136                0:                 ArgExprsOk = false;
     137                0:                 SkipUntil(tok::r_paren);
     138                 :                 break;
     139                 :               } else {
     140              151:                 ArgExprs.push_back(ArgExpr.release());
     141                 :               }
                       76: branch 1 taken
                       75: branch 2 taken
     142              151:               if (Tok.isNot(tok::comma))
     143                 :                 break;
     144               75:               ConsumeToken(); // Eat the comma, move to the next argument
     145                 :             }
                       76: branch 0 taken
                        0: branch 1 not taken
                       76: branch 3 taken
                        0: branch 4 not taken
                       76: branch 5 taken
                        0: branch 6 not taken
     146               76:             if (ArgExprsOk && Tok.is(tok::r_paren)) {
     147               76:               ConsumeParen(); // ignore the right paren loc for now
     148                 :               CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
     149                 :                                            AttrNameLoc, ParmName, ParmLoc,
     150                 :                                            ArgExprs.take(), ArgExprs.size(),
     151               76:                                            CurrAttr);
     152               76:             }
     153                 :           }
     154                 :         } else { // not an identifier
                        4: branch 1 taken
                        0: branch 2 not taken
                      835: branch 3 taken
     155              839:           switch (Tok.getKind()) {
     156                 :           case tok::r_paren:
     157                 :           // parse a possibly empty comma separated list of expressions
     158                 :             // __attribute__(( nonnull() ))
     159                4:             ConsumeParen(); // ignore the right paren loc for now
     160                 :             CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
     161                4:                                          0, SourceLocation(), 0, 0, CurrAttr);
     162                4:             break;
     163                 :           case tok::kw_char:
     164                 :           case tok::kw_wchar_t:
     165                 :           case tok::kw_char16_t:
     166                 :           case tok::kw_char32_t:
     167                 :           case tok::kw_bool:
     168                 :           case tok::kw_short:
     169                 :           case tok::kw_int:
     170                 :           case tok::kw_long:
     171                 :           case tok::kw_signed:
     172                 :           case tok::kw_unsigned:
     173                 :           case tok::kw_float:
     174                 :           case tok::kw_double:
     175                 :           case tok::kw_void:
     176                 :           case tok::kw_typeof:
     177                 :             // If it's a builtin type name, eat it and expect a rparen
     178                 :             // __attribute__(( vec_type_hint(char) ))
     179                0:             ConsumeToken();
     180                 :             CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
     181                0:                                          0, SourceLocation(), 0, 0, CurrAttr);
                        0: branch 1 not taken
                        0: branch 2 not taken
     182                0:             if (Tok.is(tok::r_paren))
     183                0:               ConsumeParen();
     184                0:             break;
     185                 :           default:
     186                 :             // __attribute__(( aligned(16) ))
     187              835:             ExprVector ArgExprs(Actions);
     188              835:             bool ArgExprsOk = true;
     189                 : 
     190                 :             // now parse the list of expressions
                      202: branch 1 taken
                      835: branch 2 taken
     191             1037:             while (1) {
     192             1037:               OwningExprResult ArgExpr(ParseAssignmentExpression());
                        0: branch 1 not taken
                     1037: branch 2 taken
     193             1037:               if (ArgExpr.isInvalid()) {
     194                0:                 ArgExprsOk = false;
     195                0:                 SkipUntil(tok::r_paren);
     196                 :                 break;
     197                 :               } else {
     198             1037:                 ArgExprs.push_back(ArgExpr.release());
     199                 :               }
                      835: branch 1 taken
                      202: branch 2 taken
     200             1037:               if (Tok.isNot(tok::comma))
     201                 :                 break;
     202              202:               ConsumeToken(); // Eat the comma, move to the next argument
     203                 :             }
     204                 :             // Match the ')'.
                      835: branch 0 taken
                        0: branch 1 not taken
                      835: branch 3 taken
                        0: branch 4 not taken
                      835: branch 5 taken
                        0: branch 6 not taken
     205              835:             if (ArgExprsOk && Tok.is(tok::r_paren)) {
     206              835:               ConsumeParen(); // ignore the right paren loc for now
     207                 :               CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
     208                 :                            AttrNameLoc, 0, SourceLocation(), ArgExprs.take(),
     209                 :                            ArgExprs.size(),
     210              835:                            CurrAttr);
     211                 :             }
     212              835:             break;
     213                 :           }
     214                 :         }
     215                 :       } else {
     216                 :         CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
     217             3612:                                      0, SourceLocation(), 0, 0, CurrAttr);
     218                 :       }
     219                 :     }
                        0: branch 1 not taken
                     3592: branch 2 taken
     220             3592:     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
     221                0:       SkipUntil(tok::r_paren, false);
     222             3592:     SourceLocation Loc = Tok.getLocation();
                        0: branch 1 not taken
                     3592: branch 2 taken
     223             3592:     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
     224                0:       SkipUntil(tok::r_paren, false);
     225                 :     }
                     1678: branch 0 taken
                     1914: branch 1 taken
     226             3592:     if (EndLoc)
     227             1678:       *EndLoc = Loc;
     228                 :   }
     229             3261:   return CurrAttr;
     230                 : }
     231                 : 
     232                 : /// ParseMicrosoftDeclSpec - Parse an __declspec construct
     233                 : ///
     234                 : /// [MS] decl-specifier:
     235                 : ///             __declspec ( extended-decl-modifier-seq )
     236                 : ///
     237                 : /// [MS] extended-decl-modifier-seq:
     238                 : ///             extended-decl-modifier[opt]
     239                 : ///             extended-decl-modifier extended-decl-modifier-seq
     240                 : 
     241               11: AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
                       11: branch 1 taken
                        0: branch 2 not taken
     242               11:   assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
     243                 : 
     244               11:   ConsumeToken();
                        0: branch 1 not taken
                       11: branch 2 taken
     245               11:   if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
     246                 :                        "declspec")) {
     247                0:     SkipUntil(tok::r_paren, true); // skip until ) or ;
     248                0:     return CurrAttr;
     249                 :   }
                       11: branch 1 taken
                       11: branch 2 taken
     250               33:   while (Tok.getIdentifierInfo()) {
     251               11:     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     252               11:     SourceLocation AttrNameLoc = ConsumeToken();
                        1: branch 1 taken
                       10: branch 2 taken
     253               11:     if (Tok.is(tok::l_paren)) {
     254                1:       ConsumeParen();
     255                 :       // FIXME: This doesn't parse __declspec(property(get=get_func_name))
     256                 :       // correctly.
     257                1:       OwningExprResult ArgExpr(ParseAssignmentExpression());
                        1: branch 1 taken
                        0: branch 2 not taken
     258                1:       if (!ArgExpr.isInvalid()) {
     259                1:         ExprTy* ExprList = ArgExpr.take();
     260                 :         CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
     261                 :                                      SourceLocation(), &ExprList, 1,
     262                1:                                      CurrAttr, true);
     263                 :       }
                        0: branch 1 not taken
                        1: branch 2 taken
     264                1:       if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
     265                0:         SkipUntil(tok::r_paren, false);
     266                 :     } else {
     267                 :       CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
     268               10:                                    0, SourceLocation(), 0, 0, CurrAttr, true);
     269                 :     }
     270                 :   }
                        0: branch 1 not taken
                       11: branch 2 taken
     271               11:   if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
     272                0:     SkipUntil(tok::r_paren, false);
     273               11:   return CurrAttr;
     274                 : }
     275                 : 
     276               11: AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
     277                 :   // Treat these like attributes
     278                 :   // FIXME: Allow Sema to distinguish between these and real attributes!
                       22: branch 1 taken
                        1: branch 2 taken
                       17: branch 4 taken
                        5: branch 5 taken
                       14: branch 7 taken
                        3: branch 8 taken
                       12: branch 10 taken
                        2: branch 11 taken
                        1: branch 13 taken
                       11: branch 14 taken
                       12: branch 15 taken
                       11: branch 16 taken
     279               34:   while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
     280                 :          Tok.is(tok::kw___cdecl)    || Tok.is(tok::kw___ptr64) ||
     281                 :          Tok.is(tok::kw___w64)) {
     282               12:     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     283               12:     SourceLocation AttrNameLoc = ConsumeToken();
                       12: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                       12: branch 5 taken
                        0: branch 6 not taken
                       12: branch 7 taken
     284               12:     if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
     285                 :       // FIXME: Support these properly!
     286                0:       continue;
     287                 :     CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
     288               12:                                  SourceLocation(), 0, 0, CurrAttr, true);
     289                 :   }
     290               11:   return CurrAttr;
     291                 : }
     292                 : 
     293                 : /// ParseDeclaration - Parse a full 'declaration', which consists of
     294                 : /// declaration-specifiers, some number of declarators, and a semicolon.
     295                 : /// 'Context' should be a Declarator::TheContext value.  This returns the
     296                 : /// location of the semicolon in DeclEnd.
     297                 : ///
     298                 : ///       declaration: [C99 6.7]
     299                 : ///         block-declaration ->
     300                 : ///           simple-declaration
     301                 : ///           others                   [FIXME]
     302                 : /// [C++]   template-declaration
     303                 : /// [C++]   namespace-definition
     304                 : /// [C++]   using-directive
     305                 : /// [C++]   using-declaration
     306                 : /// [C++0x] static_assert-declaration
     307                 : ///         others... [FIXME]
     308                 : ///
     309                 : Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
     310                 :                                                 SourceLocation &DeclEnd,
     311            15888:                                                 CXX0XAttributeList Attr) {
     312            15888:   DeclPtrTy SingleDecl;
                     1990: branch 1 taken
                      694: branch 2 taken
                      150: branch 3 taken
                       58: branch 4 taken
                    12996: branch 5 taken
     313            15888:   switch (Tok.getKind()) {
     314                 :   case tok::kw_template:
     315                 :   case tok::kw_export:
                        1: branch 0 taken
                     1989: branch 1 taken
     316             1990:     if (Attr.HasAttr)
     317                 :       Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
     318                1:         << Attr.Range;
     319             1990:     SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
     320             1990:     break;
     321                 :   case tok::kw_namespace:
                        1: branch 0 taken
                      693: branch 1 taken
     322              694:     if (Attr.HasAttr)
     323                 :       Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
     324                1:         << Attr.Range;
     325              694:     SingleDecl = ParseNamespace(Context, DeclEnd);
     326              694:     break;
     327                 :   case tok::kw_using:
     328              150:     SingleDecl = ParseUsingDirectiveOrDeclaration(Context, DeclEnd, Attr);
     329              150:     break;
     330                 :   case tok::kw_static_assert:
                        1: branch 0 taken
                       57: branch 1 taken
     331               58:     if (Attr.HasAttr)
     332                 :       Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
     333                1:         << Attr.Range;
     334               58:     SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
     335               58:     break;
     336                 :   default:
     337            12996:     return ParseSimpleDeclaration(Context, DeclEnd, Attr.AttrList);
     338                 :   }
     339                 :   
     340                 :   // This routine returns a DeclGroup, if the thing we parsed only contains a
     341                 :   // single decl, convert it now.
     342             2892:   return Actions.ConvertDeclToDeclGroup(SingleDecl);
     343                 : }
     344                 : 
     345                 : ///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
     346                 : ///         declaration-specifiers init-declarator-list[opt] ';'
     347                 : ///[C90/C++]init-declarator-list ';'                             [TODO]
     348                 : /// [OMP]   threadprivate-directive                              [TODO]
     349                 : ///
     350                 : /// If RequireSemi is false, this does not check for a ';' at the end of the
     351                 : /// declaration.
     352                 : Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
     353                 :                                                       SourceLocation &DeclEnd,
     354            13127:                                                       AttributeList *Attr) {
     355                 :   // Parse the common declaration-specifiers piece.
     356            13127:   ParsingDeclSpec DS(*this);
                        0: branch 0 not taken
                    13127: branch 1 taken
     357            13127:   if (Attr)
     358                0:     DS.AddAttributes(Attr);
     359                 :   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
     360            13127:                             getDeclSpecContextFromDeclaratorContext(Context));
     361                 : 
     362                 :   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
     363                 :   // declaration-specifiers init-declarator-list[opt] ';'
                       92: branch 1 taken
                    13035: branch 2 taken
     364            13127:   if (Tok.is(tok::semi)) {
     365               92:     ConsumeToken();
     366               92:     DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
     367               92:     DS.complete(TheDecl);
     368               92:     return Actions.ConvertDeclToDeclGroup(TheDecl);
     369                 :   }
     370                 : 
     371                 :   DeclGroupPtrTy DG = ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false,
     372            13035:                                      &DeclEnd);
     373            13035:   return DG;
     374                 : }
     375                 : 
     376                 : /// ParseDeclGroup - Having concluded that this is either a function
     377                 : /// definition or a group of object declarations, actually parse the
     378                 : /// result.
     379                 : Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
     380                 :                                               unsigned Context,
     381                 :                                               bool AllowFunctionDefinitions,
     382            26190:                                               SourceLocation *DeclEnd) {
     383                 :   // Parse the first declarator.
     384            26190:   ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
     385            26190:   ParseDeclarator(D);
     386                 : 
     387                 :   // Bail out if the first declarator didn't seem well-formed.
                       25: branch 1 taken
                    26165: branch 2 taken
                       25: branch 4 taken
                        0: branch 5 not taken
                       25: branch 6 taken
                    26165: branch 7 taken
     388            26190:   if (!D.hasName() && !D.mayOmitIdentifier()) {
     389                 :     // Skip until ; or }.
     390               25:     SkipUntil(tok::r_brace, true, true);
                       18: branch 1 taken
                        7: branch 2 taken
     391               25:     if (Tok.is(tok::semi))
     392               18:       ConsumeToken();
     393               25:     return DeclGroupPtrTy();
     394                 :   }
     395                 : 
                    13136: branch 0 taken
                    13029: branch 1 taken
                    10033: branch 3 taken
                     3103: branch 4 taken
                    10033: branch 5 taken
                    16132: branch 6 taken
     396            26165:   if (AllowFunctionDefinitions && D.isFunctionDeclarator()) {
                     6915: branch 1 taken
                     3118: branch 2 taken
     397            10033:     if (isDeclarationAfterDeclarator()) {
     398                 :       // Fall though.  We have to check this first, though, because
     399                 :       // __attribute__ might be the start of a function definition in
     400                 :       // (extended) K&R C.
                     6913: branch 1 taken
                        2: branch 2 taken
     401             6915:     } else if (isStartOfFunctionDefinition()) {
                        1: branch 1 taken
                     6912: branch 2 taken
     402             6913:       if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
     403                1:         Diag(Tok, diag::err_function_declared_typedef);
     404                 : 
     405                 :         // Recover by treating the 'typedef' as spurious.
     406                1:         DS.ClearStorageClassSpecs();
     407                 :       }
     408                 : 
     409             6913:       DeclPtrTy TheDecl = ParseFunctionDefinition(D);
     410             6913:       return Actions.ConvertDeclToDeclGroup(TheDecl);
     411                 :     } else {
     412                2:       Diag(Tok, diag::err_expected_fn_body);
     413                2:       SkipUntil(tok::semi);
     414                2:       return DeclGroupPtrTy();
     415                 :     }
     416                 :   }
     417                 : 
     418            19250:   llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
     419            19250:   DeclPtrTy FirstDecl = ParseDeclarationAfterDeclarator(D);
     420            19250:   D.complete(FirstDecl);
                    18982: branch 1 taken
                      268: branch 2 taken
     421            19250:   if (FirstDecl.get())
     422            18982:     DeclsInGroup.push_back(FirstDecl);
     423                 : 
     424                 :   // If we don't have a comma, it is either the end of the list (a ';') or an
     425                 :   // error, bail out.
                      368: branch 1 taken
                    19250: branch 2 taken
     426            38868:   while (Tok.is(tok::comma)) {
     427                 :     // Consume the comma.
     428              368:     ConsumeToken();
     429                 : 
     430                 :     // Parse the next declarator.
     431              368:     D.clear();
     432                 : 
     433                 :     // Accept attributes in an init-declarator.  In the first declarator in a
     434                 :     // declaration, these would be part of the declspec.  In subsequent
     435                 :     // declarators, they become part of the declarator itself, so that they
     436                 :     // don't apply to declarators after *this* one.  Examples:
     437                 :     //    short __attribute__((common)) var;    -> declspec
     438                 :     //    short var __attribute__((common));    -> declarator
     439                 :     //    short x, __attribute__((common)) var;    -> declarator
                        2: branch 1 taken
                      366: branch 2 taken
     440              368:     if (Tok.is(tok::kw___attribute)) {
     441                2:       SourceLocation Loc;
     442                2:       AttributeList *AttrList = ParseGNUAttributes(&Loc);
     443                2:       D.AddAttributes(AttrList, Loc);
     444                 :     }
     445                 : 
     446              368:     ParseDeclarator(D);
     447                 : 
     448              368:     DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(D);
     449              368:     D.complete(ThisDecl);
                      346: branch 1 taken
                       22: branch 2 taken
     450              368:     if (ThisDecl.get())
     451              346:       DeclsInGroup.push_back(ThisDecl);    
     452                 :   }
     453                 : 
                    13029: branch 0 taken
                     6221: branch 1 taken
     454            19250:   if (DeclEnd)
     455            13029:     *DeclEnd = Tok.getLocation();
     456                 : 
                    19119: branch 0 taken
                      131: branch 1 taken
                    12160: branch 2 taken
                     6959: branch 3 taken
                        6: branch 5 taken
                    19113: branch 6 taken
                        6: branch 7 taken
                    19244: branch 8 taken
     457            19250:   if (Context != Declarator::ForContext &&
     458                 :       ExpectAndConsume(tok::semi,
     459                 :                        Context == Declarator::FileContext
     460                 :                          ? diag::err_invalid_token_after_toplevel_declarator
     461                 :                          : diag::err_expected_semi_declaration)) {
     462                6:     SkipUntil(tok::r_brace, true, true);
                        2: branch 1 taken
                        4: branch 2 taken
     463                6:     if (Tok.is(tok::semi))
     464                2:       ConsumeToken();
     465                 :   }
     466                 : 
     467                 :   return Actions.FinalizeDeclaratorGroup(CurScope, DS,
     468                 :                                          DeclsInGroup.data(),
     469            19250:                                          DeclsInGroup.size());
     470                 : }
     471                 : 
     472                 : /// \brief Parse 'declaration' after parsing 'declaration-specifiers
     473                 : /// declarator'. This method parses the remainder of the declaration
     474                 : /// (including any attributes or initializer, among other things) and
     475                 : /// finalizes the declaration.
     476                 : ///
     477                 : ///       init-declarator: [C99 6.7]
     478                 : ///         declarator
     479                 : ///         declarator '=' initializer
     480                 : /// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
     481                 : /// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
     482                 : /// [C++]   declarator initializer[opt]
     483                 : ///
     484                 : /// [C++] initializer:
     485                 : /// [C++]   '=' initializer-clause
     486                 : /// [C++]   '(' expression-list ')'
     487                 : /// [C++0x] '=' 'default'                                                [TODO]
     488                 : /// [C++0x] '=' 'delete'
     489                 : ///
     490                 : /// According to the standard grammar, =default and =delete are function
     491                 : /// definitions, but that definitely doesn't fit with the parser here.
     492                 : ///
     493                 : Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D,
     494            19966:                                      const ParsedTemplateInfo &TemplateInfo) {
     495                 :   // If a simple-asm-expr is present, parse it.
                       29: branch 1 taken
                    19937: branch 2 taken
     496            19966:   if (Tok.is(tok::kw_asm)) {
     497               29:     SourceLocation Loc;
     498               29:     OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
                        0: branch 1 not taken
                       29: branch 2 taken
     499               29:     if (AsmLabel.isInvalid()) {
     500                0:       SkipUntil(tok::semi, true, true);
     501                0:       return DeclPtrTy();
     502                 :     }
     503                 : 
     504               29:     D.setAsmLabel(AsmLabel.release());
                       29: branch 2 taken
                        0: branch 3 not taken
     505               29:     D.SetRangeEnd(Loc);
     506                 :   }
     507                 : 
     508                 :   // If attributes are present, parse them.
                     1306: branch 1 taken
                    18660: branch 2 taken
     509            19966:   if (Tok.is(tok::kw___attribute)) {
     510             1306:     SourceLocation Loc;
     511             1306:     AttributeList *AttrList = ParseGNUAttributes(&Loc);
     512             1306:     D.AddAttributes(AttrList, Loc);
     513                 :   }
     514                 : 
     515                 :   // Inform the current actions module that we just parsed this declarator.
     516            19966:   DeclPtrTy ThisDecl;
                    19618: branch 0 taken
                      225: branch 1 taken
                      123: branch 2 taken
                        0: branch 3 not taken
     517            19966:   switch (TemplateInfo.Kind) {
     518                 :   case ParsedTemplateInfo::NonTemplate:
     519            19618:     ThisDecl = Actions.ActOnDeclarator(CurScope, D);
     520            19618:     break;
     521                 :       
     522                 :   case ParsedTemplateInfo::Template:
     523                 :   case ParsedTemplateInfo::ExplicitSpecialization:
     524                 :     ThisDecl = Actions.ActOnTemplateDeclarator(CurScope,
     525                 :                              Action::MultiTemplateParamsArg(Actions,
     526                 :                                           TemplateInfo.TemplateParams->data(),
     527                 :                                           TemplateInfo.TemplateParams->size()),
     528              225:                                                D);
     529              225:     break;
     530                 :       
     531                 :   case ParsedTemplateInfo::ExplicitInstantiation: {
     532                 :     Action::DeclResult ThisRes 
     533                 :       = Actions.ActOnExplicitInstantiation(CurScope,
     534                 :                                            TemplateInfo.ExternLoc,
     535                 :                                            TemplateInfo.TemplateLoc,
     536              123:                                            D);
                       15: branch 1 taken
                      108: branch 2 taken
     537              123:     if (ThisRes.isInvalid()) {
     538               15:       SkipUntil(tok::semi, true, true);
     539               15:       return DeclPtrTy();
     540                 :     }
     541                 :     
     542              108:     ThisDecl = ThisRes.get();
     543                 :     break;
     544                 :     }
     545                 :   }
     546                 : 
     547                 :   // Parse declarator '=' initializer.
                     5377: branch 1 taken
                    14574: branch 2 taken
     548            19951:   if (Tok.is(tok::equal)) {
     549             5377:     ConsumeToken();
                      181: branch 1 taken
                     5196: branch 2 taken
                        5: branch 4 taken
                      176: branch 5 taken
                        5: branch 6 taken
                     5372: branch 7 taken
     550             5377:     if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
     551                5:       SourceLocation DelLoc = ConsumeToken();
     552                5:       Actions.SetDeclDeleted(ThisDecl, DelLoc);
     553                 :     } else {
                     1548: branch 1 taken
                     3824: branch 2 taken
                       38: branch 5 taken
                     1510: branch 6 taken
                       38: branch 7 taken
                     5334: branch 8 taken
     554             5372:       if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
     555               38:         EnterScope(0);
     556               38:         Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
     557                 :       }
     558                 : 
     559             5372:       OwningExprResult Init(ParseInitializer());
     560                 : 
                     1548: branch 1 taken
                     3824: branch 2 taken
                       38: branch 5 taken
                     1510: branch 6 taken
                       38: branch 7 taken
                     5334: branch 8 taken
     561             5372:       if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
     562               38:         Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
     563               38:         ExitScope();
     564                 :       }
     565                 : 
                       92: branch 1 taken
                     5280: branch 2 taken
     566             5372:       if (Init.isInvalid()) {
     567               92:         SkipUntil(tok::semi, true, true);
     568              184:         return DeclPtrTy();
     569                 :       }
                     5280: branch 7 taken
                       92: branch 8 taken
     570             5280:       Actions.AddInitializerToDecl(ThisDecl, move(Init));
     571                 :     }
                      109: branch 1 taken
                    14465: branch 2 taken
     572            14574:   } else if (Tok.is(tok::l_paren)) {
     573                 :     // Parse C++ direct initializer: '(' expression-list ')'
     574              109:     SourceLocation LParenLoc = ConsumeParen();
     575              109:     ExprVector Exprs(Actions);
     576              109:     CommaLocsTy CommaLocs;
     577                 : 
                      109: branch 1 taken
                        0: branch 2 not taken
                        1: branch 5 taken
                      108: branch 6 taken
                        1: branch 7 taken
                      108: branch 8 taken
     578              109:     if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
     579                1:       EnterScope(0);
     580                1:       Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
     581                 :     }
     582                 : 
                        2: branch 1 taken
                      107: branch 2 taken
     583              109:     if (ParseExpressionList(Exprs, CommaLocs)) {
     584                2:       SkipUntil(tok::r_paren);
     585                 : 
                        2: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        2: branch 6 taken
                        0: branch 7 not taken
                        2: branch 8 taken
     586                2:       if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
     587                0:         Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
     588                0:         ExitScope();
     589                 :       }
     590                 :     } else {
     591                 :       // Match the ')'.
     592              107:       SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
     593                 : 
     594                 :       assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
                      107: branch 1 taken
                        0: branch 2 not taken
                      107: branch 5 taken
                        0: branch 6 not taken
     595              107:              "Unexpected number of commas!");
     596                 : 
                      107: branch 1 taken
                        0: branch 2 not taken
                        1: branch 5 taken
                      106: branch 6 taken
                        1: branch 7 taken
                      106: branch 8 taken
     597              214:       if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
     598                1:         Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
     599                1:         ExitScope();
     600                 :       }
     601                 : 
     602                 :       Actions.AddCXXDirectInitializerToDecl(ThisDecl, LParenLoc,
     603                 :                                             move_arg(Exprs),
     604              107:                                             CommaLocs.data(), RParenLoc);
     605              109:     }
     606                 :   } else {
     607                 :     bool TypeContainsUndeducedAuto =
     608            14465:       D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
     609            14465:     Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsUndeducedAuto);
     610                 :   }
     611                 : 
     612            19859:   return ThisDecl;
     613                 : }
     614                 : 
     615                 : /// ParseSpecifierQualifierList
     616                 : ///        specifier-qualifier-list:
     617                 : ///          type-specifier specifier-qualifier-list[opt]
     618                 : ///          type-qualifier specifier-qualifier-list[opt]
     619                 : /// [GNU]    attributes     specifier-qualifier-list[opt]
     620                 : ///
     621            17492: void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
     622                 :   /// specifier-qualifier-list is a subset of declaration-specifiers.  Just
     623                 :   /// parse declaration-specifiers and complain about extra stuff.
     624            17492:   ParseDeclarationSpecifiers(DS);
     625                 : 
     626                 :   // Validate declspec for type-name.
     627            17492:   unsigned Specs = DS.getParsedSpecifiers();
                       19: branch 0 taken
                    17473: branch 1 taken
                       17: branch 3 taken
                        2: branch 4 taken
                       10: branch 6 taken
                        7: branch 7 taken
                       10: branch 8 taken
                    17482: branch 9 taken
     628            17492:   if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
     629                 :       !DS.getAttributes())
     630               10:     Diag(Tok, diag::err_typename_requires_specqual);
     631                 : 
     632                 :   // Issue diagnostic and remove storage class if present.
                        1: branch 0 taken
                    17491: branch 1 taken
     633            17492:   if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
                        0: branch 2 not taken
                        1: branch 3 taken
     634                1:     if (DS.getStorageClassSpecLoc().isValid())
     635                0:       Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
     636                 :     else
     637                1:       Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
     638                1:     DS.ClearStorageClassSpecs();
     639                 :   }
     640                 : 
     641                 :   // Issue diagnostic and remove function specfier if present.
                        0: branch 0 not taken
                    17492: branch 1 taken
     642            17492:   if (Specs & DeclSpec::PQ_FunctionSpecifier) {
                        0: branch 1 not taken
                        0: branch 2 not taken
     643                0:     if (DS.isInlineSpecified())
     644                0:       Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
                        0: branch 1 not taken
                        0: branch 2 not taken
     645                0:     if (DS.isVirtualSpecified())
     646                0:       Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
                        0: branch 1 not taken
                        0: branch 2 not taken
     647                0:     if (DS.isExplicitSpecified())
     648                0:       Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
     649                0:     DS.ClearFunctionSpecs();
     650                 :   }
     651            17492: }
     652                 : 
     653                 : /// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
     654                 : /// specified token is valid after the identifier in a declarator which
     655                 : /// immediately follows the declspec.  For example, these things are valid:
     656                 : ///
     657                 : ///      int x   [             4];         // direct-declarator
     658                 : ///      int x   (             int y);     // direct-declarator
     659                 : ///  int(int x   )                         // direct-declarator
     660                 : ///      int x   ;                         // simple-declaration
     661                 : ///      int x   =             17;         // init-declarator-list
     662                 : ///      int x   ,             y;          // init-declarator-list
     663                 : ///      int x   __asm__       ("foo");    // init-declarator-list
     664                 : ///      int x   :             4;          // struct-declarator
     665                 : ///      int x   {             5};         // C++'0x unified initializers
     666                 : ///
     667                 : /// This is not, because 'x' does not immediately follow the declspec (though
     668                 : /// ')' happens to be valid anyway).
     669                 : ///    int (x)
     670                 : ///
     671               62: static bool isValidAfterIdentifierInDeclarator(const Token &T) {
     672                 :   return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
     673                 :          T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
                       62: branch 1 taken
                        0: branch 2 not taken
                       55: branch 4 taken
                        7: branch 5 taken
                       50: branch 7 taken
                        5: branch 8 taken
                       39: branch 10 taken
                       11: branch 11 taken
                       37: branch 13 taken
                        2: branch 14 taken
                       35: branch 16 taken
                        2: branch 17 taken
                       34: branch 19 taken
                        1: branch 20 taken
                       34: branch 22 taken
                        0: branch 23 not taken
                        1: branch 25 taken
                       33: branch 26 taken
     674               62:          T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
     675                 : }
     676                 : 
     677                 : 
     678                 : /// ParseImplicitInt - This method is called when we have an non-typename
     679                 : /// identifier in a declspec (which normally terminates the decl spec) when
     680                 : /// the declspec has no type specifier.  In this case, the declspec is either
     681                 : /// malformed or is "implicit int" (in K&R and C89).
     682                 : ///
     683                 : /// This method handles diagnosing this prettily and returns false if the
     684                 : /// declspec is done being processed.  If it recovers and thinks there may be
     685                 : /// other pieces of declspec after it, it returns true.
     686                 : ///
     687                 : bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
     688                 :                               const ParsedTemplateInfo &TemplateInfo,
     689               62:                               AccessSpecifier AS) {
                       62: branch 1 taken
                        0: branch 2 not taken
     690               62:   assert(Tok.is(tok::identifier) && "should have identifier");
     691                 : 
     692               62:   SourceLocation Loc = Tok.getLocation();
     693                 :   // If we see an identifier that is not a type name, we normally would
     694                 :   // parse it as the identifer being declared.  However, when a typename
     695                 :   // is typo'd or the definition is not included, this will incorrectly
     696                 :   // parse the typename as the identifier name and fall over misparsing
     697                 :   // later parts of the diagnostic.
     698                 :   //
     699                 :   // As such, we try to do some look-ahead in cases where this would
     700                 :   // otherwise be an "implicit-int" case to see if this is invalid.  For
     701                 :   // example: "static foo_t x = 4;"  In this case, if we parsed foo_t as
     702                 :   // an identifier with implicit int, we'd get a parse error because the
     703                 :   // next token is obviously invalid for a type.  Parse these as a case
     704                 :   // with an invalid type specifier.
                       62: branch 1 taken
                        0: branch 2 not taken
     705               62:   assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
     706                 : 
     707                 :   // Since we know that this either implicit int (which is rare) or an
     708                 :   // error, we'd do lookahead to try to do better recovery.
                       29: branch 2 taken
                       33: branch 3 taken
     709               62:   if (isValidAfterIdentifierInDeclarator(NextToken())) {
     710                 :     // If this token is valid for implicit int, e.g. "static x = 4", then
     711                 :     // we just avoid eating the identifier, so it will be parsed as the
     712                 :     // identifier in the declarator.
     713               29:     return false;
     714                 :   }
     715                 : 
     716                 :   // Otherwise, if we don't consume this token, we are going to emit an
     717                 :   // error anyway.  Try to recover from various common problems.  Check
     718                 :   // to see if this was a reference to a tag name without a tag specified.
     719                 :   // This is a common problem in C (saying 'foo' instead of 'struct foo').
     720                 :   //
     721                 :   // C++ doesn't need this, and isTagName doesn't take SS.
                       17: branch 0 taken
                       16: branch 1 taken
     722               33:   if (SS == 0) {
     723               17:     const char *TagName = 0;
     724               17:     tok::TokenKind TagKind = tok::unknown;
     725                 : 
                       15: branch 2 taken
                        1: branch 3 taken
                        0: branch 4 not taken
                        1: branch 5 taken
                        0: branch 6 not taken
     726               17:     switch (Actions.isTagName(*Tok.getIdentifierInfo(), CurScope)) {
     727               15:       default: break;
     728                1:       case DeclSpec::TST_enum:  TagName="enum"  ;TagKind=tok::kw_enum  ;break;
     729                0:       case DeclSpec::TST_union: TagName="union" ;TagKind=tok::kw_union ;break;
     730                1:       case DeclSpec::TST_struct:TagName="struct";TagKind=tok::kw_struct;break;
     731                0:       case DeclSpec::TST_class: TagName="class" ;TagKind=tok::kw_class ;break;
     732                 :     }
     733                 : 
                        2: branch 0 taken
                       15: branch 1 taken
     734               17:     if (TagName) {
     735                 :       Diag(Loc, diag::err_use_of_tag_name_without_tag)
     736                 :         << Tok.getIdentifierInfo() << TagName
     737                2:         << CodeModificationHint::CreateInsertion(Tok.getLocation(),TagName);
     738                 : 
     739                 :       // Parse this as a tag as if the missing tag were present.
                        1: branch 0 taken
                        1: branch 1 taken
     740                2:       if (TagKind == tok::kw_enum)
     741                1:         ParseEnumSpecifier(Loc, DS, AS);
     742                 :       else
     743                1:         ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS);
     744                2:       return true;
     745                 :     }
     746                 :   }
     747                 : 
     748                 :   // This is almost certainly an invalid type name. Let the action emit a 
     749                 :   // diagnostic and attempt to recover.
     750               31:   Action::TypeTy *T = 0;
                       31: branch 2 taken
                        0: branch 3 not taken
     751               31:   if (Actions.DiagnoseUnknownTypeName(*Tok.getIdentifierInfo(), Loc,
     752                 :                                       CurScope, SS, T)) {
     753                 :     // The action emitted a diagnostic, so we don't have to.
                        6: branch 0 taken
                       25: branch 1 taken
     754               31:     if (T) {
     755                 :       // The action has suggested that the type T could be used. Set that as
     756                 :       // the type in the declaration specifiers, consume the would-be type
     757                 :       // name token, and we're done.
     758                 :       const char *PrevSpec;
     759                 :       unsigned DiagID;
     760                 :       DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T, 
     761                6:                          false);
     762                6:       DS.SetRangeEnd(Tok.getLocation());
     763                6:       ConsumeToken();
     764                 :       
     765                 :       // There may be other declaration specifiers after this.
     766                6:       return true;
     767                 :     }
     768                 :     
     769                 :     // Fall through; the action had no suggestion for us.
     770                 :   } else {
     771                 :     // The action did not emit a diagnostic, so emit one now.
     772                0:     SourceRange R;
                        0: branch 0 not taken
                        0: branch 1 not taken
     773                0:     if (SS) R = SS->getRange();
     774                0:     Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
     775                 :   }
     776                 : 
     777                 :   // Mark this as an error.
     778                 :   const char *PrevSpec;
     779                 :   unsigned DiagID;
     780               25:   DS.SetTypeSpecType(DeclSpec::TST_error, Loc, PrevSpec, DiagID);
     781               25:   DS.SetRangeEnd(Tok.getLocation());
     782               25:   ConsumeToken();
     783                 : 
     784                 :   // TODO: Could inject an invalid typedef decl in an enclosing scope to
     785                 :   // avoid rippling error messages on subsequent uses of the same type,
     786                 :   // could be useful if #include was forgotten.
     787               25:   return false;
     788                 : }
     789                 : 
     790                 : /// \brief Determine the declaration specifier context from the declarator
     791                 : /// context.
     792                 : ///
     793                 : /// \param Context the declarator context, which is one of the
     794                 : /// Declarator::TheContext enumerator values.
     795                 : Parser::DeclSpecContext 
     796            15133: Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
                        0: branch 0 not taken
                    15133: branch 1 taken
     797            15133:   if (Context == Declarator::MemberContext)
     798                0:     return DSC_class;
                     7951: branch 0 taken
                     7182: branch 1 taken
     799            15133:   if (Context == Declarator::FileContext)
     800             7951:     return DSC_top_level;
     801             7182:   return DSC_normal;
     802                 : }
     803                 : 
     804                 : /// ParseDeclarationSpecifiers
     805                 : ///       declaration-specifiers: [C99 6.7]
     806                 : ///         storage-class-specifier declaration-specifiers[opt]
     807                 : ///         type-specifier declaration-specifiers[opt]
     808                 : /// [C99]   function-specifier declaration-specifiers[opt]
     809                 : /// [GNU]   attributes declaration-specifiers[opt]
     810                 : ///
     811                 : ///       storage-class-specifier: [C99 6.7.1]
     812                 : ///         'typedef'
     813                 : ///         'extern'
     814                 : ///         'static'
     815                 : ///         'auto'
     816                 : ///         'register'
     817                 : /// [C++]   'mutable'
     818                 : /// [GNU]   '__thread'
     819                 : ///       function-specifier: [C99 6.7.4]
     820                 : /// [C99]   'inline'
     821                 : /// [C++]   'virtual'
     822                 : /// [C++]   'explicit'
     823                 : ///       'friend': [C++ dcl.friend]
     824                 : ///       'constexpr': [C++0x dcl.constexpr]
     825                 : 
     826                 : ///
     827                 : void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
     828                 :                                         const ParsedTemplateInfo &TemplateInfo,
     829                 :                                         AccessSpecifier AS,
     830            68202:                                         DeclSpecContext DSContext) {
                        1: branch 1 taken
                    68201: branch 2 taken
     831            68202:   if (Tok.is(tok::code_completion)) {
     832                1:     Action::CodeCompletionContext CCC = Action::CCC_Namespace;
                        0: branch 0 not taken
                        1: branch 1 taken
     833                1:     if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
     834                 :       CCC = DSContext == DSC_class? Action::CCC_MemberTemplate 
                        0: branch 0 not taken
                        0: branch 1 not taken
     835                0:                                   : Action::CCC_Template;
                        1: branch 0 taken
                        0: branch 1 not taken
     836                1:     else if (DSContext == DSC_class)
     837                1:       CCC = Action::CCC_Class;
                        0: branch 1 not taken
                        0: branch 2 not taken
     838                0:     else if (ObjCImpDecl)
     839                0:       CCC = Action::CCC_ObjCImplementation;
     840                 :     
     841                1:     Actions.CodeCompleteOrdinaryName(CurScope, CCC);
     842                1:     ConsumeToken();
     843                 :   }
     844                 :   
     845            68202:   DS.SetRangeStart(Tok.getLocation());
     846            89325:   while (1) {
     847           157527:     bool isInvalid = false;
     848           157527:     const char *PrevSpec = 0;
     849           157527:     unsigned DiagID = 0;
     850                 : 
     851           157527:     SourceLocation Loc = Tok.getLocation();
     852                 : 
                    34535: branch 1 taken
                       21: branch 2 taken
                      710: branch 3 taken
                    11977: branch 4 taken
                    42614: branch 5 taken
                      492: branch 6 taken
                     1766: branch 7 taken
                       11: branch 8 taken
                        1: branch 9 taken
                        4: branch 10 taken
                     6304: branch 11 taken
                     1909: branch 12 taken
                       19: branch 13 taken
                     2050: branch 14 taken
                       15: branch 15 taken
                       64: branch 16 taken
                       20: branch 17 taken
                       20: branch 18 taken
                     1407: branch 19 taken
                      557: branch 20 taken
                       31: branch 21 taken
                       97: branch 22 taken
                        0: branch 23 not taken
                      742: branch 24 taken
                     2083: branch 25 taken
                      420: branch 26 taken
                     2647: branch 27 taken
                      195: branch 28 taken
                        0: branch 29 not taken
                    11765: branch 30 taken
                     5462: branch 31 taken
                    16069: branch 32 taken
                     1626: branch 33 taken
                      985: branch 34 taken
                       20: branch 35 taken
                        2: branch 36 taken
                        2: branch 37 taken
                      346: branch 38 taken
                        1: branch 39 taken
                        0: branch 40 not taken
                        0: branch 41 not taken
                       84: branch 42 taken
                        4: branch 43 taken
                     7110: branch 44 taken
                      380: branch 45 taken
                     2395: branch 46 taken
                      151: branch 47 taken
                        9: branch 48 taken
                      125: branch 49 taken
                      260: branch 50 taken
                       16: branch 51 taken
                        4: branch 52 taken
     853           157527:     switch (Tok.getKind()) {
     854                 :     default:
     855            68202:     DoneWithDeclSpec:
     856                 :       // If this is not a declaration specifier token, we're done reading decl
     857                 :       // specifiers.  First verify that DeclSpec's are consistent.
     858            68202:       DS.Finish(Diags, PP);
     859                 :       return;
     860                 : 
     861                 :     case tok::coloncolon: // ::foo::bar
     862                 :       // Annotate C++ scope specifiers.  If we get one, loop.
                       21: branch 1 taken
                        0: branch 2 not taken
     863               21:       if (TryAnnotateCXXScopeToken(true))
     864               21:         continue;
     865                0:       goto DoneWithDeclSpec;
     866                 : 
     867                 :     case tok::annot_cxxscope: {
                      465: branch 1 taken
                      245: branch 2 taken
     868              710:       if (DS.hasTypeSpecifier())
     869              465:         goto DoneWithDeclSpec;
     870                 : 
     871              245:       CXXScopeSpec SS;
     872              245:       SS.setScopeRep(Tok.getAnnotationValue());
     873              245:       SS.setRange(Tok.getAnnotationRange());
     874                 : 
     875                 :       // We are looking for a qualified typename.
     876              245:       Token Next = NextToken();
                       41: branch 1 taken
                      204: branch 2 taken
                       41: branch 4 taken
                        0: branch 5 not taken
                       41: branch 6 taken
                      204: branch 7 taken
     877              245:       if (Next.is(tok::annot_template_id) &&
     878                 :           static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
     879                 :             ->Kind == TNK_Type_template) {
     880                 :         // We have a qualified template-id, e.g., N::A<int>
     881                 : 
     882                 :         // C++ [class.qual]p2:
     883                 :         //   In a lookup in which the constructor is an acceptable lookup
     884                 :         //   result and the nested-name-specifier nominates a class C:
     885                 :         //
     886                 :         //     - if the name specified after the
     887                 :         //       nested-name-specifier, when looked up in C, is the
     888                 :         //       injected-class-name of C (Clause 9), or
     889                 :         //
     890                 :         //     - if the name specified after the nested-name-specifier
     891                 :         //       is the same as the identifier or the
     892                 :         //       simple-template-id's template-name in the last
     893                 :         //       component of the nested-name-specifier,
     894                 :         //
     895                 :         //   the name is instead considered to name the constructor of
     896                 :         //   class C.
     897                 :         // 
     898                 :         // Thus, if the template-name is actually the constructor
     899                 :         // name, then the code is ill-formed; this interpretation is
     900                 :         // reinforced by the NAD status of core issue 635. 
     901                 :         TemplateIdAnnotation *TemplateId
     902               41:           = static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue());
                       23: branch 0 taken
                       18: branch 1 taken
                       23: branch 2 taken
                        0: branch 3 not taken
                        4: branch 5 taken
                       19: branch 6 taken
                        4: branch 7 taken
                       37: branch 8 taken
     903               41:         if (DSContext == DSC_top_level && TemplateId->Name &&
     904                 :             Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) {
                        1: branch 1 taken
                        3: branch 2 taken
     905                4:           if (isConstructorDeclarator()) {
     906                 :             // The user meant this to be an out-of-line constructor
     907                 :             // definition, but template arguments are not allowed
     908                 :             // there.  Just allow this as a constructor; we'll
     909                 :             // complain about it later.
     910                1:             goto DoneWithDeclSpec;
     911                 :           }
     912                 : 
     913                 :           // The user meant this to name a type, but it actually names
     914                 :           // a constructor with some extraneous template
     915                 :           // arguments. Complain, then parse it as a type as the user
     916                 :           // intended.
     917                 :           Diag(TemplateId->TemplateNameLoc,
     918                 :                diag::err_out_of_line_template_id_names_constructor)
     919                3:             << TemplateId->Name;
     920                 :         }
     921                 : 
     922               40:         DS.getTypeSpecScope() = SS;
     923               40:         ConsumeToken(); // The C++ scope.
     924                 :         assert(Tok.is(tok::annot_template_id) &&
                       40: branch 1 taken
                        0: branch 2 not taken
     925               40:                "ParseOptionalCXXScopeSpecifier not working");
     926               40:         AnnotateTemplateIdTokenAsType(&SS);
     927               40:         continue;
     928                 :       }
     929                 : 
                        0: branch 1 not taken
                      204: branch 2 taken
     930              204:       if (Next.is(tok::annot_typename)) {
     931                0:         DS.getTypeSpecScope() = SS;
     932                0:         ConsumeToken(); // The C++ scope.
                        0: branch 1 not taken
                        0: branch 2 not taken
     933                0:         if (Tok.getAnnotationValue())
     934                 :           isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, 
     935                 :                                          PrevSpec, DiagID, 
     936                0:                                          Tok.getAnnotationValue());
     937                 :         else
     938                0:           DS.SetTypeSpecError();
     939                0:         DS.SetRangeEnd(Tok.getAnnotationEndLoc());
     940                0:         ConsumeToken(); // The typename
     941                 :       }
     942                 : 
                       41: branch 1 taken
                      163: branch 2 taken
     943              204:       if (Next.isNot(tok::identifier))
     944               41:         goto DoneWithDeclSpec;
     945                 : 
     946                 :       // If we're in a context where the identifier could be a class name,
     947                 :       // check whether this is a constructor declaration.
                      135: branch 0 taken
                       28: branch 1 taken
                       58: branch 4 taken
                       77: branch 5 taken
                       58: branch 6 taken
                      105: branch 7 taken
     948              163:       if (DSContext == DSC_top_level &&
     949                 :           Actions.isCurrentClassName(*Next.getIdentifierInfo(), CurScope, 
     950                 :                                      &SS)) {
                       55: branch 1 taken
                        3: branch 2 taken
     951               58:         if (isConstructorDeclarator())
     952               55:           goto DoneWithDeclSpec;
     953                 : 
     954                 :         // As noted in C++ [class.qual]p2 (cited above), when the name
     955                 :         // of the class is qualified in a context where it could name
     956                 :         // a constructor, its a constructor name. However, we've
     957                 :         // looked at the declarator, and the user probably meant this
     958                 :         // to be a type. Complain that it isn't supposed to be treated
     959                 :         // as a type, then proceed to parse it as a type.
     960                 :         Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
     961                3:           << Next.getIdentifierInfo();
     962                 :       }
     963                 : 
     964                 :       TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
     965              108:                                             Next.getLocation(), CurScope, &SS);
     966                 : 
     967                 :       // If the referenced identifier is not a type, then this declspec is
     968                 :       // erroneous: We already checked about that it has no type specifier, and
     969                 :       // C++ doesn't have implicit int.  Diagnose it as a typo w.r.t. to the
     970                 :       // typename.
                       17: branch 0 taken
                       91: branch 1 taken
     971              108:       if (TypeRep == 0) {
     972               17:         ConsumeToken();   // Eat the scope spec so the identifier is current.
                       13: branch 1 taken
                        4: branch 2 taken
     973               17:         if (ParseImplicitInt(DS, &SS, TemplateInfo, AS)) continue;
     974               13:         goto DoneWithDeclSpec;
     975                 :       }
     976                 : 
     977               91:       DS.getTypeSpecScope() = SS;
     978               91:       ConsumeToken(); // The C++ scope.
     979                 : 
     980                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
     981               91:                                      DiagID, TypeRep);
                       91: branch 0 taken
                        0: branch 1 not taken
     982               91:       if (isInvalid)
     983                0:         break;
     984                 : 
     985               91:       DS.SetRangeEnd(Tok.getLocation());
     986               91:       ConsumeToken(); // The typename.
     987                 : 
     988               91:       continue;
     989                 :     }
     990                 : 
     991                 :     case tok::annot_typename: {
                    11921: branch 1 taken
                       56: branch 2 taken
     992            11977:       if (Tok.getAnnotationValue())
     993                 :         isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
     994            11921:                                        DiagID, Tok.getAnnotationValue());
     995                 :       else
     996               56:         DS.SetTypeSpecError();
     997            11977:       DS.SetRangeEnd(Tok.getAnnotationEndLoc());
     998            11977:       ConsumeToken(); // The typename
     999                 : 
    1000                 :       // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
    1001                 :       // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
    1002                 :       // Objective-C interface.  If we don't have Objective-C or a '<', this is
    1003                 :       // just a normal reference to a typedef name.
                      218: branch 1 taken
                    11759: branch 2 taken
                        0: branch 4 not taken
                      218: branch 5 taken
                    11759: branch 6 taken
                      218: branch 7 taken
    1004            11977:       if (!Tok.is(tok::less) || !getLang().ObjC1)
    1005            11759:         continue;
    1006                 : 
    1007              218:       SourceLocation LAngleLoc, EndProtoLoc;
    1008              218:       llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
    1009              218:       llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
    1010                 :       ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
    1011              218:                                   LAngleLoc, EndProtoLoc);
    1012                 :       DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
    1013              218:                                ProtocolLocs.data(), LAngleLoc);
    1014                 : 
    1015              218:       DS.SetRangeEnd(EndProtoLoc);
    1016              218:       continue;
    1017                 :     }
    1018                 : 
    1019                 :       // typedef-name
    1020                 :     case tok::identifier: {
    1021                 :       // In C++, check to see if this is a scope specifier like foo::bar::, if
    1022                 :       // so handle it as such.  This is important for ctor parsing.
                    16211: branch 1 taken
                    26403: branch 2 taken
                     1139: branch 4 taken
                    15072: branch 5 taken
                     1139: branch 6 taken
                    41475: branch 7 taken
    1023            42614:       if (getLang().CPlusPlus && TryAnnotateCXXScopeToken(true))
    1024             1139:         continue;
    1025                 : 
    1026                 :       // This identifier can only be a typedef name if we haven't already seen
    1027                 :       // a type-specifier.  Without this check we misparse:
    1028                 :       //  typedef int X; struct Y { short X; };  as 'short int'.
                    32399: branch 1 taken
                     9076: branch 2 taken
    1029            41475:       if (DS.hasTypeSpecifier())
    1030            32399:         goto DoneWithDeclSpec;
    1031                 : 
    1032                 :       // Check for need to substitute AltiVec keyword tokens.
                       64: branch 1 taken
                     9012: branch 2 taken
    1033             9076:       if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
    1034               64:         break;
    1035                 : 
    1036                 :       // It has to be available as a typedef too!
    1037                 :       TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(),
    1038             9012:                                             Tok.getLocation(), CurScope);
    1039                 : 
    1040                 :       // If this is not a typedef name, don't parse it as part of the declspec,
    1041                 :       // it must be an implicit int or an error.
                       45: branch 0 taken
                     8967: branch 1 taken
    1042             9012:       if (TypeRep == 0) {
                       41: branch 1 taken
                        4: branch 2 taken
    1043               45:         if (ParseImplicitInt(DS, 0, TemplateInfo, AS)) continue;
    1044               41:         goto DoneWithDeclSpec;
    1045                 :       }
    1046                 : 
    1047                 :       // If we're in a context where the identifier could be a class name,
    1048                 :       // check whether this is a constructor declaration.
                     4024: branch 1 taken
                     4943: branch 2 taken
                     1203: branch 3 taken
                     2821: branch 4 taken
                      722: branch 7 taken
                      481: branch 8 taken
                      588: branch 10 taken
                      134: branch 11 taken
                      588: branch 12 taken
                     8379: branch 13 taken
    1049             8967:       if (getLang().CPlusPlus && DSContext == DSC_class &&
    1050                 :           Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope) &&
    1051                 :           isConstructorDeclarator())
    1052              588:         goto DoneWithDeclSpec;
    1053                 : 
    1054                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
    1055             8379:                                      DiagID, TypeRep);
                        0: branch 0 not taken
                     8379: branch 1 taken
    1056             8379:       if (isInvalid)
    1057                0:         break;
    1058                 : 
    1059             8379:       DS.SetRangeEnd(Tok.getLocation());
    1060             8379:       ConsumeToken(); // The identifier
    1061                 : 
    1062                 :       // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
    1063                 :       // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
    1064                 :       // Objective-C interface.  If we don't have Objective-C or a '<', this is
    1065                 :       // just a normal reference to a typedef name.
                      116: branch 1 taken
                     8263: branch 2 taken
                        0: branch 4 not taken
                      116: branch 5 taken
                     8263: branch 6 taken
                      116: branch 7 taken
    1066             8379:       if (!Tok.is(tok::less) || !getLang().ObjC1)
    1067             8263:         continue;
    1068                 : 
    1069              116:       SourceLocation LAngleLoc, EndProtoLoc;
    1070              116:       llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
    1071              116:       llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
    1072                 :       ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
    1073              116:                                   LAngleLoc, EndProtoLoc);
    1074                 :       DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
    1075              116:                                ProtocolLocs.data(), LAngleLoc);
    1076                 : 
    1077              116:       DS.SetRangeEnd(EndProtoLoc);
    1078                 : 
    1079                 :       // Need to support trailing type qualifiers (e.g. "id<p> const").
    1080                 :       // If a type specifier follows, it will be diagnosed elsewhere.
    1081              116:       continue;
    1082                 :     }
    1083                 : 
    1084                 :       // type-name
    1085                 :     case tok::annot_template_id: {
    1086                 :       TemplateIdAnnotation *TemplateId
    1087              492:         = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
                       60: branch 0 taken
                      432: branch 1 taken
    1088              492:       if (TemplateId->Kind != TNK_Type_template) {
    1089                 :         // This template-id does not refer to a type name, so we're
    1090                 :         // done with the type-specifiers.
    1091               60:         goto DoneWithDeclSpec;
    1092                 :       }
    1093                 : 
    1094                 :       // If we're in a context where the template-id could be a
    1095                 :       // constructor name or specialization, check whether this is a
    1096                 :       // constructor declaration.
                      432: branch 1 taken
                        0: branch 2 not taken
                       80: branch 3 taken
                      352: branch 4 taken
                       15: branch 6 taken
                       65: branch 7 taken
                        3: branch 9 taken
                       12: branch 10 taken
                        3: branch 11 taken
                      429: branch 12 taken
    1097              432:       if (getLang().CPlusPlus && DSContext == DSC_class &&
    1098                 :           Actions.isCurrentClassName(*TemplateId->Name, CurScope) &&
    1099                 :           isConstructorDeclarator())
    1100                3:         goto DoneWithDeclSpec;
    1101                 : 
    1102                 :       // Turn the template-id annotation token into a type annotation
    1103                 :       // token, then try again to parse it as a type-specifier.
    1104              429:       AnnotateTemplateIdTokenAsType();
    1105              429:       continue;
    1106                 :     }
    1107                 : 
    1108                 :     // GNU attributes support.
    1109                 :     case tok::kw___attribute:
    1110             1766:       DS.AddAttributes(ParseGNUAttributes());
    1111             1766:       continue;
    1112                 : 
    1113                 :     // Microsoft declspec support.
    1114                 :     case tok::kw___declspec:
    1115               11:       DS.AddAttributes(ParseMicrosoftDeclSpec());
    1116               11:       continue;
    1117                 : 
    1118                 :     // Microsoft single token adornments.
    1119                 :     case tok::kw___forceinline:
    1120                 :       // FIXME: Add handling here!
    1121                1:       break;
    1122                 : 
    1123                 :     case tok::kw___ptr64:
    1124                 :     case tok::kw___w64:
    1125                 :     case tok::kw___cdecl:
    1126                 :     case tok::kw___stdcall:
    1127                 :     case tok::kw___fastcall:
    1128                4:       DS.AddAttributes(ParseMicrosoftTypeAttributes());
    1129                4:       continue;
    1130                 : 
    1131                 :     // storage-class-specifier
    1132                 :     case tok::kw_typedef:
    1133                 :       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec,
    1134             6304:                                          DiagID);
    1135             6304:       break;
    1136                 :     case tok::kw_extern:
                        2: branch 1 taken
                     1907: branch 2 taken
    1137             1909:       if (DS.isThreadSpecified())
    1138                2:         Diag(Tok, diag::ext_thread_before) << "extern";
    1139                 :       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec,
    1140             1909:                                          DiagID);
    1141             1909:       break;
    1142                 :     case tok::kw___private_extern__:
    1143                 :       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
    1144               19:                                          PrevSpec, DiagID);
    1145               19:       break;
    1146                 :     case tok::kw_static:
                        4: branch 1 taken
                     2046: branch 2 taken
    1147             2050:       if (DS.isThreadSpecified())
    1148                4:         Diag(Tok, diag::ext_thread_before) << "static";
    1149                 :       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec,
    1150             2050:                                          DiagID);
    1151             2050:       break;
    1152                 :     case tok::kw_auto:
                       10: branch 1 taken
                        5: branch 2 taken
    1153               15:       if (getLang().CPlusPlus0x)
    1154                 :         isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
    1155               10:                                        DiagID);
    1156                 :       else
    1157                 :         isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec,
    1158                5:                                            DiagID);
    1159               15:       break;
    1160                 :     case tok::kw_register:
    1161                 :       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec,
    1162               64:                                          DiagID);
    1163               64:       break;
    1164                 :     case tok::kw_mutable:
    1165                 :       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec,
    1166               20:                                          DiagID);
    1167               20:       break;
    1168                 :     case tok::kw___thread:
    1169               20:       isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
    1170               20:       break;
    1171                 : 
    1172                 :     // function-specifier
    1173                 :     case tok::kw_inline:
    1174             1407:       isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
    1175             1407:       break;
    1176                 :     case tok::kw_virtual:
    1177              557:       isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID);
    1178              557:       break;
    1179                 :     case tok::kw_explicit:
    1180               31:       isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
    1181               31:       break;
    1182                 : 
    1183                 :     // friend
    1184                 :     case tok::kw_friend:
                       91: branch 0 taken
                        6: branch 1 taken
    1185               97:       if (DSContext == DSC_class)
    1186               91:         isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
    1187                 :       else {
    1188                6:         PrevSpec = ""; // not actually used by the diagnostic
    1189                6:         DiagID = diag::err_friend_invalid_in_context;
    1190                6:         isInvalid = true;
    1191                 :       }
    1192               97:       break;
    1193                 : 
    1194                 :     // constexpr
    1195                 :     case tok::kw_constexpr:
    1196                0:       isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
    1197                0:       break;
    1198                 : 
    1199                 :     // type-specifier
    1200                 :     case tok::kw_short:
    1201                 :       isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
    1202              742:                                       DiagID);
    1203              742:       break;
    1204                 :     case tok::kw_long:
                     1563: branch 1 taken
                      520: branch 2 taken
    1205             2083:       if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
    1206                 :         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
    1207             1563:                                         DiagID);
    1208                 :       else
    1209                 :         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
    1210              520:                                         DiagID);
    1211             2083:       break;
    1212                 :     case tok::kw_signed:
    1213                 :       isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
    1214              420:                                      DiagID);
    1215              420:       break;
    1216                 :     case tok::kw_unsigned:
    1217                 :       isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
    1218             2647:                                      DiagID);
    1219             2647:       break;
    1220                 :     case tok::kw__Complex:
    1221                 :       isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
    1222              195:                                         DiagID);
    1223              195:       break;
    1224                 :     case tok::kw__Imaginary:
    1225                 :       isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
    1226                0:                                         DiagID);
    1227                0:       break;
    1228                 :     case tok::kw_void:
    1229                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
    1230            11765:                                      DiagID);
    1231            11765:       break;
    1232                 :     case tok::kw_char:
    1233                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
    1234             5462:                                      DiagID);
    1235             5462:       break;
    1236                 :     case tok::kw_int:
    1237                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
    1238            16069:                                      DiagID);
    1239            16069:       break;
    1240                 :     case tok::kw_float:
    1241                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
    1242             1626:                                      DiagID);
    1243             1626:       break;
    1244                 :     case tok::kw_double:
    1245                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
    1246              985:                                      DiagID);
    1247              985:       break;
    1248                 :     case tok::kw_wchar_t:
    1249                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
    1250               20:                                      DiagID);
    1251               20:       break;
    1252                 :     case tok::kw_char16_t:
    1253                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
    1254                2:                                      DiagID);
    1255                2:       break;
    1256                 :     case tok::kw_char32_t:
    1257                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
    1258                2:                                      DiagID);
    1259                2:       break;
    1260                 :     case tok::kw_bool:
    1261                 :     case tok::kw__Bool:
    1262                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
    1263              346:                                      DiagID);
    1264              346:       break;
    1265                 :     case tok::kw__Decimal32:
    1266                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
    1267                1:                                      DiagID);
    1268                1:       break;
    1269                 :     case tok::kw__Decimal64:
    1270                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
    1271                0:                                      DiagID);
    1272                0:       break;
    1273                 :     case tok::kw__Decimal128:
    1274                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
    1275                0:                                      DiagID);
    1276                0:       break;
    1277                 :     case tok::kw___vector:
    1278               84:       isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
    1279               84:       break;
    1280                 :     case tok::kw___pixel:
    1281                4:       isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
    1282                4:       break;
    1283                 : 
    1284                 :     // class-specifier:
    1285                 :     case tok::kw_class:
    1286                 :     case tok::kw_struct:
    1287                 :     case tok::kw_union: {
    1288             7110:       tok::TokenKind Kind = Tok.getKind();
    1289             7110:       ConsumeToken();
    1290             7110:       ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS);
    1291             7110:       continue;
    1292                 :     }
    1293                 : 
    1294                 :     // enum-specifier:
    1295                 :     case tok::kw_enum:
    1296              380:       ConsumeToken();
    1297              380:       ParseEnumSpecifier(Loc, DS, AS);
    1298              380:       continue;
    1299                 : 
    1300                 :     // cv-qualifier:
    1301                 :     case tok::kw_const:
    1302                 :       isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
    1303             2395:                                  getLang());
    1304             2395:       break;
    1305                 :     case tok::kw_volatile:
    1306                 :       isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
    1307              151:                                  getLang());
    1308              151:       break;
    1309                 :     case tok::kw_restrict:
    1310                 :       isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
    1311                9:                                  getLang());
    1312                9:       break;
    1313                 : 
    1314                 :     // C++ typename-specifier:
    1315                 :     case tok::kw_typename:
                      123: branch 1 taken
                        2: branch 2 taken
    1316              125:       if (TryAnnotateTypeOrScopeToken())
    1317              123:         continue;
    1318                2:       break;
    1319                 : 
    1320                 :     // GNU typeof support.
    1321                 :     case tok::kw_typeof:
    1322              260:       ParseTypeofSpecifier(DS);
    1323              260:       continue;
    1324                 : 
    1325                 :     case tok::kw_decltype:
    1326               16:       ParseDecltypeSpecifier(DS);
    1327               16:       continue;
    1328                 : 
    1329                 :     case tok::less:
    1330                 :       // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
    1331                 :       // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous,
    1332                 :       // but we support it.
                        3: branch 1 taken
                        1: branch 2 taken
                        0: branch 4 not taken
                        3: branch 5 taken
                        1: branch 6 taken
                        3: branch 7 taken
    1333                4:       if (DS.hasTypeSpecifier() || !getLang().ObjC1)
    1334                1:         goto DoneWithDeclSpec;
    1335                 : 
    1336                 :       {
    1337                3:         SourceLocation LAngleLoc, EndProtoLoc;
    1338                3:         llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
    1339                3:         llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
    1340                 :         ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
    1341                3:                                     LAngleLoc, EndProtoLoc);
    1342                 :         DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
    1343                3:                                  ProtocolLocs.data(), LAngleLoc);
    1344                3:         DS.SetRangeEnd(EndProtoLoc);
    1345                 : 
    1346                 :         Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
    1347                 :           << CodeModificationHint::CreateInsertion(Loc, "id")
    1348                3:           << SourceRange(Loc, EndProtoLoc);
    1349                 :         // Need to support trailing type qualifiers (e.g. "id<p> const").
    1350                 :         // If a type specifier follows, it will be diagnosed elsewhere.
    1351                3:         continue;
    1352                 :       }
    1353                 :     }
    1354                 :     // If the specifier wasn't legal, issue a diagnostic.
                       55: branch 0 taken
                    57513: branch 1 taken
    1355            57568:     if (isInvalid) {
                        0: branch 0 not taken
                       55: branch 1 taken
    1356               55:       assert(PrevSpec && "Method did not return previous specifier!");
                        0: branch 0 not taken
                       55: branch 1 taken
    1357               55:       assert(DiagID);
    1358               55:       Diag(Tok, DiagID) << PrevSpec;
    1359                 :     }
    1360            57568:     DS.SetRangeEnd(Tok.getLocation());
    1361            57568:     ConsumeToken();
    1362                 :   }
    1363                 : }
    1364                 : 
    1365                 : /// ParseOptionalTypeSpecifier - Try to parse a single type-specifier. We
    1366                 : /// primarily follow the C++ grammar with additions for C99 and GNU,
    1367                 : /// which together subsume the C grammar. Note that the C++
    1368                 : /// type-specifier also includes the C type-qualifier (for const,
    1369                 : /// volatile, and C99 restrict). Returns true if a type-specifier was
    1370                 : /// found (and parsed), false otherwise.
    1371                 : ///
    1372                 : ///       type-specifier: [C++ 7.1.5]
    1373                 : ///         simple-type-specifier
    1374                 : ///         class-specifier
    1375                 : ///         enum-specifier
    1376                 : ///         elaborated-type-specifier  [TODO]
    1377                 : ///         cv-qualifier
    1378                 : ///
    1379                 : ///       cv-qualifier: [C++ 7.1.5.1]
    1380                 : ///         'const'
    1381                 : ///         'volatile'
    1382                 : /// [C99]   'restrict'
    1383                 : ///
    1384                 : ///       simple-type-specifier: [ C++ 7.1.5.2]
    1385                 : ///         '::'[opt] nested-name-specifier[opt] type-name [TODO]
    1386                 : ///         '::'[opt] nested-name-specifier 'template' template-id [TODO]
    1387                 : ///         'char'
    1388                 : ///         'wchar_t'
    1389                 : ///         'bool'
    1390                 : ///         'short'
    1391                 : ///         'int'
    1392                 : ///         'long'
    1393                 : ///         'signed'
    1394                 : ///         'unsigned'
    1395                 : ///         'float'
    1396                 : ///         'double'
    1397                 : ///         'void'
    1398                 : /// [C99]   '_Bool'
    1399                 : /// [C99]   '_Complex'
    1400                 : /// [C99]   '_Imaginary'  // Removed in TC2?
    1401                 : /// [GNU]   '_Decimal32'
    1402                 : /// [GNU]   '_Decimal64'
    1403                 : /// [GNU]   '_Decimal128'
    1404                 : /// [GNU]   typeof-specifier
    1405                 : /// [OBJC]  class-name objc-protocol-refs[opt]    [TODO]
    1406                 : /// [OBJC]  typedef-name objc-protocol-refs[opt]  [TODO]
    1407                 : /// [C++0x] 'decltype' ( expression )
    1408                 : /// [AltiVec] '__vector'
    1409                 : bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
    1410                 :                                         const char *&PrevSpec,
    1411                 :                                         unsigned &DiagID,
    1412                 :                                         const ParsedTemplateInfo &TemplateInfo,
    1413             1075:                                         bool SuppressDeclarations) {
    1414             1075:   SourceLocation Loc = Tok.getLocation();
    1415                 : 
                      231: branch 1 taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                      215: branch 4 taken
                        5: branch 5 taken
                        5: branch 6 taken
                        1: branch 7 taken
                        3: branch 8 taken
                        1: branch 9 taken
                        0: branch 10 not taken
                        3: branch 11 taken
                        9: branch 12 taken
                      130: branch 13 taken
                       14: branch 14 taken
                        3: branch 15 taken
                        0: branch 16 not taken
                        0: branch 17 not taken
                        0: branch 18 not taken
                       19: branch 19 taken
                        0: branch 20 not taken
                        0: branch 21 not taken
                        0: branch 22 not taken
                        0: branch 23 not taken
                        0: branch 24 not taken
                        3: branch 25 taken
                        0: branch 26 not taken
                       22: branch 27 taken
                        6: branch 28 taken
                        0: branch 29 not taken
                        0: branch 30 not taken
                        0: branch 31 not taken
                        1: branch 32 taken
                        0: branch 33 not taken
                      404: branch 34 taken
    1416             1075:   switch (Tok.getKind()) {
    1417                 :   case tok::identifier:   // foo::bar
    1418                 :     // Check for need to substitute AltiVec keyword tokens.
                      231: branch 1 taken
                        0: branch 2 not taken
    1419              231:     if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
    1420                0:       break;
    1421                 :     // Fall through.
    1422                 :   case tok::kw_typename:  // typename foo::bar
    1423                 :     // Annotate typenames and C++ scope specifiers.  If we get one, just
    1424                 :     // recurse to handle whatever we get.
                      218: branch 1 taken
                       13: branch 2 taken
    1425              231:     if (TryAnnotateTypeOrScopeToken())
    1426                 :       return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
    1427              218:                                         TemplateInfo, SuppressDeclarations);
    1428                 :     // Otherwise, not a type specifier.
    1429               13:     return false;
    1430                 :   case tok::coloncolon:   // ::foo::bar
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
    1431                0:     if (NextToken().is(tok::kw_new) ||    // ::new
    1432                 :         NextToken().is(tok::kw_delete))   // ::delete
    1433                0:       return false;
    1434                 : 
    1435                 :     // Annotate typenames and C++ scope specifiers.  If we get one, just
    1436                 :     // recurse to handle whatever we get.
                        0: branch 1 not taken
                        0: branch 2 not taken
    1437                0:     if (TryAnnotateTypeOrScopeToken())
    1438                 :       return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
    1439                0:                                         TemplateInfo, SuppressDeclarations);
    1440                 :     // Otherwise, not a type specifier.
    1441                0:     return false;
    1442                 : 
    1443                 :   // simple-type-specifier:
    1444                 :   case tok::annot_typename: {
                      215: branch 1 taken
                        0: branch 2 not taken
    1445              215:     if (Tok.getAnnotationValue())
    1446                 :       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
    1447              215:                                      DiagID, Tok.getAnnotationValue());
    1448                 :     else
    1449                0:       DS.SetTypeSpecError();
    1450              215:     DS.SetRangeEnd(Tok.getAnnotationEndLoc());
    1451              215:     ConsumeToken(); // The typename
    1452                 : 
    1453                 :     // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
    1454                 :     // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
    1455                 :     // Objective-C interface.  If we don't have Objective-C or a '<', this is
    1456                 :     // just a normal reference to a typedef name.
                        0: branch 1 not taken
                      215: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                      215: branch 6 taken
                        0: branch 7 not taken
    1457              215:     if (!Tok.is(tok::less) || !getLang().ObjC1)
    1458              215:       return true;
    1459                 : 
    1460                0:     SourceLocation LAngleLoc, EndProtoLoc;
    1461                0:     llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
    1462                0:     llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
    1463                 :     ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
    1464                0:                                 LAngleLoc, EndProtoLoc);
    1465                 :     DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
    1466                0:                              ProtocolLocs.data(), LAngleLoc);
    1467                 : 
    1468                0:     DS.SetRangeEnd(EndProtoLoc);
    1469                0:     return true;
    1470                 :   }
    1471                 : 
    1472                 :   case tok::kw_short:
    1473                5:     isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
    1474                5:     break;
    1475                 :   case tok::kw_long:
                        5: branch 1 taken
                        0: branch 2 not taken
    1476                5:     if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
    1477                 :       isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
    1478                5:                                       DiagID);
    1479                 :     else
    1480                 :       isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
    1481                0:                                       DiagID);
    1482                5:     break;
    1483                 :   case tok::kw_signed:
    1484                1:     isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
    1485                1:     break;
    1486                 :   case tok::kw_unsigned:
    1487                 :     isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
    1488                3:                                    DiagID);
    1489                3:     break;
    1490                 :   case tok::kw__Complex:
    1491                 :     isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
    1492                1:                                       DiagID);
    1493                1:     break;
    1494                 :   case tok::kw__Imaginary:
    1495                 :     isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
    1496                0:                                       DiagID);
    1497                0:     break;
    1498                 :   case tok::kw_void:
    1499                3:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
    1500                3:     break;
    1501                 :   case tok::kw_char:
    1502                9:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
    1503                9:     break;
    1504                 :   case tok::kw_int:
    1505              130:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
    1506              130:     break;
    1507                 :   case tok::kw_float:
    1508               14:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
    1509               14:     break;
    1510                 :   case tok::kw_double:
    1511                3:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
    1512                3:     break;
    1513                 :   case tok::kw_wchar_t:
    1514                0:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
    1515                0:     break;
    1516                 :   case tok::kw_char16_t:
    1517                0:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
    1518                0:     break;
    1519                 :   case tok::kw_char32_t:
    1520                0:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
    1521                0:     break;
    1522                 :   case tok::kw_bool:
    1523                 :   case tok::kw__Bool:
    1524               19:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
    1525               19:     break;
    1526                 :   case tok::kw__Decimal32:
    1527                 :     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
    1528                0:                                    DiagID);
    1529                0:     break;
    1530                 :   case tok::kw__Decimal64:
    1531                 :     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
    1532                0:                                    DiagID);
    1533                0:     break;
    1534                 :   case tok::kw__Decimal128:
    1535                 :     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
    1536                0:                                    DiagID);
    1537                0:     break;
    1538                 :   case tok::kw___vector:
    1539                0:     isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
    1540                0:     break;
    1541                 :   case tok::kw___pixel:
    1542                0:     isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
    1543                0:     break;
    1544                 :   
    1545                 :   // class-specifier:
    1546                 :   case tok::kw_class:
    1547                 :   case tok::kw_struct:
    1548                 :   case tok::kw_union: {
    1549                3:     tok::TokenKind Kind = Tok.getKind();
    1550                3:     ConsumeToken();
    1551                 :     ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS_none,
    1552                3:                         SuppressDeclarations);
    1553                3:     return true;
    1554                 :   }
    1555                 : 
    1556                 :   // enum-specifier:
    1557                 :   case tok::kw_enum:
    1558                0:     ConsumeToken();
    1559                0:     ParseEnumSpecifier(Loc, DS);
    1560                0:     return true;
    1561                 : 
    1562                 :   // cv-qualifier:
    1563                 :   case tok::kw_const:
    1564                 :     isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec,
    1565               22:                                DiagID, getLang());
    1566               22:     break;
    1567                 :   case tok::kw_volatile:
    1568                 :     isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
    1569                6:                                DiagID, getLang());
    1570                6:     break;
    1571                 :   case tok::kw_restrict:
    1572                 :     isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
    1573                0:                                DiagID, getLang());
    1574                0:     break;
    1575                 : 
    1576                 :   // GNU typeof support.
    1577                 :   case tok::kw_typeof:
    1578                0:     ParseTypeofSpecifier(DS);
    1579                0:     return true;
    1580                 : 
    1581                 :   // C++0x decltype support.
    1582                 :   case tok::kw_decltype:
    1583                0:     ParseDecltypeSpecifier(DS);
    1584                0:     return true;
    1585                 : 
    1586                 :   // C++0x auto support.
    1587                 :   case tok::kw_auto:
                        0: branch 1 not taken
                        1: branch 2 taken
    1588                1:     if (!getLang().CPlusPlus0x)
    1589                0:       return false;
    1590                 : 
    1591                1:     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID);
    1592                1:     break;
    1593                 :   case tok::kw___ptr64:
    1594                 :   case tok::kw___w64:
    1595                 :   case tok::kw___cdecl:
    1596                 :   case tok::kw___stdcall:
    1597                 :   case tok::kw___fastcall:
    1598                0:     DS.AddAttributes(ParseMicrosoftTypeAttributes());
    1599                0:     return true;
    1600                 : 
    1601                 :   default:
    1602                 :     // Not a type-specifier; do nothing.
    1603              404:     return false;
    1604                 :   }
    1605                 : 
    1606                 :   // If the specifier combination wasn't legal, issue a diagnostic.
                        0: branch 0 not taken
                      222: branch 1 taken
    1607              222:   if (isInvalid) {
                        0: branch 0 not taken
                        0: branch 1 not taken
    1608                0:     assert(PrevSpec && "Method did not return previous specifier!");
    1609                 :     // Pick between error or extwarn.
    1610                0:     Diag(Tok, DiagID) << PrevSpec;
    1611                 :   }
    1612              222:   DS.SetRangeEnd(Tok.getLocation());
    1613              222:   ConsumeToken(); // whatever we parsed above.
    1614              222:   return true;
    1615                 : }
    1616                 : 
    1617                 : /// ParseStructDeclaration - Parse a struct declaration without the terminating
    1618                 : /// semicolon.
    1619                 : ///
    1620                 : ///       struct-declaration:
    1621                 : ///         specifier-qualifier-list struct-declarator-list
    1622                 : /// [GNU]   __extension__ struct-declaration
    1623                 : /// [GNU]   specifier-qualifier-list
    1624                 : ///       struct-declarator-list:
    1625                 : ///         struct-declarator
    1626                 : ///         struct-declarator-list ',' struct-declarator
    1627                 : /// [GNU]   struct-declarator-list ',' attributes[opt] struct-declarator
    1628                 : ///       struct-declarator:
    1629                 : ///         declarator
    1630                 : /// [GNU]   declarator attributes[opt]
    1631                 : ///         declarator[opt] ':' constant-expression
    1632                 : /// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
    1633                 : ///
    1634                 : void Parser::
    1635             3603: ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
                       21: branch 1 taken
                     3582: branch 2 taken
    1636             3603:   if (Tok.is(tok::kw___extension__)) {
    1637                 :     // __extension__ silences extension warnings in the subexpression.
    1638               21:     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
    1639               21:     ConsumeToken();
    1640               21:     return ParseStructDeclaration(DS, Fields);
    1641                 :   }
    1642                 : 
    1643                 :   // Parse the common specifier-qualifiers-list piece.
    1644             3582:   SourceLocation DSStart = Tok.getLocation();
    1645             3582:   ParseSpecifierQualifierList(DS);
    1646                 : 
    1647                 :   // If there are no declarators, this is a free-standing declaration
    1648                 :   // specifier. Let the actions module cope with it.
                       24: branch 1 taken
                     3558: branch 2 taken
    1649             3582:   if (Tok.is(tok::semi)) {
    1650               24:     Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
    1651               24:     return;
    1652                 :   }
    1653                 : 
    1654                 :   // Read struct-declarators until we find the semicolon.
    1655             3558:   bool FirstDeclarator = true;
                      180: branch 1 taken
                     3558: branch 2 taken
                      180: branch 4 taken
                     3558: branch 5 taken
    1656             3738:   while (1) {
    1657             3738:     ParsingDeclRAIIObject PD(*this);
    1658             3738:     FieldDeclarator DeclaratorInfo(DS);
    1659                 : 
    1660                 :     // Attributes are only allowed here on successive declarators.
                      180: branch 0 taken
                     3558: branch 1 taken
                        0: branch 3 not taken
                      180: branch 4 taken
                        0: branch 5 not taken
                     3738: branch 6 taken
    1661             3738:     if (!FirstDeclarator && Tok.is(tok::kw___attribute)) {
    1662                0:       SourceLocation Loc;
    1663                0:       AttributeList *AttrList = ParseGNUAttributes(&Loc);
    1664                0:       DeclaratorInfo.D.AddAttributes(AttrList, Loc);
    1665                 :     }
    1666                 : 
    1667                 :     /// struct-declarator: declarator
    1668                 :     /// struct-declarator: declarator[opt] ':' constant-expression
                     3695: branch 1 taken
                       43: branch 2 taken
    1669             3738:     if (Tok.isNot(tok::colon)) {
    1670                 :       // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
    1671             3695:       ColonProtectionRAIIObject X(*this);
    1672             3695:       ParseDeclarator(DeclaratorInfo.D);
    1673                 :     }
    1674                 : 
                      269: branch 1 taken
                     3469: branch 2 taken
    1675             3738:     if (Tok.is(tok::colon)) {
    1676              269:       ConsumeToken();
    1677              269:       OwningExprResult Res(ParseConstantExpression());
                        0: branch 1 not taken
                      269: branch 2 taken
    1678              269:       if (Res.isInvalid())
    1679                0:         SkipUntil(tok::semi, true, true);
    1680                 :       else
    1681              269:         DeclaratorInfo.BitfieldSize = Res.release();
    1682                 :     }
    1683                 : 
    1684                 :     // If attributes exist after the declarator, parse them.
                       25: branch 1 taken
                     3713: branch 2 taken
    1685             3738:     if (Tok.is(tok::kw___attribute)) {
    1686               25:       SourceLocation Loc;
    1687               25:       AttributeList *AttrList = ParseGNUAttributes(&Loc);
    1688               25:       DeclaratorInfo.D.AddAttributes(AttrList, Loc);
    1689                 :     }
    1690                 : 
    1691                 :     // We're done with this declarator;  invoke the callback.
    1692             3738:     DeclPtrTy D = Fields.invoke(DeclaratorInfo);
    1693             3738:     PD.complete(D);
    1694                 : 
    1695                 :     // If we don't have a comma, it is either the end of the list (a ';')
    1696                 :     // or an error, bail out.
                     3558: branch 1 taken
                      180: branch 2 taken
    1697             3738:     if (Tok.isNot(tok::comma))
    1698             3558:       return;
    1699                 : 
    1700                 :     // Consume the comma.
    1701              180:     ConsumeToken();
    1702                 : 
    1703              180:     FirstDeclarator = false;
    1704                 :   }
    1705                 : }
    1706                 : 
    1707                 : /// ParseStructUnionBody
    1708                 : ///       struct-contents:
    1709                 : ///         struct-declaration-list
    1710                 : /// [EXT]   empty
    1711                 : /// [GNU]   "struct-declaration-list" without terminatoring ';'
    1712                 : ///       struct-declaration-list:
    1713                 : ///         struct-declaration
    1714                 : ///         struct-declaration-list struct-declaration
    1715                 : /// [OBC]   '@' 'defs' '(' class-name ')'
    1716                 : ///
    1717                 : void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
    1718             1416:                                   unsigned TagType, DeclPtrTy TagDecl) {
    1719                 :   PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
    1720                 :                                         PP.getSourceManager(),
    1721             1416:                                         "parsing struct/union body");
    1722                 : 
    1723             1416:   SourceLocation LBraceLoc = ConsumeBrace();
    1724                 : 
    1725             1416:   ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
    1726             1416:   Actions.ActOnTagStartDefinition(CurScope, TagDecl);
    1727                 : 
    1728                 :   // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
    1729                 :   // C++.
                      174: branch 1 taken
                     1242: branch 2 taken
                      174: branch 4 taken
                        0: branch 5 not taken
                      174: branch 6 taken
                     1242: branch 7 taken
    1730             1416:   if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
    1731                 :     Diag(Tok, diag::ext_empty_struct_union_enum)
    1732              174:       << DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
    1733                 : 
    1734             1416:   llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
    1735                 : 
    1736                 :   // While we still have something to read, read the declarations in the struct.
                     2404: branch 1 taken
                        0: branch 2 not taken
                        6: branch 3 taken
                     2412: branch 5 taken
                     1410: branch 6 taken
                     2412: branch 8 taken
                        0: branch 9 not taken
                     2412: branch 10 taken
                     1410: branch 11 taken
    1737             3826:   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
    1738                 :     // Each iteration of this loop reads one struct-declaration.
    1739                 : 
    1740                 :     // Check for extraneous top-level semicolon.
                        2: branch 1 taken
                     2410: branch 2 taken
    1741             2412:     if (Tok.is(tok::semi)) {
    1742                 :       Diag(Tok, diag::ext_extra_struct_semi)
    1743                2:         << CodeModificationHint::CreateRemoval(Tok.getLocation());
    1744                2:       ConsumeToken();
    1745                2:       continue;
    1746                 :     }
    1747                 : 
    1748                 :     // Parse all the comma separated declarators.
    1749             2410:     DeclSpec DS;
    1750                 : 
                     2400: branch 1 taken
                       10: branch 2 taken
    1751             2410:     if (!Tok.is(tok::at)) {
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                     2400: branch 6 taken
                        0: branch 9 not taken
                        0: branch 10 not taken
    1752             2400:       struct CFieldCallback : FieldCallback {
    1753                 :         Parser &P;
    1754                 :         DeclPtrTy TagDecl;
    1755                 :         llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls;
    1756                 : 
    1757                 :         CFieldCallback(Parser &P, DeclPtrTy TagDecl,
    1758             2400:                        llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls) :
    1759             2400:           P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
    1760                 : 
    1761             2546:         virtual DeclPtrTy invoke(FieldDeclarator &FD) {
    1762                 :           // Install the declarator into the current TagDecl.
    1763                 :           DeclPtrTy Field = P.Actions.ActOnField(P.CurScope, TagDecl,
    1764                 :                               FD.D.getDeclSpec().getSourceRange().getBegin(),
    1765             2546:                                                  FD.D, FD.BitfieldSize);
    1766             2546:           FieldDecls.push_back(Field);
    1767                 :           return Field;
    1768                 :         }
    1769             2400:       } Callback(*this, TagDecl, FieldDecls);
    1770                 : 
    1771             2400:       ParseStructDeclaration(DS, Callback);
    1772                 :     } else { // Handle @defs
    1773               10:       ConsumeToken();
                        0: branch 1 not taken
                       10: branch 2 taken
    1774               10:       if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
    1775                0:         Diag(Tok, diag::err_unexpected_at);
    1776                0:         SkipUntil(tok::semi, true);
    1777                0:         continue;
    1778                 :       }
    1779               10:       ConsumeToken();
    1780               10:       ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
                        0: branch 1 not taken
                       10: branch 2 taken
    1781               10:       if (!Tok.is(tok::identifier)) {
    1782                0:         Diag(Tok, diag::err_expected_ident);
    1783                0:         SkipUntil(tok::semi, true);
    1784                 :         continue;
    1785                 :       }
    1786               10:       llvm::SmallVector<DeclPtrTy, 16> Fields;
    1787                 :       Actions.ActOnDefs(CurScope, TagDecl, Tok.getLocation(),
    1788               10:                         Tok.getIdentifierInfo(), Fields);
    1789               10:       FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
    1790               10:       ConsumeToken();
    1791               10:       ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
    1792                 :     }
    1793                 : 
                     2403: branch 1 taken
                        7: branch 2 taken
    1794             2410:     if (Tok.is(tok::semi)) {
    1795             2403:       ConsumeToken();
                        6: branch 1 taken
                        1: branch 2 taken
    1796                7:     } else if (Tok.is(tok::r_brace)) {
    1797                6:       ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
    1798                6:       break;
    1799                 :     } else {
    1800                1:       ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
    1801                 :       // Skip to end of block or statement to avoid ext-warning on extra ';'.
    1802                1:       SkipUntil(tok::r_brace, true, true);
    1803                 :       // If we stopped at a ';', eat it.
                        1: branch 1 taken
                        0: branch 2 not taken
    1804                1:       if (Tok.is(tok::semi)) ConsumeToken();
    1805                 :     }
    1806                 :   }
    1807                 : 
    1808             1416:   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
    1809                 : 
    1810             1416:   AttributeList *AttrList = 0;
    1811                 :   // If attributes exist after struct contents, parse them.
                       11: branch 1 taken
                     1405: branch 2 taken
    1812             1416:   if (Tok.is(tok::kw___attribute))
    1813               11:     AttrList = ParseGNUAttributes();
    1814                 : 
    1815                 :   Actions.ActOnFields(CurScope,
    1816                 :                       RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
    1817                 :                       LBraceLoc, RBraceLoc,
    1818             1416:                       AttrList);
    1819             1416:   StructScope.Exit();
    1820             1416:   Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
    1821             1416: }
    1822                 : 
    1823                 : 
    1824                 : /// ParseEnumSpecifier
    1825                 : ///       enum-specifier: [C99 6.7.2.2]
    1826                 : ///         'enum' identifier[opt] '{' enumerator-list '}'
    1827                 : ///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
    1828                 : /// [GNU]   'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
    1829                 : ///                                                 '}' attributes[opt]
    1830                 : ///         'enum' identifier
    1831                 : /// [GNU]   'enum' attributes[opt] identifier
    1832                 : ///
    1833                 : /// [C++] elaborated-type-specifier:
    1834                 : /// [C++]   'enum' '::'[opt] nested-name-specifier[opt] identifier
    1835                 : ///
    1836                 : void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
    1837              381:                                 AccessSpecifier AS) {
    1838                 :   // Parse the tag portion of this.
                        1: branch 1 taken
                      380: branch 2 taken
    1839              381:   if (Tok.is(tok::code_completion)) {
    1840                 :     // Code completion for an enum name.
    1841                1:     Actions.CodeCompleteTag(CurScope, DeclSpec::TST_enum);
    1842                1:     ConsumeToken();
    1843                 :   }
    1844                 :   
    1845              381:   AttributeList *Attr = 0;
    1846                 :   // If attributes exist after tag, parse them.
                        0: branch 1 not taken
                      381: branch 2 taken
    1847              381:   if (Tok.is(tok::kw___attribute))
    1848                0:     Attr = ParseGNUAttributes();
    1849                 : 
    1850              381:   CXXScopeSpec SS;
                      135: branch 1 taken
                      246: branch 2 taken
                        5: branch 4 taken
                      130: branch 5 taken
                        5: branch 6 taken
                      376: branch 7 taken
    1851              381:   if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS, 0, false)) {
                        0: branch 1 not taken
                        5: branch 2 taken
    1852                5:     if (Tok.isNot(tok::identifier)) {
    1853                0:       Diag(Tok, diag::err_expected_ident);
                        0: branch 1 not taken
                        0: branch 2 not taken
    1854                0:       if (Tok.isNot(tok::l_brace)) {
    1855                 :         // Has no name and is not a definition.
    1856                 :         // Skip the rest of this declarator, up until the comma or semicolon.
    1857                0:         SkipUntil(tok::comma, true);
    1858                0:         return;
    1859                 :       }
    1860                 :     }
    1861                 :   }
    1862                 : 
    1863                 :   // Must have either 'enum name' or 'enum {...}'.
                      165: branch 1 taken
                      216: branch 2 taken
                        1: branch 4 taken
                      164: branch 5 taken
                        1: branch 6 taken
                      380: branch 7 taken
    1864              381:   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace)) {
    1865                1:     Diag(Tok, diag::err_expected_ident_lbrace);
    1866                 : 
    1867                 :     // Skip the rest of this declarator, up until the comma or semicolon.
    1868                1:     SkipUntil(tok::comma, true);
    1869                1:     return;
    1870                 :   }
    1871                 : 
    1872                 :   // If an identifier is present, consume and remember it.
    1873              380:   IdentifierInfo *Name = 0;
    1874              380:   SourceLocation NameLoc;
                      216: branch 1 taken
                      164: branch 2 taken
    1875              380:   if (Tok.is(tok::identifier)) {
    1876              216:     Name = Tok.getIdentifierInfo();
    1877              216:     NameLoc = ConsumeToken();
    1878                 :   }
    1879                 : 
    1880                 :   // There are three options here.  If we have 'enum foo;', then this is a
    1881                 :   // forward declaration.  If we have 'enum foo {...' then this is a
    1882                 :   // definition. Otherwise we have something like 'enum foo xyz', a reference.
    1883                 :   //
    1884                 :   // This is needed to handle stuff like this right (C99 6.7.2.3p11):
    1885                 :   // enum foo {..};  void bar() { enum foo; }    <- new foo in bar.
    1886                 :   // enum foo {..};  void bar() { enum foo x; }  <- use of old foo.
    1887                 :   //
    1888                 :   Action::TagUseKind TUK;
                      319: branch 1 taken
                       61: branch 2 taken
    1889              380:   if (Tok.is(tok::l_brace))
    1890              319:     TUK = Action::TUK_Definition;
                        6: branch 1 taken
                       55: branch 2 taken
    1891               61:   else if (Tok.is(tok::semi))
    1892                6:     TUK = Action::TUK_Declaration;
    1893                 :   else
    1894               55:     TUK = Action::TUK_Reference;
    1895              380:   bool Owned = false;
    1896              380:   bool IsDependent = false;
    1897                 :   DeclPtrTy TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TUK,
    1898                 :                                        StartLoc, SS, Name, NameLoc, Attr, AS,
    1899                 :                                        Action::MultiTemplateParamsArg(Actions),
    1900              380:                                        Owned, IsDependent);
                        0: branch 0 not taken
                      380: branch 1 taken
    1901              380:   assert(!IsDependent && "didn't expect dependent enum");
    1902                 : 
                      319: branch 1 taken
                       61: branch 2 taken
    1903              380:   if (Tok.is(tok::l_brace))
    1904              319:     ParseEnumBody(StartLoc, TagDecl);
    1905                 : 
    1906                 :   // FIXME: The DeclSpec should keep the locations of both the keyword and the
    1907                 :   // name (if there is one).
                      216: branch 1 taken
                      164: branch 2 taken
    1908              380:   SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc;
    1909              380:   const char *PrevSpec = 0;
    1910                 :   unsigned DiagID;
                        0: branch 2 not taken
                      380: branch 3 taken
    1911              380:   if (DS.SetTypeSpecType(DeclSpec::TST_enum, TSTLoc, PrevSpec, DiagID,
    1912                 :                          TagDecl.getAs<void>(), Owned))
    1913                0:     Diag(StartLoc, DiagID) << PrevSpec;
    1914                 : }
    1915                 : 
    1916                 : /// ParseEnumBody - Parse a {} enclosed enumerator-list.
    1917                 : ///       enumerator-list:
    1918                 : ///         enumerator
    1919                 : ///         enumerator-list ',' enumerator
    1920                 : ///       enumerator:
    1921                 : ///         enumeration-constant
    1922                 : ///         enumeration-constant '=' constant-expression
    1923                 : ///       enumeration-constant:
    1924                 : ///         identifier
    1925                 : ///
    1926              319: void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) {
    1927                 :   // Enter the scope of the enum body and start the definition.
    1928              319:   ParseScope EnumScope(this, Scope::DeclScope);
    1929              319:   Actions.ActOnTagStartDefinition(CurScope, EnumDecl);
    1930                 : 
    1931              319:   SourceLocation LBraceLoc = ConsumeBrace();
    1932                 : 
    1933                 :   // C does not allow an empty enumerator-list, C++ does [dcl.enum].
                       11: branch 1 taken
                      308: branch 2 taken
                        3: branch 4 taken
                        8: branch 5 taken
                        3: branch 6 taken
                      316: branch 7 taken
    1934              319:   if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
    1935                3:     Diag(Tok, diag::ext_empty_struct_union_enum) << "enum";
    1936                 : 
    1937              319:   llvm::SmallVector<DeclPtrTy, 32> EnumConstantDecls;
    1938                 : 
    1939              319:   DeclPtrTy LastEnumConstDecl;
    1940                 : 
    1941                 :   // Parse the enumerator-list.
                      939: branch 1 taken
                      295: branch 2 taken
                     1234: branch 4 taken
                       24: branch 5 taken
    1942             1553:   while (Tok.is(tok::identifier)) {
    1943             1234:     IdentifierInfo *Ident = Tok.getIdentifierInfo();
    1944             1234:     SourceLocation IdentLoc = ConsumeToken();
    1945                 : 
    1946             1234:     SourceLocation EqualLoc;
    1947             1234:     OwningExprResult AssignedVal(Actions);
                      948: branch 1 taken
                      286: branch 2 taken
    1948             1234:     if (Tok.is(tok::equal)) {
    1949              948:       EqualLoc = ConsumeToken();
    1950              948:       AssignedVal = ParseConstantExpression();
                        2: branch 1 taken
                      946: branch 2 taken
    1951              948:       if (AssignedVal.isInvalid())
    1952                2:         SkipUntil(tok::comma, tok::r_brace, true, true);
    1953                 :     }
    1954                 : 
    1955                 :     // Install the enumerator constant into EnumDecl.
    1956                 :     DeclPtrTy EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
    1957                 :                                                         LastEnumConstDecl,
    1958                 :                                                         IdentLoc, Ident,
    1959                 :                                                         EqualLoc,
    1960             1234:                                                         AssignedVal.release());
    1961             1234:     EnumConstantDecls.push_back(EnumConstDecl);
    1962             1234:     LastEnumConstDecl = EnumConstDecl;
    1963                 : 
                      295: branch 1 taken
                      939: branch 2 taken
    1964             1234:     if (Tok.isNot(tok::comma))
    1965              295:       break;
    1966              939:     SourceLocation CommaLoc = ConsumeToken();
    1967                 : 
                       13: branch 1 taken
                      926: branch 2 taken
                        2: branch 4 taken
                       11: branch 5 taken
                        2: branch 7 taken
                        0: branch 8 not taken
                        2: branch 9 taken
                      937: branch 10 taken
    1968              939:     if (Tok.isNot(tok::identifier) &&
    1969                 :         !(getLang().C99 || getLang().CPlusPlus0x))
    1970                 :       Diag(CommaLoc, diag::ext_enumerator_list_comma)
    1971                 :         << getLang().CPlusPlus
    1972                2:         << CodeModificationHint::CreateRemoval(CommaLoc);
    1973                 :   }
    1974                 : 
    1975                 :   // Eat the }.
    1976              319:   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
    1977                 : 
    1978              319:   AttributeList *Attr = 0;
    1979                 :   // If attributes exist after the identifier list, parse them.
                        4: branch 1 taken
                      315: branch 2 taken
    1980              319:   if (Tok.is(tok::kw___attribute))
    1981                4:     Attr = ParseGNUAttributes(); // FIXME: where do they do?
    1982                 : 
    1983                 :   Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
    1984                 :                         EnumConstantDecls.data(), EnumConstantDecls.size(),
    1985              319:                         CurScope, Attr);
    1986                 : 
    1987              319:   EnumScope.Exit();
    1988              319:   Actions.ActOnTagFinishDefinition(CurScope, EnumDecl, RBraceLoc);
    1989              319: }
    1990                 : 
    1991                 : /// isTypeSpecifierQualifier - Return true if the current token could be the
    1992                 : /// start of a type-qualifier-list.
    1993                5: bool Parser::isTypeQualifier() const {
                        5: branch 1 taken
                        0: branch 2 not taken
    1994                5:   switch (Tok.getKind()) {
    1995                5:   default: return false;
    1996                 :     // type-qualifier
    1997                 :   case tok::kw_const:
    1998                 :   case tok::kw_volatile:
    1999                 :   case tok::kw_restrict:
    2000                0:     return true;
    2001                 :   }
    2002                 : }
    2003                 : 
    2004                 : /// isTypeSpecifierQualifier - Return true if the current token could be the
    2005                 : /// start of a specifier-qualifier-list.
    2006            15283: bool Parser::isTypeSpecifierQualifier() {
                     1875: branch 1 taken
                     5011: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                     8395: branch 5 taken
                        2: branch 6 taken
                        0: branch 7 not taken
    2007            15283:   switch (Tok.getKind()) {
    2008             1875:   default: return false;
    2009                 : 
    2010                 :   case tok::identifier:   // foo::bar
                        2: branch 1 taken
                     5009: branch 2 taken
    2011             5011:     if (TryAltiVecVectorToken())
    2012                2:       return true;
    2013                 :     // Fall through.
    2014                 :   case tok::kw_typename:  // typename T::type
    2015                 :     // Annotate typenames and C++ scope specifiers.  If we get one, just
    2016                 :     // recurse to handle whatever we get.
                     4196: branch 1 taken
                      813: branch 2 taken
    2017             5009:     if (TryAnnotateTypeOrScopeToken())
    2018             4196:       return isTypeSpecifierQualifier();
    2019                 :     // Otherwise, not a type specifier.
    2020              813:     return false;
    2021                 : 
    2022                 :   case tok::coloncolon:   // ::foo::bar
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
    2023                0:     if (NextToken().is(tok::kw_new) ||    // ::new
    2024                 :         NextToken().is(tok::kw_delete))   // ::delete
    2025                0:       return false;
    2026                 : 
    2027                 :     // Annotate typenames and C++ scope specifiers.  If we get one, just
    2028                 :     // recurse to handle whatever we get.
                        0: branch 1 not taken
                        0: branch 2 not taken
    2029                0:     if (TryAnnotateTypeOrScopeToken())
    2030                0:       return isTypeSpecifierQualifier();
    2031                 :     // Otherwise, not a type specifier.
    2032                0:     return false;
    2033                 : 
    2034                 :     // GNU attributes support.
    2035                 :   case tok::kw___attribute:
    2036                 :     // GNU typeof support.
    2037                 :   case tok::kw_typeof:
    2038                 : 
    2039                 :     // type-specifiers
    2040                 :   case tok::kw_short:
    2041                 :   case tok::kw_long:
    2042                 :   case tok::kw_signed:
    2043                 :   case tok::kw_unsigned:
    2044                 :   case tok::kw__Complex:
    2045                 :   case tok::kw__Imaginary:
    2046                 :   case tok::kw_void:
    2047                 :   case tok::kw_char:
    2048                 :   case tok::kw_wchar_t:
    2049                 :   case tok::kw_char16_t:
    2050                 :   case tok::kw_char32_t:
    2051                 :   case tok::kw_int:
    2052                 :   case tok::kw_float:
    2053                 :   case tok::kw_double:
    2054                 :   case tok::kw_bool:
    2055                 :   case tok::kw__Bool:
    2056                 :   case tok::kw__Decimal32:
    2057                 :   case tok::kw__Decimal64:
    2058                 :   case tok::kw__Decimal128:
    2059                 :   case tok::kw___vector:
    2060                 : 
    2061                 :     // struct-or-union-specifier (C99) or class-specifier (C++)
    2062                 :   case tok::kw_class:
    2063                 :   case tok::kw_struct:
    2064                 :   case tok::kw_union:
    2065                 :     // enum-specifier
    2066                 :   case tok::kw_enum:
    2067                 : 
    2068                 :     // type-qualifier
    2069                 :   case tok::kw_const:
    2070                 :   case tok::kw_volatile:
    2071                 :   case tok::kw_restrict:
    2072                 : 
    2073                 :     // typedef-name
    2074                 :   case tok::annot_typename:
    2075             8395:     return true;
    2076                 : 
    2077                 :     // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
    2078                 :   case tok::less:
    2079                2:     return getLang().ObjC1;
    2080                 : 
    2081                 :   case tok::kw___cdecl:
    2082                 :   case tok::kw___stdcall:
    2083                 :   case tok::kw___fastcall:
    2084                 :   case tok::kw___w64:
    2085                 :   case tok::kw___ptr64:
    2086                0:     return true;
    2087                 :   }
    2088                 : }
    2089                 : 
    2090                 : /// isDeclarationSpecifier() - Return true if the current token is part of a
    2091                 : /// declaration specifier.
    2092            18264: bool Parser::isDeclarationSpecifier() {
                     7239: branch 1 taken
                     5422: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                     5602: branch 5 taken
                        1: branch 6 taken
                        0: branch 7 not taken
    2093            18264:   switch (Tok.getKind()) {
    2094             7239:   default: return false;
    2095                 : 
    2096                 :   case tok::identifier:   // foo::bar
    2097                 :     // Unfortunate hack to support "Class.factoryMethod" notation.
                     2536: branch 1 taken
                     2886: branch 2 taken
                      189: branch 5 taken
                     2347: branch 6 taken
                      189: branch 7 taken
                     5233: branch 8 taken
    2098             5422:     if (getLang().ObjC1 && NextToken().is(tok::period))
    2099              189:       return false;
                        0: branch 1 not taken
                     5233: branch 2 taken
    2100             5233:     if (TryAltiVecVectorToken())
    2101                0:       return true;
    2102                 :     // Fall through.
    2103                 : 
    2104                 :   case tok::kw_typename: // typename T::type
    2105                 :     // Annotate typenames and C++ scope specifiers.  If we get one, just
    2106                 :     // recurse to handle whatever we get.
                     1484: branch 1 taken
                     3749: branch 2 taken
    2107             5233:     if (TryAnnotateTypeOrScopeToken())
    2108             1484:       return isDeclarationSpecifier();
    2109                 :     // Otherwise, not a declaration specifier.
    2110             3749:     return false;
    2111                 :   case tok::coloncolon:   // ::foo::bar
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
    2112                0:     if (NextToken().is(tok::kw_new) ||    // ::new
    2113                 :         NextToken().is(tok::kw_delete))   // ::delete
    2114                0:       return false;
    2115                 : 
    2116                 :     // Annotate typenames and C++ scope specifiers.  If we get one, just
    2117                 :     // recurse to handle whatever we get.
                        0: branch 1 not taken
                        0: branch 2 not taken
    2118                0:     if (TryAnnotateTypeOrScopeToken())
    2119                0:       return isDeclarationSpecifier();
    2120                 :     // Otherwise, not a declaration specifier.
    2121                0:     return false;
    2122                 : 
    2123                 :     // storage-class-specifier
    2124                 :   case tok::kw_typedef:
    2125                 :   case tok::kw_extern:
    2126                 :   case tok::kw___private_extern__:
    2127                 :   case tok::kw_static:
    2128                 :   case tok::kw_auto:
    2129                 :   case tok::kw_register:
    2130                 :   case tok::kw___thread:
    2131                 : 
    2132                 :     // type-specifiers
    2133                 :   case tok::kw_short:
    2134                 :   case tok::kw_long:
    2135                 :   case tok::kw_signed:
    2136                 :   case tok::kw_unsigned:
    2137                 :   case tok::kw__Complex:
    2138                 :   case tok::kw__Imaginary:
    2139                 :   case tok::kw_void:
    2140                 :   case tok::kw_char:
    2141                 :   case tok::kw_wchar_t:
    2142                 :   case tok::kw_char16_t:
    2143                 :   case tok::kw_char32_t:
    2144                 : 
    2145                 :   case tok::kw_int:
    2146                 :   case tok::kw_float:
    2147                 :   case tok::kw_double:
    2148                 :   case tok::kw_bool:
    2149                 :   case tok::kw__Bool:
    2150                 :   case tok::kw__Decimal32:
    2151                 :   case tok::kw__Decimal64:
    2152                 :   case tok::kw__Decimal128:
    2153                 :   case tok::kw___vector:
    2154                 : 
    2155                 :     // struct-or-union-specifier (C99) or class-specifier (C++)
    2156                 :   case tok::kw_class:
    2157                 :   case tok::kw_struct:
    2158                 :   case tok::kw_union:
    2159                 :     // enum-specifier
    2160                 :   case tok::kw_enum:
    2161                 : 
    2162                 :     // type-qualifier
    2163                 :   case tok::kw_const:
    2164                 :   case tok::kw_volatile:
    2165                 :   case tok::kw_restrict:
    2166                 : 
    2167                 :     // function-specifier
    2168                 :   case tok::kw_inline:
    2169                 :   case tok::kw_virtual:
    2170                 :   case tok::kw_explicit:
    2171                 : 
    2172                 :     // typedef-name
    2173                 :   case tok::annot_typename:
    2174                 : 
    2175                 :     // GNU typeof support.
    2176                 :   case tok::kw_typeof:
    2177                 : 
    2178                 :     // GNU attributes.
    2179                 :   case tok::kw___attribute:
    2180             5602:     return true;
    2181                 : 
    2182                 :     // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
    2183                 :   case tok::less:
    2184                1:     return getLang().ObjC1;
    2185                 : 
    2186                 :   case tok::kw___declspec:
    2187                 :   case tok::kw___cdecl:
    2188                 :   case tok::kw___stdcall:
    2189                 :   case tok::kw___fastcall:
    2190                 :   case tok::kw___w64:
    2191                 :   case tok::kw___ptr64:
    2192                 :   case tok::kw___forceinline:
    2193                0:     return true;
    2194                 :   }
    2195                 : }
    2196                 : 
    2197              799: bool Parser::isConstructorDeclarator() {
    2198              799:   TentativeParsingAction TPA(*this);
    2199                 : 
    2200                 :   // Parse the C++ scope specifier.
    2201              799:   CXXScopeSpec SS;
    2202              799:   ParseOptionalCXXScopeSpecifier(SS, 0, true);
    2203                 : 
    2204                 :   // Parse the constructor name.
                       19: branch 1 taken
                      780: branch 2 taken
                       19: branch 4 taken
                        0: branch 5 not taken
                      799: branch 6 taken
                        0: branch 7 not taken
    2205              799:   if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
    2206                 :     // We already know that we have a constructor name; just consume
    2207                 :     // the token.
    2208              799:     ConsumeToken();
    2209                 :   } else {
    2210                0:     TPA.Revert();
    2211                0:     return false;
    2212                 :   }
    2213                 : 
    2214                 :   // Current class name must be followed by a left parentheses.
                      145: branch 1 taken
                      654: branch 2 taken
    2215              799:   if (Tok.isNot(tok::l_paren)) {
    2216              145:     TPA.Revert();
    2217              145:     return false;
    2218                 :   }
    2219              654:   ConsumeParen();
    2220                 : 
    2221                 :   // A right parentheses or ellipsis signals that we have a constructor.
                      325: branch 1 taken
                      329: branch 2 taken
                        1: branch 4 taken
                      324: branch 5 taken
                      330: branch 6 taken
                      324: branch 7 taken
    2222              654:   if (Tok.is(tok::r_paren) || Tok.is(tok::ellipsis)) {
    2223              330:     TPA.Revert();
    2224              330:     return true;
    2225                 :   }
    2226                 : 
    2227                 :   // If we need to, enter the specified scope.
    2228              324:   DeclaratorScopeObj DeclScopeObj(*this, SS);
                       21: branch 1 taken
                      303: branch 2 taken
                       21: branch 4 taken
                        0: branch 5 not taken
                       21: branch 6 taken
                      303: branch 7 taken
    2229              324:   if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(CurScope, SS))
    2230               21:     DeclScopeObj.EnterDeclaratorScope();
    2231                 : 
    2232                 :   // Check whether the next token(s) are part of a declaration
    2233                 :   // specifier, in which case we have the start of a parameter and,
    2234                 :   // therefore, we know that this is a constructor.
    2235              324:   bool IsConstructor = isDeclarationSpecifier();
    2236              324:   TPA.Revert();
    2237              324:   return IsConstructor;
    2238                 : }
    2239                 : 
    2240                 : /// ParseTypeQualifierListOpt
    2241                 : ///       type-qualifier-list: [C99 6.7.5]
    2242                 : ///         type-qualifier
    2243                 : /// [GNU]   attributes                        [ only if AttributesAllowed=true ]
    2244                 : ///         type-qualifier-list type-qualifier
    2245                 : /// [GNU]   type-qualifier-list attributes    [ only if AttributesAllowed=true ]
    2246                 : /// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
    2247                 : ///           if CXX0XAttributesAllowed = true
    2248                 : ///
    2249                 : void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed,
    2250            24649:                                        bool CXX0XAttributesAllowed) {
                     1612: branch 1 taken
                    23037: branch 2 taken
                        3: branch 4 taken
                     1609: branch 5 taken
                        3: branch 6 taken
                    24646: branch 7 taken
    2251            24649:   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
    2252                3:     SourceLocation Loc = Tok.getLocation();
    2253                3:     CXX0XAttributeList Attr = ParseCXX0XAttributes();
                        2: branch 0 taken
                        1: branch 1 taken
    2254                3:     if (CXX0XAttributesAllowed)
    2255                2:       DS.AddAttributes(Attr.AttrList);
    2256                 :     else
    2257                1:       Diag(Loc, diag::err_attributes_not_allowed);
    2258                 :   }
    2259                 :   
    2260             1033:   while (1) {
    2261            25682:     bool isInvalid = false;
    2262            25682:     const char *PrevSpec = 0;
    2263            25682:     unsigned DiagID = 0;
    2264            25682:     SourceLocation Loc = Tok.getLocation();
    2265                 : 
                      319: branch 1 taken
                       47: branch 2 taken
                      634: branch 3 taken
                        5: branch 4 taken
                       75: branch 5 taken
                    24602: branch 6 taken
    2266            25682:     switch (Tok.getKind()) {
    2267                 :     case tok::kw_const:
    2268                 :       isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec, DiagID,
    2269              319:                                  getLang());
    2270              319:       break;
    2271                 :     case tok::kw_volatile:
    2272                 :       isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
    2273               47:                                  getLang());
    2274               47:       break;
    2275                 :     case tok::kw_restrict:
    2276                 :       isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
    2277              634:                                  getLang());
    2278              634:       break;
    2279                 :     case tok::kw___w64:
    2280                 :     case tok::kw___ptr64:
    2281                 :     case tok::kw___cdecl:
    2282                 :     case tok::kw___stdcall:
    2283                 :     case tok::kw___fastcall:
                        5: branch 0 taken
                        0: branch 1 not taken
    2284                5:       if (GNUAttributesAllowed) {
    2285                5:         DS.AddAttributes(ParseMicrosoftTypeAttributes());
    2286                5:         continue;
    2287                 :       }
    2288                0:       goto DoneWithTypeQuals;
    2289                 :     case tok::kw___attribute:
                       28: branch 0 taken
                       47: branch 1 taken
    2290               75:       if (GNUAttributesAllowed) {
    2291               28:         DS.AddAttributes(ParseGNUAttributes());
    2292               28:         continue; // do *not* consume the next token!
    2293                 :       }
    2294                 :       // otherwise, FALL THROUGH!
    2295                 :     default:
    2296            24649:       DoneWithTypeQuals:
    2297                 :       // If this is not a type-qualifier token, we're done reading type
    2298                 :       // qualifiers.  First verify that DeclSpec's are consistent.
    2299            24649:       DS.Finish(Diags, PP);
    2300                 :       return;
    2301                 :     }
    2302                 : 
    2303                 :     // If the specifier combination wasn't legal, issue a diagnostic.
                        0: branch 0 not taken
                     1000: branch 1 taken
    2304             1000:     if (isInvalid) {
                        0: branch 0 not taken
                        0: branch 1 not taken
    2305                0:       assert(PrevSpec && "Method did not return previous specifier!");
    2306                0:       Diag(Tok, DiagID) << PrevSpec;
    2307                 :     }
    2308             1000:     ConsumeToken();
    2309                 :   }
    2310                 : }
    2311                 : 
    2312                 : 
    2313                 : /// ParseDeclarator - Parse and verify a newly-initialized declarator.
    2314                 : ///
    2315            63892: void Parser::ParseDeclarator(Declarator &D) {
    2316                 :   /// This implements the 'declarator' production in the C grammar, then checks
    2317                 :   /// for well-formedness and issues diagnostics.
    2318            63892:   ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
    2319            63892: }
    2320                 : 
    2321                 : /// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
    2322                 : /// is parsed by the function passed to it. Pass null, and the direct-declarator
    2323                 : /// isn't parsed at all, making this function effectively parse the C++
    2324                 : /// ptr-operator production.
    2325                 : ///
    2326                 : ///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
    2327                 : /// [C]     pointer[opt] direct-declarator
    2328                 : /// [C++]   direct-declarator
    2329                 : /// [C++]   ptr-operator declarator
    2330                 : ///
    2331                 : ///       pointer: [C99 6.7.5]
    2332                 : ///         '*' type-qualifier-list[opt]
    2333                 : ///         '*' type-qualifier-list[opt] pointer
    2334                 : ///
    2335                 : ///       ptr-operator:
    2336                 : ///         '*' cv-qualifier-seq[opt]
    2337                 : ///         '&'
    2338                 : /// [C++0x] '&&'
    2339                 : /// [GNU]   '&' restrict[opt] attributes[opt]
    2340                 : /// [GNU?]  '&&' restrict[opt] attributes[opt]
    2341                 : ///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
    2342                 : void Parser::ParseDeclaratorInternal(Declarator &D,
    2343            82058:                                      DirectDeclParseFunction DirectDeclParser) {
                      808: branch 1 taken
                    81250: branch 2 taken
    2344            82058:   if (Diags.hasAllExtensionsSilenced())
    2345              808:     D.setExtension();
    2346                 :   // C++ member pointers start with a '::' or a nested-name.
    2347                 :   // Member pointers get special handling, since there's no place for the
    2348                 :   // scope spec in the generic path below.
                    32360: branch 1 taken
                    49698: branch 2 taken
                    32359: branch 4 taken
                        1: branch 5 taken
                    16532: branch 7 taken
                    15827: branch 8 taken
                      657: branch 10 taken
                    15875: branch 11 taken
                    16485: branch 12 taken
                    65573: branch 13 taken
    2349            82058:   if (getLang().CPlusPlus &&
    2350                 :       (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
    2351                 :        Tok.is(tok::annot_cxxscope))) {
    2352            16485:     CXXScopeSpec SS;
                      762: branch 1 taken
                    15723: branch 2 taken
    2353            16485:     if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true)) {
                      470: branch 1 taken
                      292: branch 2 taken
    2354              762:       if (Tok.isNot(tok::star)) {
    2355                 :         // The scope spec really belongs to the direct-declarator.
    2356              470:         D.getCXXScopeSpec() = SS;
                      470: branch 0 taken
                        0: branch 1 not taken
    2357              470:         if (DirectDeclParser)
                        0: branch 0 not taken
                      470: branch 1 taken
    2358              470:           (this->*DirectDeclParser)(D);
    2359              470:         return;
    2360                 :       }
    2361                 : 
    2362              292:       SourceLocation Loc = ConsumeToken();
    2363              292:       D.SetRangeEnd(Loc);
    2364              292:       DeclSpec DS;
    2365              292:       ParseTypeQualifierListOpt(DS);
    2366              292:       D.ExtendWithDeclSpec(DS);
    2367                 : 
    2368                 :       // Recurse to parse whatever is left.
    2369              292:       ParseDeclaratorInternal(D, DirectDeclParser);
    2370                 : 
    2371                 :       // Sema will have to catch (syntactically invalid) pointers into global
    2372                 :       // scope. It has to catch pointers into namespace scope anyway.
    2373                 :       D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
    2374                 :                                                       Loc, DS.TakeAttributes()),
    2375              292:                     /* Don't replace range end. */SourceLocation());
    2376              292:       return;
    2377                 :     }
    2378                 :   }
    2379                 : 
    2380            81296:   tok::TokenKind Kind = Tok.getKind();
    2381                 :   // Not a pointer, C++ reference, or block.
                    66630: branch 0 taken
                    14666: branch 1 taken
                    66394: branch 2 taken
                      236: branch 3 taken
                     1564: branch 4 taken
                    64830: branch 5 taken
                        0: branch 7 not taken
                     1564: branch 8 taken
                       38: branch 9 taken
                    64792: branch 10 taken
                        0: branch 12 not taken
                       38: branch 13 taken
                    64792: branch 14 taken
                    16504: branch 15 taken
    2382            81296:   if (Kind != tok::star && Kind != tok::caret &&
    2383                 :       (Kind != tok::amp || !getLang().CPlusPlus) &&
    2384                 :       // We parse rvalue refs in C++03, because otherwise the errors are scary.
    2385                 :       (Kind != tok::ampamp || !getLang().CPlusPlus)) {
                    64512: branch 0 taken
                      280: branch 1 taken
    2386            64792:     if (DirectDeclParser)
                        0: branch 0 not taken
                    64512: branch 1 taken
    2387            64512:       (this->*DirectDeclParser)(D);
    2388            64792:     return;
    2389                 :   }
    2390                 : 
    2391                 :   // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
    2392                 :   // '&&' -> rvalue reference
    2393            16504:   SourceLocation Loc = ConsumeToken();  // Eat the *, ^, & or &&.
    2394            16504:   D.SetRangeEnd(Loc);
    2395                 : 
                     1838: branch 0 taken
                    14666: branch 1 taken
                      236: branch 2 taken
                     1602: branch 3 taken
    2396            31406:   if (Kind == tok::star || Kind == tok::caret) {
    2397                 :     // Is a pointer.
    2398            14902:     DeclSpec DS;
    2399                 : 
    2400            14902:     ParseTypeQualifierListOpt(DS);
    2401            14902:     D.ExtendWithDeclSpec(DS);
    2402                 : 
    2403                 :     // Recursively parse the declarator.
    2404            14902:     ParseDeclaratorInternal(D, DirectDeclParser);
                    14666: branch 0 taken
                      236: branch 1 taken
    2405            14902:     if (Kind == tok::star)
    2406                 :       // Remember that we parsed a pointer type, and remember the type-quals.
    2407                 :       D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
    2408                 :                                                 DS.TakeAttributes()),
    2409            14666:                     SourceLocation());
    2410                 :     else
    2411                 :       // Remember that we parsed a Block type, and remember the type-quals.
    2412                 :       D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
    2413                 :                                                      Loc, DS.TakeAttributes()),
    2414              236:                     SourceLocation());
    2415                 :   } else {
    2416                 :     // Is a reference
    2417             1602:     DeclSpec DS;
    2418                 : 
    2419                 :     // Complain about rvalue references in C++03, but then go on and build
    2420                 :     // the declarator.
                       38: branch 0 taken
                     1564: branch 1 taken
                        1: branch 3 taken
                       37: branch 4 taken
                        1: branch 5 taken
                     1601: branch 6 taken
    2421             1602:     if (Kind == tok::ampamp && !getLang().CPlusPlus0x)
    2422                1:       Diag(Loc, diag::err_rvalue_reference);
    2423                 : 
    2424                 :     // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
    2425                 :     // cv-qualifiers are introduced through the use of a typedef or of a
    2426                 :     // template type argument, in which case the cv-qualifiers are ignored.
    2427                 :     //
    2428                 :     // [GNU] Retricted references are allowed.
    2429                 :     // [GNU] Attributes on references are allowed.
    2430                 :     // [C++0x] Attributes on references are not allowed.
    2431             1602:     ParseTypeQualifierListOpt(DS, true, false);
    2432             1602:     D.ExtendWithDeclSpec(DS);
    2433                 : 
                        4: branch 1 taken
                     1598: branch 2 taken
    2434             1602:     if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
                        3: branch 1 taken
                        1: branch 2 taken
    2435                4:       if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
    2436                 :         Diag(DS.getConstSpecLoc(),
    2437                3:              diag::err_invalid_reference_qualifier_application) << "const";
                        2: branch 1 taken
                        2: branch 2 taken
    2438                4:       if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
    2439                 :         Diag(DS.getVolatileSpecLoc(),
    2440                2:              diag::err_invalid_reference_qualifier_application) << "volatile";
    2441                 :     }
    2442                 : 
    2443                 :     // Recursively parse the declarator.
    2444             1602:     ParseDeclaratorInternal(D, DirectDeclParser);
    2445                 : 
                      298: branch 1 taken
                     1304: branch 2 taken
    2446             1602:     if (D.getNumTypeObjects() > 0) {
    2447                 :       // C++ [dcl.ref]p4: There shall be no references to references.
    2448              298:       DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
                        3: branch 0 taken
                      295: branch 1 taken
    2449              298:       if (InnerChunk.Kind == DeclaratorChunk::Reference) {
                        2: branch 1 taken
                        1: branch 2 taken
    2450                3:         if (const IdentifierInfo *II = D.getIdentifier())
    2451                 :           Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
    2452                2:            << II;
    2453                 :         else
    2454                 :           Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
    2455                1:             << "type name";
    2456                 : 
    2457                 :         // Once we've complained about the reference-to-reference, we
    2458                 :         // can go ahead and build the (technically ill-formed)
    2459                 :         // declarator: reference collapsing will take care of it.
    2460                 :       }
    2461                 :     }
    2462                 : 
    2463                 :     // Remember that we parsed a reference type. It doesn't have type-quals.
    2464                 :     D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
    2465                 :                                                 DS.TakeAttributes(),
    2466                 :                                                 Kind == tok::amp),
    2467             1602:                   SourceLocation());
    2468                 :   }
    2469                 : }
    2470                 : 
    2471                 : /// ParseDirectDeclarator
    2472                 : ///       direct-declarator: [C99 6.7.5]
    2473                 : /// [C99]   identifier
    2474                 : ///         '(' declarator ')'
    2475                 : /// [GNU]   '(' attributes declarator ')'
    2476                 : /// [C90]   direct-declarator '[' constant-expression[opt] ']'
    2477                 : /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
    2478                 : /// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
    2479                 : /// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
    2480                 : /// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
    2481                 : ///         direct-declarator '(' parameter-type-list ')'
    2482                 : ///         direct-declarator '(' identifier-list[opt] ')'
    2483                 : /// [GNU]   direct-declarator '(' parameter-forward-declarations
    2484                 : ///                    parameter-type-list[opt] ')'
    2485                 : /// [C++]   direct-declarator '(' parameter-declaration-clause ')'
    2486                 : ///                    cv-qualifier-seq[opt] exception-specification[opt]
    2487                 : /// [C++]   declarator-id
    2488                 : ///
    2489                 : ///       declarator-id: [C++ 8]
    2490                 : ///         id-expression
    2491                 : ///         '::'[opt] nested-name-specifier[opt] type-name
    2492                 : ///
    2493                 : ///       id-expression: [C++ 5.1]
    2494                 : ///         unqualified-id
    2495                 : ///         qualified-id
    2496                 : ///
    2497                 : ///       unqualified-id: [C++ 5.1]
    2498                 : ///         identifier
    2499                 : ///         operator-function-id
    2500                 : ///         conversion-function-id
    2501                 : ///          '~' class-name
    2502                 : ///         template-id
    2503                 : ///
    2504            64877: void Parser::ParseDirectDeclarator(Declarator &D) {
    2505            64877:   DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
    2506                 : 
                    24975: branch 1 taken
                    39902: branch 2 taken
                    19640: branch 4 taken
                     5335: branch 5 taken
                    19640: branch 6 taken
                    45237: branch 7 taken
    2507            64877:   if (getLang().CPlusPlus && D.mayHaveIdentifier()) {
    2508                 :     // ParseDeclaratorInternal might already have parsed the scope.
    2509                 :     bool afterCXXScope = D.getCXXScopeSpec().isSet() ||
    2510                 :       ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0,
                    19170: branch 2 taken
                      470: branch 3 taken
                        0: branch 6 not taken
                    19170: branch 7 taken
    2511            19640:                                      true);
                      470: branch 0 taken
                    19170: branch 1 taken
    2512            19640:     if (afterCXXScope) {
                      466: branch 2 taken
                        4: branch 3 taken
    2513              470:       if (Actions.ShouldEnterDeclaratorScope(CurScope, D.getCXXScopeSpec()))
    2514                 :         // Change the declaration context for name lookup, until this function
    2515                 :         // is exited (and the declarator has been parsed).
    2516              466:         DeclScopeObj.EnterDeclaratorScope();
    2517                 :     } 
    2518                 :     
                     3515: branch 1 taken
                    16125: branch 2 taken
                     2959: branch 4 taken
                      556: branch 5 taken
                     2884: branch 7 taken
                       75: branch 8 taken
                      186: branch 10 taken
                     2698: branch 11 taken
                    16942: branch 12 taken
                     2698: branch 13 taken
    2519            19640:     if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
    2520                 :         Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
    2521                 :       // We found something that indicates the start of an unqualified-id.
    2522                 :       // Parse that unqualified-id.
    2523                 :       bool AllowConstructorName
    2524                 :         = ((D.getCXXScopeSpec().isSet() && 
    2525                 :             D.getContext() == Declarator::FileContext) ||
    2526                 :            (!D.getCXXScopeSpec().isSet() &&
    2527                 :             D.getContext() == Declarator::MemberContext)) &&
                      466: branch 2 taken
                    16476: branch 3 taken
                       14: branch 5 taken
                      452: branch 6 taken
                    16476: branch 9 taken
                       14: branch 10 taken
                     4684: branch 12 taken
                    11792: branch 13 taken
                     1095: branch 16 taken
                     4041: branch 17 taken
    2528            16942:         !D.getDeclSpec().hasTypeSpecifier();
                        4: branch 3 taken
                    16938: branch 4 taken
    2529            16942:       if (ParseUnqualifiedId(D.getCXXScopeSpec(), 
    2530                 :                              /*EnteringContext=*/true, 
    2531                 :                              /*AllowDestructorName=*/true, 
    2532                 :                              AllowConstructorName,
    2533                 :                              /*ObjectType=*/0,
    2534                 :                              D.getName())) {
    2535                4:         D.SetIdentifier(0, Tok.getLocation());
    2536                4:         D.setInvalidType(true);
    2537                 :       } else {
    2538                 :         // Parsed the unqualified-id; update range information and move along.
                        0: branch 3 not taken
                    16938: branch 4 taken
    2539            16938:         if (D.getSourceRange().getBegin().isInvalid())
    2540                0:           D.SetRangeBegin(D.getName().getSourceRange().getBegin());
    2541            16938:         D.SetRangeEnd(D.getName().getSourceRange().getEnd());
    2542                 :       }
    2543            16942:       goto PastIdentifier;
    2544                 :     }
                    29212: branch 1 taken
                    16025: branch 2 taken
                    29209: branch 4 taken
                        3: branch 5 taken
                    29209: branch 6 taken
                    16028: branch 7 taken
    2545            45237:   } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
    2546                 :     assert(!getLang().CPlusPlus &&
                    29209: branch 1 taken
                        0: branch 2 not taken
    2547            29209:            "There's a C++-specific check for tok::identifier above");
                    29209: branch 1 taken
                        0: branch 2 not taken
    2548            29209:     assert(Tok.getIdentifierInfo() && "Not an identifier?");
    2549            29209:     D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
    2550            29209:     ConsumeToken();
    2551            29209:     goto PastIdentifier;
    2552                 :   }
    2553                 :     
                     1063: branch 1 taken
                    17663: branch 2 taken
    2554            18726:   if (Tok.is(tok::l_paren)) {
    2555                 :     // direct-declarator: '(' declarator ')'
    2556                 :     // direct-declarator: '(' attributes declarator ')'
    2557                 :     // Example: 'char (*X)'   or 'int (*XX)(void)'
    2558             1063:     ParseParenDeclarator(D);
    2559                 : 
    2560                 :     // If the declarator was parenthesized, we entered the declarator
    2561                 :     // scope when parsing the parenthesized declarator, then exited
    2562                 :     // the scope already. Re-enter the scope, if we need to.
                        9: branch 2 taken
                     1054: branch 3 taken
    2563             1063:     if (D.getCXXScopeSpec().isSet()) {
                        9: branch 2 taken
                        0: branch 3 not taken
    2564                9:       if (Actions.ShouldEnterDeclaratorScope(CurScope, D.getCXXScopeSpec()))
    2565                 :         // Change the declaration context for name lookup, until this function
    2566                 :         // is exited (and the declarator has been parsed).
    2567                9:         DeclScopeObj.EnterDeclaratorScope();
    2568                 :     }
                    17630: branch 1 taken
                       33: branch 2 taken
    2569            17663:   } else if (D.mayOmitIdentifier()) {
    2570                 :     // This could be something simple like "int" (in which case the declarator
    2571                 :     // portion is empty), if an abstract-declarator is allowed.
    2572            17630:     D.SetIdentifier(0, Tok.getLocation());
    2573                 :   } else {
                       10: branch 1 taken
                       23: branch 2 taken
    2574               33:     if (D.getContext() == Declarator::MemberContext)
    2575                 :       Diag(Tok, diag::err_expected_member_name_or_semi)
    2576               10:         << D.getDeclSpec().getSourceRange();
                       13: branch 1 taken
                       10: branch 2 taken
    2577               23:     else if (getLang().CPlusPlus)
    2578               13:       Diag(Tok, diag::err_expected_unqualified_id) << getLang().CPlusPlus;
    2579                 :     else
    2580               10:       Diag(Tok, diag::err_expected_ident_lparen);
    2581               33:     D.SetIdentifier(0, Tok.getLocation());
    2582               33:     D.setInvalidType(true);
    2583                 :   }
    2584                 : 
    2585            64877:  PastIdentifier:
    2586                 :   assert(D.isPastIdentifier() &&
                    64877: branch 1 taken
                        0: branch 2 not taken
    2587            64877:          "Haven't past the location of the identifier yet?");
    2588                 : 
    2589                 :   // Don't parse attributes unless we have an identifier.
                    45460: branch 1 taken
                    19417: branch 2 taken
                    15856: branch 4 taken
                    29604: branch 5 taken
                       13: branch 7 taken
                    15843: branch 8 taken
                       13: branch 9 taken
                    64864: branch 10 taken
    2590           110337:   if (D.getIdentifier() && getLang().CPlusPlus
    2591                 :    && isCXX0XAttributeSpecifier(true)) {
    2592               13:     SourceLocation AttrEndLoc;
    2593               13:     CXX0XAttributeList Attr = ParseCXX0XAttributes();
    2594               13:     D.AddAttributes(Attr.AttrList, AttrEndLoc);
    2595                 :   }
    2596                 : 
    2597            16726:   while (1) {
                    14518: branch 1 taken
                    67085: branch 2 taken
    2598            81603:     if (Tok.is(tok::l_paren)) {
    2599                 :       // The paren may be part of a C++ direct initializer, eg. "int x(1);".
    2600                 :       // In such a case, check if we actually have a function declarator; if it
    2601                 :       // is not, the declarator has been fully parsed.
                     7028: branch 1 taken
                     7490: branch 2 taken
                     4075: branch 4 taken
                     2953: branch 5 taken
                     4075: branch 6 taken
                    10443: branch 7 taken
    2602            14518:       if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
    2603                 :         // When not in file scope, warn for ambiguous function declarators, just
    2604                 :         // in case the author intended it as a variable definition.
    2605             4075:         bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
                     3966: branch 1 taken
                      109: branch 2 taken
    2606             4075:         if (!isCXXFunctionDeclarator(warnIfAmbiguous))
    2607              109:           break;
    2608                 :       }
    2609            14409:       ParseFunctionDeclarator(ConsumeParen(), D);
                    64768: branch 1 taken
                     2317: branch 2 taken
    2610            67085:     } else if (Tok.is(tok::l_square)) {
    2611             2317:       ParseBracketDeclarator(D);
    2612                 :     } else {
    2613            64768:       break;
    2614                 :     }
    2615            64877:   }
    2616            64877: }
    2617                 : 
    2618                 : /// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
    2619                 : /// only called before the identifier, so these are most likely just grouping
    2620                 : /// parens for precedence.  If we find that these are actually function
    2621                 : /// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
    2622                 : ///
    2623                 : ///       direct-declarator:
    2624                 : ///         '(' declarator ')'
    2625                 : /// [GNU]   '(' attributes declarator ')'
    2626                 : ///         direct-declarator '(' parameter-type-list ')'
    2627                 : ///         direct-declarator '(' identifier-list[opt] ')'
    2628                 : /// [GNU]   direct-declarator '(' parameter-forward-declarations
    2629                 : ///                    parameter-type-list[opt] ')'
    2630                 : ///
    2631             1122: void Parser::ParseParenDeclarator(Declarator &D) {
    2632             1122:   SourceLocation StartLoc = ConsumeParen();
                     1122: branch 1 taken
                        0: branch 2 not taken
    2633             1122:   assert(!D.isPastIdentifier() && "Should be called before passing identifier");
    2634                 : 
    2635                 :   // Eat any attributes before we look at whether this is a grouping or function
    2636                 :   // declarator paren.  If this is a grouping paren, the attribute applies to
    2637                 :   // the type being built up, for example:
    2638                 :   //     int (__attribute__(()) *x)(long y)
    2639                 :   // If this ends up not being a grouping paren, the attribute applies to the
    2640                 :   // first argument, for example:
    2641                 :   //     int (__attribute__(()) int x)
    2642                 :   // In either case, we need to eat any attributes to be able to determine what
    2643                 :   // sort of paren this is.
    2644                 :   //
    2645             1122:   AttributeList *AttrList = 0;
    2646             1122:   bool RequiresArg = false;
                       12: branch 1 taken
                     1110: branch 2 taken
    2647             1122:   if (Tok.is(tok::kw___attribute)) {
    2648               12:     AttrList = ParseGNUAttributes();
    2649                 : 
    2650                 :     // We require that the argument list (if this is a non-grouping paren) be
    2651                 :     // present even if the attribute list was empty.
    2652               12:     RequiresArg = true;
    2653                 :   }
    2654                 :   // Eat any Microsoft extensions.
                     1121: branch 1 taken
                        1: branch 2 taken
                     1120: branch 4 taken
                        1: branch 5 taken
                     1120: branch 7 taken
                        0: branch 8 not taken
                     1120: branch 10 taken
                        0: branch 11 not taken
                        0: branch 13 not taken
                     1120: branch 14 taken
                        2: branch 15 taken
                     1120: branch 16 taken
    2655             1122:   if  (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
    2656                 :        Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___w64) ||
    2657                 :        Tok.is(tok::kw___ptr64)) {
    2658                2:     AttrList = ParseMicrosoftTypeAttributes(AttrList);
    2659                 :   }
    2660                 : 
    2661                 :   // If we haven't past the identifier yet (or where the identifier would be
    2662                 :   // stored, if this is an abstract declarator), then this is probably just
    2663                 :   // grouping parens. However, if this could be an abstract-declarator, then
    2664                 :   // this could also be the start of function arguments (consider 'void()').
    2665                 :   bool isGrouping;
    2666                 : 
                      613: branch 1 taken
                      509: branch 2 taken
    2667             1122:   if (!D.mayOmitIdentifier()) {
    2668                 :     // If this can't be an abstract-declarator, this *must* be a grouping
    2669                 :     // paren, because we haven't seen the identifier yet.
    2670              613:     isGrouping = true;
                      490: branch 1 taken
                       19: branch 2 taken
                      265: branch 4 taken
                      225: branch 5 taken
                      264: branch 7 taken
                        1: branch 8 taken
                      117: branch 10 taken
                      372: branch 11 taken
                      137: branch 12 taken
                      372: branch 13 taken
    2671              509:   } else if (Tok.is(tok::r_paren) ||           // 'int()' is a function.
    2672                 :              (getLang().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
    2673                 :              isDeclarationSpecifier()) {       // 'int(int)' is a function.
    2674                 :     // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
    2675                 :     // considered to be a type, not a K&R identifier-list.
    2676              137:     isGrouping = false;
    2677                 :   } else {
    2678                 :     // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
    2679              372:     isGrouping = true;
    2680                 :   }
    2681                 : 
    2682                 :   // If this is a grouping paren, handle:
    2683                 :   // direct-declarator: '(' declarator ')'
    2684                 :   // direct-declarator: '(' attributes declarator ')'
                      985: branch 0 taken
                      137: branch 1 taken
    2685             1122:   if (isGrouping) {
    2686              985:     bool hadGroupingParens = D.hasGroupingParens();
    2687              985:     D.setGroupingParens(true);
                       12: branch 0 taken
                      973: branch 1 taken
    2688              985:     if (AttrList)
    2689               12:       D.AddAttributes(AttrList, SourceLocation());
    2690                 : 
    2691              985:     ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
    2692                 :     // Match the ')'.
    2693              985:     SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, StartLoc);
    2694                 : 
    2695              985:     D.setGroupingParens(hadGroupingParens);
    2696              985:     D.SetRangeEnd(Loc);
    2697              985:     return;
    2698                 :   }
    2699                 : 
    2700                 :   // Okay, if this wasn't a grouping paren, it must be the start of a function
    2701                 :   // argument list.  Recognize that this declarator will never have an
    2702                 :   // identifier (and remember where it would have been), then call into
    2703                 :   // ParseFunctionDeclarator to handle of argument list.
    2704              137:   D.SetIdentifier(0, Tok.getLocation());
    2705                 : 
    2706              137:   ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
    2707                 : }
    2708                 : 
    2709                 : /// ParseFunctionDeclarator - We are after the identifier and have parsed the
    2710                 : /// declarator D up to a paren, which indicates that we are parsing function
    2711                 : /// arguments.
    2712                 : ///
    2713                 : /// If AttrList is non-null, then the caller parsed those arguments immediately
    2714                 : /// after the open paren - they should be considered to be the first argument of
    2715                 : /// a parameter.  If RequiresArg is true, then the first argument of the
    2716                 : /// function is required to be present and required to not be an identifier
    2717                 : /// list.
    2718                 : ///
    2719                 : /// This method also handles this portion of the grammar:
    2720                 : ///       parameter-type-list: [C99 6.7.5]
    2721                 : ///         parameter-list
    2722                 : ///         parameter-list ',' '...'
    2723                 : /// [C++]   parameter-list '...'
    2724                 : ///
    2725                 : ///       parameter-list: [C99 6.7.5]
    2726                 : ///         parameter-declaration
    2727                 : ///         parameter-list ',' parameter-declaration
    2728                 : ///
    2729                 : ///       parameter-declaration: [C99 6.7.5]
    2730                 : ///         declaration-specifiers declarator
    2731                 : /// [C++]   declaration-specifiers declarator '=' assignment-expression
    2732                 : /// [GNU]   declaration-specifiers declarator attributes
    2733                 : ///         declaration-specifiers abstract-declarator[opt]
    2734                 : /// [C++]   declaration-specifiers abstract-declarator[opt]
    2735                 : ///           '=' assignment-expression
    2736                 : /// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
    2737                 : ///
    2738                 : /// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]"
    2739                 : /// and "exception-specification[opt]".
    2740                 : ///
    2741                 : void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
    2742                 :                                      AttributeList *AttrList,
    2743            14546:                                      bool RequiresArg) {
    2744                 :   // lparen is already consumed!
                    14546: branch 1 taken
                        0: branch 2 not taken
    2745            14546:   assert(D.isPastIdentifier() && "Should not call before identifier!");
    2746                 : 
    2747                 :   // This parameter list may be empty.
                     5249: branch 1 taken
                     9297: branch 2 taken
    2748            14546:   if (Tok.is(tok::r_paren)) {
                        0: branch 0 not taken
                     5249: branch 1 taken
    2749             5249:     if (RequiresArg) {
    2750                0:       Diag(Tok, diag::err_argument_required_after_attribute);
                        0: branch 0 not taken
                        0: branch 1 not taken
    2751                0:       delete AttrList;
    2752                 :     }
    2753                 : 
    2754             5249:     SourceLocation RParenLoc = ConsumeParen();  // Eat the closing ')'.
    2755             5249:     SourceLocation EndLoc = RParenLoc;
    2756                 : 
    2757                 :     // cv-qualifier-seq[opt].
    2758             5249:     DeclSpec DS;
    2759             5249:     bool hasExceptionSpec = false;
    2760             5249:     SourceLocation ThrowLoc;
    2761             5249:     bool hasAnyExceptionSpec = false;
    2762             5249:     llvm::SmallVector<TypeTy*, 2> Exceptions;
    2763             5249:     llvm::SmallVector<SourceRange, 2> ExceptionRanges;
                     3208: branch 1 taken
                     2041: branch 2 taken
    2764             5249:     if (getLang().CPlusPlus) {
    2765             3208:       ParseTypeQualifierListOpt(DS, false /*no attributes*/);
                        0: branch 3 not taken
                     3208: branch 4 taken
    2766             3208:       if (!DS.getSourceRange().getEnd().isInvalid())
    2767                0:         EndLoc = DS.getSourceRange().getEnd();
    2768                 : 
    2769                 :       // Parse exception-specification[opt].
                       96: branch 1 taken
                     3112: branch 2 taken
    2770             3208:       if (Tok.is(tok::kw_throw)) {
    2771               96:         hasExceptionSpec = true;
    2772               96:         ThrowLoc = Tok.getLocation();
    2773                 :         ParseExceptionSpecification(EndLoc, Exceptions, ExceptionRanges,
    2774               96:                                     hasAnyExceptionSpec);
    2775                 :         assert(Exceptions.size() == ExceptionRanges.size() &&
                       96: branch 2 taken
                        0: branch 3 not taken
    2776               96:                "Produced different number of exception types and ranges.");
    2777                 :       }
    2778                 :     }
    2779                 : 
    2780                 :     // Remember that we parsed a function type, and remember the attributes.
    2781                 :     // int() -> no prototype, no '...'.
    2782                 :     D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
    2783                 :                                                /*variadic*/ false,
    2784                 :                                                SourceLocation(),
    2785                 :                                                /*arglist*/ 0, 0,
    2786                 :                                                DS.getTypeQualifiers(),
    2787                 :                                                hasExceptionSpec, ThrowLoc,
    2788                 :                                                hasAnyExceptionSpec,
    2789                 :                                                Exceptions.data(),
    2790                 :                                                ExceptionRanges.data(),
    2791                 :                                                Exceptions.size(),
    2792                 :                                                LParenLoc, RParenLoc, D),
    2793             5249:                   EndLoc);
    2794             5249:     return;
    2795                 :   }
    2796                 : 
    2797                 :   // Alternatively, this parameter list may be an identifier list form for a
    2798                 :   // K&R-style function:  void foo(a,b,c)
                     5538: branch 1 taken
                     3759: branch 2 taken
                     1905: branch 4 taken
                     3633: branch 5 taken
                     1904: branch 7 taken
                        1: branch 8 taken
                     1904: branch 9 taken
                     7393: branch 10 taken
    2799             9297:   if (!getLang().CPlusPlus && Tok.is(tok::identifier)
    2800                 :       && !TryAltiVecVectorToken()) {
                       57: branch 1 taken
                     1847: branch 2 taken
    2801             1904:     if (!TryAnnotateTypeOrScopeToken()) {
    2802                 :       // K&R identifier lists can't have typedefs as identifiers, per
    2803                 :       // C99 6.7.5.3p11.
                        0: branch 0 not taken
                       57: branch 1 taken
    2804               57:       if (RequiresArg) {
    2805                0:         Diag(Tok, diag::err_argument_required_after_attribute);
                        0: branch 0 not taken
                        0: branch 1 not taken
    2806                0:         delete AttrList;
    2807                 :       }
    2808                 :       // Identifier list.  Note that '(' identifier-list ')' is only allowed for
    2809                 :       // normal declarators, not for abstract-declarators.
    2810               57:       return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
    2811                 :     }
    2812                 :   }
    2813                 : 
    2814                 :   // Finally, a normal, non-empty parameter type list.
    2815                 : 
    2816                 :   // Build up an array of information about the parsed arguments.
    2817             9240:   llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
    2818                 : 
    2819                 :   // Enter function-declaration scope, limiting any declarators to the
    2820                 :   // function prototype scope, including parameter declarators.
    2821                 :   ParseScope PrototypeScope(this,
    2822             9240:                             Scope::FunctionPrototypeScope|Scope::DeclScope);
    2823                 : 
    2824             9240:   bool IsVariadic = false;
    2825             9240:   SourceLocation EllipsisLoc;
                     4933: branch 1 taken
                     8934: branch 2 taken
                     4933: branch 4 taken
                     8934: branch 5 taken
    2826            13867:   while (1) {
                      306: branch 1 taken
                    13867: branch 2 taken
    2827            14173:     if (Tok.is(tok::ellipsis)) {
    2828              306:       IsVariadic = true;
    2829              306:       EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
    2830              306:       break;
    2831                 :     }
    2832                 : 
    2833            13867:     SourceLocation DSStart = Tok.getLocation();
    2834                 : 
    2835                 :     // Parse the declaration-specifiers.
    2836                 :     // Just use the ParsingDeclaration "scope" of the declarator.
    2837            13867:     DeclSpec DS;
    2838                 : 
    2839                 :     // If the caller parsed attributes for the first argument, add them now.
                        0: branch 0 not taken
                    13867: branch 1 taken
    2840            13867:     if (AttrList) {
    2841                0:       DS.AddAttributes(AttrList);
    2842                0:       AttrList = 0;  // Only apply the attributes to the first parameter.
    2843                 :     }
    2844            13867:     ParseDeclarationSpecifiers(DS);
    2845                 : 
    2846                 :     // Parse the declarator.  This is "PrototypeContext", because we must
    2847                 :     // accept either 'declarator' or 'abstract-declarator' here.
    2848            13867:     Declarator ParmDecl(DS, Declarator::PrototypeContext);
    2849            13867:     ParseDeclarator(ParmDecl);
    2850                 : 
    2851                 :     // Parse GNU attributes, if present.
                        3: branch 1 taken
                    13864: branch 2 taken
    2852            13867:     if (Tok.is(tok::kw___attribute)) {
    2853                3:       SourceLocation Loc;
    2854                3:       AttributeList *AttrList = ParseGNUAttributes(&Loc);
    2855                3:       ParmDecl.AddAttributes(AttrList, Loc);
    2856                 :     }
    2857                 : 
    2858                 :     // Remember this parsed parameter in ParamInfo.
    2859            13867:     IdentifierInfo *ParmII = ParmDecl.getIdentifier();
    2860                 : 
    2861                 :     // DefArgToks is used when the parsing of default arguments needs
    2862                 :     // to be delayed.
    2863            13867:     CachedTokens *DefArgToks = 0;
    2864                 : 
    2865                 :     // If no parameter was specified, verify that *something* was specified,
    2866                 :     // otherwise we have a missing type and identifier.
                       18: branch 1 taken
                    13849: branch 2 taken
                        7: branch 4 taken
                       11: branch 5 taken
                        7: branch 7 taken
                        0: branch 8 not taken
                        7: branch 9 taken
                    13860: branch 10 taken
    2867            13867:     if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
    2868                 :         ParmDecl.getNumTypeObjects() == 0) {
    2869                 :       // Completely missing, emit error.
    2870                7:       Diag(DSStart, diag::err_missing_param);
    2871                 :     } else {
    2872                 :       // Otherwise, we have something.  Add it and let semantic analysis try
    2873                 :       // to grok it and add the result to the ParamInfo we are building.
    2874                 : 
    2875                 :       // Inform the actions module about the parameter declarator, so it gets
    2876                 :       // added to the current scope.
    2877            13860:       DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
    2878                 : 
    2879                 :       // Parse the default argument, if any. We parse the default
    2880                 :       // arguments in all dialects; the semantic analysis in
    2881                 :       // ActOnParamDefaultArgument will reject the default argument in
    2882                 :       // C.
                      169: branch 1 taken
                    13691: branch 2 taken
    2883            13860:       if (Tok.is(tok::equal)) {
    2884              169:         SourceLocation EqualLoc = Tok.getLocation();
    2885                 : 
    2886                 :         // Parse the default argument
                       82: branch 1 taken
                       87: branch 2 taken
    2887              169:         if (D.getContext() == Declarator::MemberContext) {
    2888                 :           // If we're inside a class definition, cache the tokens
    2889                 :           // corresponding to the default argument. We'll actually parse
    2890                 :           // them when we see the end of the class definition.
    2891                 :           // FIXME: Templates will require something similar.
    2892                 :           // FIXME: Can we use a smart pointer for Toks?
    2893               82:           DefArgToks = new CachedTokens;
    2894                 : 
                        0: branch 1 not taken
                       82: branch 2 taken
    2895               82:           if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
    2896                 :                                     tok::semi, false)) {
                        0: branch 0 not taken
                        0: branch 1 not taken
    2897                0:             delete DefArgToks;
    2898                0:             DefArgToks = 0;
    2899                0:             Actions.ActOnParamDefaultArgumentError(Param);
    2900                 :           } else
    2901                 :             Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
    2902               82:                                                 (*DefArgToks)[1].getLocation());
    2903                 :         } else {
    2904                 :           // Consume the '='.
    2905               87:           ConsumeToken();
    2906                 : 
    2907               87:           OwningExprResult DefArgResult(ParseAssignmentExpression());
                        1: branch 1 taken
                       86: branch 2 taken
    2908               87:           if (DefArgResult.isInvalid()) {
    2909                1:             Actions.ActOnParamDefaultArgumentError(Param);
    2910                1:             SkipUntil(tok::comma, tok::r_paren, true, true);
    2911                 :           } else {
    2912                 :             // Inform the actions module about the default argument
    2913                 :             Actions.ActOnParamDefaultArgument(Param, EqualLoc,
    2914               86:                                               move(DefArgResult));
    2915               87:           }
    2916                 :         }
    2917                 :       }
    2918                 : 
    2919                 :       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
    2920                 :                                           ParmDecl.getIdentifierLoc(), Param,
    2921            13860:                                           DefArgToks));
    2922                 :     }
    2923                 : 
    2924                 :     // If the next token is a comma, consume it and keep reading arguments.
                     8934: branch 1 taken
                     4933: branch 2 taken
    2925            13867:     if (Tok.isNot(tok::comma)) {
                        3: branch 1 taken
                     8931: branch 2 taken
    2926             8934:       if (Tok.is(tok::ellipsis)) {
    2927                3:         IsVariadic = true;
    2928                3:         EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
    2929                 :         
                        1: branch 1 taken
                        2: branch 2 taken
    2930                3:         if (!getLang().CPlusPlus) {
    2931                 :           // We have ellipsis without a preceding ',', which is ill-formed
    2932                 :           // in C. Complain and provide the fix.
    2933                 :           Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
    2934                1:             << CodeModificationHint::CreateInsertion(EllipsisLoc, ", ");
    2935                 :         }
    2936                 :       }
    2937                 :       
    2938             8934:       break;
    2939                 :     }
    2940                 : 
    2941                 :     // Consume the comma.
    2942             4933:     ConsumeToken();
    2943                 :   }
    2944                 : 
    2945                 :   // Leave prototype scope.
    2946             9240:   PrototypeScope.Exit();
    2947                 : 
    2948                 :   // If we have the closing ')', eat it.
    2949             9240:   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
    2950             9240:   SourceLocation EndLoc = RParenLoc;
    2951                 : 
    2952             9240:   DeclSpec DS;
    2953             9240:   bool hasExceptionSpec = false;
    2954             9240:   SourceLocation ThrowLoc;
    2955             9240:   bool hasAnyExceptionSpec = false;
    2956             9240:   llvm::SmallVector<TypeTy*, 2> Exceptions;
    2957             9240:   llvm::SmallVector<SourceRange, 2> ExceptionRanges;
    2958                 :   
                     3759: branch 1 taken
                     5481: branch 2 taken
    2959             9240:   if (getLang().CPlusPlus) {
    2960                 :     // Parse cv-qualifier-seq[opt].
    2961             3759:     ParseTypeQualifierListOpt(DS, false /*no attributes*/);
                        0: branch 3 not taken
                     3759: branch 4 taken
    2962             3759:       if (!DS.getSourceRange().getEnd().isInvalid())
    2963                0:         EndLoc = DS.getSourceRange().getEnd();
    2964                 : 
    2965                 :     // Parse exception-specification[opt].
                      232: branch 1 taken
                     3527: branch 2 taken
    2966             3759:     if (Tok.is(tok::kw_throw)) {
    2967              232:       hasExceptionSpec = true;
    2968              232:       ThrowLoc = Tok.getLocation();
    2969                 :       ParseExceptionSpecification(EndLoc, Exceptions, ExceptionRanges,
    2970              232:                                   hasAnyExceptionSpec);
    2971                 :       assert(Exceptions.size() == ExceptionRanges.size() &&
                      232: branch 2 taken
                        0: branch 3 not taken
    2972              232:              "Produced different number of exception types and ranges.");
    2973                 :     }
    2974                 :   }
    2975                 : 
    2976                 :   // Remember that we parsed a function type, and remember the attributes.
    2977                 :   D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
    2978                 :                                              EllipsisLoc,
    2979                 :                                              ParamInfo.data(), ParamInfo.size(),
    2980                 :                                              DS.getTypeQualifiers(),
    2981                 :                                              hasExceptionSpec, ThrowLoc,
    2982                 :                                              hasAnyExceptionSpec,
    2983                 :                                              Exceptions.data(),
    2984                 :                                              ExceptionRanges.data(),
    2985                 :                                              Exceptions.size(),
    2986                 :                                              LParenLoc, RParenLoc, D),
    2987             9240:                 EndLoc);
    2988                 : }
    2989                 : 
    2990                 : /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
    2991                 : /// we found a K&R-style identifier list instead of a type argument list.  The
    2992                 : /// current token is known to be the first identifier in the list.
    2993                 : ///
    2994                 : ///       identifier-list: [C99 6.7.5]
    2995                 : ///         identifier
    2996                 : ///         identifier-list ',' identifier
    2997                 : ///
    2998                 : void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
    2999               57:                                                    Declarator &D) {
    3000                 :   // Build up an array of information about the parsed arguments.
    3001               57:   llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
    3002               57:   llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
    3003                 : 
    3004                 :   // If there was no identifier specified for the declarator, either we are in
    3005                 :   // an abstract-declarator, or we are in a parameter declarator which was found
    3006                 :   // to be abstract.  In abstract-declarators, identifier lists are not valid:
    3007                 :   // diagnose this.
                        0: branch 1 not taken
                       57: branch 2 taken
    3008               57:   if (!D.getIdentifier())
    3009                0:     Diag(Tok, diag::ext_ident_list_in_param);
    3010                 : 
    3011                 :   // Tok is known to be the first identifier in the list.  Remember this
    3012                 :   // identifier in ParamInfo.
    3013               57:   ParamsSoFar.insert(Tok.getIdentifierInfo());
    3014                 :   ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
    3015                 :                                                  Tok.getLocation(),
    3016               57:                                                  DeclPtrTy()));
    3017                 : 
    3018               57:   ConsumeToken();  // eat the first identifier.
    3019                 : 
                       22: branch 1 taken
                       54: branch 2 taken
    3020              133:   while (Tok.is(tok::comma)) {
    3021                 :     // Eat the comma.
    3022               22:     ConsumeToken();
    3023                 : 
    3024                 :     // If this isn't an identifier, report the error and skip until ')'.
                        3: branch 1 taken
                       19: branch 2 taken
    3025               22:     if (Tok.isNot(tok::identifier)) {
    3026                3:       Diag(Tok, diag::err_expected_ident);
    3027                3:       SkipUntil(tok::r_paren);
    3028                3:       return;
    3029                 :     }
    3030                 : 
    3031               19:     IdentifierInfo *ParmII = Tok.getIdentifierInfo();
    3032                 : 
    3033                 :     // Reject 'typedef int y; int test(x, y)', but continue parsing.
                        1: branch 2 taken
                       18: branch 3 taken
    3034               19:     if (Actions.getTypeName(*ParmII, Tok.getLocation(), CurScope))
    3035                1:       Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
    3036                 : 
    3037                 :     // Verify that the argument identifier has not already been mentioned.
                        2: branch 1 taken
                       17: branch 2 taken
    3038               19:     if (!ParamsSoFar.insert(ParmII)) {
    3039                2:       Diag(Tok, diag::err_param_redefinition) << ParmII;
    3040                 :     } else {
    3041                 :       // Remember this identifier in ParamInfo.
    3042                 :       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
    3043                 :                                                      Tok.getLocation(),
    3044               17:                                                      DeclPtrTy()));
    3045                 :     }
    3046                 : 
    3047                 :     // Eat the identifier.
    3048               19:     ConsumeToken();
    3049                 :   }
    3050                 : 
    3051                 :   // If we have the closing ')', eat it and we're done.
    3052               54:   SourceLocation RLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
    3053                 : 
    3054                 :   // Remember that we parsed a function type, and remember the attributes.  This
    3055                 :   // function type is always a K&R style function type, which is not varargs and
    3056                 :   // has no prototype.
    3057                 :   D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
    3058                 :                                              SourceLocation(),
    3059                 :                                              &ParamInfo[0], ParamInfo.size(),
    3060                 :                                              /*TypeQuals*/0,
    3061                 :                                              /*exception*/false,
    3062                 :                                              SourceLocation(), false, 0, 0, 0,
    3063                 :                                              LParenLoc, RLoc, D),
                       54: branch 7 taken
                        3: branch 8 taken
                       54: branch 10 taken
                        3: branch 11 taken
    3064               54:                 RLoc);
    3065                 : }
    3066                 : 
    3067                 : /// [C90]   direct-declarator '[' constant-expression[opt] ']'
    3068                 : /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
    3069                 : /// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
    3070                 : /// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
    3071                 : /// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
    3072             2317: void Parser::ParseBracketDeclarator(Declarator &D) {
    3073             2317:   SourceLocation StartLoc = ConsumeBracket();
    3074                 : 
    3075                 :   // C array syntax has many features, but by-far the most common is [] and [4].
    3076                 :   // This code does a fast path to handle some of the most obvious cases.
                      344: branch 1 taken
                     1973: branch 2 taken
    3077             2317:   if (Tok.getKind() == tok::r_square) {
    3078              344:     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
    3079                 :     //FIXME: Use these
    3080              344:     CXX0XAttributeList Attr;
                        3: branch 1 taken
                      341: branch 2 taken
                        0: branch 4 not taken
                        3: branch 5 taken
                        0: branch 6 not taken
                      344: branch 7 taken
    3081              344:     if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier(true)) {
    3082                0:       Attr = ParseCXX0XAttributes();
    3083                 :     }
    3084                 :     
    3085                 :     // Remember that we parsed the empty array type.
    3086              344:     OwningExprResult NumElements(Actions);
    3087                 :     D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
    3088                 :                                             StartLoc, EndLoc),
    3089              344:                   EndLoc);
    3090              344:     return;
                     1215: branch 1 taken
                      758: branch 2 taken
                     1190: branch 5 taken
                       25: branch 6 taken
                     1190: branch 7 taken
                      783: branch 8 taken
    3091             1973:   } else if (Tok.getKind() == tok::numeric_constant &&
    3092                 :              GetLookAheadToken(1).is(tok::r_square)) {
    3093                 :     // [4] is very common.  Parse the numeric constant expression.
    3094             1190:     OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
    3095             1190:     ConsumeToken();
    3096                 : 
    3097             1190:     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
    3098                 :     //FIXME: Use these
    3099             1190:     CXX0XAttributeList Attr;
                       68: branch 1 taken
                     1122: branch 2 taken
                        1: branch 4 taken
                       67: branch 5 taken
                        1: branch 6 taken
                     1189: branch 7 taken
    3100             1190:     if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
    3101                1:       Attr = ParseCXX0XAttributes();
    3102                 :     }
    3103                 : 
    3104                 :     // If there was an error parsing the assignment-expression, recover.
                        0: branch 1 not taken
                     1190: branch 2 taken
    3105             1190:     if (ExprRes.isInvalid())
    3106                0:       ExprRes.release();  // Deallocate expr, just use [].
    3107                 : 
    3108                 :     // Remember that we parsed a array type, and remember its features.
    3109                 :     D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, ExprRes.release(),
    3110                 :                                             StartLoc, EndLoc),
    3111             1190:                   EndLoc);
    3112             1190:     return;
    3113                 :   }
    3114                 : 
    3115                 :   // If valid, this location is the position where we read the 'static' keyword.
    3116              783:   SourceLocation StaticLoc;
                        2: branch 1 taken
                      781: branch 2 taken
    3117              783:   if (Tok.is(tok::kw_static))
    3118                2:     StaticLoc = ConsumeToken();
    3119                 : 
    3120                 :   // If there is a type-qualifier-list, read it now.
    3121                 :   // Type qualifiers in an array subscript are a C99 feature.
    3122              783:   DeclSpec DS;
    3123              783:   ParseTypeQualifierListOpt(DS, false /*no attributes*/);
    3124                 : 
    3125                 :   // If we haven't already read 'static', check to see if there is one after the
    3126                 :   // type-qualifier-list.
                      781: branch 1 taken
                        2: branch 2 taken
                        0: branch 4 not taken
                      781: branch 5 taken
                        0: branch 6 not taken