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 | 4e4db7adfc9858a8f77f841c7467bc6fcbb8110e (patch) | |
tree | 3ef227b9e607013736fca50b48e0f408703d4bef /tools/llvm-mc/AsmParser.cpp | |
parent | 74a77812d1785ad6c62226c52dcd4d129b3cdd0b (diff) | |
download | external_llvm-4e4db7adfc9858a8f77f841c7467bc6fcbb8110e.zip external_llvm-4e4db7adfc9858a8f77f841c7467bc6fcbb8110e.tar.gz external_llvm-4e4db7adfc9858a8f77f841c7467bc6fcbb8110e.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/llvm-mc/AsmParser.cpp')
-rw-r--r-- | tools/llvm-mc/AsmParser.cpp | 59 |
1 files changed, 59 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; +} |