[cfe-dev] clang does not emit Ivar class name when compiling libobjc2 on Linux (Mac and gcc Linux are OK)

Lobron, David via cfe-dev cfe-dev at lists.llvm.org
Wed Sep 14 12:53:39 PDT 2016


Hello cfe-users,

I'm working to get my the libobjc2 Objective-C runtime working on Linux with clang-3.8.0.  I'm running into a problem with a library of mine that does class introspection.  My ObjC code does type introspection by looping through the ivars of an object and calling ivar_getTypeEncoding on each to get the type of the ivar.  When I compile with gcc, the ivar type for non-primitive variables comes through as @"NSString", @"NSDictionary", etc.  This also works with clang on my Mac.  But when I compile with clang on Linux, I only get the @ character.  I verified that the call to class_copyIvarList on Linux does return a list of Ivar objects, but when I call ivar_getTypeEncoding on those objects on Linux, I only get @, rather than the class name.  I've copied my library's ObjC code below.  

I talked this over with the owners of libobjc2, and we were wondering if there is a flag I can pass to clang to instruct it to emit this class data.  I looked at lib/CodeGen/CGObjCGNU.cpp in the clang source tree, but it wasn't immediately clear what flag I could pass here.  It's possible that there's no such flag, and the non-Apple clang simply doesn't emit this data, but I'd be somewhat surprised if Apple had diverged that much.

Thanks in advance for any help you can give,

David

My library's introspection code, with a debug print statement:

Ivar *ivarList = class_copyIvarList(c, &ivarCount);
for (i = 0; i < ivarCount; i++) {
  Ivar ivar = ivarList[i];
  const char *ivarCname = ivar_getName(ivar);
  if (ivarCname != 0 && ivarCname[0] != '_') {
     NSString *ivarName = [NSString stringWithUTF8String:ivarCname];
     const char *ivarType = ivar_getTypeEncoding(ivar);                    
     if (ivarType[0] == '@' && ivarType[1] == '"') {
         NSString *className = [[[NSString alloc] initWithBytes: &ivarType[2]
                              length: strlen(&ivarType[2])-1
                         encoding: NSUTF8StringEncoding] autorelease];
         Class c = NSClassFromString(className);
         if (c == nil) {
             NSLog(@"WARNING: unknown class name \"%@\" in declaration of %@", className, [self class]);
         } else {
             NSLog(@"DBG: Deduced class %@ from className %@", c, className);

With gcc and clang on the Mac, I get messages like this:

2016-09-14 19:29:21.950 archiveserver[1015:1015] DBG: Deduced class NSSet from className NSSet
2016-09-14 19:29:21.950 archiveserver[1015:1015] DBG: Deduced class NSString from className NSString
2016-09-14 19:29:21.950 archiveserver[1015:1015] DBG: Deduced class NSString from className NSString
2016-09-14 19:29:21.950 archiveserver[1015:1015] DBG: Deduced class NSString from className NSString
2016-09-14 19:29:21.950 archiveserver[1015:1015] DBG: Deduced class NSDictionary from className NSDictionary
2016-09-14 19:29:21.950 archiveserver[1015:1015] DBG: Deduced class NSDictionary from className NSDictionary
2016-09-14 19:29:21.950 archiveserver[1015:1015] DBG: Deduced class NSArray from className NSArray

With clang on Linux, nothing is printed, because ivarType[1] is not a double quote, so the second if evaluates to false.





More information about the cfe-dev mailing list