r233817 - Mark instantiated function decls as inline specified if any pattern is

David Blaikie dblaikie at gmail.com
Wed Apr 1 09:51:30 PDT 2015


On Wed, Apr 1, 2015 at 9:23 AM, Reid Kleckner <reid at kleckner.net> 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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150401/87b5443d/attachment.html>


More information about the cfe-commits mailing list