diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 45361bd77b8..072bc159d83 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -188,6 +188,7 @@ external { return EXTERNAL; } implementation { return IMPLEMENTATION; } zeroinitializer { return ZEROINITIALIZER; } \.\.\. { return DOTDOTDOT; } +undef { return UNDEF; } null { return NULL_TOK; } to { return TO; } except { RET_TOK(TermOpVal, Unwind, UNWIND); } @@ -247,7 +248,7 @@ br { RET_TOK(TermOpVal, Br, BR); } switch { RET_TOK(TermOpVal, Switch, SWITCH); } invoke { RET_TOK(TermOpVal, Invoke, INVOKE); } unwind { RET_TOK(TermOpVal, Unwind, UNWIND); } - +unreachable { RET_TOK(TermOpVal, Unreachable, UNREACHABLE); } malloc { RET_TOK(MemOpVal, Malloc, MALLOC); } alloca { RET_TOK(MemOpVal, Alloca, ALLOCA); } diff --git a/lib/AsmParser/ParserInternals.h b/lib/AsmParser/ParserInternals.h index 9fdc8e66f8b..98ea0341c69 100644 --- a/lib/AsmParser/ParserInternals.h +++ b/lib/AsmParser/ParserInternals.h @@ -72,7 +72,7 @@ static inline void ThrowException(const std::string &message, struct ValID { enum { NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstFPVal, ConstNullVal, - ConstantVal, + ConstUndefVal, ConstantVal, } Type; union { @@ -108,6 +108,10 @@ struct ValID { ValID D; D.Type = ConstNullVal; return D; } + static ValID createUndef() { + ValID D; D.Type = ConstUndefVal; return D; + } + static ValID create(Constant *Val) { ValID D; D.Type = ConstantVal; D.ConstantValue = Val; return D; } @@ -130,6 +134,7 @@ struct ValID { case NameVal : return Name; case ConstFPVal : return ftostr(ConstPoolFP); case ConstNullVal : return "null"; + case ConstUndefVal : return "undef"; case ConstUIntVal : case ConstSIntVal : return std::string("%") + itostr(ConstPool64); case ConstantVal: @@ -152,6 +157,7 @@ struct ValID { case ConstUIntVal: return UConstPool64 < V.UConstPool64; case ConstFPVal: return ConstPoolFP < V.ConstPoolFP; case ConstNullVal: return false; + case ConstUndefVal: return false; case ConstantVal: return ConstantValue < V.ConstantValue; default: assert(0 && "Unknown value type!"); return false; } diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 70aee05f1ce..f450c8f0c55 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -298,6 +298,9 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) { ThrowException("Cannot create a a non pointer null!"); return ConstantPointerNull::get(cast(Ty)); + case ValID::ConstUndefVal: // Is it an undef value? + return UndefValue::get(Ty); + case ValID::ConstantVal: // Fully resolved constant? if (D.ConstantValue->getType() != Ty) ThrowException("Constant expression type different from required type!"); @@ -908,12 +911,12 @@ Module *llvm::RunVMAsmParser(const std::string &Filename, FILE *F) { %token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK %token DECLARE GLOBAL CONSTANT VOLATILE -%token TO DOTDOTDOT NULL_TOK CONST INTERNAL LINKONCE WEAK APPENDING +%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG %token DEPLIBS // Basic Block Terminating Operators -%token RET BR SWITCH INVOKE UNWIND +%token RET BR SWITCH INVOKE UNWIND UNREACHABLE // Binary Operators %type ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories @@ -1221,6 +1224,10 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr $$ = ConstantPointerNull::get(PTy); delete $1; } + | Types UNDEF { + $$ = UndefValue::get($1->get()); + delete $1; + } | Types SymbolicValueRef { const PointerType *Ty = dyn_cast($1->get()); if (Ty == 0) @@ -1687,6 +1694,9 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant | NULL_TOK { $$ = ValID::createNull(); } + | UNDEF { + $$ = ValID::createUndef(); + } | '<' ConstVector '>' { // Nonempty unsized packed vector const Type *ETy = (*$2)[0]->getType(); int NumElements = $2->size(); @@ -1858,6 +1868,9 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... } | UNWIND { $$ = new UnwindInst(); + } + | UNREACHABLE { + $$ = new UnreachableInst(); };