aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/RecordLayout.h5
-rw-r--r--include/clang/Basic/LangOptions.h5
-rw-r--r--include/clang/Driver/Options.def1
-rw-r--r--lib/AST/ASTContext.cpp9
-rw-r--r--lib/Driver/Tools.cpp1
-rw-r--r--tools/clang-cc/clang-cc.cpp8
6 files changed, 26 insertions, 3 deletions
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index c68edfaf71..57adc8a555 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -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;
}
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index fba474b2f5..fa5b689490 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -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;
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index 13456d9531..5f029628e7 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -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)
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index d89c8c2b2e..a9f13c9518 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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.
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index a714be81c3..2a959b3c55 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -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);
diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp
index a8836887a7..5ef2bf6c34 100644
--- a/tools/clang-cc/clang-cc.cpp
+++ b/tools/clang-cc/clang-cc.cpp
@@ -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;