diff --git a/interpreter/cling/lib/MetaProcessor/InputValidator.cpp b/interpreter/cling/lib/MetaProcessor/InputValidator.cpp index f0a757a7c127908479f94cd9df9c823f29edde48..61fcda01afad6a2ec464dd304ec6fa540dc65805 100644 --- a/interpreter/cling/lib/MetaProcessor/InputValidator.cpp +++ b/interpreter/cling/lib/MetaProcessor/InputValidator.cpp @@ -75,10 +75,22 @@ namespace cling { bool multilineComment = inBlockComment(); int commentTok = multilineComment ? tok::asterik : tok::slash; + if (!multilineComment && m_ParenStack.empty()) { + // Only check for 'template' if we're not already indented + MetaLexer Lex(curPos, true); + Lex.Lex(Tok); + curPos = Lex.getLocation(); + if (Tok.is(tok::ident)) { + if (Tok.getIdent()=="template") + m_ParenStack.push_back(tok::greater); + } else + curPos -= Tok.getLength(); // Rewind buffer for LexPunctuatorAndAdvance + } + do { const char* prevStart = curPos; MetaLexer::LexPunctuatorAndAdvance(curPos, Tok); - int kind = (int)Tok.getKind(); + const int kind = (int)Tok.getKind(); if (kind == commentTok) { if (kind == tok::slash) { @@ -145,6 +157,12 @@ namespace cling { break; } m_ParenStack.pop_back(); + + // Right brace will pop a template if their is one + if (kind == tok::r_brace && m_ParenStack.size() == 1 ) { + if (m_ParenStack.back() == tok::greater) + m_ParenStack.pop_back(); + } } else m_ParenStack.push_back(kind); @@ -166,12 +184,16 @@ namespace cling { m_ParenStack.push_back(tok::hash); } } + else if (kind == tok::semicolon) { + // Template forward declatation + if (m_ParenStack.size() == 1 && m_ParenStack.back()==tok::greater) + m_ParenStack.pop_back(); + } else if (kind >= (int)tok::stringlit && kind <= (int)tok::charlit) { MetaLexer::LexQuotedStringAndAdvance(curPos, Tok); } } - } - while (Tok.isNot(tok::eof)); + } while (Tok.isNot(tok::eof)); if (!m_ParenStack.empty() && Res != kMismatch) Res = kIncomplete; diff --git a/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp b/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp index 60db7d66e82894b1c65cd85f65f4a8613b108c58..9c77dd07ffa74b164d488f790686a1b9f17588cd 100644 --- a/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp +++ b/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp @@ -39,9 +39,11 @@ namespace cling { return value; } - MetaLexer::MetaLexer(llvm::StringRef line) - : bufferStart(line.data()), curPos(line.data()) - { } + MetaLexer::MetaLexer(llvm::StringRef line, bool skipWhite) + : bufferStart(line.data()), curPos(line.data()) { + if (skipWhite) + SkipWhitespace(); + } void MetaLexer::reset(llvm::StringRef line) { bufferStart = line.data(); @@ -56,7 +58,7 @@ namespace cling { return LexQuotedStringAndAdvance(curPos, Tok); case '[': case ']': case '(': case ')': case '{': case '}': case '\\': case ',': case '.': case '!': case '?': case '>': - case '&': case '#': case '@': case '*': + case '&': case '#': case '@': case '*': case ';': // INTENTIONAL FALL THROUGHs return LexPunctuator(curPos - 1, Tok); @@ -127,6 +129,7 @@ namespace cling { case '&' : Tok.setKind(tok::ampersand); break; case '#' : Tok.setKind(tok::hash); break; case '*' : Tok.setKind(tok::asterik); break; + case ';' : Tok.setKind(tok::semicolon); break; case '\0' : Tok.setKind(tok::eof); Tok.setLength(0); break;// if static call default: Tok.setLength(0); break; } @@ -224,11 +227,15 @@ namespace cling { } } - void MetaLexer::LexWhitespace(char C, Token& Tok) { + void MetaLexer::SkipWhitespace() { + char C = *curPos; while((C == ' ' || C == '\t') && C != '\0') - C = *curPos++; + C = *(++curPos); + } + + void MetaLexer::LexWhitespace(char C, Token& Tok) { + SkipWhitespace(); - --curPos; // Back up over the non whitespace char. Tok.setLength(curPos - Tok.getBufStart()); Tok.setKind(tok::space); } diff --git a/interpreter/cling/lib/MetaProcessor/MetaLexer.h b/interpreter/cling/lib/MetaProcessor/MetaLexer.h index a7ac2623a34788ebd33d2cff2213774c53ffedec..4479d8c70e95d311a2a12abc00187bdb1984425d 100644 --- a/interpreter/cling/lib/MetaProcessor/MetaLexer.h +++ b/interpreter/cling/lib/MetaProcessor/MetaLexer.h @@ -40,6 +40,7 @@ namespace cling { constant, // {0-9} at, // @ asterik, // * + semicolon, // ; eof, unknown }; @@ -83,7 +84,7 @@ namespace cling { const char* bufferStart; const char* curPos; public: - MetaLexer(llvm::StringRef input); + MetaLexer(llvm::StringRef input, bool skipWhiteSpace = false); void reset(llvm::StringRef Line); void Lex(Token& Tok); @@ -98,9 +99,7 @@ namespace cling { void LexEndOfFile(char C, Token& Tok); void LexWhitespace(char C, Token& Tok); void SkipWhitespace(); - inline char getAndAdvanceChar(const char *&Ptr) { - return *Ptr++; - } + const char* getLocation() const { return curPos; } }; } //end namespace cling