bool MetaParser::isfilesCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("files")) { m_Actions->actOnfilesCommand(); return true; } return false; }
bool MetaParser::isOCommand() { const Token& currTok = getCurTok(); if (currTok.is(tok::ident)) { llvm::StringRef ident = currTok.getIdent(); if (ident.startswith("O")) { if (ident.size() > 1) { int level = 0; if (!ident.substr(1).getAsInteger(10, level) && level >= 0) { consumeAnyStringToken(tok::eof); if (getCurTok().is(tok::raw_ident)) return false; //TODO: Process .OXXX here as .O with level XXX. return true; } } else { consumeAnyStringToken(tok::eof); const Token& lastStringToken = getCurTok(); if (lastStringToken.is(tok::raw_ident) && lastStringToken.getLength()) { int level = 0; if (!lastStringToken.getIdent().getAsInteger(10, level) && level >= 0) { //TODO: process .O XXX return true; } } else { //TODO: process .O return true; } } } } return false; }
bool MetaParser::isqCommand() { bool result = false; if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("q")) { result = true; m_Actions->actOnqCommand(); } return result; }
bool MetaParser::isgCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("g")) { consumeToken(); skipWhitespace(); llvm::StringRef varName; if (getCurTok().is(tok::ident)) varName = getCurTok().getIdent(); m_Actions->actOngCommand(varName); return true; } return false; }
bool MetaParser::isUCommand(MetaSema::ActionResult& actionResult) { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("U")) { consumeAnyStringToken(tok::eof); llvm::StringRef path; if (getCurTok().is(tok::raw_ident)) { path = getCurTok().getIdent(); actionResult = m_Actions->actOnUCommand(path); return true; } } return false; }
bool MetaParser::isICommand() { if (getCurTok().is(tok::ident) && ( getCurTok().getIdent().equals("I") || getCurTok().getIdent().equals("include"))) { consumeAnyStringToken(tok::eof); llvm::StringRef path; if (getCurTok().is(tok::raw_ident)) path = getCurTok().getIdent(); m_Actions->actOnICommand(path); return true; } return false; }
bool MetaParser::isdebugCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("debug")) { llvm::Optional<int> mode; consumeToken(); skipWhitespace(); if (getCurTok().is(tok::constant)) mode = getCurTok().getConstant(); m_Actions->actOndebugCommand(mode); return true; } return false; }
bool MetaParser::isdynamicExtensionsCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("dynamicExtensions")) { MetaSema::SwitchMode mode = MetaSema::kToggle; consumeToken(); skipWhitespace(); if (getCurTok().is(tok::constant)) mode = (MetaSema::SwitchMode)getCurTok().getConstantAsBool(); m_Actions->actOndynamicExtensionsCommand(mode); return true; } return false; }
bool MetaParser::isNamespaceCommand() { const Token& Tok = getCurTok(); if (Tok.is(tok::ident)) { if (Tok.getIdent().equals("namespace")) { consumeAnyStringToken(tok::eof); if (getCurTok().is(tok::raw_ident)) return false; m_Actions->actOnNamespaceCommand(); return true; } } return false; }
bool MetaParser::isstatsCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("stats")) { consumeToken(); skipWhitespace(); if (!getCurTok().is(tok::ident)) return false; // FIXME: Issue proper diagnostics std::string ident = getCurTok().getIdent(); consumeToken(); m_Actions->actOnstatsCommand(ident); return true; } return false; }
bool MetaParser::isundoCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("undo")) { consumeToken(); skipWhitespace(); const Token& next = getCurTok(); if (next.is(tok::constant)) m_Actions->actOnUndoCommand(next.getConstant()); else m_Actions->actOnUndoCommand(); return true; } return false; }
bool MetaParser::isTypedefCommand() { const Token& Tok = getCurTok(); if (Tok.is(tok::ident)) { if (Tok.getIdent().equals("typedef")) { consumeAnyStringToken(tok::eof); const Token& NextTok = getCurTok(); llvm::StringRef typedefName; if (NextTok.is(tok::raw_ident)) typedefName = NextTok.getIdent(); m_Actions->actOnTypedefCommand(typedefName); return true; } } return false; }
bool MetaParser::iscompareStateCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("compareState")) { //MetaSema::SwitchMode mode = MetaSema::kToggle; consumeToken(); skipWhitespace(); if (!getCurTok().is(tok::stringlit)) return false; // FIXME: Issue proper diagnostics std::string ident = getCurTok().getIdentNoQuotes(); consumeToken(); m_Actions->actOncompareStateCommand(ident); return true; } return false; }
bool MetaParser::isstatsCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("stats")) { consumeToken(); skipWhitespace(); if (!getCurTok().is(tok::ident)) return false; // FIXME: Issue proper diagnostics llvm::StringRef what = getCurTok().getIdent(); consumeToken(); skipWhitespace(); const Token& next = getCurTok(); m_Actions->actOnstatsCommand(what, next.is(tok::ident) ? next.getIdent() : llvm::StringRef()); return true; } return false; }
bool MetaParser::isCommandSymbol() { for (size_t i = 0; i < m_MetaSymbolCache.size(); ++i) { if (getCurTok().getKind() != m_MetaSymbolCache[i].getKind()) return false; consumeToken(); } return true; }
bool MetaParser::ishelpCommand() { const Token& Tok = getCurTok(); if (Tok.is(tok::quest_mark) || (Tok.is(tok::ident) && Tok.getIdent().equals("help"))) { m_Actions->actOnhelpCommand(); return true; } return false; }
bool MetaParser::isShellCommand(MetaSema::ActionResult& actionResult, Value* resultValue) { if (resultValue) *resultValue = Value(); const Token& Tok = getCurTok(); if (Tok.is(tok::excl_mark)) { consumeAnyStringToken(tok::eof); const Token& NextTok = getCurTok(); if (NextTok.is(tok::raw_ident)) { llvm::StringRef commandLine(NextTok.getIdent()); if (!commandLine.empty()) actionResult = m_Actions->actOnShellCommand(commandLine, resultValue); } return true; } return false; }
bool MetaParser::isAtCommand() { if (getCurTok().is(tok::at) // && getCurTok().getIdent().equals("@") ) { consumeToken(); skipWhitespace(); m_Actions->actOnAtCommand(); return true; } return false; }
bool MetaParser::isClassCommand() { const Token& Tok = getCurTok(); if (Tok.is(tok::ident)) { if (Tok.getIdent().equals("class")) { consumeAnyStringToken(tok::eof); const Token& NextTok = getCurTok(); llvm::StringRef className; if (NextTok.is(tok::raw_ident)) className = NextTok.getIdent(); m_Actions->actOnclassCommand(className); return true; } else if (Tok.getIdent().equals("Class")) { m_Actions->actOnClassCommand(); return true; } } return false; }
// XCommand := 'x' FilePath[ArgList] | 'X' FilePath[ArgList] // FilePath := AnyString // ArgList := (ExtraArgList) ' ' [ArgList] // ExtraArgList := AnyString [, ExtraArgList] bool MetaParser::isXCommand(MetaSema::ActionResult& actionResult, Value* resultValue) { if (resultValue) *resultValue = Value(); const Token& Tok = getCurTok(); if (Tok.is(tok::ident) && (Tok.getIdent().equals("x") || Tok.getIdent().equals("X"))) { // There might be ArgList consumeAnyStringToken(tok::l_paren); llvm::StringRef file(getCurTok().getIdent()); llvm::StringRef args; consumeToken(); if (getCurTok().is(tok::l_paren) && isExtraArgList()) { args = getCurTok().getIdent(); consumeToken(); // consume the closing paren } actionResult = m_Actions->actOnxCommand(file, args, resultValue); if (getCurTok().is(tok::comment)) { consumeAnyStringToken(); m_Actions->actOnComment(getCurTok().getIdent()); } return true; } return false; }
// XCommand := 'x' FilePath[ArgList] | 'X' FilePath[ArgList] // FilePath := AnyString // ArgList := (ExtraArgList) ' ' [ArgList] // ExtraArgList := AnyString [, ExtraArgList] bool MetaParser::isXCommand(MetaSema::ActionResult& actionResult, Value* resultValue) { if (resultValue) *resultValue = Value(); const Token& Tok = getCurTok(); if (Tok.is(tok::ident) && (Tok.getIdent().equals("x") || Tok.getIdent().equals("X"))) { // There might be ArgList consumeAnyStringToken(tok::l_paren); llvm::StringRef file(getCurTok().getIdent()); consumeToken(); // '(' to end of string: std::string args = getCurTok().getBufStart(); if (args.empty()) args = "()"; actionResult = m_Actions->actOnxCommand(file, args, resultValue); return true; } return false; }
// L := 'L' FilePath Comment // FilePath := AnyString // AnyString := .*^('\t' Comment) bool MetaParser::isLCommand(MetaSema::ActionResult& actionResult) { bool result = false; if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("L")) { consumeAnyStringToken(tok::comment); if (getCurTok().is(tok::raw_ident)) { result = true; actionResult = m_Actions->actOnLCommand(getCurTok().getIdent()); consumeToken(); if (getCurTok().is(tok::comment)) { consumeAnyStringToken(tok::eof); m_Actions->actOnComment(getCurTok().getIdent()); } } } // TODO: Some fine grained diagnostics return result; }
// T := 'T' FilePath Comment // FilePath := AnyString // AnyString := .*^('\t' Comment) bool MetaParser::isTCommand(MetaSema::ActionResult& actionResult) { bool result = false; if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("T")) { consumeAnyStringToken(); if (getCurTok().is(tok::raw_ident)) { std::string inputFile = getCurTok().getIdent(); consumeAnyStringToken(tok::eof); if (getCurTok().is(tok::raw_ident)) { result = true; std::string outputFile = getCurTok().getIdent(); actionResult = m_Actions->actOnTCommand(inputFile, outputFile); } } } // TODO: Some fine grained diagnostics return result; }
// dumps/creates a trace of the requested representation. bool MetaParser::istraceCommand() { if (getCurTok().is(tok::ident) && getCurTok().getIdent().equals("trace")) { consumeToken(); skipWhitespace(); if (!getCurTok().is(tok::ident)) return false; llvm::StringRef ident = getCurTok().getIdent(); consumeToken(); skipWhitespace(); m_Actions->actOnstatsCommand(ident.equals("ast") ? llvm::StringRef("asttree") : ident, getCurTok().is(tok::ident) ? getCurTok().getIdent() : llvm::StringRef()); consumeToken(); return true; } return false; }
// >RedirectCommand := '>' FilePath // FilePath := AnyString // AnyString := .*^(' ' | '\t') bool MetaParser::isRedirectCommand(MetaSema::ActionResult& actionResult) { unsigned constant_FD = 0; // Default redirect is stdout. MetaProcessor::RedirectionScope stream = MetaProcessor::kSTDOUT; if (getCurTok().is(tok::constant)) { // > or 1> the redirection is for stdout stream // 2> redirection for stderr stream constant_FD = getCurTok().getConstant(); if (constant_FD == 2) { stream = MetaProcessor::kSTDERR; // Wrong constant_FD, do not redirect. } else if (constant_FD != 1) { cling::errs() << "cling::MetaParser::isRedirectCommand():" << "invalid file descriptor number " << constant_FD <<"\n"; return true; } consumeToken(); } // &> redirection for both stdout & stderr if (getCurTok().is(tok::ampersand)) { if (constant_FD == 0) { stream = MetaProcessor::kSTDBOTH; } consumeToken(); } llvm::StringRef file; if (getCurTok().is(tok::greater)) { bool append = false; // check whether we have >> if (lookAhead(1).is(tok::greater)) { consumeToken(); append = true; } // check for syntax like: 2>&1 if (lookAhead(1).is(tok::ampersand)) { if (constant_FD == 0) stream = MetaProcessor::kSTDBOTH; const Token& Tok = lookAhead(2); if (Tok.is(tok::constant)) { switch (Tok.getConstant()) { case 1: file = llvm::StringRef("&1"); break; case 2: file = llvm::StringRef("&2"); break; default: break; } if (!file.empty()) { // Mark the stream name as refering to stderr or stdout, not a name stream = MetaProcessor::RedirectionScope(stream | MetaProcessor::kSTDSTRM); consumeToken(); // & consumeToken(); // 1,2 } } } std::string EnvExpand; if (!lookAhead(1).is(tok::eof) && !(stream & MetaProcessor::kSTDSTRM)) { consumeAnyStringToken(tok::eof); if (getCurTok().is(tok::raw_ident)) { EnvExpand = getCurTok().getIdent(); // Quoted path, no expansion and strip quotes if (EnvExpand.size() > 3 && EnvExpand.front() == '"' && EnvExpand.back() == '"') { file = EnvExpand; file = file.substr(1, file.size()-2); } else if (!EnvExpand.empty()) { cling::utils::ExpandEnvVars(EnvExpand); file = EnvExpand; } consumeToken(); // If we had a token, we need a path; empty means to undo a redirect if (file.empty()) return false; } } // Empty file means std. actionResult = m_Actions->actOnRedirectCommand(file/*file*/, stream/*which stream to redirect*/, append/*append mode*/); return true; } return false; }
// ExtraArgList := AnyString [, ExtraArgList] bool MetaParser::isExtraArgList() { // This might be expanded if we need better arg parsing. consumeAnyStringToken(tok::r_paren); return getCurTok().is(tok::raw_ident); }
void MetaParser::skipWhitespace() { while(getCurTok().is(tok::space)) consumeToken(); }
// >RedirectCommand := '>' FilePath // FilePath := AnyString // AnyString := .*^(' ' | '\t') bool MetaParser::isRedirectCommand(MetaSema::ActionResult& actionResult) { unsigned constant_FD = 0; // Default redirect is stdout. MetaProcessor::RedirectionScope stream = MetaProcessor::kSTDOUT; if (getCurTok().is(tok::constant)) { // > or 1> the redirection is for stdout stream // 2> redirection for stderr stream constant_FD = getCurTok().getConstant(); if (constant_FD == 2) { stream = MetaProcessor::kSTDERR; // Wrong constant_FD, do not redirect. } else if (constant_FD != 1) { llvm::errs() << "cling::MetaParser::isRedirectCommand():" << "invalid file descriptor number " << constant_FD <<"\n"; return true; } consumeToken(); } // &> redirection for both stdout & stderr if (getCurTok().is(tok::ampersand)) { if (constant_FD != 2) { stream = MetaProcessor::kSTDBOTH; } consumeToken(); } if (getCurTok().is(tok::greater)) { bool append = false; consumeToken(); // check for syntax like: 2>&1 if (getCurTok().is(tok::ampersand)) { if (constant_FD != 2) { stream = MetaProcessor::kSTDBOTH; } consumeToken(); } else { // check whether we have >> if (getCurTok().is(tok::greater)) { append = true; consumeToken(); } } llvm::StringRef file; if (getCurTok().is(tok::constant) && getCurTok().getConstant() == 1) { file = llvm::StringRef("_IO_2_1_stdout_"); } else { if (getCurTok().is(tok::eof)) { file = llvm::StringRef(); } else { consumeAnyStringToken(tok::eof); if (getCurTok().is(tok::raw_ident)) { file = getCurTok().getIdent(); consumeToken(); } else { file = llvm::StringRef(); } } } // Empty file means std. actionResult = m_Actions->actOnRedirectCommand(file/*file*/, stream/*which stream to redirect*/, append/*append mode*/); return true; } return false; }