1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

Emit template type and value parameter DIEs for template variables.

Summary:
Ensure the TemplateParam attribute of the DIGlobalVariable node is translated into the proper DIEs.

Resolves https://bugs.llvm.org/show_bug.cgi?id=22119

Reviewers: dblaikie, probinson, aprantl, JDevlieghere, clayborg, whitequark, deadalnix

Reviewed By: dblaikie

Subscribers: llvm-commits

Tags: #debug-info

Differential Revision: https://reviews.llvm.org/D52057

llvm-svn: 343706
This commit is contained in:
Matthew Voss 2018-10-03 18:44:53 +00:00
parent 05b23382bf
commit 843987e0bf
16 changed files with 249 additions and 202 deletions

View File

@ -1007,21 +1007,15 @@ LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder,
* \param Expr The location of the global relative to the attached
* GlobalVariable.
* \param Decl Reference to the corresponding declaration.
* variables.
* \param AlignInBits Variable alignment(or 0 if no alignment attr was
* specified)
*/
LLVMMetadataRef
LLVMDIBuilderCreateGlobalVariableExpression(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
const char *Name, size_t NameLen,
const char *Linkage, size_t LinkLen,
LLVMMetadataRef File,
unsigned LineNo,
LLVMMetadataRef Ty,
LLVMBool LocalToUnit,
LLVMMetadataRef Expr,
LLVMMetadataRef Decl,
uint32_t AlignInBits);
LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File,
unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits);
/**
* Create a new temporary \c MDNode. Suitable for use in constructing cyclic
* \c MDNode structures. A temporary \c MDNode is not uniqued, may be RAUW'd,
@ -1067,17 +1061,11 @@ void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef TempTargetMetadata,
* \param AlignInBits Variable alignment(or 0 if no alignment attr was
* specified)
*/
LLVMMetadataRef
LLVMDIBuilderCreateTempGlobalVariableFwdDecl(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
const char *Name, size_t NameLen,
const char *Linkage, size_t LnkLen,
LLVMMetadataRef File,
unsigned LineNo,
LLVMMetadataRef Ty,
LLVMBool LocalToUnit,
LLVMMetadataRef Decl,
uint32_t AlignInBits);
LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File,
unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
LLVMMetadataRef Decl, uint32_t AlignInBits);
/**
* Insert a new llvm.dbg.declare intrinsic call before the given instruction.

View File

@ -583,14 +583,14 @@ namespace llvm {
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DIType *Ty, bool isLocalToUnit,
DIExpression *Expr = nullptr, MDNode *Decl = nullptr,
uint32_t AlignInBits = 0);
MDTuple *templateParams = nullptr, uint32_t AlignInBits = 0);
/// Identical to createGlobalVariable
/// except that the resulting DbgNode is temporary and meant to be RAUWed.
DIGlobalVariable *createTempGlobalVariableFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DIType *Ty, bool isLocalToUnit, MDNode *Decl = nullptr,
uint32_t AlignInBits = 0);
MDTuple *templateParams = nullptr, uint32_t AlignInBits = 0);
/// Create a new descriptor for an auto variable. This is a local variable
/// that is not a subprogram parameter.

View File

@ -2534,30 +2534,30 @@ class DIGlobalVariable : public DIVariable {
IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
~DIGlobalVariable() = default;
static DIGlobalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
StringRef Name, StringRef LinkageName,
DIFile *File, unsigned Line, DITypeRef Type,
bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration,
uint32_t AlignInBits, StorageType Storage,
bool ShouldCreate = true) {
static DIGlobalVariable *
getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type,
bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
AlignInBits, Storage, ShouldCreate);
cast_or_null<Metadata>(TemplateParams), AlignInBits, 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, uint32_t AlignInBits,
StorageType Storage, bool ShouldCreate = true);
Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true);
TempDIGlobalVariable cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
getFile(), getLine(), getType(), isLocalToUnit(),
isDefinition(), getStaticDataMemberDeclaration(),
getAlignInBits());
getTemplateParams(), getAlignInBits());
}
public:
@ -2566,17 +2566,19 @@ public:
DIFile *File, unsigned Line, DITypeRef Type,
bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration,
uint32_t AlignInBits),
MDTuple *TemplateParams, uint32_t AlignInBits),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, AlignInBits))
IsDefinition, StaticDataMemberDeclaration, TemplateParams,
AlignInBits))
DEFINE_MDNODE_GET(DIGlobalVariable,
(Metadata * Scope, MDString *Name, MDString *LinkageName,
Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration,
uint32_t AlignInBits),
Metadata *TemplateParams, uint32_t AlignInBits),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, AlignInBits))
IsDefinition, StaticDataMemberDeclaration, TemplateParams,
AlignInBits))
TempDIGlobalVariable clone() const { return cloneImpl(); }
@ -2590,6 +2592,8 @@ public:
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); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIGlobalVariableKind;

View File

@ -4664,7 +4664,8 @@ bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) {
/// ParseDIGlobalVariable:
/// ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo",
/// file: !1, line: 7, type: !2, isLocal: false,
/// isDefinition: true, declaration: !3, align: 8)
/// isDefinition: true, templateParams: !3,
/// declaration: !4, align: 8)
bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \
@ -4675,15 +4676,17 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
OPTIONAL(type, MDField, ); \
OPTIONAL(isLocal, MDBoolField, ); \
OPTIONAL(isDefinition, MDBoolField, (true)); \
OPTIONAL(templateParams, MDField, ); \
OPTIONAL(declaration, MDField, ); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(DIGlobalVariable,
(Context, scope.Val, name.Val, linkageName.Val,
file.Val, line.Val, type.Val, isLocal.Val,
isDefinition.Val, declaration.Val, align.Val));
Result =
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));
return false;
}

View File

@ -1562,21 +1562,35 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_GLOBAL_VAR: {
if (Record.size() < 11 || Record.size() > 12)
if (Record.size() < 11 || Record.size() > 13)
return error("Invalid record");
IsDistinct = Record[0] & 1;
unsigned Version = Record[0] >> 1;
if (Version == 1) {
if (Version == 2) {
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])),
NextMetadataNo);
NextMetadataNo++;
} else if (Version == 1) {
// No upgrade necessary. A null field will be introduced to indicate
// that no parameter information is available.
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[10]), Record[11])),
getMDOrNull(Record[10]), nullptr, Record[11])),
NextMetadataNo);
NextMetadataNo++;
} else if (Version == 0) {
// Upgrade old metadata, which stored a global variable reference or a
@ -1607,7 +1621,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
(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]), AlignInBits));
getMDOrNull(Record[10]), nullptr, AlignInBits));
DIGlobalVariableExpression *DGVE = nullptr;
if (Attach || Expr)

View File

@ -1745,7 +1745,7 @@ void ModuleBitcodeWriter::writeDITemplateValueParameter(
void ModuleBitcodeWriter::writeDIGlobalVariable(
const DIGlobalVariable *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
const uint64_t Version = 1 << 1;
const uint64_t Version = 2 << 1;
Record.push_back((uint64_t)N->isDistinct() | Version);
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
@ -1755,8 +1755,8 @@ void ModuleBitcodeWriter::writeDIGlobalVariable(
Record.push_back(VE.getMetadataOrNullID(N->getType()));
Record.push_back(N->isLocalToUnit());
Record.push_back(N->isDefinition());
Record.push_back(/* expr */ 0);
Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration()));
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams()));
Record.push_back(N->getAlignInBits());
Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev);

