diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 8654db55966..80bab43a22a 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -202,6 +202,8 @@ private: bool ParseDirectiveInclude(); // ".include" bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if" + // ".ifdef" or ".ifndef", depending on expect_defined + bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else" bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif @@ -222,7 +224,6 @@ class GenericAsmParser : public MCAsmParserExtension { getParser().AddDirectiveHandler(this, Directive, HandleDirective); } - public: GenericAsmParser() {} @@ -887,6 +888,10 @@ bool AsmParser::ParseStatement() { // example. if (IDVal == ".if") return ParseDirectiveIf(IDLoc); + if (IDVal == ".ifdef") + return ParseDirectiveIfdef(IDLoc, true); + if (IDVal == ".ifndef" || IDVal == ".ifnotdef") + return ParseDirectiveIfdef(IDLoc, false); if (IDVal == ".elseif") return ParseDirectiveElseIf(IDLoc); if (IDVal == ".else") @@ -1933,6 +1938,31 @@ bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { return false; } +bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { + StringRef Name; + TheCondStack.push_back(TheCondState); + TheCondState.TheCond = AsmCond::IfCond; + + if (TheCondState.Ignore) { + EatToEndOfStatement(); + } else { + if (ParseIdentifier(Name)) + return TokError("expected identifier after '.ifdef'"); + + Lex(); + + MCSymbol *Sym = getContext().LookupSymbol(Name); + + if (expect_defined) + TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined()); + else + TheCondState.CondMet = (Sym == NULL || Sym->isUndefined()); + TheCondState.Ignore = !TheCondState.CondMet; + } + + return false; +} + /// ParseDirectiveElseIf /// ::= .elseif expression bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { diff --git a/test/MC/AsmParser/ifdef.s b/test/MC/AsmParser/ifdef.s new file mode 100644 index 00000000000..98bff6525b2 --- /dev/null +++ b/test/MC/AsmParser/ifdef.s @@ -0,0 +1,29 @@ +# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s + +# CHECK-NOT: .byte 0 +# CHECK: .byte 1 +.ifdef undefined + .byte 0 +.else + .byte 1 +.endif + +defined: + +# CHECK: .byte 1 +# CHECK-NOT: .byte 0 +.ifdef defined + .byte 1 +.else + .byte 0 +.endif + + movl %eax, undefined + +# CHECK-NOT: .byte 0 +# CHECK: .byte 1 +.ifdef undefined + .byte 0 +.else + .byte 1 +.endif diff --git a/test/MC/AsmParser/ifndef.s b/test/MC/AsmParser/ifndef.s new file mode 100644 index 00000000000..d9c9c5457a7 --- /dev/null +++ b/test/MC/AsmParser/ifndef.s @@ -0,0 +1,29 @@ +# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s + +# CHECK: .byte 1 +# CHECK-NOT: byte 0 +.ifndef undefined + .byte 1 +.else + .byte 0 +.endif + +defined: + +# CHECK-NOT: byte 0 +# CHECK: .byte 1 +.ifndef defined + .byte 0 +.else + .byte 1 +.endif + + movl %eax, undefined + +# CHECK: .byte 1 +# CHECK-NOT: byte 0 +.ifndef undefined + .byte 1 +.else + .byte 0 +.endif