Add a new attribute called 'jumptable' that creates jump-instruction tables for funct...
[oota-llvm.git] / lib / AsmParser / LLLexer.cpp
index 310ea5b052a495086ed8f8bf46503cf1de0ad324..b9193e89e7ed5b199e08bd8afff2ef86144153b7 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 //===----------------------------------------------------------------------===//
 
 #include "LLLexer.h"
-#include "ParserInternals.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
-
-#include <list>
-#include "llvmAsmParser.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
 using namespace llvm;
 
+bool LLLexer::Error(LocTy ErrorLoc, const Twine &Msg) const {
+  ErrorInfo = SM.GetMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
+  return true;
+}
+
+void LLLexer::Warning(LocTy WarningLoc, const Twine &Msg) const {
+  SM.PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);
+}
+
 //===----------------------------------------------------------------------===//
 // Helper functions.
 //===----------------------------------------------------------------------===//
@@ -27,81 +46,76 @@ using namespace llvm;
 // long representation... this does not have to do input error checking,
 // because we know that the input will be matched by a suitable regex...
 //
-static uint64_t atoull(const char *Buffer, const char *End) {
+uint64_t LLLexer::atoull(const char *Buffer, const char *End) {
   uint64_t Result = 0;
   for (; Buffer != End; Buffer++) {
     uint64_t OldRes = Result;
     Result *= 10;
     Result += *Buffer-'0';
     if (Result < OldRes) {  // Uh, oh, overflow detected!!!
-      GenerateError("constant bigger than 64 bits detected!");
+      Error("constant bigger than 64 bits detected!");
       return 0;
     }
   }
   return Result;
 }
 
-static uint64_t HexIntToVal(const char *Buffer, const char *End) {
+uint64_t LLLexer::HexIntToVal(const char *Buffer, const char *End) {
   uint64_t Result = 0;
   for (; Buffer != End; ++Buffer) {
     uint64_t OldRes = Result;
     Result *= 16;
-    char C = *Buffer;
-    if (C >= '0' && C <= '9')
-      Result += C-'0';
-    else if (C >= 'A' && C <= 'F')
-      Result += C-'A'+10;
-    else if (C >= 'a' && C <= 'f')
-      Result += C-'a'+10;
-    
+    Result += hexDigitValue(*Buffer);
+
     if (Result < OldRes) {   // Uh, oh, overflow detected!!!
-      GenerateError("constant bigger than 64 bits detected!");
+      Error("constant bigger than 64 bits detected!");
       return 0;
     }
   }
   return Result;
 }
 
-// HexToFP - Convert the ascii string in hexadecimal format to the floating
-// point representation of it.
-//
-static double HexToFP(const char *Buffer, const char *End) {
-  return BitsToDouble(HexIntToVal(Buffer, End)); // Cast Hex constant to double
-}
-
-static void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]){
+void LLLexer::HexToIntPair(const char *Buffer, const char *End,
+                           uint64_t Pair[2]) {
   Pair[0] = 0;
   for (int i=0; i<16; i++, Buffer++) {
     assert(Buffer != End);
     Pair[0] *= 16;
-    char C = *Buffer;
-    if (C >= '0' && C <= '9')
-      Pair[0] += C-'0';
-    else if (C >= 'A' && C <= 'F')
-      Pair[0] += C-'A'+10;
-    else if (C >= 'a' && C <= 'f')
-      Pair[0] += C-'a'+10;
+    Pair[0] += hexDigitValue(*Buffer);
   }
   Pair[1] = 0;
   for (int i=0; i<16 && Buffer != End; i++, Buffer++) {
     Pair[1] *= 16;
-    char C = *Buffer;
-    if (C >= '0' && C <= '9')
-      Pair[1] += C-'0';
-    else if (C >= 'A' && C <= 'F')
-      Pair[1] += C-'A'+10;
-    else if (C >= 'a' && C <= 'f')
-      Pair[1] += C-'a'+10;
-  }
-  if (*Buffer)
-    GenerateError("constant bigger than 128 bits detected!");
+    Pair[1] += hexDigitValue(*Buffer);
+  }
+  if (Buffer != End)
+    Error("constant bigger than 128 bits detected!");
+}
+
+/// FP80HexToIntPair - translate an 80 bit FP80 number (20 hexits) into
+/// { low64, high16 } as usual for an APInt.
+void LLLexer::FP80HexToIntPair(const char *Buffer, const char *End,
+                           uint64_t Pair[2]) {
+  Pair[1] = 0;
+  for (int i=0; i<4 && Buffer != End; i++, Buffer++) {
+    assert(Buffer != End);
+    Pair[1] *= 16;
+    Pair[1] += hexDigitValue(*Buffer);
+  }
+  Pair[0] = 0;
+  for (int i=0; i<16; i++, Buffer++) {
+    Pair[0] *= 16;
+    Pair[0] += hexDigitValue(*Buffer);
+  }
+  if (Buffer != End)
+    Error("constant bigger than 128 bits detected!");
 }
 
 // UnEscapeLexed - Run through the specified buffer and change \xx codes to the
 // appropriate character.
 static void UnEscapeLexed(std::string &Str) {
   if (Str.empty()) return;
-  
+
   char *Buffer = &Str[0], *EndBuffer = Buffer+Str.size();
   char *BOut = Buffer;
   for (char *BIn = Buffer; BIn != EndBuffer; ) {
@@ -109,10 +123,10 @@ static void UnEscapeLexed(std::string &Str) {
       if (BIn < EndBuffer-1 && BIn[1] == '\\') {
         *BOut++ = '\\'; // Two \ becomes one
         BIn += 2;
-      } else if (BIn < EndBuffer-2 && isxdigit(BIn[1]) && isxdigit(BIn[2])) {
-        char Tmp = BIn[3]; BIn[3] = 0;      // Terminate string
-        *BOut = (char)strtol(BIn+1, 0, 16); // Convert to number
-        BIn[3] = Tmp;                       // Restore character
+      } else if (BIn < EndBuffer-2 &&
+                 isxdigit(static_cast<unsigned char>(BIn[1])) &&
+                 isxdigit(static_cast<unsigned char>(BIn[2]))) {
+        *BOut = hexDigitValue(BIn[1]) * 16 + hexDigitValue(BIn[2]);
         BIn += 3;                           // Skip over handled chars
         ++BOut;
       } else {
@@ -127,7 +141,8 @@ static void UnEscapeLexed(std::string &Str) {
 
 /// isLabelChar - Return true for [-a-zA-Z$._0-9].
 static bool isLabelChar(char C) {
-  return isalnum(C) || C == '-' || C == '$' || C == '.' || C == '_';
+  return isalnum(static_cast<unsigned char>(C)) || C == '-' || C == '$' ||
+         C == '.' || C == '_';
 }
 
 
@@ -135,7 +150,7 @@ static bool isLabelChar(char C) {
 static const char *isLabelTail(const char *CurPtr) {
   while (1) {
     if (CurPtr[0] == ':') return CurPtr+1;
-    if (!isLabelChar(CurPtr[0])) return 0;
+    if (!isLabelChar(CurPtr[0])) return nullptr;
     ++CurPtr;
   }
 }
@@ -146,11 +161,9 @@ static const char *isLabelTail(const char *CurPtr) {
 // Lexer definition.
 //===----------------------------------------------------------------------===//
 
-// FIXME: REMOVE THIS.
-#define YYEOF 0
-#define YYERROR -2
-
-LLLexer::LLLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) {
+LLLexer::LLLexer(MemoryBuffer *StartBuf, SourceMgr &sm, SMDiagnostic &Err,
+                 LLVMContext &C)
+  : CurBuf(StartBuf), ErrorInfo(Err), SM(sm), Context(C), APFloatVal(0.0) {
   CurPtr = CurBuf->getBufferStart();
 }
 
@@ -167,38 +180,26 @@ int LLLexer::getNextChar() {
     // a random nul in the file.  Disambiguate that here.
     if (CurPtr-1 != CurBuf->getBufferEnd())
       return 0;  // Just whitespace.
-        
+
     // Otherwise, return end of file.
-    --CurPtr;  // Another call to lex will return EOF again.  
+    --CurPtr;  // Another call to lex will return EOF again.
     return EOF;
-  case '\n':
-  case '\r':
-    // Handle the newline character by ignoring it and incrementing the line
-    // count.  However, be careful about 'dos style' files with \n\r in them.
-    // Only treat a \n\r or \r\n as a single line.
-    if ((*CurPtr == '\n' || (*CurPtr == '\r')) &&
-        *CurPtr != CurChar)
-      ++CurPtr;  // Eat the two char newline sequence.
-      
-    ++CurLineNo;
-    return '\n';
-  }  
+  }
 }
 
 
-int LLLexer::LexToken() {
+lltok::Kind LLLexer::LexToken() {
   TokStart = CurPtr;
-  
+
   int CurChar = getNextChar();
-  
   switch (CurChar) {
   default:
     // Handle letters: [a-zA-Z_]
-    if (isalpha(CurChar) || CurChar == '_')
+    if (isalpha(static_cast<unsigned char>(CurChar)) || CurChar == '_')
       return LexIdentifier();
-    
-    return CurChar;
-  case EOF: return YYEOF;
+
+    return lltok::Error;
+  case EOF: return lltok::Eof;
   case 0:
   case ' ':
   case '\t':
@@ -213,28 +214,42 @@ int LLLexer::LexToken() {
   case '.':
     if (const char *Ptr = isLabelTail(CurPtr)) {
       CurPtr = Ptr;
-      llvmAsmlval.StrVal = new std::string(TokStart, CurPtr-1);
-      return LABELSTR;
+      StrVal.assign(TokStart, CurPtr-1);
+      return lltok::LabelStr;
     }
     if (CurPtr[0] == '.' && CurPtr[1] == '.') {
       CurPtr += 2;
-      return DOTDOTDOT;
+      return lltok::dotdotdot;
     }
-    return '.';
+    return lltok::Error;
   case '$':
     if (const char *Ptr = isLabelTail(CurPtr)) {
       CurPtr = Ptr;
-      llvmAsmlval.StrVal = new std::string(TokStart, CurPtr-1);
-      return LABELSTR;
+      StrVal.assign(TokStart, CurPtr-1);
+      return lltok::LabelStr;
     }
-    return '$';
+    return lltok::Error;
   case ';':
     SkipLineComment();
     return LexToken();
+  case '!': return LexExclaim();
+  case '#': return LexHash();
   case '0': case '1': case '2': case '3': case '4':
   case '5': case '6': case '7': case '8': case '9':
-  case '-': 
+  case '-':
     return LexDigitOrNegative();
+  case '=': return lltok::equal;
+  case '[': return lltok::lsquare;
+  case ']': return lltok::rsquare;
+  case '{': return lltok::lbrace;
+  case '}': return lltok::rbrace;
+  case '<': return lltok::less;
+  case '>': return lltok::greater;
+  case '(': return lltok::lparen;
+  case ')': return lltok::rparen;
+  case ',': return lltok::comma;
+  case '*': return lltok::star;
+  case '\\': return lltok::backslash;
   }
 }
 
@@ -246,386 +261,475 @@ void LLLexer::SkipLineComment() {
 }
 
 /// LexAt - Lex all tokens that start with an @ character:
-///   AtStringConstant @\"[^\"]*\"
-///   GlobalVarName    @[-a-zA-Z$._][-a-zA-Z$._0-9]*
-///   GlobalVarID      @[0-9]+
-int LLLexer::LexAt() {
+///   GlobalVar   @\"[^\"]*\"
+///   GlobalVar   @[-a-zA-Z$._][-a-zA-Z$._0-9]*
+///   GlobalVarID @[0-9]+
+lltok::Kind LLLexer::LexAt() {
   // Handle AtStringConstant: @\"[^\"]*\"
   if (CurPtr[0] == '"') {
     ++CurPtr;
-    
+
     while (1) {
       int CurChar = getNextChar();
-    
-      if (CurChar == EOF) { 
-        GenerateError("End of file in global variable name");
-        return YYERROR;
+
+      if (CurChar == EOF) {
+        Error("end of file in global variable name");
+        return lltok::Error;
       }
       if (CurChar == '"') {
-        llvmAsmlval.StrVal = new std::string(TokStart+2, CurPtr-1);
-        UnEscapeLexed(*llvmAsmlval.StrVal);
-        return ATSTRINGCONSTANT;
+        StrVal.assign(TokStart+2, CurPtr-1);
+        UnEscapeLexed(StrVal);
+        if (StringRef(StrVal).find_first_of(0) != StringRef::npos) {
+          Error("Null bytes are not allowed in names");
+          return lltok::Error;
+        }
+        return lltok::GlobalVar;
       }
     }
   }
-  
+
   // Handle GlobalVarName: @[-a-zA-Z$._][-a-zA-Z$._0-9]*
-  if (isalpha(CurPtr[0]) || CurPtr[0] == '-' || CurPtr[0] == '$' || 
-      CurPtr[0] == '.' || CurPtr[0] == '_') {
-    ++CurPtr;
-    while (isalnum(CurPtr[0]) || CurPtr[0] == '-' || CurPtr[0] == '$' || 
-           CurPtr[0] == '.' || CurPtr[0] == '_')
-      ++CurPtr;
+  if (ReadVarName())
+    return lltok::GlobalVar;
 
-    llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr);   // Skip @
-    return GLOBALVAR;
-  }
-  
   // Handle GlobalVarID: @[0-9]+
-  if (isdigit(CurPtr[0])) {
-    for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr);
-    
+  if (isdigit(static_cast<unsigned char>(CurPtr[0]))) {
+    for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
+      /*empty*/;
+
     uint64_t Val = atoull(TokStart+1, CurPtr);
     if ((unsigned)Val != Val)
-      GenerateError("Invalid value number (too large)!");
-    llvmAsmlval.UIntVal = unsigned(Val);
-    return GLOBALVAL_ID;
+      Error("invalid value number (too large)!");
+    UIntVal = unsigned(Val);
+    return lltok::GlobalID;
   }
-  
-  return '@';
+
+  return lltok::Error;
 }
 
+/// ReadString - Read a string until the closing quote.
+lltok::Kind LLLexer::ReadString(lltok::Kind kind) {
+  const char *Start = CurPtr;
+  while (1) {
+    int CurChar = getNextChar();
 
-/// LexPercent - Lex all tokens that start with a % character:
-///   PctStringConstant  %\"[^\"]*\"
-///   LocalVarName       %[-a-zA-Z$._][-a-zA-Z$._0-9]*
-///   LocalVarID         %[0-9]+
-int LLLexer::LexPercent() {
-  // Handle PctStringConstant: %\"[^\"]*\"
-  if (CurPtr[0] == '"') {
-    ++CurPtr;
-    
-    while (1) {
-      int CurChar = getNextChar();
-      
-      if (CurChar == EOF) { 
-        GenerateError("End of file in local variable name");
-        return YYERROR;
-      }
-      if (CurChar == '"') {
-        llvmAsmlval.StrVal = new std::string(TokStart+2, CurPtr-1);
-        UnEscapeLexed(*llvmAsmlval.StrVal);
-        return PCTSTRINGCONSTANT;
-      }
+    if (CurChar == EOF) {
+      Error("end of file in string constant");
+      return lltok::Error;
+    }
+    if (CurChar == '"') {
+      StrVal.assign(Start, CurPtr-1);
+      UnEscapeLexed(StrVal);
+      return kind;
     }
   }
-  
-  // Handle LocalVarName: %[-a-zA-Z$._][-a-zA-Z$._0-9]*
-  if (isalpha(CurPtr[0]) || CurPtr[0] == '-' || CurPtr[0] == '$' || 
+}
+
+/// ReadVarName - Read the rest of a token containing a variable name.
+bool LLLexer::ReadVarName() {
+  const char *NameStart = CurPtr;
+  if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||
+      CurPtr[0] == '-' || CurPtr[0] == '$' ||
       CurPtr[0] == '.' || CurPtr[0] == '_') {
     ++CurPtr;
-    while (isalnum(CurPtr[0]) || CurPtr[0] == '-' || CurPtr[0] == '$' || 
+    while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||
+           CurPtr[0] == '-' || CurPtr[0] == '$' ||
            CurPtr[0] == '.' || CurPtr[0] == '_')
       ++CurPtr;
-    
-    llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr);   // Skip %
-    return LOCALVAR;
+
+    StrVal.assign(NameStart, CurPtr);
+    return true;
+  }
+  return false;
+}
+
+/// LexPercent - Lex all tokens that start with a % character:
+///   LocalVar   ::= %\"[^\"]*\"
+///   LocalVar   ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]*
+///   LocalVarID ::= %[0-9]+
+lltok::Kind LLLexer::LexPercent() {
+  // Handle LocalVarName: %\"[^\"]*\"
+  if (CurPtr[0] == '"') {
+    ++CurPtr;
+    return ReadString(lltok::LocalVar);
   }
-  
+
+  // Handle LocalVarName: %[-a-zA-Z$._][-a-zA-Z$._0-9]*
+  if (ReadVarName())
+    return lltok::LocalVar;
+
   // Handle LocalVarID: %[0-9]+
-  if (isdigit(CurPtr[0])) {
-    for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr);
-    
+  if (isdigit(static_cast<unsigned char>(CurPtr[0]))) {
+    for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
+      /*empty*/;
+
     uint64_t Val = atoull(TokStart+1, CurPtr);
     if ((unsigned)Val != Val)
-      GenerateError("Invalid value number (too large)!");
-    llvmAsmlval.UIntVal = unsigned(Val);
-    return LOCALVAL_ID;
+      Error("invalid value number (too large)!");
+    UIntVal = unsigned(Val);
+    return lltok::LocalVarID;
   }
-  
-  return '%';
+
+  return lltok::Error;
 }
 
 /// LexQuote - Lex all tokens that start with a " character:
 ///   QuoteLabel        "[^"]+":
 ///   StringConstant    "[^"]*"
-int LLLexer::LexQuote() {
-  while (1) {
-    int CurChar = getNextChar();
-    
-    if (CurChar == EOF) { 
-      GenerateError("End of file in quoted string");
-      return YYERROR;
-    }
-    
-    if (CurChar != '"') continue;
+lltok::Kind LLLexer::LexQuote() {
+  lltok::Kind kind = ReadString(lltok::StringConstant);
+  if (kind == lltok::Error || kind == lltok::Eof)
+    return kind;
 
-    if (CurPtr[0] != ':') {
-      llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr-1);
-      UnEscapeLexed(*llvmAsmlval.StrVal);
-      return STRINGCONSTANT;
-    }
-    
+  if (CurPtr[0] == ':') {
     ++CurPtr;
-    llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr-2);
-    UnEscapeLexed(*llvmAsmlval.StrVal);
-    return LABELSTR;
+    kind = lltok::LabelStr;
   }
+
+  return kind;
 }
 
-static bool JustWhitespaceNewLine(const char *&Ptr) {
-  const char *ThisPtr = Ptr;
-  while (*ThisPtr == ' ' || *ThisPtr == '\t')
-    ++ThisPtr;
-  if (*ThisPtr == '\n' || *ThisPtr == '\r') {
-    Ptr = ThisPtr;
-    return true;
+/// LexExclaim:
+///    !foo
+///    !
+lltok::Kind LLLexer::LexExclaim() {
+  // Lex a metadata name as a MetadataVar.
+  if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||
+      CurPtr[0] == '-' || CurPtr[0] == '$' ||
+      CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\') {
+    ++CurPtr;
+    while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||
+           CurPtr[0] == '-' || CurPtr[0] == '$' ||
+           CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\')
+      ++CurPtr;
+
+    StrVal.assign(TokStart+1, CurPtr);   // Skip !
+    UnEscapeLexed(StrVal);
+    return lltok::MetadataVar;
   }
-  return false;
+  return lltok::exclaim;
 }
 
+/// LexHash - Lex all tokens that start with a # character:
+///    AttrGrpID ::= #[0-9]+
+lltok::Kind LLLexer::LexHash() {
+  // Handle AttrGrpID: #[0-9]+
+  if (isdigit(static_cast<unsigned char>(CurPtr[0]))) {
+    for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
+      /*empty*/;
+
+    uint64_t Val = atoull(TokStart+1, CurPtr);
+    if ((unsigned)Val != Val)
+      Error("invalid value number (too large)!");
+    UIntVal = unsigned(Val);
+    return lltok::AttrGrpID;
+  }
+
+  return lltok::Error;
+}
 
 /// LexIdentifier: Handle several related productions:
 ///    Label           [-a-zA-Z$._0-9]+:
 ///    IntegerType     i[0-9]+
 ///    Keyword         sdiv, float, ...
 ///    HexIntConstant  [us]0x[0-9A-Fa-f]+
-int LLLexer::LexIdentifier() {
+lltok::Kind LLLexer::LexIdentifier() {
   const char *StartChar = CurPtr;
-  const char *IntEnd = CurPtr[-1] == 'i' ? 0 : StartChar;
-  const char *KeywordEnd = 0;
-  
+  const char *IntEnd = CurPtr[-1] == 'i' ? nullptr : StartChar;
+  const char *KeywordEnd = nullptr;
+
   for (; isLabelChar(*CurPtr); ++CurPtr) {
     // If we decide this is an integer, remember the end of the sequence.
-    if (!IntEnd && !isdigit(*CurPtr)) IntEnd = CurPtr;
-    if (!KeywordEnd && !isalnum(*CurPtr) && *CurPtr != '_') KeywordEnd = CurPtr;
+    if (!IntEnd && !isdigit(static_cast<unsigned char>(*CurPtr)))
+      IntEnd = CurPtr;
+    if (!KeywordEnd && !isalnum(static_cast<unsigned char>(*CurPtr)) &&
+        *CurPtr != '_')
+      KeywordEnd = CurPtr;
   }
-  
+
   // If we stopped due to a colon, this really is a label.
   if (*CurPtr == ':') {
-    llvmAsmlval.StrVal = new std::string(StartChar-1, CurPtr++);
-    return LABELSTR;
+    StrVal.assign(StartChar-1, CurPtr++);
+    return lltok::LabelStr;
   }
-  
+
   // Otherwise, this wasn't a label.  If this was valid as an integer type,
   // return it.
-  if (IntEnd == 0) IntEnd = CurPtr;
+  if (!IntEnd) IntEnd = CurPtr;
   if (IntEnd != StartChar) {
     CurPtr = IntEnd;
     uint64_t NumBits = atoull(StartChar, CurPtr);
-    if (NumBits < IntegerType::MIN_INT_BITS || 
+    if (NumBits < IntegerType::MIN_INT_BITS ||
         NumBits > IntegerType::MAX_INT_BITS) {
-      GenerateError("Bitwidth for integer type out of range!");
-      return YYERROR;
+      Error("bitwidth for integer type out of range!");
+      return lltok::Error;
     }
-    const Type* Ty = IntegerType::get(NumBits);
-    llvmAsmlval.PrimType = Ty;
-    return INTTYPE;
+    TyVal = IntegerType::get(Context, NumBits);
+    return lltok::Type;
   }
-  
+
   // Otherwise, this was a letter sequence.  See which keyword this is.
-  if (KeywordEnd == 0) KeywordEnd = CurPtr;
+  if (!KeywordEnd) KeywordEnd = CurPtr;
   CurPtr = KeywordEnd;
   --StartChar;
   unsigned Len = CurPtr-StartChar;
-#define KEYWORD(STR, TOK) \
-  if (Len == strlen(STR) && !memcmp(StartChar, STR, strlen(STR))) return TOK;
-
-  KEYWORD("begin",     BEGINTOK);
-  KEYWORD("end",       ENDTOK);
-  KEYWORD("true",      TRUETOK);
-  KEYWORD("false",     FALSETOK);
-  KEYWORD("declare",   DECLARE);
-  KEYWORD("define",    DEFINE);
-  KEYWORD("global",    GLOBAL);
-  KEYWORD("constant",  CONSTANT);
-  
-  KEYWORD("internal",  INTERNAL);
-  KEYWORD("linkonce",  LINKONCE);
-  KEYWORD("weak",      WEAK);
-  KEYWORD("appending", APPENDING);
-  KEYWORD("dllimport", DLLIMPORT);
-  KEYWORD("dllexport", DLLEXPORT);
-  KEYWORD("hidden", HIDDEN);
-  KEYWORD("protected", PROTECTED);
-  KEYWORD("extern_weak", EXTERN_WEAK);
-  KEYWORD("external", EXTERNAL);
-  KEYWORD("thread_local", THREAD_LOCAL);
-  KEYWORD("zeroinitializer", ZEROINITIALIZER);
-  KEYWORD("undef", UNDEF);
-  KEYWORD("null", NULL_TOK);
-  KEYWORD("to", TO);
-  KEYWORD("tail", TAIL);
-  KEYWORD("target", TARGET);
-  KEYWORD("triple", TRIPLE);
-  KEYWORD("deplibs", DEPLIBS);
-  KEYWORD("datalayout", DATALAYOUT);
-  KEYWORD("volatile", VOLATILE);
-  KEYWORD("align", ALIGN);
-  KEYWORD("section", SECTION);
-  KEYWORD("alias", ALIAS);
-  KEYWORD("module", MODULE);
-  KEYWORD("asm", ASM_TOK);
-  KEYWORD("sideeffect", SIDEEFFECT);
-  
-  KEYWORD("cc", CC_TOK);
-  KEYWORD("ccc", CCC_TOK);
-  KEYWORD("fastcc", FASTCC_TOK);
-  KEYWORD("coldcc", COLDCC_TOK);
-  KEYWORD("x86_stdcallcc", X86_STDCALLCC_TOK);
-  KEYWORD("x86_fastcallcc", X86_FASTCALLCC_TOK);
-  
-  KEYWORD("signext", SIGNEXT);
-  KEYWORD("zeroext", ZEROEXT);
-  KEYWORD("inreg", INREG);
-  KEYWORD("sret", SRET);
-  KEYWORD("nounwind", NOUNWIND);
-  KEYWORD("noreturn", NORETURN);
-  KEYWORD("noalias", NOALIAS);
-  KEYWORD("byval", BYVAL);
-  KEYWORD("nest", NEST);
-  KEYWORD("pure", PURE);
-  KEYWORD("const", CONST);
-  
-  KEYWORD("type", TYPE);
-  KEYWORD("opaque", OPAQUE);
-
-  KEYWORD("eq" , EQ);
-  KEYWORD("ne" , NE);
-  KEYWORD("slt", SLT);
-  KEYWORD("sgt", SGT);
-  KEYWORD("sle", SLE);
-  KEYWORD("sge", SGE);
-  KEYWORD("ult", ULT);
-  KEYWORD("ugt", UGT);
-  KEYWORD("ule", ULE);
-  KEYWORD("uge", UGE);
-  KEYWORD("oeq", OEQ);
-  KEYWORD("one", ONE);
-  KEYWORD("olt", OLT);
-  KEYWORD("ogt", OGT);
-  KEYWORD("ole", OLE);
-  KEYWORD("oge", OGE);
-  KEYWORD("ord", ORD);
-  KEYWORD("uno", UNO);
-  KEYWORD("ueq", UEQ);
-  KEYWORD("une", UNE);
+#define KEYWORD(STR)                                                    \
+  do {                                                                  \
+    if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR)))  \
+      return lltok::kw_##STR;                                           \
+  } while (0)
+
+  KEYWORD(true);    KEYWORD(false);
+  KEYWORD(declare); KEYWORD(define);
+  KEYWORD(global);  KEYWORD(constant);
+
+  KEYWORD(private);
+  KEYWORD(internal);
+  KEYWORD(linker_private);        // NOTE: deprecated, for parser compatibility
+  KEYWORD(linker_private_weak);   // NOTE: deprecated, for parser compatibility
+  KEYWORD(available_externally);
+  KEYWORD(linkonce);
+  KEYWORD(linkonce_odr);
+  KEYWORD(weak);
+  KEYWORD(weak_odr);
+  KEYWORD(appending);
+  KEYWORD(dllimport);
+  KEYWORD(dllexport);
+  KEYWORD(common);
+  KEYWORD(default);
+  KEYWORD(hidden);
+  KEYWORD(protected);
+  KEYWORD(unnamed_addr);
+  KEYWORD(externally_initialized);
+  KEYWORD(extern_weak);
+  KEYWORD(external);
+  KEYWORD(thread_local);
+  KEYWORD(localdynamic);
+  KEYWORD(initialexec);
+  KEYWORD(localexec);
+  KEYWORD(zeroinitializer);
+  KEYWORD(undef);
+  KEYWORD(null);
+  KEYWORD(to);
+  KEYWORD(tail);
+  KEYWORD(musttail);
+  KEYWORD(target);
+  KEYWORD(triple);
+  KEYWORD(unwind);
+  KEYWORD(deplibs);             // FIXME: Remove in 4.0.
+  KEYWORD(datalayout);
+  KEYWORD(volatile);
+  KEYWORD(atomic);
+  KEYWORD(unordered);
+  KEYWORD(monotonic);
+  KEYWORD(acquire);
+  KEYWORD(release);
+  KEYWORD(acq_rel);
+  KEYWORD(seq_cst);
+  KEYWORD(singlethread);
+
+  KEYWORD(nnan);
+  KEYWORD(ninf);
+  KEYWORD(nsz);
+  KEYWORD(arcp);
+  KEYWORD(fast);
+  KEYWORD(nuw);
+  KEYWORD(nsw);
+  KEYWORD(exact);
+  KEYWORD(inbounds);
+  KEYWORD(align);
+  KEYWORD(addrspace);
+  KEYWORD(section);
+  KEYWORD(alias);
+  KEYWORD(module);
+  KEYWORD(asm);
+  KEYWORD(sideeffect);
+  KEYWORD(alignstack);
+  KEYWORD(inteldialect);
+  KEYWORD(gc);
+  KEYWORD(prefix);
+
+  KEYWORD(ccc);
+  KEYWORD(fastcc);
+  KEYWORD(coldcc);
+  KEYWORD(x86_stdcallcc);
+  KEYWORD(x86_fastcallcc);
+  KEYWORD(x86_thiscallcc);
+  KEYWORD(arm_apcscc);
+  KEYWORD(arm_aapcscc);
+  KEYWORD(arm_aapcs_vfpcc);
+  KEYWORD(msp430_intrcc);
+  KEYWORD(ptx_kernel);
+  KEYWORD(ptx_device);
+  KEYWORD(spir_kernel);
+  KEYWORD(spir_func);
+  KEYWORD(intel_ocl_bicc);
+  KEYWORD(x86_64_sysvcc);
+  KEYWORD(x86_64_win64cc);
+  KEYWORD(webkit_jscc);
+  KEYWORD(anyregcc);
+  KEYWORD(preserve_mostcc);
+  KEYWORD(preserve_allcc);
+
+  KEYWORD(cc);
+  KEYWORD(c);
+
+  KEYWORD(attributes);
+
+  KEYWORD(alwaysinline);
+  KEYWORD(builtin);
+  KEYWORD(byval);
+  KEYWORD(inalloca);
+  KEYWORD(cold);
+  KEYWORD(inlinehint);
+  KEYWORD(inreg);
+  KEYWORD(jumptable);
+  KEYWORD(minsize);
+  KEYWORD(naked);
+  KEYWORD(nest);
+  KEYWORD(noalias);
+  KEYWORD(nobuiltin);
+  KEYWORD(nocapture);
+  KEYWORD(noduplicate);
+  KEYWORD(noimplicitfloat);
+  KEYWORD(noinline);
+  KEYWORD(nonlazybind);
+  KEYWORD(nonnull);
+  KEYWORD(noredzone);
+  KEYWORD(noreturn);
+  KEYWORD(nounwind);
+  KEYWORD(optnone);
+  KEYWORD(optsize);
+  KEYWORD(readnone);
+  KEYWORD(readonly);
+  KEYWORD(returned);
+  KEYWORD(returns_twice);
+  KEYWORD(signext);
+  KEYWORD(sret);
+  KEYWORD(ssp);
+  KEYWORD(sspreq);
+  KEYWORD(sspstrong);
+  KEYWORD(sanitize_address);
+  KEYWORD(sanitize_thread);
+  KEYWORD(sanitize_memory);
+  KEYWORD(uwtable);
+  KEYWORD(zeroext);
+
+  KEYWORD(type);
+  KEYWORD(opaque);
+
+  KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);
+  KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge);
+  KEYWORD(oeq); KEYWORD(one); KEYWORD(olt); KEYWORD(ogt); KEYWORD(ole);
+  KEYWORD(oge); KEYWORD(ord); KEYWORD(uno); KEYWORD(ueq); KEYWORD(une);
+
+  KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax);
+  KEYWORD(umin);
+
+  KEYWORD(x);
+  KEYWORD(blockaddress);
+
+  KEYWORD(personality);
+  KEYWORD(cleanup);
+  KEYWORD(catch);
+  KEYWORD(filter);
 #undef KEYWORD
 
   // Keywords for types.
-#define TYPEKEYWORD(STR, LLVMTY, TOK) \
+#define TYPEKEYWORD(STR, LLVMTY) \
   if (Len == strlen(STR) && !memcmp(StartChar, STR, strlen(STR))) { \
-    llvmAsmlval.PrimType = LLVMTY; return TOK; }
-  TYPEKEYWORD("void",      Type::VoidTy,  VOID);
-  TYPEKEYWORD("float",     Type::FloatTy, FLOAT);
-  TYPEKEYWORD("double",    Type::DoubleTy, DOUBLE);
-  TYPEKEYWORD("x86_fp80",  Type::X86_FP80Ty, X86_FP80);
-  TYPEKEYWORD("fp128",     Type::FP128Ty, FP128);
-  TYPEKEYWORD("ppc_fp128", Type::PPC_FP128Ty, PPC_FP128);
-  TYPEKEYWORD("label",     Type::LabelTy, LABEL);
+    TyVal = LLVMTY; return lltok::Type; }
+  TYPEKEYWORD("void",      Type::getVoidTy(Context));
+  TYPEKEYWORD("half",      Type::getHalfTy(Context));
+  TYPEKEYWORD("float",     Type::getFloatTy(Context));
+  TYPEKEYWORD("double",    Type::getDoubleTy(Context));
+  TYPEKEYWORD("x86_fp80",  Type::getX86_FP80Ty(Context));
+  TYPEKEYWORD("fp128",     Type::getFP128Ty(Context));
+  TYPEKEYWORD("ppc_fp128", Type::getPPC_FP128Ty(Context));
+  TYPEKEYWORD("label",     Type::getLabelTy(Context));
+  TYPEKEYWORD("metadata",  Type::getMetadataTy(Context));
+  TYPEKEYWORD("x86_mmx",   Type::getX86_MMXTy(Context));
 #undef TYPEKEYWORD
 
-  // Handle special forms for autoupgrading.  Drop these in LLVM 3.0.  This is
-  // to avoid conflicting with the sext/zext instructions, below.
-  if (Len == 4 && !memcmp(StartChar, "sext", 4)) {
-    // Scan CurPtr ahead, seeing if there is just whitespace before the newline.
-    if (JustWhitespaceNewLine(CurPtr))
-      return SIGNEXT;
-  } else if (Len == 4 && !memcmp(StartChar, "zext", 4)) {
-    // Scan CurPtr ahead, seeing if there is just whitespace before the newline.
-    if (JustWhitespaceNewLine(CurPtr))
-      return ZEROEXT;
-  }
-  
   // Keywords for instructions.
-#define INSTKEYWORD(STR, type, Enum, TOK) \
-  if (Len == strlen(STR) && !memcmp(StartChar, STR, strlen(STR))) { \
-    llvmAsmlval.type = Instruction::Enum; return TOK; }
-
-  INSTKEYWORD("add",     BinaryOpVal, Add, ADD);
-  INSTKEYWORD("sub",     BinaryOpVal, Sub, SUB);
-  INSTKEYWORD("mul",     BinaryOpVal, Mul, MUL);
-  INSTKEYWORD("udiv",    BinaryOpVal, UDiv, UDIV);
-  INSTKEYWORD("sdiv",    BinaryOpVal, SDiv, SDIV);
-  INSTKEYWORD("fdiv",    BinaryOpVal, FDiv, FDIV);
-  INSTKEYWORD("urem",    BinaryOpVal, URem, UREM);
-  INSTKEYWORD("srem",    BinaryOpVal, SRem, SREM);
-  INSTKEYWORD("frem",    BinaryOpVal, FRem, FREM);
-  INSTKEYWORD("shl",     BinaryOpVal, Shl, SHL);
-  INSTKEYWORD("lshr",    BinaryOpVal, LShr, LSHR);
-  INSTKEYWORD("ashr",    BinaryOpVal, AShr, ASHR);
-  INSTKEYWORD("and",     BinaryOpVal, And, AND);
-  INSTKEYWORD("or",      BinaryOpVal, Or , OR );
-  INSTKEYWORD("xor",     BinaryOpVal, Xor, XOR);
-  INSTKEYWORD("icmp",    OtherOpVal,  ICmp,  ICMP);
-  INSTKEYWORD("fcmp",    OtherOpVal,  FCmp,  FCMP);
-
-  INSTKEYWORD("phi",         OtherOpVal, PHI, PHI_TOK);
-  INSTKEYWORD("call",        OtherOpVal, Call, CALL);
-  INSTKEYWORD("trunc",       CastOpVal, Trunc, TRUNC);
-  INSTKEYWORD("zext",        CastOpVal, ZExt, ZEXT);
-  INSTKEYWORD("sext",        CastOpVal, SExt, SEXT);
-  INSTKEYWORD("fptrunc",     CastOpVal, FPTrunc, FPTRUNC);
-  INSTKEYWORD("fpext",       CastOpVal, FPExt, FPEXT);
-  INSTKEYWORD("uitofp",      CastOpVal, UIToFP, UITOFP);
-  INSTKEYWORD("sitofp",      CastOpVal, SIToFP, SITOFP);
-  INSTKEYWORD("fptoui",      CastOpVal, FPToUI, FPTOUI);
-  INSTKEYWORD("fptosi",      CastOpVal, FPToSI, FPTOSI);
-  INSTKEYWORD("inttoptr",    CastOpVal, IntToPtr, INTTOPTR);
-  INSTKEYWORD("ptrtoint",    CastOpVal, PtrToInt, PTRTOINT);
-  INSTKEYWORD("bitcast",     CastOpVal, BitCast, BITCAST);
-  INSTKEYWORD("select",      OtherOpVal, Select, SELECT);
-  INSTKEYWORD("va_arg",      OtherOpVal, VAArg , VAARG);
-  INSTKEYWORD("ret",         TermOpVal, Ret, RET);
-  INSTKEYWORD("br",          TermOpVal, Br, BR);
-  INSTKEYWORD("switch",      TermOpVal, Switch, SWITCH);
-  INSTKEYWORD("invoke",      TermOpVal, Invoke, INVOKE);
-  INSTKEYWORD("unwind",      TermOpVal, Unwind, UNWIND);
-  INSTKEYWORD("unreachable", TermOpVal, Unreachable, UNREACHABLE);
-
-  INSTKEYWORD("malloc",      MemOpVal, Malloc, MALLOC);
-  INSTKEYWORD("alloca",      MemOpVal, Alloca, ALLOCA);
-  INSTKEYWORD("free",        MemOpVal, Free, FREE);
-  INSTKEYWORD("load",        MemOpVal, Load, LOAD);
-  INSTKEYWORD("store",       MemOpVal, Store, STORE);
-  INSTKEYWORD("getelementptr", MemOpVal, GetElementPtr, GETELEMENTPTR);
-
-  INSTKEYWORD("extractelement", OtherOpVal, ExtractElement, EXTRACTELEMENT);
-  INSTKEYWORD("insertelement", OtherOpVal, InsertElement, INSERTELEMENT);
-  INSTKEYWORD("shufflevector", OtherOpVal, ShuffleVector, SHUFFLEVECTOR);
-#undef INSTKEYWORD 
-  
+#define INSTKEYWORD(STR, Enum) \
+  if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) { \
+    UIntVal = Instruction::Enum; return lltok::kw_##STR; }
+
+  INSTKEYWORD(add,   Add);  INSTKEYWORD(fadd,   FAdd);
+  INSTKEYWORD(sub,   Sub);  INSTKEYWORD(fsub,   FSub);
+  INSTKEYWORD(mul,   Mul);  INSTKEYWORD(fmul,   FMul);
+  INSTKEYWORD(udiv,  UDiv); INSTKEYWORD(sdiv,  SDiv); INSTKEYWORD(fdiv,  FDiv);
+  INSTKEYWORD(urem,  URem); INSTKEYWORD(srem,  SRem); INSTKEYWORD(frem,  FRem);
+  INSTKEYWORD(shl,   Shl);  INSTKEYWORD(lshr,  LShr); INSTKEYWORD(ashr,  AShr);
+  INSTKEYWORD(and,   And);  INSTKEYWORD(or,    Or);   INSTKEYWORD(xor,   Xor);
+  INSTKEYWORD(icmp,  ICmp); INSTKEYWORD(fcmp,  FCmp);
+
+  INSTKEYWORD(phi,         PHI);
+  INSTKEYWORD(call,        Call);
+  INSTKEYWORD(trunc,       Trunc);
+  INSTKEYWORD(zext,        ZExt);
+  INSTKEYWORD(sext,        SExt);
+  INSTKEYWORD(fptrunc,     FPTrunc);
+  INSTKEYWORD(fpext,       FPExt);
+  INSTKEYWORD(uitofp,      UIToFP);
+  INSTKEYWORD(sitofp,      SIToFP);
+  INSTKEYWORD(fptoui,      FPToUI);
+  INSTKEYWORD(fptosi,      FPToSI);
+  INSTKEYWORD(inttoptr,    IntToPtr);
+  INSTKEYWORD(ptrtoint,    PtrToInt);
+  INSTKEYWORD(bitcast,     BitCast);
+  INSTKEYWORD(addrspacecast, AddrSpaceCast);
+  INSTKEYWORD(select,      Select);
+  INSTKEYWORD(va_arg,      VAArg);
+  INSTKEYWORD(ret,         Ret);
+  INSTKEYWORD(br,          Br);
+  INSTKEYWORD(switch,      Switch);
+  INSTKEYWORD(indirectbr,  IndirectBr);
+  INSTKEYWORD(invoke,      Invoke);
+  INSTKEYWORD(resume,      Resume);
+  INSTKEYWORD(unreachable, Unreachable);
+
+  INSTKEYWORD(alloca,      Alloca);
+  INSTKEYWORD(load,        Load);
+  INSTKEYWORD(store,       Store);
+  INSTKEYWORD(cmpxchg,     AtomicCmpXchg);
+  INSTKEYWORD(atomicrmw,   AtomicRMW);
+  INSTKEYWORD(fence,       Fence);
+  INSTKEYWORD(getelementptr, GetElementPtr);
+
+  INSTKEYWORD(extractelement, ExtractElement);
+  INSTKEYWORD(insertelement,  InsertElement);
+  INSTKEYWORD(shufflevector,  ShuffleVector);
+  INSTKEYWORD(extractvalue,   ExtractValue);
+  INSTKEYWORD(insertvalue,    InsertValue);
+  INSTKEYWORD(landingpad,     LandingPad);
+#undef INSTKEYWORD
+
   // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
   // the CFE to avoid forcing it to deal with 64-bit numbers.
   if ((TokStart[0] == 'u' || TokStart[0] == 's') &&
-      TokStart[1] == '0' && TokStart[2] == 'x' && isxdigit(TokStart[3])) {
+      TokStart[1] == '0' && TokStart[2] == 'x' &&
+      isxdigit(static_cast<unsigned char>(TokStart[3]))) {
     int len = CurPtr-TokStart-3;
     uint32_t bits = len * 4;
-    APInt Tmp(bits, TokStart+3, len, 16);
+    APInt Tmp(bits, StringRef(TokStart+3, len), 16);
     uint32_t activeBits = Tmp.getActiveBits();
     if (activeBits > 0 && activeBits < bits)
-      Tmp.trunc(activeBits);
-    if (Tmp.getBitWidth() > 64) {
-      llvmAsmlval.APIntVal = new APInt(Tmp);
-      return TokStart[0] == 's' ? ESAPINTVAL : EUAPINTVAL;
-    } else if (TokStart[0] == 's') {
-      llvmAsmlval.SInt64Val = Tmp.getSExtValue();
-      return ESINT64VAL;
-    } else {
-      llvmAsmlval.UInt64Val = Tmp.getZExtValue();
-      return EUINT64VAL;
-    }
+      Tmp = Tmp.trunc(activeBits);
+    APSIntVal = APSInt(Tmp, TokStart[0] == 'u');
+    return lltok::APSInt;
   }
-  
-  // Finally, if this is "cc1234", return this as just "cc".
+
+  // If this is "cc1234", return this as just "cc".
   if (TokStart[0] == 'c' && TokStart[1] == 'c') {
     CurPtr = TokStart+2;
-    return CC_TOK;
+    return lltok::kw_cc;
   }
-  
-  // Finally, if this isn't known, return just a single character.
+
+  // Finally, if this isn't known, return an error.
   CurPtr = TokStart+1;
-  return TokStart[0];
+  return lltok::Error;
 }
 
 
@@ -635,49 +739,56 @@ int LLLexer::LexIdentifier() {
 ///    HexFP80Constant   0xK[0-9A-Fa-f]+
 ///    HexFP128Constant  0xL[0-9A-Fa-f]+
 ///    HexPPC128Constant 0xM[0-9A-Fa-f]+
-int LLLexer::Lex0x() {
+///    HexHalfConstant   0xH[0-9A-Fa-f]+
+lltok::Kind LLLexer::Lex0x() {
   CurPtr = TokStart + 2;
-  
+
   char Kind;
-  if (CurPtr[0] >= 'K' && CurPtr[0] <= 'M') {
+  if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H') {
     Kind = *CurPtr++;
   } else {
     Kind = 'J';
   }
 
-  if (!isxdigit(CurPtr[0])) {
-    // Bad token, return it as just zero.
+  if (!isxdigit(static_cast<unsigned char>(CurPtr[0]))) {
+    // Bad token, return it as an error.
     CurPtr = TokStart+1;
-    return '0';
+    return lltok::Error;
   }
-  
-  while (isxdigit(CurPtr[0]))
+
+  while (isxdigit(static_cast<unsigned char>(CurPtr[0])))
     ++CurPtr;
-  
+
   if (Kind == 'J') {
     // HexFPConstant - Floating point constant represented in IEEE format as a
     // hexadecimal number for when exponential notation is not precise enough.
-    // Float and double only.
-    llvmAsmlval.FPVal = new APFloat(HexToFP(TokStart+2, CurPtr)); 
-    return FPVAL;
+    // Half, Float, and double only.
+    APFloatVal = APFloat(BitsToDouble(HexIntToVal(TokStart+2, CurPtr)));
+    return lltok::APFloat;
   }
-  
+
   uint64_t Pair[2];
-  HexToIntPair(TokStart+3, CurPtr, Pair);
   switch (Kind) {
-  default: assert(0 && "Unknown kind!");
+  default: llvm_unreachable("Unknown kind!");
   case 'K':
     // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
-    llvmAsmlval.FPVal = new APFloat(APInt(80, 2, Pair));
-    return FPVAL;
+    FP80HexToIntPair(TokStart+3, CurPtr, Pair);
+    APFloatVal = APFloat(APFloat::x87DoubleExtended, APInt(80, Pair));
+    return lltok::APFloat;
   case 'L':
     // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)
-    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true);
-    return FPVAL;
+    HexToIntPair(TokStart+3, CurPtr, Pair);
+    APFloatVal = APFloat(APFloat::IEEEquad, APInt(128, Pair));
+    return lltok::APFloat;
   case 'M':
     // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
-    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair));
-    return FPVAL;
+    HexToIntPair(TokStart+3, CurPtr, Pair);
+    APFloatVal = APFloat(APFloat::PPCDoubleDouble, APInt(128, Pair));
+    return lltok::APFloat;
+  case 'H':
+    APFloatVal = APFloat(APFloat::IEEEhalf,
+                         APInt(16,HexIntToVal(TokStart+3, CurPtr)));
+    return lltok::APFloat;
   }
 }
 
@@ -690,33 +801,35 @@ int LLLexer::Lex0x() {
 ///    HexFP80Constant   0xK[0-9A-Fa-f]+
 ///    HexFP128Constant  0xL[0-9A-Fa-f]+
 ///    HexPPC128Constant 0xM[0-9A-Fa-f]+
-int LLLexer::LexDigitOrNegative() {
-  // If the letter after the negative is a number, this is probably a label.
-  if (!isdigit(TokStart[0]) && !isdigit(CurPtr[0])) {
+lltok::Kind LLLexer::LexDigitOrNegative() {
+  // If the letter after the negative is not a number, this is probably a label.
+  if (!isdigit(static_cast<unsigned char>(TokStart[0])) &&
+      !isdigit(static_cast<unsigned char>(CurPtr[0]))) {
     // Okay, this is not a number after the -, it's probably a label.
     if (const char *End = isLabelTail(CurPtr)) {
-      llvmAsmlval.StrVal = new std::string(TokStart, End-1);
+      StrVal.assign(TokStart, End-1);
       CurPtr = End;
-      return LABELSTR;
+      return lltok::LabelStr;
     }
-    
-    return CurPtr[-1];
+
+    return lltok::Error;
   }
-  
+
   // At this point, it is either a label, int or fp constant.
-  
+
   // Skip digits, we have at least one.
-  for (; isdigit(CurPtr[0]); ++CurPtr);
-    
+  for (; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
+    /*empty*/;
+
   // Check to see if this really is a label afterall, e.g. "-1:".
   if (isLabelChar(CurPtr[0]) || CurPtr[0] == ':') {
     if (const char *End = isLabelTail(CurPtr)) {
-      llvmAsmlval.StrVal = new std::string(TokStart, End-1);
+      StrVal.assign(TokStart, End-1);
       CurPtr = End;
-      return LABELSTR;
+      return lltok::LabelStr;
     }
   }
-    
+
   // If the next character is a '.', then it is a fp value, otherwise its
   // integer.
   if (CurPtr[0] != '.') {
@@ -724,103 +837,70 @@ int LLLexer::LexDigitOrNegative() {
       return Lex0x();
     unsigned Len = CurPtr-TokStart;
     uint32_t numBits = ((Len * 64) / 19) + 2;
-    APInt Tmp(numBits, TokStart, Len, 10);
+    APInt Tmp(numBits, StringRef(TokStart, Len), 10);
     if (TokStart[0] == '-') {
       uint32_t minBits = Tmp.getMinSignedBits();
       if (minBits > 0 && minBits < numBits)
-        Tmp.trunc(minBits);
-      if (Tmp.getBitWidth() > 64) {
-        llvmAsmlval.APIntVal = new APInt(Tmp);
-        return ESAPINTVAL;
-      } else {
-        llvmAsmlval.SInt64Val = Tmp.getSExtValue();
-        return ESINT64VAL;
-      }
+        Tmp = Tmp.trunc(minBits);
+      APSIntVal = APSInt(Tmp, false);
     } else {
       uint32_t activeBits = Tmp.getActiveBits();
       if (activeBits > 0 && activeBits < numBits)
-        Tmp.trunc(activeBits);
-      if (Tmp.getBitWidth() > 64) {
-        llvmAsmlval.APIntVal = new APInt(Tmp);
-        return EUAPINTVAL; 
-      } else {
-        llvmAsmlval.UInt64Val = Tmp.getZExtValue();
-        return EUINT64VAL;
-      }
+        Tmp = Tmp.trunc(activeBits);
+      APSIntVal = APSInt(Tmp, true);
     }
+    return lltok::APSInt;
   }
 
   ++CurPtr;
-  
+
   // Skip over [0-9]*([eE][-+]?[0-9]+)?
-  while (isdigit(CurPtr[0])) ++CurPtr;
-  
+  while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
+
   if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {
-    if (isdigit(CurPtr[1]) || 
-        ((CurPtr[1] == '-' || CurPtr[1] == '+') && isdigit(CurPtr[2]))) {
+    if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||
+        ((CurPtr[1] == '-' || CurPtr[1] == '+') &&
+          isdigit(static_cast<unsigned char>(CurPtr[2])))) {
       CurPtr += 2;
-      while (isdigit(CurPtr[0])) ++CurPtr;
+      while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
     }
   }
-  
-  llvmAsmlval.FPVal = new APFloat(atof(TokStart));
-  return FPVAL; 
+
+  APFloatVal = APFloat(std::atof(TokStart));
+  return lltok::APFloat;
 }
 
 ///    FPConstant  [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
-int LLLexer::LexPositive() {
+lltok::Kind LLLexer::LexPositive() {
   // If the letter after the negative is a number, this is probably not a
   // label.
-  if (!isdigit(CurPtr[0]))
-    return CurPtr[-1];
-  
+  if (!isdigit(static_cast<unsigned char>(CurPtr[0])))
+    return lltok::Error;
+
   // Skip digits.
-  for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr);
+  for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
+    /*empty*/;
 
   // At this point, we need a '.'.
   if (CurPtr[0] != '.') {
     CurPtr = TokStart+1;
-    return TokStart[0];
+    return lltok::Error;
   }
-  
+
   ++CurPtr;
-  
+
   // Skip over [0-9]*([eE][-+]?[0-9]+)?
-  while (isdigit(CurPtr[0])) ++CurPtr;
-  
+  while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
+
   if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {
-    if (isdigit(CurPtr[1]) || 
-        ((CurPtr[1] == '-' || CurPtr[1] == '+') && isdigit(CurPtr[2]))) {
+    if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||
+        ((CurPtr[1] == '-' || CurPtr[1] == '+') &&
+        isdigit(static_cast<unsigned char>(CurPtr[2])))) {
       CurPtr += 2;
-      while (isdigit(CurPtr[0])) ++CurPtr;
+      while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
     }
   }
-  
-  llvmAsmlval.FPVal = new APFloat(atof(TokStart));
-  return FPVAL; 
-}
-
 
-//===----------------------------------------------------------------------===//
-// Define the interface to this file.
-//===----------------------------------------------------------------------===//
-
-static LLLexer *TheLexer;
-
-void InitLLLexer(llvm::MemoryBuffer *MB) {
-  assert(TheLexer == 0 && "LL Lexer isn't reentrant yet");
-  TheLexer = new LLLexer(MB);
-}
-
-int llvmAsmlex() {
-  return TheLexer->LexToken();
-}
-const char *LLLgetTokenStart() { return TheLexer->getTokStart(); }
-unsigned LLLgetTokenLength() { return TheLexer->getTokLength(); }
-std::string LLLgetFilename() { return TheLexer->getFilename(); }
-unsigned LLLgetLineNo() { return TheLexer->getLineNo(); }
-
-void FreeLexer() {
-  delete TheLexer;
-  TheLexer = 0;
+  APFloatVal = APFloat(std::atof(TokStart));
+  return lltok::APFloat;
 }