View File

@ -160,6 +160,9 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
AlignInBytes);
if (MDTuple *TP = GV->getTemplateParams())
addTemplateParams(*VariableDIE, DINodeArray(TP));
// Add location.
bool addToAccelTable = false;
DIELoc *Loc = nullptr;

View File

@ -2059,6 +2059,7 @@ static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
Printer.printBool("isLocal", N->isLocalToUnit());
Printer.printBool("isDefinition", N->isDefinition());
Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printInt("align", N->getAlignInBits());
Out << ")";
}

View File

@ -639,13 +639,13 @@ static void checkGlobalVariableScope(DIScope *Context) {
DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr,
MDNode *Decl, uint32_t AlignInBits) {
MDNode *Decl, MDTuple *templateParams, uint32_t AlignInBits) {
checkGlobalVariableScope(Context);
auto *GV = DIGlobalVariable::getDistinct(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
LineNumber, Ty, isLocalToUnit, true, cast_or_null<DIDerivedType>(Decl),
AlignInBits);
templateParams, AlignInBits);
if (!Expr)
Expr = createExpression();
auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr);
@ -656,13 +656,13 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(
DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
unsigned LineNumber, DIType *Ty, bool isLocalToUnit, MDNode *Decl,
uint32_t AlignInBits) {
MDTuple *templateParams, uint32_t AlignInBits) {
checkGlobalVariableScope(Context);
return DIGlobalVariable::getTemporary(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
LineNumber, Ty, isLocalToUnit, false,
cast_or_null<DIDerivedType>(Decl), AlignInBits)
cast_or_null<DIDerivedType>(Decl), templateParams, AlignInBits)
.release();
}

