I just saw this. Simon Pilgrim already fixed it in r343846. Thanks Simon! Louis
> On Oct 4, 2018, at 22:02, Galina Kistanova <gkistan...@gmail.com> wrote: > > Hello Louis, > > This commit broke build step on one of our builders: > http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/13042 > > <http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/13042> > > . . . > FAILED: tools/clang/lib/Sema/CMakeFiles/clangSema.dir/SemaExprCXX.cpp.obj > C:\PROGRA~2\MICROS~1.0\VC\bin\amd64\cl.exe /nologo /TP -DEXPENSIVE_CHECKS > -DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE > -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE > -D_CRT_SECURE_NO_WARNINGS -D_GLIBCXX_DEBUG -D_GNU_SOURCE -D_HAS_EXCEPTIONS=0 > -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE > -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS > -Itools\clang\lib\Sema > -IC:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\lib\Sema > > -IC:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\include > -Itools\clang\include -Iinclude > -IC:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\include > /DWIN32 /D_WINDOWS /Zc:inline /Zc:strictStrings /Oi /Zc:rvalueCast /W4 > -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 > -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 > -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 > -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 > -wd4592 -wd4319 -wd4324 -w14062 -we4238 /MDd /Zi /Ob0 /Od /RTC1 /EHs-c- > /GR- /showIncludes > /Fotools\clang\lib\Sema\CMakeFiles\clangSema.dir\SemaExprCXX.cpp.obj > /Fdtools\clang\lib\Sema\CMakeFiles\clangSema.dir\clangSema.pdb /FS -c > C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp > C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp > : fatal error C1128: number of sections exceeded object file format limit: > compile with /bigobj > > > Please have a look? > The builder was already red and did not send notifications on this. > > Thanks > > Galina > > On Thu, Oct 4, 2018 at 8:51 AM Louis Dionne via cfe-commits > <cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>> wrote: > Author: ldionne > Date: Thu Oct 4 08:49:42 2018 > New Revision: 343790 > > URL: http://llvm.org/viewvc/llvm-project?rev=343790&view=rev > <http://llvm.org/viewvc/llvm-project?rev=343790&view=rev> > Log: > [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 > <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 > <https://reviews.llvm.org/D51789> > > Added: > > cfe/trunk/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp > > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp > > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp > > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp > > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp > Modified: > cfe/trunk/include/clang/Basic/Attr.td > cfe/trunk/include/clang/Basic/AttrDocs.td > cfe/trunk/lib/Sema/Sema.cpp > cfe/trunk/lib/Sema/SemaDeclAttr.cpp > cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp > cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test > > Modified: cfe/trunk/include/clang/Basic/Attr.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=343790&r1=343789&r2=343790&view=diff > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=343790&r1=343789&r2=343790&view=diff> > ============================================================================== > --- cfe/trunk/include/clang/Basic/Attr.td (original) > +++ cfe/trunk/include/clang/Basic/Attr.td Thu Oct 4 08:49:42 2018 > @@ -3042,6 +3042,13 @@ def InternalLinkage : InheritableAttr { > let Documentation = [InternalLinkageDocs]; > } > > +def ExcludeFromExplicitInstantiation : InheritableAttr { > + let Spellings = [Clang<"exclude_from_explicit_instantiation">]; > + let Subjects = SubjectList<[Var, Function, CXXRecord]>; > + let Documentation = [ExcludeFromExplicitInstantiationDocs]; > + let MeaningfulToClassTemplateDefinition = 1; > +} > + > def Reinitializes : InheritableAttr { > let Spellings = [Clang<"reinitializes", 0>]; > let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>; > > Modified: cfe/trunk/include/clang/Basic/AttrDocs.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=343790&r1=343789&r2=343790&view=diff > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=343790&r1=343789&r2=343790&view=diff> > ============================================================================== > --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) > +++ cfe/trunk/include/clang/Basic/AttrDocs.td Thu Oct 4 08:49:42 2018 > @@ -2975,6 +2975,68 @@ This can be used to contain the ABI of a > }]; > } > > +def ExcludeFromExplicitInstantiationDocs : Documentation { > + let Category = DocCatFunction; > + let Content = [{ > +The ``exclude_from_explicit_instantiation`` attribute opts-out a member of a > +class template from being part of explicit template instantiations of that > +class template. This means that an explicit instantiation will not > instantiate > +members of the class template marked with the attribute, but also that code > +where an extern template declaration of the enclosing class template is > visible > +will not take for granted that an external instantiation of the class > template > +would provide those members (which would otherwise be a link error, since the > +explicit instantiation won't provide those members). For example, let's say > we > +don't want the ``data()`` method to be part of libc++'s ABI. To make sure it > +is not exported from the dylib, we give it hidden visibility: > + > + .. code-block:: c++ > + > + // in <string> > + template <class CharT> > + class basic_string { > + public: > + __attribute__((__visibility__("hidden"))) > + const value_type* data() const noexcept { ... } > + }; > + > + template class basic_string<char>; > + > +Since an explicit template instantiation declaration for > ``basic_string<char>`` > +is provided, the compiler is free to assume that > ``basic_string<char>::data()`` > +will be provided by another translation unit, and it is free to produce an > +external call to this function. However, since ``data()`` has hidden > visibility > +and the explicit template instantiation is provided in a shared library (as > +opposed to simply another translation unit), ``basic_string<char>::data()`` > +won't be found and a link error will ensue. This happens because the compiler > +assumes that ``basic_string<char>::data()`` is part of the explicit template > +instantiation declaration, when it really isn't. To tell the compiler that > +``data()`` is not part of the explicit template instantiation declaration, > the > +``exclude_from_explicit_instantiation`` attribute can be used: > + > + .. code-block:: c++ > + > + // in <string> > + template <class CharT> > + class basic_string { > + public: > + __attribute__((__visibility__("hidden"))) > + __attribute__((exclude_from_explicit_instantiation)) > + const value_type* data() const noexcept { ... } > + }; > + > + template class basic_string<char>; > + > +Now, the compiler won't assume that ``basic_string<char>::data()`` is > provided > +externally despite there being an explicit template instantiation > declaration: > +the compiler will implicitly instantiate ``basic_string<char>::data()`` in > the > +TUs where it is used. > + > +This attribute can be used on static and non-static member functions of class > +templates, static data members of class templates and member classes of class > +templates. > + }]; > +} > + > def DisableTailCallsDocs : Documentation { > let Category = DocCatFunction; > let Content = [{ > > Modified: cfe/trunk/lib/Sema/Sema.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=343790&r1=343789&r2=343790&view=diff > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=343790&r1=343789&r2=343790&view=diff> > ============================================================================== > --- cfe/trunk/lib/Sema/Sema.cpp (original) > +++ cfe/trunk/lib/Sema/Sema.cpp Thu Oct 4 08:49:42 2018 > @@ -644,7 +644,8 @@ void Sema::getUndefinedButUsed( > continue; > if (FD->isExternallyVisible() && > !isExternalWithNoLinkageType(FD) && > - !FD->getMostRecentDecl()->isInlined()) > + !FD->getMostRecentDecl()->isInlined() && > + !FD->hasAttr<ExcludeFromExplicitInstantiationAttr>()) > continue; > if (FD->getBuiltinID()) > continue; > @@ -654,7 +655,8 @@ void Sema::getUndefinedButUsed( > 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 > > Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=343790&r1=343789&r2=343790&view=diff > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=343790&r1=343789&r2=343790&view=diff> > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Oct 4 08:49:42 2018 > @@ -6512,6 +6512,9 @@ static void ProcessDeclAttribute(Sema &S > case ParsedAttr::AT_InternalLinkage: > handleInternalLinkageAttr(S, D, AL); > break; > + case ParsedAttr::AT_ExcludeFromExplicitInstantiation: > + handleSimpleAttribute<ExcludeFromExplicitInstantiationAttr>(S, D, AL); > + break; > case ParsedAttr::AT_LTOVisibilityPublic: > handleSimpleAttribute<LTOVisibilityPublicAttr>(S, D, AL); > break; > > Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=343790&r1=343789&r2=343790&view=diff > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=343790&r1=343789&r2=343790&view=diff> > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Oct 4 08:49:42 2018 > @@ -2574,10 +2574,14 @@ Sema::InstantiateClassMembers(SourceLoca > 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(SourceLoca > 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(SourceLoca > } > } > } 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. > > Added: > cfe/trunk/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp?rev=343790&view=auto > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp?rev=343790&view=auto> > ============================================================================== > --- > cfe/trunk/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp > (added) > +++ > cfe/trunk/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp > Thu Oct 4 08:49:42 2018 > @@ -0,0 +1,84 @@ > +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -O0 -o - %s | > FileCheck %s > + > +// Test that we do not assume that entities marked with the > +// exclude_from_explicit_instantiation attribute are instantiated > +// in another TU when an extern template instantiation declaration > +// is present. We test that by making sure that definitions are > +// generated in this TU despite there being an extern template > +// instantiation declaration, which is normally not the case. > + > +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION > __attribute__((exclude_from_explicit_instantiation)) > + > +template <class T> > +struct Foo { > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void > non_static_member_function1(); > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void > non_static_member_function2(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void > static_member_function1(); > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void > static_member_function2(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; > + > + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 { > + static void static_member_function() { } > + }; > + > + struct member_class2 { > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function() > { } > + }; > +}; > + > +template <class T> inline void Foo<T>::non_static_member_function1() { } > +template <class T> void Foo<T>::non_static_member_function2() { } > + > +template <class T> inline void Foo<T>::static_member_function1() { } > +template <class T> void Foo<T>::static_member_function2() { } > + > +template <class T> int Foo<T>::static_data_member = 0; > + > +extern template struct Foo<int>; > + > +void use() { > + Foo<int> f; > + > + // An inline non-static member function marked with the attribute is not > + // part of the extern template declaration, so a definition must be emitted > + // in this TU. > + // CHECK-DAG: define linkonce_odr void > @_ZN3FooIiE27non_static_member_function1Ev > + f.non_static_member_function1(); > + > + // A non-inline non-static member function marked with the attribute is > + // not part of the extern template declaration, so a definition must be > + // emitted in this TU. > + // CHECK-DAG: define linkonce_odr void > @_ZN3FooIiE27non_static_member_function2Ev > + f.non_static_member_function2(); > + > + // An inline static member function marked with the attribute is not > + // part of the extern template declaration, so a definition must be > + // emitted in this TU. > + // CHECK-DAG: define linkonce_odr void > @_ZN3FooIiE23static_member_function1Ev > + Foo<int>::static_member_function1(); > + > + // A non-inline static member function marked with the attribute is not > + // part of the extern template declaration, so a definition must be > + // emitted in this TU. > + // CHECK-DAG: define linkonce_odr void > @_ZN3FooIiE23static_member_function2Ev > + Foo<int>::static_member_function2(); > + > + // A static data member marked with the attribute is not part of the > + // extern template declaration, so a definition must be emitted in this TU. > + // CHECK-DAG: @_ZN3FooIiE18static_data_memberE = linkonce_odr global > + int& odr_use = Foo<int>::static_data_member; > + > + // A member class marked with the attribute is not part of the extern > + // template declaration (it is not recursively instantiated), so its member > + // functions must be emitted in this TU. > + // CHECK-DAG: define linkonce_odr void > @_ZN3FooIiE13member_class122static_member_functionEv > + Foo<int>::member_class1::static_member_function(); > + > + // A member function marked with the attribute in a member class is not > + // part of the extern template declaration of the parent class template, so > + // it must be emitted in this TU. > + // CHECK-DAG: define linkonce_odr void > @_ZN3FooIiE13member_class222static_member_functionEv > + Foo<int>::member_class2::static_member_function(); > +} > > Modified: cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test?rev=343790&r1=343789&r2=343790&view=diff > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test?rev=343790&r1=343789&r2=343790&view=diff> > ============================================================================== > --- cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test > (original) > +++ cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test Thu > Oct 4 08:49:42 2018 > @@ -2,7 +2,7 @@ > > // The number of supported attributes should never go down! > > -// CHECK: #pragma clang attribute supports 128 attributes: > +// CHECK: #pragma clang attribute supports 129 attributes: > // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) > // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) > // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) > @@ -47,6 +47,7 @@ > // CHECK-NEXT: DisableTailCalls (SubjectMatchRule_function, > SubjectMatchRule_objc_method) > // CHECK-NEXT: EnableIf (SubjectMatchRule_function) > // CHECK-NEXT: EnumExtensibility (SubjectMatchRule_enum) > +// CHECK-NEXT: ExcludeFromExplicitInstantiation (SubjectMatchRule_variable, > SubjectMatchRule_function, SubjectMatchRule_record) > // CHECK-NEXT: ExternalSourceSymbol ((SubjectMatchRule_record, > SubjectMatchRule_enum, SubjectMatchRule_enum_constant, > SubjectMatchRule_field, SubjectMatchRule_function, > SubjectMatchRule_namespace, SubjectMatchRule_objc_category, > SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, > SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, > SubjectMatchRule_record, SubjectMatchRule_type_alias, > SubjectMatchRule_variable)) > // CHECK-NEXT: FlagEnum (SubjectMatchRule_enum) > // CHECK-NEXT: Flatten (SubjectMatchRule_function) > > Added: > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp?rev=343790&view=auto > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp?rev=343790&view=auto> > ============================================================================== > --- > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp > (added) > +++ > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.diagnose_on_undefined_entity.cpp > Thu Oct 4 08:49:42 2018 > @@ -0,0 +1,36 @@ > +// RUN: %clang_cc1 -fsyntax-only -Wundefined-func-template > -Wundefined-var-template -verify %s > + > +// Test that a diagnostic is emitted when an entity marked with the > +// exclude_from_explicit_instantiation attribute is not defined in > +// the current TU but it is used (and it is hence implicitly > +// instantiated). > + > +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION > __attribute__((exclude_from_explicit_instantiation)) > + > +template <class T> > +struct Foo { > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function(); // > expected-note{{forward declaration of template entity is here}} > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function(); > // expected-note{{forward declaration of template entity is here}} > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; // > expected-note{{forward declaration of template entity is here}} > + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION nested { > + static int static_member_function(); // expected-note{{forward > declaration of template entity is here}} > + }; > +}; > + > +extern template struct Foo<int>; > + > +void use() { > + Foo<int> foo; > + > + foo.non_static_member_function(); // expected-warning{{instantiation of > function 'Foo<int>::non_static_member_function' required here, but no > definition is available}} > + // expected-note@-1 {{add an explicit instantiation}} > + > + Foo<int>::static_member_function(); // expected-warning{{instantiation of > function 'Foo<int>::static_member_function' required here, but no definition > is available}} > + // expected-note@-1 {{add an explicit instantiation}} > + > + (void)Foo<int>::static_data_member; // expected-warning{{instantiation of > variable 'Foo<int>::static_data_member' required here, but no definition is > available}} > + // expected-note@-1 {{add an explicit instantiation}} > + > + Foo<int>::nested::static_member_function(); // > expected-warning{{instantiation of function > 'Foo<int>::nested::static_member_function' required here, but no definition > is available}} > + // expected-note@-1 {{add an explicit instantiation}} > +} > > Added: > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp?rev=343790&view=auto > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp?rev=343790&view=auto> > ============================================================================== > --- > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp > (added) > +++ > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.explicit_instantiation.cpp > Thu Oct 4 08:49:42 2018 > @@ -0,0 +1,45 @@ > +// RUN: %clang_cc1 -fsyntax-only -verify %s > + > +// Test that explicit instantiations do not instantiate entities > +// marked with the exclude_from_explicit_instantiation attribute. > + > +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION > __attribute__((exclude_from_explicit_instantiation)) > + > +template <class T> > +struct Foo { > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void > non_static_member_function1(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void > static_member_function1(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; > + > + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 { > + static void non_static_member_function() { using Fail = typename > T::fail; } > + }; > + > + struct member_class2 { > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void > non_static_member_function() { using Fail = typename T::fail; } > + }; > +}; > + > +template <class T> > +inline void Foo<T>::non_static_member_function1() { using Fail = typename > T::fail; } > + > +template <class T> > +void Foo<T>::non_static_member_function2() { using Fail = typename T::fail; } > + > +template <class T> > +inline void Foo<T>::static_member_function1() { using Fail = typename > T::fail; } > + > +template <class T> > +void Foo<T>::static_member_function2() { using Fail = typename T::fail; } > + > +template <class T> > +int Foo<T>::static_data_member = T::fail; > + > +// expected-no-diagnostics > +template struct Foo<int>; > > Added: > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp?rev=343790&view=auto > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp?rev=343790&view=auto> > ============================================================================== > --- > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp > (added) > +++ > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp > Thu Oct 4 08:49:42 2018 > @@ -0,0 +1,69 @@ > +// RUN: %clang_cc1 -Wno-unused-local-typedef -fsyntax-only -verify %s > + > +// Test that extern instantiation declarations cause members marked with > +// the exclude_from_explicit_instantiation attribute to be instantiated in > +// the current TU. > + > +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION > __attribute__((exclude_from_explicit_instantiation)) > + > +template <class T> > +struct Foo { > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void > non_static_member_function1(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void > static_member_function1(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2(); > + > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; > + > + struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 { > + static void static_member_function() { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > + } > + }; > + > + struct member_class2 { > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function() > { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > + } > + }; > +}; > + > +template <class T> > +inline void Foo<T>::non_static_member_function1() { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > +} > + > +template <class T> > +void Foo<T>::non_static_member_function2() { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > +} > + > +template <class T> > +inline void Foo<T>::static_member_function1() { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > +} > + > +template <class T> > +void Foo<T>::static_member_function2() { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > +} > + > +template <class T> > +int Foo<T>::static_data_member = T::invalid; // expected-error{{no member > named 'invalid' in 'Empty'}} > + > +struct Empty { }; > +extern template struct Foo<Empty>; > + > +int main() { > + Foo<Empty> foo; > + foo.non_static_member_function1(); // expected-note{{in > instantiation of}} > + foo.non_static_member_function2(); // expected-note{{in > instantiation of}} > + Foo<Empty>::static_member_function1(); // expected-note{{in > instantiation of}} > + Foo<Empty>::static_member_function2(); // expected-note{{in > instantiation of}} > + (void)foo.static_data_member; // expected-note{{in > instantiation of}} > + Foo<Empty>::member_class1::static_member_function(); // expected-note{{in > instantiation of}} > + Foo<Empty>::member_class2::static_member_function(); // expected-note{{in > instantiation of}} > +} > > Added: > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp?rev=343790&view=auto > > <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp?rev=343790&view=auto> > ============================================================================== > --- > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp > (added) > +++ > cfe/trunk/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp > Thu Oct 4 08:49:42 2018 > @@ -0,0 +1,43 @@ > +// RUN: %clang_cc1 -fsyntax-only -verify %s > + > +// Test that we properly merge the exclude_from_explicit_instantiation > +// attribute on redeclarations. > + > +#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION > __attribute__((exclude_from_explicit_instantiation)) > + > +template <class T> > +struct Foo { > + // Declaration without the attribute, definition with the attribute. > + void func1(); > + > + // Declaration with the attribute, definition without the attribute. > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void func2(); > + > + // Declaration with the attribute, definition with the attribute. > + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void func3(); > +}; > + > +template <class T> > +EXCLUDE_FROM_EXPLICIT_INSTANTIATION void Foo<T>::func1() { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > +} > + > +template <class T> > +void Foo<T>::func2() { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > +} > + > +template <class T> > +EXCLUDE_FROM_EXPLICIT_INSTANTIATION void Foo<T>::func3() { > + using Fail = typename T::invalid; // expected-error{{no type named > 'invalid' in 'Empty'}} > +} > + > +struct Empty { }; > +extern template struct Foo<Empty>; > + > +int main() { > + Foo<Empty> foo; > + foo.func1(); // expected-note{{in instantiation of}} > + foo.func2(); // expected-note{{in instantiation of}} > + foo.func3(); // expected-note{{in instantiation of}} > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits