]> granicus.if.org Git - clang/commitdiff
add an initial stab at emitting deferred c++ inline functions. This handles static
authorChris Lattner <sabre@nondot.org>
Tue, 12 May 2009 21:02:27 +0000 (21:02 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 12 May 2009 21:02:27 +0000 (21:02 +0000)
functions and methods declared inline, but not ctors/dtors or methods not declared
inline (apparently my previous patch wasn't good enough).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71591 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
test/CodeGenCXX/member-functions.cpp

index c2dc629680c399a87da88cdb9cd4be096f002f9a..6e4a67b917b3466410517065610ce376e9ed59ed 100644 (file)
@@ -606,6 +606,15 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
     // list, and remove it from DeferredDecls (since we don't need it anymore).
     DeferredDeclsToEmit.push_back(DDI->second);
     DeferredDecls.erase(DDI);
+  } else if (D && D->isThisDeclarationADefinition() && MayDeferGeneration(D)) {
+    // If this the first reference to a C++ inline function in a class, queue up
+    // the deferred function body for emission.  These are not seen as
+    // top-level declarations.
+    // FIXME: Make this work for ctor/dtors.  We need to pass down a full
+    // GlobalDecl instead of just a FunctionDecl.
+    if (!isa<CXXConstructorDecl>(D) &&
+        !isa<CXXDestructorDecl>(D))
+    DeferredDeclsToEmit.push_back(GlobalDecl(D));
   }
   
   // This function doesn't have a complete type (for example, the return
index 9cdab0a6624befdac47ed746d830fa56892ec91f..83278909eac89e77e58abdb764140b5e30430443 100644 (file)
@@ -8,12 +8,36 @@ struct C {
 void C::f() {
 }
 
-void f() {
+void test1() {
   C c;
   
 // RUN: grep "call void @_ZN1C1fEv" %t | count 1 &&
   c.f();
   
-// RUN: grep "call void (.struct.C\*, i32, ...)\* @_ZN1C1gEiz" %t | count 1
+// RUN: grep "call void (.struct.C\*, i32, ...)\* @_ZN1C1gEiz" %t | count 1 &&
   c.g(1, 2, 3);
 }
+
+
+struct S {
+  S() { }
+  ~S() { }
+  
+  
+  void f_inline1() { }
+  // RUN: grep "define linkonce_odr void @_ZN1S9f_inline2Ev" %t &&
+  inline void f_inline2() { }
+  
+  // RUN: grep "define internal void @_ZN1S1gEv" %t
+  static void g() { }
+};
+
+void test2() {
+  S s;
+  
+  s.f_inline1();
+  s.f_inline2();
+  
+  S::g();
+  
+}