zcov: / lib/Lex/TokenLexer.cpp


Files: 1 Branches Taken: 87.4% 159 / 182
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 182 / 182
Line Coverage: 99.5% 213 / 214


Programs: 2 Runs 3018


       1                 : //===--- TokenLexer.cpp - Lex from a token stream -------------------------===//
       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 TokenLexer interface.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/Lex/TokenLexer.h"
      15                 : #include "MacroArgs.h"
      16                 : #include "clang/Lex/MacroInfo.h"
      17                 : #include "clang/Lex/Preprocessor.h"
      18                 : #include "clang/Basic/SourceManager.h"
      19                 : #include "clang/Lex/LexDiagnostic.h"
      20                 : #include "llvm/ADT/SmallVector.h"
      21                 : using namespace clang;
      22                 : 
      23                 : 
      24                 : /// Create a TokenLexer for the specified macro with the specified actual
      25                 : /// arguments.  Note that this ctor takes ownership of the ActualArgs pointer.
      26             7515: void TokenLexer::Init(Token &Tok, SourceLocation ILEnd, MacroArgs *Actuals) {
      27                 :   // If the client is reusing a TokenLexer, make sure to free any memory
      28                 :   // associated with it.
      29             7515:   destroy();
      30                 : 
      31             7515:   Macro = PP.getMacroInfo(Tok.getIdentifierInfo());
      32             7515:   ActualArgs = Actuals;
      33             7515:   CurToken = 0;
      34                 : 
      35             7515:   InstantiateLocStart = Tok.getLocation();
      36             7515:   InstantiateLocEnd = ILEnd;
      37             7515:   AtStartOfLine = Tok.isAtStartOfLine();
      38             7515:   HasLeadingSpace = Tok.hasLeadingSpace();
      39             7515:   Tokens = &*Macro->tokens_begin();
      40             7515:   OwnsTokens = false;
      41             7515:   DisableMacroExpansion = false;
      42             7515:   NumTokens = Macro->tokens_end()-Macro->tokens_begin();
      43                 : 
      44                 :   // If this is a function-like macro, expand the arguments and change
      45                 :   // Tokens to point to the expanded tokens.
                     3934: branch 1 taken
                     3581: branch 2 taken
                     3918: branch 4 taken
                       16: branch 5 taken
                     3918: branch 6 taken
                     3597: branch 7 taken
      46             7515:   if (Macro->isFunctionLike() && Macro->getNumArgs())
      47             3918:     ExpandFunctionArguments();
      48                 : 
      49                 :   // Mark the macro as currently disabled, so that it is not recursively
      50                 :   // expanded.  The macro must be disabled only after argument pre-expansion of
      51                 :   // function-like macro arguments occurs.
      52             7515:   Macro->DisableMacro();
      53             7515: }
      54                 : 
      55                 : 
      56                 : 
      57                 : /// Create a TokenLexer for the specified token stream.  This does not
      58                 : /// take ownership of the specified token vector.
      59                 : void TokenLexer::Init(const Token *TokArray, unsigned NumToks,
      60             1753:                       bool disableMacroExpansion, bool ownsTokens) {
      61                 :   // If the client is reusing a TokenLexer, make sure to free any memory
      62                 :   // associated with it.
      63             1753:   destroy();
      64                 : 
      65             1753:   Macro = 0;
      66             1753:   ActualArgs = 0;
      67             1753:   Tokens = TokArray;
      68             1753:   OwnsTokens = ownsTokens;
      69             1753:   DisableMacroExpansion = disableMacroExpansion;
      70             1753:   NumTokens = NumToks;
      71             1753:   CurToken = 0;
      72             1753:   InstantiateLocStart = InstantiateLocEnd = SourceLocation();
      73             1753:   AtStartOfLine = false;
      74             1753:   HasLeadingSpace = false;
      75                 : 
      76                 :   // Set HasLeadingSpace/AtStartOfLine so that the first token will be
      77                 :   // returned unmodified.
                     1753: branch 0 taken
                        0: branch 1 not taken
      78             1753:   if (NumToks != 0) {
      79             1753:     AtStartOfLine   = TokArray[0].isAtStartOfLine();
      80             1753:     HasLeadingSpace = TokArray[0].hasLeadingSpace();
      81                 :   }
      82             1753: }
      83                 : 
      84                 : 
      85            10220: void TokenLexer::destroy() {
      86                 :   // If this was a function-like macro that actually uses its arguments, delete
      87                 :   // the expanded tokens.
                       18: branch 0 taken
                    10202: branch 1 taken
      88            10220:   if (OwnsTokens) {
                       18: branch 0 taken
                        0: branch 1 not taken
      89               18:     delete [] Tokens;
      90               18:     Tokens = 0;
      91               18:     OwnsTokens = false;
      92                 :   }
      93                 : 
      94                 :   // TokenLexer owns its formal arguments.
                     3934: branch 0 taken
                     6286: branch 1 taken
      95            10220:   if (ActualArgs) ActualArgs->destroy(PP);
      96            10220: }
      97                 : 
      98                 : /// Expand the arguments of a function-like macro so that we can quickly
      99                 : /// return preexpanded tokens from Tokens.
     100             3918: void TokenLexer::ExpandFunctionArguments() {
     101             3918:   llvm::SmallVector<Token, 128> ResultToks;
     102                 : 
     103                 :   // Loop through 'Tokens', expanding them into ResultToks.  Keep
     104                 :   // track of whether we change anything.  If not, no need to keep them.  If so,
     105                 :   // we install the newly expanded sequence as the new 'Tokens' list.
     106             3918:   bool MadeChange = false;
     107                 : 
     108                 :   // NextTokGetsSpace - When this is true, the next token appended to the
     109                 :   // output list will get a leading space, regardless of whether it had one to
     110                 :   // begin with or not.  This is used for placemarker support.
     111             3918:   bool NextTokGetsSpace = false;
     112                 : 
                    35632: branch 0 taken
                     3918: branch 1 taken
     113            39550:   for (unsigned i = 0, e = NumTokens; i != e; ++i) {
     114                 :     // If we found the stringify operator, get the argument stringified.  The
     115                 :     // preprocessor already verified that the following token is a macro name
     116                 :     // when the #define was parsed.
     117            35632:     const Token &CurTok = Tokens[i];
                    35327: branch 1 taken
                      305: branch 2 taken
                        1: branch 4 taken
                    35326: branch 5 taken
                      306: branch 6 taken
                    35326: branch 7 taken
     118            35632:     if (CurTok.is(tok::hash) || CurTok.is(tok::hashat)) {
     119              306:       int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo());
                        0: branch 0 not taken
                      306: branch 1 taken
     120              306:       assert(ArgNo != -1 && "Token following # is not an argument?");
     121                 : 
     122              306:       Token Res;
                      305: branch 1 taken
                        1: branch 2 taken
     123              306:       if (CurTok.is(tok::hash))  // Stringify
     124              305:         Res = ActualArgs->getStringifiedArgument(ArgNo, PP);
     125                 :       else {
     126                 :         // 'charify': don't bother caching these.
     127                 :         Res = MacroArgs::StringifyArgument(ActualArgs->getUnexpArgument(ArgNo),
     128                1:                                            PP, true);
     129                 :       }
     130                 : 
     131                 :       // The stringified/charified string leading space flag gets set to match
     132                 :       // the #/#@ operator.
                      172: branch 1 taken
                      134: branch 2 taken
                        0: branch 3 not taken
                      172: branch 4 taken
                      134: branch 5 taken
                      172: branch 6 taken
     133              306:       if (CurTok.hasLeadingSpace() || NextTokGetsSpace)
     134              134:         Res.setFlag(Token::LeadingSpace);
     135                 : 
     136              306:       ResultToks.push_back(Res);
     137              306:       MadeChange = true;
     138              306:       ++i;  // Skip arg name.
     139              306:       NextTokGetsSpace = false;
     140              306:       continue;
     141                 :     }
     142                 : 
     143                 :     // Otherwise, if this is not an argument token, just add the token to the
     144                 :     // output buffer.
     145            35326:     IdentifierInfo *II = CurTok.getIdentifierInfo();
                    12782: branch 0 taken
                    22544: branch 1 taken
     146            35326:     int ArgNo = II ? Macro->getArgumentNum(II) : -1;
                    28955: branch 0 taken
                     6371: branch 1 taken
     147            35326:     if (ArgNo == -1) {
     148                 :       // This isn't an argument, just add it.
     149            28955:       ResultToks.push_back(CurTok);
     150                 : 
                       24: branch 0 taken
                    28931: branch 1 taken
     151            28955:       if (NextTokGetsSpace) {
     152               24:         ResultToks.back().setFlag(Token::LeadingSpace);
     153               24:         NextTokGetsSpace = false;
     154                 :       }
     155            28955:       continue;
     156                 :     }
     157                 : 
     158                 :     // An argument is expanded somehow, the result is different than the
     159                 :     // input.
     160             6371:     MadeChange = true;
     161                 : 
     162                 :     // Otherwise, this is a use of the argument.  Find out if there is a paste
     163                 :     // (##) operator before or after the argument.
     164                 :     bool PasteBefore =
                     5168: branch 1 taken
                     1203: branch 2 taken
                     1300: branch 5 taken
                     3868: branch 6 taken
     165             6371:       !ResultToks.empty() && ResultToks.back().is(tok::hashhash);
                     5432: branch 0 taken
                      939: branch 1 taken
                     1157: branch 3 taken
                     4275: branch 4 taken
     166             6371:     bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash);
     167                 : 
     168                 :     // If it is not the LHS/RHS of a ## operator, we must pre-expand the
     169                 :     // argument and substitute the expanded tokens into the result.  This is
     170                 :     // C99 6.10.3.1p1.
                     5071: branch 0 taken
                     1300: branch 1 taken
                     4292: branch 2 taken
                      779: branch 3 taken
     171             6371:     if (!PasteBefore && !PasteAfter) {
     172                 :       const Token *ResultArgToks;
     173                 : 
     174                 :       // Only preexpand the argument if it could possibly need it.  This
     175                 :       // avoids some work in common cases.
     176             4292:       const Token *ArgTok = ActualArgs->getUnexpArgument(ArgNo);
                      567: branch 1 taken
                     3725: branch 2 taken
     177             4292:       if (ActualArgs->ArgNeedsPreexpansion(ArgTok, PP))
     178              567:         ResultArgToks = &ActualArgs->getPreExpArgument(ArgNo, Macro, PP)[0];
     179                 :       else
     180             3725:         ResultArgToks = ArgTok;  // Use non-preexpanded tokens.
     181                 : 
     182                 :       // If the arg token expanded into anything, append it.
                     4258: branch 1 taken
                       34: branch 2 taken
     183             4292:       if (ResultArgToks->isNot(tok::eof)) {
     184             4258:         unsigned FirstResult = ResultToks.size();
     185             4258:         unsigned NumToks = MacroArgs::getArgLength(ResultArgToks);
     186             4258:         ResultToks.append(ResultArgToks, ResultArgToks+NumToks);
     187                 : 
     188                 :         // If any tokens were substituted from the argument, the whitespace
     189                 :         // before the first token should match the whitespace of the arg
     190                 :         // identifier.
     191                 :         ResultToks[FirstResult].setFlagValue(Token::LeadingSpace,
     192                 :                                              CurTok.hasLeadingSpace() ||
                     2484: branch 1 taken
                     1774: branch 2 taken
                        0: branch 3 not taken
                     2484: branch 4 taken
     193             4258:                                              NextTokGetsSpace);
     194             4258:         NextTokGetsSpace = false;
     195                 :       } else {
     196                 :         // If this is an empty argument, and if there was whitespace before the
     197                 :         // formal token, make sure the next token gets whitespace before it.
     198               34:         NextTokGetsSpace = CurTok.hasLeadingSpace();
     199                 :       }
     200             4292:       continue;
     201                 :     }
     202                 : 
     203                 :     // Okay, we have a token that is either the LHS or RHS of a paste (##)
     204                 :     // argument.  It gets substituted as its non-pre-expanded tokens.
     205             2079:     const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo);
     206             2079:     unsigned NumToks = MacroArgs::getArgLength(ArgToks);
                     2016: branch 0 taken
                       63: branch 1 taken
     207             2079:     if (NumToks) {  // Not an empty argument?
     208                 :       // If this is the GNU ", ## __VA_ARG__" extension, and we just learned
     209                 :       // that __VA_ARG__ expands to multiple tokens, avoid a pasting error when
     210                 :       // the expander trys to paste ',' with the first token of the __VA_ARG__
     211                 :       // expansion.
                     1252: branch 0 taken
                      764: branch 1 taken
                     1252: branch 3 taken
                        0: branch 4 not taken
                       13: branch 8 taken
                     1239: branch 9 taken
                       13: branch 11 taken
                        0: branch 12 not taken
                       13: branch 14 taken
                        0: branch 15 not taken
                       13: branch 16 taken
                     2003: branch 17 taken
     212             2016:       if (PasteBefore && ResultToks.size() >= 2 &&
     213                 :           ResultToks[ResultToks.size()-2].is(tok::comma) &&
     214                 :           (unsigned)ArgNo == Macro->getNumArgs()-1 &&
     215                 :           Macro->isVariadic()) {
     216                 :         // Remove the paste operator, report use of the extension.
     217               13:         PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
     218               13:         ResultToks.pop_back();
     219                 :       }
     220                 : 
     221             2016:       ResultToks.append(ArgToks, ArgToks+NumToks);
     222                 : 
     223                 :       // If this token (the macro argument) was supposed to get leading
     224                 :       // whitespace, transfer this information onto the first token of the
     225                 :       // expansion.
     226                 :       //
     227                 :       // Do not do this if the paste operator occurs before the macro argument,
     228                 :       // as in "A ## MACROARG".  In valid code, the first token will get
     229                 :       // smooshed onto the preceding one anyway (forming AMACROARG).  In
     230                 :       // assembler-with-cpp mode, invalid pastes are allowed through: in this
     231                 :       // case, we do not want the extra whitespace to be added.  For example,
     232                 :       // we want ". ## foo" -> ".foo" not ". foo".
                      578: branch 1 taken
                     1438: branch 2 taken
                        0: branch 3 not taken
                      578: branch 4 taken
                      673: branch 5 taken
                      765: branch 6 taken
                      673: branch 7 taken
                     1343: branch 8 taken
     233             2016:       if ((CurTok.hasLeadingSpace() || NextTokGetsSpace) &&
     234                 :           !PasteBefore)
     235              673:         ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace);
     236                 : 
     237             2016:       NextTokGetsSpace = false;
     238             2016:       continue;
     239                 :     }
     240                 : 
     241                 :     // If an empty argument is on the LHS or RHS of a paste, the standard (C99
     242                 :     // 6.10.3.3p2,3) calls for a bunch of placemarker stuff to occur.  We
     243                 :     // implement this by eating ## operators when a LHS or RHS expands to
     244                 :     // empty.
     245               63:     NextTokGetsSpace |= CurTok.hasLeadingSpace();
                       23: branch 0 taken
                       40: branch 1 taken
     246               63:     if (PasteAfter) {
     247                 :       // Discard the argument token and skip (don't copy to the expansion
     248                 :       // buffer) the paste operator after it.
     249               23:       NextTokGetsSpace |= Tokens[i+1].hasLeadingSpace();
     250               23:       ++i;
     251               23:       continue;
     252                 :     }
     253                 : 
     254                 :     // If this is on the RHS of a paste operator, we've already copied the
     255                 :     // paste operator to the ResultToks list.  Remove it.
                       40: branch 0 taken
                        0: branch 1 not taken
                        0: branch 4 not taken
                       40: branch 5 taken
     256               40:     assert(PasteBefore && ResultToks.back().is(tok::hashhash));
     257               40:     NextTokGetsSpace |= ResultToks.back().hasLeadingSpace();
     258               40:     ResultToks.pop_back();
     259                 : 
     260                 :     // If this is the __VA_ARGS__ token, and if the argument wasn't provided,
     261                 :     // and if the macro had at least one real argument, and if the token before
     262                 :     // the ## was a comma, remove the comma.
                       40: branch 1 taken
                        0: branch 2 not taken
                       16: branch 4 taken
                       24: branch 5 taken
                       16: branch 7 taken
                        0: branch 8 not taken
                       16: branch 11 taken
                        0: branch 12 not taken
                       16: branch 13 taken
                       24: branch 14 taken
     263               40:     if ((unsigned)ArgNo == Macro->getNumArgs()-1 && // is __VA_ARGS__
     264                 :         ActualArgs->isVarargsElidedUse() &&       // Argument elided.
     265                 :         !ResultToks.empty() && ResultToks.back().is(tok::comma)) {
     266                 :       // Never add a space, even if the comma, ##, or arg had a space.
     267               16:       NextTokGetsSpace = false;
     268                 :       // Remove the paste operator, report use of the extension.
     269               16:       PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
     270               16:       ResultToks.pop_back();
     271                 :     }
     272                 :     continue;
     273                 :   }
     274                 : 
     275                 :   // If anything changed, install this as the new Tokens list.
                     3915: branch 0 taken
                        3: branch 1 taken
     276             3918:   if (MadeChange) {
                        0: branch 0 not taken
                     3915: branch 1 taken
     277             3915:     assert(!OwnsTokens && "This would leak if we already own the token list");
     278                 :     // This is deleted in the dtor.
     279             3915:     NumTokens = ResultToks.size();
     280             3915:     llvm::BumpPtrAllocator &Alloc = PP.getPreprocessorAllocator();
     281                 :     Token *Res =
     282                 :       static_cast<Token *>(Alloc.Allocate(sizeof(Token)*ResultToks.size(),
     283             3915:                                           llvm::alignof<Token>()));
                     3907: branch 0 taken
                        8: branch 1 taken
     284             3915:     if (NumTokens)
     285             3907:       memcpy(Res, &ResultToks[0], NumTokens*sizeof(Token));
     286             3915:     Tokens = Res;
     287                 : 
     288                 :     // The preprocessor bump pointer owns these tokens, not us.
     289             3915:     OwnsTokens = false;
     290             3918:   }
     291             3918: }
     292                 : 
     293                 : /// Lex - Lex and return a token from this macro stream.
     294                 : ///
     295            74493: void TokenLexer::Lex(Token &Tok) {
     296                 :   // Lexing off the end of the macro, pop this macro off the expansion stack.
                     8691: branch 1 taken
                    65802: branch 2 taken
     297            74493:   if (isAtEnd()) {
     298                 :     // If this is a macro (not a token stream), mark the macro enabled now
     299                 :     // that it is no longer being expanded.
                     7509: branch 0 taken
                     1182: branch 1 taken
     300             8691:     if (Macro) Macro->EnableMacro();
     301                 : 
     302                 :     // Pop this context off the preprocessors lexer stack and get the next
     303                 :     // token.  This will delete "this" so remember the PP instance var.
     304             8691:     Preprocessor &PPCache = PP;
                        0: branch 1 not taken
                     8691: branch 2 taken
     305             8691:     if (PP.HandleEndOfTokenLexer(Tok))
     306                0:       return;
     307                 : 
     308                 :     // HandleEndOfTokenLexer may not return a token.  If it doesn't, lex
     309                 :     // whatever is next.
     310             8691:     return PPCache.Lex(Tok);
     311                 :   }
     312                 : 
     313                 :   // If this is the first token of the expanded result, we inherit spacing
     314                 :   // properties later.
     315            65802:   bool isFirstToken = CurToken == 0;
     316                 : 
     317                 :   // Get the next token to return.
     318            65802:   Tok = Tokens[CurToken++];
     319                 : 
     320            65802:   bool TokenIsFromPaste = false;
     321                 : 
     322                 :   // If this token is followed by a token paste (##) operator, paste the tokens!
                    57195: branch 1 taken
                     8607: branch 2 taken
                     1215: branch 4 taken
                    55980: branch 5 taken
                     1215: branch 6 taken
                    64587: branch 7 taken
     323            65802:   if (!isAtEnd() && Tokens[CurToken].is(tok::hashhash)) {
     324                 :     // When handling the microsoft /##/ extension, the final token is
     325                 :     // returned by PasteTokens, not the pasted token.
                        2: branch 1 taken
                     1213: branch 2 taken
     326             1215:     if (PasteTokens(Tok))
     327                2:       return;
     328                 :     
     329             1213:     TokenIsFromPaste = true;
     330                 :   }
     331                 : 
     332                 :   // The token's current location indicate where the token was lexed from.  We
     333                 :   // need this information to compute the spelling of the token, but any
     334                 :   // diagnostics for the expanded token should appear as if they came from
     335                 :   // InstantiationLoc.  Pull this information together into a new SourceLocation
     336                 :   // that captures all of this.
                    51602: branch 1 taken
                    14198: branch 2 taken
     337            65800:   if (InstantiateLocStart.isValid()) {   // Don't do this for token streams.
     338            51602:     SourceManager &SM = PP.getSourceManager();
     339                 :     Tok.setLocation(SM.createInstantiationLoc(Tok.getLocation(),
     340                 :                                               InstantiateLocStart,
     341                 :                                               InstantiateLocEnd,
     342            51602:                                               Tok.getLength()));
     343                 :   }
     344                 : 
     345                 :   // If this is the first token, set the lexical properties of the token to
     346                 :   // match the lexical properties of the macro identifier.
                     9258: branch 0 taken
                    56542: branch 1 taken
     347            65800:   if (isFirstToken) {
     348             9258:     Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
     349             9258:     Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
     350                 :   }
     351                 : 
     352                 :   // Handle recursive expansion!
                    65776: branch 1 taken
                       24: branch 2 taken
                    17997: branch 4 taken
                    47779: branch 5 taken
                    17997: branch 6 taken
                    47803: branch 7 taken
     353            65800:   if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != 0) {
     354                 :     // Change the kind of this identifier to the appropriate token kind, e.g.
     355                 :     // turning "for" into a keyword.
     356            17997:     IdentifierInfo *II = Tok.getIdentifierInfo();
     357            17997:     Tok.setKind(II->getTokenID());
     358                 : 
     359                 :     // If this identifier was poisoned and from a paste, emit an error.  This
     360                 :     // won't be handled by Preprocessor::HandleIdentifier because this is coming
     361                 :     // from a macro expansion.
                        4: branch 1 taken
                    17993: branch 2 taken
                        2: branch 3 taken
                        2: branch 4 taken
                        2: branch 5 taken
                    17995: branch 6 taken
     362            17997:     if (II->isPoisoned() && TokenIsFromPaste) {
     363                 :       // We warn about __VA_ARGS__ with poisoning.
                        1: branch 1 taken
                        1: branch 2 taken
     364                2:       if (II->isStr("__VA_ARGS__"))
     365                1:         PP.Diag(Tok, diag::ext_pp_bad_vaargs_use);
     366                 :       else
     367                1:         PP.Diag(Tok, diag::err_pp_used_poisoned_id);
     368                 :     }
     369                 : 
                    14760: branch 0 taken
                     3237: branch 1 taken
                     5596: branch 3 taken
                     9164: branch 4 taken
                     5596: branch 5 taken
                    12401: branch 6 taken
     370            17997:     if (!DisableMacroExpansion && II->isHandleIdentifierCase())
     371             5596:       PP.HandleIdentifier(Tok);
     372                 :   }
     373                 : 
     374                 :   // Otherwise, return a normal token.
     375                 : }
     376                 : 
     377                 : /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
     378                 : /// operator.  Read the ## and RHS, and paste the LHS/RHS together.  If there
     379                 : /// are more ## after it, chomp them iteratively.  Return the result as Tok.
     380                 : /// If this returns true, the caller should immediately return the token.
     381             1215: bool TokenLexer::PasteTokens(Token &Tok) {
     382             1215:   llvm::SmallVector<char, 128> Buffer;
     383             1215:   const char *ResultTokStrPtr = 0;
                      936: branch 1 taken
                      647: branch 2 taken
                      370: branch 4 taken
                      566: branch 5 taken
                      370: branch 6 taken
                     1213: branch 7 taken
     384             1583:   do {
     385                 :     // Consume the ## operator.
     386             1585:     SourceLocation PasteOpLoc = Tokens[CurToken].getLocation();
     387             1585:     ++CurToken;
                     1585: branch 1 taken
                        0: branch 2 not taken
     388             1585:     assert(!isAtEnd() && "No token on the RHS of a paste operator!");
     389                 : 
     390                 :     // Get the RHS token.
     391             1585:     const Token &RHS = Tokens[CurToken];
     392                 : 
     393                 :     // Allocate space for the result token.  This is guaranteed to be enough for
     394                 :     // the two tokens.
     395             1585:     Buffer.resize(Tok.getLength() + RHS.getLength());
     396                 : 
     397                 :     // Get the spelling of the LHS token in Buffer.
     398             1585:     const char *BufPtr = &Buffer[0];
     399             1585:     unsigned LHSLen = PP.getSpelling(Tok, BufPtr);
                     1585: branch 1 taken
                        0: branch 2 not taken
     400             1585:     if (BufPtr != &Buffer[0])   // Really, we want the chars in Buffer!
     401             1585:       memcpy(&Buffer[0], BufPtr, LHSLen);
     402                 : 
     403             1585:     BufPtr = &Buffer[LHSLen];
     404             1585:     unsigned RHSLen = PP.getSpelling(RHS, BufPtr);
                     1585: branch 1 taken
                        0: branch 2 not taken
     405             1585:     if (BufPtr != &Buffer[LHSLen])   // Really, we want the chars in Buffer!
     406             1585:       memcpy(&Buffer[LHSLen], BufPtr, RHSLen);
     407                 : 
     408                 :     // Trim excess space.
     409             1585:     Buffer.resize(LHSLen+RHSLen);
     410                 : 
     411                 :     // Plop the pasted result (including the trailing newline and null) into a
     412                 :     // scratch buffer where we can lex it.
     413             1585:     Token ResultTokTmp;
     414             1585:     ResultTokTmp.startToken();
     415                 : 
     416                 :     // Claim that the tmp token is a string_literal so that we can get the
     417                 :     // character pointer back from CreateString in getLiteralData().
     418             1585:     ResultTokTmp.setKind(tok::string_literal);
     419             1585:     PP.CreateString(&Buffer[0], Buffer.size(), ResultTokTmp);
     420             1585:     SourceLocation ResultTokLoc = ResultTokTmp.getLocation();
     421             1585:     ResultTokStrPtr = ResultTokTmp.getLiteralData();
     422                 : 
     423                 :     // Lex the resultant pasted token into Result.
     424             1585:     Token Result;
     425                 : 
                     1073: branch 1 taken
                      512: branch 2 taken
                      452: branch 4 taken
                      621: branch 5 taken
                      452: branch 6 taken
                     1133: branch 7 taken
     426             1585:     if (Tok.is(tok::identifier) && RHS.is(tok::identifier)) {
     427                 :       // Common paste case: identifier+identifier = identifier.  Avoid creating
     428                 :       // a lexer and other overhead.
     429              452:       PP.IncrementPasteCounter(true);
     430              452:       Result.startToken();
     431              452:       Result.setKind(tok::identifier);
     432              452:       Result.setLocation(ResultTokLoc);
     433              452:       Result.setLength(LHSLen+RHSLen);
     434                 :     } else {
     435             1133:       PP.IncrementPasteCounter(false);
     436                 : 
     437                 :       assert(ResultTokLoc.isFileID() &&
                     1133: branch 1 taken
                        0: branch 2 not taken
     438             1133:              "Should be a raw location into scratch buffer");
     439             1133:       SourceManager &SourceMgr = PP.getSourceManager();
     440             1133:       FileID LocFileID = SourceMgr.getFileID(ResultTokLoc);
     441                 : 
     442             1133:       const char *ScratchBufStart = SourceMgr.getBufferData(LocFileID).first;
     443                 : 
     444                 :       // Make a lexer to lex this string from.  Lex just this one token.
     445                 :       // Make a lexer object so that we lex and expand the paste result.
     446                 :       Lexer TL(SourceMgr.getLocForStartOfFile(LocFileID),
     447                 :                PP.getLangOptions(), ScratchBufStart,
     448             1133:                ResultTokStrPtr, ResultTokStrPtr+LHSLen+RHSLen);
     449                 : 
     450                 :       // Lex a token in raw mode.  This way it won't look up identifiers
     451                 :       // automatically, lexing off the end will return an eof token, and
     452                 :       // warnings are disabled.  This returns true if the result token is the
     453                 :       // entire buffer.
     454             1133:       bool isInvalid = !TL.LexFromRawLexer(Result);
     455                 : 
     456                 :       // If we got an EOF token, we didn't form even ONE token.  For example, we
     457                 :       // did "/ ## /" to get "//".
     458             1133:       isInvalid |= Result.is(tok::eof);
     459                 : 
     460                 :       // If pasting the two tokens didn't form a full new token, this is an
     461                 :       // error.  This occurs with "x ## +"  and other stuff.  Return with Tok
     462                 :       // unmodified and with RHS as the next token to lex.
                       16: branch 0 taken
                     1117: branch 1 taken
     463             1133:       if (isInvalid) {
     464                 :         // Test for the Microsoft extension of /##/ turning into // here on the
     465                 :         // error path.
                        2: branch 1 taken
                       14: branch 2 taken
                        2: branch 4 taken
                        0: branch 5 not taken
                        2: branch 7 taken
                        0: branch 8 not taken
                        2: branch 9 taken
                       14: branch 10 taken
     466               16:         if (PP.getLangOptions().Microsoft && Tok.is(tok::slash) &&
     467                 :             RHS.is(tok::slash)) {
     468                2:           HandleMicrosoftCommentPaste(Tok);
     469                2:           return true;
     470                 :         }
     471                 : 
     472                 :         // Do not emit the warning when preprocessing assembler code.
                        6: branch 1 taken
                        8: branch 2 taken
     473               14:         if (!PP.getLangOptions().AsmPreprocessor) {
     474                 :           // Explicitly convert the token location to have proper instantiation
     475                 :           // information so that the user knows where it came from.
     476                6:           SourceManager &SM = PP.getSourceManager();
     477                 :           SourceLocation Loc =
     478                 :             SM.createInstantiationLoc(PasteOpLoc, InstantiateLocStart,
     479                6:                                       InstantiateLocEnd, 2);
     480                 :           PP.Diag(Loc, diag::err_pp_bad_paste)
     481                6:             << std::string(Buffer.begin(), Buffer.end());
     482                 :         }
     483                 : 
     484                 :         // Do not consume the RHS.
     485               14:         --CurToken;
     486                 :       }
     487                 : 
     488                 :       // Turn ## into 'unknown' to avoid # ## # from looking like a paste
     489                 :       // operator.
                        2: branch 1 taken
                     1129: branch 2 taken
     490             1131:       if (Result.is(tok::hashhash))
                     1131: branch 2 taken
                        2: branch 3 taken
     491                2:         Result.setKind(tok::unknown);
     492                 :     }
     493                 : 
     494                 :     // Transfer properties of the LHS over the the Result.
     495             1583:     Result.setFlagValue(Token::StartOfLine , Tok.isAtStartOfLine());
     496             1583:     Result.setFlagValue(Token::LeadingSpace, Tok.hasLeadingSpace());
     497                 : 
     498                 :     // Finally, replace LHS with the result, consume the RHS, and iterate.
     499             1583:     ++CurToken;
     500             1583:     Tok = Result;
     501                 :   } while (!isAtEnd() && Tokens[CurToken].is(tok::hashhash));
     502                 : 
     503                 :   // Now that we got the result token, it will be subject to expansion.  Since
     504                 :   // token pasting re-lexes the result token in raw mode, identifier information
     505                 :   // isn't looked up.  As such, if the result is an identifier, look up id info.
                      755: branch 1 taken
                      458: branch 2 taken
     506             1213:   if (Tok.is(tok::identifier)) {
     507                 :     // Look up the identifier info for the token.  We disabled identifier lookup
     508                 :     // by saying we're skipping contents, so we need to do this manually.
     509              755:     IdentifierInfo *II = PP.LookUpIdentifierInfo(Tok, ResultTokStrPtr);
     510              755:     Tok.setIdentifierInfo(II);
     511                 :   }
     512             1213:   return false;
     513                 : }
     514                 : 
     515                 : /// isNextTokenLParen - If the next token lexed will pop this macro off the
     516                 : /// expansion stack, return 2.  If the next unexpanded token is a '(', return
     517                 : /// 1, otherwise return 0.
     518             1936: unsigned TokenLexer::isNextTokenLParen() const {
     519                 :   // Out of tokens?
                       42: branch 1 taken
                     1894: branch 2 taken
     520             1936:   if (isAtEnd())
     521               42:     return 2;
     522             1894:   return Tokens[CurToken].is(tok::l_paren);
     523                 : }
     524                 : 
     525                 : 
     526                 : /// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes
     527                 : /// together to form a comment that comments out everything in the current
     528                 : /// macro, other active macros, and anything left on the current physical
     529                 : /// source line of the instantiated buffer.  Handle this by returning the
     530                 : /// first token on the next line.
     531                2: void TokenLexer::HandleMicrosoftCommentPaste(Token &Tok) {
     532                 :   // We 'comment out' the rest of this macro by just ignoring the rest of the
     533                 :   // tokens that have not been lexed yet, if any.
     534                 : 
     535                 :   // Since this must be a macro, mark the macro enabled now that it is no longer
     536                 :   // being expanded.
                        0: branch 0 not taken
                        2: branch 1 taken
     537                2:   assert(Macro && "Token streams can't paste comments");
     538                2:   Macro->EnableMacro();
     539                 : 
     540                2:   PP.HandleMicrosoftCommentPaste(Tok);
     541                2: }

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