blob: 35e4f8e158d31261d792aba8322e3336f20d497f [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 Lattner0707bd32006-07-15 05:23:58 +000018#include "clang/Basic/Diagnostic.h"
Chris Lattner22eb9722006-06-18 05:43:12 +000019using namespace llvm;
20using namespace clang;
21
Chris Lattner78186052006-07-09 00:45:31 +000022//===----------------------------------------------------------------------===//
23// MacroFormalArgs Implementation
24//===----------------------------------------------------------------------===//
25
26MacroFormalArgs::MacroFormalArgs(const MacroInfo *MI) {
27 assert(MI->isFunctionLike() &&
28 "Can't have formal args for an object-like macro!");
29 // Reserve space for arguments to avoid reallocation.
30 unsigned NumArgs = MI->getNumArgs();
31 if (MI->isC99Varargs() || MI->isGNUVarargs())
32 NumArgs += 3; // Varargs can have more than this, just some guess.
33
34 ArgTokens.reserve(NumArgs);
35}
36
Chris Lattner0707bd32006-07-15 05:23:58 +000037/// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
38/// tokens into the literal string token that should be produced by the C #
39/// preprocessor operator.
40///
Chris Lattnerb935d8c2006-07-14 06:54:44 +000041static LexerToken StringifyArgument(const std::vector<LexerToken> &Toks,
42 Preprocessor &PP) {
43 LexerToken Tok;
44 Tok.StartToken();
45 Tok.SetKind(tok::string_literal);
Chris Lattner0707bd32006-07-15 05:23:58 +000046
47 // Stringify all the tokens.
48 std::string Result = "\"";
49 for (unsigned i = 0, e = Toks.size(); i != e; ++i) {
50 const LexerToken &Tok = Toks[i];
51 // FIXME: Optimize this.
52 if (i != 0 && Tok.hasLeadingSpace())
53 Result += ' ';
54
55 // If this is a string or character constant, escape the token as specified
56 // by 6.10.3.2p2.
57 if (Tok.getKind() == tok::string_literal || // "foo" and L"foo".
58 Tok.getKind() == tok::char_constant) { // 'x' and L'x'.
59 Result += Lexer::Stringify(PP.getSpelling(Tok));
60 } else {
61 // Otherwise, just append the token.
62 Result += PP.getSpelling(Tok);
63 }
64 }
Chris Lattnerb935d8c2006-07-14 06:54:44 +000065
Chris Lattner0707bd32006-07-15 05:23:58 +000066 // If the last character of the string is a \, and if it isn't escaped, this
67 // is an invalid string literal, diagnose it as specified in C99.
68 if (Result[Result.size()-1] == '\\') {
69 // Count the number of consequtive \ characters. If even, then they are
70 // just escaped backslashes, otherwise it's an error.
71 unsigned FirstNonSlash = Result.size()-2;
72 // Guaranteed to find the starting " if nothing else.
73 while (Result[FirstNonSlash] == '\\')
74 --FirstNonSlash;
75 if ((Result.size()-1-FirstNonSlash) & 1) {
76 PP.Diag(Toks.back(), diag::pp_invalid_string_literal);
77 Result.erase(Result.end()-1); // remove one of the \'s.
78 }
79 }
80
81 Result += '"';
82
83 Tok.SetLength(Result.size());
84 Tok.SetLocation(PP.CreateString(&Result[0], Result.size()));
Chris Lattnerb935d8c2006-07-14 06:54:44 +000085 return Tok;
86}
87
88/// getStringifiedArgument - Compute, cache, and return the specified argument
89/// that has been 'stringified' as required by the # operator.
90const LexerToken &MacroFormalArgs::getStringifiedArgument(unsigned ArgNo,
91 Preprocessor &PP) {
92 assert(ArgNo < ArgTokens.size() && "Invalid argument number!");
93 if (StringifiedArgs.empty()) {
94 StringifiedArgs.resize(ArgTokens.size());
95 memset(&StringifiedArgs[0], 0, sizeof(StringifiedArgs[0])*ArgTokens.size());
96 }
97 if (StringifiedArgs[ArgNo].getKind() != tok::string_literal)
98 StringifiedArgs[ArgNo] = StringifyArgument(ArgTokens[ArgNo], PP);
99 return StringifiedArgs[ArgNo];
100}
101
Chris Lattner78186052006-07-09 00:45:31 +0000102//===----------------------------------------------------------------------===//
103// MacroExpander Implementation
104//===----------------------------------------------------------------------===//
105
106MacroExpander::MacroExpander(LexerToken &Tok, MacroFormalArgs *Formals,
107 Preprocessor &pp)
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000108 : Macro(*Tok.getIdentifierInfo()->getMacroInfo()),
109 FormalArgs(Formals), PP(pp), CurToken(0),
Chris Lattner50b497e2006-06-18 16:32:35 +0000110 InstantiateLoc(Tok.getLocation()),
Chris Lattnerd01e2912006-06-18 16:22:51 +0000111 AtStartOfLine(Tok.isAtStartOfLine()),
112 HasLeadingSpace(Tok.hasLeadingSpace()) {
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000113 MacroTokens = &Macro.getReplacementTokens();
114
115 // If this is a function-like macro, expand the arguments and change
116 // MacroTokens to point to the expanded tokens.
117 if (Macro.isFunctionLike() && Macro.getNumArgs())
118 ExpandFunctionArguments();
Chris Lattnerd01e2912006-06-18 16:22:51 +0000119}
120
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000121MacroExpander::~MacroExpander() {
122 // If this was a function-like macro that actually uses its arguments, delete
123 // the expanded tokens.
124 if (MacroTokens != &Macro.getReplacementTokens())
125 delete MacroTokens;
126
127 // MacroExpander owns its formal arguments.
128 delete FormalArgs;
129}
130
131/// Expand the arguments of a function-like macro so that we can quickly
132/// return preexpanded tokens from MacroTokens.
133void MacroExpander::ExpandFunctionArguments() {
134 std::vector<LexerToken> ResultToks;
135
136 // Loop through the MacroTokens tokens, expanding them into ResultToks. Keep
137 // track of whether we change anything. If not, no need to keep them. If so,
138 // we install the newly expanded sequence as MacroTokens.
139 bool MadeChange = false;
140 for (unsigned i = 0, e = MacroTokens->size(); i != e; ++i) {
141 // If we found the stringify operator, get the argument stringified. The
142 // preprocessor already verified that the following token is a macro name
143 // when the #define was parsed.
144 const LexerToken &CurTok = (*MacroTokens)[i];
145 if (CurTok.getKind() == tok::hash) {
146 int ArgNo = Macro.getArgumentNum((*MacroTokens)[i+1].getIdentifierInfo());
147 assert(ArgNo != -1 && "Token following # is not an argument?");
148
149 ResultToks.push_back(FormalArgs->getStringifiedArgument(ArgNo, PP));
150
151 // FIXME: Should the stringified string leading space flag get set to
152 // match the # or the identifier?
153
154 MadeChange = true;
155 ++i; // Skip arg name.
156 } else {
157 // FIXME: handle microsoft charize extension.
158
159 ResultToks.push_back(CurTok);
160 }
161 }
162
163 // If anything changed, install this as the new MacroTokens list.
164 if (MadeChange) {
165 // This is deleted in the dtor.
166 std::vector<LexerToken> *Res = new std::vector<LexerToken>();
167 Res->swap(ResultToks);
168 MacroTokens = Res;
169 }
170}
Chris Lattner67b07cb2006-06-26 02:03:42 +0000171
Chris Lattner22eb9722006-06-18 05:43:12 +0000172/// Lex - Lex and return a token from this macro stream.
Chris Lattnerd01e2912006-06-18 16:22:51 +0000173///
Chris Lattnercb283342006-06-18 06:48:37 +0000174void MacroExpander::Lex(LexerToken &Tok) {
Chris Lattner22eb9722006-06-18 05:43:12 +0000175 // Lexing off the end of the macro, pop this macro off the expansion stack.
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000176 if (isAtEnd())
Chris Lattner22eb9722006-06-18 05:43:12 +0000177 return PP.HandleEndOfMacro(Tok);
178
179 // Get the next token to return.
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000180 Tok = (*MacroTokens)[CurToken++];
Chris Lattner22eb9722006-06-18 05:43:12 +0000181
Chris Lattnerc673f902006-06-30 06:10:41 +0000182 // The token's current location indicate where the token was lexed from. We
183 // need this information to compute the spelling of the token, but any
184 // diagnostics for the expanded token should appear as if they came from
185 // InstantiationLoc. Pull this information together into a new SourceLocation
186 // that captures all of this.
187 Tok.SetLocation(PP.getSourceManager().getInstantiationLoc(Tok.getLocation(),
188 InstantiateLoc));
Chris Lattner30709b032006-06-21 03:01:55 +0000189
Chris Lattner22eb9722006-06-18 05:43:12 +0000190 // If this is the first token, set the lexical properties of the token to
191 // match the lexical properties of the macro identifier.
192 if (CurToken == 1) {
193 Tok.SetFlagValue(LexerToken::StartOfLine , AtStartOfLine);
194 Tok.SetFlagValue(LexerToken::LeadingSpace, HasLeadingSpace);
195 }
196
197 // Handle recursive expansion!
198 if (Tok.getIdentifierInfo())
199 return PP.HandleIdentifier(Tok);
200
201 // Otherwise, return a normal token.
Chris Lattner22eb9722006-06-18 05:43:12 +0000202}
Chris Lattnerafe603f2006-07-11 04:02:46 +0000203
Chris Lattnerd8aee0e2006-07-11 05:04:55 +0000204/// isNextTokenLParen - If the next token lexed will pop this macro off the
205/// expansion stack, return 2. If the next unexpanded token is a '(', return
206/// 1, otherwise return 0.
207unsigned MacroExpander::isNextTokenLParen() const {
Chris Lattnerafe603f2006-07-11 04:02:46 +0000208 // Out of tokens?
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000209 if (isAtEnd())
Chris Lattnerd8aee0e2006-07-11 05:04:55 +0000210 return 2;
Chris Lattnerb935d8c2006-07-14 06:54:44 +0000211 return (*MacroTokens)[CurToken].getKind() == tok::l_paren;
Chris Lattnerafe603f2006-07-11 04:02:46 +0000212}