From 19ce2d03b66866327fbbcd3f3731e9ff5ab0fa5b Mon Sep 17 00:00:00 2001 From: Liza Sakellari Date: Tue, 31 Mar 2015 10:14:48 +0200 Subject: [PATCH] Fixed bug "Parser error when calling a macro with arguments". --- lib/MetaProcessor/MetaLexer.cpp | 29 +++++++++++++++++------------ lib/MetaProcessor/MetaParser.cpp | 20 ++++++++++++++++++++ lib/MetaProcessor/MetaParser.h | 1 + test/Driver/args.C | 11 ++++++++--- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/lib/MetaProcessor/MetaLexer.cpp b/lib/MetaProcessor/MetaLexer.cpp index 4f23694e..13864ca4 100644 --- a/lib/MetaProcessor/MetaLexer.cpp +++ b/lib/MetaProcessor/MetaLexer.cpp @@ -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; + } } } diff --git a/lib/MetaProcessor/MetaParser.cpp b/lib/MetaProcessor/MetaParser.cpp index 920eb7b1..07b13080 100644 --- a/lib/MetaProcessor/MetaParser.cpp +++ b/lib/MetaProcessor/MetaParser.cpp @@ -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); diff --git a/lib/MetaProcessor/MetaParser.h b/lib/MetaProcessor/MetaParser.h index 89dc9d15..be527349 100644 --- a/lib/MetaProcessor/MetaParser.h +++ b/lib/MetaProcessor/MetaParser.h @@ -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(); diff --git a/test/Driver/args.C b/test/Driver/args.C index 946c9bdd..252c5435 100644 --- a/test/Driver/args.C +++ b/test/Driver/args.C @@ -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); + }