Hi all,

I found a strange result on clang-3.1 when recursive type was converted. A 
example is as following.
C language source code:
struct foo1 {
  struct foo2* a;
  struct foo3* b;
};
struct foo2 {
  void (*func1)(struct foo1*);
};
struct foo3 {
  void (*func1)(struct foo1*);
};
struct foo2 e;

Converted result to llvm IR:
%struct.foo2 = type { void (%struct.foo1*)* }
%struct.foo1 = type { %struct.foo2*, %struct.foo3* }
%struct.foo3 = type { {}* }
@e = common global %struct.foo2 zeroinitializer, align 4

struct.foo3 type has "{}*". The reason of strange result is that clang 
generates struct type for function type with parameter of cycled type as 
following. 
File: clang/lib/CodeGen/CodeGenTypes.cpp
463     // While we're converting the argument types for a function, we don't 
want
464     // to recursively convert any pointed-to structs.  Converting 
directly-used
465     // structs is ok though.
466     if (!RecordsBeingLaidOut.insert(Ty)) {
467       ResultType = llvm::StructType::get(getLLVMContext());
468
469       SkippedLayout = true;
470       break;
471     }

I think that cycle of types should be cut to translate cycled clang types into 
llvm IR so clang generates struct type as type holder. Is it right? What do you 
think about this?

I made a simple patch for clang-3.1 to fix this problem. Resolved result is as 
following.
Resolved result:
%struct.foo2 = type { void (%struct.foo1*)* }
%struct.foo1 = type { %struct.foo2*, %struct.foo3* }
%struct.foo3 = type { void (%struct.foo1*)* }
@e = common global %struct.foo2 zeroinitializer, align 4

Please review this patch.

Thanks,
Jin-Gu Kang

Attachment: RecursiveType.patch
Description: RecursiveType.patch

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to