View File

@ -1220,23 +1220,16 @@ LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder,
return wrap(unwrap(Builder)->createConstantValueExpression(Value));
}
LLVMMetadataRef
LLVMDIBuilderCreateGlobalVariableExpression(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
const char *Name, size_t NameLen,
const char *Linkage, size_t LinkLen,
LLVMMetadataRef File,
unsigned LineNo,
LLVMMetadataRef Ty,
LLVMBool LocalToUnit,
LLVMMetadataRef Expr,
LLVMMetadataRef Decl,
uint32_t AlignInBits) {
LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File,
unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits) {
return wrap(unwrap(Builder)->createGlobalVariableExpression(
unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LinkLen},
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty),
LocalToUnit, unwrap<DIExpression>(Expr),
unwrapDI<MDNode>(Decl), AlignInBits));
unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LinkLen},
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,
unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl),
nullptr, AlignInBits));
}
LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef Ctx, LLVMMetadataRef *Data,
@ -1256,26 +1249,21 @@ void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef TargetMetadata,
MDNode::deleteTemporary(Node);
}
LLVMMetadataRef
LLVMDIBuilderCreateTempGlobalVariableFwdDecl(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
const char *Name, size_t NameLen,
const char *Linkage, size_t LnkLen,
LLVMMetadataRef File,
unsigned LineNo,
LLVMMetadataRef Ty,
LLVMBool LocalToUnit,
LLVMMetadataRef Decl,
uint32_t AlignInBits) {
LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File,
unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
LLVMMetadataRef Decl, uint32_t AlignInBits) {
return wrap(unwrap(Builder)->createTempGlobalVariableFwdDecl(
unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LnkLen},
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty),
LocalToUnit, unwrapDI<MDNode>(Decl), AlignInBits));
unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LnkLen},
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,
unwrapDI<MDNode>(Decl), nullptr, AlignInBits));
}
LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo,
LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMValueRef Instr) {
LLVMValueRef
LLVMDIBuilderInsertDeclareBefore(LLVMDIBuilderRef Builder, LLVMValueRef Storage,
LLVMMetadataRef VarInfo, LLVMMetadataRef Expr,
LLVMMetadataRef DL, LLVMValueRef Instr) {
return wrap(unwrap(Builder)->insertDeclare(
unwrap(Storage), unwrap<DILocalVariable>(VarInfo),
unwrap<DIExpression>(Expr), unwrap<DILocation>(DL),

View File

@ -653,19 +653,24 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line,
Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration,
uint32_t AlignInBits, StorageType Storage,
bool ShouldCreate) {
Metadata *TemplateParams, uint32_t AlignInBits,
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, AlignInBits));
Metadata *Ops[] = {
Scope, Name, File, Type, Name, LinkageName, StaticDataMemberDeclaration};
DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
TemplateParams, AlignInBits));
Metadata *Ops[] = {Scope,
Name,
File,
Type,
Name,
LinkageName,
StaticDataMemberDeclaration,
TemplateParams};
DEFINE_GETIMPL_STORE(DIGlobalVariable,
(Line, IsLocalToUnit, IsDefinition, AlignInBits),
Ops);
(Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
}
DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope,

View File

