[clang] [llvm] [llvm] minor fixes for clang-cl Windows DLL build (PR #144386)
Andrew Rogers via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 16 09:29:40 PDT 2025
https://github.com/andrurogerz created https://github.com/llvm/llvm-project/pull/144386
## Purpose
This patch makes a minor changes to LLVM and Clang so that LLVM can be built as a Windows DLL with `clang-cl`. These changes were not required for building a Windows DLL with MSVC.
## Background
The Windows DLL effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).
## Overview
Specific changes made in this patch:
- Remove `constexpr` fields that reference DLL exported symbols. These symbols cannot be resolved at compile time when building a Windows DLL using `clang-cl`, so they cannot be `constexpr`. Instead, they are made `const` and initialized in the implementation file rather than at declaration in the header.
- Annotate symbols now defined out-of-line with `LLVM_ABI` so they are exported when building as a shared library.
- Explicitly add default copy assignment operator for `ELFFile` to resolve a compiler warning.
## Validation
Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations:
- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang
>From 50a64efe33d38b2cd8cc268908dd6bcbd55c0c97 Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Tue, 10 Jun 2025 12:49:55 -0700
Subject: [PATCH 1/2] constexpr fixes for clang-cl Windows DLL build
---
.../lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp | 2 +-
llvm/include/llvm/BinaryFormat/Dwarf.h | 12 ++++++------
llvm/lib/BinaryFormat/Dwarf.cpp | 12 ++++++++++++
3 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp b/clang/lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp
index 836fc375809ad..f965bfb590d80 100644
--- a/clang/lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp
@@ -92,7 +92,7 @@ void Z3CrosscheckVisitor::finalizeVisitor(BugReporterContext &BRC,
};
auto AttemptOnce = [&](const llvm::SMTSolverRef &Solver) -> Z3Result {
- constexpr auto getCurrentTime = llvm::TimeRecord::getCurrentTime;
+ auto getCurrentTime = llvm::TimeRecord::getCurrentTime;
unsigned InitialRLimit = GetUsedRLimit(Solver);
double Start = getCurrentTime(/*Start=*/true).getWallTime();
std::optional<bool> IsSAT = Solver->check();
diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h
index 2ead62025efa7..231b7ac17d75f 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.h
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -1191,32 +1191,32 @@ template <typename Enum> struct EnumTraits : public std::false_type {};
template <> struct EnumTraits<Attribute> : public std::true_type {
static constexpr char Type[3] = "AT";
- static constexpr StringRef (*StringFn)(unsigned) = &AttributeString;
+ LLVM_ABI static StringRef (*const StringFn)(unsigned);
};
template <> struct EnumTraits<Form> : public std::true_type {
static constexpr char Type[5] = "FORM";
- static constexpr StringRef (*StringFn)(unsigned) = &FormEncodingString;
+ LLVM_ABI static StringRef (*const StringFn)(unsigned);
};
template <> struct EnumTraits<Index> : public std::true_type {
static constexpr char Type[4] = "IDX";
- static constexpr StringRef (*StringFn)(unsigned) = &IndexString;
+ LLVM_ABI static StringRef (*const StringFn)(unsigned);
};
template <> struct EnumTraits<Tag> : public std::true_type {
static constexpr char Type[4] = "TAG";
- static constexpr StringRef (*StringFn)(unsigned) = &TagString;
+ LLVM_ABI static StringRef (*const StringFn)(unsigned);
};
template <> struct EnumTraits<LineNumberOps> : public std::true_type {
static constexpr char Type[4] = "LNS";
- static constexpr StringRef (*StringFn)(unsigned) = &LNStandardString;
+ LLVM_ABI static StringRef (*const StringFn)(unsigned);
};
template <> struct EnumTraits<LocationAtom> : public std::true_type {
static constexpr char Type[3] = "OP";
- static constexpr StringRef (*StringFn)(unsigned) = &OperationEncodingString;
+ LLVM_ABI static StringRef (*const StringFn)(unsigned);
};
inline uint64_t computeTombstoneAddress(uint8_t AddressByteSize) {
diff --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp
index b9b10a541b263..0d17dc175fed9 100644
--- a/llvm/lib/BinaryFormat/Dwarf.cpp
+++ b/llvm/lib/BinaryFormat/Dwarf.cpp
@@ -911,6 +911,18 @@ StringRef llvm::dwarf::RLEString(unsigned RLE) {
}
}
+StringRef (*const llvm::dwarf::EnumTraits<Tag>::StringFn)(unsigned) = TagString;
+StringRef (*const llvm::dwarf::EnumTraits<Attribute>::StringFn)(unsigned) =
+ AttributeString;
+StringRef (*const llvm::dwarf::EnumTraits<Form>::StringFn)(unsigned) =
+ FormEncodingString;
+StringRef (*const llvm::dwarf::EnumTraits<LocationAtom>::StringFn)(unsigned) =
+ OperationEncodingString;
+StringRef (*const llvm::dwarf::EnumTraits<LineNumberOps>::StringFn)(unsigned) =
+ LNStandardString;
+StringRef (*const llvm::dwarf::EnumTraits<Index>::StringFn)(unsigned) =
+ IndexString;
+
constexpr char llvm::dwarf::EnumTraits<Attribute>::Type[];
constexpr char llvm::dwarf::EnumTraits<Form>::Type[];
constexpr char llvm::dwarf::EnumTraits<Index>::Type[];
>From 3654d9f0144c5339452157bddddf191688786c6d Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Wed, 11 Jun 2025 10:31:47 -0700
Subject: [PATCH 2/2] add default copy assignment operator to ELFFile for
clang-cl warning
---
llvm/include/llvm/Object/ELF.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h
index a0dc522e13cab..8d7545144dfd9 100644
--- a/llvm/include/llvm/Object/ELF.h
+++ b/llvm/include/llvm/Object/ELF.h
@@ -256,8 +256,10 @@ class ELFFile {
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- // Default ctor required to instantiate the template for DLL export.
+ // Default ctor and copy assignment operator required to instantiate the
+ // template for DLL export.
ELFFile(const ELFFile &) = default;
+ ELFFile &operator=(const ELFFile &) = default;
// This is a callback that can be passed to a number of functions.
// It can be used to ignore non-critical errors (warnings), which is
More information about the llvm-commits
mailing list