diff options
author | Chris Lattner <sabre@nondot.org> | 2009-07-07 20:30:46 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-07-07 20:30:46 +0000 |
commit | e29dbe364ee4b2bda677d8339a2807d8a639fcf5 (patch) | |
tree | 3ef227b9e607013736fca50b48e0f408703d4bef /tools | |
parent | 4956cde4ae52dbd63ddb6cdf7af56a72731007ec (diff) | |
download | external_llvm-e29dbe364ee4b2bda677d8339a2807d8a639fcf5.zip external_llvm-e29dbe364ee4b2bda677d8339a2807d8a639fcf5.tar.gz external_llvm-e29dbe364ee4b2bda677d8339a2807d8a639fcf5.tar.bz2 |
Implement parsing support for the .comm directive. Patch by
Kevin Enderby!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74944 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/llvm-mc/AsmParser.cpp | 59 | ||||
-rw-r--r-- | tools/llvm-mc/AsmParser.h | 2 |
2 files changed, 61 insertions, 0 deletions
diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index f5bf589..1a3543a 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -520,6 +520,9 @@ bool AsmParser::ParseStatement() { if (!strcmp(IDVal, ".weak_reference")) return ParseDirectiveSymbolAttribute(MCStreamer::WeakReference); + if (!strcmp(IDVal, ".comm")) + return ParseDirectiveComm(); + Warning(IDLoc, "ignoring directive for now"); EatToEndOfStatement(); return false; @@ -896,3 +899,59 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr) { Lexer.Lex(); return false; } + +/// ParseDirectiveComm +/// ::= .comm identifier , size_expression [ , align_expression ] +bool AsmParser::ParseDirectiveComm() { + if (Lexer.isNot(asmtok::Identifier)) + return TokError("expected identifier in directive"); + + // handle the identifier as the key symbol. + SMLoc IDLoc = Lexer.getLoc(); + MCSymbol *Sym = Ctx.GetOrCreateSymbol(Lexer.getCurStrVal()); + Lexer.Lex(); + + if (Lexer.isNot(asmtok::Comma)) + return TokError("unexpected token in directive"); + Lexer.Lex(); + + int64_t Size; + SMLoc SizeLoc = Lexer.getLoc(); + if (ParseAbsoluteExpression(Size)) + return true; + + int64_t Pow2Alignment = 0; + SMLoc Pow2AlignmentLoc; + if (Lexer.is(asmtok::Comma)) { + Lexer.Lex(); + Pow2AlignmentLoc = Lexer.getLoc(); + if (ParseAbsoluteExpression(Pow2Alignment)) + return true; + } + + if (Lexer.isNot(asmtok::EndOfStatement)) + return TokError("unexpected token in '.comm' directive"); + + Lexer.Lex(); + + // NOTE: a size of zero should create a undefined symbol + if (Size < 0) + return Error(SizeLoc, "invalid '.comm' size, can't be less than zero"); + + // NOTE: The alignment in the directive is a power of 2 value, the assember + // may internally end up wanting an alignment in bytes. + // FIXME: Diagnose overflow. + if (Pow2Alignment < 0) + return Error(Pow2AlignmentLoc, "invalid '.comm' alignment, can't be less " + "than zero"); + + // TODO: Symbol must be undefined or it is a error to re-defined the symbol + if (Sym->getSection() || Ctx.GetSymbolValue(Sym)) + return Error(IDLoc, "invalid symbol redefinition"); + + // TODO: Symbol to be made into a common with this Size and Pow2Alignment + + Out.EmitCommonSymbol(Sym, Size, Pow2Alignment); + + return false; +} diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h index 333b284..bafdfb7 100644 --- a/tools/llvm-mc/AsmParser.h +++ b/tools/llvm-mc/AsmParser.h @@ -109,6 +109,8 @@ private: /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which /// accepts a single symbol (which should be a label or an external). bool ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr); + + bool ParseDirectiveComm(); // ".comm" }; |