mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
Verifier: Add operand checks for MDLexicalBlock
Add operand checks for `MDLexicalBlock` and `MDLexicalBlockFile`. Like `MDLocalVariable` and `MDLocation`, these nodes always require a scope. There was no test bitrot to fix here (just updated the serialization tests in test/Assembler/mdlexicalblock.ll). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233561 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0c251f74ef
commit
d3ec0ca17e
@ -1129,7 +1129,12 @@ protected:
|
||||
~MDLexicalBlockBase() {}
|
||||
|
||||
public:
|
||||
Metadata *getScope() const { return getOperand(1); }
|
||||
// FIXME: Remove this once MDScope::getFile() does the same.
|
||||
MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
|
||||
|
||||
MDLocalScope *getScope() const { return cast<MDLocalScope>(getRawScope()); }
|
||||
|
||||
Metadata *getRawScope() const { return getOperand(1); }
|
||||
|
||||
static bool classof(const Metadata *MD) {
|
||||
return MD->getMetadataID() == MDLexicalBlockKind ||
|
||||
@ -1150,6 +1155,15 @@ class MDLexicalBlock : public MDLexicalBlockBase {
|
||||
Column(Column) {}
|
||||
~MDLexicalBlock() {}
|
||||
|
||||
static MDLexicalBlock *getImpl(LLVMContext &Context, MDLocalScope *Scope,
|
||||
MDFile *File, unsigned Line, unsigned Column,
|
||||
StorageType Storage,
|
||||
bool ShouldCreate = true) {
|
||||
return getImpl(Context, static_cast<Metadata *>(Scope),
|
||||
static_cast<Metadata *>(File), Line, Column, Storage,
|
||||
ShouldCreate);
|
||||
}
|
||||
|
||||
static MDLexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
|
||||
Metadata *File, unsigned Line, unsigned Column,
|
||||
StorageType Storage, bool ShouldCreate = true);
|
||||
@ -1160,6 +1174,9 @@ class MDLexicalBlock : public MDLexicalBlockBase {
|
||||
}
|
||||
|
||||
public:
|
||||
DEFINE_MDNODE_GET(MDLexicalBlock, (MDLocalScope * Scope, MDFile *File,
|
||||
unsigned Line, unsigned Column),
|
||||
(Scope, File, Line, Column))
|
||||
DEFINE_MDNODE_GET(MDLexicalBlock, (Metadata * Scope, Metadata *File,
|
||||
unsigned Line, unsigned Column),
|
||||
(Scope, File, Line, Column))
|
||||
@ -1186,6 +1203,15 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
|
||||
Discriminator(Discriminator) {}
|
||||
~MDLexicalBlockFile() {}
|
||||
|
||||
static MDLexicalBlockFile *getImpl(LLVMContext &Context, MDLocalScope *Scope,
|
||||
MDFile *File, unsigned Discriminator,
|
||||
StorageType Storage,
|
||||
bool ShouldCreate = true) {
|
||||
return getImpl(Context, static_cast<Metadata *>(Scope),
|
||||
static_cast<Metadata *>(File), Discriminator, Storage,
|
||||
ShouldCreate);
|
||||
}
|
||||
|
||||
static MDLexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
|
||||
Metadata *File, unsigned Discriminator,
|
||||
StorageType Storage,
|
||||
@ -1197,6 +1223,9 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
|
||||
}
|
||||
|
||||
public:
|
||||
DEFINE_MDNODE_GET(MDLexicalBlockFile, (MDLocalScope * Scope, MDFile *File,
|
||||
unsigned Discriminator),
|
||||
(Scope, File, Discriminator))
|
||||
DEFINE_MDNODE_GET(MDLexicalBlockFile,
|
||||
(Metadata * Scope, Metadata *File, unsigned Discriminator),
|
||||
(Scope, File, Discriminator))
|
||||
|
@ -3571,7 +3571,7 @@ bool LLParser::ParseMDSubprogram(MDNode *&Result, bool IsDistinct) {
|
||||
/// ::= !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 9)
|
||||
bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) {
|
||||
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
|
||||
REQUIRED(scope, MDField, ); \
|
||||
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
|
||||
OPTIONAL(file, MDField, ); \
|
||||
OPTIONAL(line, LineField, ); \
|
||||
OPTIONAL(column, ColumnField, );
|
||||
@ -3587,7 +3587,7 @@ bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) {
|
||||
/// ::= !MDLexicalBlockFile(scope: !0, file: !2, discriminator: 9)
|
||||
bool LLParser::ParseMDLexicalBlockFile(MDNode *&Result, bool IsDistinct) {
|
||||
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
|
||||
REQUIRED(scope, MDField, ); \
|
||||
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
|
||||
OPTIONAL(file, MDField, ); \
|
||||
REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX));
|
||||
PARSE_MD_FIELDS();
|
||||
|
@ -1654,8 +1654,8 @@ static void writeMDLexicalBlock(raw_ostream &Out, const MDLexicalBlock *N,
|
||||
const Module *Context) {
|
||||
Out << "!MDLexicalBlock(";
|
||||
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
|
||||
Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
|
||||
Printer.printMetadata("file", N->getFile());
|
||||
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
|
||||
Printer.printMetadata("file", N->getRawFile());
|
||||
Printer.printInt("line", N->getLine());
|
||||
Printer.printInt("column", N->getColumn());
|
||||
Out << ")";
|
||||
@ -1668,8 +1668,8 @@ static void writeMDLexicalBlockFile(raw_ostream &Out,
|
||||
const Module *Context) {
|
||||
Out << "!MDLexicalBlockFile(";
|
||||
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
|
||||
Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
|
||||
Printer.printMetadata("file", N->getFile());
|
||||
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
|
||||
Printer.printMetadata("file", N->getRawFile());
|
||||
Printer.printInt("discriminator", N->getDiscriminator(),
|
||||
/* ShouldSkipZero */ false);
|
||||
Out << ")";
|
||||
|
@ -272,6 +272,7 @@ MDLexicalBlock *MDLexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
|
||||
Metadata *File, unsigned Line,
|
||||
unsigned Column, StorageType Storage,
|
||||
bool ShouldCreate) {
|
||||
assert(Scope && "Expected scope");
|
||||
DEFINE_GETIMPL_LOOKUP(MDLexicalBlock, (Scope, File, Line, Column));
|
||||
Metadata *Ops[] = {File, Scope};
|
||||
DEFINE_GETIMPL_STORE(MDLexicalBlock, (Line, Column), Ops);
|
||||
@ -282,6 +283,7 @@ MDLexicalBlockFile *MDLexicalBlockFile::getImpl(LLVMContext &Context,
|
||||
unsigned Discriminator,
|
||||
StorageType Storage,
|
||||
bool ShouldCreate) {
|
||||
assert(Scope && "Expected scope");
|
||||
DEFINE_GETIMPL_LOOKUP(MDLexicalBlockFile, (Scope, File, Discriminator));
|
||||
Metadata *Ops[] = {File, Scope};
|
||||
DEFINE_GETIMPL_STORE(MDLexicalBlockFile, (Discriminator), Ops);
|
||||
|
@ -594,11 +594,11 @@ template <> struct MDNodeKeyImpl<MDLexicalBlock> {
|
||||
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
|
||||
: Scope(Scope), File(File), Line(Line), Column(Column) {}
|
||||
MDNodeKeyImpl(const MDLexicalBlock *N)
|
||||
: Scope(N->getScope()), File(N->getFile()), Line(N->getLine()),
|
||||
: Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
|
||||
Column(N->getColumn()) {}
|
||||
|
||||
bool isKeyOf(const MDLexicalBlock *RHS) const {
|
||||
return Scope == RHS->getScope() && File == RHS->getFile() &&
|
||||
return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
|
||||
Line == RHS->getLine() && Column == RHS->getColumn();
|
||||
}
|
||||
unsigned getHashValue() const {
|
||||
@ -614,11 +614,11 @@ template <> struct MDNodeKeyImpl<MDLexicalBlockFile> {
|
||||
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
|
||||
: Scope(Scope), File(File), Discriminator(Discriminator) {}
|
||||
MDNodeKeyImpl(const MDLexicalBlockFile *N)
|
||||
: Scope(N->getScope()), File(N->getFile()),
|
||||
: Scope(N->getRawScope()), File(N->getRawFile()),
|
||||
Discriminator(N->getDiscriminator()) {}
|
||||
|
||||
bool isKeyOf(const MDLexicalBlockFile *RHS) const {
|
||||
return Scope == RHS->getScope() && File == RHS->getFile() &&
|
||||
return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
|
||||
Discriminator == RHS->getDiscriminator();
|
||||
}
|
||||
unsigned getHashValue() const {
|
||||
|
@ -302,6 +302,7 @@ private:
|
||||
void visitMDScope(const MDScope &N);
|
||||
void visitMDDerivedTypeBase(const MDDerivedTypeBase &N);
|
||||
void visitMDVariable(const MDVariable &N);
|
||||
void visitMDLexicalBlockBase(const MDLexicalBlockBase &N);
|
||||
|
||||
// InstVisitor overrides...
|
||||
using InstVisitor<Verifier>::visit;
|
||||
@ -871,12 +872,21 @@ void Verifier::visitMDSubprogram(const MDSubprogram &N) {
|
||||
}
|
||||
}
|
||||
|
||||
void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) {
|
||||
void Verifier::visitMDLexicalBlockBase(const MDLexicalBlockBase &N) {
|
||||
Assert(N.getTag() == dwarf::DW_TAG_lexical_block, "invalid tag", &N);
|
||||
Assert(N.getRawScope() && isa<MDLocalScope>(N.getRawScope()),
|
||||
"invalid local scope", &N, N.getRawScope());
|
||||
}
|
||||
|
||||
void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) {
|
||||
visitMDLexicalBlockBase(N);
|
||||
|
||||
Assert(N.getLine() || !N.getColumn(),
|
||||
"cannot have column info without line info", &N);
|
||||
}
|
||||
|
||||
void Verifier::visitMDLexicalBlockFile(const MDLexicalBlockFile &N) {
|
||||
Assert(N.getTag() == dwarf::DW_TAG_lexical_block, "invalid tag", &N);
|
||||
visitMDLexicalBlockBase(N);
|
||||
}
|
||||
|
||||
void Verifier::visitMDNamespace(const MDNamespace &N) {
|
||||
|
4
test/Assembler/invalid-mdlexicalblock-null-scope.ll
Normal file
4
test/Assembler/invalid-mdlexicalblock-null-scope.ll
Normal file
@ -0,0 +1,4 @@
|
||||
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: <stdin>:[[@LINE+1]]:29: error: 'scope' cannot be null
|
||||
!0 = !MDLexicalBlock(scope: null)
|
4
test/Assembler/invalid-mdlexicalblockfile-null-scope.ll
Normal file
4
test/Assembler/invalid-mdlexicalblockfile-null-scope.ll
Normal file
@ -0,0 +1,4 @@
|
||||
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: <stdin>:[[@LINE+1]]:33: error: 'scope' cannot be null
|
||||
!0 = !MDLexicalBlockFile(scope: null)
|
@ -5,15 +5,15 @@
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
|
||||
|
||||
!0 = distinct !{}
|
||||
!1 = distinct !{}
|
||||
!1 = !MDSubprogram(name: "foo", scope: !2)
|
||||
!2 = !MDFile(filename: "path/to/file", directory: "/path/to/dir")
|
||||
|
||||
; CHECK: !3 = !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 35)
|
||||
!3 = !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 35)
|
||||
; CHECK: !3 = !MDLexicalBlock(scope: !1, file: !2, line: 7, column: 35)
|
||||
!3 = !MDLexicalBlock(scope: !1, file: !2, line: 7, column: 35)
|
||||
|
||||
; CHECK: !4 = !MDLexicalBlock(scope: !0)
|
||||
!4 = !MDLexicalBlock(scope: !0)
|
||||
!5 = !MDLexicalBlock(scope: !0, file: null, line: 0, column: 0)
|
||||
; CHECK: !4 = !MDLexicalBlock(scope: !1)
|
||||
!4 = !MDLexicalBlock(scope: !1)
|
||||
!5 = !MDLexicalBlock(scope: !1, file: null, line: 0, column: 0)
|
||||
|
||||
; CHECK: !5 = !MDLexicalBlockFile(scope: !3, file: !2, discriminator: 0)
|
||||
; CHECK: !6 = !MDLexicalBlockFile(scope: !3, file: !2, discriminator: 1)
|
||||
|
@ -299,7 +299,9 @@ TEST_F(IRBuilderTest, DIBuilder) {
|
||||
false, true, 1, 0, true, F);
|
||||
EXPECT_TRUE(SP.Verify());
|
||||
AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
|
||||
auto BadScope = DIB.createLexicalBlockFile(DIDescriptor(), File, 0);
|
||||
auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1,
|
||||
0, true, nullptr);
|
||||
auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
|
||||
I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
|
||||
EXPECT_FALSE(SP.Verify());
|
||||
DIB.finalize();
|
||||
|
@ -1555,8 +1555,8 @@ TEST_F(MDSubprogramTest, replaceFunction) {
|
||||
typedef MetadataTest MDLexicalBlockTest;
|
||||
|
||||
TEST_F(MDLexicalBlockTest, get) {
|
||||
Metadata *Scope = MDTuple::getDistinct(Context, None);
|
||||
Metadata *File = MDTuple::getDistinct(Context, None);
|
||||
MDLocalScope *Scope = getSubprogram();
|
||||
MDFile *File = getFile();
|
||||
unsigned Line = 5;
|
||||
unsigned Column = 8;
|
||||
|
||||
@ -1569,8 +1569,9 @@ TEST_F(MDLexicalBlockTest, get) {
|
||||
EXPECT_EQ(Column, N->getColumn());
|
||||
EXPECT_EQ(N, MDLexicalBlock::get(Context, Scope, File, Line, Column));
|
||||
|
||||
EXPECT_NE(N, MDLexicalBlock::get(Context, File, File, Line, Column));
|
||||
EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, Scope, Line, Column));
|
||||
EXPECT_NE(N,
|
||||
MDLexicalBlock::get(Context, getSubprogram(), File, Line, Column));
|
||||
EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, getFile(), Line, Column));
|
||||
EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, File, Line + 1, Column));
|
||||
EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, File, Line, Column + 1));
|
||||
|
||||
@ -1581,8 +1582,8 @@ TEST_F(MDLexicalBlockTest, get) {
|
||||
typedef MetadataTest MDLexicalBlockFileTest;
|
||||
|
||||
TEST_F(MDLexicalBlockFileTest, get) {
|
||||
Metadata *Scope = MDTuple::getDistinct(Context, None);
|
||||
Metadata *File = MDTuple::getDistinct(Context, None);
|
||||
MDLocalScope *Scope = getSubprogram();
|
||||
MDFile *File = getFile();
|
||||
unsigned Discriminator = 5;
|
||||
|
||||
auto *N = MDLexicalBlockFile::get(Context, Scope, File, Discriminator);
|
||||
@ -1593,8 +1594,10 @@ TEST_F(MDLexicalBlockFileTest, get) {
|
||||
EXPECT_EQ(Discriminator, N->getDiscriminator());
|
||||
EXPECT_EQ(N, MDLexicalBlockFile::get(Context, Scope, File, Discriminator));
|
||||
|
||||
EXPECT_NE(N, MDLexicalBlockFile::get(Context, File, File, Discriminator));
|
||||
EXPECT_NE(N, MDLexicalBlockFile::get(Context, Scope, Scope, Discriminator));
|
||||
EXPECT_NE(N, MDLexicalBlockFile::get(Context, getSubprogram(), File,
|
||||
Discriminator));
|
||||
EXPECT_NE(N,
|
||||
MDLexicalBlockFile::get(Context, Scope, getFile(), Discriminator));
|
||||
EXPECT_NE(N,
|
||||
MDLexicalBlockFile::get(Context, Scope, File, Discriminator + 1));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user