@ -870,23 +870,26 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
bool IsLocalToUnit;
bool IsDefinition;
Metadata *StaticDataMemberDeclaration;
Metadata *TemplateParams;
uint32_t AlignInBits;
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration, uint32_t AlignInBits)
Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
uint32_t AlignInBits)
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
IsDefinition(IsDefinition),
StaticDataMemberDeclaration(StaticDataMemberDeclaration),
AlignInBits(AlignInBits) {}
TemplateParams(TemplateParams), AlignInBits(AlignInBits) {}
MDNodeKeyImpl(const DIGlobalVariable *N)
: Scope(N->getRawScope()), Name(N->getRawName()),
LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
Line(N->getLine()), Type(N->getRawType()),
IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
TemplateParams(N->getRawTemplateParams()),
AlignInBits(N->getAlignInBits()) {}
bool isKeyOf(const DIGlobalVariable *RHS) const {
@ -897,6 +900,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
IsDefinition == RHS->isDefinition() &&
StaticDataMemberDeclaration ==
RHS->getRawStaticDataMemberDeclaration() &&
TemplateParams == RHS->getRawTemplateParams() &&
AlignInBits == RHS->getAlignInBits();
}

View File

@ -3,8 +3,8 @@
@foo = global i32 0
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12}
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12}
!0 = !DIFile(filename: "scope.h", directory: "/path/to/dir")
!1 = distinct !{}
@ -23,3 +23,8 @@
; CHECK: !8 = !DIGlobalVariable(name: "mem", scope: !0, type: !9, isLocal: false, isDefinition: true, declaration: !7)
!8 = !DIGlobalVariable(name: "mem", scope: !0, declaration: !7, type: !9)
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
; CHECK: !12 = !DIGlobalVariable(name: "bar", linkageName: "bar", scope: !0, file: !2, line: 8, type: !3, isLocal: true, isDefinition: false, templateParams: !11, align: 32)
!10 = !DITemplateTypeParameter(name: "Ty", type: !3)
!11 = distinct !{!10}
!12 = !DIGlobalVariable(name: "bar", linkageName: "bar", scope: !0, file: !2, line: 8, type: !3, isLocal: true, isDefinition: false, templateParams: !11, align: 32)

View File

