summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mc/AsmParser.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-07-07 20:30:46 +0000
committerChris Lattner <sabre@nondot.org>2009-07-07 20:30:46 +0000
commita1e11f530ee287ccce8ce1cd236159fb58b81e83 (patch)
tree3372607d1515156212540f111049d99f79d16f0a /llvm/tools/llvm-mc/AsmParser.cpp
parent86be854fa869f4c292e6b261d0ce1bf5d27b495e (diff)
downloadbcm5719-llvm-a1e11f530ee287ccce8ce1cd236159fb58b81e83.tar.gz
bcm5719-llvm-a1e11f530ee287ccce8ce1cd236159fb58b81e83.zip
Implement parsing support for the .comm directive. Patch by
Kevin Enderby! llvm-svn: 74944
Diffstat (limited to 'llvm/tools/llvm-mc/AsmParser.cpp')
-rw-r--r--llvm/tools/llvm-mc/AsmParser.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/llvm/tools/llvm-mc/AsmParser.cpp b/llvm/tools/llvm-mc/AsmParser.cpp
index f5bf5892012..1a3543aac77 100644
--- a/llvm/tools/llvm-mc/AsmParser.cpp
+++ b/llvm/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;
+}
OpenPOWER on IntegriCloud