Reinforce ARMTargetParser::getCanonicalArchName validation

Before, getCanonicalArchName was relying on parseArch() to validate the arch
name, which was a problem when other methods, that also needed to call it,
were duplicating the steps.

But to dissociate getCanonicalArchName from parseArch, we needed to make
getCanonicalArchName more robust in detecting valid arch names. It's still
not perfect, but will do for the time being, until we merge Triple with
TargetParser into a TargetDescription mega class.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238047 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Renato Golin 2015-05-22 20:43:30 +00:00
parent 157fbac534
commit 0ceb20d6f4

View File

@ -16,6 +16,7 @@
#include "llvm/Support/TargetParser.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include <cctype>
using namespace llvm;
@ -279,14 +280,17 @@ StringRef ARMTargetParser::getArchSynonym(StringRef Arch) {
// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
// (iwmmxt|xscale)(eb)? is also permitted. If the former, return
// "v.+", if the latter, return unmodified string. If invalid, return "".
// "v.+", if the latter, return unmodified string, minus 'eb'.
// If invalid, return empty string.
StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
size_t offset = StringRef::npos;
StringRef A = Arch;
StringRef Error = "";
// Begins with "arm" / "thumb", move past it.
if (A.startswith("arm"))
if (A.startswith("arm64"))
offset = 5;
else if (A.startswith("arm"))
offset = 3;
else if (A.startswith("thumb"))
offset = 5;
@ -305,21 +309,25 @@ StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
// Or, if it ends with eb ("armv7eb"), chop it off.
else if (A.endswith("eb"))
A = A.substr(0, A.size() - 2);
// Reached the end or a 'v', canonicalise.
if (offset != StringRef::npos && (offset == A.size() || A[offset] == 'v'))
// Trim the head
if (offset != StringRef::npos)
A = A.substr(offset);
// Empty string mans offset reached the end. Although valid, this arch
// will not have a match in the table. Return the original string.
// Empty string means offset reached the end, which means it's valid.
if (A.empty())
return Arch;
// If can't find the arch, return an empty StringRef.
if (parseArch(A) == ARM::AK_INVALID)
return Error;
// Only match non-marketing names
if (offset != StringRef::npos) {
// Must start with 'vN'.
if (A[0] != 'v' || !std::isdigit(A[1]))
return Error;
// Can't have an extra 'eb'.
if (A.find("eb") != StringRef::npos)
return Error;
}
// Arch will either be a 'v' name (v7a) or a marketing name (xscale)
// or empty, if invalid.
// Arch will either be a 'v' name (v7a) or a marketing name (xscale).
return A;
}
@ -390,7 +398,6 @@ unsigned ARMTargetParser::parseArchEndian(StringRef Arch) {
// Profile A/R/M
unsigned ARMTargetParser::parseArchProfile(StringRef Arch) {
// FIXME: We're running parseArch twice.
Arch = getCanonicalArchName(Arch);
switch(parseArch(Arch)) {
case ARM::AK_ARMV6M:
@ -409,9 +416,8 @@ unsigned ARMTargetParser::parseArchProfile(StringRef Arch) {
return ARM::PK_INVALID;
}
// Version number 4 ~ 8 (ex. v7 = 7).
// Version number (ex. v7 = 7).
unsigned ARMTargetParser::parseArchVersion(StringRef Arch) {
// FIXME: We're running parseArch twice.
Arch = getCanonicalArchName(Arch);
switch(parseArch(Arch)) {
case ARM::AK_ARMV2: