This revision was automatically updated to reflect the committed changes.
Closed by commit rGa088766508aa: [dllexport] Instantiate default ctor default
args for explicit specializations… (authored by hans).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91089/new/
https://reviews.llvm.org/D91089
Files:
clang/include/clang/Sema/Sema.h
clang/lib/CodeGen/MicrosoftCXXABI.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
clang/test/SemaCXX/dllexport.cpp
Index: clang/test/SemaCXX/dllexport.cpp
===================================================================
--- clang/test/SemaCXX/dllexport.cpp
+++ clang/test/SemaCXX/dllexport.cpp
@@ -792,6 +792,11 @@
};
template struct HasDefaults2<void>; // expected-note {{in instantiation of member function 'HasDefaults2<void>::HasDefaults2' requested here}}
+template <typename T> struct __declspec(dllexport) HasDefaults3 { // expected-note{{in instantiation of default function argument expression for 'HasDefaults3<void>' required here}}
+ HasDefaults3(int x = sizeof(T)) {} // expected-error {{invalid application of 'sizeof'}}
+};
+template <> HasDefaults3<void>::HasDefaults3(int) {};
+
#endif
//===----------------------------------------------------------------------===//
Index: clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
===================================================================
--- clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
+++ clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
@@ -50,6 +50,14 @@
// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_F?$TemplateWithClosure@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
// CHECK: call {{.*}} @"??0?$TemplateWithClosure@H@@QAE@H@Z"({{.*}}, i32 4)
+template <typename T> struct __declspec(dllexport) ExportedTemplateWithClosure {
+ ExportedTemplateWithClosure(int x = sizeof(T)) {}
+};
+template <> ExportedTemplateWithClosure<int>::ExportedTemplateWithClosure(int); // Don't try to emit the closure for a declaration.
+template <> ExportedTemplateWithClosure<int>::ExportedTemplateWithClosure(int) {};
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_F?$ExportedTemplateWithClosure@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK: call {{.*}} @"??0?$ExportedTemplateWithClosure@H@@QAE@H@Z"({{.*}}, i32 4)
+
struct __declspec(dllexport) NestedOuter {
DELETE_IMPLICIT_MEMBERS(NestedOuter);
NestedOuter(void *p = 0) {}
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -715,6 +715,26 @@
}
}
+/// In the MS ABI, we need to instantiate default arguments of dllexported
+/// default constructors along with the constructor definition. This allows IR
+/// gen to emit a constructor closure which calls the default constructor with
+/// its default arguments.
+void Sema::InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl *Ctor) {
+ assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ Ctor->isDefaultConstructor());
+ unsigned NumParams = Ctor->getNumParams();
+ if (NumParams == 0)
+ return;
+ DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>();
+ if (!Attr)
+ return;
+ for (unsigned I = 0; I != NumParams; ++I) {
+ (void)CheckCXXDefaultArgExpr(Attr->getLocation(), Ctor,
+ Ctor->getParamDecl(I));
+ DiscardCleanupsInEvaluationContext();
+ }
+}
+
/// Get the previous declaration of a declaration for the purposes of template
/// instantiation. If this finds a previous declaration, then the previous
/// declaration of the instantiation of D should be an instantiation of the
@@ -4608,27 +4628,6 @@
return cast_or_null<FunctionDecl>(SubstDecl(FD, FD->getParent(), MArgs));
}
-/// In the MS ABI, we need to instantiate default arguments of dllexported
-/// default constructors along with the constructor definition. This allows IR
-/// gen to emit a constructor closure which calls the default constructor with
-/// its default arguments.
-static void InstantiateDefaultCtorDefaultArgs(Sema &S,
- CXXConstructorDecl *Ctor) {
- assert(S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- Ctor->isDefaultConstructor());
- unsigned NumParams = Ctor->getNumParams();
- if (NumParams == 0)
- return;
- DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>();
- if (!Attr)
- return;
- for (unsigned I = 0; I != NumParams; ++I) {
- (void)S.CheckCXXDefaultArgExpr(Attr->getLocation(), Ctor,
- Ctor->getParamDecl(I));
- S.DiscardCleanupsInEvaluationContext();
- }
-}
-
/// Instantiate the definition of the given function from its
/// template.
///
@@ -4847,7 +4846,7 @@
// default arguments.
if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
Ctor->isDefaultConstructor()) {
- InstantiateDefaultCtorDefaultArgs(*this, Ctor);
+ InstantiateDefaultCtorDefaultArgs(Ctor);
}
}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13994,6 +13994,16 @@
FD->setInvalidDecl();
}
+ if (auto *Ctor = dyn_cast<CXXConstructorDecl>(FD)) {
+ if (Ctor->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
+ Ctor->isDefaultConstructor() &&
+ Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ // If this is an MS ABI dllexport default constructor, instantiate any
+ // default arguments.
+ InstantiateDefaultCtorDefaultArgs(Ctor);
+ }
+ }
+
// See if this is a redefinition. If 'will have body' (or similar) is already
// set, then these checks were already performed when it was set.
if (!FD->willHaveBody() && !FD->isLateTemplateParsed() &&
Index: clang/lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1244,12 +1244,14 @@
// the typical calling convention and have a single 'this' pointer for an
// argument -or- they get a wrapper function which appropriately thunks to the
// real default constructor. This thunk is the default constructor closure.
- if (D->hasAttr<DLLExportAttr>() && D->isDefaultConstructor())
+ if (D->hasAttr<DLLExportAttr>() && D->isDefaultConstructor() &&
+ D->isDefined()) {
if (!hasDefaultCXXMethodCC(getContext(), D) || D->getNumParams() != 0) {
llvm::Function *Fn = getAddrOfCXXCtorClosure(D, Ctor_DefaultClosure);
Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
CGM.setGVProperties(Fn, D);
}
+ }
}
void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -9253,6 +9253,8 @@
LateInstantiatedAttrVec *LateAttrs = nullptr,
LocalInstantiationScope *OuterMostScope = nullptr);
+ void InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl *Ctor);
+
bool usesPartialOrExplicitSpecialization(
SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits