Skip to content

Commit e3d8ee3

Browse files
committed
reland "[DebugInfo] Support to emit debugInfo for extern variables"
Commit d77ae15 ("[DebugInfo] Support to emit debugInfo for extern variables") added deebugInfo for extern variables for BPF target. The commit is reverted by 891e25b as the committed tests using %clang instead of %clang_cc1 causing test failed in certain scenarios as reported by Reid Kleckner. This patch fixed the tests by using %clang_cc1. Differential Revision: https://reviews.llvm.org/D71818
1 parent fb53396 commit e3d8ee3

20 files changed

+166
-7
lines changed

clang/include/clang/AST/ASTConsumer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ class ASTConsumer {
102102
/// modified by the introduction of an implicit zero initializer.
103103
virtual void CompleteTentativeDefinition(VarDecl *D) {}
104104

105+
/// CompleteExternalDeclaration - Callback invoked at the end of a translation
106+
/// unit to notify the consumer that the given external declaration should be
107+
/// completed.
108+
virtual void CompleteExternalDeclaration(VarDecl *D) {}
109+
105110
/// Callback invoked when an MSInheritanceAttr has been attached to a
106111
/// CXXRecordDecl.
107112
virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}

clang/include/clang/Basic/TargetInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,9 @@ class TargetInfo : public virtual TransferrableTargetInfo,
13891389

13901390
virtual void setAuxTarget(const TargetInfo *Aux) {}
13911391

1392+
/// Whether target allows debuginfo types for decl only variables.
1393+
virtual bool allowDebugInfoForExternalVar() const { return false; }
1394+
13921395
protected:
13931396
/// Copy type and layout related info.
13941397
void copyAuxTarget(const TargetInfo *Aux);

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,9 @@ class Sema final {
668668
/// All the tentative definitions encountered in the TU.
669669
TentativeDefinitionsType TentativeDefinitions;
670670

671+
/// All the external declarations encoutered and used in the TU.
672+
SmallVector<VarDecl *, 4> ExternalDeclarations;
673+
671674
typedef LazyVector<const DeclaratorDecl *, ExternalSemaSource,
672675
&ExternalSemaSource::ReadUnusedFileScopedDecls, 2, 2>
673676
UnusedFileScopedDeclsType;

clang/lib/Basic/Targets/BPF.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
7676
return None;
7777
}
7878

79+
bool allowDebugInfoForExternalVar() const override { return true; }
80+
7981
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
8082
switch (CC) {
8183
default:

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4485,7 +4485,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
44854485

44864486
GVE = DBuilder.createGlobalVariableExpression(
44874487
DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
4488-
Var->hasLocalLinkage(),
4488+
Var->hasLocalLinkage(), true,
44894489
Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
44904490
getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
44914491
Align);
@@ -4588,10 +4588,29 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
45884588

45894589
GV.reset(DBuilder.createGlobalVariableExpression(
45904590
DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty,
4591-
true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
4591+
true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
45924592
TemplateParameters, Align));
45934593
}
45944594