@ -3,7 +3,10 @@
; RUN: llc -mtriple=x86_64-linux -O0 -filetype=obj < %s | llvm-dwarfdump -v -debug-info - | FileCheck %s
; IR generated with `clang++ -g -emit-llvm -S` from the following code:
; template<int x, int*, template<typename> class y, decltype(nullptr) n, int ...z> int func() { return 3; }
; template<int x, int*, template<typename> class y, decltype(nullptr) n, int ...z> int func() {
; var<int> = 5;
; return var<int>;
; }
; template<typename> struct y_impl { struct nested { }; };
; int glbl = func<3, &glbl, y_impl, nullptr, 1, 2>();
; y_impl<int>::nested n;
@ -12,9 +15,17 @@
; CHECK-NEXT: DW_AT_name{{.*}} = "int"
; CHECK: DW_TAG_structure_type
; CHECK-NEXT: DW_AT_name{{.*}}"y_impl<int>"
; CHECK: DW_AT_name{{.*}}"y_impl<int>"
; CHECK-NOT: {{TAG|NULL}}
; CHECK: DW_TAG_template_type_parameter
; CHECK: DW_TAG_variable
; CHECK-NEXT: DW_AT_name{{.*}}"var"
; CHECK-NOT: NULL
; CHECK: DW_TAG_template_type_parameter
; CHECK-NEXT: DW_AT_type{{.*}}=> {[[INT]]}
; CHECK-NEXT: DW_AT_name{{.*}}= "T"
; CHECK: DW_AT_name{{.*}}"func<3, &glbl, y_impl, nullptr, 1, 2>"
; CHECK-NOT: NULL
@ -59,75 +70,84 @@
; CHECK-NEXT: DW_AT_name{{.*}}= "decltype(nullptr)"
source_filename = "test/DebugInfo/X86/template.ll"
%"struct.y_impl<int>::nested" = type { i8 }
@glbl = global i32 0, align 4, !dbg !0
@n = global %"struct.y_impl<int>::nested" zeroinitializer, align 1, !dbg !4
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_template.cpp, i8* null }]
@glbl = dso_local global i32 0, align 4, !dbg !0
@_Z3varIiE = linkonce_odr dso_local global i32 0, align 4, !dbg !13
@n = dso_local global %"struct.y_impl<int>::nested" zeroinitializer, align 1, !dbg !6
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_upstream_test.cpp, i8* null }]
define internal void @__cxx_global_var_init() section ".text.startup" !dbg !17 {
; Function Attrs: noinline uwtable
define internal void @__cxx_global_var_init() #0 section ".text.startup" !dbg !21 {
entry:
%call = call i32 @_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv(), !dbg !20
store i32 %call, i32* @glbl, align 4, !dbg !20
ret void, !dbg !20
%call = call i32 @_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv(), !dbg !24
store i32 %call, i32* @glbl, align 4, !dbg !24
ret void, !dbg !24
}
; Function Attrs: nounwind uwtable
define linkonce_odr i32 @_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv() #0 !dbg !21 {
; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr dso_local i32 @_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv() #1 !dbg !25 {
entry:
ret i32 3, !dbg !35
store i32 5, i32* @_Z3varIiE, align 4, !dbg !39
%0 = load i32, i32* @_Z3varIiE, align 4, !dbg !40
ret i32 %0, !dbg !41
}
define internal void @_GLOBAL__sub_I_template.cpp() section ".text.startup" {
; Function Attrs: noinline uwtable
define internal void @_GLOBAL__sub_I_upstream_test.cpp() #0 section ".text.startup" !dbg !42 {
entry:
call void @__cxx_global_var_init(), !dbg !36
call void @__cxx_global_var_init(), !dbg !44
ret void
}
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #0 = { nounwind uwtable }
attributes #1 = { nounwind uwtable noinline optnone }
!llvm.dbg.cu = !{!11}
!llvm.module.flags = !{!14, !15}
!llvm.ident = !{!16}
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!17, !18, !19}
!llvm.ident = !{!20}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = !DIGlobalVariable(name: "glbl", scope: null, file: !2, line: 3, type: !3, isLocal: false, isDefinition: true)
!2 = !DIFile(filename: "template.cpp", directory: "/tmp/dbginfo")
!3 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
!5 = !DIGlobalVariable(name: "n", scope: null, file: !2, line: 4, type: !6, isLocal: false, isDefinition: true)
!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "nested", scope: !7, file: !2, line: 2, size: 8, align: 8, elements: !8, identifier: "_ZTSN6y_implIiE6nestedE")
!7 = !DICompositeType(tag: DW_TAG_structure_type, name: "y_impl<int>", file: !2, line: 2, size: 8, align: 8, elements: !8, templateParams: !9, identifier: "_ZTS6y_implIiE")
!8 = !{}
!9 = !{!10}
!10 = !DITemplateTypeParameter(type: !3)
!11 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "clang version 3.6.0 (trunk 224394) (llvm/trunk 224384)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, retainedTypes: !12, globals: !13, imports: !8)
!12 = !{!7, !6}
!13 = !{!0, !4}
!14 = !{i32 2, !"Dwarf Version", i32 4}
!15 = !{i32 2, !"Debug Info Version", i32 3}
!16 = !{!"clang version 3.6.0 (trunk 224394) (llvm/trunk 224384)"}
!17 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !2, file: !2, line: 3, type: !18, isLocal: true, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !11, retainedNodes: !8)
!18 = !DISubroutineType(types: !19)
!19 = !{null}
!20 = !DILocation(line: 3, column: 12, scope: !17)
!21 = distinct !DISubprogram(name: "func<3, &glbl, y_impl, nullptr, 1, 2>", linkageName: "_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv", scope: !2, file: !2, line: 1, type: !22, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !11, templateParams: !24, retainedNodes: !8)
!1 = distinct !DIGlobalVariable(name: "glbl", scope: !2, file: !3, line: 7, type: !12, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
!3 = !DIFile(filename: "upstream_test.cpp", directory: "/home/mvoss/src/92562")
!4 = !{}
!5 = !{!0, !6, !13}
!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
!7 = distinct !DIGlobalVariable(name: "n", scope: !2, file: !3, line: 8, type: !8, isLocal: false, isDefinition: true)!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "nested", scope: !9, file: !3, line: 6, size: 8, flags: DIFlagTypePassByValue, elements: !4, identifier: "_ZTSN6y_implIiE6nestedE")
!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "y_impl<int>", file: !3, line: 6, size: 8, flags: DIFlagTypePassByValue, elements: !4, templateParams: !10, identifier: "_ZTS6y_implIiE")
!10 = !{!11}
!11 = !DITemplateTypeParameter(type: !12)
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression())
!14 = distinct !DIGlobalVariable(name: "var", linkageName: "_Z3varIiE", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true, templateParams: !15)
!15 = !{!16}
!16 = !DITemplateTypeParameter(name: "T", type: !12)
!17 = !{i32 2, !"Dwarf Version", i32 4}
!18 = !{i32 2, !"Debug Info Version", i32 3}
!19 = !{i32 1, !"wchar_size", i32 4}
!20 = !{!"clang version 7.0.0 "}
!21 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !3, file: !3, line: 7, type: !22, isLocal: true, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, unit: !2, retainedNodes: !4)
!22 = !DISubroutineType(types: !23)
!23 = !{!3}
!24 = !{!25, !26, !28, !29, !31}
!25 = !DITemplateValueParameter(name: "x", type: !3, value: i32 3)
!26 = !DITemplateValueParameter(type: !27, value: i32* @glbl)
!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3, size: 64, align: 64)
!28 = !DITemplateValueParameter(tag: DW_TAG_GNU_template_template_param, name: "y", value: !"y_impl")
!29 = !DITemplateValueParameter(name: "n", type: !30, value: i8 0)
!30 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)")
!31 = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "z", value: !32)
!32 = !{!33, !34}
!33 = !DITemplateValueParameter(type: !3, value: i32 1)
!34 = !DITemplateValueParameter(type: !3, value: i32 2)
!35 = !DILocation(line: 1, column: 96, scope: !21)
!36 = !DILocation(line: 0, scope: !37)
!37 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_template.cpp", scope: !2, file: !2, type: !38, isLocal: true, isDefinition: true, flags: DIFlagArtificial, isOptimized: false, unit: !11, retainedNodes: !8)
!38 = !DISubroutineType(types: !8)
!23 = !{null}
!24 = !DILocation(line: 7, column: 12, scope: !21)
!25 = distinct !DISubprogram(name: "func<3, &glbl, y_impl, nullptr, 1, 2>", linkageName: "_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv", scope: !3, file: !3, line: 2, type: !26, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !2, templateParams: !28, retainedNodes: !4)
!26 = !DISubroutineType(types: !27)
!27 = !{!12}
!28 = !{!29, !30, !32, !33, !35}
!29 = !DITemplateValueParameter(name: "x", type: !12, value: i32 3)
!30 = !DITemplateValueParameter(type: !31, value: i32* @glbl)
!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
!32 = !DITemplateValueParameter(tag: DW_TAG_GNU_template_template_param, name: "y", value: !"y_impl")
!33 = !DITemplateValueParameter(name: "n", type: !34, value: i8 0)
!34 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)")
!35 = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "z", value: !36)
!36 = !{!37, !38}
!37 = !DITemplateValueParameter(type: !12, value: i32 1)
!38 = !DITemplateValueParameter(type: !12, value: i32 2)
!39 = !DILocation(line: 3, column: 12, scope: !25)
!40 = !DILocation(line: 4, column: 10, scope: !25)
!41 = !DILocation(line: 4, column: 3, scope: !25)
!42 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_upstream_test.cpp", scope: !3, file: !3, type: !43, isLocal: true, isDefinition: true, flags: DIFlagArtificial, isOptimized: false, unit: !2, retainedNodes: !4)
!43 = !DISubroutineType(types: !4)
!44 = !DILocation(line: 0, scope: !42)

