kavitha-natarajan created this revision.
kavitha-natarajan added reviewers: kamleshbhalui, umesh.kalappa0, probinson, 
dblaikie.
kavitha-natarajan added a project: debug-info.
Herald added a subscriber: jeroen.dobbelaere.
Herald added a project: All.
kavitha-natarajan requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is in continuation with the patch posted earlier for bug-50052 
<https://bugs.llvm.org/show_bug.cgi?id=50052>:

https://reviews.llvm.org/D103131

For the below testcase, when compiled with clang compiler, debugger is not able 
to print alias variable type or value. 
$ cat test.c
int oldname = 1;
extern int newname attribute((alias("oldname")));

int main ()
{

  return 0;

}

$ clang -g -O0 test.c

$ gdb a.out
(gdb) ptype oldname
type = int
(gdb) ptype newname
type = <data variable, no debug info>
(gdb) p oldname
$1 = 1
(gdb) p newname
'newname' has unknown type; cast it to its declared type

This is because clang is not emitting dwarf information for alias variable. The 
above mentioned patch supports clang to emit debug info for alias variable as 
imported entity (DW_TAG_imported_declaration). However, gdb cannot handle the 
imported declaration for alias variables. GCC emits debug info for alias 
variables as DW_TAG_variable which gdb can handle. The discussions in the above 
bug report and patch review links talk about why it is appropriate to emit 
alias variable as DW_TAG_imported_declaration rather than DW_TAG_variable. 
Refer section "3.2.3 Imported (or Renamed) Declaration Entries" in DWARF 5 
specification.

In the clang patch, CGDebugInfo.cpp:EmitGlobalAlias() function is rewritten to 
handle nested (recursive) imported declaration and developed a testcase as 
well. A corresponding gdb patch that can handle DW_TAG_imported_declaration as 
alias variables is also developed and will be posted to gdb community for 
review in parallel.

After clang and gdb fixes:

$ gdb a.out
(gdb) ptype oldname
type = int
(gdb) ptype newname
type = int
(gdb) p oldname
$1 = 1
(gdb) p newname
$2 = 1
(gdb)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D120989

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/test/CodeGen/debug-info-alias.c

Index: clang/test/CodeGen/debug-info-alias.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/debug-info-alias.c
@@ -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;
Index: clang/lib/CodeGen/CodeGenModule.h
===================================================================
--- clang/lib/CodeGen/CodeGenModule.h
+++ clang/lib/CodeGen/CodeGenModule.h
@@ -1213,6 +1213,7 @@
 
   StringRef getMangledName(GlobalDecl GD);
   StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
+  const GlobalDecl getMangledNameDecl(StringRef);
 
   void EmitTentativeDefinition(const VarDecl *D);
 
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1495,6 +1495,16 @@
   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);
 }
@@ -5139,6 +5149,13 @@
       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) {
Index: clang/lib/CodeGen/CGDebugInfo.h
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -152,8 +152,10 @@
   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;
@@ -512,6 +514,9 @@
   /// 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);
 
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3955,6 +3955,16 @@
     return dyn_cast_or_null<llvm::DINode>(N);
   }
 
+  // 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);
+  }
+
   // No definition for now. Emit a forward definition that might be
   // merged with a potential upcoming definition.
   if (const auto *FD = dyn_cast<FunctionDecl>(D))
@@ -5364,6 +5374,48 @@
   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;
+  else 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();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to