From 82795f2e8b06c8ae866c2f58e463d21958105108 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/4] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++++++++++++++++++------------- clang/lib/CodeGen/CGDebugInfo.h | 5 ++++ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c..9de55e41f885d 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5580,25 +5580,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { - // FIXME: Add a representation for integer constants wider than 64 bits. - if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) - InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) - // Transform a signed optional to unsigned optional. When cpp 23 comes, - // use std::optional::transform - InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) - InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); - } else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { + // FIXME: Add a representation for integer constants wider than 64 bits. + if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) + ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) + // Transform a signed optional to unsigned optional. When cpp 23 comes, + // use std::optional::transform + ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) + ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); + } else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca7..7b60e94555d06 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, + const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. From 96a433349a0db8c096bb8a7aeeaccd914392e592 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 30 Oct 2023 17:57:01 +0000 Subject: [PATCH 2/4] fixup! refactor function to use llvm code-style --- clang/lib/CodeGen/CGDebugInfo.cpp | 43 ++++++++++++++++--------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9de55e41f885d..76ce1572cdfc6 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5920,26 +5920,27 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { } llvm::DIExpression * -CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, +CGDebugInfo::createConstantValueExpression(const clang::ValueDecl *VD, const APValue &Val) { - llvm::DIExpression *ValExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { - // FIXME: Add a representation for integer constants wider than 64 bits. - if (Val.isInt()) { - const llvm::APSInt &ValInt = Val.getInt(); - std::optional ValIntOpt; - if (ValInt.isUnsigned()) - ValIntOpt = ValInt.tryZExtValue(); - else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) - // Transform a signed optional to unsigned optional. When cpp 23 comes, - // use std::optional::transform - ValIntOpt = (uint64_t)tmp.value(); - if (ValIntOpt) - ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); - } else if (Val.isFloat()) - ValExpr = DBuilder.createConstantValueExpression( - Val.getFloat().bitcastToAPInt().getZExtValue()); - } - - return ValExpr; + // FIXME: Add a representation for integer constants wider than 64 bits. + if (CGM.getContext().getTypeSize(VD->getType()) > 64) + return nullptr; + + if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) + ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) + // Transform a signed optional to unsigned optional. When cpp 23 comes, + // use std::optional::transform + ValIntOpt = (uint64_t)tmp.value(); + + if (ValIntOpt) + return DBuilder.createConstantValueExpression(ValIntOpt.value()); + } else if (Val.isFloat()) + return DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + + return nullptr; } From 8117a12a23e80c50ba128f0cfcffc41cccaac63a Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Tue, 31 Oct 2023 08:48:39 +0000 Subject: [PATCH 3/4] fixup! clean up according to LLVM-style some more --- clang/lib/CodeGen/CGDebugInfo.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 76ce1572cdfc6..ab5c86c426c88 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5926,21 +5926,21 @@ CGDebugInfo::createConstantValueExpression(const clang::ValueDecl *VD, if (CGM.getContext().getTypeSize(VD->getType()) > 64) return nullptr; - if (Val.isInt()) { - const llvm::APSInt &ValInt = Val.getInt(); - std::optional ValIntOpt; - if (ValInt.isUnsigned()) - ValIntOpt = ValInt.tryZExtValue(); - else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) - // Transform a signed optional to unsigned optional. When cpp 23 comes, - // use std::optional::transform - ValIntOpt = (uint64_t)tmp.value(); - - if (ValIntOpt) - return DBuilder.createConstantValueExpression(ValIntOpt.value()); - } else if (Val.isFloat()) + if (Val.isFloat()) return DBuilder.createConstantValueExpression( Val.getFloat().bitcastToAPInt().getZExtValue()); + llvm::APSInt const &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) + ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue()) + // Transform a signed optional to unsigned optional. When cpp 23 comes, + // use std::optional::transform + ValIntOpt = static_cast(*tmp); + + if (ValIntOpt) + return DBuilder.createConstantValueExpression(ValIntOpt.value()); + return nullptr; } From ad67ad1fe7b800f17d2ee813a37d57f7cd919999 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Tue, 31 Oct 2023 09:24:00 +0000 Subject: [PATCH 4/4] fixup! early return if not isInt() --- clang/lib/CodeGen/CGDebugInfo.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index ab5c86c426c88..b175c4b0ba2a5 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5930,6 +5930,9 @@ CGDebugInfo::createConstantValueExpression(const clang::ValueDecl *VD, return DBuilder.createConstantValueExpression( Val.getFloat().bitcastToAPInt().getZExtValue()); + if (!Val.isInt()) + return nullptr; + llvm::APSInt const &ValInt = Val.getInt(); std::optional ValIntOpt; if (ValInt.isUnsigned())