mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-25 04:39:51 +00:00
Reimplement the old and horrible bison parser for .ll files with a nice
and clean recursive descent parser. This change has a couple of ramifications: 1. The parser code is about 400 lines shorter (in what we maintain, not including what is autogenerated). 2. The code should be significantly faster than the old code because we don't have to work around bison's poor handling of datatypes with ctors/dtors. This also makes the code much more resistant to memory leaks. 3. We now get caret diagnostics from the .ll parser, woo. 4. The actual diagnostics emited from the parser are completely different so a bunch of testcases had to be updated. 5. I now disallow "%ty = type opaque %ty = type i32". There was no good reason to support this, it was just an accident of the old implementation. I have no reason to think that anyone is actually using this. 6. The syntax for sticking a global variable has changed to make it unambiguous. I don't think anyone is depending on this since only clang supports this and it is not solid yet, so I'm not worried about anything breaking. 7. This gets rid of the last use of bison, and along with it the .cvs files. I'll prune this from the makefiles as a subsequent commit. There are a few minor cleanups that can be done after this commit (suggestions welcome!) but this passes dejagnu testing and is ready for its time in the limelight. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61558 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ccb6976a69
commit
df98617b23
@ -20,6 +20,7 @@ namespace llvm {
|
||||
|
||||
class Module;
|
||||
class ParseError;
|
||||
class raw_ostream;
|
||||
|
||||
/// This function is the main interface to the LLVM Assembly Parser. It parses
|
||||
/// an ASCII file that (presumably) contains LLVM Assembly code. It returns a
|
||||
@ -29,7 +30,7 @@ class ParseError;
|
||||
/// @brief Parse LLVM Assembly from a file
|
||||
Module *ParseAssemblyFile(
|
||||
const std::string &Filename, ///< The name of the file to parse
|
||||
ParseError* Error = 0 ///< If not null, an object to return errors in.
|
||||
ParseError &Error ///< If not null, an object to return errors in.
|
||||
);
|
||||
|
||||
/// The function is a secondary interface to the LLVM Assembly Parser. It parses
|
||||
@ -39,9 +40,9 @@ Module *ParseAssemblyFile(
|
||||
/// run the verifier after parsing the file to check that it is okay.
|
||||
/// @brief Parse LLVM Assembly from a string
|
||||
Module *ParseAssemblyString(
|
||||
const char * AsmString, ///< The string containing assembly
|
||||
Module * M, ///< A module to add the assembly too.
|
||||
ParseError* Error = 0 ///< If not null, an object to return errors in.
|
||||
const char *AsmString, ///< The string containing assembly
|
||||
Module *M, ///< A module to add the assembly too.
|
||||
ParseError &Error ///< If not null, an object to return errors in.
|
||||
);
|
||||
|
||||
//===------------------------------------------------------------------------===
|
||||
@ -58,6 +59,8 @@ public:
|
||||
ParseError() : Filename("unknown"), Message("none"), LineNo(0), ColumnNo(0) {}
|
||||
ParseError(const ParseError &E);
|
||||
|
||||
void setFilename(const std::string &F) { Filename = F; }
|
||||
|
||||
// getMessage - Return the message passed in at construction time plus extra
|
||||
// information extracted from the options used to parse with...
|
||||
//
|
||||
@ -71,8 +74,12 @@ public:
|
||||
return Filename;
|
||||
}
|
||||
|
||||
void setError(const std::string &filename, const std::string &message,
|
||||
int LineNo = -1, int ColNo = -1);
|
||||
void setError(const std::string &message, int lineNo = -1, int ColNo = -1,
|
||||
const std::string &FileContents = "") {
|
||||
Message = message;
|
||||
LineNo = lineNo; ColumnNo = ColNo;
|
||||
LineContents = FileContents;
|
||||
}
|
||||
|
||||
// getErrorLocation - Return the line and column number of the error in the
|
||||
// input source file. The source filename can be derived from the
|
||||
@ -82,13 +89,16 @@ public:
|
||||
inline void getErrorLocation(int &Line, int &Column) const {
|
||||
Line = LineNo; Column = ColumnNo;
|
||||
}
|
||||
|
||||
void PrintError(const char *ProgName, raw_ostream &S);
|
||||
|
||||
private :
|
||||
std::string Filename;
|
||||
std::string Message;
|
||||
int LineNo, ColumnNo; // -1 if not relevant
|
||||
std::string LineContents;
|
||||
|
||||
ParseError &operator=(const ParseError &E); // objects by reference
|
||||
void operator=(const ParseError &E); // DO NOT IMPLEMENT
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -12,16 +12,36 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "LLLexer.h"
|
||||
#include "ParserInternals.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
|
||||
#include <list>
|
||||
#include "llvmAsmParser.h"
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Assembly/Parser.h"
|
||||
#include <cstring>
|
||||
using namespace llvm;
|
||||
|
||||
bool LLLexer::Error(LocTy ErrorLoc, const std::string &Msg) const {
|
||||
// Scan backward to find the start of the line.
|
||||
const char *LineStart = ErrorLoc;
|
||||
while (LineStart != CurBuf->getBufferStart() &&
|
||||
LineStart[-1] != '\n' && LineStart[-1] != '\r')
|
||||
--LineStart;
|
||||
// Get the end of the line.
|
||||
const char *LineEnd = ErrorLoc;
|
||||
while (LineEnd != CurBuf->getBufferEnd() &&
|
||||
LineEnd[0] != '\n' && LineEnd[0] != '\r')
|
||||
++LineEnd;
|
||||
|
||||
unsigned LineNo = 1;
|
||||
for (const char *FP = CurBuf->getBufferStart(); FP != ErrorLoc; ++FP)
|
||||
if (*FP == '\n') ++LineNo;
|
||||
|
||||
std::string LineContents(LineStart, LineEnd);
|
||||
ErrorInfo.setError(Msg, LineNo, ErrorLoc-LineStart, LineContents);
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Helper functions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -30,21 +50,21 @@ 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;
|
||||
@ -58,21 +78,15 @@ static uint64_t HexIntToVal(const char *Buffer, const char *End) {
|
||||
Result += C-'a'+10;
|
||||
|
||||
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);
|
||||
@ -97,7 +111,7 @@ static void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]){
|
||||
Pair[1] += C-'a'+10;
|
||||
}
|
||||
if (Buffer != End)
|
||||
GenerateError("constant bigger than 128 bits detected!");
|
||||
Error("constant bigger than 128 bits detected!");
|
||||
}
|
||||
|
||||
// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
|
||||
@ -149,11 +163,8 @@ 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, ParseError &Err)
|
||||
: CurBuf(StartBuf), ErrorInfo(Err), APFloatVal(0.0) {
|
||||
CurPtr = CurBuf->getBufferStart();
|
||||
}
|
||||
|
||||
@ -174,34 +185,22 @@ int LLLexer::getNextChar() {
|
||||
// Otherwise, return end of file.
|
||||
--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 == '_')
|
||||
return LexIdentifier();
|
||||
|
||||
return CurChar;
|
||||
case EOF: return YYEOF;
|
||||
return lltok::Error;
|
||||
case EOF: return lltok::Eof;
|
||||
case 0:
|
||||
case ' ':
|
||||
case '\t':
|
||||
@ -216,21 +215,21 @@ 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();
|
||||
@ -238,6 +237,18 @@ int LLLexer::LexToken() {
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,10 +260,10 @@ 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;
|
||||
@ -261,13 +272,13 @@ int LLLexer::LexAt() {
|
||||
int CurChar = getNextChar();
|
||||
|
||||
if (CurChar == EOF) {
|
||||
GenerateError("End of file in global variable name");
|
||||
return YYERROR;
|
||||
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);
|
||||
return lltok::GlobalVar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -280,8 +291,8 @@ int LLLexer::LexAt() {
|
||||
CurPtr[0] == '.' || CurPtr[0] == '_')
|
||||
++CurPtr;
|
||||
|
||||
llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr); // Skip @
|
||||
return GLOBALVAR;
|
||||
StrVal.assign(TokStart+1, CurPtr); // Skip @
|
||||
return lltok::GlobalVar;
|
||||
}
|
||||
|
||||
// Handle GlobalVarID: @[0-9]+
|
||||
@ -291,21 +302,21 @@ int LLLexer::LexAt() {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// 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: %\"[^\"]*\"
|
||||
/// LocalVar ::= %\"[^\"]*\"
|
||||
/// LocalVar ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]*
|
||||
/// LocalVarID ::= %[0-9]+
|
||||
lltok::Kind LLLexer::LexPercent() {
|
||||
// Handle LocalVarName: %\"[^\"]*\"
|
||||
if (CurPtr[0] == '"') {
|
||||
++CurPtr;
|
||||
|
||||
@ -313,13 +324,13 @@ int LLLexer::LexPercent() {
|
||||
int CurChar = getNextChar();
|
||||
|
||||
if (CurChar == EOF) {
|
||||
GenerateError("End of file in local variable name");
|
||||
return YYERROR;
|
||||
Error("end of file in string constant");
|
||||
return lltok::Error;
|
||||
}
|
||||
if (CurChar == '"') {
|
||||
llvmAsmlval.StrVal = new std::string(TokStart+2, CurPtr-1);
|
||||
UnEscapeLexed(*llvmAsmlval.StrVal);
|
||||
return PCTSTRINGCONSTANT;
|
||||
StrVal.assign(TokStart+2, CurPtr-1);
|
||||
UnEscapeLexed(StrVal);
|
||||
return lltok::LocalVar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -332,8 +343,8 @@ int LLLexer::LexPercent() {
|
||||
CurPtr[0] == '.' || CurPtr[0] == '_')
|
||||
++CurPtr;
|
||||
|
||||
llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr); // Skip %
|
||||
return LOCALVAR;
|
||||
StrVal.assign(TokStart+1, CurPtr); // Skip %
|
||||
return lltok::LocalVar;
|
||||
}
|
||||
|
||||
// Handle LocalVarID: %[0-9]+
|
||||
@ -343,38 +354,38 @@ int LLLexer::LexPercent() {
|
||||
|
||||
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() {
|
||||
lltok::Kind LLLexer::LexQuote() {
|
||||
while (1) {
|
||||
int CurChar = getNextChar();
|
||||
|
||||
if (CurChar == EOF) {
|
||||
GenerateError("End of file in quoted string");
|
||||
return YYERROR;
|
||||
Error("end of file in quoted string");
|
||||
return lltok::Error;
|
||||
}
|
||||
|
||||
if (CurChar != '"') continue;
|
||||
|
||||
if (CurPtr[0] != ':') {
|
||||
llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr-1);
|
||||
UnEscapeLexed(*llvmAsmlval.StrVal);
|
||||
return STRINGCONSTANT;
|
||||
StrVal.assign(TokStart+1, CurPtr-1);
|
||||
UnEscapeLexed(StrVal);
|
||||
return lltok::StringConstant;
|
||||
}
|
||||
|
||||
++CurPtr;
|
||||
llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr-2);
|
||||
UnEscapeLexed(*llvmAsmlval.StrVal);
|
||||
return LABELSTR;
|
||||
StrVal.assign(TokStart+1, CurPtr-2);
|
||||
UnEscapeLexed(StrVal);
|
||||
return lltok::LabelStr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,7 +406,7 @@ static bool JustWhitespaceNewLine(const char *&Ptr) {
|
||||
/// 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;
|
||||
@ -408,8 +419,8 @@ int LLLexer::LexIdentifier() {
|
||||
|
||||
// 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,
|
||||
@ -420,12 +431,11 @@ int LLLexer::LexIdentifier() {
|
||||
uint64_t NumBits = atoull(StartChar, CurPtr);
|
||||
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(NumBits);
|
||||
return lltok::Type;
|
||||
}
|
||||
|
||||
// Otherwise, this was a letter sequence. See which keyword this is.
|
||||
@ -433,112 +443,96 @@ int LLLexer::LexIdentifier() {
|
||||
CurPtr = KeywordEnd;
|
||||
--StartChar;
|
||||
unsigned Len = CurPtr-StartChar;
|
||||
#define KEYWORD(STR, TOK) \
|
||||
if (Len == strlen(STR) && !memcmp(StartChar, STR, strlen(STR))) return TOK;
|
||||
#define KEYWORD(STR) \
|
||||
if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) \
|
||||
return lltok::kw_##STR;
|
||||
|
||||
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(begin); KEYWORD(end);
|
||||
KEYWORD(true); KEYWORD(false);
|
||||
KEYWORD(declare); KEYWORD(define);
|
||||
KEYWORD(global); KEYWORD(constant);
|
||||
|
||||
KEYWORD("internal", INTERNAL);
|
||||
KEYWORD("linkonce", LINKONCE);
|
||||
KEYWORD("weak", WEAK);
|
||||
KEYWORD("appending", APPENDING);
|
||||
KEYWORD("dllimport", DLLIMPORT);
|
||||
KEYWORD("dllexport", DLLEXPORT);
|
||||
KEYWORD("common", COMMON);
|
||||
KEYWORD("default", DEFAULT);
|
||||
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("addrspace", ADDRSPACE);
|
||||
KEYWORD("section", SECTION);
|
||||
KEYWORD("alias", ALIAS);
|
||||
KEYWORD("module", MODULE);
|
||||
KEYWORD("asm", ASM_TOK);
|
||||
KEYWORD("sideeffect", SIDEEFFECT);
|
||||
KEYWORD("gc", GC);
|
||||
KEYWORD(internal);
|
||||
KEYWORD(linkonce);
|
||||
KEYWORD(weak);
|
||||
KEYWORD(appending);
|
||||
KEYWORD(dllimport);
|
||||
KEYWORD(dllexport);
|
||||
KEYWORD(common);
|
||||
KEYWORD(default);
|
||||
KEYWORD(hidden);
|
||||
KEYWORD(protected);
|
||||
KEYWORD(extern_weak);
|
||||
KEYWORD(external);
|
||||
KEYWORD(thread_local);
|
||||
KEYWORD(zeroinitializer);
|
||||
KEYWORD(undef);
|
||||
KEYWORD(null);
|
||||
KEYWORD(to);
|
||||
KEYWORD(tail);
|
||||
KEYWORD(target);
|
||||
KEYWORD(triple);
|
||||
KEYWORD(deplibs);
|
||||
KEYWORD(datalayout);
|
||||
KEYWORD(volatile);
|
||||
KEYWORD(align);
|
||||
KEYWORD(addrspace);
|
||||
KEYWORD(section);
|
||||
KEYWORD(alias);
|
||||
KEYWORD(module);
|
||||
KEYWORD(asm);
|
||||
KEYWORD(sideeffect);
|
||||
KEYWORD(gc);
|
||||
|
||||
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(ccc);
|
||||
KEYWORD(fastcc);
|
||||
KEYWORD(coldcc);
|
||||
KEYWORD(x86_stdcallcc);
|
||||
KEYWORD(x86_fastcallcc);
|
||||
KEYWORD(cc);
|
||||
KEYWORD(c);
|
||||
|
||||
KEYWORD("signext", SIGNEXT);
|
||||
KEYWORD("zeroext", ZEROEXT);
|
||||
KEYWORD("inreg", INREG);
|
||||
KEYWORD("sret", SRET);
|
||||
KEYWORD("nounwind", NOUNWIND);
|
||||
KEYWORD("noreturn", NORETURN);
|
||||
KEYWORD("noalias", NOALIAS);
|
||||
KEYWORD("nocapture", NOCAPTURE);
|
||||
KEYWORD("byval", BYVAL);
|
||||
KEYWORD("nest", NEST);
|
||||
KEYWORD("readnone", READNONE);
|
||||
KEYWORD("readonly", READONLY);
|
||||
KEYWORD(signext);
|
||||
KEYWORD(zeroext);
|
||||
KEYWORD(inreg);
|
||||
KEYWORD(sret);
|
||||
KEYWORD(nounwind);
|
||||
KEYWORD(noreturn);
|
||||
KEYWORD(noalias);
|
||||
KEYWORD(nocapture);
|
||||
KEYWORD(byval);
|
||||
KEYWORD(nest);
|
||||
KEYWORD(readnone);
|
||||
KEYWORD(readonly);
|
||||
|
||||
KEYWORD("noinline", NOINLINE);
|
||||
KEYWORD("alwaysinline", ALWAYSINLINE);
|
||||
KEYWORD("optsize", OPTSIZE);
|
||||
KEYWORD("ssp", SSP);
|
||||
KEYWORD("sspreq", SSPREQ);
|
||||
KEYWORD(noinline);
|
||||
KEYWORD(alwaysinline);
|
||||
KEYWORD(optsize);
|
||||
KEYWORD(ssp);
|
||||
KEYWORD(sspreq);
|
||||
|
||||
KEYWORD("type", TYPE);
|
||||
KEYWORD("opaque", OPAQUE);
|
||||
KEYWORD(type);
|
||||
KEYWORD(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);
|
||||
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(x);
|
||||
#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::VoidTy);
|
||||
TYPEKEYWORD("float", Type::FloatTy);
|
||||
TYPEKEYWORD("double", Type::DoubleTy);
|
||||
TYPEKEYWORD("x86_fp80", Type::X86_FP80Ty);
|
||||
TYPEKEYWORD("fp128", Type::FP128Ty);
|
||||
TYPEKEYWORD("ppc_fp128", Type::PPC_FP128Ty);
|
||||
TYPEKEYWORD("label", Type::LabelTy);
|
||||
#undef TYPEKEYWORD
|
||||
|
||||
// Handle special forms for autoupgrading. Drop these in LLVM 3.0. This is
|
||||
@ -546,74 +540,62 @@ int LLLexer::LexIdentifier() {
|
||||
if (Len == 4 && !memcmp(StartChar, "sext", 4)) {
|
||||
// Scan CurPtr ahead, seeing if there is just whitespace before the newline.
|
||||
if (JustWhitespaceNewLine(CurPtr))
|
||||
return SIGNEXT;
|
||||
return lltok::kw_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;
|
||||
return lltok::kw_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; }
|
||||
#define INSTKEYWORD(STR, Enum) \
|
||||
if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) { \
|
||||
UIntVal = Instruction::Enum; return lltok::kw_##STR; }
|
||||
|
||||
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("vicmp", OtherOpVal, VICmp, VICMP);
|
||||
INSTKEYWORD("vfcmp", OtherOpVal, VFCmp, VFCMP);
|
||||
INSTKEYWORD(add, Add); INSTKEYWORD(sub, Sub); INSTKEYWORD(mul, Mul);
|
||||
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(vicmp, VICmp); INSTKEYWORD(vfcmp, VFCmp);
|
||||
|
||||
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(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(select, Select);
|
||||
INSTKEYWORD(va_arg, VAArg);
|
||||
INSTKEYWORD(ret, Ret);
|
||||
INSTKEYWORD(br, Br);
|
||||
INSTKEYWORD(switch, Switch);
|
||||
INSTKEYWORD(invoke, Invoke);
|
||||
INSTKEYWORD(unwind, Unwind);
|
||||
INSTKEYWORD(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(malloc, Malloc);
|
||||
INSTKEYWORD(alloca, Alloca);
|
||||
INSTKEYWORD(free, Free);
|
||||
INSTKEYWORD(load, Load);
|
||||
INSTKEYWORD(store, Store);
|
||||
INSTKEYWORD(getelementptr, GetElementPtr);
|
||||
|
||||
INSTKEYWORD("extractelement", OtherOpVal, ExtractElement, EXTRACTELEMENT);
|
||||
INSTKEYWORD("insertelement", OtherOpVal, InsertElement, INSERTELEMENT);
|
||||
INSTKEYWORD("shufflevector", OtherOpVal, ShuffleVector, SHUFFLEVECTOR);
|
||||
INSTKEYWORD("getresult", OtherOpVal, ExtractValue, GETRESULT);
|
||||
INSTKEYWORD("extractvalue", OtherOpVal, ExtractValue, EXTRACTVALUE);
|
||||
INSTKEYWORD("insertvalue", OtherOpVal, InsertValue, INSERTVALUE);
|
||||
INSTKEYWORD(extractelement, ExtractElement);
|
||||
INSTKEYWORD(insertelement, InsertElement);
|
||||
INSTKEYWORD(shufflevector, ShuffleVector);
|
||||
INSTKEYWORD(getresult, ExtractValue);
|
||||
INSTKEYWORD(extractvalue, ExtractValue);
|
||||
INSTKEYWORD(insertvalue, InsertValue);
|
||||
#undef INSTKEYWORD
|
||||
|
||||
// Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
|
||||
@ -626,35 +608,27 @@ int LLLexer::LexIdentifier() {
|
||||
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;
|
||||
}
|
||||
APSIntVal = APSInt(Tmp, TokStart[0] == 'u');
|
||||
return lltok::APSInt;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// If this starts with "call", return it as CALL. This is to support old
|
||||
// broken .ll files. FIXME: remove this with LLVM 3.0.
|
||||
if (CurPtr-TokStart > 4 && !memcmp(TokStart, "call", 4)) {
|
||||
CurPtr = TokStart+4;
|
||||
llvmAsmlval.OtherOpVal = Instruction::Call;
|
||||
return CALL;
|
||||
UIntVal = Instruction::Call;
|
||||
return lltok::kw_call;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
@ -664,7 +638,7 @@ int LLLexer::LexIdentifier() {
|
||||
/// HexFP80Constant 0xK[0-9A-Fa-f]+
|
||||
/// HexFP128Constant 0xL[0-9A-Fa-f]+
|
||||
/// HexPPC128Constant 0xM[0-9A-Fa-f]+
|
||||
int LLLexer::Lex0x() {
|
||||
lltok::Kind LLLexer::Lex0x() {
|
||||
CurPtr = TokStart + 2;
|
||||
|
||||
char Kind;
|
||||
@ -675,9 +649,9 @@ int LLLexer::Lex0x() {
|
||||
}
|
||||
|
||||
if (!isxdigit(CurPtr[0])) {
|
||||
// Bad token, return it as just zero.
|
||||
// Bad token, return it as an error.
|
||||
CurPtr = TokStart+1;
|
||||
return '0';
|
||||
return lltok::Error;
|
||||
}
|
||||
|
||||
while (isxdigit(CurPtr[0]))
|
||||
@ -687,8 +661,8 @@ int LLLexer::Lex0x() {
|
||||
// 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;
|
||||
APFloatVal = APFloat(BitsToDouble(HexIntToVal(TokStart+2, CurPtr)));
|
||||
return lltok::APFloat;
|
||||
}
|
||||
|
||||
uint64_t Pair[2];
|
||||
@ -697,16 +671,16 @@ int LLLexer::Lex0x() {
|
||||
default: assert(0 && "Unknown kind!");
|
||||
case 'K':
|
||||
// F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
|
||||
llvmAsmlval.FPVal = new APFloat(APInt(80, 2, Pair));
|
||||
return FPVAL;
|
||||
APFloatVal = APFloat(APInt(80, 2, 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;
|
||||
APFloatVal = APFloat(APInt(128, 2, Pair), true);
|
||||
return lltok::APFloat;
|
||||
case 'M':
|
||||
// PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
|
||||
llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair));
|
||||
return FPVAL;
|
||||
APFloatVal = APFloat(APInt(128, 2, Pair));
|
||||
return lltok::APFloat;
|
||||
}
|
||||
}
|
||||
|
||||
@ -719,17 +693,17 @@ int LLLexer::Lex0x() {
|
||||
/// HexFP80Constant 0xK[0-9A-Fa-f]+
|
||||
/// HexFP128Constant 0xL[0-9A-Fa-f]+
|
||||
/// HexPPC128Constant 0xM[0-9A-Fa-f]+
|
||||
int LLLexer::LexDigitOrNegative() {
|
||||
lltok::Kind LLLexer::LexDigitOrNegative() {
|
||||
// If the letter after the negative is a number, this is probably a label.
|
||||
if (!isdigit(TokStart[0]) && !isdigit(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.
|
||||
@ -741,9 +715,9 @@ int LLLexer::LexDigitOrNegative() {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -759,25 +733,14 @@ int LLLexer::LexDigitOrNegative() {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
APSIntVal = APSInt(Tmp, true);
|
||||
}
|
||||
return lltok::APSInt;
|
||||
}
|
||||
|
||||
++CurPtr;
|
||||
@ -793,16 +756,16 @@ int LLLexer::LexDigitOrNegative() {
|
||||
}
|
||||
}
|
||||
|
||||
llvmAsmlval.FPVal = new APFloat(atof(TokStart));
|
||||
return FPVAL;
|
||||
APFloatVal = APFloat(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];
|
||||
return lltok::Error;
|
||||
|
||||
// Skip digits.
|
||||
for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr)
|
||||
@ -811,7 +774,7 @@ int LLLexer::LexPositive() {
|
||||
// At this point, we need a '.'.
|
||||
if (CurPtr[0] != '.') {
|
||||
CurPtr = TokStart+1;
|
||||
return TokStart[0];
|
||||
return lltok::Error;
|
||||
}
|
||||
|
||||
++CurPtr;
|
||||
@ -827,31 +790,6 @@ int LLLexer::LexPositive() {
|
||||
}
|
||||
}
|
||||
|
||||
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(atof(TokStart));
|
||||
return lltok::APFloat;
|
||||
}
|
||||
|
@ -14,43 +14,72 @@
|
||||
#ifndef LIB_ASMPARSER_LLLEXER_H
|
||||
#define LIB_ASMPARSER_LLLEXER_H
|
||||
|
||||
#include "LLToken.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
class Type;
|
||||
class ParseError;
|
||||
|
||||
class LLLexer {
|
||||
const char *CurPtr;
|
||||
unsigned CurLineNo;
|
||||
MemoryBuffer *CurBuf;
|
||||
|
||||
ParseError &ErrorInfo;
|
||||
|
||||
// Information about the current token.
|
||||
const char *TokStart;
|
||||
lltok::Kind CurKind;
|
||||
std::string StrVal;
|
||||
unsigned UIntVal;
|
||||
const Type *TyVal;
|
||||
APFloat APFloatVal;
|
||||
APSInt APSIntVal;
|
||||
|
||||
std::string TheError;
|
||||
public:
|
||||
explicit LLLexer(MemoryBuffer *StartBuf);
|
||||
explicit LLLexer(MemoryBuffer *StartBuf, ParseError &);
|
||||
~LLLexer() {}
|
||||
|
||||
const char *getTokStart() const { return TokStart; }
|
||||
unsigned getTokLength() const { return CurPtr-TokStart; }
|
||||
unsigned getLineNo() const { return CurLineNo; }
|
||||
lltok::Kind Lex() {
|
||||
return CurKind = LexToken();
|
||||
}
|
||||
|
||||
typedef const char* LocTy;
|
||||
LocTy getLoc() const { return TokStart; }
|
||||
lltok::Kind getKind() const { return CurKind; }
|
||||
const std::string getStrVal() const { return StrVal; }
|
||||
const Type *getTyVal() const { return TyVal; }
|
||||
unsigned getUIntVal() const { return UIntVal; }
|
||||
const APSInt &getAPSIntVal() const { return APSIntVal; }
|
||||
const APFloat &getAPFloatVal() const { return APFloatVal; }
|
||||
|
||||
|
||||
bool Error(LocTy L, const std::string &Msg) const;
|
||||
bool Error(const std::string &Msg) const { return Error(CurPtr, Msg); }
|
||||
std::string getFilename() const;
|
||||
int LexToken();
|
||||
|
||||
const std::string getError() const { return TheError; }
|
||||
|
||||
|
||||
private:
|
||||
lltok::Kind LexToken();
|
||||
|
||||
int getNextChar();
|
||||
void SkipLineComment();
|
||||
int LexIdentifier();
|
||||
int LexDigitOrNegative();
|
||||
int LexPositive();
|
||||
int LexAt();
|
||||
int LexPercent();
|
||||
int LexQuote();
|
||||
int Lex0x();
|
||||
lltok::Kind LexIdentifier();
|
||||
lltok::Kind LexDigitOrNegative();
|
||||
lltok::Kind LexPositive();
|
||||
lltok::Kind LexAt();
|
||||
lltok::Kind LexPercent();
|
||||
lltok::Kind LexQuote();
|
||||
lltok::Kind Lex0x();
|
||||
|
||||
uint64_t atoull(const char *Buffer, const char *End);
|
||||
uint64_t HexIntToVal(const char *Buffer, const char *End);
|
||||
void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]);
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
|
3158
lib/AsmParser/LLParser.cpp
Normal file
3158
lib/AsmParser/LLParser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
266
lib/AsmParser/LLParser.h
Normal file
266
lib/AsmParser/LLParser.h
Normal file
@ -0,0 +1,266 @@
|
||||
//===-- LLParser.h - Parser Class -------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the parser class for .ll files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ASMPARSER_LLPARSER_H
|
||||
#define LLVM_ASMPARSER_LLPARSER_H
|
||||
|
||||
#include "LLLexer.h"
|
||||
#include "llvm/Type.h"
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
class OpaqueType;
|
||||
class Function;
|
||||
class Value;
|
||||
class BasicBlock;
|
||||
class Instruction;
|
||||
class Constant;
|
||||
class GlobalValue;
|
||||
struct ValID;
|
||||
|
||||
class LLParser {
|
||||
public:
|
||||
typedef LLLexer::LocTy LocTy;
|
||||
private:
|
||||
|
||||
LLLexer Lex;
|
||||
Module *M;
|
||||
|
||||
// Type resolution handling data structures.
|
||||
std::map<std::string, std::pair<PATypeHolder, LocTy> > ForwardRefTypes;
|
||||
std::map<unsigned, std::pair<PATypeHolder, LocTy> > ForwardRefTypeIDs;
|
||||
std::vector<PATypeHolder> NumberedTypes;
|
||||
|
||||
struct UpRefRecord {
|
||||
/// Loc - This is the location of the upref.
|
||||
LocTy Loc;
|
||||
|
||||
/// NestingLevel - The number of nesting levels that need to be popped
|
||||
/// before this type is resolved.
|
||||
unsigned NestingLevel;
|
||||
|
||||
/// LastContainedTy - This is the type at the current binding level for
|
||||
/// the type. Every time we reduce the nesting level, this gets updated.
|
||||
const Type *LastContainedTy;
|
||||
|
||||
/// UpRefTy - This is the actual opaque type that the upreference is
|
||||
/// represented with.
|
||||
OpaqueType *UpRefTy;
|
||||
|
||||
UpRefRecord(LocTy L, unsigned NL, OpaqueType *URTy)
|
||||
: Loc(L), NestingLevel(NL), LastContainedTy((Type*)URTy),
|
||||
UpRefTy(URTy) {}
|
||||
};
|
||||
std::vector<UpRefRecord> UpRefs;
|
||||
|
||||
// Global Value reference information.
|
||||
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;
|
||||
std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs;
|
||||
std::vector<GlobalValue*> NumberedVals;
|
||||
public:
|
||||
LLParser(MemoryBuffer *F, ParseError &Err) : Lex(F, Err), M(0) {}
|
||||
Module *Run();
|
||||
|
||||
private:
|
||||
|
||||
bool Error(LocTy L, const std::string &Msg) const {
|
||||
return Lex.Error(L, Msg);
|
||||
}
|
||||
bool TokError(const std::string &Msg) const {
|
||||
return Error(Lex.getLoc(), Msg);
|
||||
}
|
||||
|
||||
/// GetGlobalVal - Get a value with the specified name or ID, creating a
|
||||
/// forward reference record if needed. This can return null if the value
|
||||
/// exists but does not have the right type.
|
||||
GlobalValue *GetGlobalVal(const std::string &N, const Type *Ty, LocTy Loc);
|
||||
GlobalValue *GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc);
|
||||
|
||||
// Helper Routines.
|
||||
bool ParseToken(lltok::Kind T, const char *ErrMsg);
|
||||
bool ParseOptionalToken(lltok::Kind T, bool &Present) {
|
||||
if (Lex.getKind() != T) {
|
||||
Present = false;
|
||||
} else {
|
||||
Lex.Lex();
|
||||
Present = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ParseUnsigned(unsigned &Val);
|
||||
bool ParseUnsigned(unsigned &Val, LocTy &Loc) {
|
||||
Loc = Lex.getLoc();
|
||||
return ParseUnsigned(Val);
|
||||
}
|
||||
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
|
||||
bool ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind);
|
||||
bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage);
|
||||
bool ParseOptionalLinkage(unsigned &Linkage) {
|
||||
bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);
|
||||
}
|
||||
bool ParseOptionalVisibility(unsigned &Visibility);
|
||||
bool ParseOptionalCallingConv(unsigned &CC);
|
||||
bool ParseOptionalAlignment(unsigned &Alignment);
|
||||
bool ParseOptionalCommaAlignment(unsigned &Alignment);
|
||||
bool ParseIndexList(SmallVectorImpl<unsigned> &Indices);
|
||||
|
||||
// Top-Level Entities
|
||||
bool ParseTopLevelEntities();
|
||||
bool ValidateEndOfModule();
|
||||
bool ParseTargetDefinition();
|
||||
bool ParseDepLibs();
|
||||
bool ParseModuleAsm();
|
||||
bool ParseUnnamedType();
|
||||
bool ParseNamedType();
|
||||
bool ParseDeclare();
|
||||
bool ParseDefine();
|
||||
|
||||
bool ParseGlobalType(bool &IsConstant);
|
||||
bool ParseNamedGlobal();
|
||||
bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
|
||||
bool HasLinkage, unsigned Visibility);
|
||||
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility);
|
||||
|
||||
// Type Parsing.
|
||||
bool ParseType(PATypeHolder &Result);
|
||||
bool ParseType(PATypeHolder &Result, LocTy &Loc) {
|
||||
Loc = Lex.getLoc();
|
||||
return ParseType(Result);
|
||||
}
|
||||
bool ParseTypeRec(PATypeHolder &H);
|
||||
bool ParseStructType(PATypeHolder &H, bool Packed);
|
||||
bool ParseArrayVectorType(PATypeHolder &H, bool isVector);
|
||||
bool ParseFunctionType(PATypeHolder &Result);
|
||||
PATypeHolder HandleUpRefs(const Type *Ty);
|
||||
|
||||
// Constants.
|
||||
bool ParseValID(ValID &ID);
|
||||
bool ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, Constant *&V);
|
||||
bool ParseGlobalValue(const Type *Ty, Constant *&V);
|
||||
bool ParseGlobalTypeAndValue(Constant *&V);
|
||||
bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
|
||||
|
||||
|
||||
// Function Semantic Analysis.
|
||||
class PerFunctionState {
|
||||
LLParser &P;
|
||||
Function &F;
|
||||
std::map<std::string, std::pair<Value*, LocTy> > ForwardRefVals;
|
||||
std::map<unsigned, std::pair<Value*, LocTy> > ForwardRefValIDs;
|
||||
std::vector<Value*> NumberedVals;
|
||||
public:
|
||||
PerFunctionState(LLParser &p, Function &f);
|
||||
~PerFunctionState();
|
||||
|
||||
Function &getFunction() const { return F; }
|
||||
|
||||
bool VerifyFunctionComplete();
|
||||
|
||||
/// GetVal - Get a value with the specified name or ID, creating a
|
||||
/// forward reference record if needed. This can return null if the value
|
||||
/// exists but does not have the right type.
|
||||
Value *GetVal(const std::string &Name, const Type *Ty, LocTy Loc);
|
||||
Value *GetVal(unsigned ID, const Type *Ty, LocTy Loc);
|
||||
|
||||
/// SetInstName - After an instruction is parsed and inserted into its
|
||||
/// basic block, this installs its name.
|
||||
bool SetInstName(int NameID, const std::string &NameStr, LocTy NameLoc,
|
||||
Instruction *Inst);
|
||||
|
||||
/// GetBB - Get a basic block with the specified name or ID, creating a
|
||||
/// forward reference record if needed. This can return null if the value
|
||||
/// is not a BasicBlock.
|
||||
BasicBlock *GetBB(const std::string &Name, LocTy Loc);
|
||||
BasicBlock *GetBB(unsigned ID, LocTy Loc);
|
||||
|
||||
/// DefineBB - Define the specified basic block, which is either named or
|
||||
/// unnamed. If there is an error, this returns null otherwise it returns
|
||||
/// the block being defined.
|
||||
BasicBlock *DefineBB(const std::string &Name, LocTy Loc);
|
||||
};
|
||||
|
||||
bool ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
|
||||
PerFunctionState &PFS);
|
||||
|
||||
bool ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS);
|
||||
bool ParseValue(const Type *Ty, Value *&V, LocTy &Loc,
|
||||
PerFunctionState &PFS) {
|
||||
Loc = Lex.getLoc();
|
||||
return ParseValue(Ty, V, PFS);
|
||||
}
|
||||
|
||||
bool ParseTypeAndValue(Value *&V, PerFunctionState &PFS);
|
||||
bool ParseTypeAndValue(Value *&V, LocTy &Loc, PerFunctionState &PFS) {
|
||||
Loc = Lex.getLoc();
|
||||
return ParseTypeAndValue(V, PFS);
|
||||
}
|
||||
|
||||
struct ParamInfo {
|
||||
LocTy Loc;
|
||||
Value *V;
|
||||
unsigned Attrs;
|
||||
ParamInfo(LocTy loc, Value *v, unsigned attrs)
|
||||
: Loc(loc), V(v), Attrs(attrs) {}
|
||||
};
|
||||
bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
|
||||
PerFunctionState &PFS);
|
||||
|
||||
// Function Parsing.
|
||||
struct ArgInfo {
|
||||
LocTy Loc;
|
||||
PATypeHolder Type;
|
||||
unsigned Attrs;
|
||||
std::string Name;
|
||||
ArgInfo(LocTy L, PATypeHolder Ty, unsigned Attr, const std::string &N)
|
||||
: Loc(L), Type(Ty), Attrs(Attr), Name(N) {}
|
||||
};
|
||||
bool ParseArgumentList(std::vector<ArgInfo> &ArgList,
|
||||
bool &isVarArg);
|
||||
bool ParseFunctionHeader(Function *&Fn, bool isDefine);
|
||||
bool ParseFunctionBody(Function &Fn);
|
||||
bool ParseBasicBlock(PerFunctionState &PFS);
|
||||
|
||||
// Instruction Parsing.
|
||||
bool ParseInstruction(Instruction *&Inst, BasicBlock *BB,
|
||||
PerFunctionState &PFS);
|
||||
bool ParseCmpPredicate(unsigned &Pred, unsigned Opc);
|
||||
|
||||
bool ParseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS);
|
||||
bool ParseBr(Instruction *&Inst, PerFunctionState &PFS);
|
||||
bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS);
|
||||
bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS);
|
||||
|
||||
bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc);
|
||||
bool ParseLogical(Instruction *&I, PerFunctionState &PFS, unsigned Opc);
|
||||
bool ParseCompare(Instruction *&I, PerFunctionState &PFS, unsigned Opc);
|
||||
bool ParseCast(Instruction *&I, PerFunctionState &PFS, unsigned Opc);
|
||||
bool ParseSelect(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseVAArg(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseExtractElement(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseInsertElement(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParsePHI(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseCall(Instruction *&I, PerFunctionState &PFS, bool isTail);
|
||||
bool ParseAlloc(Instruction *&I, PerFunctionState &PFS, unsigned Opc);
|
||||
bool ParseFree(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseLoad(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
|
||||
bool ParseStore(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
|
||||
bool ParseGetResult(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseGetElementPtr(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseExtractValue(Instruction *&I, PerFunctionState &PFS);
|
||||
bool ParseInsertValue(Instruction *&I, PerFunctionState &PFS);
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
126
lib/AsmParser/LLToken.h
Normal file
126
lib/AsmParser/LLToken.h
Normal file
@ -0,0 +1,126 @@
|
||||
//===- LLToken.h - Token Codes for LLVM Assembly Files ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the enums for the .ll lexer.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LIBS_ASMPARSER_LLTOKEN_H
|
||||
#define LIBS_ASMPARSER_LLTOKEN_H
|
||||
|
||||
namespace llvm {
|
||||
namespace lltok {
|
||||
enum Kind {
|
||||
// Markers
|
||||
Eof, Error,
|
||||
|
||||
// Tokens with no info.
|
||||
dotdotdot, // ...
|
||||
equal, comma, // = ,
|
||||
star, // *
|
||||
lsquare, rsquare, // [ ]
|
||||
lbrace, rbrace, // { }
|
||||
less, greater, // < >
|
||||
lparen, rparen, // ( )
|
||||
backslash, // \ /
|
||||
|
||||
kw_x,
|
||||
kw_begin, kw_end,
|
||||
kw_true, kw_false,
|
||||
kw_declare, kw_define,
|
||||
kw_global, kw_constant,
|
||||
|
||||
kw_internal, kw_linkonce, kw_weak, kw_appending, kw_dllimport,
|
||||
kw_dllexport, kw_common, kw_default, kw_hidden, kw_protected,
|
||||
kw_extern_weak,
|
||||
kw_external, kw_thread_local,
|
||||
kw_zeroinitializer,
|
||||
kw_undef, kw_null,
|
||||
kw_to,
|
||||
kw_tail,
|
||||
kw_target,
|
||||
kw_triple,
|
||||
kw_deplibs,
|
||||
kw_datalayout,
|
||||
kw_volatile,
|
||||
kw_align,
|
||||
kw_addrspace,
|
||||
kw_section,
|
||||
kw_alias,
|
||||
kw_module,
|
||||
kw_asm,
|
||||
kw_sideeffect,
|
||||
kw_gc,
|
||||
kw_c,
|
||||
|
||||
kw_cc, kw_ccc, kw_fastcc, kw_coldcc, kw_x86_stdcallcc, kw_x86_fastcallcc,
|
||||
|
||||
kw_signext,
|
||||
kw_zeroext,
|
||||
kw_inreg,
|
||||
kw_sret,
|
||||
kw_nounwind,
|
||||
kw_noreturn,
|
||||
kw_noalias,
|
||||
kw_nocapture,
|
||||
kw_byval,
|
||||
kw_nest,
|
||||
kw_readnone,
|
||||
kw_readonly,
|
||||
|
||||
kw_noinline,
|
||||
kw_alwaysinline,
|
||||
kw_optsize,
|
||||
kw_ssp,
|
||||
kw_sspreq,
|
||||
|
||||
kw_type,
|
||||
kw_opaque,
|
||||
|
||||
kw_eq, kw_ne, kw_slt, kw_sgt, kw_sle, kw_sge, kw_ult, kw_ugt, kw_ule,
|
||||
kw_uge, kw_oeq, kw_one, kw_olt, kw_ogt, kw_ole, kw_oge, kw_ord, kw_uno,
|
||||
kw_ueq, kw_une,
|
||||
|
||||
// Instruction Opcodes (Opcode in UIntVal).
|
||||
kw_add, kw_sub, kw_mul, kw_udiv, kw_sdiv, kw_fdiv,
|
||||
kw_urem, kw_srem, kw_frem, kw_shl, kw_lshr, kw_ashr,
|
||||
kw_and, kw_or, kw_xor, kw_icmp, kw_fcmp, kw_vicmp, kw_vfcmp,
|
||||
|
||||
kw_phi, kw_call,
|
||||
kw_trunc, kw_zext, kw_sext, kw_fptrunc, kw_fpext, kw_uitofp, kw_sitofp,
|
||||
kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast,
|
||||
kw_select, kw_va_arg,
|
||||
|
||||
kw_ret, kw_br, kw_switch, kw_invoke, kw_unwind, kw_unreachable,
|
||||
|
||||
kw_malloc, kw_alloca, kw_free, kw_load, kw_store, kw_getelementptr,
|
||||
|
||||
kw_extractelement, kw_insertelement, kw_shufflevector, kw_getresult,
|
||||
kw_extractvalue, kw_insertvalue,
|
||||
|
||||
// Unsigned Valued tokens (UIntVal).
|
||||
GlobalID, // @42
|
||||
LocalVarID, // %42
|
||||
|
||||
// String valued tokens (StrVal).
|
||||
LabelStr, // foo:
|
||||
GlobalVar, // @foo @"foo"
|
||||
LocalVar, // %foo %"foo"
|
||||
StringConstant, // "foo"
|
||||
|
||||
// Type valued tokens (TyVal).
|
||||
Type,
|
||||
|
||||
APFloat, // APFloatVal
|
||||
APSInt, // APSInt
|
||||
};
|
||||
} // end namespace lltok
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
//===- Parser.cpp - Main dispatch module for the Parser library -------------===
|
||||
//===- Parser.cpp - Main dispatch module for the Parser library -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -9,39 +9,40 @@
|
||||
//
|
||||
// This library implements the functionality defined in llvm/assembly/parser.h
|
||||
//
|
||||
//===------------------------------------------------------------------------===
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ParserInternals.h"
|
||||
#include "llvm/Assembly/Parser.h"
|
||||
#include "LLParser.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstring>
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
ParseError* TheParseError = 0; /// FIXME: Not threading friendly
|
||||
|
||||
Module *llvm::ParseAssemblyFile(const std::string &Filename, ParseError* Err) {
|
||||
Module *llvm::ParseAssemblyFile(const std::string &Filename, ParseError &Err) {
|
||||
Err.setFilename(Filename);
|
||||
|
||||
std::string ErrorStr;
|
||||
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr);
|
||||
if (F == 0) {
|
||||
if (Err)
|
||||
Err->setError(Filename, "Could not open input file '" + Filename + "'");
|
||||
Err.setError("Could not open input file '" + Filename + "'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TheParseError = Err;
|
||||
Module *Result = RunVMAsmParser(F);
|
||||
Module *Result = LLParser(F, Err).Run();
|
||||
delete F;
|
||||
return Result;
|
||||
}
|
||||
|
||||
// FIXME: M is ignored??
|
||||
Module *llvm::ParseAssemblyString(const char *AsmString, Module *M,
|
||||
ParseError *Err) {
|
||||
TheParseError = Err;
|
||||
ParseError &Err) {
|
||||
Err.setFilename("<string>");
|
||||
|
||||
MemoryBuffer *F = MemoryBuffer::getMemBuffer(AsmString,
|
||||
AsmString+strlen(AsmString),
|
||||
"<string>");
|
||||
Module *Result = RunVMAsmParser(F);
|
||||
Module *Result = LLParser(F, Err).Run();
|
||||
delete F;
|
||||
return Result;
|
||||
}
|
||||
@ -51,40 +52,28 @@ Module *llvm::ParseAssemblyString(const char *AsmString, Module *M,
|
||||
// ParseError Class
|
||||
//===------------------------------------------------------------------------===
|
||||
|
||||
|
||||
void ParseError::setError(const std::string &filename,
|
||||
const std::string &message,
|
||||
int lineNo, int colNo) {
|
||||
Filename = filename;
|
||||
Message = message;
|
||||
LineNo = lineNo;
|
||||
colNo = colNo;
|
||||
}
|
||||
|
||||
ParseError::ParseError(const ParseError &E)
|
||||
: Filename(E.Filename), Message(E.Message) {
|
||||
LineNo = E.LineNo;
|
||||
ColumnNo = E.ColumnNo;
|
||||
}
|
||||
|
||||
// Includes info from options
|
||||
const std::string ParseError::getMessage() const {
|
||||
std::string Result;
|
||||
char Buffer[10];
|
||||
|
||||
void ParseError::PrintError(const char *ProgName, raw_ostream &S) {
|
||||
errs() << ProgName << ": ";
|
||||
if (Filename == "-")
|
||||
Result += "<stdin>";
|
||||
errs() << "<stdin>";
|
||||
else
|
||||
Result += Filename;
|
||||
|
||||
errs() << Filename;
|
||||
|
||||
if (LineNo != -1) {
|
||||
sprintf(Buffer, "%d", LineNo);
|
||||
Result += std::string(":") + Buffer;
|
||||
if (ColumnNo != -1) {
|
||||
sprintf(Buffer, "%d", ColumnNo);
|
||||
Result += std::string(",") + Buffer;
|
||||
}
|
||||
errs() << ':' << LineNo;
|
||||
if (ColumnNo != -1)
|
||||
errs() << ':' << (ColumnNo+1);
|
||||
}
|
||||
|
||||
errs() << ": " << Message << '\n';
|
||||
|
||||
if (LineNo != -1 && ColumnNo != -1) {
|
||||
errs() << LineContents << '\n';
|
||||
|
||||
// Print out spaces/tabs before the caret.
|
||||
for (unsigned i = 0; i != unsigned(ColumnNo); ++i)
|
||||
errs() << (LineContents[i] == '\t' ? '\t' : ' ');
|
||||
errs() << "^\n";
|
||||
}
|
||||
|
||||
return Result + ": " + Message;
|
||||
}
|
||||
|
||||
|
@ -1,260 +0,0 @@
|
||||
//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This header file defines the various variables that are shared among the
|
||||
// different components of the parser...
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef PARSER_INTERNALS_H
|
||||
#define PARSER_INTERNALS_H
|
||||
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Attributes.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Assembly/Parser.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
namespace llvm { class MemoryBuffer; }
|
||||
|
||||
// Global variables exported from the lexer...
|
||||
|
||||
extern llvm::ParseError* TheParseError; /// FIXME: Not threading friendly
|
||||
|
||||
// functions exported from the lexer
|
||||
void InitLLLexer(llvm::MemoryBuffer *MB);
|
||||
const char *LLLgetTokenStart();
|
||||
unsigned LLLgetTokenLength();
|
||||
std::string LLLgetFilename();
|
||||
unsigned LLLgetLineNo();
|
||||
void FreeLexer();
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
|
||||
// RunVMAsmParser - Parse a buffer and return Module
|
||||
Module *RunVMAsmParser(llvm::MemoryBuffer *MB);
|
||||
|
||||
// GenerateError - Wrapper around the ParseException class that automatically
|
||||
// fills in file line number and column number and options info.
|
||||
//
|
||||
// This also helps me because I keep typing 'throw new ParseException' instead
|
||||
// of just 'throw ParseException'... sigh...
|
||||
//
|
||||
extern void GenerateError(const std::string &message, int LineNo = -1);
|
||||
|
||||
/// InlineAsmDescriptor - This is a simple class that holds info about inline
|
||||
/// asm blocks, for use by ValID.
|
||||
struct InlineAsmDescriptor {
|
||||
std::string AsmString, Constraints;
|
||||
bool HasSideEffects;
|
||||
|
||||
InlineAsmDescriptor(const std::string &as, const std::string &c, bool HSE)
|
||||
: AsmString(as), Constraints(c), HasSideEffects(HSE) {}
|
||||
};
|
||||
|
||||
|
||||
// ValID - Represents a reference of a definition of some sort. This may either
|
||||
// be a numeric reference or a symbolic (%var) reference. This is just a
|
||||
// discriminated union.
|
||||
//
|
||||
// Note that I can't implement this class in a straight forward manner with
|
||||
// constructors and stuff because it goes in a union.
|
||||
//
|
||||
struct ValID {
|
||||
enum {
|
||||
LocalID, GlobalID, LocalName, GlobalName,
|
||||
ConstSIntVal, ConstUIntVal, ConstAPInt, ConstFPVal, ConstNullVal,
|
||||
ConstUndefVal, ConstZeroVal, ConstantVal, InlineAsmVal
|
||||
} Type;
|
||||
|
||||
union {
|
||||
unsigned Num; // If it's a numeric reference like %1234
|
||||
std::string *Name; // If it's a named reference. Memory must be deleted.
|
||||
int64_t ConstPool64; // Constant pool reference. This is the value
|
||||
uint64_t UConstPool64; // Unsigned constant pool reference.
|
||||
APSInt *ConstPoolInt; // Large Integer constant pool reference
|
||||
APFloat *ConstPoolFP; // Floating point constant pool reference
|
||||
Constant *ConstantValue; // Fully resolved constant for ConstantVal case.
|
||||
InlineAsmDescriptor *IAD;
|
||||
};
|
||||
|
||||
static ValID createLocalID(unsigned Num) {
|
||||
ValID D; D.Type = LocalID; D.Num = Num; return D;
|
||||
}
|
||||
static ValID createGlobalID(unsigned Num) {
|
||||
ValID D; D.Type = GlobalID; D.Num = Num; return D;
|
||||
}
|
||||
static ValID createLocalName(const std::string &Name) {
|
||||
ValID D; D.Type = LocalName; D.Name = new std::string(Name); return D;
|
||||
}
|
||||
static ValID createGlobalName(const std::string &Name) {
|
||||
ValID D; D.Type = GlobalName; D.Name = new std::string(Name); return D;
|
||||
}
|
||||
|
||||
static ValID create(int64_t Val) {
|
||||
ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val; return D;
|
||||
}
|
||||
|
||||
static ValID create(uint64_t Val) {
|
||||
ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val; return D;
|
||||
}
|
||||
|
||||
static ValID create(APFloat *Val) {
|
||||
ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val; return D;
|
||||
}
|
||||
|
||||
static ValID create(const APInt &Val, bool isSigned) {
|
||||
ValID D; D.Type = ConstAPInt;
|
||||
D.ConstPoolInt = new APSInt(Val, !isSigned);
|
||||
return D;
|
||||
}
|
||||
|
||||
|
||||
static ValID createNull() {
|
||||
ValID D; D.Type = ConstNullVal; return D;
|
||||
}
|
||||
|
||||
static ValID createUndef() {
|
||||
ValID D; D.Type = ConstUndefVal; return D;
|
||||
}
|
||||
|
||||
static ValID createZeroInit() {
|
||||
ValID D; D.Type = ConstZeroVal; return D;
|
||||
}
|
||||
|
||||
static ValID create(Constant *Val) {
|
||||
ValID D; D.Type = ConstantVal; D.ConstantValue = Val; return D;
|
||||
}
|
||||
|
||||
static ValID createInlineAsm(const std::string &AsmString,
|
||||
const std::string &Constraints,
|
||||
bool HasSideEffects) {
|
||||
ValID D;
|
||||
D.Type = InlineAsmVal;
|
||||
D.IAD = new InlineAsmDescriptor(AsmString, Constraints, HasSideEffects);
|
||||
return D;
|
||||
}
|
||||
|
||||
inline void destroy() const {
|
||||
if (Type == LocalName || Type == GlobalName)
|
||||
delete Name; // Free this strdup'd memory.
|
||||
else if (Type == InlineAsmVal)
|
||||
delete IAD;
|
||||
else if (Type == ConstAPInt)
|
||||
delete ConstPoolInt;
|
||||
else if (Type == ConstFPVal)
|
||||
delete ConstPoolFP;
|
||||
}
|
||||
|
||||
inline ValID copy() const {
|
||||
ValID Result = *this;
|
||||
if (Type == ConstAPInt)
|
||||
Result.ConstPoolInt = new APSInt(*ConstPoolInt);
|
||||
|
||||
if (Type != LocalName && Type != GlobalName) return Result;
|
||||
Result.Name = new std::string(*Name);
|
||||
return Result;
|
||||
}
|
||||
|
||||
inline std::string getName() const {
|
||||
switch (Type) {
|
||||
case LocalID : return '%' + utostr(Num);
|
||||
case GlobalID : return '@' + utostr(Num);
|
||||
case LocalName : return *Name;
|
||||
case GlobalName : return *Name;
|
||||
case ConstAPInt : return ConstPoolInt->toString(10);
|
||||
case ConstFPVal : return ftostr(*ConstPoolFP);
|
||||
case ConstNullVal : return "null";
|
||||
case ConstUndefVal : return "undef";
|
||||
case ConstZeroVal : return "zeroinitializer";
|
||||
case ConstUIntVal :
|
||||
case ConstSIntVal : return std::string("%") + itostr(ConstPool64);
|
||||
case ConstantVal:
|
||||
if (ConstantValue == ConstantInt::getTrue()) return "true";
|
||||
if (ConstantValue == ConstantInt::getFalse()) return "false";
|
||||
return "<constant expression>";
|
||||
default:
|
||||
assert(0 && "Unknown value!");
|
||||
abort();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool operator<(const ValID &V) const {
|
||||
if (Type != V.Type) return Type < V.Type;
|
||||
switch (Type) {
|
||||
case LocalID:
|
||||
case GlobalID: return Num < V.Num;
|
||||
case LocalName:
|
||||
case GlobalName: return *Name < *V.Name;
|
||||
case ConstSIntVal: return ConstPool64 < V.ConstPool64;
|
||||
case ConstUIntVal: return UConstPool64 < V.UConstPool64;
|
||||
case ConstAPInt: return ConstPoolInt->ult(*V.ConstPoolInt);
|
||||
case ConstFPVal: return ConstPoolFP->compare(*V.ConstPoolFP) ==
|
||||
APFloat::cmpLessThan;
|
||||
case ConstNullVal: return false;
|
||||
case ConstUndefVal: return false;
|
||||
case ConstZeroVal: return false;
|
||||
case ConstantVal: return ConstantValue < V.ConstantValue;
|
||||
default: assert(0 && "Unknown value type!"); return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const ValID &V) const {
|
||||
if (Type != V.Type) return false;
|
||||
|
||||
switch (Type) {
|
||||
default: assert(0 && "Unknown value type!");
|
||||
case LocalID:
|
||||
case GlobalID: return Num == V.Num;
|
||||
case LocalName:
|
||||
case GlobalName: return *Name == *(V.Name);
|
||||
case ConstSIntVal: return ConstPool64 == V.ConstPool64;
|
||||
case ConstUIntVal: return UConstPool64 == V.UConstPool64;
|
||||
case ConstAPInt: return *ConstPoolInt == *V.ConstPoolInt;
|
||||
case ConstFPVal: return ConstPoolFP->compare(*V.ConstPoolFP) ==
|
||||
APFloat::cmpEqual;
|
||||
case ConstantVal: return ConstantValue == V.ConstantValue;
|
||||
case ConstNullVal: return true;
|
||||
case ConstUndefVal: return true;
|
||||
case ConstZeroVal: return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TypeWithAttrs {
|
||||
llvm::PATypeHolder *Ty;
|
||||
Attributes Attrs;
|
||||
};
|
||||
|
||||
typedef std::vector<TypeWithAttrs> TypeWithAttrsList;
|
||||
|
||||
struct ArgListEntry {
|
||||
Attributes Attrs;
|
||||
llvm::PATypeHolder *Ty;
|
||||
std::string *Name;
|
||||
};
|
||||
|
||||
typedef std::vector<struct ArgListEntry> ArgListType;
|
||||
|
||||
struct ParamListEntry {
|
||||
Value *Val;
|
||||
Attributes Attrs;
|
||||
};
|
||||
|
||||
typedef std::vector<ParamListEntry> ParamList;
|
||||
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,426 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
ESINT64VAL = 258,
|
||||
EUINT64VAL = 259,
|
||||
ESAPINTVAL = 260,
|
||||
EUAPINTVAL = 261,
|
||||
LOCALVAL_ID = 262,
|
||||
GLOBALVAL_ID = 263,
|
||||
FPVAL = 264,
|
||||
VOID = 265,
|
||||
INTTYPE = 266,
|
||||
FLOAT = 267,
|
||||
DOUBLE = 268,
|
||||
X86_FP80 = 269,
|
||||
FP128 = 270,
|
||||
PPC_FP128 = 271,
|
||||
LABEL = 272,
|
||||
TYPE = 273,
|
||||
LOCALVAR = 274,
|
||||
GLOBALVAR = 275,
|
||||
LABELSTR = 276,
|
||||
STRINGCONSTANT = 277,
|
||||
ATSTRINGCONSTANT = 278,
|
||||
PCTSTRINGCONSTANT = 279,
|
||||
ZEROINITIALIZER = 280,
|
||||
TRUETOK = 281,
|
||||
FALSETOK = 282,
|
||||
BEGINTOK = 283,
|
||||
ENDTOK = 284,
|
||||
DECLARE = 285,
|
||||
DEFINE = 286,
|
||||
GLOBAL = 287,
|
||||
CONSTANT = 288,
|
||||
SECTION = 289,
|
||||
ALIAS = 290,
|
||||
VOLATILE = 291,
|
||||
THREAD_LOCAL = 292,
|
||||
TO = 293,
|
||||
DOTDOTDOT = 294,
|
||||
NULL_TOK = 295,
|
||||
UNDEF = 296,
|
||||
INTERNAL = 297,
|
||||
LINKONCE = 298,
|
||||
WEAK = 299,
|
||||
APPENDING = 300,
|
||||
DLLIMPORT = 301,
|
||||
DLLEXPORT = 302,
|
||||
EXTERN_WEAK = 303,
|
||||
COMMON = 304,
|
||||
OPAQUE = 305,
|
||||
EXTERNAL = 306,
|
||||
TARGET = 307,
|
||||
TRIPLE = 308,
|
||||
ALIGN = 309,
|
||||
ADDRSPACE = 310,
|
||||
DEPLIBS = 311,
|
||||
CALL = 312,
|
||||
TAIL = 313,
|
||||
ASM_TOK = 314,
|
||||
MODULE = 315,
|
||||
SIDEEFFECT = 316,
|
||||
CC_TOK = 317,
|
||||
CCC_TOK = 318,
|
||||
FASTCC_TOK = 319,
|
||||
COLDCC_TOK = 320,
|
||||
X86_STDCALLCC_TOK = 321,
|
||||
X86_FASTCALLCC_TOK = 322,
|
||||
DATALAYOUT = 323,
|
||||
RET = 324,
|
||||
BR = 325,
|
||||
SWITCH = 326,
|
||||
INVOKE = 327,
|
||||
UNWIND = 328,
|
||||
UNREACHABLE = 329,
|
||||
ADD = 330,
|
||||
SUB = 331,
|
||||
MUL = 332,
|
||||
UDIV = 333,
|
||||
SDIV = 334,
|
||||
FDIV = 335,
|
||||
UREM = 336,
|
||||
SREM = 337,
|
||||
FREM = 338,
|
||||
AND = 339,
|
||||
OR = 340,
|
||||
XOR = 341,
|
||||
SHL = 342,
|
||||
LSHR = 343,
|
||||
ASHR = 344,
|
||||
ICMP = 345,
|
||||
FCMP = 346,
|
||||
VICMP = 347,
|
||||
VFCMP = 348,
|
||||
EQ = 349,
|
||||
NE = 350,
|
||||
SLT = 351,
|
||||
SGT = 352,
|
||||
SLE = 353,
|
||||
SGE = 354,
|
||||
ULT = 355,
|
||||
UGT = 356,
|
||||
ULE = 357,
|
||||
UGE = 358,
|
||||
OEQ = 359,
|
||||
ONE = 360,
|
||||
OLT = 361,
|
||||
OGT = 362,
|
||||
OLE = 363,
|
||||
OGE = 364,
|
||||
ORD = 365,
|
||||
UNO = 366,
|
||||
UEQ = 367,
|
||||
UNE = 368,
|
||||
MALLOC = 369,
|
||||
ALLOCA = 370,
|
||||
FREE = 371,
|
||||
LOAD = 372,
|
||||
STORE = 373,
|
||||
GETELEMENTPTR = 374,
|
||||
TRUNC = 375,
|
||||
ZEXT = 376,
|
||||
SEXT = 377,
|
||||
FPTRUNC = 378,
|
||||
FPEXT = 379,
|
||||
BITCAST = 380,
|
||||
UITOFP = 381,
|
||||
SITOFP = 382,
|
||||
FPTOUI = 383,
|
||||
FPTOSI = 384,
|
||||
INTTOPTR = 385,
|
||||
PTRTOINT = 386,
|
||||
PHI_TOK = 387,
|
||||
SELECT = 388,
|
||||
VAARG = 389,
|
||||
EXTRACTELEMENT = 390,
|
||||
INSERTELEMENT = 391,
|
||||
SHUFFLEVECTOR = 392,
|
||||
GETRESULT = 393,
|
||||
EXTRACTVALUE = 394,
|
||||
INSERTVALUE = 395,
|
||||
SIGNEXT = 396,
|
||||
ZEROEXT = 397,
|
||||
NORETURN = 398,
|
||||
INREG = 399,
|
||||
SRET = 400,
|
||||
NOUNWIND = 401,
|
||||
NOALIAS = 402,
|
||||
NOCAPTURE = 403,
|
||||
BYVAL = 404,
|
||||
READNONE = 405,
|
||||
READONLY = 406,
|
||||
GC = 407,
|
||||
OPTSIZE = 408,
|
||||
NOINLINE = 409,
|
||||
ALWAYSINLINE = 410,
|
||||
SSP = 411,
|
||||
SSPREQ = 412,
|
||||
NEST = 413,
|
||||
DEFAULT = 414,
|
||||
HIDDEN = 415,
|
||||
PROTECTED = 416
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define ESINT64VAL 258
|
||||
#define EUINT64VAL 259
|
||||
#define ESAPINTVAL 260
|
||||
#define EUAPINTVAL 261
|
||||
#define LOCALVAL_ID 262
|
||||
#define GLOBALVAL_ID 263
|
||||
#define FPVAL 264
|
||||
#define VOID 265
|
||||
#define INTTYPE 266
|
||||
#define FLOAT 267
|
||||
#define DOUBLE 268
|
||||
#define X86_FP80 269
|
||||
#define FP128 270
|
||||
#define PPC_FP128 271
|
||||
#define LABEL 272
|
||||
#define TYPE 273
|
||||
#define LOCALVAR 274
|
||||
#define GLOBALVAR 275
|
||||
#define LABELSTR 276
|
||||
#define STRINGCONSTANT 277
|
||||
#define ATSTRINGCONSTANT 278
|
||||
#define PCTSTRINGCONSTANT 279
|
||||
#define ZEROINITIALIZER 280
|
||||
#define TRUETOK 281
|
||||
#define FALSETOK 282
|
||||
#define BEGINTOK 283
|
||||
#define ENDTOK 284
|
||||
#define DECLARE 285
|
||||
#define DEFINE 286
|
||||
#define GLOBAL 287
|
||||
#define CONSTANT 288
|
||||
#define SECTION 289
|
||||
#define ALIAS 290
|
||||
#define VOLATILE 291
|
||||
#define THREAD_LOCAL 292
|
||||
#define TO 293
|
||||
#define DOTDOTDOT 294
|
||||
#define NULL_TOK 295
|
||||
#define UNDEF 296
|
||||
#define INTERNAL 297
|
||||
#define LINKONCE 298
|
||||
#define WEAK 299
|
||||
#define APPENDING 300
|
||||
#define DLLIMPORT 301
|
||||
#define DLLEXPORT 302
|
||||
#define EXTERN_WEAK 303
|
||||
#define COMMON 304
|
||||
#define OPAQUE 305
|
||||
#define EXTERNAL 306
|
||||
#define TARGET 307
|
||||
#define TRIPLE 308
|
||||
#define ALIGN 309
|
||||
#define ADDRSPACE 310
|
||||
#define DEPLIBS 311
|
||||
#define CALL 312
|
||||
#define TAIL 313
|
||||
#define ASM_TOK 314
|
||||
#define MODULE 315
|
||||
#define SIDEEFFECT 316
|
||||
#define CC_TOK 317
|
||||
#define CCC_TOK 318
|
||||
#define FASTCC_TOK 319
|
||||
#define COLDCC_TOK 320
|
||||
#define X86_STDCALLCC_TOK 321
|
||||
#define X86_FASTCALLCC_TOK 322
|
||||
#define DATALAYOUT 323
|
||||
#define RET 324
|
||||
#define BR 325
|
||||
#define SWITCH 326
|
||||
#define INVOKE 327
|
||||
#define UNWIND 328
|
||||
#define UNREACHABLE 329
|
||||
#define ADD 330
|
||||
#define SUB 331
|
||||
#define MUL 332
|
||||
#define UDIV 333
|
||||
#define SDIV 334
|
||||
#define FDIV 335
|
||||
#define UREM 336
|
||||
#define SREM 337
|
||||
#define FREM 338
|
||||
#define AND 339
|
||||
#define OR 340
|
||||
#define XOR 341
|
||||
#define SHL 342
|
||||
#define LSHR 343
|
||||
#define ASHR 344
|
||||
#define ICMP 345
|
||||
#define FCMP 346
|
||||
#define VICMP 347
|
||||
#define VFCMP 348
|
||||
#define EQ 349
|
||||
#define NE 350
|
||||
#define SLT 351
|
||||
#define SGT 352
|
||||
#define SLE 353
|
||||
#define SGE 354
|
||||
#define ULT 355
|
||||
#define UGT 356
|
||||
#define ULE 357
|
||||
#define UGE 358
|
||||
#define OEQ 359
|
||||
#define ONE 360
|
||||
#define OLT 361
|
||||
#define OGT 362
|
||||
#define OLE 363
|
||||
#define OGE 364
|
||||
#define ORD 365
|
||||
#define UNO 366
|
||||
#define UEQ 367
|
||||
#define UNE 368
|
||||
#define MALLOC 369
|
||||
#define ALLOCA 370
|
||||
#define FREE 371
|
||||
#define LOAD 372
|
||||
#define STORE 373
|
||||
#define GETELEMENTPTR 374
|
||||
#define TRUNC 375
|
||||
#define ZEXT 376
|
||||
#define SEXT 377
|
||||
#define FPTRUNC 378
|
||||
#define FPEXT 379
|
||||
#define BITCAST 380
|
||||
#define UITOFP 381
|
||||
#define SITOFP 382
|
||||
#define FPTOUI 383
|
||||
#define FPTOSI 384
|
||||
#define INTTOPTR 385
|
||||
#define PTRTOINT 386
|
||||
#define PHI_TOK 387
|
||||
#define SELECT 388
|
||||
#define VAARG 389
|
||||
#define EXTRACTELEMENT 390
|
||||
#define INSERTELEMENT 391
|
||||
#define SHUFFLEVECTOR 392
|
||||
#define GETRESULT 393
|
||||
#define EXTRACTVALUE 394
|
||||
#define INSERTVALUE 395
|
||||
#define SIGNEXT 396
|
||||
#define ZEROEXT 397
|
||||
#define NORETURN 398
|
||||
#define INREG 399
|
||||
#define SRET 400
|
||||
#define NOUNWIND 401
|
||||
#define NOALIAS 402
|
||||
#define NOCAPTURE 403
|
||||
#define BYVAL 404
|
||||
#define READNONE 405
|
||||
#define READONLY 406
|
||||
#define GC 407
|
||||
#define OPTSIZE 408
|
||||
#define NOINLINE 409
|
||||
#define ALWAYSINLINE 410
|
||||
#define SSP 411
|
||||
#define SSPREQ 412
|
||||
#define NEST 413
|
||||
#define DEFAULT 414
|
||||
#define HIDDEN 415
|
||||
#define PROTECTED 416
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 986 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y"
|
||||
{
|
||||
llvm::Module *ModuleVal;
|
||||
llvm::Function *FunctionVal;
|
||||
llvm::BasicBlock *BasicBlockVal;
|
||||
llvm::TerminatorInst *TermInstVal;
|
||||
llvm::Instruction *InstVal;
|
||||
llvm::Constant *ConstVal;
|
||||
|
||||
const llvm::Type *PrimType;
|
||||
std::list<llvm::PATypeHolder> *TypeList;
|
||||
llvm::PATypeHolder *TypeVal;
|
||||
llvm::Value *ValueVal;
|
||||
std::vector<llvm::Value*> *ValueList;
|
||||
std::vector<unsigned> *ConstantList;
|
||||
llvm::ArgListType *ArgList;
|
||||
llvm::TypeWithAttrs TypeWithAttrs;
|
||||
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
||||
llvm::ParamList *ParamList;
|
||||
|
||||
// Represent the RHS of PHI node
|
||||
std::list<std::pair<llvm::Value*,
|
||||
llvm::BasicBlock*> > *PHIList;
|
||||
std::vector<std::pair<llvm::Constant*, llvm::BasicBlock*> > *JumpTable;
|
||||
std::vector<llvm::Constant*> *ConstVector;
|
||||
|
||||
llvm::GlobalValue::LinkageTypes Linkage;
|
||||
llvm::GlobalValue::VisibilityTypes Visibility;
|
||||
llvm::Attributes Attributes;
|
||||
llvm::APInt *APIntVal;
|
||||
int64_t SInt64Val;
|
||||
uint64_t UInt64Val;
|
||||
int SIntVal;
|
||||
unsigned UIntVal;
|
||||
llvm::APFloat *FPVal;
|
||||
bool BoolVal;
|
||||
|
||||
std::string *StrVal; // This memory must be deleted
|
||||
llvm::ValID ValIDVal;
|
||||
|
||||
llvm::Instruction::BinaryOps BinaryOpVal;
|
||||
llvm::Instruction::TermOps TermOpVal;
|
||||
llvm::Instruction::MemoryOps MemOpVal;
|
||||
llvm::Instruction::CastOps CastOpVal;
|
||||
llvm::Instruction::OtherOps OtherOpVal;
|
||||
llvm::ICmpInst::Predicate IPredicate;
|
||||
llvm::FCmpInst::Predicate FPredicate;
|
||||
}
|
||||
/* Line 1489 of yacc.c. */
|
||||
#line 419 "llvmAsmParser.tab.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE llvmAsmlval;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1188,6 +1188,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||
PrintVisibility(GV->getVisibility(), Out);
|
||||
|
||||
if (GV->isThreadLocal()) Out << "thread_local ";
|
||||
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
|
||||
Out << "addrspace(" << AddressSpace << ") ";
|
||||
Out << (GV->isConstant() ? "constant " : "global ");
|
||||
printType(GV->getType()->getElementType());
|
||||
|
||||
@ -1195,9 +1197,6 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||
Out << ' ';
|
||||
writeOperand(GV->getInitializer(), false);
|
||||
}
|
||||
|
||||
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
|
||||
Out << " addrspace(" << AddressSpace << ") ";
|
||||
|
||||
if (GV->hasSection())
|
||||
Out << ", section \"" << GV->getSection() << '"';
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Make sure we don't get an assertion failure, even though this is a parse
|
||||
; error
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep {No arguments}
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep {'@foo' defined with}
|
||||
|
||||
%ty = type void (i32)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: not llvm-as < %s >/dev/null |& grep {Expected type 'i32' for element #0}
|
||||
; RUN: not llvm-as < %s >/dev/null |& grep {constant expression type mismatch}
|
||||
; Test the case of a misformed constant initializer
|
||||
; This should cause an assembler error, not an assertion failure!
|
||||
constant { i32 } { float 1.0 }
|
||||
|
@ -1,4 +1,4 @@
|
||||
; Found by inspection of the code
|
||||
; RUN: not llvm-as < %s > /dev/null |& grep {Logical operator requires integral}
|
||||
; RUN: not llvm-as < %s > /dev/null |& grep {constexpr requires integer or integer vector operands}
|
||||
|
||||
global i32 ashr (float 1.0, float 2.0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
; Found by inspection of the code
|
||||
; RUN: not llvm-as < %s > /dev/null |& grep {Illegal number of init}
|
||||
; RUN: not llvm-as < %s > /dev/null |& grep {constant expression type mismatch}
|
||||
|
||||
global {} { i32 7, float 1.0, i32 7, i32 8 }
|
||||
|
@ -1,5 +1,4 @@
|
||||
; RUN: not llvm-as < %s |& not grep Asserti
|
||||
; RUN: not llvm-as < %s |& grep Redefinition
|
||||
; RUN: not llvm-as < %s |& grep {multiple definition}
|
||||
|
||||
define void @test() {
|
||||
%tmp.1 = add i32 0, 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep {Undefined type remains}
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep {use of undefined type named 'struct.D_Scope'}
|
||||
; END.
|
||||
|
||||
@d_reduction_0_dparser_gram = global {
|
||||
|
@ -1,3 +1,3 @@
|
||||
; RUN: not llvm-as %s |& grep error
|
||||
; RUN: not llvm-as %s |& grep {found end of file when expecting more instructions}
|
||||
|
||||
void %foo() {
|
||||
define void @foo() {
|
||||
|
@ -1,5 +1,4 @@
|
||||
; Test for PR463. This program is erroneous, but should not crash llvm-as.
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& \
|
||||
; RUN: grep {Cannot create a null initialized value of this type}
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep {invalid type for null constant}
|
||||
|
||||
@.FOO = internal global %struct.none zeroinitializer
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Test for PR902. This program is erroneous, but should not crash llvm-as.
|
||||
; This tests that a simple error is caught and processed correctly.
|
||||
; RUN: not llvm-as < %s >/dev/null |& grep {FP constant invalid for type}
|
||||
; RUN: not llvm-as < %s >/dev/null |& grep {floating point constant invalid for type}
|
||||
|
||||
define void @test() {
|
||||
add i32 1, 2.0
|
||||
|
@ -1,5 +1,5 @@
|
||||
; The assembler should catch an undefined argument type .
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep {Reference to abstract argument}
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep {use of undefined type named 'typedef.bc_struct'}
|
||||
|
||||
; %typedef.bc_struct = type opaque
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
; PR 1258
|
||||
; RUN: not llvm-as < %s >/dev/null -f |& grep {Numbered.*does not match}
|
||||
; RUN: not llvm-as < %s >/dev/null -f |& grep {'%0' defined with type 'i1'}
|
||||
|
||||
define i32 @test1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
|
@ -1,7 +1,9 @@
|
||||
; RUN: not llvm-as < %s > /dev/null |& grep {Invalid type for reference to global}
|
||||
; RUN: not llvm-as < %s > /dev/null |& grep {expected top-level entity}
|
||||
; PR1577
|
||||
|
||||
@anInt = global i32 1 alias i32 @anAlias
|
||||
@anInt = global i32 1
|
||||
alias i32 @anAlias
|
||||
|
||||
define i32 @main() {
|
||||
ret i32 0
|
||||
}
|
||||
|
@ -5,9 +5,9 @@
|
||||
; RUN: llvm-as < %s | llvm-dis | grep {addrspace(22)} | count 5
|
||||
|
||||
%struct.mystruct = type { i32, i32 addrspace(33)*, i32, i32 addrspace(33)* }
|
||||
@input = weak global %struct.mystruct zeroinitializer addrspace(42) ; <%struct.mystruct addrspace(42)*> [#uses=1]
|
||||
@output = global %struct.mystruct zeroinitializer addrspace(66) ; <%struct.mystruct addrspace(66)*> [#uses=1]
|
||||
@y = external global i32 addrspace(11)* addrspace(22)* addrspace(33) ; <i32 addrspace(11)* addrspace(22)* addrspace(33)*> [#uses=1]
|
||||
@input = weak addrspace(42) global %struct.mystruct zeroinitializer ; <%struct.mystruct addrspace(42)*> [#uses=1]
|
||||
@output = addrspace(66) global %struct.mystruct zeroinitializer ; <%struct.mystruct addrspace(66)*> [#uses=1]
|
||||
@y = external addrspace(33) global i32 addrspace(11)* addrspace(22)* ; <i32 addrspace(11)* addrspace(22)* addrspace(33)*> [#uses=1]
|
||||
|
||||
define void @foo() {
|
||||
entry:
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: not llvm-as %s |& grep {is invalid or}
|
||||
; RUN: not llvm-as %s |& grep {integer constant must have integer type}
|
||||
; PR2060
|
||||
|
||||
define i8* @foo() {
|
||||
|
@ -1,6 +1,4 @@
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep \
|
||||
; RUN: "Redefinition of global variable named 'B'"
|
||||
; END.
|
||||
; RUN: not llvm-as %s -o /dev/null -f |& grep {redefinition of global '@B'}
|
||||
|
||||
@B = global i32 7
|
||||
@B = global i32 7
|
||||
|
@ -7,7 +7,6 @@
|
||||
;
|
||||
|
||||
%SQ1 = type { i32 }
|
||||
%ITy = type opaque
|
||||
%SQ2 = type { %ITy }
|
||||
%ITy = type i32
|
||||
|
||||
@ -22,7 +21,6 @@ type %BBB
|
||||
%Composite = type { %0, %1 }
|
||||
|
||||
; Test simple opaque type resolution...
|
||||
%intty = type opaque
|
||||
%intty = type i32
|
||||
|
||||
; Perform a simple forward reference...
|
||||
|
@ -7,7 +7,6 @@
|
||||
;
|
||||
|
||||
%SQ1 = type { i31 }
|
||||
%ITy = type opaque
|
||||
%SQ2 = type { %ITy }
|
||||
%ITy = type i31
|
||||
|
||||
@ -22,7 +21,6 @@ type %BBB
|
||||
%Composite = type { %0, %1 }
|
||||
|
||||
; Test simple opaque type resolution...
|
||||
%i31ty = type opaque
|
||||
%i31ty = type i31
|
||||
|
||||
; Perform a simple forward reference...
|
||||
|
@ -6,4 +6,4 @@
|
||||
; RUN: llvm-link %t.foo1.bc %t.foo2.bc | llvm-dis | grep {addrspace(2)}
|
||||
; rdar://6038021
|
||||
|
||||
@G = global i32 256 addrspace(2)
|
||||
@G = addrspace(2) global i32 256
|
||||
|
@ -6,8 +6,8 @@
|
||||
; Check that the new global values still have their address space
|
||||
; RUN: cat %t | grep global.*addrspace
|
||||
|
||||
@struct = internal global { i32, i32 } zeroinitializer addrspace(1)
|
||||
@array = internal global [ 2 x i32 ] zeroinitializer addrspace(1)
|
||||
@struct = internal addrspace(1) global { i32, i32 } zeroinitializer
|
||||
@array = internal addrspace(1) global [ 2 x i32 ] zeroinitializer
|
||||
|
||||
define i32 @foo() {
|
||||
%A = load i32 addrspace(1) * getelementptr ({ i32, i32 } addrspace(1) * @struct, i32 0, i32 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: not llvm-as < %s |& grep {Invalid getelementptr indices}
|
||||
; RUN: not llvm-as < %s |& grep {invalid getelementptr indices}
|
||||
|
||||
; This testcase is invalid because we are indexing into a pointer that is
|
||||
; contained WITHIN a structure.
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: not llvm-as < %s |& grep {Reference to an undefined type}
|
||||
; RUN: not llvm-as < %s |& grep {use of undefined type named 'InvalidType'}
|
||||
|
||||
define void @test() {
|
||||
malloc %InvalidType
|
||||
|
@ -1,5 +1,4 @@
|
||||
; RUN: not llvm-as < %s > /dev/null |& \
|
||||
; RUN: grep {Cannot form a pointer to a basic block}
|
||||
; RUN: not llvm-as < %s > /dev/null |& grep {basic block pointers are invalid}
|
||||
|
||||
define i32 @main() {
|
||||
%foo = call i8* %llvm.stacksave()
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileUtilities.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
using namespace llvm;
|
||||
@ -80,8 +81,8 @@ Module *llvm::ParseInputFile(const std::string &Filename) {
|
||||
Result = ParseBitcodeFile(Buffer.get());
|
||||
|
||||
ParseError Err;
|
||||
if (!Result && !(Result = ParseAssemblyFile(Filename, &Err))) {
|
||||
std::cerr << "bugpoint: " << Err.getMessage() << "\n";
|
||||
if (!Result && !(Result = ParseAssemblyFile(Filename, Err))) {
|
||||
Err.PrintError("bugpoint", errs());
|
||||
Result = 0;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/Streams.h"
|
||||
#include "llvm/Support/SystemUtils.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/System/Signals.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@ -59,9 +60,9 @@ int main(int argc, char **argv) {
|
||||
try {
|
||||
// Parse the file now...
|
||||
ParseError Err;
|
||||
std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename,&Err));
|
||||
std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename, Err));
|
||||
if (M.get() == 0) {
|
||||
cerr << argv[0] << ": " << Err.getMessage() << "\n";
|
||||
Err.PrintError(argv[0], errs());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user