diff options
author | Louis Dionne <ldionne@apple.com> | 2018-10-04 15:49:42 +0000 |
---|---|---|
committer | Louis Dionne <ldionne@apple.com> | 2018-10-04 15:49:42 +0000 |
commit | 59e8cd87d4c8c90562715567dab1297c3d498a0c (patch) | |
tree | 71a61aea8b184c380ffff2f2fddeebfd1e4126d9 /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 53a522e1306aff01960a0249ffe8bbd704e7abbe (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.cpp | 18 |
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. |