summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorLouis Dionne <ldionne@apple.com>2018-10-04 15:49:42 +0000
committerLouis Dionne <ldionne@apple.com>2018-10-04 15:49:42 +0000
commit59e8cd87d4c8c90562715567dab1297c3d498a0c (patch)
tree71a61aea8b184c380ffff2f2fddeebfd1e4126d9 /lib/Sema/SemaTemplateInstantiate.cpp
parent53a522e1306aff01960a0249ffe8bbd704e7abbe (diff)
[clang] Add the exclude_from_explicit_instantiation attribute
Summary: This attribute allows excluding a member of a class template from being part of an explicit template instantiation of that class template. This also makes sure that code using such a member will not take for granted that an external instantiation exists in another translation unit. The attribute was discussed on cfe-dev at [1] and is primarily motivated by the removal of always_inline in libc++ to control what's part of the ABI (see links in [1]). [1]: http://lists.llvm.org/pipermail/cfe-dev/2018-August/059024.html rdar://problem/43428125 Reviewers: rsmith Subscribers: dexonsmith, cfe-commits Differential Revision: https://reviews.llvm.org/D51789 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@343790 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 5666cf04a2..cfedf0a099 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2574,10 +2574,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
for (auto *D : Instantiation->decls()) {
bool SuppressNew = false;
if (auto *Function = dyn_cast<FunctionDecl>(D)) {
- if (FunctionDecl *Pattern
- = Function->getInstantiatedFromMemberFunction()) {
- MemberSpecializationInfo *MSInfo
- = Function->getMemberSpecializationInfo();
+ if (FunctionDecl *Pattern =
+ Function->getInstantiatedFromMemberFunction()) {
+
+ if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+ continue;
+
+ MemberSpecializationInfo *MSInfo =
+ Function->getMemberSpecializationInfo();
assert(MSInfo && "No member specialization information?");
if (MSInfo->getTemplateSpecializationKind()
== TSK_ExplicitSpecialization)
@@ -2618,6 +2622,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
continue;
if (Var->isStaticDataMember()) {
+ if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+ continue;
+
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
assert(MSInfo && "No member specialization information?");
if (MSInfo->getTemplateSpecializationKind()
@@ -2649,6 +2656,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
}
}
} else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) {
+ if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+ continue;
+
// Always skip the injected-class-name, along with any
// redeclarations of nested classes, since both would cause us
// to try to instantiate the members of a class twice.