[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