blob: 8bb4ebfd5d02c5a5f2d81287e1b9f33de8716135 [file] [log] [blame]
//===--- MacroExpander.h - Lex from a macro expansion -----------*- C++ -*-===//
//
// 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 defines the MacroExpander and MacroArgs interfaces.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_MACROEXPANDER_H
#define LLVM_CLANG_MACROEXPANDER_H
#include "clang/Basic/SourceLocation.h"
#include <vector>
namespace clang {
class MacroInfo;
class Preprocessor;
class LexerToken;
/// MacroArgs - An instance of this class captures information about
/// the formal arguments specified to a function-like macro invocation.
class MacroArgs {
/// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
/// arguments. All of the actual argument tokens are allocated immediately
/// after the MacroArgs object in memory. This is all of the arguments
/// concatenated together, with 'EOF' markers at the end of each argument.
unsigned NumUnexpArgTokens;
/// PreExpArgTokens - Pre-expanded tokens for arguments that need them. Empty
/// if not yet computed. This includes the EOF marker at the end of the
/// stream.
std::vector<std::vector<LexerToken> > PreExpArgTokens;
/// StringifiedArgs - This contains arguments in 'stringified' form. If the
/// stringified form of an argument has not yet been computed, this is empty.
std::vector<LexerToken> StringifiedArgs;
/// VarargsElided - True if this is a C99 style varargs macro invocation and
/// there was no argument specified for the "..." argument. If the argument
/// was specified (even empty) or this isn't a C99 style varargs function, or
/// if in strict mode and the C99 varargs macro had only a ... argument, this
/// is false.
bool VarargsElided;
MacroArgs(unsigned NumToks, bool varargsElided)
: NumUnexpArgTokens(NumToks), VarargsElided(varargsElided) {}
~MacroArgs() {}
public:
/// MacroArgs ctor function - Create a new MacroArgs object with the specified
/// macro and argument info.
static MacroArgs *create(const MacroInfo *MI,
const LexerToken *UnexpArgTokens,
unsigned NumArgTokens, bool VarargsElided);
/// destroy - Destroy and deallocate the memory for this object.
///
void destroy();
/// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
/// by pre-expansion, return false. Otherwise, conservatively return true.
bool ArgNeedsPreexpansion(const LexerToken *ArgTok) const;
/// getUnexpArgument - Return a pointer to the first token of the unexpanded
/// token list for the specified formal.
///
const LexerToken *getUnexpArgument(unsigned Arg) const;
/// getArgLength - Given a pointer to an expanded or unexpanded argument,
/// return the number of tokens, not counting the EOF, that make up the
/// argument.
static unsigned getArgLength(const LexerToken *ArgPtr);
/// getPreExpArgument - Return the pre-expanded form of the specified
/// argument.
const std::vector<LexerToken> &
getPreExpArgument(unsigned Arg, Preprocessor &PP);
/// getStringifiedArgument - Compute, cache, and return the specified argument
/// that has been 'stringified' as required by the # operator.
const LexerToken &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP);
/// getNumArguments - Return the number of arguments passed into this macro
/// invocation.
unsigned getNumArguments() const { return NumUnexpArgTokens; }
/// isVarargsElidedUse - Return true if this is a C99 style varargs macro
/// invocation and there was no argument specified for the "..." argument. If
/// the argument was specified (even empty) or this isn't a C99 style varargs
/// function, or if in strict mode and the C99 varargs macro had only a ...
/// argument, this returns false.
bool isVarargsElidedUse() const { return VarargsElided; }
};
/// MacroExpander - This implements a lexer that returns token from a macro body
/// or token stream instead of lexing from a character buffer.
///
class MacroExpander {
/// Macro - The macro we are expanding from. This is null if expanding a
/// token stream.
///
MacroInfo *Macro;
/// ActualArgs - The actual arguments specified for a function-like macro, or
/// null. The MacroExpander owns the pointed-to object.
MacroArgs *ActualArgs;
/// PP - The current preprocessor object we are expanding for.
///
Preprocessor &PP;
/// MacroTokens - This is the pointer to an array of tokens that the macro is
/// defined to, with arguments expanded for function-like macros. If this is
/// a token stream, these are the tokens we are returning.
const LexerToken *MacroTokens;
/// NumMacroTokens - This is the length of the MacroTokens array.
///
unsigned NumMacroTokens;
/// CurToken - This is the next token that Lex will return.
///
unsigned CurToken;
/// InstantiateLoc - The source location where this macro was instantiated.
///
SourceLocation InstantiateLoc;
/// Lexical information about the expansion point of the macro: the identifier
/// that the macro expanded from had these properties.
bool AtStartOfLine, HasLeadingSpace;
MacroExpander(const MacroExpander&); // DO NOT IMPLEMENT
void operator=(const MacroExpander&); // DO NOT IMPLEMENT
public:
/// Create a macro expander for the specified macro with the specified actual
/// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
MacroExpander(LexerToken &Tok, MacroArgs *ActualArgs, Preprocessor &PP);
/// Create a macro expander for the specified token stream. This does not
/// take ownership of the specified token vector.
MacroExpander(const LexerToken *TokArray, unsigned NumToks, Preprocessor &PP);
~MacroExpander();
/// 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 isNextTokenLParen() const;
/// Lex - Lex and return a token from this macro stream.
void Lex(LexerToken &Tok);
private:
/// isAtEnd - Return true if the next lex call will pop this macro off the
/// include stack.
bool isAtEnd() const {
return CurToken == NumMacroTokens;
}
/// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
/// operator. Read the ## and RHS, and paste the LHS/RHS together. If there
/// are is another ## after it, chomp it iteratively. Return the result as
/// Tok.
void PasteTokens(LexerToken &Tok);
/// Expand the arguments of a function-like macro so that we can quickly
/// return preexpanded tokens from MacroTokens.
void ExpandFunctionArguments();
};
} // end namespace clang
#endif