Fixed bug "Parser error when calling a macro with arguments".
This commit is contained in:
parent
d38891b490
commit
19ce2d03b6
@ -44,8 +44,10 @@ namespace cling {
|
||||
Tok.startToken(curPos);
|
||||
char C = *curPos++;
|
||||
switch (C) {
|
||||
case '[': case ']': case '(': case ')': case '{': case '}': case '"':
|
||||
case '\'': case '\\': case ',': case '.': case '!': case '?': case '>':
|
||||
case '"': case '\'':
|
||||
return LexQuotedStringAndAdvance(--curPos, Tok);
|
||||
case '[': case ']': case '(': case ')': case '{': case '}':
|
||||
case '\\': case ',': case '.': case '!': case '?': case '>':
|
||||
case '&': case '#': case '@':
|
||||
// INTENTIONAL FALL THROUGHs
|
||||
return LexPunctuator(C, Tok);
|
||||
@ -146,20 +148,21 @@ namespace cling {
|
||||
// Tok must be the starting quote (single or double), and we will
|
||||
// lex until the next one or the end of the line.
|
||||
|
||||
const char* const start = curPos;
|
||||
LexPunctuator(*curPos++, Tok); // '"' or "'"
|
||||
assert( (Tok.getKind() >= tok::quote && Tok.getKind() <= tok::apostrophe) );
|
||||
tok::TokenKind EndTokKind = Tok.getKind();
|
||||
Tok.setKind(tok::raw_ident);
|
||||
|
||||
char start = '\0';
|
||||
if (Tok.is(tok::quote)) start = '"';
|
||||
else if (Tok.is(tok::apostrophe)) start = '\'';
|
||||
|
||||
Tok.startToken(curPos);
|
||||
//consuming the string
|
||||
while (true) {
|
||||
bool escape = false;
|
||||
while ( (escape || *curPos != start)
|
||||
&& *curPos != '\0' && *curPos != '\r' && *curPos != '\n') {
|
||||
|
||||
// "AB\"foo \0x12 \012 \n"
|
||||
/* bool escape = false;
|
||||
while ( (escape || *curPos != *start) && *curPos != '\0' && *curPos != '\r' && *curPos != '\n') {
|
||||
escape = ( (*curPos) == '\\' );
|
||||
++curPos;
|
||||
}
|
||||
}*/
|
||||
if (*curPos == '\0') {
|
||||
Tok.setBufStart(curPos);
|
||||
Tok.setKind(tok::eof);
|
||||
@ -167,8 +170,10 @@ namespace cling {
|
||||
return;
|
||||
}
|
||||
MetaLexer::LexPunctuator(*curPos++, Tok);
|
||||
if (Tok.isNot(tok::unknown))
|
||||
if (Tok.is(EndTokKind)) {
|
||||
Tok.setLength(curPos - start + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,25 @@ namespace cling {
|
||||
lookAhead(0);
|
||||
}
|
||||
|
||||
void MetaParser::consumeToken_string(Token &tok) {
|
||||
if (m_TokenCache.size())
|
||||
m_TokenCache.erase(m_TokenCache.begin());
|
||||
|
||||
tok = lookAhead(0);
|
||||
}
|
||||
|
||||
void MetaParser::consumeAnyStringToken(tok::TokenKind stopAt/*=tok::space*/) {
|
||||
|
||||
//this token is needed in order to check if we have reached the end of the string
|
||||
//Token tok_is_quote;
|
||||
//consumeToken_string(tok_is_quote);
|
||||
|
||||
//if the token tok_is_quote is of kind "quote"
|
||||
//tok_is_quote.is(tok::quote){
|
||||
//it means we have reached the end of the string
|
||||
|
||||
//}
|
||||
|
||||
consumeToken();
|
||||
// we have to merge the tokens from the queue until we reach eof token or
|
||||
// space token
|
||||
@ -61,12 +79,14 @@ namespace cling {
|
||||
|| MergedTok.is(tok::comment))
|
||||
return;
|
||||
|
||||
//look ahead for the next token without consuming it
|
||||
Token Tok = lookAhead(1);
|
||||
Token PrevTok = Tok;
|
||||
while (Tok.isNot(stopAt) && Tok.isNot(tok::eof)){
|
||||
//MergedTok.setLength(MergedTok.getLength() + Tok.getLength());
|
||||
m_TokenCache.erase(m_TokenCache.begin() + 1);
|
||||
PrevTok = Tok;
|
||||
//look ahead for the next token without consuming it
|
||||
Tok = lookAhead(1);
|
||||
}
|
||||
MergedTok.setKind(tok::raw_ident);
|
||||
|
@ -75,6 +75,7 @@ namespace cling {
|
||||
///\brief Consume the current 'peek' token.
|
||||
///
|
||||
void consumeToken();
|
||||
void consumeToken_string(Token &tok);
|
||||
void consumeAnyStringToken(tok::TokenKind stopAt = tok::space);
|
||||
const Token& lookAhead(unsigned Num);
|
||||
void skipWhitespace();
|
||||
|
@ -6,12 +6,17 @@
|
||||
// LICENSE.TXT for details.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// RUN: %cling %s "args(42)" 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: %cling %s 'args(42,"")' 2>&1 | FileCheck %s
|
||||
//CHECK-NOT: {{.*error|note:.*}}
|
||||
//CHECK: warning: function 'args' cannot be called with no arguments.
|
||||
|
||||
extern "C" int printf(const char* fmt, ...);
|
||||
void args(int I, const char* S = "ArgString") {
|
||||
|
||||
void args(int I, const char* R, const char* S = "ArgString") {
|
||||
|
||||
|
||||
printf("I=%d\n", I); // CHECK: I=42
|
||||
printf("S=%s\n", S); // CHECK: S=ArgString
|
||||
printf("R=%s\n", R);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user