diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/ASTConsumer.h | 3 | ||||
-rw-r--r-- | clang/include/clang/Frontend/MultiplexConsumer.h | 2 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/BackendConsumer.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 17 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 19 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/ModuleBuilder.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/MultiplexConsumer.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Interpreter/IncrementalParser.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 8 | ||||
-rw-r--r-- | clang/test/CodeGen/bpf-debug-info-extern-func.c | 9 | ||||
-rw-r--r-- | clang/test/CodeGen/bpf-debug-info-unref.c | 11 |
14 files changed, 58 insertions, 26 deletions
diff --git a/clang/include/clang/AST/ASTConsumer.h b/clang/include/clang/AST/ASTConsumer.h index ebcd805..447f259 100644 --- a/clang/include/clang/AST/ASTConsumer.h +++ b/clang/include/clang/AST/ASTConsumer.h @@ -23,6 +23,7 @@ namespace clang { class ASTDeserializationListener; // layering violation because void* is ugly class SemaConsumer; // layering violation required for safe SemaConsumer class TagDecl; + class DeclaratorDecl; class VarDecl; class FunctionDecl; class ImportDecl; @@ -105,7 +106,7 @@ public: /// CompleteExternalDeclaration - Callback invoked at the end of a translation /// unit to notify the consumer that the given external declaration should be /// completed. - virtual void CompleteExternalDeclaration(VarDecl *D) {} + virtual void CompleteExternalDeclaration(DeclaratorDecl *D) {} /// Callback invoked when an MSInheritanceAttr has been attached to a /// CXXRecordDecl. diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h b/clang/include/clang/Frontend/MultiplexConsumer.h index 4ed0d86..e49e339 100644 --- a/clang/include/clang/Frontend/MultiplexConsumer.h +++ b/clang/include/clang/Frontend/MultiplexConsumer.h @@ -67,7 +67,7 @@ public: void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override; void HandleImplicitImportDecl(ImportDecl *D) override; void CompleteTentativeDefinition(VarDecl *D) override; - void CompleteExternalDeclaration(VarDecl *D) override; + void CompleteExternalDeclaration(DeclaratorDecl *D) override; void AssignInheritanceModel(CXXRecordDecl *RD) override; void HandleVTable(CXXRecordDecl *RD) override; ASTMutationListener *GetASTMutationListener() override; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fb3a5d2..75a8054 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3098,7 +3098,7 @@ public: TentativeDefinitionsType TentativeDefinitions; /// All the external declarations encoutered and used in the TU. - SmallVector<VarDecl *, 4> ExternalDeclarations; + SmallVector<DeclaratorDecl *, 4> ExternalDeclarations; /// Generally null except when we temporarily switch decl contexts, /// like in \see SemaObjC::ActOnObjCTemporaryExitContainerContext. diff --git a/clang/lib/CodeGen/BackendConsumer.h b/clang/lib/CodeGen/BackendConsumer.h index a648bd3..a023d29 100644 --- a/clang/lib/CodeGen/BackendConsumer.h +++ b/clang/lib/CodeGen/BackendConsumer.h @@ -107,7 +107,7 @@ public: void HandleTagDeclDefinition(TagDecl *D) override; void HandleTagDeclRequiredDefinition(const TagDecl *D) override; void CompleteTentativeDefinition(VarDecl *D) override; - void CompleteExternalDeclaration(VarDecl *D) override; + void CompleteExternalDeclaration(DeclaratorDecl *D) override; void AssignInheritanceModel(CXXRecordDecl *RD) override; void HandleVTable(CXXRecordDecl *RD) override; diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 23e5dee..039f60c 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3141,21 +3141,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { return LV; } - if (const auto *FD = dyn_cast<FunctionDecl>(ND)) { - LValue LV = EmitFunctionDeclLValue(*this, E, FD); - - // Emit debuginfo for the function declaration if the target wants to. - if (getContext().getTargetInfo().allowDebugInfoForExternalRef()) { - if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) { - auto *Fn = - cast<llvm::Function>(LV.getPointer(*this)->stripPointerCasts()); - if (!Fn->getSubprogram()) - DI->EmitFunctionDecl(FD, FD->getLocation(), T, Fn); - } - } - - return LV; - } + if (const auto *FD = dyn_cast<FunctionDecl>(ND)) + return EmitFunctionDeclLValue(*this, E, FD); // FIXME: While we're emitting a binding from an enclosing scope, all other // DeclRefExprs we see should be implicitly treated as if they also refer to diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 0b92c53..e87226e 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -376,7 +376,7 @@ void BackendConsumer::CompleteTentativeDefinition(VarDecl *D) { Gen->CompleteTentativeDefinition(D); } -void BackendConsumer::CompleteExternalDeclaration(VarDecl *D) { +void BackendConsumer::CompleteExternalDeclaration(DeclaratorDecl *D) { Gen->CompleteExternalDeclaration(D); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 99e986d..dc9dd03 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5185,8 +5185,11 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) { EmitGlobalVarDefinition(D); } -void CodeGenModule::EmitExternalDeclaration(const VarDecl *D) { - EmitExternalVarDeclaration(D); +void CodeGenModule::EmitExternalDeclaration(const DeclaratorDecl *D) { + if (auto const *V = dyn_cast<const VarDecl>(D)) + EmitExternalVarDeclaration(V); + if (auto const *FD = dyn_cast<const FunctionDecl>(D)) + EmitExternalFunctionDeclaration(FD); } CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const { @@ -5622,6 +5625,18 @@ void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) { } } +void CodeGenModule::EmitExternalFunctionDeclaration(const FunctionDecl *FD) { + if (CGDebugInfo *DI = getModuleDebugInfo()) + if (getCodeGenOpts().hasReducedDebugInfo()) { + auto *Ty = getTypes().ConvertType(FD->getType()); + StringRef MangledName = getMangledName(FD); + auto *Fn = dyn_cast<llvm::Function>( + GetOrCreateLLVMFunction(MangledName, Ty, FD, /* ForVTable */ false)); + if (!Fn->getSubprogram()) + DI->EmitFunctionDecl(FD, FD->getLocation(), FD->getType(), Fn); + } +} + static bool isVarDeclStrongDefinition(const ASTContext &Context, CodeGenModule &CGM, const VarDecl *D, bool NoCommon) { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 4796d42..0444f9f 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1338,7 +1338,7 @@ public: void EmitTentativeDefinition(const VarDecl *D); - void EmitExternalDeclaration(const VarDecl *D); + void EmitExternalDeclaration(const DeclaratorDecl *D); void EmitVTable(CXXRecordDecl *Class); @@ -1690,6 +1690,7 @@ private: void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false); void EmitExternalVarDeclaration(const VarDecl *D); + void EmitExternalFunctionDeclaration(const FunctionDecl *D); void EmitAliasDefinition(GlobalDecl GD); void emitIFuncDefinition(GlobalDecl GD); void emitCPUDispatchDefinition(GlobalDecl GD); diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index df85295..d4e0ab0 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -310,7 +310,7 @@ namespace { Builder->EmitTentativeDefinition(D); } - void CompleteExternalDeclaration(VarDecl *D) override { + void CompleteExternalDeclaration(DeclaratorDecl *D) override { Builder->EmitExternalDeclaration(D); } diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index 8fdc7f5..651c55a 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -357,7 +357,7 @@ void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { Consumer->CompleteTentativeDefinition(D); } -void MultiplexConsumer::CompleteExternalDeclaration(VarDecl *D) { +void MultiplexConsumer::CompleteExternalDeclaration(DeclaratorDecl *D) { for (auto &Consumer : Consumers) Consumer->CompleteExternalDeclaration(D); } diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index a8d0294..b7c809c 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -79,7 +79,7 @@ public: void CompleteTentativeDefinition(VarDecl *D) override final { Consumer->CompleteTentativeDefinition(D); } - void CompleteExternalDeclaration(VarDecl *D) override final { + void CompleteExternalDeclaration(DeclaratorDecl *D) override final { Consumer->CompleteExternalDeclaration(D); } void AssignInheritanceModel(CXXRecordDecl *RD) override final { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b3bfdac..aa44608 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10818,6 +10818,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, break; } + // Similar to no_builtin logic above, at this point of the code + // FunctionDecl::isThisDeclarationADefinition() always returns `false` + // because Sema::ActOnStartOfFunctionDef has not been called yet. + if (Context.getTargetInfo().allowDebugInfoForExternalRef() && + !NewFD->isInvalidDecl() && + D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration) + ExternalDeclarations.push_back(NewFD); + return NewFD; } diff --git a/clang/test/CodeGen/bpf-debug-info-extern-func.c b/clang/test/CodeGen/bpf-debug-info-extern-func.c new file mode 100644 index 0000000..e87c8be --- /dev/null +++ b/clang/test/CodeGen/bpf-debug-info-extern-func.c @@ -0,0 +1,9 @@ +// RUN: %clang -g -target bpf -S -emit-llvm %s -o - | FileCheck %s +// +// When linking BPF object files via bpftool, BTF info is required for +// every symbol. BTF is generated from debug info. Ensure that debug info +// is emitted for extern functions referenced via variable initializers. +// +// CHECK: !DISubprogram(name: "fn" +extern void fn(void); +void (*pfn) (void) = &fn; diff --git a/clang/test/CodeGen/bpf-debug-info-unref.c b/clang/test/CodeGen/bpf-debug-info-unref.c new file mode 100644 index 0000000..91f761e --- /dev/null +++ b/clang/test/CodeGen/bpf-debug-info-unref.c @@ -0,0 +1,11 @@ +// RUN: %clang -g -target bpf -S -emit-llvm %s -o - | FileCheck %s +// +// No debug info is produced for unreferenced functions. +// CHECK-NOT: !DISubprogram +void unref(void); +void unref2(typeof(unref)); + +// No debug info for unused extern variables as well. +// CHECK-NOT: !DiGlobalVariable +extern int unused; +extern int unused2[sizeof(unused)]; |