[cfe-dev] C++ member methods defined inline in the class defintion

Bradley Murray bradtgmurray at gmail.com
Tue May 12 20:03:01 PDT 2009


Hello,

I started playing with clang the other day and I realized it didn't handle a
fairly simple case.

    #include <stdio.h>

    class Test
    {
    public:
        void TestingInlineMethod()
        {
            printf("TestingInlineMethod!\n");
        }
    };

    int main(int argc, char* argv[])
    {
        Test a;
        a.TestingInlineMethod();

        return 0;
    }

Compiling this code resulted in a linking error.

    brad-macbook:clang bradleymurray$ clang -ccc-clang-cxx test.cpp
    Undefined symbols:
      "__ZN4Test19TestingInlineMethodEv", referenced from:
          _main in cc-oKiqB0.o
    ld: symbol(s) not found

Interested, I dug into the code a bit and tried to figure out what was going
wrong. I've attached a patch that fixes the issue, but I'm not sure if it's
correct. Comments would be appreciated.

Thanks,
Brad Murray
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20090512/b48eb08d/attachment.html>
-------------- next part --------------
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h	(revision 71616)
+++ lib/CodeGen/CodeGenModule.h	(working copy)
@@ -416,9 +416,9 @@
   void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
 
   // C++ related functions.
-  
   void EmitNamespace(const NamespaceDecl *D);
   void EmitLinkageSpec(const LinkageSpecDecl *D);
+  void EmitCXXRecord(const CXXRecordDecl *D);
 
   /// EmitCXXConstructors - Emit constructors (base, complete) from a
   /// C++ constructor Decl.
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp	(revision 71616)
+++ lib/CodeGen/CodeGenModule.cpp	(working copy)
@@ -1443,6 +1443,21 @@
     EmitTopLevelDecl(*I);
 }
 
+/// EmitCXXRecord- Emit all declarations in a record.
+/// Used to catch inline method definitions.
+void CodeGenModule::EmitCXXRecord(const CXXRecordDecl *CRD) {
+  for (RecordDecl::decl_iterator I = CRD->decls_begin(getContext()),
+         E = CRD->decls_end(getContext());
+       I != E; ++I) {
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+      if (FD->getBodyIfAvailable())
+      {
+        EmitTopLevelDecl(*I);
+      }
+    }
+  }
+}
+
 /// EmitTopLevelDecl - Emit code for a single top level declaration.
 void CodeGenModule::EmitTopLevelDecl(Decl *D) {
   // If an error has occurred, stop code generation, but continue
@@ -1468,6 +1483,9 @@
   case Decl::CXXDestructor:
     EmitCXXDestructors(cast<CXXDestructorDecl>(D));
     break;
+  case Decl::CXXRecord:
+    EmitCXXRecord(cast<CXXRecordDecl>(D));
+	break;
         
   // Objective-C Decls
     


More information about the cfe-dev mailing list