summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2017-12-14 00:12:46 +0000
committerMatthias Braun <matze@braunis.de>2017-12-14 00:12:46 +0000
commit0148c88c080cce52c09bd9bfc4dd2127734a6a9e (patch)
tree75fe343be05f900e3dc0e5b8aec67e790995e718 /llvm/lib/MC/MCParser/DarwinAsmParser.cpp
parent2c1fa4feb183b7168d98f5dba8984b9dfde4ab31 (diff)
downloadbcm5719-llvm-0148c88c080cce52c09bd9bfc4dd2127734a6a9e.tar.gz
bcm5719-llvm-0148c88c080cce52c09bd9bfc4dd2127734a6a9e.zip
MC: Add support for mach-o build_version
LC_BUILD_VERSION is a new load command superseding the previously used LC_XXX_MIN_VERSION commands. This adds an assembler directive along with encoding/streaming support. llvm-svn: 320661
Diffstat (limited to 'llvm/lib/MC/MCParser/DarwinAsmParser.cpp')
-rw-r--r--llvm/lib/MC/MCParser/DarwinAsmParser.cpp194
1 files changed, 144 insertions, 50 deletions
diff --git a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
index f4152a9067a..195ddc78d45 100644
--- a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -54,7 +54,7 @@ class DarwinAsmParser : public MCAsmParserExtension {
unsigned TAA = 0, unsigned ImplicitAlign = 0,
unsigned StubSize = 0);
- SMLoc LastVersionMinDirective;
+ SMLoc LastVersionDirective;
public:
DarwinAsmParser() = default;
@@ -186,14 +186,17 @@ public:
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
- addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
+ addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(
".watchos_version_min");
- addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".tvos_version_min");
- addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
- addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
+ addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(
+ ".tvos_version_min");
+ addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(
+ ".ios_version_min");
+ addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(
".macosx_version_min");
+ addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");
- LastVersionMinDirective = SMLoc();
+ LastVersionDirective = SMLoc();
}
bool parseDirectiveAltEntry(StringRef, SMLoc);
@@ -441,7 +444,24 @@ public:
MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
}
- bool parseVersionMin(StringRef, SMLoc);
+ bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) {
+ return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin);
+ }
+ bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) {
+ return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin);
+ }
+ bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) {
+ return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin);
+ }
+ bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) {
+ return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin);
+ }
+
+ bool parseBuildVersion(StringRef Directive, SMLoc Loc);
+ bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);
+ bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);
+ void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,
+ Triple::OSType ExpectedOS);
};
} // end anonymous namespace
@@ -978,70 +998,144 @@ bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
return false;
}
-/// parseVersionMin
-/// ::= .ios_version_min major,minor[,update]
-/// ::= .macosx_version_min major,minor[,update]
-bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc) {
- int64_t Major = 0, Minor = 0, Update = 0;
- int Kind = StringSwitch<int>(Directive)
- .Case(".watchos_version_min", MCVM_WatchOSVersionMin)
- .Case(".tvos_version_min", MCVM_TvOSVersionMin)
- .Case(".ios_version_min", MCVM_IOSVersionMin)
- .Case(".macosx_version_min", MCVM_OSXVersionMin);
+/// parseVersion ::= major, minor [, update]
+bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
+ unsigned *Update) {
// Get the major version number.
if (getLexer().isNot(AsmToken::Integer))
+ return TokError("invalid OS major version number, integer expected");
+ int64_t MajorVal = getLexer().getTok().getIntVal();
+ if (MajorVal > 65535 || MajorVal <= 0)
return TokError("invalid OS major version number");
- Major = getLexer().getTok().getIntVal();
- if (Major > 65535 || Major <= 0)
- return TokError("invalid OS major version number");
+ *Major = (unsigned)MajorVal;
Lex();
if (getLexer().isNot(AsmToken::Comma))
- return TokError("minor OS version number required, comma expected");
+ return TokError("OS minor version number required, comma expected");
Lex();
// Get the minor version number.
if (getLexer().isNot(AsmToken::Integer))
+ return TokError("invalid OS minor version number, integer expected");
+ int64_t MinorVal = getLexer().getTok().getIntVal();
+ if (MinorVal > 255 || MinorVal < 0)
return TokError("invalid OS minor version number");
- Minor = getLexer().getTok().getIntVal();
- if (Minor > 255 || Minor < 0)
- return TokError("invalid OS minor version number");
+ *Minor = MinorVal;
Lex();
+
// Get the update level, if specified
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("invalid update specifier, comma expected");
- Lex();
- if (getLexer().isNot(AsmToken::Integer))
- return TokError("invalid OS update number");
- Update = getLexer().getTok().getIntVal();
- if (Update > 255 || Update < 0)
- return TokError("invalid OS update number");
- Lex();
+ *Update = 0;
+ if (getLexer().is(AsmToken::EndOfStatement))
+ return false;
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("invalid OS update specifier, comma expected");
+ Lex();
+ if (getLexer().isNot(AsmToken::Integer))
+ return TokError("invalid OS update version number, integer expected");
+ int64_t UpdateVal = getLexer().getTok().getIntVal();
+ if (UpdateVal > 255 || UpdateVal < 0)
+ return TokError("invalid OS update version number");
+ *Update = UpdateVal;
+ Lex();
+ return false;
+}
+
+void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,
+ SMLoc Loc, Triple::OSType ExpectedOS) {
+ const Triple &Target = getContext().getObjectFileInfo()->getTargetTriple();
+ if (Target.getOS() != ExpectedOS)
+ Warning(Loc, Twine(Directive) +
+ (Arg.empty() ? Twine() : Twine(' ') + Arg) +
+ " used while targeting " + Target.getOSName());
+
+ if (LastVersionDirective.isValid()) {
+ Warning(Loc, "overriding previous version directive");
+ Note(LastVersionDirective, "previous definition is here");
}
+ LastVersionDirective = Loc;
+}
- const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
- Triple::OSType ExpectedOS = Triple::UnknownOS;
- switch ((MCVersionMinType)Kind) {
- case MCVM_WatchOSVersionMin: ExpectedOS = Triple::WatchOS; break;
- case MCVM_TvOSVersionMin: ExpectedOS = Triple::TvOS; break;
- case MCVM_IOSVersionMin: ExpectedOS = Triple::IOS; break;
- case MCVM_OSXVersionMin: ExpectedOS = Triple::MacOSX; break;
+static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {
+ switch (Type) {
+ case MCVM_WatchOSVersionMin: return Triple::WatchOS;
+ case MCVM_TvOSVersionMin: return Triple::TvOS;
+ case MCVM_IOSVersionMin: return Triple::IOS;
+ case MCVM_OSXVersionMin: return Triple::MacOSX;
}
- if (T.getOS() != ExpectedOS)
- Warning(Loc, Directive + " should only be used for " +
- Triple::getOSTypeName(ExpectedOS) + " targets");
+ llvm_unreachable("Invalid mc version min type");
+}
+
+/// parseVersionMin
+/// ::= .ios_version_min parseVersion
+/// | .macosx_version_min parseVersion
+/// | .tvos_version_min parseVersion
+/// | .watchos_version_min parseVersion
+bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,
+ MCVersionMinType Type) {
+ unsigned Major;
+ unsigned Minor;
+ unsigned Update;
+ if (parseVersion(&Major, &Minor, &Update))
+ return true;
+
+ if (parseToken(AsmToken::EndOfStatement))
+ return addErrorSuffix(Twine(" in '") + Directive + "' directive");
+
+ Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);
+ checkVersion(Directive, StringRef(), Loc, ExpectedOS);
+
+ getStreamer().EmitVersionMin(Type, Major, Minor, Update);
+ return false;
+}
- if (LastVersionMinDirective.isValid()) {
- Warning(Loc, "overriding previous version_min directive");
- Note(LastVersionMinDirective, "previous definition is here");
+Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {
+ switch (Type) {
+ case MachO::PLATFORM_MACOS: return Triple::MacOSX;
+ case MachO::PLATFORM_IOS: return Triple::IOS;
+ case MachO::PLATFORM_TVOS: return Triple::TvOS;
+ case MachO::PLATFORM_WATCHOS: return Triple::WatchOS;
+ case MachO::PLATFORM_BRIDGEOS: /* silence warning */break;
}
- LastVersionMinDirective = Loc;
+ llvm_unreachable("Invalid mach-o platform type");
+}
- // We've parsed a correct version specifier, so send it to the streamer.
- getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update);
+/// parseBuildVersion
+/// ::= .build_version (macos|ios|tvos|watchos), parseVersion
+bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
+ StringRef PlatformName;
+ SMLoc PlatformLoc = getTok().getLoc();
+ if (getParser().parseIdentifier(PlatformName))
+ return TokError("platform name expected");
+
+ unsigned Platform = StringSwitch<unsigned>(PlatformName)
+ .Case("macos", MachO::PLATFORM_MACOS)
+ .Case("ios", MachO::PLATFORM_IOS)
+ .Case("tvos", MachO::PLATFORM_TVOS)
+ .Case("watchos", MachO::PLATFORM_WATCHOS)
+ .Default(0);
+ if (Platform == 0)
+ return Error(PlatformLoc, "unknown platform name");
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("version number required, comma expected");
+ Lex();
+
+ unsigned Major;
+ unsigned Minor;
+ unsigned Update;
+ if (parseVersion(&Major, &Minor, &Update))
+ return true;
+
+ if (parseToken(AsmToken::EndOfStatement))
+ return addErrorSuffix(" in '.build_version' directive");
+
+ Triple::OSType ExpectedOS
+ = getOSTypeFromPlatform((MachO::PlatformType)Platform);
+ checkVersion(Directive, PlatformName, Loc, ExpectedOS);
+
+ getStreamer().EmitBuildVersion(Platform, Major, Minor, Update);
return false;
}
+
namespace llvm {
MCAsmParserExtension *createDarwinAsmParser() {
OpenPOWER on IntegriCloud