4595+
void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
4596+
const VarDecl *D) {
4597+
assert(DebugKind >= codegenoptions::LimitedDebugInfo);
4598+
if (D->hasAttr<NoDebugAttr>())
4599+
return;
4600+
4601+
auto Align = getDeclAlignIfRequired(D, CGM.getContext());
4602+
llvm::DIFile *Unit = getOrCreateFile(D->getLocation());
4603+
StringRef Name = D->getName();
4604+
llvm::DIType *Ty = getOrCreateType(D->getType(), Unit);
4605+
4606+
llvm::DIScope *DContext = getDeclContextDescriptor(D);
4607+
llvm::DIGlobalVariableExpression *GVE =
4608+
DBuilder.createGlobalVariableExpression(
4609+
DContext, Name, StringRef(), Unit, getLineNumber(D->getLocation()),
4610+
Ty, false, false, nullptr, nullptr, nullptr, Align);
4611+
Var->addDebugInfo(GVE);
4612+
}
4613+
45954614
llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) {
45964615
if (!LexicalBlockStack.empty())
45974616
return LexicalBlockStack.back();

clang/lib/CodeGen/CGDebugInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,9 @@ class CGDebugInfo {
478478
/// Emit a constant global variable's debug info.
479479
void EmitGlobalVariable(const ValueDecl *VD, const APValue &Init);
480480

481+
/// Emit information about an external variable.
482+
void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
483+
481484
/// Emit C++ using directive.
482485
void EmitUsingDirective(const UsingDirectiveDecl &UD);
483486

clang/lib/CodeGen/CodeGenAction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ namespace clang {
336336
Gen->CompleteTentativeDefinition(D);
337337
}
338338

339+
void CompleteExternalDeclaration(VarDecl *D) override {
340+
Gen->CompleteExternalDeclaration(D);
341+
}
342+
339343
void AssignInheritanceModel(CXXRecordDecl *RD) override {
340344
Gen->AssignInheritanceModel(RD);
341345
}

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3730,6 +3730,10 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
37303730
EmitGlobalVarDefinition(D);
37313731
}
37323732

3733+
void CodeGenModule::EmitExternalDeclaration(const VarDecl *D) {
3734+
EmitExternalVarDeclaration(D);
3735+
}
3736+
37333737
CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {
37343738
return Context.toCharUnitsFromBits(
37353739
getDataLayout().getTypeStoreSizeInBits(Ty));
@@ -4113,6 +4117,19 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
41134117
DI->EmitGlobalVariable(GV, D);
41144118
}
41154119

4120+
void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) {
4121+
if (CGDebugInfo *DI = getModuleDebugInfo())
4122+
if (getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo) {
4123+
QualType ASTTy = D->getType();
4124+
llvm::Type *Ty = getTypes().ConvertTypeForMem(D->getType());
4125+
llvm::PointerType *PTy =
4126+
llvm::PointerType::get(Ty, getContext().getTargetAddressSpace(ASTTy));
4127+
llvm::Constant *GV = GetOrCreateLLVMGlobal(D->getName(), PTy, D);
4128+
DI->EmitExternalVariable(
4129+
cast<llvm::GlobalVariable>(GV->stripPointerCasts()), D);
4130+
}
4131+
}
4132+
41164133
static bool isVarDeclStrongDefinition(const ASTContext &Context,
41174134
CodeGenModule &CGM, const VarDecl *D,
41184135
bool NoCommon) {

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,8 @@ class CodeGenModule : public CodeGenTypeCache {
11701170

11711171
void EmitTentativeDefinition(const VarDecl *D);
11721172

1173+
void EmitExternalDeclaration(const VarDecl *D);
1174+
11731175
void EmitVTable(CXXRecordDecl *Class);
11741176

11751177
void RefreshTypeCacheForClass(const CXXRecordDecl *Class);
@@ -1405,6 +1407,7 @@ class CodeGenModule : public CodeGenTypeCache {
14051407
void EmitMultiVersionFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
14061408

14071409
void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false);
1410+
void EmitExternalVarDeclaration(const VarDecl *D);
14081411
void EmitAliasDefinition(GlobalDecl GD);
14091412
void emitIFuncDefinition(GlobalDecl GD);
14101413
void emitCPUDispatchDefinition(GlobalDecl GD);

clang/lib/CodeGen/ModuleBuilder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ namespace {
290290
Builder->EmitTentativeDefinition(D);
291291
}
292292

293+
void CompleteExternalDeclaration(VarDecl *D) override {
294+
Builder->EmitExternalDeclaration(D);
295+
}
296+
293297
void HandleVTable(CXXRecordDecl *RD) override {
294298
if (Diags.hasErrorOccurred())
295299
return;

clang/lib/Sema/Sema.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,13 @@ void Sema::ActOnEndOfTranslationUnit() {
11361136
Consumer.CompleteTentativeDefinition(VD);
11371137
}
11381138

1139+
for (auto D : ExternalDeclarations) {
1140+
if (!D || D->isInvalidDecl() || D->getPreviousDecl() || !D->isUsed())
1141+
continue;
1142+
1143+
Consumer.CompleteExternalDeclaration(D);
1144+
}
1145+
11391146
// If there were errors, disable 'unused' warnings since they will mostly be
11401147
// noise. Don't warn for a use from a module: either we should warn on all
11411148
// file-scope declarations in modules or not at all, but whether the

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12220,6 +12220,10 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
1222012220
Diag(Var->getLocation(), diag::note_private_extern);
1222112221
}
1222212222

12223+
if (Context.getTargetInfo().allowDebugInfoForExternalVar() &&
12224+
!Var->isInvalidDecl() && !getLangOpts().CPlusPlus)
12225+
ExternalDeclarations.push_back(Var);
12226+
1222312227
return;
1222412228

1222512229
case VarDecl::TentativeDefinition:
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -x c -debug-info-kind=limited -triple bpf-linux-gnu -emit-llvm %s -o - | FileCheck %s
2+
3+
extern char ch;
4+
int test() {
5+
return ch;
6+
}
7+
8+
int test2() {
9+
extern char ch2;
10+
return ch2;
11+
}
12+
13+
extern int (*foo)(int);
14+
int test3() {
15+
return foo(0);
16+
}
17+
18+
// CHECK: distinct !DIGlobalVariable(name: "ch",{{.*}} type: ![[CHART:[0-9]+]], isLocal: false, isDefinition: false
19+
// CHECK: distinct !DIGlobalVariable(name: "ch2",{{.*}} type: ![[CHART]], isLocal: false, isDefinition: false
20+
// CHECK: ![[CHART]] = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
21+
22+
// CHECK: distinct !DIGlobalVariable(name: "foo",{{.*}} type: ![[FUNC:[0-9]+]], isLocal: false, isDefinition: false)
23+
// CHECK: ![[FUNC]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[SUB:[0-9]+]], size: 64)
24+
// CHECK: ![[SUB]] = !DISubroutineType(types: ![[TYPES:[0-9]+]])
25+
// CHECK: ![[TYPES]] = !{![[BASET:[0-9]+]], ![[BASET]]}
26+
// CHECK: ![[BASET]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -x c -debug-info-kind=limited -triple bpf-linux-gnu -emit-llvm %s -o - | FileCheck %s
2+
3+
extern char ch;
4+
extern char ch;
5+
int test() {
6+
return ch;
7+
}
8+
9+
// CHECK: distinct !DIGlobalVariable(name: "ch",{{.*}} type: ![[T:[0-9]+]], isLocal: false, isDefinition: false
10+
// CHECK-NOT: distinct !DIGlobalVariable(name: "ch"
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_cc1 -x c -debug-info-kind=limited -triple bpf-linux-gnu -emit-llvm %s -o - | FileCheck %s
2+
3+
extern char ch;
4+
int test() {
5+
extern short sh;
6+
return ch + sh;
7+
}
8+
9+
extern char (*foo)(char);
10+
int test2() {
11+
return foo(0) + ch;
12+
}
13+
14+
// CHECK: distinct !DIGlobalVariable(name: "ch",{{.*}} type: ![[Tch:[0-9]+]], isLocal: false, isDefinition: false
15+
// CHECK: distinct !DIGlobalVariable(name: "sh",{{.*}} type: ![[Tsh:[0-9]+]], isLocal: false, isDefinition: false
16+
// CHECK: ![[Tsh]] = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed)
17+
18+
// CHECK: distinct !DIGlobalVariable(name: "foo",{{.*}} type: ![[Tptr:[0-9]+]], isLocal: false, isDefinition: false
19+
// ![[Tptr]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[Tsub:[0-9]+]], size: 64)
20+
// ![[Tsub]] = !DISubroutineType(types: ![[Tproto:[0-9]+]])
21+
// ![[Tproto]] = !{![[Tch]], ![[Tch]]}
22+
// CHECK: ![[Tch]] = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -x c -debug-info-kind=limited -triple bpf-linux-gnu -emit-llvm %s -o - | FileCheck %s
2+
3+
extern char ch;
4+
int test() {
5+
return 0;
6+
}
7+
8+
int test2() {
9+
extern char ch2;
10+
return 0;
11+
}
12+
13+
extern int (*foo)(int);
14+
int test3() {
15+
return 0;
16+
}
17+
18+
int test4() {
19+
extern int (*foo2)(int);
20+
return 0;
21+
}
22+
23+
// CHECK-NOT: distinct !DIGlobalVariable(name: "ch"
24+
// CHECK-NOT: distinct !DIGlobalVariable(name: "ch2"
25+
// CHECK-NOT: distinct !DIGlobalVariable(name: "foo"
26+
// CHECK-NOT: distinct !DIGlobalVariable(name: "foo2"

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ namespace llvm {
583583
/// specified)
584584
DIGlobalVariableExpression *createGlobalVariableExpression(
585585
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
586-
unsigned LineNo, DIType *Ty, bool isLocalToUnit,
586+
unsigned LineNo, DIType *Ty, bool isLocalToUnit, bool isDefined = true,
587587
DIExpression *Expr = nullptr, MDNode *Decl = nullptr,
588588
MDTuple *templateParams = nullptr, uint32_t AlignInBits = 0);
589589

llvm/lib/IR/DIBuilder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,13 +640,14 @@ static void checkGlobalVariableScope(DIScope *Context) {
640640

641641
DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(
642642
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
643-
unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr,
643+
unsigned LineNumber, DIType *Ty, bool isLocalToUnit,
644+
bool isDefined, DIExpression *Expr,
644645
MDNode *Decl, MDTuple *templateParams, uint32_t AlignInBits) {
645646
checkGlobalVariableScope(Context);
646647

647648
auto *GV = DIGlobalVariable::getDistinct(
648649
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
649-
LineNumber, Ty, isLocalToUnit, true, cast_or_null<DIDerivedType>(Decl),
650+
LineNumber, Ty, isLocalToUnit, isDefined, cast_or_null<DIDerivedType>(Decl),
650651
templateParams, AlignInBits);
651652
if (!Expr)
652653
Expr = createExpression();

llvm/lib/IR/DebugInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression(
12891289
return wrap(unwrap(Builder)->createGlobalVariableExpression(
12901290
unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LinkLen},
12911291
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,
1292-
unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl),
1292+
true, unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl),
12931293
nullptr, AlignInBits));
12941294
}
12951295

llvm/unittests/Transforms/Utils/CloningTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ class CloneModule : public ::testing::Test {
764764

765765
DBuilder.createGlobalVariableExpression(
766766
Subprogram, "unattached", "unattached", File, 1,
767-
DBuilder.createNullPtrType(), false, Expr);
767+
DBuilder.createNullPtrType(), false, true, Expr);
768768

769769
auto *Entry = BasicBlock::Create(C, "", F);
770770
IBuilder.SetInsertPoint(Entry);

0 commit comments

Comments
 (0)