forked from OSchip/llvm-project
[clang][DebugInfo] Support debug info for alias variable
clang to emit DWARF information for global alias variable as DW_TAG_imported_declaration. This change also handles nested (recursive) imported declarations. Reviewed by: dblaikie, aprantl Differential Revision: https://reviews.llvm.org/D120989
This commit is contained in:
parent
ca3c746ba8
commit
b1ea0191a4
|
@ -3845,6 +3845,17 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
|
|||
auto N = I->second;
|
||||
if (auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N))
|
||||
return GVE->getVariable();
|
||||
return cast<llvm::DINode>(N);
|
||||
}
|
||||
|
||||
// Search imported declaration cache if it is already defined
|
||||
// as imported declaration.
|
||||
auto IE = ImportedDeclCache.find(D->getCanonicalDecl());
|
||||
|
||||
if (IE != ImportedDeclCache.end()) {
|
||||
auto N = IE->second;
|
||||
if (auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N))
|
||||
return cast<llvm::DINode>(GVE);
|
||||
return dyn_cast_or_null<llvm::DINode>(N);
|
||||
}
|
||||
|
||||
|
@ -5392,6 +5403,47 @@ void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
|
|||
Var->addDebugInfo(GVE);
|
||||
}
|
||||
|
||||
void CGDebugInfo::EmitGlobalAlias(const llvm::GlobalValue *GV,
|
||||
const GlobalDecl GD) {
|
||||
|
||||
assert(GV);
|
||||
|
||||
if (!CGM.getCodeGenOpts().hasReducedDebugInfo())
|
||||
return;
|
||||
|
||||
const auto *D = cast<ValueDecl>(GD.getDecl());
|
||||
if (D->hasAttr<NoDebugAttr>())
|
||||
return;
|
||||
|
||||
auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName());
|
||||
llvm::DINode *DI;
|
||||
|
||||
if (!AliaseeDecl)
|
||||
// FIXME: Aliasee not declared yet - possibly declared later
|
||||
// For example,
|
||||
//
|
||||
// 1 extern int newname __attribute__((alias("oldname")));
|
||||
// 2 int oldname = 1;
|
||||
//
|
||||
// No debug info would be generated for 'newname' in this case.
|
||||
//
|
||||
// Fix compiler to generate "newname" as imported_declaration
|
||||
// pointing to the DIE of "oldname".
|
||||
return;
|
||||
if (!(DI = getDeclarationOrDefinition(
|
||||
AliaseeDecl.getCanonicalDecl().getDecl())))
|
||||
return;
|
||||
|
||||
llvm::DIScope *DContext = getDeclContextDescriptor(D);
|
||||
auto Loc = D->getLocation();
|
||||
|
||||
llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
|
||||
DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
|
||||
|
||||
// Record this DIE in the cache for nested declaration reference.
|
||||
ImportedDeclCache[GD.getCanonicalDecl().getDecl()].reset(ImportDI);
|
||||
}
|
||||
|
||||
llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) {
|
||||
if (!LexicalBlockStack.empty())
|
||||
return LexicalBlockStack.back();
|
||||
|
|
|
@ -152,8 +152,10 @@ class CGDebugInfo {
|
|||
llvm::DenseMap<const char *, llvm::TrackingMDRef> DIFileCache;
|
||||
llvm::DenseMap<const FunctionDecl *, llvm::TrackingMDRef> SPCache;
|
||||
/// Cache declarations relevant to DW_TAG_imported_declarations (C++
|
||||
/// using declarations) that aren't covered by other more specific caches.
|
||||
/// using declarations and global alias variables) that aren't covered
|
||||
/// by other more specific caches.
|
||||
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
|
||||
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> ImportedDeclCache;
|
||||
llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NamespaceCache;
|
||||
llvm::DenseMap<const NamespaceAliasDecl *, llvm::TrackingMDRef>
|
||||
NamespaceAliasCache;
|
||||
|
@ -507,6 +509,9 @@ public:
|
|||
/// Emit information about an external variable.
|
||||
void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
|
||||
|
||||
/// Emit information about global variable alias.
|
||||
void EmitGlobalAlias(const llvm::GlobalValue *GV, const GlobalDecl Decl);
|
||||
|
||||
/// Emit C++ using directive.
|
||||
void EmitUsingDirective(const UsingDirectiveDecl &UD);
|
||||
|
||||
|
|
|
@ -1502,6 +1502,16 @@ StringRef CodeGenModule::getBlockMangledName(GlobalDecl GD,
|
|||
return Result.first->first();
|
||||
}
|
||||
|
||||
const GlobalDecl CodeGenModule::getMangledNameDecl(StringRef Name) {
|
||||
auto it = MangledDeclNames.begin();
|
||||
while (it != MangledDeclNames.end()) {
|
||||
if (it->second == Name)
|
||||
return it->first;
|
||||
it++;
|
||||
}
|
||||
return GlobalDecl();
|
||||
}
|
||||
|
||||
llvm::GlobalValue *CodeGenModule::GetGlobalValue(StringRef Name) {
|
||||
return getModule().getNamedValue(Name);
|
||||
}
|
||||
|
@ -5171,6 +5181,13 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
|||
setTLSMode(GA, *VD);
|
||||
|
||||
SetCommonAttributes(GD, GA);
|
||||
|
||||
// Emit global alias debug information.
|
||||
if (const auto *VD = dyn_cast<VarDecl>(D)) {
|
||||
if (CGDebugInfo *DI = getModuleDebugInfo()) {
|
||||
DI->EmitGlobalAlias(cast<llvm::GlobalValue>(GA->getAliasee()), GD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) {
|
||||
|
|
|
@ -1222,6 +1222,7 @@ public:
|
|||
|
||||
StringRef getMangledName(GlobalDecl GD);
|
||||
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
|
||||
const GlobalDecl getMangledNameDecl(StringRef);
|
||||
|
||||
void EmitTentativeDefinition(const VarDecl *D);
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
|
||||
|
||||
// CHECK-DAG: [[ENTITY1:![0-9]+]] = distinct !DIGlobalVariable(name: "aliased_global"
|
||||
// CHECK-DAG: [[ENTITY2:![0-9]+]] = distinct !DIGlobalVariable(name: "aliased_global_2"
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "__global_alias", scope: !2, entity: [[ENTITY1]]
|
||||
// CHECK-DAG: [[ENTITY3:![0-9]+]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "global_alias_2", scope: !2, entity: [[ENTITY2]]
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "__global_alias_2_alias", scope: !2, entity: [[ENTITY3]]
|
||||
|
||||
int aliased_global = 1;
|
||||
extern int __attribute__((alias("aliased_global"))) __global_alias;
|
||||
|
||||
// Recursive alias:
|
||||
int aliased_global_2 = 2;
|
||||
extern int __attribute__((alias("aliased_global_2"))) global_alias_2;
|
||||
extern int __attribute__((alias("global_alias_2"))) __global_alias_2_alias;
|
Loading…
Reference in New Issue