zcov: / lib/Parse/ParseTemplate.cpp


Files: 1 Branches Taken: 81.8% 224 / 274
Generated: 2010-02-10 01:31 Branches Executed: 94.9% 260 / 274
Line Coverage: 92.7% 332 / 358


Programs: 2 Runs 3018


       1                 : //===--- ParseTemplate.cpp - Template 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 parsing of C++ templates.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/Parse/Parser.h"
      15                 : #include "clang/Parse/ParseDiagnostic.h"
      16                 : #include "clang/Parse/DeclSpec.h"
      17                 : #include "clang/Parse/Scope.h"
      18                 : #include "clang/Parse/Template.h"
      19                 : #include "RAIIObjectsForParser.h"
      20                 : using namespace clang;
      21                 : 
      22                 : /// \brief Parse a template declaration, explicit instantiation, or
      23                 : /// explicit specialization.
      24                 : Parser::DeclPtrTy
      25                 : Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
      26                 :                                              SourceLocation &DeclEnd,
      27             2191:                                              AccessSpecifier AS) {
                     2188: branch 1 taken
                        3: branch 2 taken
                      359: branch 5 taken
                     1829: branch 6 taken
                      359: branch 7 taken
                     1832: branch 8 taken
      28             2191:   if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less))
      29                 :     return ParseExplicitInstantiation(SourceLocation(), ConsumeToken(),
      30              359:                                       DeclEnd);
      31                 : 
      32             1832:   return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS);
      33                 : }
      34                 : 
      35                 : /// \brief RAII class that manages the template parameter depth.
      36                 : namespace {
      37                 :   class TemplateParameterDepthCounter {
      38                 :     unsigned &Depth;
      39                 :     unsigned AddedLevels;
      40                 : 
      41                 :   public:
      42             1832:     explicit TemplateParameterDepthCounter(unsigned &Depth)
      43             1832:       : Depth(Depth), AddedLevels(0) { }
      44                 : 
      45             1832:     ~TemplateParameterDepthCounter() {
      46             1832:       Depth -= AddedLevels;
      47             1832:     }
      48                 : 
      49             1648:     void operator++() {
      50             1648:       ++Depth;
      51             1648:       ++AddedLevels;
      52             1648:     }
      53                 : 
      54             3777:     operator unsigned() const { return Depth; }
      55                 :   };
      56                 : }
      57                 : 
      58                 : /// \brief Parse a template declaration or an explicit specialization.
      59                 : ///
      60                 : /// Template declarations include one or more template parameter lists
      61                 : /// and either the function or class template declaration. Explicit
      62                 : /// specializations contain one or more 'template < >' prefixes
      63                 : /// followed by a (possibly templated) declaration. Since the
      64                 : /// syntactic form of both features is nearly identical, we parse all
      65                 : /// of the template headers together and let semantic analysis sort
      66                 : /// the declarations from the explicit specializations.
      67                 : ///
      68                 : ///       template-declaration: [C++ temp]
      69                 : ///         'export'[opt] 'template' '<' template-parameter-list '>' declaration
      70                 : ///
      71                 : ///       explicit-specialization: [ C++ temp.expl.spec]
      72                 : ///         'template' '<' '>' declaration
      73                 : Parser::DeclPtrTy
      74                 : Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
      75                 :                                                  SourceLocation &DeclEnd,
      76             1832:                                                  AccessSpecifier AS) {
      77                 :   assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) &&
                     1829: branch 1 taken
                        3: branch 2 taken
                     1829: branch 4 taken
                        0: branch 5 not taken
      78             1832:          "Token does not start a template declaration.");
      79                 : 
      80                 :   // Enter template-parameter scope.
      81             1832:   ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
      82                 : 
      83                 :   // Parse multiple levels of template headers within this template
      84                 :   // parameter scope, e.g.,
      85                 :   //
      86                 :   //   template<typename T>
      87                 :   //     template<typename U>
      88                 :   //       class A<T>::B { ... };
      89                 :   //
      90                 :   // We parse multiple levels non-recursively so that we can build a
      91                 :   // single data structure containing all of the template parameter
      92                 :   // lists to easily differentiate between the case above and:
      93                 :   //
      94                 :   //   template<typename T>
      95                 :   //   class A {
      96                 :   //     template<typename U> class B;
      97                 :   //   };
      98                 :   //
      99                 :   // In the first case, the action for declaring A<T>::B receives
     100                 :   // both template parameter lists. In the second case, the action for
     101                 :   // defining A<T>::B receives just the inner template parameter list
     102                 :   // (and retrieves the outer template parameter list from its
     103                 :   // context).
     104             1832:   bool isSpecialization = true;
     105             1832:   bool LastParamListWasEmpty = false;
     106             1832:   TemplateParameterLists ParamLists;
     107             1832:   TemplateParameterDepthCounter Depth(TemplateParameterDepth);
                     1888: branch 1 taken
                        0: branch 2 not taken
                       58: branch 4 taken
                     1830: branch 5 taken
                       58: branch 6 taken
                     1830: branch 7 taken
     108             1888:   do {
     109                 :     // Consume the 'export', if any.
     110             1890:     SourceLocation ExportLoc;
                        3: branch 1 taken
                     1887: branch 2 taken
     111             1890:     if (Tok.is(tok::kw_export)) {
     112                3:       ExportLoc = ConsumeToken();
     113                 :     }
     114                 : 
     115                 :     // Consume the 'template', which should be here.
     116             1890:     SourceLocation TemplateLoc;
                     1889: branch 1 taken
                        1: branch 2 taken
     117             1890:     if (Tok.is(tok::kw_template)) {
     118             1889:       TemplateLoc = ConsumeToken();
     119                 :     } else {
     120                1:       Diag(Tok.getLocation(), diag::err_expected_template);
     121                1:       return DeclPtrTy();
     122                 :     }
     123                 : 
     124                 :     // Parse the '<' template-parameter-list '>'
     125             1889:     SourceLocation LAngleLoc, RAngleLoc;
     126             1889:     TemplateParameterList TemplateParams;
                        1: branch 2 taken
                     1888: branch 3 taken
     127             1889:     if (ParseTemplateParameters(Depth, TemplateParams, LAngleLoc,
     128                 :                                 RAngleLoc)) {
     129                 :       // Skip until the semi-colon or a }.
     130                1:       SkipUntil(tok::r_brace, true, true);
                        1: branch 1 taken
                        0: branch 2 not taken
     131                1:       if (Tok.is(tok::semi))
     132                1:         ConsumeToken();
     133                1:       return DeclPtrTy();
     134                 :     }
     135                 : 
     136                 :     ParamLists.push_back(
     137                 :       Actions.ActOnTemplateParameterList(Depth, ExportLoc,
     138                 :                                          TemplateLoc, LAngleLoc,
     139                 :                                          TemplateParams.data(),
     140             1888:                                          TemplateParams.size(), RAngleLoc));
     141                 : 
                     1648: branch 1 taken
                      240: branch 2 taken
     142             1888:     if (!TemplateParams.empty()) {
     143             1648:       isSpecialization = false;
     144             1648:       ++Depth;
     145                 :     } else {
     146              240:       LastParamListWasEmpty = true;
                     1888: branch 1 taken
                        1: branch 2 taken
     147             1889:     }
     148                 :   } while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template));
     149                 : 
     150                 :   // Parse the actual template declaration.
     151                 :   return ParseSingleDeclarationAfterTemplate(Context,
     152                 :                                              ParsedTemplateInfo(&ParamLists,
     153                 :                                                              isSpecialization,
     154                 :                                                          LastParamListWasEmpty),
     155             1830:                                              DeclEnd, AS);
     156                 : }
     157                 : 
     158                 : /// \brief Parse a single declaration that declares a template,
     159                 : /// template specialization, or explicit instantiation of a template.
     160                 : ///
     161                 : /// \param TemplateParams if non-NULL, the template parameter lists
     162                 : /// that preceded this declaration. In this case, the declaration is a
     163                 : /// template declaration, out-of-line definition of a template, or an
     164                 : /// explicit template specialization. When NULL, the declaration is an
     165                 : /// explicit template instantiation.
     166                 : ///
     167                 : /// \param TemplateLoc when TemplateParams is NULL, the location of
     168                 : /// the 'template' keyword that indicates that we have an explicit
     169                 : /// template instantiation.
     170                 : ///
     171                 : /// \param DeclEnd will receive the source location of the last token
     172                 : /// within this declaration.
     173                 : ///
     174                 : /// \param AS the access specifier associated with this
     175                 : /// declaration. Will be AS_none for namespace-scope declarations.
     176                 : ///
     177                 : /// \returns the new declaration.
     178                 : Parser::DeclPtrTy
     179                 : Parser::ParseSingleDeclarationAfterTemplate(
     180                 :                                        unsigned Context,
     181                 :                                        const ParsedTemplateInfo &TemplateInfo,
     182                 :                                        SourceLocation &DeclEnd,
     183             2207:                                        AccessSpecifier AS) {
     184                 :   assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
                        0: branch 0 not taken
                     2207: branch 1 taken
     185             2207:          "Template information required");
     186                 : 
                      201: branch 0 taken
                     2006: branch 1 taken
     187             2207:   if (Context == Declarator::MemberContext) {
     188                 :     // We are parsing a member template.
     189              201:     ParseCXXClassMemberDeclaration(AS, TemplateInfo);
     190              201:     return DeclPtrTy::make((void*)0);
     191                 :   }
     192                 : 
     193                 :   // Parse the declaration specifiers.
     194             2006:   ParsingDeclSpec DS(*this);
     195                 : 
                       96: branch 1 taken
                     1910: branch 2 taken
                        1: branch 4 taken
                       95: branch 5 taken
                        1: branch 6 taken
                     2005: branch 7 taken
     196             2006:   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
     197                1:     DS.AddAttributes(ParseCXX0XAttributes().AttrList);
     198                 : 
     199                 :   ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
     200             2006:                              getDeclSpecContextFromDeclaratorContext(Context));
     201                 : 
                     1358: branch 1 taken
                      648: branch 2 taken
     202             2006:   if (Tok.is(tok::semi)) {
     203             1358:     DeclEnd = ConsumeToken();
     204             1358:     DeclPtrTy Decl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
     205             1358:     DS.complete(Decl);
     206             1358:     return Decl;
     207                 :   }
     208                 : 
     209                 :   // Parse the declarator.
     210              648:   ParsingDeclarator DeclaratorInfo(*this, DS, (Declarator::TheContext)Context);
     211              648:   ParseDeclarator(DeclaratorInfo);
     212                 :   // Error parsing the declarator?
                        1: branch 1 taken
                      647: branch 2 taken
     213              648:   if (!DeclaratorInfo.hasName()) {
     214                 :     // If so, skip until the semi-colon or a }.
     215                1:     SkipUntil(tok::r_brace, true, true);
                        1: branch 1 taken
                        0: branch 2 not taken
     216                1:     if (Tok.is(tok::semi))
     217                1:       ConsumeToken();
     218                1:     return DeclPtrTy();
     219                 :   }
     220                 : 
     221                 :   // If we have a declaration or declarator list, handle it.
                      348: branch 1 taken
                      299: branch 2 taken
     222              647:   if (isDeclarationAfterDeclarator()) {
     223                 :     // Parse this declaration.
     224                 :     DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
     225              348:                                                          TemplateInfo);
     226                 : 
                        1: branch 1 taken
                      347: branch 2 taken
     227              348:     if (Tok.is(tok::comma)) {
     228                 :       Diag(Tok, diag::err_multiple_template_declarators)
     229                1:         << (int)TemplateInfo.Kind;
     230                1:       SkipUntil(tok::semi, true, false);
     231                1:       return ThisDecl;
     232                 :     }
     233                 : 
     234                 :     // Eat the semi colon after the declaration.
     235              347:     ExpectAndConsume(tok::semi, diag::err_expected_semi_declaration);
     236              347:     DS.complete(ThisDecl);
     237              347:     return ThisDecl;
     238                 :   }
     239                 : 
                      297: branch 1 taken
                        2: branch 2 taken
                      297: branch 4 taken
                        0: branch 5 not taken
                      297: branch 6 taken
                        2: branch 7 taken
     240              299:   if (DeclaratorInfo.isFunctionDeclarator() &&
     241                 :       isStartOfFunctionDefinition()) {
                        0: branch 1 not taken
                      297: branch 2 taken
     242              297:     if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
     243                0:       Diag(Tok, diag::err_function_declared_typedef);
     244                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
     245                0:       if (Tok.is(tok::l_brace)) {
     246                 :         // This recovery skips the entire function body. It would be nice
     247                 :         // to simply call ParseFunctionDefinition() below, however Sema
     248                 :         // assumes the declarator represents a function, not a typedef.
     249                0:         ConsumeBrace();
     250                0:         SkipUntil(tok::r_brace, true);
     251                 :       } else {
     252                0:         SkipUntil(tok::semi);
     253                 :       }
     254                0:       return DeclPtrTy();
     255                 :     }
     256              297:     return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo);
     257                 :   }
     258                 : 
                        0: branch 1 not taken
                        2: branch 2 taken
     259                2:   if (DeclaratorInfo.isFunctionDeclarator())
     260                0:     Diag(Tok, diag::err_expected_fn_body);
     261                 :   else
     262                2:     Diag(Tok, diag::err_invalid_token_after_toplevel_declarator);
     263                2:   SkipUntil(tok::semi);
     264                2:   return DeclPtrTy();
     265                 : }
     266                 : 
     267                 : /// ParseTemplateParameters - Parses a template-parameter-list enclosed in
     268                 : /// angle brackets. Depth is the depth of this template-parameter-list, which
     269                 : /// is the number of template headers directly enclosing this template header.
     270                 : /// TemplateParams is the current list of template parameters we're building.
     271                 : /// The template parameter we parse will be added to this list. LAngleLoc and
     272                 : /// RAngleLoc will receive the positions of the '<' and '>', respectively,
     273                 : /// that enclose this template parameter list.
     274                 : ///
     275                 : /// \returns true if an error occurred, false otherwise.
     276                 : bool Parser::ParseTemplateParameters(unsigned Depth,
     277                 :                                      TemplateParameterList &TemplateParams,
     278                 :                                      SourceLocation &LAngleLoc,
     279             1948:                                      SourceLocation &RAngleLoc) {
     280                 :   // Get the template parameter list.
                        2: branch 1 taken
                     1946: branch 2 taken
     281             1948:   if (!Tok.is(tok::less)) {
     282                2:     Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";
     283                2:     return true;
     284                 :   }
     285             1946:   LAngleLoc = ConsumeToken();
     286                 : 
     287                 :   // Try to parse the template parameter list.
                      236: branch 1 taken
                     1710: branch 2 taken
     288             1946:   if (Tok.is(tok::greater))
     289              236:     RAngleLoc = ConsumeToken();
                     1709: branch 1 taken
                        1: branch 2 taken
     290             1710:   else if (ParseTemplateParameterList(Depth, TemplateParams)) {
                        0: branch 1 not taken
                     1709: branch 2 taken
     291             1709:     if (!Tok.is(tok::greater)) {
     292                0:       Diag(Tok.getLocation(), diag::err_expected_greater);
     293                0:       return true;
     294                 :     }
     295             1709:     RAngleLoc = ConsumeToken();
     296                 :   }
     297             1946:   return false;
     298                 : }
     299                 : 
     300                 : /// ParseTemplateParameterList - Parse a template parameter list. If
     301                 : /// the parsing fails badly (i.e., closing bracket was left out), this
     302                 : /// will try to put the token stream in a reasonable position (closing
     303                 : /// a statement, etc.) and return false.
     304                 : ///
     305                 : ///       template-parameter-list:    [C++ temp]
     306                 : ///         template-parameter
     307                 : ///         template-parameter-list ',' template-parameter
     308                 : bool
     309                 : Parser::ParseTemplateParameterList(unsigned Depth,
     310             2165:                                    TemplateParameterList &TemplateParams) {
     311              455:   while (1) {
                     2161: branch 1 taken
                        4: branch 2 taken
     312             2165:     if (DeclPtrTy TmpParam
     313             2165:           = ParseTemplateParameter(Depth, TemplateParams.size())) {
     314             2161:       TemplateParams.push_back(TmpParam);
     315                 :     } else {
     316                 :       // If we failed to parse a template parameter, skip until we find
     317                 :       // a comma or closing brace.
     318                4:       SkipUntil(tok::comma, tok::greater, true, true);
     319                 :     }
     320                 : 
     321                 :     // Did we find a comma or the end of the template parmeter list?
                      455: branch 1 taken
                     1710: branch 2 taken
     322             2165:     if (Tok.is(tok::comma)) {
     323              455:       ConsumeToken();
                        1: branch 1 taken
                     1709: branch 2 taken
     324             1710:     } else if (Tok.is(tok::greater)) {
     325                 :       // Don't consume this... that's done by template parser.
     326             1709:       break;
     327                 :     } else {
     328                 :       // Somebody probably forgot to close the template. Skip ahead and
     329                 :       // try to get out of the expression. This error is currently
     330                 :       // subsumed by whatever goes on in ParseTemplateParameter.
     331                 :       // TODO: This could match >>, and it would be nice to avoid those
     332                 :       // silly errors with template <vec<T>>.
     333                 :       // Diag(Tok.getLocation(), diag::err_expected_comma_greater);
     334                1:       SkipUntil(tok::greater, true, true);
     335                1:       return false;
     336                 :     }
     337                 :   }
     338             1709:   return true;
     339                 : }
     340                 : 
     341                 : /// \brief Determine whether the parser is at the start of a template
     342                 : /// type parameter.
     343             2165: bool Parser::isStartOfTemplateTypeParameter() {
                      322: branch 1 taken
                     1843: branch 2 taken
     344             2165:   if (Tok.is(tok::kw_class))
     345              322:     return true;
     346                 : 
                      450: branch 1 taken
                     1393: branch 2 taken
     347             1843:   if (Tok.isNot(tok::kw_typename))
     348              450:     return false;
     349                 : 
     350                 :   // C++ [temp.param]p2:
     351                 :   //   There is no semantic difference between class and typename in a
     352                 :   //   template-parameter. typename followed by an unqualified-id
     353                 :   //   names a template type parameter. typename followed by a
     354                 :   //   qualified-id denotes the type in a non-type
     355                 :   //   parameter-declaration.
     356             1393:   Token Next = NextToken();
     357                 : 
     358                 :   // If we have an identifier, skip over it.
                     1323: branch 1 taken
                       70: branch 2 taken
     359             1393:   if (Next.getKind() == tok::identifier)
     360             1323:     Next = GetLookAheadToken(2);
     361                 : 
                     1391: branch 1 taken
                        2: branch 2 taken
     362             1393:   switch (Next.getKind()) {
     363                 :   case tok::equal:
     364                 :   case tok::comma:
     365                 :   case tok::greater:
     366                 :   case tok::greatergreater:
     367                 :   case tok::ellipsis:
     368             1391:     return true;
     369                 : 
     370                 :   default:
     371                2:     return false;
     372                 :   }
     373                 : }
     374                 : 
     375                 : /// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]).
     376                 : ///
     377                 : ///       template-parameter: [C++ temp.param]
     378                 : ///         type-parameter
     379                 : ///         parameter-declaration
     380                 : ///
     381                 : ///       type-parameter: (see below)
     382                 : ///         'class' ...[opt][C++0x] identifier[opt]
     383                 : ///         'class' identifier[opt] '=' type-id
     384                 : ///         'typename' ...[opt][C++0x] identifier[opt]
     385                 : ///         'typename' identifier[opt] '=' type-id
     386                 : ///         'template' ...[opt][C++0x] '<' template-parameter-list '>' 'class' identifier[opt]
     387                 : ///         'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
     388                 : Parser::DeclPtrTy
     389             2165: Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
                     1713: branch 1 taken
                      452: branch 2 taken
     390             2165:   if (isStartOfTemplateTypeParameter())
     391             1713:     return ParseTypeParameter(Depth, Position);
     392                 : 
                       59: branch 1 taken
                      393: branch 2 taken
     393              452:   if (Tok.is(tok::kw_template))
     394               59:     return ParseTemplateTemplateParameter(Depth, Position);
     395                 : 
     396                 :   // If it's none of the above, then it must be a parameter declaration.
     397                 :   // NOTE: This will pick up errors in the closure of the template parameter
     398                 :   // list (e.g., template < ; Check here to implement >> style closures.
     399              393:   return ParseNonTypeTemplateParameter(Depth, Position);
     400                 : }
     401                 : 
     402                 : /// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]).
     403                 : /// Other kinds of template parameters are parsed in
     404                 : /// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter.
     405                 : ///
     406                 : ///       type-parameter:     [C++ temp.param]
     407                 : ///         'class' ...[opt][C++0x] identifier[opt]
     408                 : ///         'class' identifier[opt] '=' type-id
     409                 : ///         'typename' ...[opt][C++0x] identifier[opt]
     410                 : ///         'typename' identifier[opt] '=' type-id
     411             1713: Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){
     412                 :   assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_typename)) &&
                     1391: branch 1 taken
                      322: branch 2 taken
                     1391: branch 4 taken
                        0: branch 5 not taken
     413             1713:          "A type-parameter starts with 'class' or 'typename'");
     414                 : 
     415                 :   // Consume the 'class' or 'typename' keyword.
     416             1713:   bool TypenameKeyword = Tok.is(tok::kw_typename);
     417             1713:   SourceLocation KeyLoc = ConsumeToken();
     418                 : 
     419                 :   // Grab the ellipsis (if given).
     420             1713:   bool Ellipsis = false;
     421             1713:   SourceLocation EllipsisLoc;
                        8: branch 1 taken
                     1705: branch 2 taken
     422             1713:   if (Tok.is(tok::ellipsis)) {
     423                8:     Ellipsis = true;
     424                8:     EllipsisLoc = ConsumeToken();
     425                 : 
                        1: branch 1 taken
                        7: branch 2 taken
     426                8:     if (!getLang().CPlusPlus0x)
     427                1:       Diag(EllipsisLoc, diag::err_variadic_templates);
     428                 :   }
     429                 : 
     430                 :   // Grab the template parameter name (if given)
     431             1713:   SourceLocation NameLoc;
     432             1713:   IdentifierInfo* ParamName = 0;
                     1620: branch 1 taken
                       93: branch 2 taken
     433             1713:   if (Tok.is(tok::identifier)) {
     434             1620:     ParamName = Tok.getIdentifierInfo();
     435             1620:     NameLoc = ConsumeToken();
                       90: branch 1 taken
                        3: branch 2 taken
                       70: branch 4 taken
                       20: branch 5 taken
                       70: branch 7 taken
                        0: branch 8 not taken
                        0: branch 9 not taken
                       93: branch 10 taken
     436               93:   } else if (Tok.is(tok::equal) || Tok.is(tok::comma) ||
     437                 :             Tok.is(tok::greater)) {
     438                 :     // Unnamed template parameter. Don't have to do anything here, just
     439                 :     // don't consume this token.
     440                 :   } else {
     441                0:     Diag(Tok.getLocation(), diag::err_expected_ident);
     442                0:     return DeclPtrTy();
     443                 :   }
     444                 : 
     445                 :   DeclPtrTy TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword,
     446                 :                                                    Ellipsis, EllipsisLoc,
     447                 :                                                    KeyLoc, ParamName, NameLoc,
     448             1713:                                                    Depth, Position);
     449                 : 
     450                 :   // Grab a default type id (if given).
                       49: branch 1 taken
                     1664: branch 2 taken
     451             1713:   if (Tok.is(tok::equal)) {
     452               49:     SourceLocation EqualLoc = ConsumeToken();
     453               49:     SourceLocation DefaultLoc = Tok.getLocation();
     454               49:     TypeResult DefaultType = ParseTypeName();
                       49: branch 1 taken
                        0: branch 2 not taken
     455               49:     if (!DefaultType.isInvalid())
     456                 :       Actions.ActOnTypeParameterDefault(TypeParam, EqualLoc, DefaultLoc,
     457               49:                                         DefaultType.get());
     458                 :   }
     459                 : 
     460             1713:   return TypeParam;
     461                 : }
     462                 : 
     463                 : /// ParseTemplateTemplateParameter - Handle the parsing of template
     464                 : /// template parameters.
     465                 : ///
     466                 : ///       type-parameter:    [C++ temp.param]
     467                 : ///         'template' '<' template-parameter-list '>' 'class' identifier[opt]
     468                 : ///         'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
     469                 : Parser::DeclPtrTy
     470               59: Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
                       59: branch 1 taken
                        0: branch 2 not taken
     471               59:   assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
     472                 : 
     473                 :   // Handle the template <...> part.
     474               59:   SourceLocation TemplateLoc = ConsumeToken();
     475               59:   TemplateParameterList TemplateParams;
     476               59:   SourceLocation LAngleLoc, RAngleLoc;
     477                 :   {
     478               59:     ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
                        1: branch 1 taken
                       58: branch 2 taken
     479               59:     if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
     480                 :                                RAngleLoc)) {
     481                1:       return DeclPtrTy();
                       58: branch 1 taken
                        1: branch 2 taken
     482               59:     }
     483                 :   }
     484                 : 
     485                 :   // Generate a meaningful error if the user forgot to put class before the
     486                 :   // identifier, comma, or greater.
                        2: branch 1 taken
                       56: branch 2 taken
     487               58:   if (!Tok.is(tok::kw_class)) {
     488                 :     Diag(Tok.getLocation(), diag::err_expected_class_before)
     489                2:       << PP.getSpelling(Tok);
     490                2:     return DeclPtrTy();
     491                 :   }
     492               56:   SourceLocation ClassLoc = ConsumeToken();
     493                 : 
     494                 :   // Get the identifier, if given.
     495               56:   SourceLocation NameLoc;
     496               56:   IdentifierInfo* ParamName = 0;
                       36: branch 1 taken
                       20: branch 2 taken
     497               56:   if (Tok.is(tok::identifier)) {
     498               36:     ParamName = Tok.getIdentifierInfo();
     499               36:     NameLoc = ConsumeToken();
                       13: branch 1 taken
                        7: branch 2 taken
                        7: branch 4 taken
                        6: branch 5 taken
                        7: branch 7 taken
                        0: branch 8 not taken
                        0: branch 9 not taken
                       20: branch 10 taken
     500               20:   } else if (Tok.is(tok::equal) || Tok.is(tok::comma) || Tok.is(tok::greater)) {
     501                 :     // Unnamed template parameter. Don't have to do anything here, just
     502                 :     // don't consume this token.
     503                 :   } else {
     504                0:     Diag(Tok.getLocation(), diag::err_expected_ident);
     505                0:     return DeclPtrTy();
     506                 :   }
     507                 : 
     508                 :   TemplateParamsTy *ParamList =
     509                 :     Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
     510                 :                                        TemplateLoc, LAngleLoc,
     511                 :                                        &TemplateParams[0],
     512                 :                                        TemplateParams.size(),
     513               56:                                        RAngleLoc);
     514                 : 
     515                 :   Parser::DeclPtrTy Param
     516                 :     = Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
     517                 :                                              ParamList, ParamName,
     518               56:                                              NameLoc, Depth, Position);
     519                 : 
     520                 :   // Get the a default value, if given.
                       14: branch 1 taken
                       42: branch 2 taken
     521               56:   if (Tok.is(tok::equal)) {
     522               14:     SourceLocation EqualLoc = ConsumeToken();
     523               14:     ParsedTemplateArgument Default = ParseTemplateTemplateArgument();
                        3: branch 1 taken
                       11: branch 2 taken
     524               14:     if (Default.isInvalid()) {
     525                 :       Diag(Tok.getLocation(), 
     526                3:            diag::err_default_template_template_parameter_not_template);
     527                 :       static const tok::TokenKind EndToks[] = { 
     528                 :         tok::comma, tok::greater, tok::greatergreater
     529                 :       };
     530                3:       SkipUntil(EndToks, 3, true, true);
     531                3:       return Param;
                       11: branch 1 taken
                        0: branch 2 not taken
     532               11:     } else if (Param)
     533               11:       Actions.ActOnTemplateTemplateParameterDefault(Param, EqualLoc, Default);
     534                 :   }
     535                 : 
     536               53:   return Param;
     537                 : }
     538                 : 
     539                 : /// ParseNonTypeTemplateParameter - Handle the parsing of non-type
     540                 : /// template parameters (e.g., in "template<int Size> class array;").
     541                 : ///
     542                 : ///       template-parameter:
     543                 : ///         ...
     544                 : ///         parameter-declaration
     545                 : ///
     546                 : /// NOTE: It would be ideal to simply call out to ParseParameterDeclaration(),
     547                 : /// but that didn't work out to well. Instead, this tries to recrate the basic
     548                 : /// parsing of parameter declarations, but tries to constrain it for template
     549                 : /// parameters.
     550                 : /// FIXME: We need to make a ParseParameterDeclaration that works for
     551                 : /// non-type template parameters and normal function parameters.
     552                 : Parser::DeclPtrTy
     553              393: Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
     554              393:   SourceLocation StartLoc = Tok.getLocation();
     555                 : 
     556                 :   // Parse the declaration-specifiers (i.e., the type).
     557                 :   // FIXME: The type should probably be restricted in some way... Not all
     558                 :   // declarators (parts of declarators?) are accepted for parameters.
     559              393:   DeclSpec DS;
     560              393:   ParseDeclarationSpecifiers(DS);
     561                 : 
     562                 :   // Parse this as a typename.
     563              393:   Declarator ParamDecl(DS, Declarator::TemplateParamContext);
     564              393:   ParseDeclarator(ParamDecl);
                        1: branch 1 taken
                      392: branch 2 taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        1: branch 6 taken
                      392: branch 7 taken
     565              393:   if (DS.getTypeSpecType() == DeclSpec::TST_unspecified && !DS.getTypeRep()) {
     566                 :     // This probably shouldn't happen - and it's more of a Sema thing, but
     567                 :     // basically we didn't parse the type name because we couldn't associate
     568                 :     // it with an AST node. we should just skip to the comma or greater.
     569                 :     // TODO: This is currently a placeholder for some kind of Sema Error.
     570                1:     Diag(Tok.getLocation(), diag::err_parse_error);
     571                1:     SkipUntil(tok::comma, tok::greater, true, true);
     572                1:     return DeclPtrTy();
     573                 :   }
     574                 : 
     575                 :   // Create the parameter.
     576                 :   DeclPtrTy Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl,
     577              392:                                                           Depth, Position);
     578                 : 
     579                 :   // If there is a default value, parse it.
                       23: branch 1 taken
                      369: branch 2 taken
     580              392:   if (Tok.is(tok::equal)) {
     581               23:     SourceLocation EqualLoc = ConsumeToken();
     582                 : 
     583                 :     // C++ [temp.param]p15:
     584                 :     //   When parsing a default template-argument for a non-type
     585                 :     //   template-parameter, the first non-nested > is taken as the
     586                 :     //   end of the template-parameter-list rather than a greater-than
     587                 :     //   operator.
     588               23:     GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
     589                 : 
     590               23:     OwningExprResult DefaultArg = ParseAssignmentExpression();
                        0: branch 1 not taken
                       23: branch 2 taken
     591               23:     if (DefaultArg.isInvalid())
     592                0:       SkipUntil(tok::comma, tok::greater, true, true);
                       23: branch 1 taken
                        0: branch 2 not taken
     593               23:     else if (Param)
     594                 :       Actions.ActOnNonTypeTemplateParameterDefault(Param, EqualLoc,
     595               23:                                                    move(DefaultArg));
     596                 :   }
     597                 : 
     598              392:   return Param;
     599                 : }
     600                 : 
     601                 : /// \brief Parses a template-id that after the template name has
     602                 : /// already been parsed.
     603                 : ///
     604                 : /// This routine takes care of parsing the enclosed template argument
     605                 : /// list ('<' template-parameter-list [opt] '>') and placing the
     606                 : /// results into a form that can be transferred to semantic analysis.
     607                 : ///
     608                 : /// \param Template the template declaration produced by isTemplateName
     609                 : ///
     610                 : /// \param TemplateNameLoc the source location of the template name
     611                 : ///
     612                 : /// \param SS if non-NULL, the nested-name-specifier preceding the
     613                 : /// template name.
     614                 : ///
     615                 : /// \param ConsumeLastToken if true, then we will consume the last
     616                 : /// token that forms the template-id. Otherwise, we will leave the
     617                 : /// last token in the stream (e.g., so that it can be replaced with an
     618                 : /// annotation token).
     619                 : bool
     620                 : Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
     621                 :                                          SourceLocation TemplateNameLoc,
     622                 :                                          const CXXScopeSpec *SS,
     623                 :                                          bool ConsumeLastToken,
     624                 :                                          SourceLocation &LAngleLoc,
     625                 :                                          TemplateArgList &TemplateArgs,
     626             2548:                                          SourceLocation &RAngleLoc) {
                     2548: branch 1 taken
                        0: branch 2 not taken
     627             2548:   assert(Tok.is(tok::less) && "Must have already parsed the template-name");
     628                 : 
     629                 :   // Consume the '<'.
     630             2548:   LAngleLoc = ConsumeToken();
     631                 : 
     632                 :   // Parse the optional template-argument-list.
     633             2548:   bool Invalid = false;
     634                 :   {
     635             2548:     GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
                     2515: branch 1 taken
                       33: branch 2 taken
     636             2548:     if (Tok.isNot(tok::greater))
     637             2515:       Invalid = ParseTemplateArgumentList(TemplateArgs);
     638                 : 
                        3: branch 0 taken
                     2545: branch 1 taken
     639             2548:     if (Invalid) {
     640                 :       // Try to find the closing '>'.
     641                3:       SkipUntil(tok::greater, true, !ConsumeLastToken);
     642                 : 
     643                6:       return true;
                     2545: branch 1 taken
                        3: branch 2 taken
     644             2548:     }
     645                 :   }
     646                 : 
                       13: branch 1 taken
                     2532: branch 2 taken
                        2: branch 4 taken
                       11: branch 5 taken
                        2: branch 6 taken
                     2543: branch 7 taken
     647             2558:   if (Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater)) {
     648                2:     Diag(Tok.getLocation(), diag::err_expected_greater);
     649                2:     return true;
     650                 :   }
     651                 : 
     652                 :   // Determine the location of the '>' or '>>'. Only consume this
     653                 :   // token if the caller asked us to.
     654             2543:   RAngleLoc = Tok.getLocation();
     655                 : 
                       11: branch 1 taken
                     2532: branch 2 taken
     656             2543:   if (Tok.is(tok::greatergreater)) {
                        3: branch 1 taken
                        8: branch 2 taken
     657               11:     if (!getLang().CPlusPlus0x) {
     658                3:       const char *ReplaceStr = "> >";
                        3: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                        2: branch 7 taken
                        1: branch 8 taken
                        2: branch 9 taken
     659                3:       if (NextToken().is(tok::greater) || NextToken().is(tok::greatergreater))
     660                1:         ReplaceStr = "> > ";
     661                 : 
     662                 :       Diag(Tok.getLocation(), diag::err_two_right_angle_brackets_need_space)
     663                 :         << CodeModificationHint::CreateReplacement(
     664                3:                                  SourceRange(Tok.getLocation()), ReplaceStr);
     665                 :     }
     666                 : 
     667               11:     Tok.setKind(tok::greater);
                       11: branch 0 taken
                        0: branch 1 not taken
     668               11:     if (!ConsumeLastToken) {
     669                 :       // Since we're not supposed to consume the '>>' token, we need
     670                 :       // to insert a second '>' token after the first.
     671               11:       PP.EnterToken(Tok);
     672                 :     }
                        7: branch 0 taken
                     2525: branch 1 taken
     673             2532:   } else if (ConsumeLastToken)
     674                7:     ConsumeToken();
     675                 : 
     676             2543:   return false;
     677                 : }
     678                 : 
     679                 : /// \brief Replace the tokens that form a simple-template-id with an
     680                 : /// annotation token containing the complete template-id.
     681                 : ///
     682                 : /// The first token in the stream must be the name of a template that
     683                 : /// is followed by a '<'. This routine will parse the complete
     684                 : /// simple-template-id and replace the tokens with a single annotation
     685                 : /// token with one of two different kinds: if the template-id names a
     686                 : /// type (and \p AllowTypeAnnotation is true), the annotation token is
     687                 : /// a type annotation that includes the optional nested-name-specifier
     688                 : /// (\p SS). Otherwise, the annotation token is a template-id
     689                 : /// annotation that does not include the optional
     690                 : /// nested-name-specifier.
     691                 : ///
     692                 : /// \param Template  the declaration of the template named by the first
     693                 : /// token (an identifier), as returned from \c Action::isTemplateName().
     694                 : ///
     695                 : /// \param TemplateNameKind the kind of template that \p Template
     696                 : /// refers to, as returned from \c Action::isTemplateName().
     697                 : ///
     698                 : /// \param SS if non-NULL, the nested-name-specifier that precedes
     699                 : /// this template name.
     700                 : ///
     701                 : /// \param TemplateKWLoc if valid, specifies that this template-id
     702                 : /// annotation was preceded by the 'template' keyword and gives the
     703                 : /// location of that keyword. If invalid (the default), then this
     704                 : /// template-id was not preceded by a 'template' keyword.
     705                 : ///
     706                 : /// \param AllowTypeAnnotation if true (the default), then a
     707                 : /// simple-template-id that refers to a class template, template
     708                 : /// template parameter, or other template that produces a type will be
     709                 : /// replaced with a type annotation token. Otherwise, the
     710                 : /// simple-template-id is always replaced with a template-id
     711                 : /// annotation token.
     712                 : ///
     713                 : /// If an unrecoverable parse error occurs and no annotation token can be
     714                 : /// formed, this function returns true.
     715                 : ///
     716                 : bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
     717                 :                                      const CXXScopeSpec *SS,
     718                 :                                      UnqualifiedId &TemplateName,
     719                 :                                      SourceLocation TemplateKWLoc,
     720             2541:                                      bool AllowTypeAnnotation) {
                     2541: branch 1 taken
                        0: branch 2 not taken
     721             2541:   assert(getLang().CPlusPlus && "Can only annotate template-ids in C++");
     722                 :   assert(Template && Tok.is(tok::less) &&
                     2541: branch 1 taken
                        0: branch 2 not taken
                     2541: branch 4 taken
                        0: branch 5 not taken
     723             5082:          "Parser isn't at the beginning of a template-id");
     724                 : 
     725                 :   // Consume the template-name.
     726             2541:   SourceLocation TemplateNameLoc = TemplateName.getSourceRange().getBegin();
     727                 : 
     728                 :   // Parse the enclosed template argument list.
     729             2541:   SourceLocation LAngleLoc, RAngleLoc;
     730             2541:   TemplateArgList TemplateArgs;
     731                 :   bool Invalid = ParseTemplateIdAfterTemplateName(Template, 
     732                 :                                                   TemplateNameLoc,
     733                 :                                                   SS, false, LAngleLoc,
     734                 :                                                   TemplateArgs,
     735             2541:                                                   RAngleLoc);
     736                 : 
                        5: branch 0 taken
                     2536: branch 1 taken
     737             2541:   if (Invalid) {
     738                 :     // If we failed to parse the template ID but skipped ahead to a >, we're not
     739                 :     // going to be able to form a token annotation.  Eat the '>' if present.
                        3: branch 1 taken
                        2: branch 2 taken
     740                5:     if (Tok.is(tok::greater))
     741                3:       ConsumeToken();
     742                5:     return true;
     743                 :   }
     744                 : 
     745                 :   ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
     746             2536:                                      TemplateArgs.size());
     747                 : 
     748                 :   // Build the annotation token.
                     2270: branch 0 taken
                      266: branch 1 taken
                        0: branch 2 not taken
                     2270: branch 3 taken
     749             2536:   if (TNK == TNK_Type_template && AllowTypeAnnotation) {
     750                 :     Action::TypeResult Type
     751                 :       = Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
     752                 :                                     LAngleLoc, TemplateArgsPtr,
     753                0:                                     RAngleLoc);
                        0: branch 1 not taken
                        0: branch 2 not taken
     754                0:     if (Type.isInvalid()) {
     755                 :       // If we failed to parse the template ID but skipped ahead to a >, we're not
     756                 :       // going to be able to form a token annotation.  Eat the '>' if present.
                        0: branch 1 not taken
                        0: branch 2 not taken
     757                0:       if (Tok.is(tok::greater))
     758                0:         ConsumeToken();
     759                0:       return true;
     760                 :     }
     761                 : 
     762                0:     Tok.setKind(tok::annot_typename);
     763                0:     Tok.setAnnotationValue(Type.get());
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
     764                0:     if (SS && SS->isNotEmpty())
     765                0:       Tok.setLocation(SS->getBeginLoc());
                        0: branch 1 not taken
                        0: branch 2 not taken
     766                0:     else if (TemplateKWLoc.isValid())
     767                0:       Tok.setLocation(TemplateKWLoc);
     768                 :     else
     769                0:       Tok.setLocation(TemplateNameLoc);
     770                 :   } else {
     771                 :     // Build a template-id annotation token that can be processed
     772                 :     // later.
     773             2536:     Tok.setKind(tok::annot_template_id);
     774                 :     TemplateIdAnnotation *TemplateId
     775             2536:       = TemplateIdAnnotation::Allocate(TemplateArgs.size());
     776             2536:     TemplateId->TemplateNameLoc = TemplateNameLoc;
                     2534: branch 1 taken
                        2: branch 2 taken
     777             2536:     if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) {
     778             2534:       TemplateId->Name = TemplateName.Identifier;
     779             2534:       TemplateId->Operator = OO_None;
     780                 :     } else {
     781                2:       TemplateId->Name = 0;
     782                2:       TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
     783                 :     }
     784             2536:     TemplateId->Template = Template.getAs<void*>();
     785             2536:     TemplateId->Kind = TNK;
     786             2536:     TemplateId->LAngleLoc = LAngleLoc;
     787             2536:     TemplateId->RAngleLoc = RAngleLoc;
     788             2536:     ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
                     3132: branch 1 taken
                     2536: branch 2 taken
     789             5668:     for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
     790             3132:       Args[Arg] = TemplateArgs[Arg];
     791             2536:     Tok.setAnnotationValue(TemplateId);
                       44: branch 1 taken
                     2492: branch 2 taken
     792             2536:     if (TemplateKWLoc.isValid())
     793               44:       Tok.setLocation(TemplateKWLoc);
     794                 :     else
     795             2492:       Tok.setLocation(TemplateNameLoc);
     796                 : 
     797             2536:     TemplateArgsPtr.release();
     798                 :   }
     799                 : 
     800                 :   // Common fields for the annotation token
     801             2536:   Tok.setAnnotationEndLoc(RAngleLoc);
     802                 : 
     803                 :   // In case the tokens were cached, have Preprocessor replace them with the
     804                 :   // annotation token.
     805             2536:   PP.AnnotateCachedTokens(Tok);
     806             2536:   return false;
     807                 : }
     808                 : 
     809                 : /// \brief Replaces a template-id annotation token with a type
     810                 : /// annotation token.
     811                 : ///
     812                 : /// If there was a failure when forming the type from the template-id,
     813                 : /// a type annotation token will still be created, but will have a
     814                 : /// NULL type pointer to signify an error.
     815             1860: void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
                     1860: branch 1 taken
                        0: branch 2 not taken
     816             1860:   assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens");
     817                 : 
     818                 :   TemplateIdAnnotation *TemplateId
     819             1860:     = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
     820                 :   assert((TemplateId->Kind == TNK_Type_template ||
     821                 :           TemplateId->Kind == TNK_Dependent_template_name) &&
                       39: branch 0 taken
                     1821: branch 1 taken
                        0: branch 2 not taken
                       39: branch 3 taken
     822             1899:          "Only works for type and dependent templates");
     823                 : 
     824                 :   ASTTemplateArgsPtr TemplateArgsPtr(Actions,
     825                 :                                      TemplateId->getTemplateArgs(),
     826             1860:                                      TemplateId->NumArgs);
     827                 : 
     828                 :   Action::TypeResult Type
     829                 :     = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
     830                 :                                   TemplateId->TemplateNameLoc,
     831                 :                                   TemplateId->LAngleLoc,
     832                 :                                   TemplateArgsPtr,
     833             1860:                                   TemplateId->RAngleLoc);
     834                 :   // Create the new "type" annotation token.
     835             1860:   Tok.setKind(tok::annot_typename);
                       54: branch 1 taken
                     1806: branch 2 taken
     836             1860:   Tok.setAnnotationValue(Type.isInvalid()? 0 : Type.get());
                     1407: branch 0 taken
                      453: branch 1 taken
                      216: branch 3 taken
                     1191: branch 4 taken
                      216: branch 5 taken
                     1644: branch 6 taken
     837             1860:   if (SS && SS->isNotEmpty()) // it was a C++ qualified type name.
     838              216:     Tok.setLocation(SS->getBeginLoc());
     839                 :   // End location stays the same
     840                 : 
     841                 :   // Replace the template-id annotation token, and possible the scope-specifier
     842                 :   // that precedes it, with the typename annotation token.
     843             1860:   PP.AnnotateCachedTokens(Tok);
     844             1860:   TemplateId->Destroy();
     845             1860: }
     846                 : 
     847                 : /// \brief Determine whether the given token can end a template argument.
     848              200: static bool isEndOfTemplateArgument(Token Tok) {
     849                 :   return Tok.is(tok::comma) || Tok.is(tok::greater) || 
                      171: branch 1 taken
                       29: branch 2 taken
                       18: branch 4 taken
                      153: branch 5 taken
                        0: branch 7 not taken
                       18: branch 8 taken
     850              200:          Tok.is(tok::greatergreater);
     851                 : }
     852                 : 
     853                 : /// \brief Parse a C++ template template argument.
     854              566: ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
                      376: branch 1 taken
                      190: branch 2 taken
                      375: branch 4 taken
                        1: branch 5 taken
                      365: branch 7 taken
                       10: branch 8 taken
                      365: branch 9 taken
                      201: branch 10 taken
     855              566:   if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
     856                 :       !Tok.is(tok::annot_cxxscope))
     857              365:     return ParsedTemplateArgument();
     858                 : 
     859                 :   // C++0x [temp.arg.template]p1:
     860                 :   //   A template-argument for a template template-parameter shall be the name
     861                 :   //   of a class template or a template alias, expressed as id-expression.
     862                 :   //   
     863                 :   // We parse an id-expression that refers to a class template or template
     864                 :   // alias. The grammar we parse is:
     865                 :   //
     866                 :   //   nested-name-specifier[opt] template[opt] identifier
     867                 :   //
     868                 :   // followed by a token that terminates a template argument, such as ',', 
     869                 :   // '>', or (in some cases) '>>'.
     870              201:   CXXScopeSpec SS; // nested-name-specifier, if present
     871                 :   ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, 
     872              201:                                  /*EnteringContext=*/false);
     873                 :   
                       12: branch 1 taken
                      189: branch 2 taken
                        1: branch 4 taken
                       11: branch 5 taken
                        1: branch 6 taken
                      200: branch 7 taken
     874              201:   if (SS.isSet() && Tok.is(tok::kw_template)) {
     875                 :     // Parse the optional 'template' keyword following the 
     876                 :     // nested-name-specifier.
     877                1:     SourceLocation TemplateLoc = ConsumeToken();
     878                 :     
                        1: branch 1 taken
                        0: branch 2 not taken
     879                1:     if (Tok.is(tok::identifier)) {
     880                 :       // We appear to have a dependent template name.
     881                1:       UnqualifiedId Name;
     882                1:       Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
     883                1:       ConsumeToken(); // the identifier
     884                 :       
     885                 :       // If the next token signals the end of a template argument,
     886                 :       // then we have a dependent template name that could be a template
     887                 :       // template argument.
                        1: branch 1 taken
                        0: branch 2 not taken
     888                1:       if (isEndOfTemplateArgument(Tok)) {
     889                 :         TemplateTy Template
     890                 :         = Actions.ActOnDependentTemplateName(TemplateLoc, SS, Name, 
     891                 :                                              /*ObjectType=*/0,
     892                1:                                              /*EnteringContext=*/false);
                        1: branch 1 taken
                        0: branch 2 not taken
     893                1:         if (Template.get())
     894                2:           return ParsedTemplateArgument(SS, Template, Name.StartLocation);
                        0: branch 1 not taken
                        1: branch 2 taken
     895                1:       }
     896                 :     } 
                      199: branch 1 taken
                        1: branch 2 taken
     897              200:   } else if (Tok.is(tok::identifier)) {
     898                 :     // We may have a (non-dependent) template name.
     899              199:     TemplateTy Template;
     900              199:     UnqualifiedId Name;
     901              199:     Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
     902              199:     ConsumeToken(); // the identifier
     903                 :     
                      181: branch 1 taken
                       18: branch 2 taken
     904              199:     if (isEndOfTemplateArgument(Tok)) {
     905                 :       TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, Name, 
     906                 :                                                     /*ObjectType=*/0, 
     907                 :                                                     /*EnteringContext=*/false, 
     908              181:                                                     Template);
                      181: branch 0 taken
                        0: branch 1 not taken
                       45: branch 2 taken
                      136: branch 3 taken
     909              181:       if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) {
     910                 :         // We have an id-expression that refers to a class template or
     911                 :         // (C++0x) template alias. 
     912               90:         return ParsedTemplateArgument(SS, Template, Name.StartLocation);
     913                 :       }
                      154: branch 1 taken
                       45: branch 2 taken
     914              199:     }
     915                 :   }
     916                 :   
     917                 :   // We don't have a template template argument.  
     918              155:   return ParsedTemplateArgument();
     919                 : }
     920                 : 
     921                 : /// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
     922                 : ///
     923                 : ///       template-argument: [C++ 14.2]
     924                 : ///         constant-expression
     925                 : ///         type-id
     926                 : ///         id-expression
     927             3145: ParsedTemplateArgument Parser::ParseTemplateArgument() {
     928                 :   // C++ [temp.arg]p2:
     929                 :   //   In a template-argument, an ambiguity between a type-id and an
     930                 :   //   expression is resolved to a type-id, regardless of the form of
     931                 :   //   the corresponding template-parameter.
     932                 :   //
     933                 :   // Therefore, we initially try to parse a type-id.  
                     2593: branch 1 taken
                      552: branch 2 taken
     934             3145:   if (isCXXTypeId(TypeIdAsTemplateArgument)) {
     935             2593:     SourceLocation Loc = Tok.getLocation();
     936             2593:     TypeResult TypeArg = ParseTypeName();
                        2: branch 1 taken
                     2591: branch 2 taken
     937             2593:     if (TypeArg.isInvalid())
     938                2:       return ParsedTemplateArgument();
     939                 :     
     940                 :     return ParsedTemplateArgument(ParsedTemplateArgument::Type, TypeArg.get(), 
     941             2591:                                   Loc);
     942                 :   }
     943                 :   
     944                 :   // Try to parse a template template argument.
     945                 :   {
     946              552:     TentativeParsingAction TPA(*this);
     947                 : 
     948                 :     ParsedTemplateArgument TemplateTemplateArgument
     949              552:       = ParseTemplateTemplateArgument();
                       35: branch 1 taken
                      517: branch 2 taken
     950              552:     if (!TemplateTemplateArgument.isInvalid()) {
     951               35:       TPA.Commit();
     952               70:       return TemplateTemplateArgument;
     953                 :     }
     954                 :     
     955                 :     // Revert this tentative parse to parse a non-type template argument.
                      517: branch 2 taken
                       35: branch 3 taken
     956              517:     TPA.Revert();
     957                 :   }
     958                 :   
     959                 :   // Parse a non-type template argument. 
     960              517:   SourceLocation Loc = Tok.getLocation();
     961              517:   OwningExprResult ExprArg = ParseConstantExpression();
                      516: branch 1 taken
                        1: branch 2 taken
                        0: branch 4 not taken
                      516: branch 5 taken
                        1: branch 6 taken
                      516: branch 7 taken
     962             1033:   if (ExprArg.isInvalid() || !ExprArg.get())
     963                1:     return ParsedTemplateArgument();
     964                 : 
     965                 :   return ParsedTemplateArgument(ParsedTemplateArgument::NonType, 
     966              516:                                 ExprArg.release(), Loc);
     967                 : }
     968                 : 
     969                 : /// ParseTemplateArgumentList - Parse a C++ template-argument-list
     970                 : /// (C++ [temp.names]). Returns true if there was an error.
     971                 : ///
     972                 : ///       template-argument-list: [C++ 14.2]
     973                 : ///         template-argument
     974                 : ///         template-argument-list ',' template-argument
     975                 : bool
     976             3145: Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
     977              630:   while (true) {
     978             3145:     ParsedTemplateArgument Arg = ParseTemplateArgument();
                        3: branch 1 taken
                     3142: branch 2 taken
     979             3145:     if (Arg.isInvalid()) {
     980                3:       SkipUntil(tok::comma, tok::greater, true, true);
     981                3:       return true;
     982                 :     }
     983                 : 
     984                 :     // Save this template argument.
     985             3142:     TemplateArgs.push_back(Arg);
     986                 :       
     987                 :     // If the next token is a comma, consume it and keep reading
     988                 :     // arguments.
                      630: branch 1 taken
                     2512: branch 2 taken
     989             3142:     if (Tok.isNot(tok::comma)) break;
     990                 : 
     991                 :     // Consume the comma.
     992              630:     ConsumeToken();
     993                 :   }
     994                 : 
     995             2512:   return false;
     996                 : }
     997                 : 
     998                 : /// \brief Parse a C++ explicit template instantiation
     999                 : /// (C++ [temp.explicit]).
    1000                 : ///
    1001                 : ///       explicit-instantiation:
    1002                 : ///         'extern' [opt] 'template' declaration
    1003                 : ///
    1004                 : /// Note that the 'extern' is a GNU extension and C++0x feature.
    1005                 : Parser::DeclPtrTy
    1006                 : Parser::ParseExplicitInstantiation(SourceLocation ExternLoc,
    1007                 :                                    SourceLocation TemplateLoc,
    1008              377:                                    SourceLocation &DeclEnd) {
    1009                 :   return ParseSingleDeclarationAfterTemplate(Declarator::FileContext,
    1010                 :                                              ParsedTemplateInfo(ExternLoc,
    1011                 :                                                                 TemplateLoc),
    1012              377:                                              DeclEnd, AS_none);
    1013                 : }

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