Exemple #1
0
/// Lex - Lex and return a token from this macro stream.
///
bool TokenLexer::Lex(Token &Tok) {
  // Lexing off the end of the macro, pop this macro off the expansion stack.
  if (isAtEnd()) {
    // If this is a macro (not a token stream), mark the macro enabled now
    // that it is no longer being expanded.
    if (Macro) Macro->EnableMacro();

    Tok.startToken();
    Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
    Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace || NextTokGetsSpace);
    if (CurToken == 0)
      Tok.setFlag(Token::LeadingEmptyMacro);
    return PP.HandleEndOfTokenLexer(Tok);
  }

  SourceManager &SM = PP.getSourceManager();

  // If this is the first token of the expanded result, we inherit spacing
  // properties later.
  bool isFirstToken = CurToken == 0;

  // Get the next token to return.
  Tok = Tokens[CurToken++];

  bool TokenIsFromPaste = false;

  // If this token is followed by a token paste (##) operator, paste the tokens!
  // Note that ## is a normal token when not expanding a macro.
  if (!isAtEnd() && Macro &&
      (Tokens[CurToken].is(tok::hashhash) ||
       // Special processing of L#x macros in -fms-compatibility mode.
       // Microsoft compiler is able to form a wide string literal from
       // 'L#macro_arg' construct in a function-like macro.
       (PP.getLangOpts().MSVCCompat &&
        isWideStringLiteralFromMacro(Tok, Tokens[CurToken])))) {
    // When handling the microsoft /##/ extension, the final token is
    // returned by PasteTokens, not the pasted token.
    if (PasteTokens(Tok))
      return true;

    TokenIsFromPaste = true;
  }

  // The token's current location indicate where the token was lexed from.  We
  // need this information to compute the spelling of the token, but any
  // diagnostics for the expanded token should appear as if they came from
  // ExpansionLoc.  Pull this information together into a new SourceLocation
  // that captures all of this.
  if (ExpandLocStart.isValid() &&   // Don't do this for token streams.
      // Check that the token's location was not already set properly.
      SM.isBeforeInSLocAddrSpace(Tok.getLocation(), MacroStartSLocOffset)) {
    SourceLocation instLoc;
    if (Tok.is(tok::comment)) {
      instLoc = SM.createExpansionLoc(Tok.getLocation(),
                                      ExpandLocStart,
                                      ExpandLocEnd,
                                      Tok.getLength());
    } else {
      instLoc = getExpansionLocForMacroDefLoc(Tok.getLocation());
    }

    Tok.setLocation(instLoc);
  }

  // If this is the first token, set the lexical properties of the token to
  // match the lexical properties of the macro identifier.
  if (isFirstToken) {
    Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
    Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
  } else {
    // If this is not the first token, we may still need to pass through
    // leading whitespace if we've expanded a macro.
    if (AtStartOfLine) Tok.setFlag(Token::StartOfLine);
    if (HasLeadingSpace) Tok.setFlag(Token::LeadingSpace);
  }
  AtStartOfLine = false;
  HasLeadingSpace = false;

  // Handle recursive expansion!
  if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != nullptr) {
    // Change the kind of this identifier to the appropriate token kind, e.g.
    // turning "for" into a keyword.
    IdentifierInfo *II = Tok.getIdentifierInfo();
    Tok.setKind(II->getTokenID());

    // If this identifier was poisoned and from a paste, emit an error.  This
    // won't be handled by Preprocessor::HandleIdentifier because this is coming
    // from a macro expansion.
    if (II->isPoisoned() && TokenIsFromPaste) {
      PP.HandlePoisonedIdentifier(Tok);
    }

    if (!DisableMacroExpansion && II->isHandleIdentifierCase())
      return PP.HandleIdentifier(Tok);
  }

  // Otherwise, return a normal token.
  return true;
}
/// Lex - Lex and return a token from this macro stream.
///
void TokenLexer::Lex(Token &Tok) {
  // Lexing off the end of the macro, pop this macro off the expansion stack.
  if (isAtEnd()) {
    // If this is a macro (not a token stream), mark the macro enabled now
    // that it is no longer being expanded.
    if (Macro) Macro->EnableMacro();

    // Pop this context off the preprocessors lexer stack and get the next
    // token.  This will delete "this" so remember the PP instance var.
    Preprocessor &PPCache = PP;
    if (PP.HandleEndOfTokenLexer(Tok))
      return;

    // HandleEndOfTokenLexer may not return a token.  If it doesn't, lex
    // whatever is next.
    return PPCache.Lex(Tok);
  }

  SourceManager &SM = PP.getSourceManager();

  // If this is the first token of the expanded result, we inherit spacing
  // properties later.
  bool isFirstToken = CurToken == 0;

  // Get the next token to return.
  Tok = Tokens[CurToken++];

  bool TokenIsFromPaste = false;

  // If this token is followed by a token paste (##) operator, paste the tokens!
  // Note that ## is a normal token when not expanding a macro.
  if (!isAtEnd() && Tokens[CurToken].is(tok::hashhash) && Macro) {
    // When handling the microsoft /##/ extension, the final token is
    // returned by PasteTokens, not the pasted token.
    if (PasteTokens(Tok))
      return;

    TokenIsFromPaste = true;
  }

  // The token's current location indicate where the token was lexed from.  We
  // need this information to compute the spelling of the token, but any
  // diagnostics for the expanded token should appear as if they came from
  // ExpansionLoc.  Pull this information together into a new SourceLocation
  // that captures all of this.
  if (ExpandLocStart.isValid() &&   // Don't do this for token streams.
      // Check that the token's location was not already set properly.
      SM.isBeforeInSLocAddrSpace(Tok.getLocation(), MacroStartSLocOffset)) {
    SourceLocation instLoc;
    if (Tok.is(tok::comment)) {
      instLoc = SM.createExpansionLoc(Tok.getLocation(),
                                      ExpandLocStart,
                                      ExpandLocEnd,
                                      Tok.getLength());
    } else {
      instLoc = getExpansionLocForMacroDefLoc(Tok.getLocation());
    }

    Tok.setLocation(instLoc);
  }

  // If this is the first token, set the lexical properties of the token to
  // match the lexical properties of the macro identifier.
  if (isFirstToken) {
    Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
    Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
  }

  // Handle recursive expansion!
  if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != 0) {
    // Change the kind of this identifier to the appropriate token kind, e.g.
    // turning "for" into a keyword.
    IdentifierInfo *II = Tok.getIdentifierInfo();
    Tok.setKind(II->getTokenID());

    // If this identifier was poisoned and from a paste, emit an error.  This
    // won't be handled by Preprocessor::HandleIdentifier because this is coming
    // from a macro expansion.
    if (II->isPoisoned() && TokenIsFromPaste) {
      PP.HandlePoisonedIdentifier(Tok);
    }

    if (!DisableMacroExpansion && II->isHandleIdentifierCase())
      PP.HandleIdentifier(Tok);
  }

  // Otherwise, return a normal token.
}
Exemple #3
0
void
NasmLexer::LexIdentifier(Token* result, const char* cur_ptr, bool is_label)
{
    // Match [_$#@~.?A-Za-z0-9]*, we have already matched [_?@A-Za-z]
    unsigned int size;
    unsigned char ch = *cur_ptr++;
    while (isIdentifierBody(ch))
        ch = *cur_ptr++;
    --cur_ptr;  // Back up over the skipped character.

    // Fast path, no \ in identifier found.  '\' might be an escaped newline.
    if (ch != '\\')
    {
FinishIdentifier:
        const char* id_start = m_buf_ptr;
        if (is_label)
            FormTokenWithChars(result, cur_ptr, NasmToken::label);
        else
            FormTokenWithChars(result, cur_ptr, NasmToken::identifier);

        // If we are in raw mode, return this identifier raw.  There is no need
        // to look up identifier information or attempt to macro expand it.
        if (isLexingRawMode())
            return;

        // Fill in result.IdentifierInfo, looking up the identifier in the
        // identifier table.
        IdentifierInfo* ii = m_preproc->LookUpIdentifierInfo(result, id_start);
    
        // Change the kind of this identifier to the appropriate token kind,
        // e.g. turning "for" into a keyword.
        unsigned int newtokkind = ii->getTokenKind();
        if (newtokkind != Token::unknown)
            result->setKind(newtokkind);
#if 0    
        // Finally, now that we know we have an identifier, pass this off to
        // the preprocessor, which may macro expand it or something.
        if (ii->isHandleIdentifierCase())
            m_preproc->HandleIdentifier(result);
#endif
        ++num_identifier;
        return;
    }
  
    // Otherwise, \ in identifier found.  Enter slower path.
    ch = getCharAndSize(cur_ptr, &size);
    for (;;)
    {
        if (!isIdentifierBody(ch))
            goto FinishIdentifier;  // Found end of identifier.

        // Otherwise, this character is good, consume it.
        cur_ptr = ConsumeChar(cur_ptr, size, result);

        ch = getCharAndSize(cur_ptr, &size);
        while (isIdentifierBody(ch))
        {
            cur_ptr = ConsumeChar(cur_ptr, size, result);
            ch = getCharAndSize(cur_ptr, &size);
        }
    }
}