Generate btf_tag annotations for DIGlobalVariable.
A field "annotations" is introduced to DIGlobalVariable, and
annotations are represented as an DINodeArray, similar to
DIComposite elements. The following example illustrates how
annotations are encoded in IR:
distinct !DIGlobalVariable(..., annotations: !10)
!10 = !{!11, !12}
!11 = !{!"btf_tag", !"a"}
!12 = !{!"btf_tag", !"b"}
Differential Revision: https://reviews.llvm.org/D106619
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DIType *Ty, bool IsLocalToUnit, bool isDefined = true,
DIExpression *Expr = nullptr, MDNode *Decl = nullptr,
- MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0);
+ MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0,
+ DINodeArray Annotations = nullptr);
/// Identical to createGlobalVariable
/// except that the resulting DbgNode is temporary and meant to be RAUWed.
StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type,
bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
- uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) {
+ uint32_t AlignInBits, DINodeArray Annotations, StorageType Storage,
+ bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
- cast_or_null<Metadata>(TemplateParams), AlignInBits, Storage,
- ShouldCreate);
+ cast_or_null<Metadata>(TemplateParams), AlignInBits,
+ Annotations.get(), Storage, ShouldCreate);
}
static DIGlobalVariable *
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
- uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true);
+ uint32_t AlignInBits, Metadata *Annotations, StorageType Storage,
+ bool ShouldCreate = true);
TempDIGlobalVariable cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
getFile(), getLine(), getType(), isLocalToUnit(),
isDefinition(), getStaticDataMemberDeclaration(),
- getTemplateParams(), getAlignInBits());
+ getTemplateParams(), getAlignInBits(),
+ getAnnotations());
}
public:
DIFile *File, unsigned Line, DIType *Type,
bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration,
- MDTuple *TemplateParams, uint32_t AlignInBits),
+ MDTuple *TemplateParams, uint32_t AlignInBits,
+ DINodeArray Annotations),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, TemplateParams,
- AlignInBits))
+ AlignInBits, Annotations))
DEFINE_MDNODE_GET(DIGlobalVariable,
(Metadata * Scope, MDString *Name, MDString *LinkageName,
Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration,
- Metadata *TemplateParams, uint32_t AlignInBits),
+ Metadata *TemplateParams, uint32_t AlignInBits,
+ Metadata *Annotations),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, TemplateParams,
- AlignInBits))
+ AlignInBits, Annotations))
TempDIGlobalVariable clone() const { return cloneImpl(); }
DIDerivedType *getStaticDataMemberDeclaration() const {
return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
}
+ DINodeArray getAnnotations() const {
+ return cast_or_null<MDTuple>(getRawAnnotations());
+ }
MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
Metadata *getRawTemplateParams() const { return getOperand(7); }
MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
+ Metadata *getRawAnnotations() const { return getOperand(8); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIGlobalVariableKind;
OPTIONAL(isDefinition, MDBoolField, (true)); \
OPTIONAL(templateParams, MDField, ); \
OPTIONAL(declaration, MDField, ); \
- OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
+ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(annotations, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
GET_OR_DISTINCT(DIGlobalVariable,
(Context, scope.Val, name.Val, linkageName.Val, file.Val,
line.Val, type.Val, isLocal.Val, isDefinition.Val,
- declaration.Val, templateParams.Val, align.Val));
+ declaration.Val, templateParams.Val, align.Val,
+ annotations.Val));
return false;
}
unsigned Version = Record[0] >> 1;
if (Version == 2) {
+ Metadata *Annotations = nullptr;
+ if (Record.size() > 12)
+ Annotations = getMDOrNull(Record[12]);
+
MetadataList.assignValue(
GET_OR_DISTINCT(
DIGlobalVariable,
(Context, getMDOrNull(Record[1]), getMDString(Record[2]),
getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- getMDOrNull(Record[9]), getMDOrNull(Record[10]), Record[11])),
+ getMDOrNull(Record[9]), getMDOrNull(Record[10]), Record[11],
+ Annotations)),
NextMetadataNo);
NextMetadataNo++;
getMDString(Record[2]), getMDString(Record[3]),
getMDOrNull(Record[4]), Record[5],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- getMDOrNull(Record[10]), nullptr, Record[11])),
+ getMDOrNull(Record[10]), nullptr, Record[11],
+ nullptr)),
NextMetadataNo);
NextMetadataNo++;
(Context, getMDOrNull(Record[1]), getMDString(Record[2]),
getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- getMDOrNull(Record[10]), nullptr, AlignInBits));
+ getMDOrNull(Record[10]), nullptr, AlignInBits, nullptr));
DIGlobalVariableExpression *DGVE = nullptr;
if (Attach || Expr)
Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration()));
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams()));
Record.push_back(N->getAlignInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get()));
Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev);
Record.clear();
Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printInt("align", N->getAlignInBits());
+ Printer.printMetadata("annotations", N->getRawAnnotations());
Out << ")";
}
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
unsigned LineNumber, DIType *Ty, bool IsLocalToUnit,
bool isDefined, DIExpression *Expr,
- MDNode *Decl, MDTuple *TemplateParams, uint32_t AlignInBits) {
+ MDNode *Decl, MDTuple *TemplateParams, uint32_t AlignInBits,
+ DINodeArray Annotations) {
checkGlobalVariableScope(Context);
auto *GV = DIGlobalVariable::getDistinct(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
LineNumber, Ty, IsLocalToUnit, isDefined, cast_or_null<DIDerivedType>(Decl),
- TemplateParams, AlignInBits);
+ TemplateParams, AlignInBits, Annotations);
if (!Expr)
Expr = createExpression();
auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr);
return DIGlobalVariable::getTemporary(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
LineNumber, Ty, IsLocalToUnit, false,
- cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits)
+ cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,
+ nullptr)
.release();
}
Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration,
Metadata *TemplateParams, uint32_t AlignInBits,
- StorageType Storage, bool ShouldCreate) {
+ Metadata *Annotations, StorageType Storage,
+ bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
- TemplateParams, AlignInBits));
+ TemplateParams, AlignInBits,
+ Annotations));
Metadata *Ops[] = {Scope,
Name,
File,
Name,
LinkageName,
StaticDataMemberDeclaration,
- TemplateParams};
+ TemplateParams,
+ Annotations};
DEFINE_GETIMPL_STORE(DIGlobalVariable,
(Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
}
Metadata *StaticDataMemberDeclaration;
Metadata *TemplateParams;
uint32_t AlignInBits;
+ Metadata *Annotations;
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
- uint32_t AlignInBits)
+ uint32_t AlignInBits, Metadata *Annotations)
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
IsDefinition(IsDefinition),
StaticDataMemberDeclaration(StaticDataMemberDeclaration),
- TemplateParams(TemplateParams), AlignInBits(AlignInBits) {}
+ TemplateParams(TemplateParams), AlignInBits(AlignInBits),
+ Annotations(Annotations) {}
MDNodeKeyImpl(const DIGlobalVariable *N)
: Scope(N->getRawScope()), Name(N->getRawName()),
LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
TemplateParams(N->getRawTemplateParams()),
- AlignInBits(N->getAlignInBits()) {}
+ AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
bool isKeyOf(const DIGlobalVariable *RHS) const {
return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
StaticDataMemberDeclaration ==
RHS->getRawStaticDataMemberDeclaration() &&
TemplateParams == RHS->getRawTemplateParams() &&
- AlignInBits == RHS->getAlignInBits();
+ AlignInBits == RHS->getAlignInBits() &&
+ Annotations == RHS->getRawAnnotations();
}
unsigned getHashValue() const {
// TODO: make hashing work fine with such situations
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
IsLocalToUnit, IsDefinition, /* AlignInBits, */
- StaticDataMemberDeclaration);
+ StaticDataMemberDeclaration, Annotations);
}
};
--- /dev/null
+; REQUIRES: x86-registered-target
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+%struct.t1 = type { i32 }
+
+@g1 = dso_local global %struct.t1 zeroinitializer, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!13, !14, !15, !16, !17}
+!llvm.ident = !{!18}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g1", scope: !2, file: !3, line: 7, type: !6, isLocal: false, isDefinition: true, annotations: !10)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 47af5574a87dc298b5c6c36ff6a969c8c77c8499)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "t.c", directory: "/home/yhs/work/tests/llvm/btf_tag")
+!4 = !{}
+!5 = !{!0}
+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 4, size: 32, elements: !7)
+!7 = !{!8}
+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !3, line: 5, baseType: !9, size: 32)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = !{!11, !12}
+!11 = !{!"btf_tag", !"tag1"}
+!12 = !{!"btf_tag", !"tag2"}
+
+; CHECK: distinct !DIGlobalVariable(name: "g1"
+; CHECK-SAME: annotations: ![[ANNOT:[0-9]+]]
+; CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
+; CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
+; CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}
+
+!13 = !{i32 7, !"Dwarf Version", i32 4}
+!14 = !{i32 2, !"Debug Info Version", i32 3}
+!15 = !{i32 1, !"wchar_size", i32 4}
+!16 = !{i32 7, !"uwtable", i32 1}
+!17 = !{i32 7, !"frame-pointer", i32 2}
+!18 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 47af5574a87dc298b5c6c36ff6a969c8c77c8499)"}
auto *N = DIGlobalVariable::get(
Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
- IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits);
+ IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits,
+ nullptr);
EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag());
EXPECT_EQ(Scope, N->getScope());
EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(
Context, getSubprogram(), Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition,
- StaticDataMemberDeclaration, templateParams, AlignInBits));
+ StaticDataMemberDeclaration, templateParams, AlignInBits,
+ nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line,
Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName,
getFile(), Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration,
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line + 1, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration,
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, getDerivedType(), IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration,
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, !IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, !IsDefinition,
StaticDataMemberDeclaration,
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
cast<DIDerivedType>(getDerivedType()),
- templateParams, AlignInBits));
+ templateParams, AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, nullptr,
- AlignInBits));
+ AlignInBits, nullptr));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
- templateParams, (AlignInBits << 1)));
+ templateParams, (AlignInBits << 1),
+ nullptr));
TempDIGlobalVariable Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
auto *Var = DIGlobalVariable::get(
Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
- IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits);
+ IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits,
+ nullptr);
auto *Var2 = DIGlobalVariable::get(
Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit,
- IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits);
+ IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits,
+ nullptr);
auto *N = DIGlobalVariableExpression::get(Context, Var, Expr);
EXPECT_EQ(Var, N->getVariable());