Parser.cpp

Go to the documentation of this file.
00001 //===-- Parser.cpp --------------------------------------------------------===//
00002 //
00003 //                     The KLEE Symbolic Virtual Machine
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "expr/Parser.h"
00011 
00012 #include "expr/Lexer.h"
00013 
00014 #include "klee/Constraints.h"
00015 #include "klee/Solver.h"
00016 #include "klee/util/ExprPPrinter.h"
00017 
00018 #include "llvm/ADT/APInt.h"
00019 #include "llvm/Support/MemoryBuffer.h"
00020 #include "llvm/Support/Streams.h"
00021 
00022 #include <cassert>
00023 #include <iostream>
00024 #include <map>
00025 #include <cstring>
00026 
00027 using namespace llvm;
00028 using namespace klee;
00029 using namespace klee::expr;
00030 
00031 namespace {
00033   template<typename T>
00034   struct ParseResult {
00035     bool IsValid;
00036     T Value;
00037 
00038   public:
00039     ParseResult() : IsValid(false) {}
00040     ParseResult(T _Value) : IsValid(true), Value(_Value) {}
00041     ParseResult(bool _IsValid, T _Value) : IsValid(_IsValid), Value(_Value) {}
00042 
00043     bool isValid() { 
00044       return IsValid; 
00045     }
00046     T get() { 
00047       assert(IsValid && "get() on invalid ParseResult!");
00048       return Value; 
00049     }
00050   };
00051   
00052   class ExprResult {
00053     bool IsValid;
00054     ExprHandle Value;
00055 
00056   public:
00057     ExprResult() : IsValid(false) {}
00058     ExprResult(ExprHandle _Value) : IsValid(true), Value(_Value) {}
00059     ExprResult(ref<ConstantExpr> _Value) : IsValid(true), Value(_Value.get()) {}
00060     ExprResult(bool _IsValid, ExprHandle _Value) : IsValid(_IsValid), Value(_Value) {}
00061 
00062     bool isValid() { 
00063       return IsValid; 
00064     }
00065     ExprHandle get() { 
00066       assert(IsValid && "get() on invalid ParseResult!");
00067       return Value; 
00068     }
00069   };
00070 
00071   typedef ParseResult<Decl*> DeclResult;
00072   typedef ParseResult<Expr::Width> TypeResult;
00073   typedef ParseResult<VersionHandle> VersionResult;
00074 
00078   class NumberOrExprResult {
00079     Token AsNumber;
00080     ExprResult AsExpr;
00081     bool IsNumber;
00082 
00083   public:
00084     NumberOrExprResult() : IsNumber(false) {}
00085     explicit NumberOrExprResult(Token _AsNumber) : AsNumber(_AsNumber),
00086                                                    IsNumber(true) {}
00087     explicit NumberOrExprResult(ExprResult _AsExpr) : AsExpr(_AsExpr),
00088                                                       IsNumber(false) {}
00089     
00090     bool isNumber() const { return IsNumber; }
00091     const Token &getNumber() const { 
00092       assert(IsNumber && "Invalid accessor call.");
00093       return AsNumber; 
00094     }
00095     const ExprResult &getExpr() const {
00096       assert(!IsNumber && "Invalid accessor call.");
00097       return AsExpr;
00098     }
00099   };
00100 
00102   class ParserImpl : public Parser {
00103     typedef std::map<const std::string, const Identifier*> IdentifierTabTy;
00104     typedef std::map<const Identifier*, ExprHandle> ExprSymTabTy;
00105     typedef std::map<const Identifier*, VersionHandle> VersionSymTabTy;
00106 
00107     const std::string Filename;
00108     const MemoryBuffer *TheMemoryBuffer;
00109     Lexer TheLexer;
00110     unsigned MaxErrors;
00111     unsigned NumErrors;
00112 
00113     // FIXME: Use LLVM symbol tables?
00114     IdentifierTabTy IdentifierTab;
00115 
00116     std::map<const Identifier*, const ArrayDecl*> ArraySymTab;
00117     ExprSymTabTy ExprSymTab;
00118     VersionSymTabTy VersionSymTab;
00119 
00121     Token Tok;
00122 
00124     unsigned ParenLevel;
00126     unsigned SquareLevel;
00127 
00128     /* Core parsing functionality */
00129     
00130     const Identifier *GetOrCreateIdentifier(const Token &Tok);
00131 
00132     void GetNextNonCommentToken() {
00133       do {
00134         TheLexer.Lex(Tok);
00135       } while (Tok.kind == Token::Comment);
00136     }
00137 
00139     void ConsumeToken() {
00140       assert(Tok.kind != Token::LParen && Tok.kind != Token::RParen);
00141       GetNextNonCommentToken();
00142     }
00143 
00146     void ConsumeExpectedToken(Token::Kind k) {
00147       assert(Tok.kind == k && "Unexpected token!");
00148       GetNextNonCommentToken();
00149     }
00150 
00151     void ConsumeLParen() {
00152       ++ParenLevel;
00153       ConsumeExpectedToken(Token::LParen);
00154     }
00155 
00156     void ConsumeRParen() {
00157       if (ParenLevel) // Cannot go below zero.
00158         --ParenLevel;
00159       ConsumeExpectedToken(Token::RParen);
00160     }
00161 
00162     void ConsumeLSquare() {
00163       ++SquareLevel;
00164       ConsumeExpectedToken(Token::LSquare);
00165     }
00166 
00167     void ConsumeRSquare() {
00168       if (SquareLevel) // Cannot go below zero.
00169         --SquareLevel;
00170       ConsumeExpectedToken(Token::RSquare);
00171     }
00172 
00173     void ConsumeAnyToken() {
00174       switch (Tok.kind) {
00175       case Token::LParen: return ConsumeLParen();
00176       case Token::RParen: return ConsumeRParen();
00177       case Token::LSquare: return ConsumeLSquare();
00178       case Token::RSquare: return ConsumeRSquare();
00179       default: 
00180         return ConsumeToken();
00181       }
00182     }
00183 
00184     /* Utility functions */
00185 
00188     void SkipUntilRParen(unsigned Level) {
00189       // FIXME: I keep wavering on whether it is an error to call this
00190       // with the current token an rparen. In most cases this should
00191       // have been handled differently (error reported,
00192       // whatever). Audit & resolve.
00193       assert(Level <= ParenLevel && 
00194              "Refusing to skip until rparen at higher level.");
00195       while (Tok.kind != Token::EndOfFile) {
00196         if (Tok.kind == Token::RParen && ParenLevel == Level) {
00197           ConsumeRParen();
00198           break;
00199         }
00200         ConsumeAnyToken();
00201       }
00202     }
00203 
00206     void SkipUntilRParen() {
00207       SkipUntilRParen(ParenLevel);
00208     }
00209     
00213     void ExpectRParen(const char *Msg) {
00214       if (Tok.kind == Token::EndOfFile) {
00215         // FIXME: Combine with Msg
00216         Error("expected ')' but found end-of-file.", Tok);
00217       } else if (Tok.kind != Token::RParen) {
00218         Error(Msg, Tok);
00219         SkipUntilRParen();
00220       } else {
00221         ConsumeRParen();
00222       }
00223     }
00224 
00227     void SkipUntilRSquare(unsigned Level) {
00228       // FIXME: I keep wavering on whether it is an error to call this
00229       // with the current token an rparen. In most cases this should
00230       // have been handled differently (error reported,
00231       // whatever). Audit & resolve.
00232       assert(Level <= ParenLevel && 
00233              "Refusing to skip until rparen at higher level.");
00234       while (Tok.kind != Token::EndOfFile) {
00235         if (Tok.kind == Token::RSquare && ParenLevel == Level) {
00236           ConsumeRSquare();
00237           break;
00238         }
00239         ConsumeAnyToken();
00240       }
00241     }
00242 
00245     void SkipUntilRSquare() {
00246       SkipUntilRSquare(ParenLevel);
00247     }
00248     
00252     void ExpectRSquare(const char *Msg) {
00253       if (Tok.kind == Token::EndOfFile) {
00254         // FIXME: Combine with Msg
00255         Error("expected ']' but found end-of-file.", Tok);
00256       } else if (Tok.kind != Token::RSquare) {
00257         Error(Msg, Tok);
00258         SkipUntilRSquare();
00259       } else {
00260         ConsumeRSquare();
00261       }
00262     }
00263 
00264     /*** Grammar productions ****/
00265 
00266     /* Top level decls */
00267 
00268     DeclResult ParseArrayDecl();
00269     DeclResult ParseExprVarDecl();
00270     DeclResult ParseVersionVarDecl();
00271     DeclResult ParseCommandDecl();
00272 
00273     /* Commands */
00274 
00275     DeclResult ParseQueryCommand();
00276 
00277     /* Etc. */
00278 
00279     NumberOrExprResult ParseNumberOrExpr();
00280 
00281     ExprResult ParseExpr(TypeResult ExpectedType);
00282     ExprResult ParseParenExpr(TypeResult ExpectedType);
00283     ExprResult ParseUnaryParenExpr(const Token &Name,
00284                                    unsigned Kind, bool IsFixed,
00285                                    Expr::Width ResTy);
00286     ExprResult ParseBinaryParenExpr(const Token &Name,
00287                                     unsigned Kind, bool IsFixed,
00288                                     Expr::Width ResTy);
00289     ExprResult ParseSelectParenExpr(const Token &Name, Expr::Width ResTy);
00290     ExprResult ParseConcatParenExpr(const Token &Name, Expr::Width ResTy);
00291     ExprResult ParseExtractParenExpr(const Token &Name, Expr::Width ResTy);
00292     ExprResult ParseAnyReadParenExpr(const Token &Name,
00293                                      unsigned Kind,
00294                                      Expr::Width ResTy);
00295     void ParseMatchedBinaryArgs(const Token &Name, 
00296                                 TypeResult ExpectType,
00297                                 ExprResult &LHS, ExprResult &RHS);
00298     ExprResult ParseNumber(Expr::Width Width);
00299     ExprResult ParseNumberToken(Expr::Width Width, const Token &Tok);
00300 
00301     VersionResult ParseVersionSpecifier();
00302     VersionResult ParseVersion();
00303 
00304     TypeResult ParseTypeSpecifier();
00305 
00306     /*** Diagnostics ***/
00307     
00308     void Error(const char *Message, const Token &At);
00309     void Error(const char *Message) { Error(Message, Tok); }
00310 
00311   public:
00312     ParserImpl(const std::string _Filename,
00313                const MemoryBuffer *MB) : Filename(_Filename),
00314                                          TheMemoryBuffer(MB),
00315                                          TheLexer(MB),
00316                                          MaxErrors(~0u),
00317                                          NumErrors(0) {}
00318 
00321     void Initialize() {
00322       ParenLevel = SquareLevel = 0;
00323 
00324       ConsumeAnyToken();
00325     }
00326 
00327     /* Parser interface implementation */
00328 
00329     virtual Decl *ParseTopLevelDecl();
00330 
00331     virtual void SetMaxErrors(unsigned N) {
00332       MaxErrors = N;
00333     }
00334 
00335     virtual unsigned GetNumErrors() const {
00336       return NumErrors; 
00337     }
00338   };
00339 }
00340 
00341 const Identifier *ParserImpl::GetOrCreateIdentifier(const Token &Tok) {
00342   // FIXME: Make not horribly inefficient please.
00343   assert(Tok.kind == Token::Identifier && "Expected only identifier tokens.");
00344   std::string Name(Tok.start, Tok.length);
00345   IdentifierTabTy::iterator it = IdentifierTab.find(Name);
00346   if (it != IdentifierTab.end())
00347     return it->second;
00348 
00349   Identifier *I = new Identifier(Name);
00350   IdentifierTab.insert(std::make_pair(Name, I));
00351 
00352   return I;
00353 }
00354 
00355 Decl *ParserImpl::ParseTopLevelDecl() {
00356   // Repeat until success or EOF.
00357   while (Tok.kind != Token::EndOfFile) {
00358     // Only handle commands for now.
00359     if (Tok.kind == Token::LParen) {
00360       DeclResult Res = ParseCommandDecl();
00361       if (Res.isValid())
00362         return Res.get();
00363     } else {
00364       Error("expected '(' token.");
00365       ConsumeAnyToken();
00366     }
00367   }
00368 
00369   return 0;
00370 }
00371 
00376 DeclResult ParserImpl::ParseCommandDecl() {
00377   ConsumeLParen();
00378 
00379   if (!Tok.isKeyword()) {
00380     Error("malformed command.");
00381     SkipUntilRParen();
00382     return DeclResult();
00383   }
00384 
00385   switch (Tok.kind) {
00386   case Token::KWQuery:
00387     return ParseQueryCommand();
00388 
00389   default:
00390     Error("malformed command (unexpected keyword).");
00391     SkipUntilRParen();
00392     return DeclResult();
00393   }
00394 }
00395 
00400 DeclResult ParserImpl::ParseQueryCommand() {
00401   std::vector<ExprHandle> Constraints;
00402   std::vector<ExprHandle> Values;
00403   std::vector<const Array*> Objects;
00404   ExprResult Res;
00405 
00406   // FIXME: We need a command for this. Or something.
00407   ExprSymTab.clear();
00408   VersionSymTab.clear();
00409 
00410   ConsumeExpectedToken(Token::KWQuery);
00411   if (Tok.kind != Token::LSquare) {
00412     Error("malformed query, expected constraint list.");
00413     SkipUntilRParen();
00414     return DeclResult();
00415   }
00416 
00417   ConsumeExpectedToken(Token::LSquare);
00418   // FIXME: Should avoid reading past unbalanced parens here.
00419   while (Tok.kind != Token::RSquare) {
00420     if (Tok.kind == Token::EndOfFile) {
00421       Error("unexpected end of file.");
00422       Res = ExprResult(ConstantExpr::alloc(0, Expr::Bool));
00423       goto exit;
00424     }
00425 
00426     ExprResult Constraint = ParseExpr(TypeResult(Expr::Bool));
00427     if (Constraint.isValid())
00428       Constraints.push_back(Constraint.get());
00429   }
00430   ConsumeRSquare();
00431 
00432   Res = ParseExpr(TypeResult(Expr::Bool));
00433   if (!Res.isValid()) // Error emitted by ParseExpr.
00434     Res = ExprResult(ConstantExpr::alloc(0, Expr::Bool));
00435 
00436   // Return if there are no optional lists of things to evaluate.
00437   if (Tok.kind == Token::RParen)
00438     goto exit;
00439   
00440   ConsumeExpectedToken(Token::LSquare);
00441   // FIXME: Should avoid reading past unbalanced parens here.
00442   while (Tok.kind != Token::RSquare) {
00443     if (Tok.kind == Token::EndOfFile) {
00444       Error("unexpected end of file.");
00445       goto exit;
00446     }
00447 
00448     ExprResult Res = ParseExpr(TypeResult());
00449     if (Res.isValid())
00450       Values.push_back(Res.get());
00451   }
00452   ConsumeRSquare();
00453 
00454   // Return if there are no optional lists of things to evaluate.
00455   if (Tok.kind == Token::RParen)
00456     goto exit;
00457 
00458   ConsumeExpectedToken(Token::LSquare);
00459   // FIXME: Should avoid reading past unbalanced parens here.
00460   while (Tok.kind != Token::RSquare) {
00461     if (Tok.kind == Token::EndOfFile) {
00462       Error("unexpected end of file.");
00463       goto exit;
00464     }
00465 
00466     // FIXME: Factor out.
00467     if (Tok.kind != Token::Identifier) {
00468       Error("unexpected token.");
00469       ConsumeToken();
00470       continue;
00471     }
00472 
00473     Token LTok = Tok;
00474     const Identifier *Label = GetOrCreateIdentifier(Tok);
00475     ConsumeToken();
00476 
00477     // Declare or create array.
00478     const ArrayDecl *AD = ArraySymTab[Label];
00479     if (!AD) {
00480       // FIXME: Don't make up arrays.
00481       unsigned Id = atoi(&Label->Name.c_str()[3]);
00482       AD = new ArrayDecl(Label, 0, 32, 8, new Array(0, Id, 0));
00483     }
00484     
00485     Objects.push_back(AD->Root);
00486   }
00487   ConsumeRSquare();
00488 
00489  exit:
00490   if (Tok.kind != Token::EndOfFile)
00491     ExpectRParen("unexpected argument to 'query'.");  
00492   return new QueryCommand(Constraints, Res.get(), Values, Objects);
00493 }
00494 
00497 NumberOrExprResult ParserImpl::ParseNumberOrExpr() {
00498   if (Tok.kind == Token::Number){ 
00499     Token Num = Tok;
00500     ConsumeToken();
00501     return NumberOrExprResult(Num);
00502   } else {
00503     return NumberOrExprResult(ParseExpr(TypeResult()));
00504   }
00505 }
00506 
00515 ExprResult ParserImpl::ParseExpr(TypeResult ExpectedType) {
00516   // FIXME: Is it right to need to do this here?
00517   if (Tok.kind == Token::EndOfFile) {
00518     Error("unexpected end of file.");
00519     return ExprResult();
00520   }
00521 
00522   if (Tok.kind == Token::KWFalse || Tok.kind == Token::KWTrue) {
00523     bool Value = Tok.kind == Token::KWTrue;
00524     ConsumeToken();
00525     return ExprResult(ConstantExpr::alloc(Value, Expr::Bool));
00526   }
00527   
00528   if (Tok.kind == Token::Number) {
00529     if (!ExpectedType.isValid()) {
00530       Error("cannot infer type of number.");
00531       ConsumeToken();
00532       return ExprResult();
00533     }
00534     
00535     return ParseNumber(ExpectedType.get());
00536   }
00537 
00538   const Identifier *Label = 0;
00539   if (Tok.kind == Token::Identifier) {
00540     Token LTok = Tok;
00541     Label = GetOrCreateIdentifier(Tok);
00542     ConsumeToken();
00543 
00544     if (Tok.kind != Token::Colon) {
00545       ExprSymTabTy::iterator it = ExprSymTab.find(Label);
00546 
00547       if (it == ExprSymTab.end()) {
00548         Error("invalid expression label reference.", LTok);
00549         return ExprResult();
00550       }
00551 
00552       return it->second;
00553     }
00554 
00555     ConsumeToken();
00556     if (ExprSymTab.count(Label)) {
00557       Error("duplicate expression label definition.", LTok);
00558       Label = 0;
00559     }
00560   }
00561 
00562   Token Start = Tok;
00563   ExprResult Res = ParseParenExpr(ExpectedType);
00564   if (!Res.isValid()) {
00565     // If we know the type, define the identifier just so we don't get
00566     // use-of-undef errors. 
00567     // FIXME: Maybe we should let the symbol table map to invalid
00568     // entries?
00569     if (Label && ExpectedType.isValid()) {
00570       ref<Expr> Value = ConstantExpr::alloc(0, ExpectedType.get());
00571       ExprSymTab.insert(std::make_pair(Label, Value));
00572     }
00573     return Res;
00574   } else if (ExpectedType.isValid()) {
00575     // Type check result.    
00576     if (Res.get()->getWidth() != ExpectedType.get()) {
00577       // FIXME: Need more info, and range
00578       Error("expression has incorrect type.", Start);
00579       return ExprResult();
00580     }
00581   }
00582 
00583   if (Label)
00584     ExprSymTab.insert(std::make_pair(Label, Res.get()));
00585   return Res;
00586 }
00587 
00588 // Additional kinds for macro forms.
00589 enum MacroKind {
00590   eMacroKind_Not = Expr::LastKind + 1,     // false == x
00591   eMacroKind_Neg,                          // 0 - x
00592   eMacroKind_ReadLSB,                      // Multibyte read
00593   eMacroKind_ReadMSB,                      // Multibyte write
00594   eMacroKind_Concat,                       // Magic concatenation syntax
00595   eMacroKind_LastMacroKind = eMacroKind_ReadMSB
00596 };
00597 
00608 static bool LookupExprInfo(const Token &Tok, unsigned &Kind, 
00609                            bool &IsFixed, int &NumArgs) {
00610 #define SetOK(kind, isfixed, numargs) (Kind=kind, IsFixed=isfixed,\
00611                                        NumArgs=numargs, true)
00612   assert(Tok.kind == Token::Identifier && "Unexpected token.");
00613   
00614   switch (Tok.length) {
00615   case 2:
00616     if (memcmp(Tok.start, "Eq", 2) == 0)
00617       return SetOK(Expr::Eq, false, 2);
00618     if (memcmp(Tok.start, "Ne", 2) == 0)
00619       return SetOK(Expr::Ne, false, 2);
00620 
00621     if (memcmp(Tok.start, "Or", 2) == 0)
00622       return SetOK(Expr::Or, true, 2);
00623     break;
00624 
00625   case 3:
00626     if (memcmp(Tok.start, "Add", 3) == 0)
00627       return SetOK(Expr::Add, true, 2);
00628     if (memcmp(Tok.start, "Sub", 3) == 0)
00629       return SetOK(Expr::Sub, true, 2);
00630     if (memcmp(Tok.start, "Mul", 3) == 0)
00631       return SetOK(Expr::Mul, true, 2);
00632 
00633     if (memcmp(Tok.start, "And", 3) == 0)
00634       return SetOK(Expr::And, true, 2);
00635     if (memcmp(Tok.start, "Shl", 3) == 0)
00636       return SetOK(Expr::Shl, true, 2);
00637     if (memcmp(Tok.start, "Xor", 3) == 0)
00638       return SetOK(Expr::Xor, true, 2);
00639 
00640     if (memcmp(Tok.start, "Not", 3) == 0)
00641       return SetOK(eMacroKind_Not, true, 1);
00642     if (memcmp(Tok.start, "Neg", 3) == 0)
00643       return SetOK(eMacroKind_Neg, true, 1);
00644     if (memcmp(Tok.start, "Ult", 3) == 0)
00645       return SetOK(Expr::Ult, false, 2);
00646     if (memcmp(Tok.start, "Ule", 3) == 0)
00647       return SetOK(Expr::Ule, false, 2);
00648     if (memcmp(Tok.start, "Ugt", 3) == 0)
00649       return SetOK(Expr::Ugt, false, 2);
00650     if (memcmp(Tok.start, "Uge", 3) == 0)
00651       return SetOK(Expr::Uge, false, 2);
00652     if (memcmp(Tok.start, "Slt", 3) == 0)
00653       return SetOK(Expr::Slt, false, 2);
00654     if (memcmp(Tok.start, "Sle", 3) == 0)
00655       return SetOK(Expr::Sle, false, 2);
00656     if (memcmp(Tok.start, "Sgt", 3) == 0)
00657       return SetOK(Expr::Sgt, false, 2);
00658     if (memcmp(Tok.start, "Sge", 3) == 0)
00659       return SetOK(Expr::Sge, false, 2);
00660     break;
00661 
00662   case 4:
00663     if (memcmp(Tok.start, "Read", 4) == 0)
00664       return SetOK(Expr::Read, true, -1);
00665     if (memcmp(Tok.start, "AShr", 4) == 0)
00666       return SetOK(Expr::AShr, true, 2);
00667     if (memcmp(Tok.start, "LShr", 4) == 0)
00668       return SetOK(Expr::LShr, true, 2);
00669 
00670     if (memcmp(Tok.start, "UDiv", 4) == 0)
00671       return SetOK(Expr::UDiv, true, 2);
00672     if (memcmp(Tok.start, "SDiv", 4) == 0)
00673       return SetOK(Expr::SDiv, true, 2);
00674     if (memcmp(Tok.start, "URem", 4) == 0)
00675       return SetOK(Expr::URem, true, 2);
00676     if (memcmp(Tok.start, "SRem", 4) == 0)
00677       return SetOK(Expr::SRem, true, 2);
00678     
00679     if (memcmp(Tok.start, "SExt", 4) == 0)
00680       return SetOK(Expr::SExt, false, 1);
00681     if (memcmp(Tok.start, "ZExt", 4) == 0)
00682       return SetOK(Expr::ZExt, false, 1);
00683     break;
00684     
00685   case 6:
00686     if (memcmp(Tok.start, "Concat", 6) == 0)
00687       return SetOK(eMacroKind_Concat, false, -1); 
00688     if (memcmp(Tok.start, "Select", 6) == 0)
00689       return SetOK(Expr::Select, false, 3);
00690     break;
00691     
00692   case 7:
00693     if (memcmp(Tok.start, "Extract", 7) == 0)
00694       return SetOK(Expr::Extract, false, -1);
00695     if (memcmp(Tok.start, "ReadLSB", 7) == 0)
00696       return SetOK(eMacroKind_ReadLSB, true, -1);
00697     if (memcmp(Tok.start, "ReadMSB", 7) == 0)
00698       return SetOK(eMacroKind_ReadMSB, true, -1);
00699     break;
00700   }
00701 
00702   return false;
00703 #undef SetOK
00704 }
00705 
00713 ExprResult ParserImpl::ParseParenExpr(TypeResult FIXME_UNUSED) {
00714   if (Tok.kind != Token::LParen) {
00715     Error("unexpected token.");
00716     ConsumeAnyToken();
00717     return ExprResult();
00718   }
00719 
00720   ConsumeLParen();
00721   
00722   // Check for coercion case (w32 11).
00723   if (Tok.kind == Token::KWWidth) {
00724     TypeResult ExpectedType = ParseTypeSpecifier();
00725 
00726     if (Tok.kind != Token::Number) {
00727       Error("coercion can only apply to a number.");
00728       SkipUntilRParen();
00729       return ExprResult();
00730     }
00731     
00732     // Make sure this was a type specifier we support.
00733     ExprResult Res;
00734     if (ExpectedType.isValid()) 
00735       Res = ParseNumber(ExpectedType.get());
00736     else
00737       ConsumeToken();
00738 
00739     ExpectRParen("unexpected argument in coercion.");  
00740     return Res;
00741   }
00742   
00743   if (Tok.kind != Token::Identifier) {
00744     Error("unexpected token, expected expression.");
00745     SkipUntilRParen();
00746     return ExprResult();
00747   }
00748 
00749   Token Name = Tok;
00750   ConsumeToken();
00751 
00752   // FIXME: Use invalid type (i.e. width==0)?
00753   Token TypeTok = Tok;
00754   bool HasType = TypeTok.kind == Token::KWWidth;
00755   TypeResult Type = HasType ? ParseTypeSpecifier() : Expr::Bool;
00756 
00757   // FIXME: For now just skip to rparen on error. It might be nice
00758   // to try and actually parse the child nodes though for error
00759   // messages & better recovery?
00760   if (!Type.isValid()) {
00761     SkipUntilRParen();
00762     return ExprResult();
00763   }
00764   Expr::Width ResTy = Type.get();
00765 
00766   unsigned ExprKind;
00767   bool IsFixed;
00768   int NumArgs;
00769   if (!LookupExprInfo(Name, ExprKind, IsFixed, NumArgs)) {
00770     // FIXME: For now just skip to rparen on error. It might be nice
00771     // to try and actually parse the child nodes though for error
00772     // messages & better recovery?
00773     Error("unknown expression kind.", Name);
00774     SkipUntilRParen();
00775     return ExprResult();
00776   }
00777 
00778   // See if we have to parse this form specially.
00779   if (NumArgs == -1) {
00780     switch (ExprKind) {
00781     case eMacroKind_Concat:
00782       return ParseConcatParenExpr(Name, ResTy);
00783 
00784     case Expr::Extract:
00785       return ParseExtractParenExpr(Name, ResTy);
00786 
00787     case eMacroKind_ReadLSB:
00788     case eMacroKind_ReadMSB:
00789     case Expr::Read:
00790       return ParseAnyReadParenExpr(Name, ExprKind, ResTy);
00791 
00792     default:
00793       Error("internal error, unimplemented special form.", Name);
00794       SkipUntilRParen();
00795       return ExprResult(ConstantExpr::alloc(0, ResTy));
00796     }
00797   }
00798 
00799   switch (NumArgs) {
00800   case 1:
00801     return ParseUnaryParenExpr(Name, ExprKind, IsFixed, ResTy);
00802   case 2:
00803     return ParseBinaryParenExpr(Name, ExprKind, IsFixed, ResTy);
00804   case 3:
00805     if (ExprKind == Expr::Select)
00806       return ParseSelectParenExpr(Name, ResTy);
00807   default:
00808     assert(0 && "Invalid argument kind (number of args).");
00809     return ExprResult();
00810   }
00811 }
00812 
00813 ExprResult ParserImpl::ParseUnaryParenExpr(const Token &Name,
00814                                            unsigned Kind, bool IsFixed,
00815                                            Expr::Width ResTy) {
00816   if (Tok.kind == Token::RParen) {
00817     Error("unexpected end of arguments.", Name);
00818     ConsumeRParen();
00819     return ConstantExpr::alloc(0, ResTy);
00820   }
00821 
00822   ExprResult Arg = ParseExpr(IsFixed ? ResTy : TypeResult());
00823   if (!Arg.isValid())
00824     Arg = ConstantExpr::alloc(0, ResTy);
00825 
00826   ExpectRParen("unexpected argument in unary expression.");  
00827   ExprHandle E = Arg.get();
00828   switch (Kind) {
00829   case eMacroKind_Not:
00830     return EqExpr::alloc(ConstantExpr::alloc(0, E->getWidth()), E);
00831   case eMacroKind_Neg:
00832     return SubExpr::alloc(ConstantExpr::alloc(0, E->getWidth()), E);
00833   case Expr::SExt:
00834     // FIXME: Type check arguments.
00835     return SExtExpr::alloc(E, ResTy);
00836   case Expr::ZExt:
00837     // FIXME: Type check arguments.
00838     return ZExtExpr::alloc(E, ResTy);
00839   default:
00840     Error("internal error, unhandled kind.", Name);
00841     return ConstantExpr::alloc(0, ResTy);
00842   }
00843 }
00844 
00851 void ParserImpl::ParseMatchedBinaryArgs(const Token &Name, 
00852                                         TypeResult ExpectType,
00853                                         ExprResult &LHS, ExprResult &RHS) {
00854   if (Tok.kind == Token::RParen) {
00855     Error("unexpected end of arguments.", Name);
00856     ConsumeRParen();
00857     return;
00858   }
00859 
00860   // Avoid NumberOrExprResult overhead and give more precise
00861   // diagnostics when we know the type.
00862   if (ExpectType.isValid()) {
00863     LHS = ParseExpr(ExpectType);
00864     if (Tok.kind == Token::RParen) {
00865       Error("unexpected end of arguments.", Name);
00866       ConsumeRParen();
00867       return;
00868     }
00869     RHS = ParseExpr(ExpectType);
00870   } else {
00871     NumberOrExprResult LHS_NOE = ParseNumberOrExpr();
00872 
00873     if (Tok.kind == Token::RParen) {
00874       Error("unexpected end of arguments.", Name);
00875       ConsumeRParen();
00876       return;
00877     }
00878 
00879     if (LHS_NOE.isNumber()) {
00880       NumberOrExprResult RHS_NOE = ParseNumberOrExpr();
00881       
00882       if (RHS_NOE.isNumber()) {
00883         Error("ambiguous arguments to expression.", Name);
00884       } else {
00885         RHS = RHS_NOE.getExpr();
00886         if (RHS.isValid())
00887           LHS = ParseNumberToken(RHS.get()->getWidth(), LHS_NOE.getNumber());
00888       }
00889     } else {
00890       LHS = LHS_NOE.getExpr();
00891       if (!LHS.isValid()) {
00892         // FIXME: Should suppress ambiguity warnings here.
00893         RHS = ParseExpr(TypeResult());
00894       } else {
00895         RHS = ParseExpr(LHS.get()->getWidth());
00896       }
00897     }
00898   }
00899 
00900   ExpectRParen("unexpected argument to expression.");
00901 }
00902 
00903 ExprResult ParserImpl::ParseBinaryParenExpr(const Token &Name,
00904                                            unsigned Kind, bool IsFixed,
00905                                            Expr::Width ResTy) {
00906   ExprResult LHS, RHS;
00907   ParseMatchedBinaryArgs(Name, IsFixed ? TypeResult(ResTy) : TypeResult(), 
00908                          LHS, RHS);
00909   if (!LHS.isValid() || !RHS.isValid())
00910     return ConstantExpr::alloc(0, ResTy);
00911 
00912   ref<Expr> LHS_E = LHS.get(), RHS_E = RHS.get();
00913   if (LHS_E->getWidth() != RHS_E->getWidth()) {
00914     Error("type widths do not match in binary expression", Name);
00915     return ConstantExpr::alloc(0, ResTy);
00916   }
00917 
00918   switch (Kind) {    
00919   case Expr::Add: return AddExpr::alloc(LHS_E, RHS_E);
00920   case Expr::Sub: return SubExpr::alloc(LHS_E, RHS_E);
00921   case Expr::Mul: return MulExpr::alloc(LHS_E, RHS_E);
00922   case Expr::UDiv: return UDivExpr::alloc(LHS_E, RHS_E);
00923   case Expr::SDiv: return SDivExpr::alloc(LHS_E, RHS_E);
00924   case Expr::URem: return URemExpr::alloc(LHS_E, RHS_E);
00925   case Expr::SRem: return SRemExpr::alloc(LHS_E, RHS_E);
00926 
00927   case Expr::AShr: return AShrExpr::alloc(LHS_E, RHS_E);
00928   case Expr::LShr: return LShrExpr::alloc(LHS_E, RHS_E);
00929   case Expr::Shl: return AndExpr::alloc(LHS_E, RHS_E);
00930 
00931   case Expr::And: return AndExpr::alloc(LHS_E, RHS_E);
00932   case Expr::Or:  return OrExpr::alloc(LHS_E, RHS_E);
00933   case Expr::Xor: return XorExpr::alloc(LHS_E, RHS_E);
00934 
00935   case Expr::Eq:  return EqExpr::alloc(LHS_E, RHS_E);
00936   case Expr::Ne:  return NeExpr::alloc(LHS_E, RHS_E);
00937   case Expr::Ult: return UltExpr::alloc(LHS_E, RHS_E);
00938   case Expr::Ule: return UleExpr::alloc(LHS_E, RHS_E);
00939   case Expr::Ugt: return UgtExpr::alloc(LHS_E, RHS_E);
00940   case Expr::Uge: return UgeExpr::alloc(LHS_E, RHS_E);
00941   case Expr::Slt: return SltExpr::alloc(LHS_E, RHS_E);
00942   case Expr::Sle: return SleExpr::alloc(LHS_E, RHS_E);
00943   case Expr::Sgt: return SgtExpr::alloc(LHS_E, RHS_E);
00944   case Expr::Sge: return SgeExpr::alloc(LHS_E, RHS_E);
00945   default:
00946     Error("FIXME: unhandled kind.", Name);
00947     return ConstantExpr::alloc(0, ResTy);
00948   }  
00949 }
00950 
00951 ExprResult ParserImpl::ParseSelectParenExpr(const Token &Name, 
00952                                             Expr::Width ResTy) {
00953   // FIXME: Why does this need to be here?
00954   if (Tok.kind == Token::RParen) {
00955     Error("unexpected end of arguments.", Name);
00956     ConsumeRParen();
00957     return ConstantExpr::alloc(0, ResTy);
00958   }
00959 
00960   ExprResult Cond = ParseExpr(Expr::Bool);
00961   ExprResult LHS, RHS;
00962   ParseMatchedBinaryArgs(Name, ResTy, LHS, RHS);
00963   if (!Cond.isValid() || !LHS.isValid() || !RHS.isValid())
00964     return ConstantExpr::alloc(0, ResTy);
00965   return SelectExpr::alloc(Cond.get(), LHS.get(), RHS.get());
00966 }
00967 
00968 
00969 // need to decide if we want to allow n-ary Concat expressions in the
00970 // language
00971 ExprResult ParserImpl::ParseConcatParenExpr(const Token &Name,
00972                                             Expr::Width ResTy) {
00973   std::vector<ExprHandle> Kids;
00974   
00975   unsigned Width = 0;
00976   while (Tok.kind != Token::RParen) {
00977     ExprResult E = ParseExpr(TypeResult());
00978 
00979     // Skip to end of expr on error.
00980     if (!E.isValid()) {
00981       SkipUntilRParen();
00982       return ConstantExpr::alloc(0, ResTy);
00983     }
00984     
00985     Kids.push_back(E.get());
00986     Width += E.get()->getWidth();
00987   }
00988   
00989   ConsumeRParen();
00990 
00991   if (Width != ResTy) {
00992     Error("concat does not match expected result size.");
00993     return ConstantExpr::alloc(0, ResTy);
00994   }
00995 
00996   return ConcatExpr::createN(Kids.size(), &Kids[0]);
00997 }
00998 
00999 ExprResult ParserImpl::ParseExtractParenExpr(const Token &Name,
01000                                              Expr::Width ResTy) {
01001   // FIXME: Pull out parse constant integer expression.
01002   ExprResult OffsetExpr = ParseNumber(Expr::Int32);
01003   ExprResult Child = ParseExpr(TypeResult());
01004 
01005   ExpectRParen("unexpected argument to expression.");
01006 
01007   if (!OffsetExpr.isValid() || !Child.isValid())
01008     return ConstantExpr::alloc(0, ResTy);
01009 
01010   unsigned Offset = 
01011     (unsigned) cast<ConstantExpr>(OffsetExpr.get())->getConstantValue();
01012 
01013   if (Offset + ResTy > Child.get()->getWidth()) {
01014     Error("extract out-of-range of child expression.", Name);
01015     return ConstantExpr::alloc(0, ResTy);
01016   }
01017 
01018   return ExtractExpr::alloc(Child.get(), Offset, ResTy);
01019 }
01020 
01021 ExprResult ParserImpl::ParseAnyReadParenExpr(const Token &Name,
01022                                              unsigned Kind,
01023                                              Expr::Width ResTy) {
01024   NumberOrExprResult Index = ParseNumberOrExpr();
01025   VersionResult Array = ParseVersionSpecifier();
01026   ExpectRParen("unexpected argument in read expression.");
01027   
01028   if (!Array.isValid())
01029     return ConstantExpr::alloc(0, ResTy);
01030 
01031   // FIXME: Need generic way to get array width. Needs to work with
01032   // anonymous arrays.
01033   Expr::Width ArrayDomainType = Expr::Int32;
01034   Expr::Width ArrayRangeType = Expr::Int8;
01035 
01036   // Coerce number to correct type.
01037   ExprResult IndexExpr;
01038   if (Index.isNumber())
01039     IndexExpr = ParseNumberToken(ArrayDomainType, Index.getNumber());
01040   else
01041     IndexExpr = Index.getExpr();
01042   
01043   if (!IndexExpr.isValid())
01044     return ConstantExpr::alloc(0, ResTy);
01045   else if (IndexExpr.get()->getWidth() != ArrayDomainType) {
01046     Error("index width does not match array domain.");
01047     return ConstantExpr::alloc(0, ResTy);
01048   }
01049 
01050   // FIXME: Check range width.
01051 
01052   switch (Kind) {
01053   default:
01054     assert(0 && "Invalid kind.");
01055     return ConstantExpr::alloc(0, ResTy);
01056   case eMacroKind_ReadLSB:
01057   case eMacroKind_ReadMSB: {
01058     unsigned NumReads = ResTy / ArrayRangeType;
01059     if (ResTy != NumReads*ArrayRangeType) {
01060       Error("invalid ordered read (not multiple of range type).", Name);
01061       return ConstantExpr::alloc(0, ResTy);
01062     }
01063     std::vector<ExprHandle> Kids;
01064     Kids.reserve(NumReads);
01065     ExprHandle Index = IndexExpr.get();
01066     for (unsigned i=0; i<NumReads; ++i) {
01067       // FIXME: using folding here
01068       ExprHandle OffsetIndex = AddExpr::create(IndexExpr.get(),
01069                                                ConstantExpr::alloc(i, ArrayDomainType));
01070       Kids.push_back(ReadExpr::alloc(Array.get(), OffsetIndex));
01071     }
01072     if (Kind == eMacroKind_ReadLSB)
01073       std::reverse(Kids.begin(), Kids.end());
01074     return ConcatExpr::createN(NumReads, &Kids[0]);
01075   }
01076   case Expr::Read:
01077     return ReadExpr::alloc(Array.get(), IndexExpr.get());
01078   }
01079 }
01080 
01083 VersionResult ParserImpl::ParseVersionSpecifier() {
01084   const Identifier *Label = 0;
01085   if (Tok.kind == Token::Identifier) {
01086     Token LTok = Tok;
01087     Label = GetOrCreateIdentifier(Tok);
01088     ConsumeToken();
01089 
01090     // FIXME: hack: add array declarations and ditch this.
01091     if (memcmp(Label->Name.c_str(), "arr", 3) == 0) {
01092       // Declare or create array.
01093       const ArrayDecl *&A = ArraySymTab[Label];
01094       if (!A) {
01095         unsigned id = atoi(&Label->Name.c_str()[3]);
01096         Array *root = new Array(0, id, 0);
01097         ArrayDecl *AD = new ArrayDecl(Label, 0, 32, 8, root);
01098         // Create update list mapping of name -> array.
01099         VersionSymTab.insert(std::make_pair(Label,
01100                                             UpdateList(root, true, NULL)));
01101         ArraySymTab.insert(std::make_pair(Label, AD));
01102       }
01103     }
01104 
01105     if (Tok.kind != Token::Colon) {
01106       VersionSymTabTy::iterator it = VersionSymTab.find(Label);
01107       
01108       if (it == VersionSymTab.end()) {
01109         Error("invalid update list label reference.", LTok);
01110         return VersionResult(false,
01111                              UpdateList(0, true, NULL));
01112       }
01113 
01114       return it->second;
01115     }
01116 
01117     ConsumeToken();
01118     if (VersionSymTab.count(Label)) {
01119       Error("duplicate update list label definition.", LTok);
01120       Label = 0;
01121     }
01122   }
01123 
01124   Token Start = Tok;
01125   VersionResult Res = ParseVersion();
01126   // Define update list to avoid use-of-undef errors.
01127   if (!Res.isValid())
01128     Res = VersionResult(false,
01129                         UpdateList(0, true, NULL));
01130   
01131   if (Label)
01132     VersionSymTab.insert(std::make_pair(Label, Res.get()));
01133   return Res;
01134 }
01135 
01139 VersionResult ParserImpl::ParseVersion() {
01140   if (Tok.kind != Token::LSquare)
01141     return VersionResult(false, UpdateList(0, false, NULL));
01142   
01143   std::vector< std::pair<NumberOrExprResult, NumberOrExprResult> > Writes;
01144   ConsumeLSquare();
01145   for (;;) {
01146     // FIXME: Type check exprs.
01147 
01148     // FIXME: We need to do this (the above) anyway just to handle
01149     // implicit constants correctly.
01150     NumberOrExprResult LHS = ParseNumberOrExpr();
01151     
01152     if (Tok.kind != Token::Equals) {
01153       Error("expected '='.", Tok);
01154       break;
01155     }
01156     
01157     ConsumeToken();
01158     NumberOrExprResult RHS = ParseNumberOrExpr();
01159 
01160     Writes.push_back(std::make_pair(LHS, RHS));
01161     
01162     if (Tok.kind == Token::Comma)
01163       ConsumeToken();
01164     else
01165       break;
01166   }
01167   ExpectRSquare("expected close of update list");
01168 
01169   VersionHandle Base(0, false, NULL);
01170 
01171   // Anonymous array case.
01172   if (Tok.kind != Token::At) { 
01173     Array *root = new Array(0, 0, 0);
01174     Base = UpdateList(root, false, NULL);
01175   } else {
01176     ConsumeToken();
01177 
01178     VersionResult BaseRes = ParseVersionSpecifier();
01179     if (!BaseRes.isValid())
01180       return BaseRes;
01181 
01182     Base = BaseRes.get();
01183   }
01184 
01185   Expr::Width ArrayDomainType = Expr::Int32;
01186   Expr::Width ArrayRangeType = Expr::Int8;
01187 
01188   for (std::vector< std::pair<NumberOrExprResult, NumberOrExprResult> >::reverse_iterator
01189          it = Writes.rbegin(), ie = Writes.rend(); it != ie; ++it) {
01190     ExprResult LHS, RHS;
01191     // FIXME: This can be factored into common helper for coercing a
01192     // NumberOrExpr into an Expr.
01193     if (it->first.isNumber()) {
01194       LHS = ParseNumberToken(ArrayDomainType, it->first.getNumber());
01195     } else {
01196       LHS = it->first.getExpr(); 
01197       if (LHS.isValid() && LHS.get()->getWidth() != ArrayDomainType) {
01198         // FIXME: bad token location. We should maybe try and know the
01199         // array up-front?
01200         Error("invalid value in write index (doesn't match domain).", Tok);
01201         LHS = ExprResult();
01202       }
01203     }
01204 
01205     if (it->second.isNumber()) {
01206       RHS = ParseNumberToken(ArrayRangeType, it->second.getNumber());
01207     } else {
01208       RHS = it->second.getExpr();
01209       if (RHS.isValid() && RHS.get()->getWidth() != ArrayRangeType) {
01210         // FIXME: bad token location. We should maybe try and know the
01211         // array up-front?
01212         Error("invalid value in write assignment (doesn't match range).", Tok);
01213         RHS = ExprResult();
01214       }
01215     }
01216     
01217     if (LHS.isValid() && RHS.isValid())
01218       Base.extend(LHS.get(), RHS.get());
01219   }
01220 
01221   return Base;
01222 }
01223 
01225 ExprResult ParserImpl::ParseNumber(Expr::Width Type) {
01226   ExprResult Res = ParseNumberToken(Type, Tok);
01227   ConsumeExpectedToken(Token::Number);
01228   return Res;
01229 }
01230 
01233 ExprResult ParserImpl::ParseNumberToken(Expr::Width Type, const Token &Tok) {
01234   const char *S = Tok.start;
01235   unsigned N = Tok.length;
01236   unsigned Radix = 10, RadixBits = 4;
01237   bool HasMinus = false;
01238 
01239   // Detect +/- (a number token cannot have both).
01240   if (S[0] == '+') {
01241     ++S;
01242     --N;
01243   } else if (S[0] == '-') {
01244     HasMinus = true;
01245     ++S;
01246     --N;
01247   }
01248 
01249   // Detect 0[box].
01250   if ((Tok.length >= 2 && S[0] == '0') &&
01251       (S[1] == 'b' || S[1] == 'o' || S[1] == 'x')) {
01252     if (S[1] == 'b') {
01253       Radix = 2; 
01254       RadixBits = 1;
01255     } else if (S[1] == 'o') {
01256       Radix = 8;
01257       RadixBits = 3;
01258     } else {
01259       Radix = 16;
01260       RadixBits = 4;
01261     }
01262     S += 2;
01263     N -= 2;
01264 
01265     // Diagnose 0[box] with no trailing digits.
01266     if (!N) {
01267       Error("invalid numeric token (no digits).", Tok);
01268       return ConstantExpr::alloc(0, Type);
01269     }
01270   }
01271 
01272   // This is a simple but slow way to handle overflow.
01273   APInt Val(std::max(64U, RadixBits * N), 0);
01274   APInt RadixVal(Val.getBitWidth(), Radix);
01275   APInt DigitVal(Val.getBitWidth(), 0);
01276   for (unsigned i=0; i<N; ++i) {
01277     unsigned Digit, Char = S[i];
01278     
01279     if (Char == '_')
01280       continue;
01281     
01282     if ('0' <= Char && Char <= '9')
01283       Digit = Char - '0';
01284     else if ('a' <= Char && Char <= 'z')
01285       Digit = Char - 'a' + 10;
01286     else if ('A' <= Char && Char <= 'Z')
01287       Digit = Char - 'A' + 10;
01288     else {
01289       Error("invalid character in numeric token.", Tok);
01290       return ConstantExpr::alloc(0, Type);
01291     }
01292 
01293     if (Digit >= Radix) {
01294       Error("invalid character in numeric token (out of range).", Tok);
01295       return ConstantExpr::alloc(0, Type);
01296     }
01297 
01298     DigitVal = Digit;
01299     Val = Val * RadixVal + DigitVal;
01300   }
01301 
01302   // FIXME: Actually do the check for overflow.
01303   if (HasMinus)
01304     Val = -Val;
01305 
01306   if (Type < Val.getBitWidth())
01307     Val = Val.trunc(Type);
01308 
01309   return ExprResult(ConstantExpr::alloc(Val.getZExtValue(), Type));
01310 }
01311 
01315 TypeResult ParserImpl::ParseTypeSpecifier() {
01316   assert(Tok.kind == Token::KWWidth && "Unexpected token.");
01317 
01318   // FIXME: Need APInt technically.
01319   Token TypeTok = Tok;
01320   int width = atoi(std::string(Tok.start+1,Tok.length-1).c_str());
01321   ConsumeToken();
01322 
01323   // FIXME: We should impose some sort of maximum just for sanity?
01324   return TypeResult(width);
01325 }
01326 
01327 void ParserImpl::Error(const char *Message, const Token &At) {
01328   ++NumErrors;
01329   if (MaxErrors && NumErrors >= MaxErrors)
01330     return;
01331 
01332   llvm::cerr << Filename 
01333              << ":" << At.line << ":" << At.column 
01334              << ": error: " << Message << "\n";
01335 
01336   // Skip carat diagnostics on EOF token.
01337   if (At.kind == Token::EndOfFile)
01338     return;
01339   
01340   // Simple caret style diagnostics.
01341   const char *LineBegin = At.start, *LineEnd = At.start,
01342     *BufferBegin = TheMemoryBuffer->getBufferStart(),
01343     *BufferEnd = TheMemoryBuffer->getBufferEnd();
01344 
01345   // Run line pointers forward and back.
01346   while (LineBegin > BufferBegin && 
01347          LineBegin[-1] != '\r' && LineBegin[-1] != '\n')
01348     --LineBegin;
01349   while (LineEnd < BufferEnd && 
01350          LineEnd[0] != '\r' && LineEnd[0] != '\n')
01351     ++LineEnd;
01352 
01353   // Show the line.
01354   llvm::cerr << std::string(LineBegin, LineEnd) << "\n";
01355 
01356   // Show the caret or squiggly, making sure to print back spaces the
01357   // same.
01358   for (const char *S=LineBegin; S != At.start; ++S)
01359     llvm::cerr << (isspace(*S) ? *S : ' ');
01360   if (At.length > 1) {
01361     for (unsigned i=0; i<At.length; ++i)
01362       llvm::cerr << '~';
01363   } else
01364     llvm::cerr << '^';
01365   llvm::cerr << '\n';
01366 }
01367 
01368 // AST API
01369 // FIXME: Move out of parser.
01370 
01371 Decl::Decl(DeclKind _Kind) : Kind(_Kind) {}
01372 
01373 void ArrayDecl::dump() {
01374   std::cout << "array " << Name->Name << " : "
01375             << 'w' << Domain << " -> "
01376             << 'w' << Range << " = ";
01377 
01378   if (Contents.empty()) {
01379     std::cout << "symbolic\n";
01380   } else {
01381     std::cout << '{';
01382     for (std::vector<ExprHandle>::const_iterator it = Contents.begin(),
01383            ie = Contents.end(); it != ie;) {
01384       std::cout << *it;
01385       if (++it != ie)
01386         std::cout << " ";
01387     }
01388     std::cout << "}\n";
01389   }
01390 }
01391 
01392 void QueryCommand::dump() {
01393   const ExprHandle *ValuesBegin = 0, *ValuesEnd = 0;
01394   const Array * const* ObjectsBegin = 0, * const* ObjectsEnd = 0;
01395   if (!Values.empty()) {
01396     ValuesBegin = &Values[0];
01397     ValuesEnd = ValuesBegin + Values.size();
01398   }
01399   if (!Objects.empty()) {
01400     ObjectsBegin = &Objects[0];
01401     ObjectsEnd = ObjectsBegin + Objects.size();
01402   }
01403   ExprPPrinter::printQuery(std::cout, ConstraintManager(Constraints), 
01404                            Query, ValuesBegin, ValuesEnd,
01405                            ObjectsBegin, ObjectsEnd);
01406 }
01407 
01408 // Public parser API
01409 
01410 Parser::Parser() {
01411 }
01412 
01413 Parser::~Parser() {
01414 }
01415 
01416 Parser *Parser::Create(const std::string Filename,
01417                        const MemoryBuffer *MB) {
01418   ParserImpl *P = new ParserImpl(Filename, MB);
01419   P->Initialize();
01420   return P;
01421 }

Generated on Fri Jun 5 03:31:32 2009 for klee by  doxygen 1.5.8