[PATCH] D70905: Actually delay processing DelayedDllExportClasses until the outermost class is finished (PR40006)
Hans Wennborg via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 2 07:56:02 PST 2019
hans created this revision.
hans added reviewers: rnk, rsmith.
This was already the intention of DelayedDllExportClasses, but this test case would break it:
template<typename> struct Tmpl {};
struct Outer {
struct Inner {
__declspec(dllexport) Inner() = default;
unsigned int x = 0;
};
Tmpl<Inner> y;
};
ActOnFinishCXXNonNestedClass() would get called when the instantiation of Templ<Inner> is finished, even though the compiler is still not finished with Outer, causing the compile fail.
This hooks into Sema::{Push,Pop}ParsingClass() to avoid calling ActOnFinishCXXNonNestedClass() for template instantiations while a class is being parsed.
This was the cleanest solution I could come up with :-)
https://reviews.llvm.org/D70905
Files:
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/CodeGenCXX/dllexport.cpp
Index: clang/test/CodeGenCXX/dllexport.cpp
===================================================================
--- clang/test/CodeGenCXX/dllexport.cpp
+++ clang/test/CodeGenCXX/dllexport.cpp
@@ -860,6 +860,20 @@
};
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.InClassInits::PR40006"* @"??0PR40006 at InClassInits@@QAE at XZ"
+namespace pr40006 {
+// Delay emitting the method also past the instantiation of Tmpl<Inner>, i.e.
+// until the top-level class Outer is completely finished.
+template<typename> struct Tmpl {};
+struct Outer {
+ struct Inner {
+ __declspec(dllexport) Inner() = default;
+ unsigned int x = 0;
+ };
+ Tmpl<Inner> y;
+};
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.InClassInits::pr40006::Outer::Inner"* @"??0Inner at Outer@pr40006 at InClassInits@@QAE at XZ"
+}
+
// PR42857: Clang would try to emit the non-trivial explicitly defaulted
// dllexport ctor twice when doing an explicit instantiation definition.
struct Qux { Qux(); };
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2226,8 +2226,10 @@
CheckCompletedCXXClass(Instantiation);
// Default arguments are parsed, if not instantiated. We can go instantiate
- // default arg exprs for default constructors if necessary now.
- ActOnFinishCXXNonNestedClass(Instantiation);
+ // default arg exprs for default constructors if necessary now. Unless we're
+ // parsing a class, in which case wait until that's finished.
+ if (ParsingClassDepth == 0)
+ ActOnFinishCXXNonNestedClass(Instantiation);
// Instantiate late parsed attributes, and attach them to their decls.
// See Sema::InstantiateAttrs
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -4335,9 +4335,11 @@
typedef ProcessingContextState ParsingClassState;
ParsingClassState PushParsingClass() {
+ ParsingClassDepth++;
return DelayedDiagnostics.pushUndelayed();
}
void PopParsingClass(ParsingClassState state) {
+ ParsingClassDepth--;
DelayedDiagnostics.popUndelayed(state);
}
@@ -11544,6 +11546,8 @@
SmallVector<CXXMethodDecl*, 4> DelayedDllExportMemberFunctions;
private:
+ int ParsingClassDepth = 0;
+
class SavePendingParsedClassStateRAII {
public:
SavePendingParsedClassStateRAII(Sema &S) : S(S) { swapSavedState(); }
@@ -11553,8 +11557,6 @@
"there shouldn't be any pending delayed exception spec checks");
assert(S.DelayedEquivalentExceptionSpecChecks.empty() &&
"there shouldn't be any pending delayed exception spec checks");
- assert(S.DelayedDllExportClasses.empty() &&
- "there shouldn't be any pending delayed DLL export classes");
swapSavedState();
}
@@ -11564,14 +11566,12 @@
SavedOverridingExceptionSpecChecks;
decltype(DelayedEquivalentExceptionSpecChecks)
SavedEquivalentExceptionSpecChecks;
- decltype(DelayedDllExportClasses) SavedDllExportClasses;
void swapSavedState() {
SavedOverridingExceptionSpecChecks.swap(
S.DelayedOverridingExceptionSpecChecks);
SavedEquivalentExceptionSpecChecks.swap(
S.DelayedEquivalentExceptionSpecChecks);
- SavedDllExportClasses.swap(S.DelayedDllExportClasses);
}
};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70905.231710.patch
Type: text/x-patch
Size: 3552 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191202/d7e2f503/attachment-0001.bin>
More information about the cfe-commits
mailing list