View File

@ -61,26 +61,24 @@ int llvm_test_dibuilder(void) {
LLVMMetadataRef ClassTy = declare_objc_class(DIB, File);
LLVMMetadataRef GlobalClassValueExpr =
LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
LLVMDIBuilderCreateGlobalVariableExpression(DIB, Module, "globalClass", 11,
"", 0, File, 1, ClassTy,
true, GlobalClassValueExpr,
NULL, 0);
LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
LLVMDIBuilderCreateGlobalVariableExpression(
DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true,
GlobalClassValueExpr, NULL, 0);
LLVMMetadataRef Int64Ty =
LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero);
LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero);
LLVMMetadataRef Int64TypeDef =
LLVMDIBuilderCreateTypedef(DIB, Int64Ty, "int64_t", 7, File, 42, File);
LLVMMetadataRef GlobalVarValueExpr =
LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
LLVMDIBuilderCreateGlobalVariableExpression(DIB, Module, "global", 6,
"", 0, File, 1, Int64TypeDef,
true, GlobalVarValueExpr,
NULL, 0);
LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
LLVMDIBuilderCreateGlobalVariableExpression(
DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true,
GlobalVarValueExpr, NULL, 0);
LLVMMetadataRef NameSpace =
LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false);
LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false);
LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty};
LLVMMetadataRef StructDbgTy =

