本文整理汇总了C++中ExprResult::isValid方法的典型用法代码示例。如果您正苦于以下问题:C++ ExprResult::isValid方法的具体用法?C++ ExprResult::isValid怎么用?C++ ExprResult::isValid使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ExprResult
的用法示例。
在下文中一共展示了ExprResult::isValid方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ParseMatchedBinaryArgs
/// ParseMatchedBinaryArgs - Parse a pair of arguments who are
/// expected to be of the same type. Upon return, if both LHS and RHS
/// are valid then they are guaranteed to have the same type.
///
/// Name - The name token of the expression, for diagnostics.
/// ExpectType - The expected type of the arguments, if known.
void ParserImpl::ParseMatchedBinaryArgs(const Token &Name,
TypeResult ExpectType,
ExprResult &LHS, ExprResult &RHS) {
if (Tok.kind == Token::RParen) {
Error("unexpected end of arguments.", Name);
ConsumeRParen();
return;
}
// Avoid NumberOrExprResult overhead and give more precise
// diagnostics when we know the type.
if (ExpectType.isValid()) {
LHS = ParseExpr(ExpectType);
if (Tok.kind == Token::RParen) {
Error("unexpected end of arguments.", Name);
ConsumeRParen();
return;
}
RHS = ParseExpr(ExpectType);
} else {
NumberOrExprResult LHS_NOE = ParseNumberOrExpr();
if (Tok.kind == Token::RParen) {
Error("unexpected end of arguments.", Name);
ConsumeRParen();
return;
}
if (LHS_NOE.isNumber()) {
NumberOrExprResult RHS_NOE = ParseNumberOrExpr();
if (RHS_NOE.isNumber()) {
Error("ambiguous arguments to expression.", Name);
} else {
RHS = RHS_NOE.getExpr();
if (RHS.isValid())
LHS = ParseNumberToken(RHS.get()->getWidth(), LHS_NOE.getNumber());
}
} else {
LHS = LHS_NOE.getExpr();
if (!LHS.isValid()) {
// FIXME: Should suppress ambiguity warnings here.
RHS = ParseExpr(TypeResult());
} else {
RHS = ParseExpr(LHS.get()->getWidth());
}
}
}
ExpectRParen("unexpected argument to expression.");
}
示例2: ParseConcatParenExpr
// FIXME: Rewrite to only accept binary form. Make type optional.
ExprResult ParserImpl::ParseConcatParenExpr(const Token &Name,
Expr::Width ResTy) {
std::vector<ExprHandle> Kids;
unsigned Width = 0;
while (Tok.kind != Token::RParen) {
ExprResult E = ParseExpr(TypeResult());
// Skip to end of expr on error.
if (!E.isValid()) {
SkipUntilRParen();
return Builder->Constant(0, ResTy);
}
Kids.push_back(E.get());
Width += E.get()->getWidth();
}
ConsumeRParen();
if (Width != ResTy) {
Error("concat does not match expected result size.");
return Builder->Constant(0, ResTy);
}
// FIXME: Use builder!
return ConcatExpr::createN(Kids.size(), &Kids[0]);
}
示例3: ParseUnaryParenExpr
ExprResult ParserImpl::ParseUnaryParenExpr(const Token &Name,
unsigned Kind, bool IsFixed,
Expr::Width ResTy) {
if (Tok.kind == Token::RParen) {
Error("unexpected end of arguments.", Name);
ConsumeRParen();
return Builder->Constant(0, ResTy);
}
ExprResult Arg = ParseExpr(IsFixed ? ResTy : TypeResult());
if (!Arg.isValid())
Arg = Builder->Constant(0, ResTy);
ExpectRParen("unexpected argument in unary expression.");
ExprHandle E = Arg.get();
switch (Kind) {
case eMacroKind_Neg:
return Builder->Sub(Builder->Constant(0, E->getWidth()), E);
case Expr::Not:
// FIXME: Type check arguments.
return Builder->Not(E);
case Expr::SExt:
// FIXME: Type check arguments.
return Builder->SExt(E, ResTy);
case Expr::ZExt:
// FIXME: Type check arguments.
return Builder->ZExt(E, ResTy);
default:
Error("internal error, unhandled kind.", Name);
return Builder->Constant(0, ResTy);
}
}
示例4: ParseIntegerConstant
IntegerResult ParserImpl::ParseIntegerConstant(Expr::Width Type) {
ExprResult Res = ParseNumber(Type);
if (!Res.isValid())
return IntegerResult();
return cast<ConstantExpr>(Res.get())->getZExtValue(Type);
}
示例5: ParseSelectParenExpr
ExprResult ParserImpl::ParseSelectParenExpr(const Token &Name,
Expr::Width ResTy) {
// FIXME: Why does this need to be here?
if (Tok.kind == Token::RParen) {
Error("unexpected end of arguments.", Name);
ConsumeRParen();
return Builder->Constant(0, ResTy);
}
ExprResult Cond = ParseExpr(Expr::Bool);
ExprResult LHS, RHS;
ParseMatchedBinaryArgs(Name, ResTy, LHS, RHS);
if (!Cond.isValid() || !LHS.isValid() || !RHS.isValid())
return Builder->Constant(0, ResTy);
return Builder->Select(Cond.get(), LHS.get(), RHS.get());
}
示例6: ParseExtractParenExpr
ExprResult ParserImpl::ParseExtractParenExpr(const Token &Name,
Expr::Width ResTy) {
IntegerResult OffsetExpr = ParseIntegerConstant(Expr::Int32);
ExprResult Child = ParseExpr(TypeResult());
ExpectRParen("unexpected argument to expression.");
if (!OffsetExpr.isValid() || !Child.isValid())
return Builder->Constant(0, ResTy);
unsigned Offset = (unsigned) OffsetExpr.get();
if (Offset + ResTy > Child.get()->getWidth()) {
Error("extract out-of-range of child expression.", Name);
return Builder->Constant(0, ResTy);
}
return Builder->Extract(Child.get(), Offset, ResTy);
}
示例7: ParseExpr
/// ParseExpr - Parse an expression with the given \arg
/// ExpectedType. \arg ExpectedType can be invalid if the type cannot
/// be inferred from the context.
///
/// expr = false | true
/// expr = <constant>
/// expr = <identifier>
/// expr = [<identifier>:] paren-expr
ExprResult ParserImpl::ParseExpr(TypeResult ExpectedType) {
// FIXME: Is it right to need to do this here?
if (Tok.kind == Token::EndOfFile) {
Error("unexpected end of file.");
return ExprResult();
}
if (Tok.kind == Token::KWFalse || Tok.kind == Token::KWTrue) {
bool Value = Tok.kind == Token::KWTrue;
ConsumeToken();
return ExprResult(Builder->Constant(Value, Expr::Bool));
}
if (Tok.kind == Token::Number) {
if (!ExpectedType.isValid()) {
Error("cannot infer type of number.");
ConsumeToken();
return ExprResult();
}
return ParseNumber(ExpectedType.get());
}
const Identifier *Label = 0;
if (Tok.kind == Token::Identifier) {
Token LTok = Tok;
Label = GetOrCreateIdentifier(Tok);
ConsumeToken();
if (Tok.kind != Token::Colon) {
ExprSymTabTy::iterator it = ExprSymTab.find(Label);
if (it == ExprSymTab.end()) {
Error("invalid expression label reference.", LTok);
return ExprResult();
}
return it->second;
}
ConsumeToken();
if (ExprSymTab.count(Label)) {
Error("duplicate expression label definition.", LTok);
Label = 0;
}
}
Token Start = Tok;
ExprResult Res = ParseParenExpr(ExpectedType);
if (!Res.isValid()) {
// If we know the type, define the identifier just so we don't get
// use-of-undef errors.
// FIXME: Maybe we should let the symbol table map to invalid
// entries?
if (Label && ExpectedType.isValid()) {
ref<Expr> Value = Builder->Constant(0, ExpectedType.get());
ExprSymTab.insert(std::make_pair(Label, Value));
}
return Res;
} else if (ExpectedType.isValid()) {
// Type check result.
if (Res.get()->getWidth() != ExpectedType.get()) {
// FIXME: Need more info, and range
Error("expression has incorrect type.", Start);
return ExprResult();
}
}
if (Label)
ExprSymTab.insert(std::make_pair(Label, Res.get()));
return Res;
}
示例8: ParseQueryCommand
/// ParseQueryCommand - Parse query command. The lexer should be
/// positioned at the 'query' keyword.
///
/// 'query' expressions-list expression [expressions-list [array-list]]
DeclResult ParserImpl::ParseQueryCommand() {
std::vector<ExprHandle> Constraints;
std::vector<ExprHandle> Values;
std::vector<const Array*> Objects;
ExprResult Res;
// FIXME: We need a command for this. Or something.
ExprSymTab.clear();
VersionSymTab.clear();
// Reinsert initial array versions.
// FIXME: Remove this!
for (std::map<const Identifier*, const ArrayDecl*>::iterator
it = ArraySymTab.begin(), ie = ArraySymTab.end(); it != ie; ++it) {
VersionSymTab.insert(std::make_pair(it->second->Name,
UpdateList(it->second->Root, NULL)));
}
ConsumeExpectedToken(Token::KWQuery);
if (Tok.kind != Token::LSquare) {
Error("malformed query, expected constraint list.");
SkipUntilRParen();
return DeclResult();
}
ConsumeLSquare();
// FIXME: Should avoid reading past unbalanced parens here.
while (Tok.kind != Token::RSquare) {
if (Tok.kind == Token::EndOfFile) {
Error("unexpected end of file.");
Res = ExprResult(Builder->Constant(0, Expr::Bool));
goto exit;
}
ExprResult Constraint = ParseExpr(TypeResult(Expr::Bool));
if (Constraint.isValid())
Constraints.push_back(Constraint.get());
}
ConsumeRSquare();
Res = ParseExpr(TypeResult(Expr::Bool));
if (!Res.isValid()) // Error emitted by ParseExpr.
Res = ExprResult(Builder->Constant(0, Expr::Bool));
// Return if there are no optional lists of things to evaluate.
if (Tok.kind == Token::RParen)
goto exit;
if (Tok.kind != Token::LSquare) {
Error("malformed query, expected expression list.");
SkipUntilRParen();
return DeclResult();
}
ConsumeLSquare();
// FIXME: Should avoid reading past unbalanced parens here.
while (Tok.kind != Token::RSquare) {
if (Tok.kind == Token::EndOfFile) {
Error("unexpected end of file.");
goto exit;
}
ExprResult Res = ParseExpr(TypeResult());
if (Res.isValid())
Values.push_back(Res.get());
}
ConsumeRSquare();
// Return if there are no optional lists of things to evaluate.
if (Tok.kind == Token::RParen)
goto exit;
if (Tok.kind != Token::LSquare) {
Error("malformed query, expected array list.");
SkipUntilRParen();
return DeclResult();
}
ConsumeLSquare();
// FIXME: Should avoid reading past unbalanced parens here.
while (Tok.kind != Token::RSquare) {
if (Tok.kind == Token::EndOfFile) {
Error("unexpected end of file.");
goto exit;
}
// FIXME: Factor out.
if (Tok.kind != Token::Identifier) {
Error("unexpected token.");
ConsumeToken();
continue;
}
Token LTok = Tok;
const Identifier *Label = GetOrCreateIdentifier(Tok);
//.........这里部分代码省略.........
示例9: ParseArrayDecl
/// ParseArrayDecl - Parse an array declaration. The lexer should be positioned
/// at the opening 'array'.
///
/// array-declaration = "array" name "[" [ size ] "]" ":" domain "->" range
/// "=" array-initializer
/// array-initializer = "symbolic" | "{" { numeric-literal } "}"
DeclResult ParserImpl::ParseArrayDecl() {
// FIXME: Recovery here is horrible, we need to scan to next decl start or
// something.
ConsumeExpectedToken(Token::KWArray);
if (Tok.kind != Token::Identifier) {
Error("expected identifier token.");
return DeclResult();
}
Token Name = Tok;
IntegerResult Size;
TypeResult DomainType;
TypeResult RangeType;
std::vector< ref<ConstantExpr> > Values;
ConsumeToken();
if (Tok.kind != Token::LSquare) {
Error("expected '['.");
goto exit;
}
ConsumeLSquare();
if (Tok.kind != Token::RSquare) {
Size = ParseIntegerConstant(64);
}
if (Tok.kind != Token::RSquare) {
Error("expected ']'.");
goto exit;
}
ConsumeRSquare();
if (Tok.kind != Token::Colon) {
Error("expected ':'.");
goto exit;
}
ConsumeExpectedToken(Token::Colon);
DomainType = ParseTypeSpecifier();
if (Tok.kind != Token::Arrow) {
Error("expected '->'.");
goto exit;
}
ConsumeExpectedToken(Token::Arrow);
RangeType = ParseTypeSpecifier();
if (Tok.kind != Token::Equals) {
Error("expected '='.");
goto exit;
}
ConsumeExpectedToken(Token::Equals);
if (Tok.kind == Token::KWSymbolic) {
ConsumeExpectedToken(Token::KWSymbolic);
} else if (Tok.kind == Token::LSquare) {
ConsumeLSquare();
while (Tok.kind != Token::RSquare) {
if (Tok.kind == Token::EndOfFile) {
Error("unexpected end of file.");
goto exit;
}
ExprResult Res = ParseNumber(RangeType.get());
if (Res.isValid())
Values.push_back(cast<ConstantExpr>(Res.get()));
}
ConsumeRSquare();
} else {
Error("expected 'symbolic' or '['.");
goto exit;
}
// Type check size.
if (!Size.isValid()) {
if (Values.empty()) {
Error("unsized arrays are not yet supported.");
Size = 1;
} else {
Size = Values.size();
}
}
if (!Values.empty()) {
if (Size.get() != Values.size()) {
// FIXME: Lame message.
Error("constant arrays must be completely specified.");
Values.clear();
}
// for (unsigned i = 0; i != Size.get(); ++i) {
// TODO: Check: Must be constant expression.
//}
}
//.........这里部分代码省略.........
示例10: ParseAnyReadParenExpr
ExprResult ParserImpl::ParseAnyReadParenExpr(const Token &Name,
unsigned Kind,
Expr::Width ResTy) {
NumberOrExprResult Index = ParseNumberOrExpr();
VersionResult Array = ParseVersionSpecifier();
ExpectRParen("unexpected argument in read expression.");
if (!Array.isValid())
return Builder->Constant(0, ResTy);
// FIXME: Need generic way to get array width. Needs to work with
// anonymous arrays.
Expr::Width ArrayDomainType = Expr::Int32;
Expr::Width ArrayRangeType = Expr::Int8;
// Coerce number to correct type.
ExprResult IndexExpr;
if (Index.isNumber())
IndexExpr = ParseNumberToken(ArrayDomainType, Index.getNumber());
else
IndexExpr = Index.getExpr();
if (!IndexExpr.isValid())
return Builder->Constant(0, ResTy);
else if (IndexExpr.get()->getWidth() != ArrayDomainType) {
Error("index width does not match array domain.");
return Builder->Constant(0, ResTy);
}
// FIXME: Check range width.
switch (Kind) {
default:
assert(0 && "Invalid kind.");
return Builder->Constant(0, ResTy);
case eMacroKind_ReadLSB:
case eMacroKind_ReadMSB: {
unsigned NumReads = ResTy / ArrayRangeType;
if (ResTy != NumReads*ArrayRangeType) {
Error("invalid ordered read (not multiple of range type).", Name);
return Builder->Constant(0, ResTy);
}
std::vector<ExprHandle> Kids(NumReads);
ExprHandle Index = IndexExpr.get();
for (unsigned i=0; i != NumReads; ++i) {
// FIXME: We rely on folding here to not complicate things to where the
// Read macro pattern fails to match.
ExprHandle OffsetIndex = Index;
if (i)
OffsetIndex = AddExpr::create(OffsetIndex,
Builder->Constant(i, ArrayDomainType));
Kids[i] = Builder->Read(Array.get(), OffsetIndex);
}
if (Kind == eMacroKind_ReadLSB)
std::reverse(Kids.begin(), Kids.end());
// FIXME: Use builder!
return ConcatExpr::createN(NumReads, &Kids[0]);
}
case Expr::Read:
return Builder->Read(Array.get(), IndexExpr.get());
}
}