[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

llvm-svn: 343790
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index ccbbe50..a9c5f7d 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -644,7 +644,8 @@
         continue;
       if (FD->isExternallyVisible() &&
           !isExternalWithNoLinkageType(FD) &&
-          !FD->getMostRecentDecl()->isInlined())
+          !FD->getMostRecentDecl()->isInlined() &&
+          !FD->hasAttr<ExcludeFromExplicitInstantiationAttr>())
         continue;
       if (FD->getBuiltinID())
         continue;
@@ -654,7 +655,8 @@
         continue;
       if (VD->isExternallyVisible() &&
           !isExternalWithNoLinkageType(VD) &&
-          !VD->getMostRecentDecl()->isInline())
+          !VD->getMostRecentDecl()->isInline() &&
+          !VD->hasAttr<ExcludeFromExplicitInstantiationAttr>())
         continue;
 
       // Skip VarDecls that lack formal definitions but which we know are in