19#include "llvm/ADT/APInt.h"
20#include "llvm/Support/MemoryBuffer.h"
21#include "llvm/Support/raw_ostream.h"
39 ParseResult() : IsValid(false), Value() {}
40 ParseResult(T _Value) : IsValid(true), Value(_Value) {}
41 ParseResult(
bool _IsValid, T _Value) : IsValid(_IsValid), Value(_Value) {}
47 assert(IsValid &&
"get() on invalid ParseResult!");
57 ExprResult() : IsValid(false) {}
58 ExprResult(
ExprHandle _Value) : IsValid(true), Value(_Value) {}
60 ExprResult(
bool _IsValid,
ExprHandle _Value) : IsValid(_IsValid), Value(_Value) {}
66 assert(IsValid &&
"get() on invalid ParseResult!");
71 typedef ParseResult<Decl*> DeclResult;
72 typedef ParseResult<Expr::Width> TypeResult;
73 typedef ParseResult<VersionHandle> VersionResult;
74 typedef ParseResult<uint64_t> IntegerResult;
79 class NumberOrExprResult {
85 NumberOrExprResult() : IsNumber(false) {}
86 explicit NumberOrExprResult(
Token _AsNumber) : AsNumber(_AsNumber),
88 explicit NumberOrExprResult(ExprResult _AsExpr) : AsExpr(_AsExpr),
91 bool isNumber()
const {
return IsNumber; }
92 const Token &getNumber()
const {
93 assert(IsNumber &&
"Invalid accessor call.");
96 const ExprResult &getExpr()
const {
97 assert(!IsNumber &&
"Invalid accessor call.");
103 class ParserImpl :
public Parser {
104 typedef std::map<const std::string, const Identifier*> IdentifierTabTy;
105 typedef std::map<const Identifier*, ExprHandle> ExprSymTabTy;
106 typedef std::map<const Identifier*, VersionHandle> VersionSymTabTy;
108 const std::string Filename;
109 const MemoryBuffer *TheMemoryBuffer;
112 bool ClearArrayAfterQuery;
119 IdentifierTabTy IdentifierTab;
121 std::map<const Identifier*, const ArrayDecl*> ArraySymTab;
122 ExprSymTabTy ExprSymTab;
123 VersionSymTabTy VersionSymTab;
131 unsigned SquareLevel;
137 void GetNextNonCommentToken() {
140 }
while (Tok.
kind == Token::Comment);
144 void ConsumeToken() {
145 assert(Tok.
kind != Token::LParen && Tok.
kind != Token::RParen &&
146 Tok.
kind != Token::LSquare && Tok.
kind != Token::RSquare);
147 GetNextNonCommentToken();
153 assert(Tok.
kind != Token::LParen && Tok.
kind != Token::RParen &&
154 Tok.
kind != Token::LSquare && Tok.
kind != Token::RSquare);
155 _ConsumeExpectedToken(k);
158 assert(Tok.
kind == k &&
"Unexpected token!");
159 GetNextNonCommentToken();
162 void ConsumeLParen() {
164 _ConsumeExpectedToken(Token::LParen);
167 void ConsumeRParen() {
170 _ConsumeExpectedToken(Token::RParen);
173 void ConsumeLSquare() {
175 _ConsumeExpectedToken(Token::LSquare);
178 void ConsumeRSquare() {
181 _ConsumeExpectedToken(Token::RSquare);
184 void ConsumeAnyToken() {
191 return ConsumeToken();
199 void SkipUntilRParen(
unsigned Level) {
204 assert(Level <= ParenLevel &&
205 "Refusing to skip until rparen at higher level.");
206 while (Tok.
kind != Token::EndOfFile) {
207 if (Tok.
kind == Token::RParen && ParenLevel == Level) {
217 void SkipUntilRParen() {
218 SkipUntilRParen(ParenLevel);
224 void ExpectRParen(
const char *Msg) {
225 if (Tok.
kind == Token::EndOfFile) {
227 Error(
"expected ')' but found end-of-file.", Tok);
228 }
else if (Tok.
kind != Token::RParen) {
238 void SkipUntilRSquare(
unsigned Level) {
243 assert(Level <= ParenLevel &&
244 "Refusing to skip until rparen at higher level.");
245 while (Tok.
kind != Token::EndOfFile) {
246 if (Tok.
kind == Token::RSquare && ParenLevel == Level) {
256 void SkipUntilRSquare() {
257 SkipUntilRSquare(ParenLevel);
263 void ExpectRSquare(
const char *Msg) {
264 if (Tok.
kind == Token::EndOfFile) {
266 Error(
"expected ']' but found end-of-file.", Tok);
267 }
else if (Tok.
kind != Token::RSquare) {
279 DeclResult ParseArrayDecl();
280 DeclResult ParseExprVarDecl();
281 DeclResult ParseVersionVarDecl();
282 DeclResult ParseCommandDecl();
286 DeclResult ParseQueryCommand();
290 NumberOrExprResult ParseNumberOrExpr();
291 IntegerResult ParseIntegerConstant(
Expr::Width Type);
293 ExprResult ParseExpr(TypeResult ExpectedType);
294 ExprResult ParseParenExpr(TypeResult ExpectedType);
295 ExprResult ParseUnaryParenExpr(
const Token &Name,
296 unsigned Kind,
bool IsFixed,
298 ExprResult ParseBinaryParenExpr(
const Token &Name,
299 unsigned Kind,
bool IsFixed,
304 ExprResult ParseAnyReadParenExpr(
const Token &Name,
307 void ParseMatchedBinaryArgs(
const Token &Name,
308 TypeResult ExpectType,
309 ExprResult &LHS, ExprResult &RHS);
313 VersionResult ParseVersionSpecifier();
314 VersionResult ParseVersion();
316 TypeResult ParseTypeSpecifier();
320 void Error(
const char *Message,
const Token &At);
321 void Error(
const char *Message) { Error(Message, Tok); }
324 ParserImpl(
const std::string _Filename,
const MemoryBuffer *MB,
326 : Filename(_Filename), TheMemoryBuffer(MB), Builder(_Builder),
327 ClearArrayAfterQuery(_ClearArrayAfterQuery), TheLexer(MB),
328 MaxErrors(~0u), NumErrors(0) {}
330 virtual ~ParserImpl();
335 ParenLevel = SquareLevel = 0;
356 assert(Tok.
kind == Token::Identifier &&
"Expected only identifier tokens.");
358 IdentifierTabTy::iterator it = IdentifierTab.find(Name);
359 if (it != IdentifierTab.end())
363 IdentifierTab.insert(std::make_pair(Name, I));
368Decl *ParserImpl::ParseTopLevelDecl() {
370 while (Tok.
kind != Token::EndOfFile) {
372 case Token::KWArray: {
373 DeclResult Res = ParseArrayDecl();
379 case Token::LParen: {
380 DeclResult Res = ParseCommandDecl();
387 Error(
"expected 'array' or '(' token.");
401DeclResult ParserImpl::ParseArrayDecl() {
404 ConsumeExpectedToken(Token::KWArray);
406 if (Tok.
kind != Token::Identifier) {
407 Error(
"expected identifier token.");
413 TypeResult DomainType;
414 TypeResult RangeType;
415 std::vector< ref<ConstantExpr> > Values;
419 if (Tok.
kind != Token::LSquare) {
420 Error(
"expected '['.");
425 if (Tok.
kind != Token::RSquare) {
426 Size = ParseIntegerConstant(64);
428 if (Tok.
kind != Token::RSquare) {
429 Error(
"expected ']'.");
434 if (Tok.
kind != Token::Colon) {
435 Error(
"expected ':'.");
438 ConsumeExpectedToken(Token::Colon);
440 DomainType = ParseTypeSpecifier();
441 if (Tok.
kind != Token::Arrow) {
442 Error(
"expected '->'.");
445 ConsumeExpectedToken(Token::Arrow);
447 RangeType = ParseTypeSpecifier();
448 if (Tok.
kind != Token::Equals) {
449 Error(
"expected '='.");
452 ConsumeExpectedToken(Token::Equals);
454 if (Tok.
kind == Token::KWSymbolic) {
455 ConsumeExpectedToken(Token::KWSymbolic);
456 }
else if (Tok.
kind == Token::LSquare) {
458 while (Tok.
kind != Token::RSquare) {
459 if (Tok.
kind == Token::EndOfFile) {
460 Error(
"unexpected end of file.");
464 ExprResult Res = ParseNumber(RangeType.get());
466 Values.push_back(cast<ConstantExpr>(Res.get()));
470 Error(
"expected 'symbolic' or '['.");
475 if (!Size.isValid()) {
476 if (Values.empty()) {
477 Error(
"unsized arrays are not yet supported.");
480 Size = Values.size();
484 if (!Values.empty()) {
485 if (Size.get() != Values.size()) {
487 Error(
"constant arrays must be completely specified.");
498 if (DomainType.get() != Expr::Int32) {
499 Error(
"array domain must currently be w32.");
500 DomainType = Expr::Int32;
504 if (RangeType.get() != Expr::Int8) {
505 Error(
"array domain must currently be w8.");
506 RangeType = Expr::Int8;
515 if (!DomainType.isValid())
517 if (!RangeType.isValid())
521 const Identifier *Label = GetOrCreateIdentifier(Name);
525 &Values[0] + Values.size());
529 DomainType.get(), RangeType.get(), Root);
531 ArraySymTab[Label] = AD;
534 VersionSymTab.insert(std::make_pair(Label,
544DeclResult ParserImpl::ParseCommandDecl() {
548 Error(
"malformed command.");
555 return ParseQueryCommand();
558 Error(
"malformed command (unexpected keyword).");
568DeclResult ParserImpl::ParseQueryCommand() {
569 std::vector<ExprHandle> Constraints;
570 std::vector<ExprHandle> Values;
571 std::vector<const Array*> Objects;
576 VersionSymTab.clear();
580 for (std::map<const Identifier*, const ArrayDecl*>::iterator
581 it = ArraySymTab.begin(), ie = ArraySymTab.end(); it != ie; ++it) {
582 VersionSymTab.insert(std::make_pair(it->second->Name,
587 ConsumeExpectedToken(Token::KWQuery);
588 if (Tok.
kind != Token::LSquare) {
589 Error(
"malformed query, expected constraint list.");
596 while (Tok.
kind != Token::RSquare) {
597 if (Tok.
kind == Token::EndOfFile) {
598 Error(
"unexpected end of file.");
599 Res = ExprResult(Builder->
Constant(0, Expr::Bool));
603 ExprResult Constraint = ParseExpr(TypeResult(Expr::Bool));
604 if (Constraint.isValid())
605 Constraints.push_back(Constraint.get());
609 Res = ParseExpr(TypeResult(Expr::Bool));
611 Res = ExprResult(Builder->
Constant(0, Expr::Bool));
614 if (Tok.
kind == Token::RParen)
617 if (Tok.
kind != Token::LSquare) {
618 Error(
"malformed query, expected expression list.");
625 while (Tok.
kind != Token::RSquare) {
626 if (Tok.
kind == Token::EndOfFile) {
627 Error(
"unexpected end of file.");
631 ExprResult Res = ParseExpr(TypeResult());
633 Values.push_back(Res.get());
638 if (Tok.
kind == Token::RParen)
641 if (Tok.
kind != Token::LSquare) {
642 Error(
"malformed query, expected array list.");
649 while (Tok.
kind != Token::RSquare) {
650 if (Tok.
kind == Token::EndOfFile) {
651 Error(
"unexpected end of file.");
656 if (Tok.
kind != Token::Identifier) {
657 Error(
"unexpected token.");
663 const Identifier *Label = GetOrCreateIdentifier(Tok);
667 std::map<const Identifier*, const ArrayDecl*>::iterator
668 it = ArraySymTab.find(Label);
670 if (it == ArraySymTab.end()) {
671 Error(
"unknown array", LTok);
673 Objects.push_back(it->second->Root);
679 if (Tok.
kind != Token::EndOfFile)
680 ExpectRParen(
"unexpected argument to 'query'.");
684 if (ClearArrayAfterQuery)
687 return new QueryCommand(Constraints, Res.get(), Values, Objects);
692NumberOrExprResult ParserImpl::ParseNumberOrExpr() {
693 if (Tok.
kind == Token::Number){
696 return NumberOrExprResult(Num);
698 return NumberOrExprResult(ParseExpr(TypeResult()));
710ExprResult ParserImpl::ParseExpr(TypeResult ExpectedType) {
712 if (Tok.
kind == Token::EndOfFile) {
713 Error(
"unexpected end of file.");
717 if (Tok.
kind == Token::KWFalse || Tok.
kind == Token::KWTrue) {
718 bool Value = Tok.
kind == Token::KWTrue;
720 return ExprResult(Builder->
Constant(Value, Expr::Bool));
723 if (Tok.
kind == Token::Number) {
724 if (!ExpectedType.isValid()) {
725 Error(
"cannot infer type of number.");
730 return ParseNumber(ExpectedType.get());
734 if (Tok.
kind == Token::Identifier) {
736 Label = GetOrCreateIdentifier(Tok);
739 if (Tok.
kind != Token::Colon) {
740 ExprSymTabTy::iterator it = ExprSymTab.find(Label);
742 if (it == ExprSymTab.end()) {
743 Error(
"invalid expression label reference.", LTok);
751 if (ExprSymTab.count(Label)) {
752 Error(
"duplicate expression label definition.", LTok);
758 ExprResult Res = ParseParenExpr(ExpectedType);
759 if (!Res.isValid()) {
764 if (Label && ExpectedType.isValid()) {
766 ExprSymTab.insert(std::make_pair(Label, Value));
769 }
else if (ExpectedType.isValid()) {
771 if (Res.get()->getWidth() != ExpectedType.get()) {
773 Error(
"expression has incorrect type.", Start);
779 ExprSymTab.insert(std::make_pair(Label, Res.get()));
803 bool &IsFixed,
int &NumArgs) {
804#define SetOK(kind, isfixed, numargs) (Kind=kind, IsFixed=isfixed,\
805 NumArgs=numargs, true)
806 assert(Tok.
kind == Token::Identifier &&
"Unexpected token.");
810 if (memcmp(Tok.
start,
"Eq", 2) == 0)
811 return SetOK(Expr::Eq,
false, 2);
812 if (memcmp(Tok.
start,
"Ne", 2) == 0)
813 return SetOK(Expr::Ne,
false, 2);
815 if (memcmp(Tok.
start,
"Or", 2) == 0)
816 return SetOK(Expr::Or,
true, 2);
820 if (memcmp(Tok.
start,
"Add", 3) == 0)
821 return SetOK(Expr::Add,
true, 2);
822 if (memcmp(Tok.
start,
"Sub", 3) == 0)
823 return SetOK(Expr::Sub,
true, 2);
824 if (memcmp(Tok.
start,
"Mul", 3) == 0)
825 return SetOK(Expr::Mul,
true, 2);
827 if (memcmp(Tok.
start,
"Not", 3) == 0)
828 return SetOK(Expr::Not,
true, 1);
829 if (memcmp(Tok.
start,
"And", 3) == 0)
830 return SetOK(Expr::And,
true, 2);
831 if (memcmp(Tok.
start,
"Shl", 3) == 0)
832 return SetOK(Expr::Shl,
true, 2);
833 if (memcmp(Tok.
start,
"Xor", 3) == 0)
834 return SetOK(Expr::Xor,
true, 2);
836 if (memcmp(Tok.
start,
"Ult", 3) == 0)
837 return SetOK(Expr::Ult,
false, 2);
838 if (memcmp(Tok.
start,
"Ule", 3) == 0)
839 return SetOK(Expr::Ule,
false, 2);
840 if (memcmp(Tok.
start,
"Ugt", 3) == 0)
841 return SetOK(Expr::Ugt,
false, 2);
842 if (memcmp(Tok.
start,
"Uge", 3) == 0)
843 return SetOK(Expr::Uge,
false, 2);
844 if (memcmp(Tok.
start,
"Slt", 3) == 0)
845 return SetOK(Expr::Slt,
false, 2);
846 if (memcmp(Tok.
start,
"Sle", 3) == 0)
847 return SetOK(Expr::Sle,
false, 2);
848 if (memcmp(Tok.
start,
"Sgt", 3) == 0)
849 return SetOK(Expr::Sgt,
false, 2);
850 if (memcmp(Tok.
start,
"Sge", 3) == 0)
851 return SetOK(Expr::Sge,
false, 2);
857 if (memcmp(Tok.
start,
"Read", 4) == 0)
858 return SetOK(Expr::Read,
true, -1);
859 if (memcmp(Tok.
start,
"AShr", 4) == 0)
860 return SetOK(Expr::AShr,
true, 2);
861 if (memcmp(Tok.
start,
"LShr", 4) == 0)
862 return SetOK(Expr::LShr,
true, 2);
864 if (memcmp(Tok.
start,
"UDiv", 4) == 0)
865 return SetOK(Expr::UDiv,
true, 2);
866 if (memcmp(Tok.
start,
"SDiv", 4) == 0)
867 return SetOK(Expr::SDiv,
true, 2);
868 if (memcmp(Tok.
start,
"URem", 4) == 0)
869 return SetOK(Expr::URem,
true, 2);
870 if (memcmp(Tok.
start,
"SRem", 4) == 0)
871 return SetOK(Expr::SRem,
true, 2);
873 if (memcmp(Tok.
start,
"SExt", 4) == 0)
874 return SetOK(Expr::SExt,
false, 1);
875 if (memcmp(Tok.
start,
"ZExt", 4) == 0)
876 return SetOK(Expr::ZExt,
false, 1);
880 if (memcmp(Tok.
start,
"Concat", 6) == 0)
882 if (memcmp(Tok.
start,
"Select", 6) == 0)
883 return SetOK(Expr::Select,
false, 3);
887 if (memcmp(Tok.
start,
"Extract", 7) == 0)
888 return SetOK(Expr::Extract,
false, -1);
889 if (memcmp(Tok.
start,
"ReadLSB", 7) == 0)
891 if (memcmp(Tok.
start,
"ReadMSB", 7) == 0)
907ExprResult ParserImpl::ParseParenExpr(TypeResult FIXME_UNUSED) {
908 if (Tok.
kind != Token::LParen) {
909 Error(
"unexpected token.");
917 if (Tok.
kind == Token::KWWidth) {
918 TypeResult ExpectedType = ParseTypeSpecifier();
920 if (Tok.
kind != Token::Number) {
921 Error(
"coercion can only apply to a number.");
928 if (ExpectedType.isValid())
929 Res = ParseNumber(ExpectedType.get());
933 ExpectRParen(
"unexpected argument in coercion.");
937 if (Tok.
kind != Token::Identifier) {
938 Error(
"unexpected token, expected expression.");
948 bool HasType = TypeTok.
kind == Token::KWWidth;
949 TypeResult Type = HasType ? ParseTypeSpecifier() :
Expr::Bool;
954 if (!Type.isValid()) {
967 Error(
"unknown expression kind.", Name);
976 return ParseConcatParenExpr(Name, ResTy);
979 return ParseExtractParenExpr(Name, ResTy);
984 return ParseAnyReadParenExpr(Name, ExprKind, ResTy);
987 Error(
"internal error, unimplemented special form.", Name);
989 return ExprResult(Builder->
Constant(0, ResTy));
995 return ParseUnaryParenExpr(Name, ExprKind, IsFixed, ResTy);
997 return ParseBinaryParenExpr(Name, ExprKind, IsFixed, ResTy);
999 if (ExprKind == Expr::Select) {
1000 return ParseSelectParenExpr(Name, ResTy);
1002 assert(0 &&
"Invalid ternary expression kind.");
1005 assert(0 &&
"Invalid argument kind (number of args).");
1006 return ExprResult();
1010ExprResult ParserImpl::ParseUnaryParenExpr(
const Token &Name,
1011 unsigned Kind,
bool IsFixed,
1013 if (Tok.
kind == Token::RParen) {
1014 Error(
"unexpected end of arguments.", Name);
1016 return Builder->
Constant(0, ResTy);
1019 ExprResult Arg = ParseExpr(IsFixed ? ResTy : TypeResult());
1023 ExpectRParen(
"unexpected argument in unary expression.");
1027 return Builder->
Sub(Builder->
Constant(0, E->getWidth()), E);
1030 return Builder->
Not(E);
1033 return Builder->
SExt(E, ResTy);
1036 return Builder->
ZExt(E, ResTy);
1038 Error(
"internal error, unhandled kind.", Name);
1039 return Builder->
Constant(0, ResTy);
1049void ParserImpl::ParseMatchedBinaryArgs(
const Token &Name,
1050 TypeResult ExpectType,
1051 ExprResult &LHS, ExprResult &RHS) {
1052 if (Tok.
kind == Token::RParen) {
1053 Error(
"unexpected end of arguments.", Name);
1060 if (ExpectType.isValid()) {
1061 LHS = ParseExpr(ExpectType);
1062 if (Tok.
kind == Token::RParen) {
1063 Error(
"unexpected end of arguments.", Name);
1067 RHS = ParseExpr(ExpectType);
1069 NumberOrExprResult LHS_NOE = ParseNumberOrExpr();
1071 if (Tok.
kind == Token::RParen) {
1072 Error(
"unexpected end of arguments.", Name);
1077 if (LHS_NOE.isNumber()) {
1078 NumberOrExprResult RHS_NOE = ParseNumberOrExpr();
1080 if (RHS_NOE.isNumber()) {
1081 Error(
"ambiguous arguments to expression.", Name);
1083 RHS = RHS_NOE.getExpr();
1085 LHS = ParseNumberToken(RHS.get()->getWidth(), LHS_NOE.getNumber());
1088 LHS = LHS_NOE.getExpr();
1089 if (!LHS.isValid()) {
1091 RHS = ParseExpr(TypeResult());
1093 RHS = ParseExpr(LHS.get()->getWidth());
1098 ExpectRParen(
"unexpected argument to expression.");
1101ExprResult ParserImpl::ParseBinaryParenExpr(
const Token &Name,
1102 unsigned Kind,
bool IsFixed,
1104 ExprResult LHS, RHS;
1105 ParseMatchedBinaryArgs(Name, IsFixed ? TypeResult(ResTy) : TypeResult(),
1107 if (!LHS.isValid() || !RHS.isValid())
1108 return Builder->
Constant(0, ResTy);
1111 if (LHS_E->
getWidth() != RHS_E->getWidth()) {
1112 Error(
"type widths do not match in binary expression", Name);
1113 return Builder->
Constant(0, ResTy);
1117 case Expr::Add:
return Builder->
Add(LHS_E, RHS_E);
1118 case Expr::Sub:
return Builder->
Sub(LHS_E, RHS_E);
1119 case Expr::Mul:
return Builder->
Mul(LHS_E, RHS_E);
1120 case Expr::UDiv:
return Builder->
UDiv(LHS_E, RHS_E);
1121 case Expr::SDiv:
return Builder->
SDiv(LHS_E, RHS_E);
1122 case Expr::URem:
return Builder->
URem(LHS_E, RHS_E);
1123 case Expr::SRem:
return Builder->
SRem(LHS_E, RHS_E);
1125 case Expr::AShr:
return Builder->
AShr(LHS_E, RHS_E);
1126 case Expr::LShr:
return Builder->
LShr(LHS_E, RHS_E);
1127 case Expr::Shl:
return Builder->
Shl(LHS_E, RHS_E);
1129 case Expr::And:
return Builder->
And(LHS_E, RHS_E);
1130 case Expr::Or:
return Builder->
Or(LHS_E, RHS_E);
1131 case Expr::Xor:
return Builder->
Xor(LHS_E, RHS_E);
1133 case Expr::Eq:
return Builder->
Eq(LHS_E, RHS_E);
1134 case Expr::Ne:
return Builder->
Ne(LHS_E, RHS_E);
1135 case Expr::Ult:
return Builder->
Ult(LHS_E, RHS_E);
1136 case Expr::Ule:
return Builder->
Ule(LHS_E, RHS_E);
1137 case Expr::Ugt:
return Builder->
Ugt(LHS_E, RHS_E);
1138 case Expr::Uge:
return Builder->
Uge(LHS_E, RHS_E);
1139 case Expr::Slt:
return Builder->
Slt(LHS_E, RHS_E);
1140 case Expr::Sle:
return Builder->
Sle(LHS_E, RHS_E);
1141 case Expr::Sgt:
return Builder->
Sgt(LHS_E, RHS_E);
1142 case Expr::Sge:
return Builder->
Sge(LHS_E, RHS_E);
1144 Error(
"FIXME: unhandled kind.", Name);
1145 return Builder->
Constant(0, ResTy);
1149ExprResult ParserImpl::ParseSelectParenExpr(
const Token &Name,
1152 if (Tok.
kind == Token::RParen) {
1153 Error(
"unexpected end of arguments.", Name);
1155 return Builder->
Constant(0, ResTy);
1158 ExprResult Cond = ParseExpr(Expr::Bool);
1159 ExprResult LHS, RHS;
1160 ParseMatchedBinaryArgs(Name, ResTy, LHS, RHS);
1161 if (!Cond.isValid() || !LHS.isValid() || !RHS.isValid())
1162 return Builder->
Constant(0, ResTy);
1163 return Builder->
Select(Cond.get(), LHS.get(), RHS.get());
1168ExprResult ParserImpl::ParseConcatParenExpr(
const Token &Name,
1170 std::vector<ExprHandle> Kids;
1173 while (Tok.
kind != Token::RParen) {
1174 ExprResult E = ParseExpr(TypeResult());
1179 return Builder->
Constant(0, ResTy);
1182 Kids.push_back(E.get());
1188 if (Width != ResTy) {
1189 Error(
"concat does not match expected result size.");
1190 return Builder->
Constant(0, ResTy);
1194 return ConcatExpr::createN(Kids.size(), &Kids[0]);
1197IntegerResult ParserImpl::ParseIntegerConstant(
Expr::Width Type) {
1198 ExprResult Res = ParseNumber(Type);
1201 return IntegerResult();
1203 return cast<ConstantExpr>(Res.get())->getZExtValue(Type);
1206ExprResult ParserImpl::ParseExtractParenExpr(
const Token &Name,
1208 IntegerResult OffsetExpr = ParseIntegerConstant(Expr::Int32);
1209 ExprResult Child = ParseExpr(TypeResult());
1211 ExpectRParen(
"unexpected argument to expression.");
1213 if (!OffsetExpr.isValid() || !Child.isValid())
1214 return Builder->
Constant(0, ResTy);
1216 unsigned Offset = (unsigned) OffsetExpr.
get();
1217 if (Offset + ResTy > Child.get()->getWidth()) {
1218 Error(
"extract out-of-range of child expression.", Name);
1219 return Builder->
Constant(0, ResTy);
1222 return Builder->
Extract(Child.get(), Offset, ResTy);
1225ExprResult ParserImpl::ParseAnyReadParenExpr(
const Token &Name,
1228 NumberOrExprResult Index = ParseNumberOrExpr();
1229 VersionResult
Array = ParseVersionSpecifier();
1230 ExpectRParen(
"unexpected argument in read expression.");
1232 if (!
Array.isValid())
1233 return Builder->
Constant(0, ResTy);
1241 ExprResult IndexExpr;
1242 if (Index.isNumber())
1243 IndexExpr = ParseNumberToken(ArrayDomainType, Index.getNumber());
1245 IndexExpr = Index.getExpr();
1247 if (!IndexExpr.isValid())
1248 return Builder->
Constant(0, ResTy);
1249 else if (IndexExpr.get()->getWidth() != ArrayDomainType) {
1250 Error(
"index width does not match array domain.");
1251 return Builder->
Constant(0, ResTy);
1258 assert(0 &&
"Invalid kind.");
1259 return Builder->
Constant(0, ResTy);
1262 unsigned NumReads = ResTy / ArrayRangeType;
1263 if (ResTy != NumReads*ArrayRangeType) {
1264 Error(
"invalid ordered read (not multiple of range type).", Name);
1265 return Builder->
Constant(0, ResTy);
1267 std::vector<ExprHandle> Kids(NumReads);
1269 for (
unsigned i=0; i != NumReads; ++i) {
1274 OffsetIndex = AddExpr::create(OffsetIndex,
1275 Builder->
Constant(i, ArrayDomainType));
1276 Kids[i] = Builder->
Read(
Array.get(), OffsetIndex);
1279 std::reverse(Kids.begin(), Kids.end());
1281 return ConcatExpr::createN(NumReads, &Kids[0]);
1284 return Builder->
Read(
Array.get(), IndexExpr.get());
1290VersionResult ParserImpl::ParseVersionSpecifier() {
1292 if (Tok.
kind == Token::Identifier) {
1294 Label = GetOrCreateIdentifier(Tok);
1297 if (Tok.
kind != Token::Colon) {
1298 VersionSymTabTy::iterator it = VersionSymTab.find(Label);
1300 if (it == VersionSymTab.end()) {
1301 Error(
"invalid version reference.", LTok);
1302 return VersionResult(
false,
UpdateList(0, NULL));
1309 if (VersionSymTab.count(Label)) {
1310 Error(
"duplicate update list label definition.", LTok);
1315 VersionResult Res = ParseVersion();
1317 if (!Res.isValid()) {
1324 VersionSymTab.insert(std::make_pair(Label, Res.get()));
1332 NumberOrExprResult LHS;
1333 NumberOrExprResult RHS;
1337 WriteInfo(NumberOrExprResult _LHS, NumberOrExprResult _RHS,
1338 Token _LHSTok,
Token _RHSTok) : LHS(_LHS), RHS(_RHS),
1339 LHSTok(_LHSTok), RHSTok(_RHSTok) {
1347VersionResult ParserImpl::ParseVersion() {
1348 if (Tok.
kind != Token::LSquare)
1349 return VersionResult(
false,
UpdateList(0, NULL));
1351 std::vector<WriteInfo> Writes;
1355 NumberOrExprResult LHS = ParseNumberOrExpr();
1357 if (Tok.
kind != Token::Equals) {
1358 Error(
"expected '='.", Tok);
1364 NumberOrExprResult RHS = ParseNumberOrExpr();
1366 Writes.push_back(WriteInfo(LHS, RHS, LHSTok, RHSTok));
1368 if (Tok.
kind == Token::Comma)
1373 ExpectRSquare(
"expected close of update list");
1377 if (Tok.
kind != Token::At) {
1378 Error(
"expected '@'.", Tok);
1379 return VersionResult(
false,
UpdateList(0, NULL));
1382 ConsumeExpectedToken(Token::At);
1384 VersionResult BaseRes = ParseVersionSpecifier();
1385 if (!BaseRes.isValid())
1388 Base = BaseRes.get();
1393 for (std::vector<WriteInfo>::reverse_iterator it = Writes.rbegin(),
1394 ie = Writes.rend(); it != ie; ++it) {
1395 const WriteInfo &WI = *it;
1396 ExprResult LHS, RHS;
1399 if (WI.LHS.isNumber()) {
1400 LHS = ParseNumberToken(ArrayDomainType, WI.LHS.getNumber());
1402 LHS = WI.LHS.getExpr();
1403 if (LHS.isValid() && LHS.get()->getWidth() != ArrayDomainType) {
1404 Error(
"invalid write index (doesn't match array domain).", WI.LHSTok);
1409 if (WI.RHS.isNumber()) {
1410 RHS = ParseNumberToken(ArrayRangeType, WI.RHS.getNumber());
1412 RHS = WI.RHS.getExpr();
1413 if (RHS.isValid() && RHS.get()->getWidth() != ArrayRangeType) {
1414 Error(
"invalid write value (doesn't match array range).", WI.RHSTok);
1419 if (LHS.isValid() && RHS.isValid())
1420 Base.extend(LHS.get(), RHS.get());
1427ExprResult ParserImpl::ParseNumber(
Expr::Width Type) {
1428 ExprResult Res = ParseNumberToken(Type, Tok);
1429 ConsumeExpectedToken(Token::Number);
1435ExprResult ParserImpl::ParseNumberToken(
Expr::Width Type,
const Token &Tok) {
1436 const char *S = Tok.
start;
1438 unsigned Radix = 10, RadixBits = 4;
1439 bool HasMinus =
false;
1445 }
else if (S[0] ==
'-') {
1452 if ((Tok.
length >= 2 && S[0] ==
'0') &&
1453 (S[1] ==
'b' || S[1] ==
'o' || S[1] ==
'x')) {
1457 }
else if (S[1] ==
'o') {
1469 Error(
"invalid numeric token (no digits).", Tok);
1475 APInt Val(RadixBits * N, 0);
1476 APInt RadixVal(Val.getBitWidth(), Radix);
1477 APInt DigitVal(Val.getBitWidth(), 0);
1478 for (
unsigned i=0; i<N; ++i) {
1479 unsigned Digit, Char = S[i];
1484 if (
'0' <= Char && Char <=
'9')
1486 else if (
'a' <= Char && Char <=
'z')
1487 Digit = Char -
'a' + 10;
1488 else if (
'A' <= Char && Char <=
'Z')
1489 Digit = Char -
'A' + 10;
1491 Error(
"invalid character in numeric token.", Tok);
1495 if (Digit >= Radix) {
1496 Error(
"invalid character in numeric token (out of range).", Tok);
1501 Val = Val * RadixVal + DigitVal;
1508 if (Type < Val.getBitWidth())
1509 Val=Val.trunc(Type);
1510 else if (Type > Val.getBitWidth())
1513 return ExprResult(Builder->
Constant(Val));
1519TypeResult ParserImpl::ParseTypeSpecifier() {
1520 assert(Tok.
kind == Token::KWWidth &&
"Unexpected token.");
1523 int width = atoi(std::string(Tok.
start+1,Tok.
length-1).c_str());
1527 return TypeResult(width);
1530void ParserImpl::Error(
const char *Message,
const Token &At) {
1532 if (MaxErrors && NumErrors >= MaxErrors)
1535 llvm::errs() << Filename
1537 <<
": error: " << Message <<
"\n";
1540 if (At.
kind == Token::EndOfFile)
1544 const char *LineBegin = At.
start, *LineEnd = At.
start,
1545 *BufferBegin = TheMemoryBuffer->getBufferStart(),
1546 *BufferEnd = TheMemoryBuffer->getBufferEnd();
1549 while (LineBegin > BufferBegin &&
1550 LineBegin[-1] !=
'\r' && LineBegin[-1] !=
'\n')
1552 while (LineEnd < BufferEnd &&
1553 LineEnd[0] !=
'\r' && LineEnd[0] !=
'\n')
1557 llvm::errs() << std::string(LineBegin, LineEnd) <<
"\n";
1561 for (
const char *S=LineBegin; S != At.
start; ++S)
1562 llvm::errs() << (isspace(*S) ? *S :
' ');
1564 for (
unsigned i=0; i<At.
length; ++i)
1565 llvm::errs() <<
'~';
1567 llvm::errs() <<
'^';
1568 llvm::errs() <<
'\n';
1571ParserImpl::~ParserImpl() {
1577 std::set<const Identifier*> freedNodes;
1578 for (IdentifierTabTy::iterator pi = IdentifierTab.begin(),
1579 pe = IdentifierTab.end();
1582 if (freedNodes.insert(
id).second)
1585 for (ExprSymTabTy::iterator pi = ExprSymTab.begin(),
1586 pe = ExprSymTab.end();
1589 if (freedNodes.insert(
id).second)
1592 for (VersionSymTabTy::iterator pi = VersionSymTab.begin(),
1593 pe = VersionSymTab.end();
1596 if (freedNodes.insert(
id).second)
1607 llvm::outs() <<
"array " <<
Root->
name
1609 <<
" : " <<
'w' <<
Domain <<
" -> " <<
'w' <<
Range <<
" = ";
1612 llvm::outs() <<
"symbolic\n";
1614 llvm::outs() <<
'[';
1615 for (
unsigned i = 0, e =
Root->
size; i != e; ++i) {
1617 llvm::outs() <<
" ";
1620 llvm::outs() <<
"]\n";
1625 const ExprHandle *ValuesBegin = 0, *ValuesEnd = 0;
1626 const Array *
const* ObjectsBegin = 0, *
const* ObjectsEnd = 0;
1628 ValuesBegin = &
Values[0];
1629 ValuesEnd = ValuesBegin +
Values.size();
1633 ObjectsEnd = ObjectsBegin +
Objects.size();
1636 ValuesBegin, ValuesEnd, ObjectsBegin, ObjectsEnd,
1649 ExprBuilder *Builder,
bool ClearArrayAfterQuery) {
1650 ParserImpl *P =
new ParserImpl(Filename, MB, Builder, ClearArrayAfterQuery);
static bool LookupExprInfo(const Token &Tok, unsigned &Kind, bool &IsFixed, int &NumArgs)
@ eMacroKind_LastMacroKind
#define SetOK(kind, isfixed, numargs)
Provides an interface for creating and destroying Array objects.
const Array * CreateArray(const std::string &_name, uint64_t _size, const ref< ConstantExpr > *constantValuesBegin=0, const ref< ConstantExpr > *constantValuesEnd=0, Expr::Width _domain=Expr::Int32, Expr::Width _range=Expr::Int8)
Create an Array object.
bool isSymbolicArray() const
const std::vector< ref< ConstantExpr > > constantValues
ExprBuilder - Base expression builder class.
virtual ref< Expr > Ule(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > URem(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Xor(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Sle(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Eq(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Or(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Not(const ref< Expr > &LHS)=0
virtual ref< Expr > ZExt(const ref< Expr > &LHS, Expr::Width W)=0
virtual ref< Expr > UDiv(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Uge(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Extract(const ref< Expr > &LHS, unsigned Offset, Expr::Width W)=0
virtual ref< Expr > And(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Sge(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > LShr(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > SExt(const ref< Expr > &LHS, Expr::Width W)=0
virtual ref< Expr > Mul(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Select(const ref< Expr > &Cond, const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Slt(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Ne(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > SRem(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > AShr(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Shl(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Sub(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > SDiv(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Ult(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Read(const UpdateList &Updates, const ref< Expr > &Index)=0
virtual ref< Expr > Ugt(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Sgt(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Constant(const llvm::APInt &Value)=0
virtual ref< Expr > Add(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
static void printQuery(llvm::raw_ostream &os, const ConstraintSet &constraints, const ref< Expr > &q, const ref< Expr > *evalExprsBegin=0, const ref< Expr > *evalExprsEnd=0, const Array *const *evalArraysBegin=0, const Array *const *evalArraysEnd=0, bool printArrayDecls=true)
Class representing symbolic expressions.
virtual Width getWidth() const =0
unsigned Width
The type of an expression is simply its width, in bits.
Class representing a complete list of updates into an array.
const Array * Root
Root - The root array object defined by this decl.
const unsigned Domain
Domain - The width of indices.
const unsigned Range
Range - The width of array contents.
virtual void dump()
dump - Dump the AST node to stderr.
Decl - Base class for top level declarations.
Lexer - Interface for lexing tokens from a .kquery language file.
Token & Lex(Token &Result)
Parser - Public interface for parsing a .kquery language file.
static Parser * Create(const std::string Name, const llvm::MemoryBuffer *MB, ExprBuilder *Builder, bool ClearArrayAfterQuery)
virtual unsigned GetNumErrors() const =0
GetNumErrors - Return the number of encountered errors.
virtual void SetMaxErrors(unsigned N)=0
SetMaxErrors - Suppress anything beyond the first N errors.
virtual Decl * ParseTopLevelDecl()=0
const std::vector< const Array * > Objects
virtual void dump()
dump - Dump the AST node to stderr.
const std::vector< ExprHandle > Constraints
const std::vector< ExprHandle > Values
Identifier - Wrapper for a uniqued string.
const char * start
The token kind.
unsigned column
The line number of the start of this token.
unsigned line
The length of the token.
unsigned length
The beginning of the token string.
bool isKeyword() const
isKeyword - True if this token is a keyword.