Skip to content

Instantly share code, notes, and snippets.

@kikairoya
Last active June 9, 2025 10:41
Show Gist options
  • Save kikairoya/97c6daea92b94db2d5b72fb200ddd1bd to your computer and use it in GitHub Desktop.
Save kikairoya/97c6daea92b94db2d5b72fb200ddd1bd to your computer and use it in GitHub Desktop.
#define EXPORT
#define EXTERN_TEMPLATE_VIS
#include "header.h"
#include <stdio.h>
void dll_fn() {
printf("dll:%p %p %p\n", &outer_template<int>::inner_class::static_var, outer_template<int>::fn_outer(), outer_template<int>::inner_class::fn_inner());
printf("oth:%p %p %p\n", &outer_template<char>::inner_class::static_var, outer_template<char>::fn_outer(), outer_template<char>::inner_class::fn_inner());
}
#define EXPORT __declspec(dllexport)
//#define EXPORT __attribute__((visibility("default")))
#define EXTERN_TEMPLATE_VIS EXPORT
#include "header.h"
template struct outer_template<int>;
#define EXPORT
#define EXTERN_TEMPLATE_VIS
#include "header.h"
#include <stdio.h>
void dll_fn();
int main() {
printf("exe:%p %p %p\n", &outer_template<int>::inner_class::static_var, outer_template<int>::fn_outer(), outer_template<int>::inner_class::fn_inner());
printf("oth:%p\n", outer_template<char>::fn_outer());
dll_fn();
}
template <typename T>
struct outer_template {
outer_template();
virtual ~outer_template() = default;
static T *fn_outer();
struct inner_class {
static T *fn_inner();
static T static_var;
inner_class();
//inner_class(inner_class &&);
virtual ~inner_class() = default;
};
};
template <typename T>
outer_template<T>::outer_template() {}
template <typename T>
T *outer_template<T>::fn_outer() { return &inner_class::static_var; }
template <typename T>
T *outer_template<T>::inner_class::fn_inner() { return &static_var; }
template <typename T>
T outer_template<T>::inner_class::static_var;
template <typename T>
outer_template<T>::inner_class::inner_class() {}
//template <typename T>
//outer_template<T>::inner_class::inner_class(inner_class &&) {}
extern template struct EXTERN_TEMPLATE_VIS outer_template<int>;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1bd9056cad81..cd84c306348d 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6588,6 +6588,15 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
// seem to be true in practice?
for (Decl *Member : Class->decls()) {
+ // TESTING: inherit dllimport/dllexport to nested class in mingw
+ if (Context.getTargetInfo().getTriple().isOSCygMing() && !getDLLAttr(Member)) {
+ if (isa<RecordDecl>(Member)) {
+ InheritableAttr *NewAttr = cast<InheritableAttr>(ClassAttr->clone(getASTContext()));
+ NewAttr->setInherited(true);
+ Member->addAttr(NewAttr);
+ continue;
+ }
+ }
VarDecl *VD = dyn_cast<VarDecl>(Member);
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment