blob: f003f4618f6e099d0b41dcb43415c4bfac5fe0a0 [file] [log] [blame]
Chris Lattner22eb9722006-06-18 05:43:12 +00001//===--- MacroExpander.cpp - Lex from a macro expansion -------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the MacroExpander interface.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Lex/MacroExpander.h"
15#include "clang/Lex/MacroInfo.h"
16#include "clang/Lex/Preprocessor.h"
Chris Lattner30709b032006-06-21 03:01:55 +000017#include "clang/Basic/SourceManager.h"
Chris Lattner22eb9722006-06-18 05:43:12 +000018using namespace llvm;
19using namespace clang;
20
Chris Lattner78186052006-07-09 00:45:31 +000021//===----------------------------------------------------------------------===//
22// MacroFormalArgs Implementation
23//===----------------------------------------------------------------------===//
24
25MacroFormalArgs::MacroFormalArgs(const MacroInfo *MI) {
26 assert(MI->isFunctionLike() &&
27 "Can't have formal args for an object-like macro!");
28 // Reserve space for arguments to avoid reallocation.
29 unsigned NumArgs = MI->getNumArgs();
30 if (MI->isC99Varargs() || MI->isGNUVarargs())
31 NumArgs += 3; // Varargs can have more than this, just some guess.
32
33 ArgTokens.reserve(NumArgs);
34}
35
Chris Lattnerb935d8c2006-07-14 06:54:44 +000036/// StringifyArgument - Implement C99 6.10.3.2p2.
37static LexerToken StringifyArgument(const std::vector<LexerToken> &Toks,
38 Preprocessor &PP) {
39 LexerToken Tok;
40 Tok.StartToken();
41 Tok.SetKind(tok::string_literal);
42
43 std::string Val = "\"XXYZLAKSDFJAS\"";
44 Tok.SetLength(Val.size());
45 Tok.SetLocation(PP.CreateString(&Val[0], Val.size()));
46 return Tok;
47}
48
49/// getStringifiedArgument - Compute, cache, and return the specified argument
50/// that has been 'stringified' as required by the # operator.
51const LexerToken &MacroFormalArgs::getStringifiedArgument(unsigned ArgNo,
52 Preprocessor &PP) {
53 assert(ArgNo < ArgTokens.size() && "Invalid argument number!");
54 if (StringifiedArgs.empty()) {
55 StringifiedArgs.resize(ArgTokens.size());
56 memset(&StringifiedArgs[0], 0, sizeof(StringifiedArgs[0])*ArgTokens.size());
57 }
58 if (StringifiedArgs[ArgNo].getKind() != tok::string_literal)
59 StringifiedArgs[ArgNo] = StringifyArgument(ArgTokens[ArgNo], PP);
60 return StringifiedArgs[ArgNo];
61}
62
Chris Lattner78186052006-07-09 00:45:31 +000063//===----------------------------------------------------------------------===//
64// MacroExpander Implementation
65//===----------------------------------------------------------------------===//
66
67MacroExpander::MacroExpander(LexerToken &Tok, MacroFormalArgs *Formals,
68 Preprocessor &pp)
Chris Lattnerb935d8c2006-07-14 06:54:44 +000069 : Macro(*Tok.getIdentifierInfo()->getMacroInfo()),
70 FormalArgs(Formals), PP(pp), CurToken(0),
Chris Lattner50b497e2006-06-18 16:32:35 +000071 InstantiateLoc(Tok.getLocation()),
Chris Lattnerd01e2912006-06-18 16:22:51 +000072 AtStartOfLine(Tok.isAtStartOfLine()),
73 HasLeadingSpace(Tok.hasLeadingSpace()) {
Chris Lattnerb935d8c2006-07-14 06:54:44 +000074 MacroTokens = &Macro.getReplacementTokens();
75
76 // If this is a function-like macro, expand the arguments and change
77 // MacroTokens to point to the expanded tokens.
78 if (Macro.isFunctionLike() && Macro.getNumArgs())
79 ExpandFunctionArguments();
Chris Lattnerd01e2912006-06-18 16:22:51 +000080}
81
Chris Lattnerb935d8c2006-07-14 06:54:44 +000082MacroExpander::~MacroExpander() {
83 // If this was a function-like macro that actually uses its arguments, delete
84 // the expanded tokens.
85 if (MacroTokens != &Macro.getReplacementTokens())
86 delete MacroTokens;
87
88 // MacroExpander owns its formal arguments.
89 delete FormalArgs;
90}
91
92/// Expand the arguments of a function-like macro so that we can quickly
93/// return preexpanded tokens from MacroTokens.
94void MacroExpander::ExpandFunctionArguments() {
95 std::vector<LexerToken> ResultToks;
96
97 // Loop through the MacroTokens tokens, expanding them into ResultToks. Keep
98 // track of whether we change anything. If not, no need to keep them. If so,
99 // we install the newly expanded sequence as MacroTokens.
100 bool MadeChange = false;
101 for (unsigned i = 0, e = MacroTokens->size(); i != e; ++i) {
102 // If we found the stringify operator, get the argument stringified. The
103 // preprocessor already verified that the following token is a macro name
104 // when the #define was parsed.
105 const LexerToken &CurTok = (*MacroTokens)[i];
106 if (CurTok.getKind() == tok::hash) {
107 int ArgNo = Macro.getArgumentNum((*MacroTokens)[i+1].getIdentifierInfo());
108 assert(ArgNo != -1 && "Token following # is not an argument?");
109
110 ResultToks.push_back(FormalArgs->getStringifiedArgument(ArgNo, PP));
111
112 // FIXME: Should the stringified string leading space flag get set to
113 // match the # or the identifier?
114
115 MadeChange = true;
116 ++i; // Skip arg name.
117 } else {
118 // FIXME: handle microsoft charize extension.
119
120 ResultToks.push_back(CurTok);
121 }
122 }
123
124 // If anything changed, install this as the new MacroTokens list.
125 if (MadeChange) {
126 // This is deleted in the dtor.
127 std::vector<LexerToken> *Res = new std::vector<LexerToken>();
128 Res->swap(ResultToks);
129 MacroTokens = Res;
130 }
131}
Chris Lattner67b07cb2006-06-26 02:03:42 +0000132
Chris Lattner22eb9722006-06-18 05:43:12 +0000133/// Lex - Lex and return a token from this macro stream.
Chris Lattnerd01e2912006-06-18 16:22:51 +0000134///
Chris Lattnercb283342006-06-18 06:48:37 +0000135void MacroExpander::Lex(LexerToken &Tok) {
Chris Lattner22eb9722006-06-18 05:43:12 +0000136 // Lexing off the end of the macro, pop this macro off the expansion stack.
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000137 if (isAtEnd())
Chris Lattner22eb9722006-06-18 05:43:12 +0000138 return PP.HandleEndOfMacro(Tok);
139
140 // Get the next token to return.
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000141 Tok = (*MacroTokens)[CurToken++];
Chris Lattner22eb9722006-06-18 05:43:12 +0000142
Chris Lattnerc673f902006-06-30 06:10:41 +0000143 // The token's current location indicate where the token was lexed from. We
144 // need this information to compute the spelling of the token, but any
145 // diagnostics for the expanded token should appear as if they came from
146 // InstantiationLoc. Pull this information together into a new SourceLocation
147 // that captures all of this.
148 Tok.SetLocation(PP.getSourceManager().getInstantiationLoc(Tok.getLocation(),
149 InstantiateLoc));
Chris Lattner30709b032006-06-21 03:01:55 +0000150
Chris Lattner22eb9722006-06-18 05:43:12 +0000151 // If this is the first token, set the lexical properties of the token to
152 // match the lexical properties of the macro identifier.
153 if (CurToken == 1) {
154 Tok.SetFlagValue(LexerToken::StartOfLine , AtStartOfLine);
155 Tok.SetFlagValue(LexerToken::LeadingSpace, HasLeadingSpace);
156 }
157
158 // Handle recursive expansion!
159 if (Tok.getIdentifierInfo())
160 return PP.HandleIdentifier(Tok);
161
162 // Otherwise, return a normal token.
Chris Lattner22eb9722006-06-18 05:43:12 +0000163}
Chris Lattnerafe603f2006-07-11 04:02:46 +0000164
Chris Lattnerd8aee0e2006-07-11 05:04:55 +0000165/// isNextTokenLParen - If the next token lexed will pop this macro off the
166/// expansion stack, return 2. If the next unexpanded token is a '(', return
167/// 1, otherwise return 0.
168unsigned MacroExpander::isNextTokenLParen() const {
Chris Lattnerafe603f2006-07-11 04:02:46 +0000169 // Out of tokens?
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000170 if (isAtEnd())
Chris Lattnerd8aee0e2006-07-11 05:04:55 +0000171 return 2;
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000172 return (*MacroTokens)[CurToken].getKind() == tok::l_paren;
Chris Lattnerafe603f2006-07-11 04:02:46 +0000173}