[cfe-commits] Building EFI with Clang on Mac OS X
Douglas Gregor
dgregor at apple.com
Mon Jan 31 11:20:11 PST 2011
Hi Carl,
On Jan 27, 2011, at 12:02 PM, Carl Norum wrote:
>
> Hi folks,
>
> I've attached a patch for review; these are the changes we use to build EFI for Mac boot ROMs using clang/llvm on Mac OS X. The simplest explanation is that it's a partial implementation of gcc's "-mms-bitfields" flag for clang.
>
> Let me know what you think!
A couple of comments...
Index: test/Misc/mms-bitfields.c
===================================================================
--- test/Misc/mms-bitfields.c (revision 0)
+++ test/Misc/mms-bitfields.c (revision 0)
@@ -0,0 +1,9 @@
+// RUN: %clang -arch i386 -mms-bitfields -emit-llvm -c %s -o %t
+// RUN: llvm-dis %t -o - | FileCheck %s
+
+struct s {
+ int f32;
+ long long f64;
+} s;
+
+// CHECK: @s = common global %struct.s zeroinitializer, align 8
Instead of using %clang and llvm-dis in the RUN line, it'd be far better to use
%clang_cc1 -triple <triple that makes sense for -mms-bitfields> -emit-llvm -o -
and pipe the results to FileCheck. The important part is the use of %clang_cc1 with -triple, so the test is completely independent of the host environment.
This test seems like it's not really testing bit-field layout at all...
Index: include/clang/Basic/LangOptions.h
===================================================================
--- include/clang/Basic/LangOptions.h (revision 124313)
+++ include/clang/Basic/LangOptions.h (working copy)
@@ -56,6 +56,7 @@
unsigned SjLjExceptions : 1; // Use setjmp-longjump exception handling.
unsigned RTTI : 1; // Support RTTI information.
+ unsigned MSBitfields : 1; // MS-compatible structure layout
unsigned NeXTRuntime : 1; // Use NeXT runtime.
unsigned Freestanding : 1; // Freestanding implementation
unsigned NoBuiltin : 1; // Do not use builtin functions (-fno-builtin)
@@ -163,6 +164,7 @@
C99 = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
+ MSBitfields = 0;
NeXTRuntime = 1;
RTTI = 1;
LaxVectorConversions = 1;
Please update the AST reader and writer, so that the MSBitfields bit is properly saved/loaded/checked.
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp (revision 124313)
+++ lib/Basic/Targets.cpp (working copy)
@@ -2675,7 +2675,10 @@
case llvm::Triple::MinGW64:
return new MinGWX86_64TargetInfo(T);
case llvm::Triple::Win32: // This is what Triple.h supports now.
- return new VisualStudioWindowsX86_64TargetInfo(T);
+ if (Triple.getEnvironment() == llvm::Triple::MachO)
+ return new DarwinX86_64TargetInfo(T);
+ else
+ return new VisualStudioWindowsX86_64TargetInfo(T);
default:
return new X86_64TargetInfo(T);
}
This change should be committed separately.
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp (revision 124313)
+++ lib/AST/RecordLayoutBuilder.cpp (working copy)
@@ -1401,6 +1401,25 @@
std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType());
FieldSize = FieldInfo.first;
FieldAlign = FieldInfo.second;
+
+ if (Context.getLangOptions().MSBitfields) {
+ // If MS bitfield layout is required, figure out what type is being
+ // laid out and align the field to the width of that type.
+ const Type *T = D->getType().getTypePtr();
+ Type::TypeClass TC = T->getTypeClass();
+
+ // Resolve all typedefs down to their base type
+ while (TC == Type::Typedef) {
+ const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
+ T = Typedef->getUnderlyingType().getTypePtr();
+ TC = T->getTypeClass();
+ }
+
+ // Round up the field alignment if necessary.
+ if ((TC == Type::Builtin) && (FieldSize > FieldAlign)) {
+ FieldAlign = FieldSize;
+ }
+ }
}
It's best not to try to walk through typedefs manually; Type's getAs member function template will do that for you. You can collapse most of that logic down to
if (const BuiltinType *BT = D->getType()->getAs<BuiltinType>())
if (FieldSize > FieldAlign)
FieldAlign = FieldSize;
However, I think you also want to look through array types, first? ASTContext has a routine to do that.
Thanks for working on this! Do we have a good sense of what else is needed for -mms-bitfields? Documentation on this feature seems a bit scarce.
- Doug
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110131/93b22e43/attachment.html>
More information about the cfe-commits
mailing list