zcov: / lib/Parse/Parser.cpp


Files: 1 Branches Taken: 79.9% 267 / 334
Generated: 2010-02-10 01:31 Branches Executed: 91.6% 306 / 334
Line Coverage: 87.8% 389 / 443


Programs: 2 Runs 3018


       1                 : //===--- Parser.cpp - C Language Family Parser ----------------------------===//
       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 Parser interfaces.
      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 "llvm/Support/raw_ostream.h"
      20                 : #include "RAIIObjectsForParser.h"
      21                 : #include "ParsePragma.h"
      22                 : using namespace clang;
      23                 : 
      24                 : /// \brief A comment handler that passes comments found by the preprocessor
      25                 : /// to the parser action.
                     2251: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
      26             2251: class ActionCommentHandler : public CommentHandler {
      27                 :   Action &Actions;
      28                 : 
      29                 : public:
      30             2251:   explicit ActionCommentHandler(Action &Actions) : Actions(Actions) { }
      31                 : 
      32            28241:   virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) {
      33            28241:     Actions.ActOnComment(Comment);
      34            28241:     return false;
      35                 :   }
      36                 : };
      37                 : 
      38             2251: Parser::Parser(Preprocessor &pp, Action &actions)
      39                 :   : CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
      40                 :     GreaterThanIsOperator(true), ColonIsSacred(false),
      41             2251:     TemplateParameterDepth(0) {
      42             2251:   Tok.setKind(tok::eof);
      43             2251:   CurScope = 0;
      44             2251:   NumCachedScopes = 0;
      45             2251:   ParenCount = BracketCount = BraceCount = 0;
      46             2251:   ObjCImpDecl = DeclPtrTy();
      47                 : 
      48                 :   // Add #pragma handlers. These are removed and destroyed in the
      49                 :   // destructor.
      50                 :   PackHandler.reset(new
      51             2251:           PragmaPackHandler(&PP.getIdentifierTable().get("pack"), actions));
      52             2251:   PP.AddPragmaHandler(0, PackHandler.get());
      53                 : 
      54                 :   UnusedHandler.reset(new
      55                 :           PragmaUnusedHandler(&PP.getIdentifierTable().get("unused"), actions,
      56             2251:                               *this));
      57             2251:   PP.AddPragmaHandler(0, UnusedHandler.get());
      58                 : 
      59                 :   WeakHandler.reset(new
      60             2251:           PragmaWeakHandler(&PP.getIdentifierTable().get("weak"), actions));
      61             2251:   PP.AddPragmaHandler(0, WeakHandler.get());
      62                 : 
      63             2251:   CommentHandler.reset(new ActionCommentHandler(actions));
      64             2251:   PP.AddCommentHandler(CommentHandler.get());
      65             2251: }
      66                 : 
      67                 : /// If a crash happens while the parser is active, print out a line indicating
      68                 : /// what the current token is.
      69                0: void PrettyStackTraceParserEntry::print(llvm::raw_ostream &OS) const {
      70                0:   const Token &Tok = P.getCurToken();
                        0: branch 1 not taken
                        0: branch 2 not taken
      71                0:   if (Tok.is(tok::eof)) {
      72                0:     OS << "<eof> parser at end of file\n";
      73                0:     return;
      74                 :   }
      75                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
      76                0:   if (Tok.getLocation().isInvalid()) {
      77                0:     OS << "<unknown> parser at unknown location\n";
      78                0:     return;
      79                 :   }
      80                 : 
      81                0:   const Preprocessor &PP = P.getPreprocessor();
      82                0:   Tok.getLocation().print(OS, PP.getSourceManager());
                        0: branch 1 not taken
                        0: branch 2 not taken
      83                0:   if (Tok.isAnnotation())
      84                0:     OS << ": at annotation token \n";
      85                 :   else
      86                0:     OS << ": current parser token '" << PP.getSpelling(Tok) << "'\n";
      87                 : }
      88                 : 
      89                 : 
      90             1162: DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
      91             1162:   return Diags.Report(FullSourceLoc(Loc, PP.getSourceManager()), DiagID);
      92                 : }
      93                 : 
      94              872: DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) {
      95              872:   return Diag(Tok.getLocation(), DiagID);
      96                 : }
      97                 : 
      98                 : /// \brief Emits a diagnostic suggesting parentheses surrounding a
      99                 : /// given range.
     100                 : ///
     101                 : /// \param Loc The location where we'll emit the diagnostic.
     102                 : /// \param Loc The kind of diagnostic to emit.
     103                 : /// \param ParenRange Source range enclosing code that should be parenthesized.
     104                 : void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK,
     105                3:                                 SourceRange ParenRange) {
     106                3:   SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd());
                        3: branch 2 taken
                        0: branch 3 not taken
                        0: branch 5 not taken
                        3: branch 6 taken
                        0: branch 7 not taken
                        3: branch 8 taken
     107                3:   if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) {
     108                 :     // We can't display the parentheses, so just dig the
     109                 :     // warning/error and return.
     110                0:     Diag(Loc, DK);
     111                0:     return;
     112                 :   }
     113                 : 
     114                 :   Diag(Loc, DK)
     115                 :     << CodeModificationHint::CreateInsertion(ParenRange.getBegin(), "(")
     116                3:     << CodeModificationHint::CreateInsertion(EndLoc, ")");
     117                 : }
     118                 : 
     119                 : /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
     120                 : /// this helper function matches and consumes the specified RHS token if
     121                 : /// present.  If not present, it emits the specified diagnostic indicating
     122                 : /// that the parser failed to match the RHS of the token at LHSLoc.  LHSName
     123                 : /// should be the name of the unmatched LHS token.
     124                 : SourceLocation Parser::MatchRHSPunctuation(tok::TokenKind RHSTok,
     125            25062:                                            SourceLocation LHSLoc) {
     126                 : 
                    25038: branch 1 taken
                       24: branch 2 taken
     127            25062:   if (Tok.is(RHSTok))
     128            25038:     return ConsumeAnyToken();
     129                 : 
     130               24:   SourceLocation R = Tok.getLocation();
     131               24:   const char *LHSName = "unknown";
     132               24:   diag::kind DID = diag::err_parse_error;
                        0: branch 0 not taken
                       13: branch 1 taken
                       10: branch 2 taken
                        1: branch 3 taken
                        0: branch 4 not taken
     133               24:   switch (RHSTok) {
     134                0:   default: break;
     135               13:   case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break;
     136               10:   case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break;
     137                1:   case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break;
     138                0:   case tok::greater:  LHSName = "<"; DID = diag::err_expected_greater; break;
     139                 :   }
     140               24:   Diag(Tok, DID);
     141               24:   Diag(LHSLoc, diag::note_matching) << LHSName;
     142               24:   SkipUntil(RHSTok);
     143               24:   return R;
     144                 : }
     145                 : 
     146                 : /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
     147                 : /// input.  If so, it is consumed and false is returned.
     148                 : ///
     149                 : /// If the input is malformed, this emits the specified diagnostic.  Next, if
     150                 : /// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
     151                 : /// returned.
     152                 : bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
     153            51168:                               const char *Msg, tok::TokenKind SkipToTok) {
                    51135: branch 1 taken
                       33: branch 2 taken
     154            51168:   if (Tok.is(ExpectedTok)) {
     155            51135:     ConsumeAnyToken();
     156            51135:     return false;
     157                 :   }
     158                 : 
     159               33:   const char *Spelling = 0;
     160               33:   SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
                       33: branch 1 taken
                        0: branch 2 not taken
                       33: branch 4 taken
                        0: branch 5 not taken
                       33: branch 6 taken
                        0: branch 7 not taken
     161               33:   if (EndLoc.isValid() &&
     162                 :       (Spelling = tok::getTokenSimpleSpelling(ExpectedTok))) {
     163                 :     // Show what code to insert to fix this problem.
     164                 :     Diag(EndLoc, DiagID)
     165                 :       << Msg
     166               33:       << CodeModificationHint::CreateInsertion(EndLoc, Spelling);
     167                 :   } else
     168                0:     Diag(Tok, DiagID) << Msg;
     169                 : 
                        9: branch 0 taken
                       24: branch 1 taken
     170               33:   if (SkipToTok != tok::unknown)
     171                9:     SkipUntil(SkipToTok);
     172               33:   return true;
     173                 : }
     174                 : 
     175                 : //===----------------------------------------------------------------------===//
     176                 : // Error recovery.
     177                 : //===----------------------------------------------------------------------===//
     178                 : 
     179                 : /// SkipUntil - Read tokens until we get to the specified token, then consume
     180                 : /// it (unless DontConsume is true).  Because we cannot guarantee that the
     181                 : /// token will ever occur, this skips to the next token, or to some likely
     182                 : /// good stopping point.  If StopAtSemi is true, skipping will stop at a ';'
     183                 : /// character.
     184                 : ///
     185                 : /// If SkipUntil finds the specified token, it returns true, otherwise it
     186                 : /// returns false.
     187                 : bool Parser::SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
     188             1772:                        bool StopAtSemi, bool DontConsume) {
     189                 :   // We always want this function to skip at least one token if the first token
     190                 :   // isn't T and if not at EOF.
     191             1772:   bool isFirstTokenSkipped = true;
     192             1348:   while (1) {
     193                 :     // If we found one of the tokens, stop and return true.
                     3147: branch 0 taken
                     1618: branch 1 taken
     194             4765:     for (unsigned i = 0; i != NumToks; ++i) {
                     1502: branch 1 taken
                     1645: branch 2 taken
     195             3147:       if (Tok.is(Toks[i])) {
                     1279: branch 0 taken
                      223: branch 1 taken
     196             1502:         if (DontConsume) {
     197                 :           // Noop, don't consume the token.
     198                 :         } else {
     199             1279:           ConsumeAnyToken();
     200                 :         }
     201             1502:         return true;
     202                 :       }
     203                 :     }
     204                 : 
                      119: branch 1 taken
                       74: branch 2 taken
                        9: branch 3 taken
                       19: branch 4 taken
                        5: branch 5 taken
                        1: branch 6 taken
                        2: branch 7 taken
                        4: branch 8 taken
                      163: branch 9 taken
                     1222: branch 10 taken
     205             1618:     switch (Tok.getKind()) {
     206                 :     case tok::eof:
     207                 :       // Ran out of tokens.
     208              119:       return false;
     209                 : 
     210                 :     case tok::l_paren:
     211                 :       // Recursively skip properly-nested parens.
     212               74:       ConsumeParen();
     213               74:       SkipUntil(tok::r_paren, false);
     214               74:       break;
     215                 :     case tok::l_square:
     216                 :       // Recursively skip properly-nested square brackets.
     217                9:       ConsumeBracket();
     218                9:       SkipUntil(tok::r_square, false);
     219                9:       break;
     220                 :     case tok::l_brace:
     221                 :       // Recursively skip properly-nested braces.
     222               19:       ConsumeBrace();
     223               19:       SkipUntil(tok::r_brace, false);
     224               19:       break;
     225                 : 
     226                 :     // Okay, we found a ']' or '}' or ')', which we think should be balanced.
     227                 :     // Since the user wasn't looking for this token (if they were, it would
     228                 :     // already be handled), this isn't balanced.  If there is a LHS token at a
     229                 :     // higher level, we will assume that this matches the unbalanced token
     230                 :     // and return it.  Otherwise, this is a spurious RHS token, which we skip.
     231                 :     case tok::r_paren:
                        4: branch 0 taken
                        1: branch 1 taken
                        3: branch 2 taken
                        1: branch 3 taken
     232                5:       if (ParenCount && !isFirstTokenSkipped)
     233                3:         return false;  // Matches something.
     234                2:       ConsumeParen();
     235                2:       break;
     236                 :     case tok::r_square:
                        0: branch 0 not taken
                        1: branch 1 taken
                        1: branch 2 taken
                        1: branch 3 taken
     237                1:       if (BracketCount && !isFirstTokenSkipped)
     238                0:         return false;  // Matches something.
     239                1:       ConsumeBracket();
     240                1:       break;
     241                 :     case tok::r_brace:
                        2: branch 0 taken
                        0: branch 1 not taken
                        1: branch 2 taken
                        1: branch 3 taken
     242                2:       if (BraceCount && !isFirstTokenSkipped)
     243                1:         return false;  // Matches something.
     244                1:       ConsumeBrace();
     245                1:       break;
     246                 : 
     247                 :     case tok::string_literal:
     248                 :     case tok::wide_string_literal:
     249                4:       ConsumeStringToken();
     250                4:       break;
     251                 :     case tok::semi:
                      147: branch 0 taken
                       16: branch 1 taken
     252              163:       if (StopAtSemi)
     253              147:         return false;
     254                 :       // FALL THROUGH.
     255                 :     default:
     256                 :       // Skip this token.
     257             1238:       ConsumeToken();
     258                 :       break;
     259                 :     }
     260             1348:     isFirstTokenSkipped = false;
     261                 :   }
     262                 : }
     263                 : 
     264                 : //===----------------------------------------------------------------------===//
     265                 : // Scope manipulation
     266                 : //===----------------------------------------------------------------------===//
     267                 : 
     268                 : /// EnterScope - Start a new scope.
     269            35381: void Parser::EnterScope(unsigned ScopeFlags) {
                    28845: branch 0 taken
                     6536: branch 1 taken
     270            35381:   if (NumCachedScopes) {
     271            28845:     Scope *N = ScopeCache[--NumCachedScopes];
     272            28845:     N->Init(CurScope, ScopeFlags);
     273            28845:     CurScope = N;
     274                 :   } else {
     275             6536:     CurScope = new Scope(CurScope, ScopeFlags);
     276                 :   }
     277            35381: }
     278                 : 
     279                 : /// ExitScope - Pop a scope off the scope stack.
     280            33145: void Parser::ExitScope() {
                        0: branch 0 not taken
                    33145: branch 1 taken
     281            33145:   assert(CurScope && "Scope imbalance!");
     282                 : 
     283                 :   // Inform the actions module that this scope is going away if there are any
     284                 :   // decls in it.
                    23726: branch 1 taken
                     9419: branch 2 taken
     285            33145:   if (!CurScope->decl_empty())
     286            23726:     Actions.ActOnPopScope(Tok.getLocation(), CurScope);
     287                 : 
     288            33145:   Scope *OldScope = CurScope;
     289            33145:   CurScope = OldScope->getParent();
     290                 : 
                        0: branch 0 not taken
                    33145: branch 1 taken
     291            33145:   if (NumCachedScopes == ScopeCacheSize)
                        0: branch 0 not taken
                        0: branch 1 not taken
     292                0:     delete OldScope;
     293                 :   else
     294            33145:     ScopeCache[NumCachedScopes++] = OldScope;
     295            33145: }
     296                 : 
     297                 : 
     298                 : 
     299                 : 
     300                 : //===----------------------------------------------------------------------===//
     301                 : // C99 6.9: External Definitions.
     302                 : //===----------------------------------------------------------------------===//
     303                 : 
     304             2251: Parser::~Parser() {
     305                 :   // If we still have scopes active, delete the scope tree.
                     2236: branch 0 taken
                       15: branch 1 taken
                     2236: branch 4 taken
                     2236: branch 5 taken
     306             2251:   delete CurScope;
     307                 : 
     308                 :   // Free the scope cache.
                     4300: branch 0 taken
                     2251: branch 1 taken
                     2251: branch 2 taken
                     2251: branch 3 taken
     309             6551:   for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
                     4300: branch 0 taken
                        0: branch 1 not taken
                     4300: branch 4 taken
                     4300: branch 5 taken
     310             4300:     delete ScopeCache[i];
     311                 : 
     312                 :   // Remove the pragma handlers we installed.
     313             2251:   PP.RemovePragmaHandler(0, PackHandler.get());
     314             2251:   PackHandler.reset();
     315             2251:   PP.RemovePragmaHandler(0, UnusedHandler.get());
     316             2251:   UnusedHandler.reset();
     317             2251:   PP.RemovePragmaHandler(0, WeakHandler.get());
     318             2251:   WeakHandler.reset();
     319             2251:   PP.RemoveCommentHandler(CommentHandler.get());
     320             2251: }
     321                 : 
     322                 : /// Initialize - Warm up the parser.
     323                 : ///
     324             2251: void Parser::Initialize() {
     325                 :   // Prime the lexer look-ahead.
     326             2251:   ConsumeToken();
     327                 : 
     328                 :   // Create the translation unit scope.  Install it as the current scope.
                        0: branch 0 not taken
                     2251: branch 1 taken
     329             2251:   assert(CurScope == 0 && "A scope is already active?");
     330             2251:   EnterScope(Scope::DeclScope);
     331             2251:   Actions.ActOnTranslationUnitScope(Tok.getLocation(), CurScope);
     332                 : 
                        5: branch 1 taken
                     2246: branch 2 taken
                        5: branch 4 taken
                        0: branch 5 not taken
                        5: branch 6 taken
                     2246: branch 7 taken
     333             2251:   if (Tok.is(tok::eof) &&
     334                 :       !getLang().CPlusPlus)  // Empty source file is an extension in C
     335                5:     Diag(Tok, diag::ext_empty_source_file);
     336                 : 
     337                 :   // Initialization for Objective-C context sensitive keywords recognition.
     338                 :   // Referenced in Parser::ParseObjCTypeQualifierList.
                      642: branch 1 taken
                     1609: branch 2 taken
     339             2251:   if (getLang().ObjC1) {
     340              642:     ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in");
     341              642:     ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out");
     342              642:     ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout");
     343              642:     ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway");
     344              642:     ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy");
     345              642:     ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref");
     346                 :   }
     347                 : 
     348             2251:   Ident_super = &PP.getIdentifierTable().get("super");
     349                 : 
                        6: branch 1 taken
                     2245: branch 2 taken
     350             2251:   if (getLang().AltiVec) {
     351                6:     Ident_vector = &PP.getIdentifierTable().get("vector");
     352                6:     Ident_pixel = &PP.getIdentifierTable().get("pixel");
     353                 :   }
     354             2251: }
     355                 : 
     356                 : /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
     357                 : /// action tells us to.  This returns true if the EOF was encountered.
     358            30521: bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
     359            30521:   Result = DeclGroupPtrTy();
                     2251: branch 1 taken
                    28270: branch 2 taken
     360            30521:   if (Tok.is(tok::eof)) {
     361             2251:     Actions.ActOnEndOfTranslationUnit();
     362             2251:     return true;
     363                 :   }
     364                 : 
     365            28270:   CXX0XAttributeList Attr;
                     1260: branch 1 taken
                    27010: branch 2 taken
                       12: branch 4 taken
                     1248: branch 5 taken
                       12: branch 6 taken
                    28258: branch 7 taken
     366            28270:   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
     367               12:     Attr = ParseCXX0XAttributes();
     368            28270:   Result = ParseExternalDeclaration(Attr);
     369            28270:   return false;
     370                 : }
     371                 : 
     372                 : /// ParseTranslationUnit:
     373                 : ///       translation-unit: [C99 6.9]
     374                 : ///         external-declaration
     375                 : ///         translation-unit external-declaration
     376               15: void Parser::ParseTranslationUnit() {
     377               15:   Initialize();
     378                 : 
     379               15:   DeclGroupPtrTy Res;
                      136: branch 1 taken
                       15: branch 2 taken
     380              151:   while (!ParseTopLevelDecl(Res))
     381                 :     /*parse them all*/;
     382                 : 
     383               15:   ExitScope();
                        0: branch 0 not taken
                       15: branch 1 taken
     384               15:   assert(CurScope == 0 && "Scope imbalance!");
     385               15: }
     386                 : 
     387                 : /// ParseExternalDeclaration:
     388                 : ///
     389                 : ///       external-declaration: [C99 6.9], declaration: [C++ dcl.dcl]
     390                 : ///         function-definition
     391                 : ///         declaration
     392                 : /// [C++0x] empty-declaration
     393                 : /// [GNU]   asm-definition
     394                 : /// [GNU]   __extension__ external-declaration
     395                 : /// [OBJC]  objc-class-definition
     396                 : /// [OBJC]  objc-class-declaration
     397                 : /// [OBJC]  objc-alias-declaration
     398                 : /// [OBJC]  objc-protocol-definition
     399                 : /// [OBJC]  objc-method-definition
     400                 : /// [OBJC]  @end
     401                 : /// [C++]   linkage-specification
     402                 : /// [GNU] asm-definition:
     403                 : ///         simple-asm-expr ';'
     404                 : ///
     405                 : /// [C++0x] empty-declaration:
     406                 : ///           ';'
     407                 : ///
     408                 : /// [C++0x/GNU] 'extern' 'template' declaration
     409            30933: Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) {
     410            30933:   DeclPtrTy SingleDecl;
                      134: branch 1 taken
                        2: branch 2 taken
                        2: branch 3 taken
                      471: branch 4 taken
                       17: branch 5 taken
                     4381: branch 6 taken
                      924: branch 7 taken
                        2: branch 8 taken
                     8794: branch 9 taken
                     1835: branch 10 taken
                    14371: branch 11 taken
     411            30933:   switch (Tok.getKind()) {
     412                 :   case tok::semi:
                      121: branch 1 taken
                       13: branch 2 taken
     413              134:     if (!getLang().CPlusPlus0x)
     414                 :       Diag(Tok, diag::ext_top_level_semi)
     415              121:         << CodeModificationHint::CreateRemoval(Tok.getLocation());
     416                 : 
     417              134:     ConsumeToken();
     418                 :     // TODO: Invoke action for top-level semicolon.
     419              134:     return DeclGroupPtrTy();
     420                 :   case tok::r_brace:
     421                2:     Diag(Tok, diag::err_expected_external_declaration);
     422                2:     ConsumeBrace();
     423                2:     return DeclGroupPtrTy();
     424                 :   case tok::eof:
     425                2:     Diag(Tok, diag::err_expected_external_declaration);
     426                2:     return DeclGroupPtrTy();
     427                 :   case tok::kw___extension__: {
     428                 :     // __extension__ silences extension warnings in the subexpression.
     429              471:     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
     430              471:     ConsumeToken();
     431              471:     return ParseExternalDeclaration(Attr);
     432                 :   }
     433                 :   case tok::kw_asm: {
                        1: branch 0 taken
                       16: branch 1 taken
     434               17:     if (Attr.HasAttr)
     435                 :       Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
     436                1:         << Attr.Range;
     437                 : 
     438               17:     OwningExprResult Result(ParseSimpleAsm());
     439                 : 
     440                 :     ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
     441               17:                      "top-level asm block");
     442                 : 
                        1: branch 1 taken
                       16: branch 2 taken
     443               17:     if (Result.isInvalid())
     444                2:       return DeclGroupPtrTy();
     445               16:     SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result));
                        1: branch 1 taken
                       16: branch 2 taken
     446               33:     break;
     447                 :   }
     448                 :   case tok::at:
     449                 :     // @ is not a legal token unless objc is enabled, no need to check for ObjC.
     450                 :     /// FIXME: ParseObjCAtDirectives should return a DeclGroup for things like
     451                 :     /// @class foo, bar;
     452             4381:     SingleDecl = ParseObjCAtDirectives();
     453             4381:     break;
     454                 :   case tok::minus:
     455                 :   case tok::plus:
                        0: branch 1 not taken
                      924: branch 2 taken
     456              924:     if (!getLang().ObjC1) {
     457                0:       Diag(Tok, diag::err_expected_external_declaration);
     458                0:       ConsumeToken();
     459                0:       return DeclGroupPtrTy();
     460                 :     }
     461              924:     SingleDecl = ParseObjCMethodDefinition();
     462              924:     break;
     463                 :   case tok::code_completion:
     464                 :       Actions.CodeCompleteOrdinaryName(CurScope, 
     465                 :                                    ObjCImpDecl? Action::CCC_ObjCImplementation
                        0: branch 1 not taken
                        2: branch 2 taken
     466                2:                                               : Action::CCC_Namespace);
     467                2:     ConsumeToken();
     468                2:     return ParseExternalDeclaration(Attr);
     469                 :   case tok::kw_using:
     470                 :   case tok::kw_namespace:
     471                 :   case tok::kw_typedef:
     472                 :   case tok::kw_template:
     473                 :   case tok::kw_export:    // As in 'export template'
     474                 :   case tok::kw_static_assert:
     475                 :     // A function definition cannot start with a these keywords.
     476                 :     {
     477             8794:       SourceLocation DeclEnd;
     478             8794:       return ParseDeclaration(Declarator::FileContext, DeclEnd, Attr);
     479                 :     }
     480                 :   case tok::kw_extern:
                      442: branch 1 taken
                     1393: branch 2 taken
                       18: branch 5 taken
                      424: branch 6 taken
                       18: branch 7 taken
                     1817: branch 8 taken
     481             1835:     if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) {
     482                 :       // Extern templates
     483               18:       SourceLocation ExternLoc = ConsumeToken();
     484               18:       SourceLocation TemplateLoc = ConsumeToken();
     485               18:       SourceLocation DeclEnd;
     486                 :       return Actions.ConvertDeclToDeclGroup(
     487               18:                   ParseExplicitInstantiation(ExternLoc, TemplateLoc, DeclEnd));
     488                 :     }
     489                 : 
     490                 :     // FIXME: Detect C++ linkage specifications here?
     491                 : 
     492                 :     // Fall through to handle other declarations or function definitions.
     493                 : 
     494                 :   default:
     495                 :     // We can't tell whether this is a function-definition or declaration yet.
     496            16188:     return ParseDeclarationOrFunctionDefinition(Attr.AttrList);
     497                 :   }
     498                 : 
     499                 :   // This routine returns a DeclGroup, if the thing we parsed only contains a
     500                 :   // single decl, convert it now.
     501             5321:   return Actions.ConvertDeclToDeclGroup(SingleDecl);
     502                 : }
     503                 : 
     504                 : /// \brief Determine whether the current token, if it occurs after a
     505                 : /// declarator, continues a declaration or declaration list.
     506            10680: bool Parser::isDeclarationAfterDeclarator() {
     507                 :   return Tok.is(tok::equal) ||      // int X()=  -> not a function def
     508                 :     Tok.is(tok::comma) ||           // int X(),  -> not a function def
     509                 :     Tok.is(tok::semi)  ||           // int X();  -> not a function def
     510                 :     Tok.is(tok::kw_asm) ||          // int X() __asm__ -> not a function def
     511                 :     Tok.is(tok::kw___attribute) ||  // int X() __attr__ -> not a function def
     512                 :     (getLang().CPlusPlus &&
                    10652: branch 1 taken
                       28: branch 2 taken
                    10645: branch 4 taken
                        7: branch 5 taken
                     8142: branch 7 taken
                     2503: branch 8 taken
                     8123: branch 10 taken
                       19: branch 11 taken
                     7214: branch 13 taken
                      909: branch 14 taken
                     2413: branch 16 taken
                     4801: branch 17 taken
                        0: branch 19 not taken
                     2413: branch 20 taken
     513            10680:      Tok.is(tok::l_paren));         // int X(0) -> not a function def [C++]
     514                 : }
     515                 : 
     516                 : /// \brief Determine whether the current token, if it occurs after a
     517                 : /// declarator, indicates the start of a function definition.
     518             7212: bool Parser::isStartOfFunctionDefinition() {
                     7150: branch 1 taken
                       62: branch 2 taken
     519             7212:   if (Tok.is(tok::l_brace))   // int X() {}
     520             7150:     return true;
     521                 :   
                       50: branch 1 taken
                       12: branch 2 taken
     522               62:   if (!getLang().CPlusPlus)
     523               50:     return isDeclarationSpecifier();   // int X(f) int f; {}
     524                 :   return Tok.is(tok::colon) ||         // X() : Base() {} (used for ctors)
                        5: branch 1 taken
                        7: branch 2 taken
                        5: branch 4 taken
                        0: branch 5 not taken
     525               12:          Tok.is(tok::kw_try);          // X() try { ... }
     526                 : }
     527                 : 
     528                 : /// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
     529                 : /// a declaration.  We can't tell which we have until we read up to the
     530                 : /// compound-statement in function-definition. TemplateParams, if
     531                 : /// non-NULL, provides the template parameters when we're parsing a
     532                 : /// C++ template-declaration.
     533                 : ///
     534                 : ///       function-definition: [C99 6.9.1]
     535                 : ///         decl-specs      declarator declaration-list[opt] compound-statement
     536                 : /// [C90] function-definition: [C99 6.7.1] - implicit int result
     537                 : /// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement
     538                 : ///
     539                 : ///       declaration: [C99 6.7]
     540                 : ///         declaration-specifiers init-declarator-list[opt] ';'
     541                 : /// [!C99]  init-declarator-list ';'                   [TODO: warn in c99 mode]
     542                 : /// [OMP]   threadprivate-directive                              [TODO]
     543                 : ///
     544                 : Parser::DeclGroupPtrTy
     545                 : Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
     546                 :                                              AttributeList *Attr,
     547            16271:                                              AccessSpecifier AS) {
     548                 :   // Parse the common declaration-specifiers piece.
                        2: branch 0 taken
                    16269: branch 1 taken
     549            16271:   if (Attr)
     550                2:     DS.AddAttributes(Attr);
     551                 : 
     552            16271:   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
     553                 : 
     554                 :   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
     555                 :   // declaration-specifiers init-declarator-list[opt] ';'
                     2983: branch 1 taken
                    13288: branch 2 taken
     556            16271:   if (Tok.is(tok::semi)) {
     557             2983:     ConsumeToken();
     558             2983:     DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
     559             2983:     DS.complete(TheDecl);
     560             2983:     return Actions.ConvertDeclToDeclGroup(TheDecl);
     561                 :   }
     562                 : 
     563                 :   // ObjC2 allows prefix attributes on class interfaces and protocols.
     564                 :   // FIXME: This still needs better diagnostics. We should only accept
     565                 :   // attributes here, no types, etc.
                     2833: branch 1 taken
                    10455: branch 2 taken
                       22: branch 4 taken
                     2811: branch 5 taken
                       22: branch 6 taken
                    13266: branch 7 taken
     566            13288:   if (getLang().ObjC2 && Tok.is(tok::at)) {
     567               22:     SourceLocation AtLoc = ConsumeToken(); // the "@"
                        7: branch 1 taken
                       15: branch 2 taken
                        2: branch 4 taken
                        5: branch 5 taken
                        2: branch 6 taken
                       20: branch 7 taken
     568               22:     if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
     569                 :         !Tok.isObjCAtKeyword(tok::objc_protocol)) {
     570                2:       Diag(Tok, diag::err_objc_unexpected_attr);
     571                2:       SkipUntil(tok::semi); // FIXME: better skip?
     572                2:       return DeclGroupPtrTy();
     573                 :     }
     574                 : 
     575               20:     DS.abort();
     576                 : 
     577               20:     const char *PrevSpec = 0;
     578                 :     unsigned DiagID;
                        1: branch 1 taken
                       19: branch 2 taken
     579               20:     if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID))
     580                1:       Diag(AtLoc, DiagID) << PrevSpec;
     581                 : 
     582               20:     DeclPtrTy TheDecl;
                        5: branch 1 taken
                       15: branch 2 taken
     583               20:     if (Tok.isObjCAtKeyword(tok::objc_protocol))
     584                5:       TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
     585                 :     else
     586               15:       TheDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
     587               20:     return Actions.ConvertDeclToDeclGroup(TheDecl);
     588                 :   }
     589                 : 
     590                 :   // If the declspec consisted only of 'extern' and we have a string
     591                 :   // literal following it, this must be a C++ linkage specifier like
     592                 :   // 'extern "C"'.
                      111: branch 1 taken
                    13155: branch 2 taken
                      111: branch 4 taken
                        0: branch 5 not taken
                      111: branch 7 taken
                        0: branch 8 not taken
                      111: branch 10 taken
                        0: branch 11 not taken
                      111: branch 12 taken
                    13155: branch 13 taken
     593            13266:   if (Tok.is(tok::string_literal) && getLang().CPlusPlus &&
     594                 :       DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
     595                 :       DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
     596              111:     DeclPtrTy TheDecl = ParseLinkage(DS, Declarator::FileContext);
     597              111:     return Actions.ConvertDeclToDeclGroup(TheDecl);
     598                 :   }
     599                 : 
     600            13155:   return ParseDeclGroup(DS, Declarator::FileContext, true);
     601                 : }
     602                 : 
     603                 : Parser::DeclGroupPtrTy
     604                 : Parser::ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
     605            16201:                                              AccessSpecifier AS) {
     606            16201:   ParsingDeclSpec DS(*this);
     607            16201:   return ParseDeclarationOrFunctionDefinition(DS, Attr, AS);
     608                 : }
     609                 : 
     610                 : /// ParseFunctionDefinition - We parsed and verified that the specified
     611                 : /// Declarator is well formed.  If this is a K&R-style function, read the
     612                 : /// parameters declaration-list, then start the compound-statement.
     613                 : ///
     614                 : ///       function-definition: [C99 6.9.1]
     615                 : ///         decl-specs      declarator declaration-list[opt] compound-statement
     616                 : /// [C90] function-definition: [C99 6.7.1] - implicit int result
     617                 : /// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement
     618                 : /// [C++] function-definition: [C++ 8.4]
     619                 : ///         decl-specifier-seq[opt] declarator ctor-initializer[opt]
     620                 : ///         function-body
     621                 : /// [C++] function-definition: [C++ 8.4]
     622                 : ///         decl-specifier-seq[opt] declarator function-try-block
     623                 : ///
     624                 : Parser::DeclPtrTy Parser::ParseFunctionDefinition(ParsingDeclarator &D,
     625             7210:                                      const ParsedTemplateInfo &TemplateInfo) {
     626             7210:   const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0);
     627                 :   assert(FnTypeInfo.Kind == DeclaratorChunk::Function &&
                        0: branch 0 not taken
                     7210: branch 1 taken
     628             7210:          "This isn't a function declarator!");
     629             7210:   const DeclaratorChunk::FunctionTypeInfo &FTI = FnTypeInfo.Fun;
     630                 : 
     631                 :   // If this is C90 and the declspecs were completely missing, fudge in an
     632                 :   // implicit int.  We do this here because this is the only place where
     633                 :   // declaration-specifiers are completely optional in the grammar.
                       53: branch 1 taken
                     7157: branch 2 taken
                        1: branch 5 taken
                       52: branch 6 taken
                        1: branch 7 taken
                     7209: branch 8 taken
     634             7210:   if (getLang().ImplicitInt && D.getDeclSpec().isEmpty()) {
     635                 :     const char *PrevSpec;
     636                 :     unsigned DiagID;
     637                 :     D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
     638                 :                                            D.getIdentifierLoc(),
     639                1:                                            PrevSpec, DiagID);
     640                1:     D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin());
     641                 :   }
     642                 : 
     643                 :   // If this declaration was formed with a K&R-style identifier list for the
     644                 :   // arguments, parse declarations for all of the args next.
     645                 :   // int foo(a,b) int a; float b; {}
                     1601: branch 0 taken
                     5609: branch 1 taken
                       53: branch 2 taken
                     1548: branch 3 taken
     646             7210:   if (!FTI.hasPrototype && FTI.NumArgs != 0)
     647               53:     ParseKNRParamDeclarations(D);
     648                 : 
     649                 :   // We should have either an opening brace or, in a C++ constructor,
     650                 :   // we may have a colon.
                       12: branch 1 taken
                     7198: branch 2 taken
                        5: branch 4 taken
                        7: branch 5 taken
                        0: branch 7 not taken
                        5: branch 8 taken
                        0: branch 9 not taken
                     7210: branch 10 taken
     651             7210:   if (Tok.isNot(tok::l_brace) && Tok.isNot(tok::colon) &&
     652                 :       Tok.isNot(tok::kw_try)) {
     653                0:     Diag(Tok, diag::err_expected_fn_body);
     654                 : 
     655                 :     // Skip over garbage, until we get to '{'.  Don't eat the '{'.
     656                0:     SkipUntil(tok::l_brace, true, true);
     657                 : 
     658                 :     // If we didn't find the '{', bail out.
                        0: branch 1 not taken
                        0: branch 2 not taken
     659                0:     if (Tok.isNot(tok::l_brace))
     660                0:       return DeclPtrTy();
     661                 :   }
     662                 : 
     663                 :   // Enter a scope for the function body.
     664             7210:   ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
     665                 : 
     666                 :   // Tell the actions module that we have entered a function definition with the
     667                 :   // specified Declarator for the function.
     668                 :   DeclPtrTy Res = TemplateInfo.TemplateParams?
     669                 :       Actions.ActOnStartOfFunctionTemplateDef(CurScope,
     670                 :                               Action::MultiTemplateParamsArg(Actions,
     671                 :                                           TemplateInfo.TemplateParams->data(),
     672                 :                                          TemplateInfo.TemplateParams->size()),
     673                 :                                               D)
                      297: branch 0 taken
                     6913: branch 1 taken
     674             7210:     : Actions.ActOnStartOfFunctionDef(CurScope, D);
     675                 : 
     676                 :   // Break out of the ParsingDeclarator context before we parse the body.
     677             7210:   D.complete(Res);
     678                 :   
     679                 :   // Break out of the ParsingDeclSpec context, too.  This const_cast is
     680                 :   // safe because we're always the sole owner.
     681             7210:   D.getMutableDeclSpec().abort();
     682                 : 
                        5: branch 1 taken
                     7205: branch 2 taken
     683             7210:   if (Tok.is(tok::kw_try))
     684                5:     return ParseFunctionTryBlock(Res);
     685                 : 
     686                 :   // If we have a colon, then we're probably parsing a C++
     687                 :   // ctor-initializer.
                        7: branch 1 taken
                     7198: branch 2 taken
     688             7205:   if (Tok.is(tok::colon))
     689                7:     ParseConstructorInitializer(Res);
     690                 :   else
     691             7198:     Actions.ActOnDefaultCtorInitializers(Res);
     692                 : 
     693             7205:   return ParseFunctionStatementBody(Res);
     694                 : }
     695                 : 
     696                 : /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
     697                 : /// types for a function with a K&R-style identifier list for arguments.
     698               53: void Parser::ParseKNRParamDeclarations(Declarator &D) {
     699                 :   // We know that the top-level of this declarator is a function.
     700               53:   DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
     701                 : 
     702                 :   // Enter function-declaration scope, limiting any declarators to the
     703                 :   // function prototype scope, including parameter declarators.
     704               53:   ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope|Scope::DeclScope);
     705                 : 
     706                 :   // Read all the argument declarations.
                       57: branch 2 taken
                        0: branch 3 not taken
                       57: branch 5 taken
                       53: branch 6 taken
     707              220:   while (isDeclarationSpecifier()) {
     708               57:     SourceLocation DSStart = Tok.getLocation();
     709                 : 
     710                 :     // Parse the common declaration-specifiers piece.
     711               57:     DeclSpec DS;
     712               57:     ParseDeclarationSpecifiers(DS);
     713                 : 
     714                 :     // C99 6.9.1p6: 'each declaration in the declaration list shall have at
     715                 :     // least one declarator'.
     716                 :     // NOTE: GCC just makes this an ext-warn.  It's not clear what it does with
     717                 :     // the declarations though.  It's trivial to ignore them, really hard to do
     718                 :     // anything else with them.
                        0: branch 1 not taken
                       57: branch 2 taken
     719               57:     if (Tok.is(tok::semi)) {
     720                0:       Diag(DSStart, diag::err_declaration_does_not_declare_param);
     721                0:       ConsumeToken();
     722                0:       continue;
     723                 :     }
     724                 : 
     725                 :     // C99 6.9.1p6: Declarations shall contain no storage-class specifiers other
     726                 :     // than register.
                        0: branch 1 not taken
                       57: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                       57: branch 7 taken
     727               57:     if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified &&
     728                 :         DS.getStorageClassSpec() != DeclSpec::SCS_register) {
     729                 :       Diag(DS.getStorageClassSpecLoc(),
     730                0:            diag::err_invalid_storage_class_in_func_decl);
     731                0:       DS.ClearStorageClassSpecs();
     732                 :     }
                        0: branch 1 not taken
                       57: branch 2 taken
     733               57:     if (DS.isThreadSpecified()) {
     734                 :       Diag(DS.getThreadSpecLoc(),
     735                0:            diag::err_invalid_storage_class_in_func_decl);
     736                0:       DS.ClearStorageClassSpecs();
     737                 :     }
     738                 : 
     739                 :     // Parse the first declarator attached to this declspec.
     740               57:     Declarator ParmDeclarator(DS, Declarator::KNRTypeListContext);
     741               57:     ParseDeclarator(ParmDeclarator);
     742                 : 
     743                 :     // Handle the full declarator list.
     744                8:     while (1) {
     745                 :       Action::AttrTy *AttrList;
     746                 :       // If attributes are present, parse them.
                        0: branch 1 not taken
                       65: branch 2 taken
     747               65:       if (Tok.is(tok::kw___attribute))
     748                 :         // FIXME: attach attributes too.
     749                0:         AttrList = ParseGNUAttributes();
     750                 : 
     751                 :       // Ask the actions module to compute the type for this declarator.
     752                 :       Action::DeclPtrTy Param =
     753               65:         Actions.ActOnParamDeclarator(CurScope, ParmDeclarator);
     754                 : 
                       60: branch 1 taken
                        5: branch 2 taken
                       59: branch 4 taken
                        1: branch 5 taken
                       59: branch 6 taken
                        6: branch 7 taken
     755               65:       if (Param &&
     756                 :           // A missing identifier has already been diagnosed.
     757                 :           ParmDeclarator.getIdentifier()) {
     758                 : 
     759                 :         // Scan the argument list looking for the correct param to apply this
     760                 :         // type.
     761               88:         for (unsigned i = 0; ; ++i) {
     762                 :           // C99 6.9.1p6: those declarators shall declare only identifiers from
     763                 :           // the identifier list.
                        0: branch 0 not taken
                       88: branch 1 taken
     764               88:           if (i == FTI.NumArgs) {
     765                 :             Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param)
     766                0:               << ParmDeclarator.getIdentifier();
     767                0:             break;
     768                 :           }
     769                 : 
                       59: branch 1 taken
                       29: branch 2 taken
     770               88:           if (FTI.ArgInfo[i].Ident == ParmDeclarator.getIdentifier()) {
     771                 :             // Reject redefinitions of parameters.
                        0: branch 1 not taken
                       59: branch 2 taken
     772               59:             if (FTI.ArgInfo[i].Param) {
     773                 :               Diag(ParmDeclarator.getIdentifierLoc(),
     774                 :                    diag::err_param_redefinition)
     775                0:                  << ParmDeclarator.getIdentifier();
     776                 :             } else {
     777               59:               FTI.ArgInfo[i].Param = Param;
     778                 :             }
     779               59:             break;
     780                 :           }
     781                 :         }
     782                 :       }
     783                 : 
     784                 :       // If we don't have a comma, it is either the end of the list (a ';') or
     785                 :       // an error, bail out.
                        8: branch 1 taken
                       57: branch 2 taken
     786               65:       if (Tok.isNot(tok::comma))
     787               57:         break;
     788                 : 
     789                 :       // Consume the comma.
     790                8:       ConsumeToken();
     791                 : 
     792                 :       // Parse the next declarator.
     793                8:       ParmDeclarator.clear();
     794                8:       ParseDeclarator(ParmDeclarator);
     795                 :     }
     796                 : 
                       57: branch 1 taken
                        0: branch 2 not taken
     797               57:     if (Tok.is(tok::semi)) {
     798               57:       ConsumeToken();
     799                 :     } else {
     800                0:       Diag(Tok, diag::err_parse_error);
     801                 :       // Skip to end of block or statement
     802                0:       SkipUntil(tok::semi, true);
                        0: branch 1 not taken
                        0: branch 2 not taken
     803                0:       if (Tok.is(tok::semi))
     804                0:         ConsumeToken();
     805                 :     }
     806                 :   }
     807                 : 
     808                 :   // The actions module must verify that all arguments were declared.
     809               53:   Actions.ActOnFinishKNRParamDeclarations(CurScope, D, Tok.getLocation());
     810               53: }
     811                 : 
     812                 : 
     813                 : /// ParseAsmStringLiteral - This is just a normal string-literal, but is not
     814                 : /// allowed to be a wide string, and is not subject to character translation.
     815                 : ///
     816                 : /// [GNU] asm-string-literal:
     817                 : ///         string-literal
     818                 : ///
     819              292: Parser::OwningExprResult Parser::ParseAsmStringLiteral() {
                        1: branch 1 taken
                      291: branch 2 taken
     820              292:   if (!isTokenStringLiteral()) {
     821                1:     Diag(Tok, diag::err_expected_string_literal);
     822                1:     return ExprError();
     823                 :   }
     824                 : 
     825              291:   OwningExprResult Res(ParseStringLiteralExpression());
                        0: branch 1 not taken
                      291: branch 2 taken
     826              291:   if (Res.isInvalid()) return move(Res);
     827                 : 
     828                 :   // TODO: Diagnose: wide string literal in 'asm'
     829                 : 
     830              291:   return move(Res);
     831                 : }
     832                 : 
     833                 : /// ParseSimpleAsm
     834                 : ///
     835                 : /// [GNU] simple-asm-expr:
     836                 : ///         'asm' '(' asm-string-literal ')'
     837                 : ///
     838               46: Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
                       46: branch 1 taken
                        0: branch 2 not taken
     839               46:   assert(Tok.is(tok::kw_asm) && "Not an asm!");
     840               46:   SourceLocation Loc = ConsumeToken();
     841                 : 
                        1: branch 1 taken
                       45: branch 2 taken
     842               46:   if (Tok.is(tok::kw_volatile)) {
     843                 :     // Remove from the end of 'asm' to the end of 'volatile'.
     844                 :     SourceRange RemovalRange(PP.getLocForEndOfToken(Loc),
     845                1:                              PP.getLocForEndOfToken(Tok.getLocation()));
     846                 : 
     847                 :     Diag(Tok, diag::warn_file_asm_volatile)
     848                1:       << CodeModificationHint::CreateRemoval(RemovalRange);
     849                1:     ConsumeToken();
     850                 :   }
     851                 : 
                        1: branch 1 taken
                       45: branch 2 taken
     852               46:   if (Tok.isNot(tok::l_paren)) {
     853                1:     Diag(Tok, diag::err_expected_lparen_after) << "asm";
     854                1:     return ExprError();
     855                 :   }
     856                 : 
     857               45:   Loc = ConsumeParen();
     858                 : 
     859               45:   OwningExprResult Result(ParseAsmStringLiteral());
     860                 : 
                        0: branch 1 not taken
                       45: branch 2 taken
     861               45:   if (Result.isInvalid()) {
     862                0:     SkipUntil(tok::r_paren, true, true);
                        0: branch 0 not taken
                        0: branch 1 not taken
     863                0:     if (EndLoc)
     864                0:       *EndLoc = Tok.getLocation();
     865                0:     ConsumeAnyToken();
     866                 :   } else {
     867               45:     Loc = MatchRHSPunctuation(tok::r_paren, Loc);
                       29: branch 0 taken
                       16: branch 1 taken
     868               45:     if (EndLoc)
     869               29:       *EndLoc = Loc;
     870                 :   }
     871                 : 
     872               45:   return move(Result);
     873                 : }
     874                 : 
     875                 : /// TryAnnotateTypeOrScopeToken - If the current token position is on a
     876                 : /// typename (possibly qualified in C++) or a C++ scope specifier not followed
     877                 : /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
     878                 : /// with a single annotation token representing the typename or C++ scope
     879                 : /// respectively.
     880                 : /// This simplifies handling of C++ scope specifiers and allows efficient
     881                 : /// backtracking without the need to re-parse and resolve nested-names and
     882                 : /// typenames.
     883                 : /// It will mainly be called when we expect to treat identifiers as typenames
     884                 : /// (if they are typenames). For example, in C we do not expect identifiers
     885                 : /// inside expressions to be treated as typenames so it will not be called
     886                 : /// for expressions in C.
     887                 : /// The benefit for C/ObjC is that a typename will be annotated and
     888                 : /// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
     889                 : /// will not be called twice, once to check whether we have a declaration
     890                 : /// specifier, and another one to get the actual type inside
     891                 : /// ParseDeclarationSpecifiers).
     892                 : ///
     893                 : /// This returns true if the token was annotated or an unrecoverable error
     894                 : /// occurs.
     895                 : ///
     896                 : /// Note that this routine emits an error if you call it with ::new or ::delete
     897                 : /// as the current tokens, so only call it in contexts where these are invalid.
     898            21887: bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) {
     899                 :   assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)
     900                 :           || Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)) &&
                      348: branch 1 taken
                    21539: branch 2 taken
                      324: branch 4 taken
                       24: branch 5 taken
                      163: branch 7 taken
                      161: branch 8 taken
                      163: branch 10 taken
                        0: branch 11 not taken
     901            21887:          "Cannot be a type or scope token!");
     902                 : 
                      161: branch 1 taken
                    21726: branch 2 taken
     903            21887:   if (Tok.is(tok::kw_typename)) {
     904                 :     // Parse a C++ typename-specifier, e.g., "typename T::type".
     905                 :     //
     906                 :     //   typename-specifier:
     907                 :     //     'typename' '::' [opt] nested-name-specifier identifier
     908                 :     //     'typename' '::' [opt] nested-name-specifier template [opt]
     909                 :     //            simple-template-id
     910              161:     SourceLocation TypenameLoc = ConsumeToken();
     911              161:     CXXScopeSpec SS;
     912                 :     bool HadNestedNameSpecifier
     913              161:       = ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
                        1: branch 0 taken
                      160: branch 1 taken
     914              161:     if (!HadNestedNameSpecifier) {
     915                1:       Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
     916                1:       return false;
     917                 :     }
     918                 : 
     919              160:     TypeResult Ty;
                      135: branch 1 taken
                       25: branch 2 taken
     920              160:     if (Tok.is(tok::identifier)) {
     921                 :       // FIXME: check whether the next token is '<', first!
     922                 :       Ty = Actions.ActOnTypenameType(TypenameLoc, SS, *Tok.getIdentifierInfo(),
     923              135:                                      Tok.getLocation());
                       23: branch 1 taken
                        2: branch 2 taken
     924               25:     } else if (Tok.is(tok::annot_template_id)) {
     925                 :       TemplateIdAnnotation *TemplateId
     926               23:         = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
                        0: branch 0 not taken
                       23: branch 1 taken
     927               23:       if (TemplateId->Kind == TNK_Function_template) {
     928                 :         Diag(Tok, diag::err_typename_refers_to_non_type_template)
     929                0:           << Tok.getAnnotationRange();
     930                0:         return false;
     931                 :       }
     932                 : 
     933               23:       AnnotateTemplateIdTokenAsType(0);
     934                 :       assert(Tok.is(tok::annot_typename) &&
                       23: branch 1 taken
                        0: branch 2 not taken
     935               23:              "AnnotateTemplateIdTokenAsType isn't working properly");
                       23: branch 1 taken
                        0: branch 2 not taken
     936               23:       if (Tok.getAnnotationValue())
     937                 :         Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(),
     938               23:                                        Tok.getAnnotationValue());
     939                 :       else
     940                0:         Ty = true;
     941                 :     } else {
     942                 :       Diag(Tok, diag::err_expected_type_name_after_typename)
     943                2:         << SS.getRange();
     944                2:       return false;
     945                 :     }
     946                 : 
     947              158:     SourceLocation EndLoc = Tok.getLastLoc();
     948              158:     Tok.setKind(tok::annot_typename);
                        3: branch 1 taken
                      155: branch 2 taken
     949              158:     Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get());
     950              158:     Tok.setAnnotationEndLoc(EndLoc);
     951              158:     Tok.setLocation(TypenameLoc);
     952              158:     PP.AnnotateCachedTokens(Tok);
     953              158:     return true;
     954                 :   }
     955                 : 
     956                 :   // Remembers whether the token was originally a scope annotation.
     957            21726:   bool wasScopeAnnotation = Tok.is(tok::annot_cxxscope);
     958                 : 
     959            21726:   CXXScopeSpec SS;
                     9765: branch 1 taken
                    11961: branch 2 taken
     960            21726:   if (getLang().CPlusPlus)
     961             9765:     ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext);
     962                 : 
                    21039: branch 1 taken
                      687: branch 2 taken
     963            21726:   if (Tok.is(tok::identifier)) {
     964                 :     // Determine whether the identifier is a type name.
                    11545: branch 0 taken
                     9494: branch 1 taken
     965            21039:     if (TypeTy *Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
     966            21039:                                          Tok.getLocation(), CurScope, &SS)) {
     967                 :       // This is a typename. Replace the current token in-place with an
     968                 :       // annotation type token.
     969            11545:       Tok.setKind(tok::annot_typename);
     970            11545:       Tok.setAnnotationValue(Ty);
     971            11545:       Tok.setAnnotationEndLoc(Tok.getLocation());
                      164: branch 1 taken
                    11381: branch 2 taken
     972            11545:       if (SS.isNotEmpty()) // it was a C++ qualified type name.
     973              164:         Tok.setLocation(SS.getBeginLoc());
     974                 : 
     975                 :       // In case the tokens were cached, have Preprocessor replace
     976                 :       // them with the annotation token.
     977            11545:       PP.AnnotateCachedTokens(Tok);
     978            11545:       return true;
     979                 :     }
     980                 : 
                     4594: branch 1 taken
                     4900: branch 2 taken
     981             9494:     if (!getLang().CPlusPlus) {
     982                 :       // If we're in C, we can't have :: tokens at all (the lexer won't return
     983                 :       // them).  If the identifier is not a type, then it can't be scope either,
     984                 :       // just early exit.
     985             4594:       return false;
     986                 :     }
     987                 : 
     988                 :     // If this is a template-id, annotate with a template-id or type token.
                      171: branch 2 taken
                     4729: branch 3 taken
     989             4900:     if (NextToken().is(tok::less)) {
     990              171:       TemplateTy Template;
     991              171:       UnqualifiedId TemplateName;
     992              171:       TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
                        0: branch 0 not taken
                      171: branch 1 taken
     993              171:       if (TemplateNameKind TNK
     994                 :             = Actions.isTemplateName(CurScope, SS, TemplateName, 
     995                 :                                      /*ObjectType=*/0, EnteringContext,
     996              171:                                      Template)) {
     997                 :         // Consume the identifier.
     998                0:         ConsumeToken();
                        0: branch 2 not taken
                        0: branch 3 not taken
     999                0:         if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName)) {
    1000                 :           // If an unrecoverable error occurred, we need to return true here,
    1001                 :           // because the token stream is in a damaged state.  We may not return
    1002                 :           // a valid identifier.
    1003                0:           return Tok.isNot(tok::identifier);
    1004                 :         }
                      171: branch 1 taken
                        0: branch 2 not taken
    1005              171:       }
    1006                 :     }
    1007                 : 
    1008                 :     // The current token, which is either an identifier or a
    1009                 :     // template-id, is not part of the annotation. Fall through to
    1010                 :     // push that token back into the stream and complete the C++ scope
    1011                 :     // specifier annotation.
    1012                 :   }
    1013                 : 
                      610: branch 1 taken
                     4977: branch 2 taken
    1014             5587:   if (Tok.is(tok::annot_template_id)) {
    1015                 :     TemplateIdAnnotation *TemplateId
    1016              610:       = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
                      479: branch 0 taken
                      131: branch 1 taken
    1017              610:     if (TemplateId->Kind == TNK_Type_template) {
    1018                 :       // A template-id that refers to a type was parsed into a
    1019                 :       // template-id annotation in a context where we weren't allowed
    1020                 :       // to produce a type annotation token. Update the template-id
    1021                 :       // annotation token to a type annotation token now.
    1022              479:       AnnotateTemplateIdTokenAsType(&SS);
    1023              479:       return true;
    1024                 :     }
    1025                 :   }
    1026                 : 
                     4363: branch 1 taken
                      745: branch 2 taken
    1027             5108:   if (SS.isEmpty())
                      124: branch 1 taken
                     4239: branch 2 taken
                      119: branch 4 taken
                        5: branch 5 taken
    1028             4363:     return Tok.isNot(tok::identifier) && Tok.isNot(tok::coloncolon);
    1029                 : 
    1030                 :   // A C++ scope specifier that isn't followed by a typename.
    1031                 :   // Push the current token back into the token stream (or revert it if it is
    1032                 :   // cached) and use an annotation scope token for current token.
                       39: branch 1 taken
                      706: branch 2 taken
    1033              745:   if (PP.isBacktrackEnabled())
    1034               39:     PP.RevertCachedTokens(1);
    1035                 :   else
    1036              706:     PP.EnterToken(Tok);
    1037              745:   Tok.setKind(tok::annot_cxxscope);
    1038              745:   Tok.setAnnotationValue(SS.getScopeRep());
    1039              745:   Tok.setAnnotationRange(SS.getRange());
    1040                 : 
    1041                 :   // In case the tokens were cached, have Preprocessor replace them
    1042                 :   // with the annotation token.  We don't need to do this if we've
    1043                 :   // just reverted back to the state we were in before being called.
                      590: branch 0 taken
                      155: branch 1 taken
    1044              745:   if (!wasScopeAnnotation)
    1045              590:     PP.AnnotateCachedTokens(Tok);
    1046              745:   return true;
    1047                 : }
    1048                 : 
    1049                 : /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
    1050                 : /// annotates C++ scope specifiers and template-ids.  This returns
    1051                 : /// true if the token was annotated or there was an error that could not be
    1052                 : /// recovered from.
    1053                 : ///
    1054                 : /// Note that this routine emits an error if you call it with ::new or ::delete
    1055                 : /// as the current tokens, so only call it in contexts where these are invalid.
    1056            17434: bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
    1057                 :   assert(getLang().CPlusPlus &&
                    17434: branch 1 taken
                        0: branch 2 not taken
    1058            17434:          "Call sites of this function should be guarded by checking for C++");
    1059                 :   assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
                       24: branch 1 taken
                    17410: branch 2 taken
                       24: branch 4 taken
                        0: branch 5 not taken
    1060            17458:          "Cannot be a type or scope token!");
    1061                 : 
    1062            17434:   CXXScopeSpec SS;
                    16675: branch 1 taken
                      759: branch 2 taken
    1063            17434:   if (!ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext))
    1064                 :     // If the token left behind is not an identifier, we either had an error or
    1065                 :     // successfully turned it into an annotation token.
    1066            16675:     return Tok.isNot(tok::identifier);
    1067                 : 
    1068                 :   // Push the current token back into the token stream (or revert it if it is
    1069                 :   // cached) and use an annotation scope token for current token.
                       50: branch 1 taken
                      709: branch 2 taken
    1070              759:   if (PP.isBacktrackEnabled())
    1071               50:     PP.RevertCachedTokens(1);
    1072                 :   else
    1073              709:     PP.EnterToken(Tok);
    1074              759:   Tok.setKind(tok::annot_cxxscope);
    1075              759:   Tok.setAnnotationValue(SS.getScopeRep());
    1076              759:   Tok.setAnnotationRange(SS.getRange());
    1077                 : 
    1078                 :   // In case the tokens were cached, have Preprocessor replace them with the
    1079                 :   // annotation token.
    1080              759:   PP.AnnotateCachedTokens(Tok);
    1081              759:   return true;
    1082                 : }
    1083                 : 
    1084                 : // Anchor the Parser::FieldCallback vtable to this translation unit.
    1085                 : // We use a spurious method instead of the destructor because
    1086                 : // destroying FieldCallbacks can actually be slightly
    1087                 : // performance-sensitive.
    1088                0: void Parser::FieldCallback::_anchor() {
    1089                0: }

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