diff options
-rw-r--r-- | include/clang/AST/RecordLayout.h | 5 | ||||
-rw-r--r-- | include/clang/Basic/LangOptions.h | 5 | ||||
-rw-r--r-- | include/clang/Driver/Options.def | 1 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 9 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 1 | ||||
-rw-r--r-- | tools/clang-cc/clang-cc.cpp | 8 |
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; |