Hi Serge, this complains on this snippet from v8:
template <LOperand::Kind kOperandKind, int kNumCachedOperands> class LSubKindOperand final : public LOperand { public: static LSubKindOperand* Create(int index, Zone* zone) { if (index < kNumCachedOperands) return &cache[index]; return new(zone) LSubKindOperand(index); } private: static LSubKindOperand* cache; explicit LSubKindOperand(int index); }; On Tue, Apr 19, 2016 at 2:19 AM, Serge Pavlov via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: sepavloff > Date: Tue Apr 19 01:19:52 2016 > New Revision: 266719 > > URL: http://llvm.org/viewvc/llvm-project?rev=266719&view=rev > Log: > Warn if function or variable cannot be implicitly instantiated > > With this patch compiler emits warning if it tries to make implicit > instantiation > of a template but cannot find the template definition. The warning can be > suppressed > by explicit instantiation declaration or by command line options > -Wundefined-var-template and -Wundefined-func-template. The implementation > follows > the discussion of http://reviews.llvm.org/D12326. > > Differential Revision: http://reviews.llvm.org/D16396 > > Added: > cfe/trunk/test/SemaTemplate/undefined-template.cpp > Modified: > cfe/trunk/include/clang/AST/DeclBase.h > cfe/trunk/include/clang/Basic/DiagnosticGroups.td > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/AST/DeclBase.cpp > cfe/trunk/lib/Sema/SemaOverload.cpp > cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp > cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp > cfe/trunk/test/OpenMP/parallel_ast_print.cpp > cfe/trunk/test/OpenMP/parallel_sections_ast_print.cpp > cfe/trunk/test/OpenMP/target_parallel_ast_print.cpp > cfe/trunk/test/OpenMP/task_ast_print.cpp > cfe/trunk/test/OpenMP/teams_ast_print.cpp > cfe/trunk/test/OpenMP/threadprivate_ast_print.cpp > cfe/trunk/test/SemaCXX/PR10177.cpp > cfe/trunk/test/SemaCXX/undefined-internal.cpp > > Modified: cfe/trunk/include/clang/AST/DeclBase.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclBase.h (original) > +++ cfe/trunk/include/clang/AST/DeclBase.h Tue Apr 19 01:19:52 2016 > @@ -52,6 +52,7 @@ struct PrintingPolicy; > class RecordDecl; > class Stmt; > class StoredDeclsMap; > +class TemplateDecl; > class TranslationUnitDecl; > class UsingDirectiveDecl; > } > @@ -905,6 +906,10 @@ public: > DeclKind == FunctionTemplate; > } > > + /// \brief If this is a declaration that describes some template, this > + /// method returns that template declaration. > + TemplateDecl *getDescribedTemplate() const; > + > /// \brief Returns the function itself, or the templated function if > this is a > /// function template. > FunctionDecl *getAsFunction() LLVM_READONLY; > > Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Apr 19 01:19:52 > 2016 > @@ -75,6 +75,8 @@ def : DiagGroup<"ctor-dtor-privacy">; > def GNUDesignator : DiagGroup<"gnu-designator">; > def GNUStringLiteralOperatorTemplate : > DiagGroup<"gnu-string-literal-operator-template">; > +def UndefinedVarTemplate : DiagGroup<"undefined-var-template">; > +def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">; > > def DeleteIncomplete : DiagGroup<"delete-incomplete">; > def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">; > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Apr 19 > 01:19:52 2016 > @@ -3883,7 +3883,18 @@ def note_template_type_alias_instantiati > "in instantiation of template type alias %0 requested here">; > def note_template_exception_spec_instantiation_here : Note< > "in instantiation of exception specification for %0 requested here">; > - > +def warn_var_template_missing : Warning<"instantiation of variable %q0 " > + "required here, but no definition is available">, > + InGroup<UndefinedVarTemplate>; > +def warn_func_template_missing : Warning<"instantiation of function %q0 " > + "required here, but no definition is available">, > + InGroup<UndefinedFuncTemplate>, DefaultIgnore; > +def note_forward_template_decl : Note< > + "forward declaration of template entity is here">; > +def note_inst_declaration_hint : Note<"add an explicit instantiation " > + "declaration to suppress this warning if %q0 is explicitly instantiated > in " > + "another translation unit">; > + > def note_default_arg_instantiation_here : Note< > "in instantiation of default argument for '%0' required here">; > def note_default_function_arg_instantiation_here : Note< > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Tue Apr 19 01:19:52 2016 > @@ -7171,7 +7171,8 @@ public: > void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, > FunctionDecl *Function, > bool Recursive = false, > - bool DefinitionRequired = false); > + bool DefinitionRequired = false, > + bool AtEndOfTU = false); > VarTemplateSpecializationDecl *BuildVarTemplateInstantiation( > VarTemplateDecl *VarTemplate, VarDecl *FromVar, > const TemplateArgumentList &TemplateArgList, > @@ -7195,7 +7196,8 @@ public: > const MultiLevelTemplateArgumentList &TemplateArgs); > void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, > VarDecl *Var, bool Recursive = false, > - bool DefinitionRequired = false); > + bool DefinitionRequired = false, > + bool AtEndOfTU = false); > void InstantiateStaticDataMemberDefinition( > SourceLocation PointOfInstantiation, > VarDecl *Var, > > Modified: cfe/trunk/lib/AST/DeclBase.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/DeclBase.cpp (original) > +++ cfe/trunk/lib/AST/DeclBase.cpp Tue Apr 19 01:19:52 2016 > @@ -196,6 +196,17 @@ bool Decl::isTemplateDecl() const { > return isa<TemplateDecl>(this); > } > > +TemplateDecl *Decl::getDescribedTemplate() const { > + if (auto *FD = dyn_cast<FunctionDecl>(this)) > + return FD->getDescribedFunctionTemplate(); > + else if (auto *RD = dyn_cast<CXXRecordDecl>(this)) > + return RD->getDescribedClassTemplate(); > + else if (auto *VD = dyn_cast<VarDecl>(this)) > + return VD->getDescribedVarTemplate(); > + > + return nullptr; > +} > + > const DeclContext *Decl::getParentFunctionOrMethod() const { > for (const DeclContext *DC = getDeclContext(); > DC && !DC->isTranslationUnit() && !DC->isNamespace(); > > Modified: cfe/trunk/lib/Sema/SemaOverload.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) > +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Apr 19 01:19:52 2016 > @@ -9324,11 +9324,8 @@ static void DiagnoseArityMismatch(Sema & > } > > static TemplateDecl *getDescribedTemplate(Decl *Templated) { > - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Templated)) > - return FD->getDescribedFunctionTemplate(); > - else if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Templated)) > - return RD->getDescribedClassTemplate(); > - > + if (TemplateDecl *TD = Templated->getDescribedTemplate()) > + return TD; > llvm_unreachable("Unsupported: Getting the described template > declaration" > " for bad deduction diagnosis"); > } > > Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Apr 19 01:19:52 > 2016 > @@ -3530,7 +3530,8 @@ TemplateDeclInstantiator::InitMethodInst > void Sema::InstantiateFunctionDefinition(SourceLocation > PointOfInstantiation, > FunctionDecl *Function, > bool Recursive, > - bool DefinitionRequired) { > + bool DefinitionRequired, > + bool AtEndOfTU) { > if (Function->isInvalidDecl() || Function->isDefined()) > return; > > @@ -3604,6 +3605,16 @@ void Sema::InstantiateFunctionDefinition > assert(!Recursive); > PendingInstantiations.push_back( > std::make_pair(Function, PointOfInstantiation)); > + } else if (Function->getTemplateSpecializationKind() > + == TSK_ImplicitInstantiation) { > + if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) { > + Diag(PointOfInstantiation, diag::warn_func_template_missing) > + << Function; > + Diag(PatternDecl->getLocation(), > diag::note_forward_template_decl); > + if (getLangOpts().CPlusPlus11) > + Diag(PointOfInstantiation, diag::note_inst_declaration_hint) > + << Function; > + } > } > > return; > @@ -3951,7 +3962,7 @@ void Sema::InstantiateStaticDataMemberDe > > void Sema::InstantiateVariableDefinition(SourceLocation > PointOfInstantiation, > VarDecl *Var, bool Recursive, > - bool DefinitionRequired) { > + bool DefinitionRequired, bool > AtEndOfTU) { > if (Var->isInvalidDecl()) > return; > > @@ -4083,6 +4094,16 @@ void Sema::InstantiateVariableDefinition > == TSK_ExplicitInstantiationDefinition) { > PendingInstantiations.push_back( > std::make_pair(Var, PointOfInstantiation)); > + } else if (Var->getTemplateSpecializationKind() > + == TSK_ImplicitInstantiation) { > + // Warn about missing definition at the end of translation unit. > + if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) { > + Diag(PointOfInstantiation, diag::warn_var_template_missing) > + << Var; > + Diag(PatternDecl->getLocation(), > diag::note_forward_template_decl); > + if (getLangOpts().CPlusPlus11) > + Diag(PointOfInstantiation, diag::note_inst_declaration_hint) << > Var; > + } > } > > return; > @@ -4852,7 +4873,7 @@ void Sema::PerformPendingInstantiations( > bool DefinitionRequired = Function->getTemplateSpecializationKind() > == > TSK_ExplicitInstantiationDefinition; > InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true, > - DefinitionRequired); > + DefinitionRequired, true); > continue; > } > > @@ -4893,7 +4914,7 @@ void Sema::PerformPendingInstantiations( > // Instantiate static data member definitions or variable template > // specializations. > InstantiateVariableDefinition(/*FIXME:*/ Inst.second, Var, true, > - DefinitionRequired); > + DefinitionRequired, true); > } > } > > > Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp (original) > +++ cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp Tue Apr 19 01:19:52 > 2016 > @@ -10,6 +10,7 @@ template <class T> struct A { > } > }; > }; > +extern template bool A<bool>::cond; > > int foo() { > A<bool>::cond = true; > > Modified: cfe/trunk/test/OpenMP/parallel_ast_print.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_ast_print.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/parallel_ast_print.cpp (original) > +++ cfe/trunk/test/OpenMP/parallel_ast_print.cpp Tue Apr 19 01:19:52 2016 > @@ -227,4 +227,7 @@ void foo(const Foo<int> &arg) { > } > } > > +template<typename T> > +T S<T>::TS = 0; > + > #endif > > Modified: cfe/trunk/test/OpenMP/parallel_sections_ast_print.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_sections_ast_print.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/parallel_sections_ast_print.cpp (original) > +++ cfe/trunk/test/OpenMP/parallel_sections_ast_print.cpp Tue Apr 19 > 01:19:52 2016 > @@ -141,4 +141,7 @@ int main(int argc, char **argv) { > return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x); > } > > +template<typename T> > +T S<T>::TS = 0; > + > #endif > > Modified: cfe/trunk/test/OpenMP/target_parallel_ast_print.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_parallel_ast_print.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/target_parallel_ast_print.cpp (original) > +++ cfe/trunk/test/OpenMP/target_parallel_ast_print.cpp Tue Apr 19 > 01:19:52 2016 > @@ -227,4 +227,7 @@ int main (int argc, char **argv) { > return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]); > } > > +extern template int S<int>::TS; > +extern template char S<char>::TS; > + > #endif > > Modified: cfe/trunk/test/OpenMP/task_ast_print.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/task_ast_print.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/task_ast_print.cpp (original) > +++ cfe/trunk/test/OpenMP/task_ast_print.cpp Tue Apr 19 01:19:52 2016 > @@ -149,4 +149,7 @@ int main(int argc, char **argv) { > return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x); > } > > +extern template int S<int>::TS; > +extern template long S<long>::TS; > + > #endif > > Modified: cfe/trunk/test/OpenMP/teams_ast_print.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/teams_ast_print.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/teams_ast_print.cpp (original) > +++ cfe/trunk/test/OpenMP/teams_ast_print.cpp Tue Apr 19 01:19:52 2016 > @@ -109,4 +109,6 @@ int main (int argc, char **argv) { > return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x); > } > > +extern template int S<int>::TS; > +extern template long S<long>::TS; > #endif > > Modified: cfe/trunk/test/OpenMP/threadprivate_ast_print.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/threadprivate_ast_print.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/OpenMP/threadprivate_ast_print.cpp (original) > +++ cfe/trunk/test/OpenMP/threadprivate_ast_print.cpp Tue Apr 19 01:19:52 > 2016 > @@ -69,4 +69,5 @@ int main () { > return (foo<int>()); > } > > +extern template int ST<int>::m; > #endif > > Modified: cfe/trunk/test/SemaCXX/PR10177.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR10177.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/PR10177.cpp (original) > +++ cfe/trunk/test/SemaCXX/PR10177.cpp Tue Apr 19 01:19:52 2016 > @@ -54,6 +54,7 @@ namespace N { > > namespace { template<typename> extern int n; } > template<typename T> int g() { return n<int>; } > +namespace { extern template int n<int>; } > > #endif > > > Modified: cfe/trunk/test/SemaCXX/undefined-internal.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/undefined-internal.cpp?rev=266719&r1=266718&r2=266719&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/undefined-internal.cpp (original) > +++ cfe/trunk/test/SemaCXX/undefined-internal.cpp Tue Apr 19 01:19:52 2016 > @@ -82,6 +82,7 @@ namespace test5 { > static int var; // expected-warning {{variable > 'test5::B<test5::(anonymous namespace)::A>::var' has internal linkage but > is not defined}} > static void foo(); // expected-warning {{function > 'test5::B<test5::(anonymous namespace)::A>::foo' has internal linkage but > is not defined}} > }; > + extern template int B<A>::var; > > void test() { > B<A>::var = 0; // expected-note {{used here}} > > Added: cfe/trunk/test/SemaTemplate/undefined-template.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/undefined-template.cpp?rev=266719&view=auto > > ============================================================================== > --- cfe/trunk/test/SemaTemplate/undefined-template.cpp (added) > +++ cfe/trunk/test/SemaTemplate/undefined-template.cpp Tue Apr 19 01:19:52 > 2016 > @@ -0,0 +1,139 @@ > +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 > -Wundefined-func-template %s > + > +template <class T> struct C1 { > + static char s_var_1; // expected-note{{forward declaration of > template entity is here}} > + static char s_var_2; // expected-note{{forward declaration of > template entity is here}} > + static void s_func_1(); // expected-note{{forward declaration of > template entity is here}} > + static void s_func_2(); // expected-note{{forward declaration of > template entity is here}} > + void meth_1(); // expected-note2{{forward declaration of > template entity is here}} > + void meth_2(); > + template <class T1> static char s_tvar_2; // > expected-note{{forward declaration of template entity is here}} > + template <class T1> static void s_tfunc_2(); // > expected-note{{forward declaration of template entity is here}} > + template<typename T1> struct C2 { > + static char s_var_2; // expected-note{{forward declaration of > template entity is here}} > + static void s_func_2(); // expected-note{{forward declaration of > template entity is here}} > + void meth_2(); // expected-note{{forward declaration of > template entity is here}} > + template <class T2> static char s_tvar_2; // > expected-note{{forward declaration of template entity is here}} > + template <class T2> void tmeth_2(); // > expected-note{{forward declaration of template entity is here}} > + }; > +}; > + > +extern template char C1<int>::s_var_2; > +extern template void C1<int>::s_func_2(); > +extern template void C1<int>::meth_2(); > +extern template char C1<int>::s_tvar_2<char>; > +extern template void C1<int>::s_tfunc_2<char>(); > +extern template void C1<int>::C2<long>::s_var_2; > +extern template void C1<int>::C2<long>::s_func_2(); > +extern template void C1<int>::C2<long>::meth_2(); > +extern template char C1<int>::C2<long>::s_tvar_2<char>; > +extern template void C1<int>::C2<long>::tmeth_2<char>(); > + > +char func_01() { > + return C1<int>::s_var_2; > +} > + > +char func_02() { > + return C1<int>::s_var_1; // expected-warning{{instantiation of variable > 'C1<int>::s_var_1' required here, but no definition is available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if 'C1<int>::s_var_1' is > explicitly instantiated in another translation unit}} > +} > + > +char func_03() { > + return C1<char>::s_var_2; // expected-warning{{instantiation of > variable 'C1<char>::s_var_2' required here, but no definition is available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if 'C1<char>::s_var_2' > is explicitly instantiated in another translation unit}} > +} > + > +void func_04() { > + C1<int>::s_func_1(); // expected-warning{{instantiation of function > 'C1<int>::s_func_1' required here, but no definition is available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if 'C1<int>::s_func_1' > is explicitly instantiated in another translation unit}} > +} > + > +void func_05() { > + C1<int>::s_func_2(); > +} > + > +void func_06() { > + C1<char>::s_func_2(); // expected-warning{{instantiation of function > 'C1<char>::s_func_2' required here, but no definition is available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if 'C1<char>::s_func_2' > is explicitly instantiated in another translation unit}} > +} > + > +void func_07(C1<int> *x) { > + x->meth_1(); // expected-warning{{instantiation of function > 'C1<int>::meth_1' required here, but no definition is available}} > + // expected-note@-1{{add an explicit instantiation > declaration to suppress this warning if 'C1<int>::meth_1' is explicitly > instantiated in another translation unit}} > +} > + > +void func_08(C1<int> *x) { > + x->meth_2(); > +} > + > +void func_09(C1<char> *x) { > + x->meth_1(); // expected-warning{{instantiation of function > 'C1<char>::meth_1' required here, but no definition is available}} > + // expected-note@-1{{add an explicit instantiation > declaration to suppress this warning if 'C1<char>::meth_1' is explicitly > instantiated in another translation unit}} > +} > + > +char func_10() { > + return C1<int>::s_tvar_2<char>; > +} > + > +char func_11() { > + return C1<int>::s_tvar_2<long>; // expected-warning{{instantiation of > variable 'C1<int>::s_tvar_2<long>' required here, but no definition is > available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if > 'C1<int>::s_tvar_2<long>' is explicitly instantiated in another translation > unit}} > +} > + > +void func_12() { > + C1<int>::s_tfunc_2<char>(); > +} > + > +void func_13() { > + C1<int>::s_tfunc_2<long>(); // expected-warning{{instantiation of > function 'C1<int>::s_tfunc_2<long>' required here, but no definition is > available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if > 'C1<int>::s_tfunc_2<long>' is explicitly instantiated in another > translation unit}} > +} > + > +char func_14() { > + return C1<int>::C2<long>::s_var_2; > +} > + > +char func_15() { > + return C1<int>::C2<char>::s_var_2; //expected-warning {{instantiation > of variable 'C1<int>::C2<char>::s_var_2' required here, but no definition > is available}} > + // expected-note@-1{{add an > explicit instantiation declaration to suppress this warning if > 'C1<int>::C2<char>::s_var_2' is explicitly instantiated in another > translation unit}} > +} > + > +void func_16() { > + C1<int>::C2<long>::s_func_2(); > +} > + > +void func_17() { > + C1<int>::C2<char>::s_func_2(); // expected-warning{{instantiation of > function 'C1<int>::C2<char>::s_func_2' required here, but no definition is > available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if > 'C1<int>::C2<char>::s_func_2' is explicitly instantiated in another > translation unit}} > +} > + > +void func_18(C1<int>::C2<long> *x) { > + x->meth_2(); > +} > + > +void func_19(C1<int>::C2<char> *x) { > + x->meth_2(); // expected-warning{{instantiation of function > 'C1<int>::C2<char>::meth_2' required here, but no definition is available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if > 'C1<int>::C2<char>::meth_2' is explicitly instantiated in another > translation unit}} > +} > + > +char func_20() { > + return C1<int>::C2<long>::s_tvar_2<char>; > +} > + > +char func_21() { > + return C1<int>::C2<long>::s_tvar_2<long>; // > expected-warning{{instantiation of variable > 'C1<int>::C2<long>::s_tvar_2<long>' required here, but no definition is > available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if > 'C1<int>::C2<long>::s_tvar_2<long>' is explicitly instantiated in another > translation unit}} > +} > + > +void func_22(C1<int>::C2<long> *x) { > + x->tmeth_2<char>(); > +} > + > +void func_23(C1<int>::C2<long> *x) { > + x->tmeth_2<int>(); // expected-warning{{instantiation of function > 'C1<int>::C2<long>::tmeth_2<int>' required here, but no definition is > available}} > + // expected-note@-1{{add an explicit > instantiation declaration to suppress this warning if > 'C1<int>::C2<long>::tmeth_2<int>' is explicitly instantiated in another > translation unit}} > +} > + > +int main() { > + return 0; > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > 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