View File

@ -2014,13 +2014,16 @@ TEST_F(DIGlobalVariableTest, get) {
DIType *Type = getDerivedType();
bool IsLocalToUnit = false;
bool IsDefinition = true;
MDTuple *templateParams = getTuple();
DIDerivedType *StaticDataMemberDeclaration =
cast<DIDerivedType>(getDerivedType());
uint32_t AlignInBits = 8;
auto *N = DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits);
auto *N = DIGlobalVariable::get(
Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits);
EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag());
EXPECT_EQ(Scope, N->getScope());
EXPECT_EQ(Name, N->getName());
@ -2031,47 +2034,57 @@ TEST_F(DIGlobalVariableTest, get) {
EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit());
EXPECT_EQ(IsDefinition, N->isDefinition());
EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration());
EXPECT_EQ(templateParams, N->getTemplateParams());
EXPECT_EQ(AlignInBits, N->getAlignInBits());
EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
StaticDataMemberDeclaration,
templateParams, AlignInBits));
EXPECT_NE(N,
DIGlobalVariable::get(Context, getSubprogram(), Name, LinkageName,
File, Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(
Context, getSubprogram(), Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
StaticDataMemberDeclaration,
templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line,
Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
EXPECT_NE(N,
DIGlobalVariable::get(Context, Scope, Name, LinkageName, getFile(),
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
EXPECT_NE(N,
DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line + 1, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
EXPECT_NE(N,
DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line,
getDerivedType(), IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
StaticDataMemberDeclaration,
templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName,
getFile(), Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration,
templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line + 1, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration,
templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, getDerivedType(), IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration,
templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, !IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
StaticDataMemberDeclaration,
templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, !IsDefinition,
StaticDataMemberDeclaration, AlignInBits));
StaticDataMemberDeclaration,
templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
cast<DIDerivedType>(getDerivedType()),
templateParams, AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, nullptr,
AlignInBits));
EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
(AlignInBits << 1)));
templateParams, (AlignInBits << 1)));
TempDIGlobalVariable Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
@ -2088,18 +2101,19 @@ TEST_F(DIGlobalVariableExpressionTest, get) {
DIType *Type = getDerivedType();
bool IsLocalToUnit = false;
bool IsDefinition = true;
MDTuple *templateParams = getTuple();
auto *Expr = DIExpression::get(Context, {1, 2});
auto *Expr2 = DIExpression::get(Context, {1, 2, 3});
DIDerivedType *StaticDataMemberDeclaration =
cast<DIDerivedType>(getDerivedType());
uint32_t AlignInBits = 8;
auto *Var = DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits);
auto *Var2 = DIGlobalVariable::get(Context, Scope, "other", LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, AlignInBits);
auto *Var = DIGlobalVariable::get(
Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits);
auto *Var2 = DIGlobalVariable::get(
Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits);
auto *N = DIGlobalVariableExpression::get(Context, Var, Expr);
EXPECT_EQ(Var, N->getVariable());