IR: Add missing API to specialized metadata nodes

Add the final bits of API that `DIBuilder` needs before the new nodes
can be moved into place.

  - Add `MDType::clone()` and `MDType::setFlags()` to support
    `DIBuilder::createTypeWithFlags()`.
  - Add `MDBasicType::get()` overload that just requires a tag and a
    name, as a convenience for `DIBuilder::createUnspecifiedType()`.
  - Add `MDLocalVariable::withInline()` and
    `MDLocalVariable::withoutInline()` to support
    `llvm::createInlinedVariable()` and
    `llvm::cleanseInlinedVariable()`.

(Somehow these got lost inside the "move into place" patch I'm about to
commit -- better to commit separately!)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231079 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-03-03 16:45:34 +00:00
parent 6800198300
commit 853cd2630e
2 changed files with 82 additions and 1 deletions

View File

@ -382,6 +382,10 @@ protected:
~MDType() {}
public:
TempMDType clone() const {
return TempMDType(cast<MDType>(MDNode::clone().release()));
}
unsigned getLine() const { return Line; }
uint64_t getSizeInBits() const { return SizeInBits; }
uint64_t getAlignInBits() const { return AlignInBits; }
@ -393,6 +397,11 @@ public:
MDString *getRawName() const { return getOperandAs<MDString>(2); }
void setFlags(unsigned NewFlags) {
assert(!isUniqued() && "Cannot set flags on uniqued nodes");
Flags = NewFlags;
}
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
@ -442,6 +451,8 @@ class MDBasicType : public MDType {
}
public:
DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name),
(Tag, Name, 0, 0, 0))
DEFINE_MDNODE_GET(MDBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint64_t AlignInBits, unsigned Encoding),
@ -1416,6 +1427,18 @@ public:
unsigned getFlags() const { return Flags; }
Metadata *getInlinedAt() const { return getOperand(4); }
/// \brief Get an inlined version of this variable.
///
/// Returns a version of this with \a getAlinedAt() set to \c InlinedAt.
MDLocalVariable *withInline(MDLocation *InlinedAt) const {
if (InlinedAt == getInlinedAt())
return const_cast<MDLocalVariable *>(this);
auto Temp = clone();
Temp->replaceOperandWith(4, InlinedAt);
return replaceWithUniqued(std::move(Temp));
}
MDLocalVariable *withoutInline() const { return withInline(nullptr); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDLocalVariableKind;
}

View File

@ -9,6 +9,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
@ -730,6 +731,48 @@ TEST_F(MDBasicTypeTest, getWithLargeValues) {
EXPECT_EQ(UINT64_MAX - 1, N->getAlignInBits());
}
TEST_F(MDBasicTypeTest, getUnspecified) {
auto *N =
MDBasicType::get(Context, dwarf::DW_TAG_unspecified_type, "unspecified");
EXPECT_EQ(dwarf::DW_TAG_unspecified_type, N->getTag());
EXPECT_EQ("unspecified", N->getName());
EXPECT_EQ(0u, N->getSizeInBits());
EXPECT_EQ(0u, N->getAlignInBits());
EXPECT_EQ(0u, N->getEncoding());
EXPECT_EQ(0u, N->getLine());
}
typedef MetadataTest MDTypeTest;
TEST_F(MDTypeTest, clone) {
// Check that MDType has a specialized clone that returns TempMDType.
MDType *N = MDBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32,
dwarf::DW_ATE_signed);
TempMDType Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
}
TEST_F(MDTypeTest, setFlags) {
// void (void)
Metadata *TypesOps[] = {nullptr};
Metadata *Types = MDTuple::get(Context, TypesOps);
MDType *D = MDSubroutineType::getDistinct(Context, 0u, Types);
EXPECT_EQ(0u, D->getFlags());
D->setFlags(DIDescriptor::FlagRValueReference);
EXPECT_EQ(DIDescriptor::FlagRValueReference, D->getFlags());
D->setFlags(0u);
EXPECT_EQ(0u, D->getFlags());
TempMDType T = MDSubroutineType::getTemporary(Context, 0u, Types);
EXPECT_EQ(0u, T->getFlags());
T->setFlags(DIDescriptor::FlagRValueReference);
EXPECT_EQ(DIDescriptor::FlagRValueReference, T->getFlags());
T->setFlags(0u);
EXPECT_EQ(0u, T->getFlags());
}
typedef MetadataTest MDDerivedTypeTest;
TEST_F(MDDerivedTypeTest, get) {
@ -1574,7 +1617,9 @@ TEST_F(MDLocalVariableTest, get) {
Metadata *Type = MDTuple::getDistinct(Context, None);
unsigned Arg = 6;
unsigned Flags = 7;
Metadata *InlinedAt = MDTuple::getDistinct(Context, None);
Metadata *InlinedAtScope = MDTuple::getDistinct(Context, None);
Metadata *InlinedAt =
MDLocation::getDistinct(Context, 10, 20, InlinedAtScope);
auto *N = MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
Arg, Flags, InlinedAt);
@ -1612,6 +1657,19 @@ TEST_F(MDLocalVariableTest, get) {
TempMDLocalVariable Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
auto *Inlined = N->withoutInline();
EXPECT_NE(N, Inlined);
EXPECT_EQ(N->getTag(), Inlined->getTag());
EXPECT_EQ(N->getScope(), Inlined->getScope());
EXPECT_EQ(N->getName(), Inlined->getName());
EXPECT_EQ(N->getFile(), Inlined->getFile());
EXPECT_EQ(N->getLine(), Inlined->getLine());
EXPECT_EQ(N->getType(), Inlined->getType());
EXPECT_EQ(N->getArg(), Inlined->getArg());
EXPECT_EQ(N->getFlags(), Inlined->getFlags());
EXPECT_EQ(nullptr, Inlined->getInlinedAt());
EXPECT_EQ(N, Inlined->withInline(cast<MDLocation>(InlinedAt)));
}
typedef MetadataTest MDExpressionTest;