2006-06-18 13:43:12 +08:00
|
|
|
//===--- MacroExpander.cpp - Lex from a macro expansion -------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file was developed by Chris Lattner and is distributed under
|
|
|
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the MacroExpander interface.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Lex/MacroExpander.h"
|
|
|
|
#include "clang/Lex/MacroInfo.h"
|
|
|
|
#include "clang/Lex/Preprocessor.h"
|
2006-06-21 11:01:55 +08:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
2006-06-18 13:43:12 +08:00
|
|
|
using namespace llvm;
|
|
|
|
using namespace clang;
|
|
|
|
|
2006-07-09 08:45:31 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// MacroFormalArgs Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
MacroFormalArgs::MacroFormalArgs(const MacroInfo *MI) {
|
|
|
|
assert(MI->isFunctionLike() &&
|
|
|
|
"Can't have formal args for an object-like macro!");
|
|
|
|
// Reserve space for arguments to avoid reallocation.
|
|
|
|
unsigned NumArgs = MI->getNumArgs();
|
|
|
|
if (MI->isC99Varargs() || MI->isGNUVarargs())
|
|
|
|
NumArgs += 3; // Varargs can have more than this, just some guess.
|
|
|
|
|
|
|
|
ArgTokens.reserve(NumArgs);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// MacroExpander Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
MacroExpander::MacroExpander(LexerToken &Tok, MacroFormalArgs *Formals,
|
|
|
|
Preprocessor &pp)
|
|
|
|
: Macro(*Tok.getIdentifierInfo()->getMacroInfo()), FormalArgs(Formals),
|
|
|
|
PP(pp), CurToken(0),
|
2006-06-19 00:32:35 +08:00
|
|
|
InstantiateLoc(Tok.getLocation()),
|
2006-06-19 00:22:51 +08:00
|
|
|
AtStartOfLine(Tok.isAtStartOfLine()),
|
|
|
|
HasLeadingSpace(Tok.hasLeadingSpace()) {
|
|
|
|
}
|
|
|
|
|
2006-06-26 10:03:42 +08:00
|
|
|
|
2006-06-18 13:43:12 +08:00
|
|
|
/// Lex - Lex and return a token from this macro stream.
|
2006-06-19 00:22:51 +08:00
|
|
|
///
|
2006-06-18 14:48:37 +08:00
|
|
|
void MacroExpander::Lex(LexerToken &Tok) {
|
2006-06-18 13:43:12 +08:00
|
|
|
// Lexing off the end of the macro, pop this macro off the expansion stack.
|
|
|
|
if (CurToken == Macro.getNumTokens())
|
|
|
|
return PP.HandleEndOfMacro(Tok);
|
|
|
|
|
|
|
|
// Get the next token to return.
|
|
|
|
Tok = Macro.getReplacementToken(CurToken++);
|
|
|
|
|
2006-06-30 14:10:41 +08:00
|
|
|
// 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
|
|
|
|
// InstantiationLoc. Pull this information together into a new SourceLocation
|
|
|
|
// that captures all of this.
|
|
|
|
Tok.SetLocation(PP.getSourceManager().getInstantiationLoc(Tok.getLocation(),
|
|
|
|
InstantiateLoc));
|
2006-06-21 11:01:55 +08:00
|
|
|
|
2006-06-18 13:43:12 +08:00
|
|
|
// If this is the first token, set the lexical properties of the token to
|
|
|
|
// match the lexical properties of the macro identifier.
|
|
|
|
if (CurToken == 1) {
|
|
|
|
Tok.SetFlagValue(LexerToken::StartOfLine , AtStartOfLine);
|
|
|
|
Tok.SetFlagValue(LexerToken::LeadingSpace, HasLeadingSpace);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle recursive expansion!
|
|
|
|
if (Tok.getIdentifierInfo())
|
|
|
|
return PP.HandleIdentifier(Tok);
|
|
|
|
|
|
|
|
// Otherwise, return a normal token.
|
|
|
|
}
|
2006-07-11 12:02:46 +08:00
|
|
|
|
2006-07-11 13:04:55 +08:00
|
|
|
/// isNextTokenLParen - If the next token lexed will pop this macro off the
|
|
|
|
/// expansion stack, return 2. If the next unexpanded token is a '(', return
|
|
|
|
/// 1, otherwise return 0.
|
|
|
|
unsigned MacroExpander::isNextTokenLParen() const {
|
2006-07-11 12:02:46 +08:00
|
|
|
// Out of tokens?
|
2006-07-11 13:04:55 +08:00
|
|
|
if (CurToken == Macro.getNumTokens())
|
|
|
|
return 2;
|
2006-07-11 12:02:46 +08:00
|
|
|
|
2006-07-11 13:04:55 +08:00
|
|
|
return Macro.getReplacementToken(CurToken).getKind() == tok::l_paren;
|
2006-07-11 12:02:46 +08:00
|
|
|
}
|