Skip to content

Commit 5a21933

Browse files
committed
[llvm] get cl::opt instantiations working with MSVC DLL build
1 parent 62f8377 commit 5a21933

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

llvm/include/llvm/Support/CommandLine.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,11 +1518,18 @@ class opt
15181518
[](const typename ParserClass::parser_data_type &) {};
15191519
};
15201520

1521-
extern template class opt<unsigned>;
1522-
extern template class opt<int>;
1523-
extern template class opt<std::string>;
1524-
extern template class opt<char>;
1525-
extern template class opt<bool>;
1521+
#if !defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) || \
1522+
!(defined(_MSC_VER) && !defined(__clang__))
1523+
// When DLL-exporting opt<std::string>, MSVC implicitly export std::basic_string
1524+
// because it is an ancestor. This situation leads to duplicate symbol errors at
1525+
// link time.
1526+
extern template class LLVM_TEMPLATE_ABI opt<std::string>;
1527+
#endif
1528+
1529+
extern template class LLVM_TEMPLATE_ABI opt<unsigned>;
1530+
extern template class LLVM_TEMPLATE_ABI opt<int>;
1531+
extern template class LLVM_TEMPLATE_ABI opt<char>;
1532+
extern template class LLVM_TEMPLATE_ABI opt<bool>;
15261533

15271534
//===----------------------------------------------------------------------===//
15281535
// Default storage class definition: external storage. This implementation

llvm/lib/Support/CommandLine.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,19 @@ template class LLVM_EXPORT_TEMPLATE basic_parser<float>;
6868
template class LLVM_EXPORT_TEMPLATE basic_parser<std::string>;
6969
template class LLVM_EXPORT_TEMPLATE basic_parser<char>;
7070

71-
template class opt<unsigned>;
72-
template class opt<int>;
73-
template class opt<std::string>;
74-
template class opt<char>;
75-
template class opt<bool>;
71+
#if !defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) || \
72+
!(defined(_MSC_VER) && !defined(__clang__))
73+
// When DLL-exporting opt<std::string>, MSVC implicitly export std::basic_string
74+
// because it is an ancestor. This situation leads to duplicate symbol errors at
75+
// link time.
76+
template class LLVM_EXPORT_TEMPLATE opt<std::string>;
77+
#endif
78+
79+
template class LLVM_EXPORT_TEMPLATE opt<bool>;
80+
template class LLVM_EXPORT_TEMPLATE opt<char>;
81+
template class LLVM_EXPORT_TEMPLATE opt<int>;
82+
template class LLVM_EXPORT_TEMPLATE opt<unsigned>;
83+
7684
} // namespace cl
7785
} // namespace llvm
7886

@@ -95,6 +103,16 @@ void parser<float>::anchor() {}
95103
void parser<std::string>::anchor() {}
96104
void parser<char>::anchor() {}
97105

106+
#if defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && defined(_MSC_VER) && \
107+
!defined(__clang__)
108+
// Force MSVC to export the vtable for the explicit opt instantiations above.
109+
// Without these references, they may be optimized out at link time.
110+
void opt_bool_anchor() { opt<bool> anchor{""}; }
111+
void opt_char_anchor() { opt<char> anchor{""}; }
112+
void opt_int_anchor() { opt<int> anchor{""}; }
113+
void opt_unsigned_anchor() { opt<unsigned> anchor{""}; }
114+
#endif
115+
98116
//===----------------------------------------------------------------------===//
99117

100118
const static size_t DefaultPad = 2;

0 commit comments

Comments
 (0)