On Wed, Apr 1, 2015 at 9:23 AM, Reid Kleckner <[email protected]> wrote:
> Author: rnk > Date: Wed Apr 1 11:23:44 2015 > New Revision: 233817 > > URL: http://llvm.org/viewvc/llvm-project?rev=233817&view=rev > Log: > Mark instantiated function decls as inline specified if any pattern is > > A function template pattern can be declared without the 'inline' > specifier and defined later with the 'inline' specifier. However, during > instantiation, we were only looking at the canonical decl to see if we > should mark the instantiated decl as inline specified. Since the > instantiated decl actually represents many pattern declarations, put the > inline specifier on the instantiation decl if any of the pattern decls > have it. > > Added: > cfe/trunk/test/CodeGenCXX/inlinehint.cpp > Modified: > cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp > > Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=233817&r1=233816&r2=233817&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Apr 1 11:23:44 > 2015 > @@ -1304,6 +1304,15 @@ static QualType adjustFunctionTypeForIns > NewFunc->getParamTypes(), NewEPI); > } > > +/// Return true if any redeclaration of FD was inline specified. Useful > for > +/// propagating the 'inline' specifier onto function template > instantiations. > +static bool isAnyRedeclInlineSpecified(const FunctionDecl *FD) { > + for (const auto *R : FD->redecls()) > + if (R->isInlineSpecified()) > This could be written with std::any_of, if you like. (yeah, it's not a strict win, between not having range-based algorithms and not having polymorphic lambdas) > + return true; > + return false; > +} > + > /// Normal class members are of more specific types and therefore > /// don't make it here. This function serves two purposes: > /// 1) instantiating function templates > @@ -1372,7 +1381,8 @@ Decl *TemplateDeclInstantiator::VisitFun > FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), > D->getNameInfo(), T, TInfo, > D->getCanonicalDecl()->getStorageClass(), > - D->isInlineSpecified(), > D->hasWrittenPrototype(), > + isAnyRedeclInlineSpecified(D), > + D->hasWrittenPrototype(), > D->isConstexpr()); > Function->setRangeEnd(D->getSourceRange().getEnd()); > > @@ -1669,7 +1679,7 @@ TemplateDeclInstantiator::VisitCXXMethod > Method = CXXConstructorDecl::Create(SemaRef.Context, Record, > StartLoc, NameInfo, T, TInfo, > Constructor->isExplicit(), > - Constructor->isInlineSpecified(), > + > isAnyRedeclInlineSpecified(Constructor), > false, > Constructor->isConstexpr()); > > // Claim that the instantiation of a constructor or constructor > template > @@ -1704,12 +1714,12 @@ TemplateDeclInstantiator::VisitCXXMethod > } else if (CXXDestructorDecl *Destructor = > dyn_cast<CXXDestructorDecl>(D)) { > Method = CXXDestructorDecl::Create(SemaRef.Context, Record, > StartLoc, NameInfo, T, TInfo, > - Destructor->isInlineSpecified(), > + > isAnyRedeclInlineSpecified(Destructor), > false); > } else if (CXXConversionDecl *Conversion = > dyn_cast<CXXConversionDecl>(D)) { > Method = CXXConversionDecl::Create(SemaRef.Context, Record, > StartLoc, NameInfo, T, TInfo, > - Conversion->isInlineSpecified(), > + > isAnyRedeclInlineSpecified(Conversion), > Conversion->isExplicit(), > Conversion->isConstexpr(), > Conversion->getLocEnd()); > @@ -1717,7 +1727,7 @@ TemplateDeclInstantiator::VisitCXXMethod > StorageClass SC = D->isStatic() ? SC_Static : SC_None; > Method = CXXMethodDecl::Create(SemaRef.Context, Record, > StartLoc, NameInfo, T, TInfo, > - SC, D->isInlineSpecified(), > + SC, isAnyRedeclInlineSpecified(D), > D->isConstexpr(), D->getLocEnd()); > } > > > Added: cfe/trunk/test/CodeGenCXX/inlinehint.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/inlinehint.cpp?rev=233817&view=auto > > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/inlinehint.cpp (added) > +++ cfe/trunk/test/CodeGenCXX/inlinehint.cpp Wed Apr 1 11:23:44 2015 > @@ -0,0 +1,33 @@ > +// RUN: %clang_cc1 -triple %itanium_abi_triple %s -emit-llvm -o - | > FileCheck %s > + > +inline void InlineFunc() {} > +// CHECK: define linkonce_odr void @_Z10InlineFuncv() > #[[INLINEHINTATTR:[0-9]+]] comdat { > + > +struct MyClass { > + static void InlineStaticMethod(); > + void InlineInstanceMethod(); > +}; > +inline void MyClass::InlineStaticMethod() {} > +// CHECK: define linkonce_odr void @_ZN7MyClass18InlineStaticMethodEv() > #[[INLINEHINTATTR]] comdat > +inline void MyClass::InlineInstanceMethod() {} > +// CHECK: define linkonce_odr void > @_ZN7MyClass20InlineInstanceMethodEv(%struct.MyClass* %this) > #[[INLINEHINTATTR]] comdat > + > +template <typename T> > +struct MyTemplate { > + static void InlineStaticMethod(); > + void InlineInstanceMethod(); > +}; > +template <typename T> inline void MyTemplate<T>::InlineStaticMethod() {} > +// CHECK: define linkonce_odr void > @_ZN10MyTemplateIiE18InlineStaticMethodEv() #[[INLINEHINTATTR]] comdat > +template <typename T> inline void MyTemplate<T>::InlineInstanceMethod() {} > +// CHECK: define linkonce_odr void > @_ZN10MyTemplateIiE20InlineInstanceMethodEv(%struct.MyTemplate* %this) > #[[INLINEHINTATTR]] comdat > + > +void UseThem() { > + InlineFunc(); > + MyClass::InlineStaticMethod(); > + MyClass().InlineInstanceMethod(); > + MyTemplate<int>::InlineStaticMethod(); > + MyTemplate<int>().InlineInstanceMethod(); > +} > + > +// CHECK: attributes #[[INLINEHINTATTR]] = { {{.*}}inlinehint{{.*}} } > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
