rafauler created this revision.
rafauler added reviewers: rsmith, ldionne.

As PR17480 describes, clang does not support the used attribute
for member functions of class templates. This means that if the member
function is not used, its definition is never instantiated. This patch
changes clang to emit the definition if it has the used attribute.

Test Plan: Added a testcase


Repository:
  rC Clang

https://reviews.llvm.org/D56928

Files:
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp


Index: test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -O0 -o - %s \
+// RUN:  | FileCheck %s
+
+#define USED __attribute__((used))
+
+namespace InstantiateUsedMemberDefinition {
+  template <typename T> struct S {
+    int USED f() {
+      return 0;
+    }
+  };
+
+  void test() {
+    // Check that InstantiateUsedMemberDefinition::S<int>::f() is defined
+    // as a result of the S class template implicit instantiation
+    // CHECK-DAG: define linkonce_odr i32 
@_ZN31InstantiateUsedMemberDefinition1SIiE1fEv
+    S<int> inst;
+  }
+}
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2176,6 +2176,24 @@
     Owner->addDecl(Method);
   }
 
+  // facebook begin T10336705
+  // PR17480: Honor the used attribute to instantiate member function
+  // definitions
+  if (Method->hasAttr<UsedAttr>()) {
+    if (auto *A = dyn_cast<CXXRecordDecl>(Owner)) {
+      SourceLocation Loc;
+      if (MemberSpecializationInfo *MSInfo = A->getMemberSpecializationInfo()) 
{
+        Loc = MSInfo->getPointOfInstantiation();
+      } else if (ClassTemplateSpecializationDecl *Spec =
+                     dyn_cast<ClassTemplateSpecializationDecl>(A)) {
+        Loc = Spec->getPointOfInstantiation();
+      }
+
+      SemaRef.MarkFunctionReferenced(Loc, Method, /*MightBeOdrUse=*/true);
+    }
+  }
+  // end facebook
+
   return Method;
 }
 


Index: test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -O0 -o - %s \
+// RUN:  | FileCheck %s
+
+#define USED __attribute__((used))
+
+namespace InstantiateUsedMemberDefinition {
+  template <typename T> struct S {
+    int USED f() {
+      return 0;
+    }
+  };
+
+  void test() {
+    // Check that InstantiateUsedMemberDefinition::S<int>::f() is defined
+    // as a result of the S class template implicit instantiation
+    // CHECK-DAG: define linkonce_odr i32 @_ZN31InstantiateUsedMemberDefinition1SIiE1fEv
+    S<int> inst;
+  }
+}
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2176,6 +2176,24 @@
     Owner->addDecl(Method);
   }
 
+  // facebook begin T10336705
+  // PR17480: Honor the used attribute to instantiate member function
+  // definitions
+  if (Method->hasAttr<UsedAttr>()) {
+    if (auto *A = dyn_cast<CXXRecordDecl>(Owner)) {
+      SourceLocation Loc;
+      if (MemberSpecializationInfo *MSInfo = A->getMemberSpecializationInfo()) {
+        Loc = MSInfo->getPointOfInstantiation();
+      } else if (ClassTemplateSpecializationDecl *Spec =
+                     dyn_cast<ClassTemplateSpecializationDecl>(A)) {
+        Loc = Spec->getPointOfInstantiation();
+      }
+
+      SemaRef.MarkFunctionReferenced(Loc, Method, /*MightBeOdrUse=*/true);
+    }
+  }
+  // end facebook
+
   return Method;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to