mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[TableGen] Eliminte source location from CodeInit
Step 1 in eliminating the 'code' type. Differential Revision: https://reviews.llvm.org/D91932
This commit is contained in:
parent
87d0019c62
commit
58226c6585
@ -336,14 +336,11 @@ The class provides the following additional functions.
|
|||||||
The ``CodeInit`` class is a subclass of ``TypedInit``. Its instances
|
The ``CodeInit`` class is a subclass of ``TypedInit``. Its instances
|
||||||
represent arbitrary-length strings produced from ``code`` literals in the
|
represent arbitrary-length strings produced from ``code`` literals in the
|
||||||
TableGen files. It includes a data member that contains a ``StringRef`` of
|
TableGen files. It includes a data member that contains a ``StringRef`` of
|
||||||
the value. It also includes a data member specifying the source code
|
the value.
|
||||||
location of the code string.
|
|
||||||
|
|
||||||
The class provides the usual ``get()`` and ``getValue()`` functions. The
|
The class provides the usual ``get()`` and ``getValue()`` functions. The
|
||||||
latter function returns the ``StringRef``.
|
latter function returns the ``StringRef``.
|
||||||
|
|
||||||
The ``getLoc()`` function returns the source code location.
|
|
||||||
|
|
||||||
|
|
||||||
``DagInit``
|
``DagInit``
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
@ -597,7 +597,13 @@ public:
|
|||||||
|
|
||||||
/// "foo" - Represent an initialization by a string value.
|
/// "foo" - Represent an initialization by a string value.
|
||||||
class StringInit : public TypedInit {
|
class StringInit : public TypedInit {
|
||||||
|
//// enum StringFormat {
|
||||||
|
//// SF_String, // Format as "text"
|
||||||
|
//// SF_Code, // Format as [{text}]
|
||||||
|
//// };
|
||||||
|
|
||||||
StringRef Value;
|
StringRef Value;
|
||||||
|
//// StringFormat Format;
|
||||||
|
|
||||||
explicit StringInit(StringRef V)
|
explicit StringInit(StringRef V)
|
||||||
: TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
|
: TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
|
||||||
@ -630,11 +636,10 @@ public:
|
|||||||
|
|
||||||
class CodeInit : public TypedInit {
|
class CodeInit : public TypedInit {
|
||||||
StringRef Value;
|
StringRef Value;
|
||||||
SMLoc Loc;
|
|
||||||
|
|
||||||
explicit CodeInit(StringRef V, const SMLoc &Loc)
|
explicit CodeInit(StringRef V)
|
||||||
: TypedInit(IK_CodeInit, static_cast<RecTy *>(CodeRecTy::get())),
|
: TypedInit(IK_CodeInit, static_cast<RecTy *>(CodeRecTy::get())),
|
||||||
Value(V), Loc(Loc) {}
|
Value(V) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CodeInit(const StringInit &) = delete;
|
CodeInit(const StringInit &) = delete;
|
||||||
@ -644,10 +649,9 @@ public:
|
|||||||
return I->getKind() == IK_CodeInit;
|
return I->getKind() == IK_CodeInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CodeInit *get(StringRef, const SMLoc &Loc);
|
static CodeInit *get(StringRef);
|
||||||
|
|
||||||
StringRef getValue() const { return Value; }
|
StringRef getValue() const { return Value; }
|
||||||
const SMLoc &getLoc() const { return Loc; }
|
|
||||||
|
|
||||||
Init *convertInitializerTo(RecTy *Ty) const override;
|
Init *convertInitializerTo(RecTy *Ty) const override;
|
||||||
|
|
||||||
@ -1649,6 +1653,9 @@ public:
|
|||||||
// High-level methods useful to tablegen back-ends
|
// High-level methods useful to tablegen back-ends
|
||||||
//
|
//
|
||||||
|
|
||||||
|
///Return the source location for the named field.
|
||||||
|
SMLoc getFieldLoc(StringRef FieldName) const;
|
||||||
|
|
||||||
/// Return the initializer for a value with the specified name,
|
/// Return the initializer for a value with the specified name,
|
||||||
/// or throw an exception if the field does not exist.
|
/// or throw an exception if the field does not exist.
|
||||||
Init *getValueInit(StringRef FieldName) const;
|
Init *getValueInit(StringRef FieldName) const;
|
||||||
|
@ -514,20 +514,13 @@ IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
|
|||||||
return BitsInit::get(NewBits);
|
return BitsInit::get(NewBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeInit *CodeInit::get(StringRef V, const SMLoc &Loc) {
|
CodeInit *CodeInit::get(StringRef V) {
|
||||||
static StringSet<BumpPtrAllocator &> ThePool(Allocator);
|
static StringMap<CodeInit*, BumpPtrAllocator &> ThePool(Allocator);
|
||||||
|
|
||||||
CodeInitsConstructed++;
|
auto &Entry = *ThePool.insert(std::make_pair(V, nullptr)).first;
|
||||||
|
if (!Entry.second)
|
||||||
// Unlike StringMap, StringSet doesn't accept empty keys.
|
Entry.second = new(Allocator) CodeInit(Entry.getKey());
|
||||||
if (V.empty())
|
return Entry.second;
|
||||||
return new (Allocator) CodeInit("", Loc);
|
|
||||||
|
|
||||||
// Location tracking prevents us from de-duping CodeInits as we're never
|
|
||||||
// called with the same string and same location twice. However, we can at
|
|
||||||
// least de-dupe the strings for a modest saving.
|
|
||||||
auto &Entry = *ThePool.insert(V).first;
|
|
||||||
return new(Allocator) CodeInit(Entry.getKey(), Loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringInit *StringInit::get(StringRef V) {
|
StringInit *StringInit::get(StringRef V) {
|
||||||
@ -543,7 +536,7 @@ Init *StringInit::convertInitializerTo(RecTy *Ty) const {
|
|||||||
if (isa<StringRecTy>(Ty))
|
if (isa<StringRecTy>(Ty))
|
||||||
return const_cast<StringInit *>(this);
|
return const_cast<StringInit *>(this);
|
||||||
if (isa<CodeRecTy>(Ty))
|
if (isa<CodeRecTy>(Ty))
|
||||||
return CodeInit::get(getValue(), SMLoc());
|
return CodeInit::get(getValue());
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -1046,8 +1039,6 @@ Init *BinOpInit::Fold(Record *CurRec) const {
|
|||||||
default: llvm_unreachable("unhandled comparison");
|
default: llvm_unreachable("unhandled comparison");
|
||||||
}
|
}
|
||||||
return BitInit::get(Result);
|
return BitInit::get(Result);
|
||||||
//// bool Equal = LHSs->getValue() == RHSs->getValue();
|
|
||||||
//// return BitInit::get(getOpcode() == EQ ? Equal : !Equal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, !eq and !ne can be used with records.
|
// Finally, !eq and !ne can be used with records.
|
||||||
@ -2170,7 +2161,7 @@ bool RecordVal::setValue(Init *V) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This version of setValue takes an source location and resets the
|
// This version of setValue takes a source location and resets the
|
||||||
// location in the RecordVal.
|
// location in the RecordVal.
|
||||||
bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
|
bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
|
||||||
Loc = NewLoc;
|
Loc = NewLoc;
|
||||||
@ -2351,6 +2342,14 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
|
|||||||
return OS << "}\n";
|
return OS << "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMLoc Record::getFieldLoc(StringRef FieldName) const {
|
||||||
|
const RecordVal *R = getValue(FieldName);
|
||||||
|
if (!R)
|
||||||
|
PrintFatalError(getLoc(), "Record `" + getName() +
|
||||||
|
"' does not have a field named `" + FieldName + "'!\n");
|
||||||
|
return R->getLoc();
|
||||||
|
}
|
||||||
|
|
||||||
Init *Record::getValueInit(StringRef FieldName) const {
|
Init *Record::getValueInit(StringRef FieldName) const {
|
||||||
const RecordVal *R = getValue(FieldName);
|
const RecordVal *R = getValue(FieldName);
|
||||||
if (!R || !R->getValue())
|
if (!R || !R->getValue())
|
||||||
|
@ -1920,7 +1920,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tgtok::CodeFragment:
|
case tgtok::CodeFragment:
|
||||||
R = CodeInit::get(Lex.getCurStrVal(), Lex.getLoc());
|
R = CodeInit::get(Lex.getCurStrVal());
|
||||||
Lex.Lex();
|
Lex.Lex();
|
||||||
break;
|
break;
|
||||||
case tgtok::question:
|
case tgtok::question:
|
||||||
|
@ -113,8 +113,8 @@ TEST(CodeExpander, NotAnExpansion) {
|
|||||||
.emit(OS);
|
.emit(OS);
|
||||||
EXPECT_EQ(OS.str(), " $foo");
|
EXPECT_EQ(OS.str(), " $foo");
|
||||||
DiagChecker.expect(SMDiagnostic(
|
DiagChecker.expect(SMDiagnostic(
|
||||||
SrcMgr, SMLoc::getFromPointer(In.data() + 1), "TestBuffer", 1, 1,
|
SrcMgr, SMLoc::getFromPointer(In.data()), "TestBuffer", 1, 0,
|
||||||
SourceMgr::DK_Warning, "Assuming missing escape character", " $foo", {}));
|
SourceMgr::DK_Warning, "Assuming missing escape character: \\$", " $foo", {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// \$foo is not an expansion but shouldn't warn as it's using the escape.
|
// \$foo is not an expansion but shouldn't warn as it's using the escape.
|
||||||
@ -162,27 +162,7 @@ TEST(CodeExpander, UndefinedExpansion) {
|
|||||||
EXPECT_EQ(OS.str(), "expansion");
|
EXPECT_EQ(OS.str(), "expansion");
|
||||||
DiagChecker.expect(
|
DiagChecker.expect(
|
||||||
SMDiagnostic(SrcMgr, SMLoc(), "<unknown>", 0, -1, SourceMgr::DK_Error,
|
SMDiagnostic(SrcMgr, SMLoc(), "<unknown>", 0, -1, SourceMgr::DK_Error,
|
||||||
"Attempting to expand an undeclared variable foo", "", {}));
|
"Attempt to expand an undeclared variable 'foo'", "", {}));
|
||||||
}
|
|
||||||
|
|
||||||
// ${foo} is an undefined expansion and should error. When given a valid
|
|
||||||
// location for the start of the buffer it should correctly point at the
|
|
||||||
// expansion being performed.
|
|
||||||
TEST(CodeExpander, UndefinedExpansionWithLoc) {
|
|
||||||
std::string Result;
|
|
||||||
raw_string_ostream OS(Result);
|
|
||||||
CodeExpansions Expansions;
|
|
||||||
Expansions.declare("bar", "expansion");
|
|
||||||
|
|
||||||
RAIIDiagnosticChecker DiagChecker;
|
|
||||||
StringRef In = bufferize("Padding ${foo}${bar}");
|
|
||||||
CodeExpander(In, Expansions, SMLoc::getFromPointer(In.data()), false)
|
|
||||||
.emit(OS);
|
|
||||||
EXPECT_EQ(OS.str(), "Padding expansion");
|
|
||||||
DiagChecker.expect(SMDiagnostic(
|
|
||||||
SrcMgr, SMLoc::getFromPointer(In.data() + 8), "TestBuffer", 1, 8,
|
|
||||||
SourceMgr::DK_Error, "Attempting to expand an undeclared variable foo",
|
|
||||||
"Padding ${foo}${bar}", {}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ${bar is an unterminated expansion. Warn and implicitly terminate it.
|
// ${bar is an unterminated expansion. Warn and implicitly terminate it.
|
||||||
@ -197,7 +177,7 @@ TEST(CodeExpander, UnterminatedExpansion) {
|
|||||||
CodeExpander(In, Expansions, SMLoc::getFromPointer(In.data()), false)
|
CodeExpander(In, Expansions, SMLoc::getFromPointer(In.data()), false)
|
||||||
.emit(OS);
|
.emit(OS);
|
||||||
EXPECT_EQ(OS.str(), " expansion");
|
EXPECT_EQ(OS.str(), " expansion");
|
||||||
DiagChecker.expect(SMDiagnostic(SrcMgr, SMLoc::getFromPointer(In.data() + 1),
|
DiagChecker.expect(SMDiagnostic(SrcMgr, SMLoc::getFromPointer(In.data()),
|
||||||
"TestBuffer", 1, 1, SourceMgr::DK_Warning,
|
"TestBuffer", 1, 0, SourceMgr::DK_Warning,
|
||||||
"Unterminated expansion", " ${bar", {}));
|
"Unterminated expansion '${bar'", " ${bar", {}));
|
||||||
}
|
}
|
||||||
|
@ -759,7 +759,7 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
|
|||||||
DagInit *Applyer = RuleDef.getValueAsDag("Apply");
|
DagInit *Applyer = RuleDef.getValueAsDag("Apply");
|
||||||
if (Applyer->getOperatorAsDef(RuleDef.getLoc())->getName() !=
|
if (Applyer->getOperatorAsDef(RuleDef.getLoc())->getName() !=
|
||||||
"apply") {
|
"apply") {
|
||||||
PrintError(RuleDef.getLoc(), "Expected apply operator");
|
PrintError(RuleDef.getLoc(), "Expected 'apply' operator in Apply DAG");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,7 +800,7 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
|
|||||||
OS << Indent << " && [&]() {\n"
|
OS << Indent << " && [&]() {\n"
|
||||||
<< Indent << " "
|
<< Indent << " "
|
||||||
<< CodeExpander(Rule->getMatchingFixupCode()->getValue(), Expansions,
|
<< CodeExpander(Rule->getMatchingFixupCode()->getValue(), Expansions,
|
||||||
Rule->getMatchingFixupCode()->getLoc(), ShowExpansions)
|
RuleDef.getLoc(), ShowExpansions)
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< Indent << " return true;\n"
|
<< Indent << " return true;\n"
|
||||||
<< Indent << " }()";
|
<< Indent << " }()";
|
||||||
@ -809,7 +809,7 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
|
|||||||
|
|
||||||
if (const CodeInit *Code = dyn_cast<CodeInit>(Applyer->getArg(0))) {
|
if (const CodeInit *Code = dyn_cast<CodeInit>(Applyer->getArg(0))) {
|
||||||
OS << CodeExpander(Code->getAsUnquotedString(), Expansions,
|
OS << CodeExpander(Code->getAsUnquotedString(), Expansions,
|
||||||
Code->getLoc(), ShowExpansions)
|
RuleDef.getLoc(), ShowExpansions)
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< Indent << " return true;\n"
|
<< Indent << " return true;\n"
|
||||||
<< Indent << " }\n";
|
<< Indent << " }\n";
|
||||||
|
@ -58,21 +58,15 @@ void CodeExpander::emit(raw_ostream &OS) const {
|
|||||||
// Warn if we split because no terminator was found.
|
// Warn if we split because no terminator was found.
|
||||||
StringRef EndVar = StartVar.drop_front(2 /* ${ */ + Var.size());
|
StringRef EndVar = StartVar.drop_front(2 /* ${ */ + Var.size());
|
||||||
if (EndVar.empty()) {
|
if (EndVar.empty()) {
|
||||||
size_t LocOffset = StartVar.data() - Code.data();
|
PrintWarning(Loc, "Unterminated expansion '${" + Var + "'");
|
||||||
PrintWarning(
|
PrintNote("Code: [{" + Code + "}]");
|
||||||
Loc.size() > 0 && Loc[0].isValid()
|
|
||||||
? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset)
|
|
||||||
: SMLoc(),
|
|
||||||
"Unterminated expansion");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ValueI = Expansions.find(Var);
|
auto ValueI = Expansions.find(Var);
|
||||||
if (ValueI == Expansions.end()) {
|
if (ValueI == Expansions.end()) {
|
||||||
size_t LocOffset = StartVar.data() - Code.data();
|
PrintError(Loc,
|
||||||
PrintError(Loc.size() > 0 && Loc[0].isValid()
|
"Attempt to expand an undeclared variable '" + Var + "'");
|
||||||
? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset)
|
PrintNote("Code: [{" + Code + "}]");
|
||||||
: SMLoc(),
|
|
||||||
"Attempting to expand an undeclared variable " + Var);
|
|
||||||
}
|
}
|
||||||
if (ShowExpansions)
|
if (ShowExpansions)
|
||||||
OS << "/*$" << Var << "{*/";
|
OS << "/*$" << Var << "{*/";
|
||||||
@ -82,11 +76,8 @@ void CodeExpander::emit(raw_ostream &OS) const {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t LocOffset = Current.data() - Code.data();
|
PrintWarning(Loc, "Assuming missing escape character: \\$");
|
||||||
PrintWarning(Loc.size() > 0 && Loc[0].isValid()
|
PrintNote("Code: [{" + Code + "}]");
|
||||||
? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset)
|
|
||||||
: SMLoc(),
|
|
||||||
"Assuming missing escape character");
|
|
||||||
OS << "$";
|
OS << "$";
|
||||||
Current = Current.drop_front(1);
|
Current = Current.drop_front(1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user