]> granicus.if.org Git - clang/commitdiff
Add -fobjc-tight-layout.
authorDaniel Dunbar <daniel@zuster.org>
Mon, 4 May 2009 05:16:21 +0000 (05:16 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Mon, 4 May 2009 05:16:21 +0000 (05:16 +0000)
 - This implements gcc style Objective-C interface layout (I
   think). Currently it is always off, there is no functionality
   change unless this is passed.

   For the curious, the deal is that gcc lays out the fields of a
   subclass as if they were part of the superclass. That is, the
   subclass fields immediately follow the super class fields instead
   of being padded to the alignment of the superclass structure.

 - Currently gcc uses the tight layout in 32-bit and 64-bit modes, and
   llvm-gcc uses it in 32-bit only, for reasons which aren't clear
   yet. We probably want to switch to matching gcc, once this makes it
   through testing... my hope is that we can also fix llvm-gcc in
   order to maintain compatibility between the compilers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70827 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/RecordLayout.h
include/clang/Basic/LangOptions.h
include/clang/Driver/Options.def
lib/AST/ASTContext.cpp
lib/Driver/Tools.cpp
tools/clang-cc/clang-cc.cpp

index c68edfaf71888dfcb1e24c7db17fb5b0406a5745..57adc8a555dca4a42a1ffcf31ad9d705e89a9f6e 100644 (file)
@@ -29,13 +29,14 @@ namespace clang {
 /// These objects are managed by ASTContext.
 class ASTRecordLayout {
   uint64_t Size;        // Size of record in bits.
+  uint64_t *FieldOffsets;
   unsigned Alignment;   // Alignment of record in bits.
   unsigned FieldCount;  // Number of fields
-  uint64_t *FieldOffsets;
+  unsigned NextOffset;  // Next available offset
   friend class ASTContext;
 
   ASTRecordLayout(uint64_t S = 0, unsigned A = 8) 
-    : Size(S), Alignment(A), FieldCount(0) {}
+    : Size(S), Alignment(A), FieldCount(0), NextOffset(0) {}
   ~ASTRecordLayout() {
     delete [] FieldOffsets;
   }
index fba474b2f527759bcd4765a19966024ce7caca09..fa5b68949054fa33f71ff64fdddeb85503a02521 100644 (file)
@@ -37,6 +37,9 @@ public:
   unsigned ObjC1             : 1;  // Objective-C 1 support enabled.
   unsigned ObjC2             : 1;  // Objective-C 2 support enabled.
   unsigned ObjCNonFragileABI : 1;  // Objective-C modern abi enabled
+  unsigned ObjCTightLayout   : 1;  // Use tight interface layout, in
+                                   // which subclass ivars can be
+                                   // placed inside the superclass.
     
   unsigned PascalStrings     : 1;  // Allow Pascal strings
   unsigned WritableStrings   : 1;  // Allow writable strings
@@ -100,7 +103,7 @@ public:
     Trigraphs = BCPLComment = DollarIdents = AsmPreprocessor = 0;
     GNUMode = ImplicitInt = Digraphs = 0;
     HexFloats = 0;
-    GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
+    GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCTightLayout = 0;
     C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
     CXXOperatorNames = PascalStrings = WritableStrings = 0;
     Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
index 13456d9531f6c6490874b682056954e0b9e616d4..5f029628e7bb1f3a6db8c880194dcc4f626c0841 100644 (file)
@@ -420,6 +420,7 @@ OPTION("-fobjc-gc-only", fobjc_gc_only, Flag, f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fobjc-gc", fobjc_gc, Flag, f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fobjc-new-property", fobjc_new_property, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fobjc-nonfragile-abi", fobjc_nonfragile_abi, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fobjc-tight-layout", fobjc_tight_layout, Flag, f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fobjc", fobjc, Flag, f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fomit-frame-pointer", fomit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fopenmp", fopenmp, Flag, f_Group, INVALID, "", 0, 0, 0)
index d89c8c2b2e3f73522f196a9688bca6971d9adbaf..a9f13c9518039006eb81b6232188fe3d6ae6e3fb 100644 (file)
@@ -654,6 +654,9 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
     Size = FieldOffset + FieldSize;
   }
   
+  // Remember the next available offset.
+  NextOffset = Size;
+
   // Remember max struct/class alignment.
   Alignment = std::max(Alignment, FieldAlign);
 }
@@ -718,6 +721,12 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
     unsigned Alignment = SL.getAlignment();
     uint64_t Size = SL.getSize();
 
+    // If we are using tight interface packing, then we start laying
+    // out ivars not at the end of the superclass structure, but at
+    // the next byte following the last field.
+    if (getLangOptions().ObjCTightLayout)
+      Size = llvm::RoundUpToAlignment(SL.NextOffset, 8);
+
     ObjCLayouts[Key] = NewEntry = new ASTRecordLayout(Size, Alignment);
     NewEntry->InitializeLayout(FieldCount);
     // Super class is at the beginning of the layout.
index a714be81c33a25fb79cb0a7b8c111088b3eac938..2a959b3c55aceda6810969240ce4e5720f0dc453 100644 (file)
@@ -466,6 +466,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc);
   // FIXME: Should we remove this?
   Args.AddLastArg(CmdArgs, options::OPT_fobjc_nonfragile_abi);
+  Args.AddLastArg(CmdArgs, options::OPT_fobjc_tight_layout);
   Args.AddLastArg(CmdArgs, options::OPT_fprint_source_range_info);
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
   Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
index a8836887a70e7a4a46d275f8102cdebb4b10c638..5ef2bf6c34beae94706a167149247f2f76655cb2 100644 (file)
@@ -628,6 +628,11 @@ static llvm::cl::opt<bool>
 ObjCNonFragileABI("fobjc-nonfragile-abi",
                   llvm::cl::desc("enable objective-c's nonfragile abi"));
 
+
+static llvm::cl::opt<bool>
+ObjCTightLayout("fobjc-tight-layout",
+                  llvm::cl::desc("enable tight objective-c interface layout"));
+
 static llvm::cl::opt<bool>
 EmitAllDecls("femit-all-decls",
               llvm::cl::desc("Emit all declarations, even if unused"));
@@ -843,6 +848,9 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
 
   if (ObjCNonFragileABI)
     Options.ObjCNonFragileABI = 1;
+  
+  if (ObjCTightLayout)
+    Options.ObjCTightLayout = 1;
 
   if (EmitAllDecls)
     Options.EmitAllDecls = 1;