klee
Parser.cpp
Go to the documentation of this file.
1//===-- Parser.cpp --------------------------------------------------------===//
2//
3// The KLEE Symbolic Virtual Machine
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "klee/Config/Version.h"
17#include "klee/Solver/Solver.h"
18
19#include "llvm/ADT/APInt.h"
20#include "llvm/Support/MemoryBuffer.h"
21#include "llvm/Support/raw_ostream.h"
22
23#include <cassert>
24#include <map>
25#include <cstring>
26
27using namespace llvm;
28using namespace klee;
29using namespace klee::expr;
30
31namespace {
33 template<typename T>
34 struct ParseResult {
35 bool IsValid;
36 T Value;
37
38 public:
39 ParseResult() : IsValid(false), Value() {}
40 ParseResult(T _Value) : IsValid(true), Value(_Value) {}
41 ParseResult(bool _IsValid, T _Value) : IsValid(_IsValid), Value(_Value) {}
42
43 bool isValid() {
44 return IsValid;
45 }
46 T get() {
47 assert(IsValid && "get() on invalid ParseResult!");
48 return Value;
49 }
50 };
51
52 class ExprResult {
53 bool IsValid;
54 ExprHandle Value;
55
56 public:
57 ExprResult() : IsValid(false) {}
58 ExprResult(ExprHandle _Value) : IsValid(true), Value(_Value) {}
59 ExprResult(ref<ConstantExpr> _Value) : IsValid(true), Value(_Value.get()) {}
60 ExprResult(bool _IsValid, ExprHandle _Value) : IsValid(_IsValid), Value(_Value) {}
61
62 bool isValid() {
63 return IsValid;
64 }
65 ExprHandle get() {
66 assert(IsValid && "get() on invalid ParseResult!");
67 return Value;
68 }
69 };
70
71 typedef ParseResult<Decl*> DeclResult;
72 typedef ParseResult<Expr::Width> TypeResult;
73 typedef ParseResult<VersionHandle> VersionResult;
74 typedef ParseResult<uint64_t> IntegerResult;
75
79 class NumberOrExprResult {
80 Token AsNumber;
81 ExprResult AsExpr;
82 bool IsNumber;
83
84 public:
85 NumberOrExprResult() : IsNumber(false) {}
86 explicit NumberOrExprResult(Token _AsNumber) : AsNumber(_AsNumber),
87 IsNumber(true) {}
88 explicit NumberOrExprResult(ExprResult _AsExpr) : AsExpr(_AsExpr),
89 IsNumber(false) {}
90
91 bool isNumber() const { return IsNumber; }
92 const Token &getNumber() const {
93 assert(IsNumber && "Invalid accessor call.");
94 return AsNumber;
95 }
96 const ExprResult &getExpr() const {
97 assert(!IsNumber && "Invalid accessor call.");
98 return AsExpr;
99 }
100 };
101
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;
107
108 const std::string Filename;
109 const MemoryBuffer *TheMemoryBuffer;
110 ExprBuilder *Builder;
111 ArrayCache TheArrayCache;
112 bool ClearArrayAfterQuery;
113
114 Lexer TheLexer;
115 unsigned MaxErrors;
116 unsigned NumErrors;
117
118 // FIXME: Use LLVM symbol tables?
119 IdentifierTabTy IdentifierTab;
120
121 std::map<const Identifier*, const ArrayDecl*> ArraySymTab;
122 ExprSymTabTy ExprSymTab;
123 VersionSymTabTy VersionSymTab;
124
126 Token Tok;
127
129 unsigned ParenLevel;
131 unsigned SquareLevel;
132
133 /* Core parsing functionality */
134
135 const Identifier *GetOrCreateIdentifier(const Token &Tok);
136
137 void GetNextNonCommentToken() {
138 do {
139 TheLexer.Lex(Tok);
140 } while (Tok.kind == Token::Comment);
141 }
142
144 void ConsumeToken() {
145 assert(Tok.kind != Token::LParen && Tok.kind != Token::RParen &&
146 Tok.kind != Token::LSquare && Tok.kind != Token::RSquare);
147 GetNextNonCommentToken();
148 }
149
152 void ConsumeExpectedToken(Token::Kind k) {
153 assert(Tok.kind != Token::LParen && Tok.kind != Token::RParen &&
154 Tok.kind != Token::LSquare && Tok.kind != Token::RSquare);
155 _ConsumeExpectedToken(k);
156 }
157 void _ConsumeExpectedToken(Token::Kind k) {
158 assert(Tok.kind == k && "Unexpected token!");
159 GetNextNonCommentToken();
160 }
161
162 void ConsumeLParen() {
163 ++ParenLevel;
164 _ConsumeExpectedToken(Token::LParen);
165 }
166
167 void ConsumeRParen() {
168 if (ParenLevel) // Cannot go below zero.
169 --ParenLevel;
170 _ConsumeExpectedToken(Token::RParen);
171 }
172
173 void ConsumeLSquare() {
174 ++SquareLevel;
175 _ConsumeExpectedToken(Token::LSquare);
176 }
177
178 void ConsumeRSquare() {
179 if (SquareLevel) // Cannot go below zero.
180 --SquareLevel;
181 _ConsumeExpectedToken(Token::RSquare);
182 }
183
184 void ConsumeAnyToken() {
185 switch (Tok.kind) {
186 case Token::LParen: return ConsumeLParen();
187 case Token::RParen: return ConsumeRParen();
188 case Token::LSquare: return ConsumeLSquare();
189 case Token::RSquare: return ConsumeRSquare();
190 default:
191 return ConsumeToken();
192 }
193 }
194
195 /* Utility functions */
196
199 void SkipUntilRParen(unsigned Level) {
200 // FIXME: I keep wavering on whether it is an error to call this
201 // with the current token an rparen. In most cases this should
202 // have been handled differently (error reported,
203 // whatever). Audit & resolve.
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) {
208 ConsumeRParen();
209 break;
210 }
211 ConsumeAnyToken();
212 }
213 }
214
217 void SkipUntilRParen() {
218 SkipUntilRParen(ParenLevel);
219 }
220
224 void ExpectRParen(const char *Msg) {
225 if (Tok.kind == Token::EndOfFile) {
226 // FIXME: Combine with Msg
227 Error("expected ')' but found end-of-file.", Tok);
228 } else if (Tok.kind != Token::RParen) {
229 Error(Msg, Tok);
230 SkipUntilRParen();
231 } else {
232 ConsumeRParen();
233 }
234 }
235
238 void SkipUntilRSquare(unsigned Level) {
239 // FIXME: I keep wavering on whether it is an error to call this
240 // with the current token an rparen. In most cases this should
241 // have been handled differently (error reported,
242 // whatever). Audit & resolve.
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) {
247 ConsumeRSquare();
248 break;
249 }
250 ConsumeAnyToken();
251 }
252 }
253
256 void SkipUntilRSquare() {
257 SkipUntilRSquare(ParenLevel);
258 }
259
263 void ExpectRSquare(const char *Msg) {
264 if (Tok.kind == Token::EndOfFile) {
265 // FIXME: Combine with Msg
266 Error("expected ']' but found end-of-file.", Tok);
267 } else if (Tok.kind != Token::RSquare) {
268 Error(Msg, Tok);
269 SkipUntilRSquare();
270 } else {
271 ConsumeRSquare();
272 }
273 }
274
275 /*** Grammar productions ****/
276
277 /* Top level decls */
278
279 DeclResult ParseArrayDecl();
280 DeclResult ParseExprVarDecl();
281 DeclResult ParseVersionVarDecl();
282 DeclResult ParseCommandDecl();
283
284 /* Commands */
285
286 DeclResult ParseQueryCommand();
287
288 /* Etc. */
289
290 NumberOrExprResult ParseNumberOrExpr();
291 IntegerResult ParseIntegerConstant(Expr::Width Type);
292
293 ExprResult ParseExpr(TypeResult ExpectedType);
294 ExprResult ParseParenExpr(TypeResult ExpectedType);
295 ExprResult ParseUnaryParenExpr(const Token &Name,
296 unsigned Kind, bool IsFixed,
297 Expr::Width ResTy);
298 ExprResult ParseBinaryParenExpr(const Token &Name,
299 unsigned Kind, bool IsFixed,
300 Expr::Width ResTy);
301 ExprResult ParseSelectParenExpr(const Token &Name, Expr::Width ResTy);
302 ExprResult ParseConcatParenExpr(const Token &Name, Expr::Width ResTy);
303 ExprResult ParseExtractParenExpr(const Token &Name, Expr::Width ResTy);
304 ExprResult ParseAnyReadParenExpr(const Token &Name,
305 unsigned Kind,
306 Expr::Width ResTy);
307 void ParseMatchedBinaryArgs(const Token &Name,
308 TypeResult ExpectType,
309 ExprResult &LHS, ExprResult &RHS);
310 ExprResult ParseNumber(Expr::Width Width);
311 ExprResult ParseNumberToken(Expr::Width Width, const Token &Tok);
312
313 VersionResult ParseVersionSpecifier();
314 VersionResult ParseVersion();
315
316 TypeResult ParseTypeSpecifier();
317
318 /*** Diagnostics ***/
319
320 void Error(const char *Message, const Token &At);
321 void Error(const char *Message) { Error(Message, Tok); }
322
323 public:
324 ParserImpl(const std::string _Filename, const MemoryBuffer *MB,
325 ExprBuilder *_Builder, bool _ClearArrayAfterQuery)
326 : Filename(_Filename), TheMemoryBuffer(MB), Builder(_Builder),
327 ClearArrayAfterQuery(_ClearArrayAfterQuery), TheLexer(MB),
328 MaxErrors(~0u), NumErrors(0) {}
329
330 virtual ~ParserImpl();
331
334 void Initialize() {
335 ParenLevel = SquareLevel = 0;
336
337 ConsumeAnyToken();
338 }
339
340 /* Parser interface implementation */
341
342 virtual Decl *ParseTopLevelDecl();
343
344 virtual void SetMaxErrors(unsigned N) {
345 MaxErrors = N;
346 }
347
348 virtual unsigned GetNumErrors() const {
349 return NumErrors;
350 }
351 };
352}
353
354const Identifier *ParserImpl::GetOrCreateIdentifier(const Token &Tok) {
355 // FIXME: Make not horribly inefficient please.
356 assert(Tok.kind == Token::Identifier && "Expected only identifier tokens.");
357 std::string Name(Tok.start, Tok.length);
358 IdentifierTabTy::iterator it = IdentifierTab.find(Name);
359 if (it != IdentifierTab.end())
360 return it->second;
361
362 Identifier *I = new Identifier(Name);
363 IdentifierTab.insert(std::make_pair(Name, I));
364
365 return I;
366}
367
368Decl *ParserImpl::ParseTopLevelDecl() {
369 // Repeat until success or EOF.
370 while (Tok.kind != Token::EndOfFile) {
371 switch (Tok.kind) {
372 case Token::KWArray: {
373 DeclResult Res = ParseArrayDecl();
374 if (Res.isValid())
375 return Res.get();
376 break;
377 }
378
379 case Token::LParen: {
380 DeclResult Res = ParseCommandDecl();
381 if (Res.isValid())
382 return Res.get();
383 break;
384 }
385
386 default:
387 Error("expected 'array' or '(' token.");
388 ConsumeAnyToken();
389 }
390 }
391
392 return 0;
393}
394
401DeclResult ParserImpl::ParseArrayDecl() {
402 // FIXME: Recovery here is horrible, we need to scan to next decl start or
403 // something.
404 ConsumeExpectedToken(Token::KWArray);
405
406 if (Tok.kind != Token::Identifier) {
407 Error("expected identifier token.");
408 return DeclResult();
409 }
410
411 Token Name = Tok;
412 IntegerResult Size;
413 TypeResult DomainType;
414 TypeResult RangeType;
415 std::vector< ref<ConstantExpr> > Values;
416
417 ConsumeToken();
418
419 if (Tok.kind != Token::LSquare) {
420 Error("expected '['.");
421 goto exit;
422 }
423 ConsumeLSquare();
424
425 if (Tok.kind != Token::RSquare) {
426 Size = ParseIntegerConstant(64);
427 }
428 if (Tok.kind != Token::RSquare) {
429 Error("expected ']'.");
430 goto exit;
431 }
432 ConsumeRSquare();
433
434 if (Tok.kind != Token::Colon) {
435 Error("expected ':'.");
436 goto exit;
437 }
438 ConsumeExpectedToken(Token::Colon);
439
440 DomainType = ParseTypeSpecifier();
441 if (Tok.kind != Token::Arrow) {
442 Error("expected '->'.");
443 goto exit;
444 }
445 ConsumeExpectedToken(Token::Arrow);
446
447 RangeType = ParseTypeSpecifier();
448 if (Tok.kind != Token::Equals) {
449 Error("expected '='.");
450 goto exit;
451 }
452 ConsumeExpectedToken(Token::Equals);
453
454 if (Tok.kind == Token::KWSymbolic) {
455 ConsumeExpectedToken(Token::KWSymbolic);
456 } else if (Tok.kind == Token::LSquare) {
457 ConsumeLSquare();
458 while (Tok.kind != Token::RSquare) {
459 if (Tok.kind == Token::EndOfFile) {
460 Error("unexpected end of file.");
461 goto exit;
462 }
463
464 ExprResult Res = ParseNumber(RangeType.get());
465 if (Res.isValid())
466 Values.push_back(cast<ConstantExpr>(Res.get()));
467 }
468 ConsumeRSquare();
469 } else {
470 Error("expected 'symbolic' or '['.");
471 goto exit;
472 }
473
474 // Type check size.
475 if (!Size.isValid()) {
476 if (Values.empty()) {
477 Error("unsized arrays are not yet supported.");
478 Size = 1;
479 } else {
480 Size = Values.size();
481 }
482 }
483
484 if (!Values.empty()) {
485 if (Size.get() != Values.size()) {
486 // FIXME: Lame message.
487 Error("constant arrays must be completely specified.");
488 Values.clear();
489 }
490
491 // for (unsigned i = 0; i != Size.get(); ++i) {
492 // TODO: Check: Must be constant expression.
493 //}
494 }
495
496 // FIXME: Validate that size makes sense for domain type.
497
498 if (DomainType.get() != Expr::Int32) {
499 Error("array domain must currently be w32.");
500 DomainType = Expr::Int32;
501 Values.clear();
502 }
503
504 if (RangeType.get() != Expr::Int8) {
505 Error("array domain must currently be w8.");
506 RangeType = Expr::Int8;
507 Values.clear();
508 }
509
510 // FIXME: Validate that this array is undeclared.
511
512 exit:
513 if (!Size.isValid())
514 Size = 1;
515 if (!DomainType.isValid())
516 DomainType = 32;
517 if (!RangeType.isValid())
518 RangeType = 8;
519
520 // FIXME: Array should take domain and range.
521 const Identifier *Label = GetOrCreateIdentifier(Name);
522 const Array *Root;
523 if (!Values.empty())
524 Root = TheArrayCache.CreateArray(Label->Name, Size.get(), &Values[0],
525 &Values[0] + Values.size());
526 else
527 Root = TheArrayCache.CreateArray(Label->Name, Size.get());
528 ArrayDecl *AD = new ArrayDecl(Label, Size.get(),
529 DomainType.get(), RangeType.get(), Root);
530
531 ArraySymTab[Label] = AD;
532
533 // Create the initial version reference.
534 VersionSymTab.insert(std::make_pair(Label,
535 UpdateList(Root, NULL)));
536
537 return AD;
538}
539
544DeclResult ParserImpl::ParseCommandDecl() {
545 ConsumeLParen();
546
547 if (!Tok.isKeyword()) {
548 Error("malformed command.");
549 SkipUntilRParen();
550 return DeclResult();
551 }
552
553 switch (Tok.kind) {
554 case Token::KWQuery:
555 return ParseQueryCommand();
556
557 default:
558 Error("malformed command (unexpected keyword).");
559 SkipUntilRParen();
560 return DeclResult();
561 }
562}
563
568DeclResult ParserImpl::ParseQueryCommand() {
569 std::vector<ExprHandle> Constraints;
570 std::vector<ExprHandle> Values;
571 std::vector<const Array*> Objects;
572 ExprResult Res;
573
574 // FIXME: We need a command for this. Or something.
575 ExprSymTab.clear();
576 VersionSymTab.clear();
577
578 // Reinsert initial array versions.
579 // FIXME: Remove this!
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,
583 UpdateList(it->second->Root, NULL)));
584 }
585
586
587 ConsumeExpectedToken(Token::KWQuery);
588 if (Tok.kind != Token::LSquare) {
589 Error("malformed query, expected constraint list.");
590 SkipUntilRParen();
591 return DeclResult();
592 }
593
594 ConsumeLSquare();
595 // FIXME: Should avoid reading past unbalanced parens here.
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));
600 goto exit;
601 }
602
603 ExprResult Constraint = ParseExpr(TypeResult(Expr::Bool));
604 if (Constraint.isValid())
605 Constraints.push_back(Constraint.get());
606 }
607 ConsumeRSquare();
608
609 Res = ParseExpr(TypeResult(Expr::Bool));
610 if (!Res.isValid()) // Error emitted by ParseExpr.
611 Res = ExprResult(Builder->Constant(0, Expr::Bool));
612
613 // Return if there are no optional lists of things to evaluate.
614 if (Tok.kind == Token::RParen)
615 goto exit;
616
617 if (Tok.kind != Token::LSquare) {
618 Error("malformed query, expected expression list.");
619 SkipUntilRParen();
620 return DeclResult();
621 }
622
623 ConsumeLSquare();
624 // FIXME: Should avoid reading past unbalanced parens here.
625 while (Tok.kind != Token::RSquare) {
626 if (Tok.kind == Token::EndOfFile) {
627 Error("unexpected end of file.");
628 goto exit;
629 }
630
631 ExprResult Res = ParseExpr(TypeResult());
632 if (Res.isValid())
633 Values.push_back(Res.get());
634 }
635 ConsumeRSquare();
636
637 // Return if there are no optional lists of things to evaluate.
638 if (Tok.kind == Token::RParen)
639 goto exit;
640
641 if (Tok.kind != Token::LSquare) {
642 Error("malformed query, expected array list.");
643 SkipUntilRParen();
644 return DeclResult();
645 }
646
647 ConsumeLSquare();
648 // FIXME: Should avoid reading past unbalanced parens here.
649 while (Tok.kind != Token::RSquare) {
650 if (Tok.kind == Token::EndOfFile) {
651 Error("unexpected end of file.");
652 goto exit;
653 }
654
655 // FIXME: Factor out.
656 if (Tok.kind != Token::Identifier) {
657 Error("unexpected token.");
658 ConsumeToken();
659 continue;
660 }
661
662 Token LTok = Tok;
663 const Identifier *Label = GetOrCreateIdentifier(Tok);
664 ConsumeToken();
665
666 // Lookup array.
667 std::map<const Identifier*, const ArrayDecl*>::iterator
668 it = ArraySymTab.find(Label);
669
670 if (it == ArraySymTab.end()) {
671 Error("unknown array", LTok);
672 } else {
673 Objects.push_back(it->second->Root);
674 }
675 }
676 ConsumeRSquare();
677
678 exit:
679 if (Tok.kind != Token::EndOfFile)
680 ExpectRParen("unexpected argument to 'query'.");
681
682 // If we assume that the queries are independent, we clear the array
683 // table from the previous declarations
684 if (ClearArrayAfterQuery)
685 ArraySymTab.clear();
686
687 return new QueryCommand(Constraints, Res.get(), Values, Objects);
688}
689
692NumberOrExprResult ParserImpl::ParseNumberOrExpr() {
693 if (Tok.kind == Token::Number){
694 Token Num = Tok;
695 ConsumeToken();
696 return NumberOrExprResult(Num);
697 } else {
698 return NumberOrExprResult(ParseExpr(TypeResult()));
699 }
700}
701
710ExprResult ParserImpl::ParseExpr(TypeResult ExpectedType) {
711 // FIXME: Is it right to need to do this here?
712 if (Tok.kind == Token::EndOfFile) {
713 Error("unexpected end of file.");
714 return ExprResult();
715 }
716
717 if (Tok.kind == Token::KWFalse || Tok.kind == Token::KWTrue) {
718 bool Value = Tok.kind == Token::KWTrue;
719 ConsumeToken();
720 return ExprResult(Builder->Constant(Value, Expr::Bool));
721 }
722
723 if (Tok.kind == Token::Number) {
724 if (!ExpectedType.isValid()) {
725 Error("cannot infer type of number.");
726 ConsumeToken();
727 return ExprResult();
728 }
729
730 return ParseNumber(ExpectedType.get());
731 }
732
733 const Identifier *Label = 0;
734 if (Tok.kind == Token::Identifier) {
735 Token LTok = Tok;
736 Label = GetOrCreateIdentifier(Tok);
737 ConsumeToken();
738
739 if (Tok.kind != Token::Colon) {
740 ExprSymTabTy::iterator it = ExprSymTab.find(Label);
741
742 if (it == ExprSymTab.end()) {
743 Error("invalid expression label reference.", LTok);
744 return ExprResult();
745 }
746
747 return it->second;
748 }
749
750 ConsumeToken();
751 if (ExprSymTab.count(Label)) {
752 Error("duplicate expression label definition.", LTok);
753 Label = 0;
754 }
755 }
756
757 Token Start = Tok;
758 ExprResult Res = ParseParenExpr(ExpectedType);
759 if (!Res.isValid()) {
760 // If we know the type, define the identifier just so we don't get
761 // use-of-undef errors.
762 // FIXME: Maybe we should let the symbol table map to invalid
763 // entries?
764 if (Label && ExpectedType.isValid()) {
765 ref<Expr> Value = Builder->Constant(0, ExpectedType.get());
766 ExprSymTab.insert(std::make_pair(Label, Value));
767 }
768 return Res;
769 } else if (ExpectedType.isValid()) {
770 // Type check result.
771 if (Res.get()->getWidth() != ExpectedType.get()) {
772 // FIXME: Need more info, and range
773 Error("expression has incorrect type.", Start);
774 return ExprResult();
775 }
776 }
777
778 if (Label)
779 ExprSymTab.insert(std::make_pair(Label, Res.get()));
780 return Res;
781}
782
783// Additional kinds for macro forms.
785 eMacroKind_ReadLSB = Expr::LastKind + 1, // Multibyte read
786 eMacroKind_ReadMSB, // Multibyte write
787 eMacroKind_Neg, // 0 - x // CrC: will disappear soon
788 eMacroKind_Concat, // Magic concatenation syntax
791
802static bool LookupExprInfo(const Token &Tok, unsigned &Kind,
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.");
807
808 switch (Tok.length) {
809 case 2:
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);
814
815 if (memcmp(Tok.start, "Or", 2) == 0)
816 return SetOK(Expr::Or, true, 2);
817 break;
818
819 case 3:
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);
826
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);
835
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);
852 break;
853
854
855
856 case 4:
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);
863
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);
872
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);
877 break;
878
879 case 6:
880 if (memcmp(Tok.start, "Concat", 6) == 0)
881 return SetOK(eMacroKind_Concat, false, -1);
882 if (memcmp(Tok.start, "Select", 6) == 0)
883 return SetOK(Expr::Select, false, 3);
884 break;
885
886 case 7:
887 if (memcmp(Tok.start, "Extract", 7) == 0)
888 return SetOK(Expr::Extract, false, -1);
889 if (memcmp(Tok.start, "ReadLSB", 7) == 0)
890 return SetOK(eMacroKind_ReadLSB, true, -1);
891 if (memcmp(Tok.start, "ReadMSB", 7) == 0)
892 return SetOK(eMacroKind_ReadMSB, true, -1);
893 break;
894 }
895
896 return false;
897#undef SetOK
898}
899
907ExprResult ParserImpl::ParseParenExpr(TypeResult FIXME_UNUSED) {
908 if (Tok.kind != Token::LParen) {
909 Error("unexpected token.");
910 ConsumeAnyToken();
911 return ExprResult();
912 }
913
914 ConsumeLParen();
915
916 // Check for coercion case (w32 11).
917 if (Tok.kind == Token::KWWidth) {
918 TypeResult ExpectedType = ParseTypeSpecifier();
919
920 if (Tok.kind != Token::Number) {
921 Error("coercion can only apply to a number.");
922 SkipUntilRParen();
923 return ExprResult();
924 }
925
926 // Make sure this was a type specifier we support.
927 ExprResult Res;
928 if (ExpectedType.isValid())
929 Res = ParseNumber(ExpectedType.get());
930 else
931 ConsumeToken();
932
933 ExpectRParen("unexpected argument in coercion.");
934 return Res;
935 }
936
937 if (Tok.kind != Token::Identifier) {
938 Error("unexpected token, expected expression.");
939 SkipUntilRParen();
940 return ExprResult();
941 }
942
943 Token Name = Tok;
944 ConsumeToken();
945
946 // FIXME: Use invalid type (i.e. width==0)?
947 Token TypeTok = Tok;
948 bool HasType = TypeTok.kind == Token::KWWidth;
949 TypeResult Type = HasType ? ParseTypeSpecifier() : Expr::Bool;
950
951 // FIXME: For now just skip to rparen on error. It might be nice
952 // to try and actually parse the child nodes though for error
953 // messages & better recovery?
954 if (!Type.isValid()) {
955 SkipUntilRParen();
956 return ExprResult();
957 }
958 Expr::Width ResTy = Type.get();
959
960 unsigned ExprKind;
961 bool IsFixed;
962 int NumArgs;
963 if (!LookupExprInfo(Name, ExprKind, IsFixed, NumArgs)) {
964 // FIXME: For now just skip to rparen on error. It might be nice
965 // to try and actually parse the child nodes though for error
966 // messages & better recovery?
967 Error("unknown expression kind.", Name);
968 SkipUntilRParen();
969 return ExprResult();
970 }
971
972 // See if we have to parse this form specially.
973 if (NumArgs == -1) {
974 switch (ExprKind) {
976 return ParseConcatParenExpr(Name, ResTy);
977
978 case Expr::Extract:
979 return ParseExtractParenExpr(Name, ResTy);
980
983 case Expr::Read:
984 return ParseAnyReadParenExpr(Name, ExprKind, ResTy);
985
986 default:
987 Error("internal error, unimplemented special form.", Name);
988 SkipUntilRParen();
989 return ExprResult(Builder->Constant(0, ResTy));
990 }
991 }
992
993 switch (NumArgs) {
994 case 1:
995 return ParseUnaryParenExpr(Name, ExprKind, IsFixed, ResTy);
996 case 2:
997 return ParseBinaryParenExpr(Name, ExprKind, IsFixed, ResTy);
998 case 3:
999 if (ExprKind == Expr::Select) {
1000 return ParseSelectParenExpr(Name, ResTy);
1001 } else {
1002 assert(0 && "Invalid ternary expression kind.");
1003 }
1004 default:
1005 assert(0 && "Invalid argument kind (number of args).");
1006 return ExprResult();
1007 }
1008}
1009
1010ExprResult ParserImpl::ParseUnaryParenExpr(const Token &Name,
1011 unsigned Kind, bool IsFixed,
1012 Expr::Width ResTy) {
1013 if (Tok.kind == Token::RParen) {
1014 Error("unexpected end of arguments.", Name);
1015 ConsumeRParen();
1016 return Builder->Constant(0, ResTy);
1017 }
1018
1019 ExprResult Arg = ParseExpr(IsFixed ? ResTy : TypeResult());
1020 if (!Arg.isValid())
1021 Arg = Builder->Constant(0, ResTy);
1022
1023 ExpectRParen("unexpected argument in unary expression.");
1024 ExprHandle E = Arg.get();
1025 switch (Kind) {
1026 case eMacroKind_Neg:
1027 return Builder->Sub(Builder->Constant(0, E->getWidth()), E);
1028 case Expr::Not:
1029 // FIXME: Type check arguments.
1030 return Builder->Not(E);
1031 case Expr::SExt:
1032 // FIXME: Type check arguments.
1033 return Builder->SExt(E, ResTy);
1034 case Expr::ZExt:
1035 // FIXME: Type check arguments.
1036 return Builder->ZExt(E, ResTy);
1037 default:
1038 Error("internal error, unhandled kind.", Name);
1039 return Builder->Constant(0, ResTy);
1040 }
1041}
1042
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);
1054 ConsumeRParen();
1055 return;
1056 }
1057
1058 // Avoid NumberOrExprResult overhead and give more precise
1059 // diagnostics when we know the type.
1060 if (ExpectType.isValid()) {
1061 LHS = ParseExpr(ExpectType);
1062 if (Tok.kind == Token::RParen) {
1063 Error("unexpected end of arguments.", Name);
1064 ConsumeRParen();
1065 return;
1066 }
1067 RHS = ParseExpr(ExpectType);
1068 } else {
1069 NumberOrExprResult LHS_NOE = ParseNumberOrExpr();
1070
1071 if (Tok.kind == Token::RParen) {
1072 Error("unexpected end of arguments.", Name);
1073 ConsumeRParen();
1074 return;
1075 }
1076
1077 if (LHS_NOE.isNumber()) {
1078 NumberOrExprResult RHS_NOE = ParseNumberOrExpr();
1079
1080 if (RHS_NOE.isNumber()) {
1081 Error("ambiguous arguments to expression.", Name);
1082 } else {
1083 RHS = RHS_NOE.getExpr();
1084 if (RHS.isValid())
1085 LHS = ParseNumberToken(RHS.get()->getWidth(), LHS_NOE.getNumber());
1086 }
1087 } else {
1088 LHS = LHS_NOE.getExpr();
1089 if (!LHS.isValid()) {
1090 // FIXME: Should suppress ambiguity warnings here.
1091 RHS = ParseExpr(TypeResult());
1092 } else {
1093 RHS = ParseExpr(LHS.get()->getWidth());
1094 }
1095 }
1096 }
1097
1098 ExpectRParen("unexpected argument to expression.");
1099}
1100
1101ExprResult ParserImpl::ParseBinaryParenExpr(const Token &Name,
1102 unsigned Kind, bool IsFixed,
1103 Expr::Width ResTy) {
1104 ExprResult LHS, RHS;
1105 ParseMatchedBinaryArgs(Name, IsFixed ? TypeResult(ResTy) : TypeResult(),
1106 LHS, RHS);
1107 if (!LHS.isValid() || !RHS.isValid())
1108 return Builder->Constant(0, ResTy);
1109
1110 ref<Expr> LHS_E = LHS.get(), RHS_E = RHS.get();
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);
1114 }
1115
1116 switch (Kind) {
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);
1124
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);
1128
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);
1132
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);
1143 default:
1144 Error("FIXME: unhandled kind.", Name);
1145 return Builder->Constant(0, ResTy);
1146 }
1147}
1148
1149ExprResult ParserImpl::ParseSelectParenExpr(const Token &Name,
1150 Expr::Width ResTy) {
1151 // FIXME: Why does this need to be here?
1152 if (Tok.kind == Token::RParen) {
1153 Error("unexpected end of arguments.", Name);
1154 ConsumeRParen();
1155 return Builder->Constant(0, ResTy);
1156 }
1157
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());
1164}
1165
1166
1167// FIXME: Rewrite to only accept binary form. Make type optional.
1168ExprResult ParserImpl::ParseConcatParenExpr(const Token &Name,
1169 Expr::Width ResTy) {
1170 std::vector<ExprHandle> Kids;
1171
1172 unsigned Width = 0;
1173 while (Tok.kind != Token::RParen) {
1174 ExprResult E = ParseExpr(TypeResult());
1175
1176 // Skip to end of expr on error.
1177 if (!E.isValid()) {
1178 SkipUntilRParen();
1179 return Builder->Constant(0, ResTy);
1180 }
1181
1182 Kids.push_back(E.get());
1183 Width += E.get()->getWidth();
1184 }
1185
1186 ConsumeRParen();
1187
1188 if (Width != ResTy) {
1189 Error("concat does not match expected result size.");
1190 return Builder->Constant(0, ResTy);
1191 }
1192
1193 // FIXME: Use builder!
1194 return ConcatExpr::createN(Kids.size(), &Kids[0]);
1195}
1196
1197IntegerResult ParserImpl::ParseIntegerConstant(Expr::Width Type) {
1198 ExprResult Res = ParseNumber(Type);
1199
1200 if (!Res.isValid())
1201 return IntegerResult();
1202
1203 return cast<ConstantExpr>(Res.get())->getZExtValue(Type);
1204}
1205
1206ExprResult ParserImpl::ParseExtractParenExpr(const Token &Name,
1207 Expr::Width ResTy) {
1208 IntegerResult OffsetExpr = ParseIntegerConstant(Expr::Int32);
1209 ExprResult Child = ParseExpr(TypeResult());
1210
1211 ExpectRParen("unexpected argument to expression.");
1212
1213 if (!OffsetExpr.isValid() || !Child.isValid())
1214 return Builder->Constant(0, ResTy);
1215
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);
1220 }
1221
1222 return Builder->Extract(Child.get(), Offset, ResTy);
1223}
1224
1225ExprResult ParserImpl::ParseAnyReadParenExpr(const Token &Name,
1226 unsigned Kind,
1227 Expr::Width ResTy) {
1228 NumberOrExprResult Index = ParseNumberOrExpr();
1229 VersionResult Array = ParseVersionSpecifier();
1230 ExpectRParen("unexpected argument in read expression.");
1231
1232 if (!Array.isValid())
1233 return Builder->Constant(0, ResTy);
1234
1235 // FIXME: Need generic way to get array width. Needs to work with
1236 // anonymous arrays.
1237 Expr::Width ArrayDomainType = Expr::Int32;
1238 Expr::Width ArrayRangeType = Expr::Int8;
1239
1240 // Coerce number to correct type.
1241 ExprResult IndexExpr;
1242 if (Index.isNumber())
1243 IndexExpr = ParseNumberToken(ArrayDomainType, Index.getNumber());
1244 else
1245 IndexExpr = Index.getExpr();
1246
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);
1252 }
1253
1254 // FIXME: Check range width.
1255
1256 switch (Kind) {
1257 default:
1258 assert(0 && "Invalid kind.");
1259 return Builder->Constant(0, ResTy);
1260 case eMacroKind_ReadLSB:
1261 case eMacroKind_ReadMSB: {
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);
1266 }
1267 std::vector<ExprHandle> Kids(NumReads);
1268 ExprHandle Index = IndexExpr.get();
1269 for (unsigned i=0; i != NumReads; ++i) {
1270 // FIXME: We rely on folding here to not complicate things to where the
1271 // Read macro pattern fails to match.
1272 ExprHandle OffsetIndex = Index;
1273 if (i)
1274 OffsetIndex = AddExpr::create(OffsetIndex,
1275 Builder->Constant(i, ArrayDomainType));
1276 Kids[i] = Builder->Read(Array.get(), OffsetIndex);
1277 }
1278 if (Kind == eMacroKind_ReadLSB)
1279 std::reverse(Kids.begin(), Kids.end());
1280 // FIXME: Use builder!
1281 return ConcatExpr::createN(NumReads, &Kids[0]);
1282 }
1283 case Expr::Read:
1284 return Builder->Read(Array.get(), IndexExpr.get());
1285 }
1286}
1287
1290VersionResult ParserImpl::ParseVersionSpecifier() {
1291 const Identifier *Label = 0;
1292 if (Tok.kind == Token::Identifier) {
1293 Token LTok = Tok;
1294 Label = GetOrCreateIdentifier(Tok);
1295 ConsumeToken();
1296
1297 if (Tok.kind != Token::Colon) {
1298 VersionSymTabTy::iterator it = VersionSymTab.find(Label);
1299
1300 if (it == VersionSymTab.end()) {
1301 Error("invalid version reference.", LTok);
1302 return VersionResult(false, UpdateList(0, NULL));
1303 }
1304
1305 return it->second;
1306 }
1307
1308 ConsumeToken();
1309 if (VersionSymTab.count(Label)) {
1310 Error("duplicate update list label definition.", LTok);
1311 Label = 0;
1312 }
1313 }
1314
1315 VersionResult Res = ParseVersion();
1316 // Define update list to avoid use-of-undef errors.
1317 if (!Res.isValid()) {
1318 // FIXME: I'm not sure if this is right. Do we need a unique array here?
1319 Res =
1320 VersionResult(true, UpdateList(TheArrayCache.CreateArray("", 0), NULL));
1321 }
1322
1323 if (Label)
1324 VersionSymTab.insert(std::make_pair(Label, Res.get()));
1325 return Res;
1326}
1327
1328namespace {
1331 struct WriteInfo {
1332 NumberOrExprResult LHS;
1333 NumberOrExprResult RHS;
1334 Token LHSTok;
1335 Token RHSTok;
1336
1337 WriteInfo(NumberOrExprResult _LHS, NumberOrExprResult _RHS,
1338 Token _LHSTok, Token _RHSTok) : LHS(_LHS), RHS(_RHS),
1339 LHSTok(_LHSTok), RHSTok(_RHSTok) {
1340 }
1341 };
1342}
1343
1347VersionResult ParserImpl::ParseVersion() {
1348 if (Tok.kind != Token::LSquare)
1349 return VersionResult(false, UpdateList(0, NULL));
1350
1351 std::vector<WriteInfo> Writes;
1352 ConsumeLSquare();
1353 for (;;) {
1354 Token LHSTok = Tok;
1355 NumberOrExprResult LHS = ParseNumberOrExpr();
1356
1357 if (Tok.kind != Token::Equals) {
1358 Error("expected '='.", Tok);
1359 break;
1360 }
1361
1362 ConsumeToken();
1363 Token RHSTok = Tok;
1364 NumberOrExprResult RHS = ParseNumberOrExpr();
1365
1366 Writes.push_back(WriteInfo(LHS, RHS, LHSTok, RHSTok));
1367
1368 if (Tok.kind == Token::Comma)
1369 ConsumeToken();
1370 else
1371 break;
1372 }
1373 ExpectRSquare("expected close of update list");
1374
1375 VersionHandle Base(0, NULL);
1376
1377 if (Tok.kind != Token::At) {
1378 Error("expected '@'.", Tok);
1379 return VersionResult(false, UpdateList(0, NULL));
1380 }
1381
1382 ConsumeExpectedToken(Token::At);
1383
1384 VersionResult BaseRes = ParseVersionSpecifier();
1385 if (!BaseRes.isValid())
1386 return BaseRes;
1387
1388 Base = BaseRes.get();
1389
1390 Expr::Width ArrayDomainType = Expr::Int32;
1391 Expr::Width ArrayRangeType = Expr::Int8;
1392
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;
1397 // FIXME: This can be factored into common helper for coercing a
1398 // NumberOrExpr into an Expr.
1399 if (WI.LHS.isNumber()) {
1400 LHS = ParseNumberToken(ArrayDomainType, WI.LHS.getNumber());
1401 } else {
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);
1405 LHS = ExprResult();
1406 }
1407 }
1408
1409 if (WI.RHS.isNumber()) {
1410 RHS = ParseNumberToken(ArrayRangeType, WI.RHS.getNumber());
1411 } else {
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);
1415 RHS = ExprResult();
1416 }
1417 }
1418
1419 if (LHS.isValid() && RHS.isValid())
1420 Base.extend(LHS.get(), RHS.get());
1421 }
1422
1423 return Base;
1424}
1425
1427ExprResult ParserImpl::ParseNumber(Expr::Width Type) {
1428 ExprResult Res = ParseNumberToken(Type, Tok);
1429 ConsumeExpectedToken(Token::Number);
1430 return Res;
1431}
1432
1435ExprResult ParserImpl::ParseNumberToken(Expr::Width Type, const Token &Tok) {
1436 const char *S = Tok.start;
1437 unsigned N = Tok.length;
1438 unsigned Radix = 10, RadixBits = 4;
1439 bool HasMinus = false;
1440
1441 // Detect +/- (a number token cannot have both).
1442 if (S[0] == '+') {
1443 ++S;
1444 --N;
1445 } else if (S[0] == '-') {
1446 HasMinus = true;
1447 ++S;
1448 --N;
1449 }
1450
1451 // Detect 0[box].
1452 if ((Tok.length >= 2 && S[0] == '0') &&
1453 (S[1] == 'b' || S[1] == 'o' || S[1] == 'x')) {
1454 if (S[1] == 'b') {
1455 Radix = 2;
1456 RadixBits = 1;
1457 } else if (S[1] == 'o') {
1458 Radix = 8;
1459 RadixBits = 3;
1460 } else {
1461 Radix = 16;
1462 RadixBits = 4;
1463 }
1464 S += 2;
1465 N -= 2;
1466
1467 // Diagnose 0[box] with no trailing digits.
1468 if (!N) {
1469 Error("invalid numeric token (no digits).", Tok);
1470 return Builder->Constant(0, Type);
1471 }
1472 }
1473
1474 // This is a simple but slow way to handle overflow.
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];
1480
1481 if (Char == '_')
1482 continue;
1483
1484 if ('0' <= Char && Char <= '9')
1485 Digit = Char - '0';
1486 else if ('a' <= Char && Char <= 'z')
1487 Digit = Char - 'a' + 10;
1488 else if ('A' <= Char && Char <= 'Z')
1489 Digit = Char - 'A' + 10;
1490 else {
1491 Error("invalid character in numeric token.", Tok);
1492 return Builder->Constant(0, Type);
1493 }
1494
1495 if (Digit >= Radix) {
1496 Error("invalid character in numeric token (out of range).", Tok);
1497 return Builder->Constant(0, Type);
1498 }
1499
1500 DigitVal = Digit;
1501 Val = Val * RadixVal + DigitVal;
1502 }
1503
1504 // FIXME: Actually do the check for overflow.
1505 if (HasMinus)
1506 Val = -Val;
1507
1508 if (Type < Val.getBitWidth())
1509 Val=Val.trunc(Type);
1510 else if (Type > Val.getBitWidth())
1511 Val=Val.zext(Type);
1512
1513 return ExprResult(Builder->Constant(Val));
1514}
1515
1519TypeResult ParserImpl::ParseTypeSpecifier() {
1520 assert(Tok.kind == Token::KWWidth && "Unexpected token.");
1521
1522 // FIXME: Need APInt technically.
1523 int width = atoi(std::string(Tok.start+1,Tok.length-1).c_str());
1524 ConsumeToken();
1525
1526 // FIXME: We should impose some sort of maximum just for sanity?
1527 return TypeResult(width);
1528}
1529
1530void ParserImpl::Error(const char *Message, const Token &At) {
1531 ++NumErrors;
1532 if (MaxErrors && NumErrors >= MaxErrors)
1533 return;
1534
1535 llvm::errs() << Filename
1536 << ":" << At.line << ":" << At.column
1537 << ": error: " << Message << "\n";
1538
1539 // Skip carat diagnostics on EOF token.
1540 if (At.kind == Token::EndOfFile)
1541 return;
1542
1543 // Simple caret style diagnostics.
1544 const char *LineBegin = At.start, *LineEnd = At.start,
1545 *BufferBegin = TheMemoryBuffer->getBufferStart(),
1546 *BufferEnd = TheMemoryBuffer->getBufferEnd();
1547
1548 // Run line pointers forward and back.
1549 while (LineBegin > BufferBegin &&
1550 LineBegin[-1] != '\r' && LineBegin[-1] != '\n')
1551 --LineBegin;
1552 while (LineEnd < BufferEnd &&
1553 LineEnd[0] != '\r' && LineEnd[0] != '\n')
1554 ++LineEnd;
1555
1556 // Show the line.
1557 llvm::errs() << std::string(LineBegin, LineEnd) << "\n";
1558
1559 // Show the caret or squiggly, making sure to print back spaces the
1560 // same.
1561 for (const char *S=LineBegin; S != At.start; ++S)
1562 llvm::errs() << (isspace(*S) ? *S : ' ');
1563 if (At.length > 1) {
1564 for (unsigned i=0; i<At.length; ++i)
1565 llvm::errs() << '~';
1566 } else
1567 llvm::errs() << '^';
1568 llvm::errs() << '\n';
1569}
1570
1571ParserImpl::~ParserImpl() {
1572 // Free identifiers
1573 //
1574 // Note the Identifiers are not disjoint across the symbol
1575 // tables so we need to keep track of what has freed to
1576 // avoid doing a double free.
1577 std::set<const Identifier*> freedNodes;
1578 for (IdentifierTabTy::iterator pi = IdentifierTab.begin(),
1579 pe = IdentifierTab.end();
1580 pi != pe; ++pi) {
1581 const Identifier* id = pi->second;
1582 if (freedNodes.insert(id).second)
1583 delete id;
1584 }
1585 for (ExprSymTabTy::iterator pi = ExprSymTab.begin(),
1586 pe = ExprSymTab.end();
1587 pi != pe; ++pi) {
1588 const Identifier* id = pi->first;
1589 if (freedNodes.insert(id).second)
1590 delete id;
1591 }
1592 for (VersionSymTabTy::iterator pi = VersionSymTab.begin(),
1593 pe = VersionSymTab.end();
1594 pi != pe; ++pi) {
1595 const Identifier* id = pi->first;
1596 if (freedNodes.insert(id).second)
1597 delete id;
1598 }
1599}
1600
1601// AST API
1602// FIXME: Move out of parser.
1603
1604Decl::Decl(DeclKind _Kind) : Kind(_Kind) {}
1605
1607 llvm::outs() << "array " << Root->name
1608 << "[" << Root->size << "]"
1609 << " : " << 'w' << Domain << " -> " << 'w' << Range << " = ";
1610
1611 if (Root->isSymbolicArray()) {
1612 llvm::outs() << "symbolic\n";
1613 } else {
1614 llvm::outs() << '[';
1615 for (unsigned i = 0, e = Root->size; i != e; ++i) {
1616 if (i)
1617 llvm::outs() << " ";
1618 llvm::outs() << Root->constantValues[i];
1619 }
1620 llvm::outs() << "]\n";
1621 }
1622}
1623
1625 const ExprHandle *ValuesBegin = 0, *ValuesEnd = 0;
1626 const Array * const* ObjectsBegin = 0, * const* ObjectsEnd = 0;
1627 if (!Values.empty()) {
1628 ValuesBegin = &Values[0];
1629 ValuesEnd = ValuesBegin + Values.size();
1630 }
1631 if (!Objects.empty()) {
1632 ObjectsBegin = &Objects[0];
1633 ObjectsEnd = ObjectsBegin + Objects.size();
1634 }
1636 ValuesBegin, ValuesEnd, ObjectsBegin, ObjectsEnd,
1637 false);
1638}
1639
1640// Public parser API
1641
1643}
1644
1646}
1647
1648Parser *Parser::Create(const std::string Filename, const MemoryBuffer *MB,
1649 ExprBuilder *Builder, bool ClearArrayAfterQuery) {
1650 ParserImpl *P = new ParserImpl(Filename, MB, Builder, ClearArrayAfterQuery);
1651 P->Initialize();
1652 return P;
1653}
static bool LookupExprInfo(const Token &Tok, unsigned &Kind, bool &IsFixed, int &NumArgs)
Definition: Parser.cpp:802
MacroKind
Definition: Parser.cpp:784
@ eMacroKind_ReadLSB
Definition: Parser.cpp:785
@ eMacroKind_ReadMSB
Definition: Parser.cpp:786
@ eMacroKind_Neg
Definition: Parser.cpp:787
@ eMacroKind_LastMacroKind
Definition: Parser.cpp:789
@ eMacroKind_Concat
Definition: Parser.cpp:788
#define SetOK(kind, isfixed, numargs)
Provides an interface for creating and destroying Array objects.
Definition: ArrayCache.h:31
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.
Definition: ArrayCache.cpp:20
const unsigned size
Definition: Expr.h:489
bool isSymbolicArray() const
Definition: Expr.h:524
const std::vector< ref< ConstantExpr > > constantValues
Definition: Expr.h:498
const std::string name
Definition: Expr.h:486
ExprBuilder - Base expression builder class.
Definition: ExprBuilder.h:17
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.
Definition: Expr.h:91
virtual Width getWidth() const =0
unsigned Width
The type of an expression is simply its width, in bits.
Definition: Expr.h:97
Class representing a complete list of updates into an array.
Definition: Expr.h:539
const Array * Root
Root - The root array object defined by this decl.
Definition: Parser.h:89
const unsigned Domain
Domain - The width of indices.
Definition: Parser.h:83
const unsigned Range
Range - The width of array contents.
Definition: Parser.h:86
virtual void dump()
dump - Dump the AST node to stderr.
Definition: Parser.cpp:1606
Decl - Base class for top level declarations.
Definition: Parser.h:41
Lexer - Interface for lexing tokens from a .kquery language file.
Definition: Lexer.h:78
Token & Lex(Token &Result)
Definition: Lexer.cpp:210
Parser - Public interface for parsing a .kquery language file.
Definition: Parser.h:206
virtual ~Parser()
Definition: Parser.cpp:1645
static Parser * Create(const std::string Name, const llvm::MemoryBuffer *MB, ExprBuilder *Builder, bool ClearArrayAfterQuery)
Definition: Parser.cpp:1648
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
Definition: Parser.h:183
virtual void dump()
dump - Dump the AST node to stderr.
Definition: Parser.cpp:1624
const std::vector< ExprHandle > Constraints
Definition: Parser.h:172
const std::vector< ExprHandle > Values
Definition: Parser.h:179
Definition: Ref.h:82
T * get() const
Definition: Ref.h:129
Definition: main.cpp:291
Identifier - Wrapper for a uniqued string.
Definition: Parser.h:31
const std::string Name
Definition: Parser.h:32
const char * start
The token kind.
Definition: Lexer.h:53
unsigned column
The line number of the start of this token.
Definition: Lexer.h:56
unsigned line
The length of the token.
Definition: Lexer.h:55
unsigned length
The beginning of the token string.
Definition: Lexer.h:54
bool isKeyword() const
isKeyword - True if this token is a keyword.
Definition: Lexer.h:67
@ RSquare
']'
Definition: Lexer.h:44
@ LSquare
'['
Definition: Lexer.h:40