Conventionally, parsing methods return false on success and true on error. However, directive parsing methods need a third state: the directive is not target specific. AsmParser::parseStatement detected this case by using a fragile heuristic: if the target parser did not consume any tokens, the directive is assumed to be not target-specific. Some targets fail to follow the convention: they return success after emitting an error or do not consume the entire line and return failure on successful parsing. This was partially worked around by checking for pending errors in parseStatement. This patch tries to improve the situation by introducing parseDirective method that returns ParseStatus -- three-state class. The new method should eventually replace the old one returning bool. ParseStatus is intentionally implicitly constructible from bool to allow uses like `return Error(Loc, "message")`. It also has a potential to replace OperandMatchResulTy as it is more convenient to use due to the implicit construction from bool and more type safe. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D154101
51 lines
1.8 KiB
C++
51 lines
1.8 KiB
C++
//===-- MCTargetAsmParser.cpp - Target Assembly Parser --------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
|
|
using namespace llvm;
|
|
|
|
MCTargetAsmParser::MCTargetAsmParser(MCTargetOptions const &MCOptions,
|
|
const MCSubtargetInfo &STI,
|
|
const MCInstrInfo &MII)
|
|
: MCOptions(MCOptions), STI(&STI), MII(MII) {}
|
|
|
|
MCTargetAsmParser::~MCTargetAsmParser() = default;
|
|
|
|
MCSubtargetInfo &MCTargetAsmParser::copySTI() {
|
|
MCSubtargetInfo &STICopy = getContext().getSubtargetCopy(getSTI());
|
|
STI = &STICopy;
|
|
return STICopy;
|
|
}
|
|
|
|
const MCSubtargetInfo &MCTargetAsmParser::getSTI() const {
|
|
return *STI;
|
|
}
|
|
|
|
ParseStatus MCTargetAsmParser::parseDirective(AsmToken DirectiveID) {
|
|
SMLoc StartTokLoc = getTok().getLoc();
|
|
// Delegate to ParseDirective by default for transition period. Once the
|
|
// transition is over, this method should just return NoMatch.
|
|
bool Res = ParseDirective(DirectiveID);
|
|
|
|
// Some targets erroneously report success after emitting an error.
|
|
if (getParser().hasPendingError())
|
|
return ParseStatus::Failure;
|
|
|
|
// ParseDirective returns true if there was an error or if the directive is
|
|
// not target-specific. Disambiguate the two cases by comparing position of
|
|
// the lexer before and after calling the method: if no tokens were consumed,
|
|
// there was no match, otherwise there was a failure.
|
|
if (!Res)
|
|
return ParseStatus::Success;
|
|
if (getTok().getLoc() != StartTokLoc)
|
|
return ParseStatus::Failure;
|
|
return ParseStatus::NoMatch;
|
|
}
|