]> granicus.if.org Git - clang/commitdiff
Driver & AST: Implement support for -fpack-struct and -fpack-struct= command
authorDaniel Dunbar <daniel@zuster.org>
Wed, 5 Oct 2011 21:04:55 +0000 (21:04 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 5 Oct 2011 21:04:55 +0000 (21:04 +0000)
line options.
 - <rdar://problem/10120602>, PR9631

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

include/clang/Basic/LangOptions.def
include/clang/Driver/CC1Options.td
include/clang/Driver/Options.td
lib/AST/RecordLayoutBuilder.cpp
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
test/Sema/fpack-struct.c [new file with mode: 0644]

index 9ff9dbacce348ccabcc9e0d19b20e64145581586..03882f8cdb099f19b80a909c3eb76b3f5eabe177 100644 (file)
@@ -94,6 +94,8 @@ BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like a
 LANGOPT(Optimize          , 1, 0, "__OPTIMIZE__ predefined macro")
 LANGOPT(OptimizeSize      , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
 LANGOPT(Static            , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
+VALUE_LANGOPT(PackStruct  , 32, 0, 
+              "default struct packing maximum alignment")
 VALUE_LANGOPT(PICLevel          , 2, 0, "__PIC__ level")
 LANGOPT(GNUInline         , 1, 0, "GNU inline semantics")
 LANGOPT(NoInline          , 1, 0, "__NO_INLINE__ predefined macro")
index 00fc815fd2e346385bce3eed64953136e744179a..ffe1eafd61b7b383eefc3239fb5289341f5b96c6 100644 (file)
@@ -541,6 +541,8 @@ def pic_level : Separate<"-pic-level">,
   HelpText<"Value for __PIC__">;
 def pthread : Flag<"-pthread">,
   HelpText<"Support POSIX threads in generated code">;
+def fpack_struct : Separate<"-fpack-struct">,
+  HelpText<"Specify the default maximum struct packing alignment">;
 def fpascal_strings : Flag<"-fpascal-strings">,
   HelpText<"Recognize and construct Pascal-style string literals">;
 def fno_rtti : Flag<"-fno-rtti">,
index 3f48b96d758367ff1f3fc5932c2eb3ac4163baf9..a0520f0beaf65bcfc9f5633d9be8d3e9ef5bb969 100644 (file)
@@ -440,6 +440,9 @@ def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">;
 def force__flat__namespace : Flag<"-force_flat_namespace">;
 def force__load : Separate<"-force_load">;
 def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>;
+def fpack_struct : Flag<"-fpack-struct">, Group<f_Group>;
+def fno_pack_struct : Flag<"-fno-pack-struct">, Group<f_Group>;
+def fpack_struct_EQ : Joined<"-fpack-struct=">, Group<f_Group>;
 def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>;
 def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>;
 def fpic : Flag<"-fpic">, Group<f_Group>;
index 97355dc04e045d2c613b85b0c0c8af890f61a5b4..8e715887680bddc08824d0e13bc155edda10b907 100644 (file)
@@ -1211,6 +1211,11 @@ void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
   
   IsMsStruct = D->hasAttr<MsStructAttr>();
 
+  // Honor the default struct packing maximum alignment flag.
+  if (unsigned DefaultMaxFieldAlignment = Context.getLangOptions().PackStruct) {
+    MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment);
+  }
+
   // mac68k alignment supersedes maximum field alignment and attribute aligned,
   // and forces all structures to have 2-byte alignment. The IBM docs on it
   // allude to additional (more complicated) semantics, especially with regard
index e193c0f505a721df0f9846e5b7cbc3a2b55296e8..1dcb8bc91dea11cf469941c866ee2bddd142adf4 100644 (file)
@@ -2062,11 +2062,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                    false))
     CmdArgs.push_back("-fpascal-strings");
 
+  // Honor -fpack-struct= and -fpack-struct, if given. Note that
+  // -fno-pack-struct doesn't apply to -fpack-struct=.
+  if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
+    CmdArgs.push_back("-fpack-struct");
+    CmdArgs.push_back(A->getValue(Args));
+  } else if (Args.hasFlag(options::OPT_fpack_struct,
+                          options::OPT_fno_pack_struct, false)) {
+    CmdArgs.push_back("-fpack-struct");
+    CmdArgs.push_back("1");
+  }
+
   if (Args.hasArg(options::OPT_mkernel) ||
       Args.hasArg(options::OPT_fapple_kext)) {
     if (!Args.hasArg(options::OPT_fcommon))
       CmdArgs.push_back("-fno-common");
   }
+
   // -fcommon is default, only pass non-default.
   else if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
     CmdArgs.push_back("-fno-common");
index 5252ebadacd696ef10dc848a6630a5967fd7999e..4fb3ee62f049c26fcd9ade9a7fc93a0a191631df 100644 (file)
@@ -1728,6 +1728,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
     Args.hasArg(OPT_fobjc_default_synthesize_properties);
   Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
   Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
+  Opts.PackStruct = Args.getLastArgIntValue(OPT_fpack_struct, 0, Diags);
   Opts.PICLevel = Args.getLastArgIntValue(OPT_pic_level, 0, Diags);
   Opts.Static = Args.hasArg(OPT_static_define);
   Opts.DumpRecordLayouts = Args.hasArg(OPT_fdump_record_layouts);
diff --git a/test/Sema/fpack-struct.c b/test/Sema/fpack-struct.c
new file mode 100644 (file)
index 0000000..37c8444
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -DEXPECTED_STRUCT_SIZE=5 -fpack-struct 1 %s
+// RUN: %clang_cc1 -DEXPECTED_STRUCT_SIZE=6 -fpack-struct 2 %s
+
+struct s0 {
+       int x;
+       char c;
+};
+
+int t0[sizeof(struct s0) == EXPECTED_STRUCT_SIZE ?: -1];