From e521445286e424c74faab38bd07458dc0d1ba1d2 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Wed, 21 Nov 2012 07:56:23 +0000 Subject: Merging r168297 into 3.2 release branch Completely re-work how the Clang driver interprets PIC and PIE options. There were numerous issues here that were all entangled, and so I've tried to do a general simplification of the logic. 1) The logic was mimicing actual GCC bugs, rather than "features". These have been fixed in trunk GCC, and this fixes Clang as well. Notably, the logic was always intended to be last-match-wins like any other flag. 2) The logic for handling '-mdynamic-no-pic' was preposterously unclear. It also allowed the use of this flag on non-Darwin platforms where it has no actual meaning. Now this option is handled directly based on tests of how llvm-gcc behaves, and it is only supported on Darwin. 3) The APIs for the Driver's ToolChains had the implementation ugliness of dynamic-no-pic leaking through them. They also had the implementation details of the LLVM relocation model flag names leaking through. 4) The actual results of passing these flags was incorrect on Darwin in many cases. For example, Darwin *always* uses PIC level 2 if it uses in PIC level, and Darwin *always* uses PIC on 64-bit regardless of the flags specified, including -fPIE. Darwin never compiles in PIE mode, but it can *link* in PIE mode. 5) Also, PIC was not always being enabled even when PIE was. This isn't a supported mode at all and may have caused some fallout in builds with complex PIC and PIE interactions. The result is (I hope) cleaner and clearer for readers. I've also left comments and tests about some of the truly strage behavior that is observed on Darwin platforms. We have no real testing of Windows platforms and PIC, but I don't have the tools handy to figure that out. Hopefully others can beef up our testing here. Unfortunately, I can't test this for every platform. =/ If folks have dependencies on these flags that aren't covered by tests, they may break. I've audited and ensured that all the changes in behavior of the existing tests are intentional and good. In particular I've tried to make sure the Darwin behavior (which is more suprising than the Linux behavior) also matches that of 'gcc' on my mac. git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_32@168416 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticDriverKinds.td | 2 + include/clang/Driver/ToolChain.h | 15 ++- lib/Driver/ToolChains.cpp | 38 ++++--- lib/Driver/ToolChains.h | 22 ++--- lib/Driver/Tools.cpp | 143 ++++++++++++++++----------- lib/Driver/WindowsToolChain.cpp | 10 +- test/Driver/pic.c | 48 ++++++++- 7 files changed, 172 insertions(+), 106 deletions(-) diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index fe0be427a4..4b43035175 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -11,6 +11,8 @@ let Component = "Driver" in { def err_drv_no_such_file : Error<"no such file or directory: '%0'">; def err_drv_unsupported_opt : Error<"unsupported option '%0'">; +def err_drv_unsupported_opt_for_target : Error< + "unsupported option '%0' for target '%1'">; def err_drv_unsupported_option_argument : Error< "unsupported argument '%1' to option '%0'">; def err_drv_unknown_stdin_type : Error< diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 71736d666e..919e880be0 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -172,14 +172,13 @@ public: /// by default. virtual bool IsUnwindTablesDefault() const; - /// GetDefaultRelocationModel - Return the LLVM name of the default - /// relocation model for this tool chain. - virtual const char *GetDefaultRelocationModel() const = 0; - - /// GetForcedPicModel - Return the LLVM name of the forced PIC model - /// for this tool chain, or 0 if this tool chain does not force a - /// particular PIC mode. - virtual const char *GetForcedPicModel() const = 0; + /// \brief Test whether this toolchain defaults to PIC. + virtual bool isPICDefault() const = 0; + + /// \brief Tests whether this toolchain forces its default for PIC or non-PIC. + /// If this returns true, any PIC related flags should be ignored and instead + /// the result of \c isPICDefault() is used exclusively. + virtual bool isPICDefaultForced() const = 0; /// SupportsProfiling - Does this tool chain support -pg. virtual bool SupportsProfiling() const { return true; } diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 819907b664..a2ccb35ed2 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -869,14 +869,12 @@ bool Darwin::UseSjLjExceptions() const { getTriple().getArch() == llvm::Triple::thumb); } -const char *Darwin::GetDefaultRelocationModel() const { - return "pic"; +bool Darwin::isPICDefault() const { + return true; } -const char *Darwin::GetForcedPicModel() const { - if (getArch() == llvm::Triple::x86_64) - return "pic"; - return 0; +bool Darwin::isPICDefaultForced() const { + return getArch() == llvm::Triple::x86_64; } bool Darwin::SupportsProfiling() const { @@ -1378,13 +1376,14 @@ bool Generic_GCC::IsUnwindTablesDefault() const { return getArch() == llvm::Triple::x86_64; } -const char *Generic_GCC::GetDefaultRelocationModel() const { - return "static"; +bool Generic_GCC::isPICDefault() const { + return false; } -const char *Generic_GCC::GetForcedPicModel() const { - return 0; +bool Generic_GCC::isPICDefaultForced() const { + return false; } + /// Hexagon Toolchain Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple& Triple) @@ -1438,14 +1437,13 @@ Tool &Hexagon_TC::SelectTool(const Compilation &C, return *T; } -const char *Hexagon_TC::GetDefaultRelocationModel() const { - return "static"; +bool Hexagon_TC::isPICDefault() const { + return false; } -const char *Hexagon_TC::GetForcedPicModel() const { - return 0; -} // End Hexagon - +bool Hexagon_TC::isPICDefaultForced() const { + return false; +} /// TCEToolChain - A tool chain using the llvm bitcode tools to perform /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. @@ -1470,12 +1468,12 @@ bool TCEToolChain::IsMathErrnoDefault() const { return true; } -const char *TCEToolChain::GetDefaultRelocationModel() const { - return "static"; +bool TCEToolChain::isPICDefault() const { + return false; } -const char *TCEToolChain::GetForcedPicModel() const { - return 0; +bool TCEToolChain::isPICDefaultForced() const { + return false; } Tool &TCEToolChain::SelectTool(const Compilation &C, diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 8ea466af77..9ef027767e 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -129,8 +129,8 @@ public: const ActionList &Inputs) const; virtual bool IsUnwindTablesDefault() const; - virtual const char *GetDefaultRelocationModel() const; - virtual const char *GetForcedPicModel() const; + virtual bool isPICDefault() const; + virtual bool isPICDefaultForced() const; protected: /// \name ToolChain Implementation Helper Functions @@ -156,8 +156,8 @@ public: virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; - virtual const char *GetDefaultRelocationModel() const; - virtual const char *GetForcedPicModel() const; + virtual bool isPICDefault() const; + virtual bool isPICDefaultForced() const; }; /// Darwin - The base Darwin tool chain. @@ -340,8 +340,8 @@ public: virtual RuntimeLibType GetDefaultRuntimeLibType() const { return ToolChain::RLT_CompilerRT; } - virtual const char *GetDefaultRelocationModel() const; - virtual const char *GetForcedPicModel() const; + virtual bool isPICDefault() const; + virtual bool isPICDefaultForced() const; virtual bool SupportsProfiling() const; @@ -389,7 +389,7 @@ public: std::string ComputeEffectiveClangTriple(const ArgList &Args, types::ID InputType) const; - virtual const char *GetDefaultRelocationModel() const { return "pic"; } + virtual bool isPICDefault() const { return false; }; }; class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { @@ -530,8 +530,8 @@ public: virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const; bool IsMathErrnoDefault() const; - const char* GetDefaultRelocationModel() const; - const char* GetForcedPicModel() const; + bool isPICDefault() const; + bool isPICDefaultForced() const; private: mutable llvm::DenseMap Tools; @@ -553,8 +553,8 @@ public: virtual bool IsIntegratedAssemblerDefault() const; virtual bool IsUnwindTablesDefault() const; - virtual const char *GetDefaultRelocationModel() const; - virtual const char *GetForcedPicModel() const; + virtual bool isPICDefault() const; + virtual bool isPICDefaultForced() const; virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index d42078461c..e37959be4e 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1769,30 +1769,46 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CheckCodeGenerationOptions(D, Args); - // Perform argument translation for LLVM backend. This - // takes some care in reconciling with llvm-gcc. The - // issue is that llvm-gcc translates these options based on - // the values in cc1, whereas we are processing based on - // the driver arguments. - - // This comes from the default translation the driver + cc1 - // would do to enable flag_pic. - - Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, - options::OPT_fpic, options::OPT_fno_pic, - options::OPT_fPIE, options::OPT_fno_PIE, - options::OPT_fpie, options::OPT_fno_pie); - bool PICDisabled = false; - bool PICEnabled = false; - bool PICForPIE = false; - if (LastPICArg) { - PICForPIE = (LastPICArg->getOption().matches(options::OPT_fPIE) || - LastPICArg->getOption().matches(options::OPT_fpie)); - PICEnabled = (PICForPIE || - LastPICArg->getOption().matches(options::OPT_fPIC) || - LastPICArg->getOption().matches(options::OPT_fpic)); - PICDisabled = !PICEnabled; + // For the PIC and PIE flag options, this logic is different from the legacy + // logic in very old versions of GCC, as that logic was just a bug no one had + // ever fixed. This logic is both more rational and consistent with GCC's new + // logic now that the bugs are fixed. The last argument relating to either + // PIC or PIE wins, and no other argument is used. If the last argument is + // any flavor of the '-fno-...' arguments, both PIC and PIE are disabled. Any + // PIE option implicitly enables PIC at the same level. + bool PIE = false; + bool PIC = getToolChain().isPICDefault(); + bool IsPICLevelTwo = PIC; + if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, + options::OPT_fpic, options::OPT_fno_pic, + options::OPT_fPIE, options::OPT_fno_PIE, + options::OPT_fpie, options::OPT_fno_pie)) { + Option O = A->getOption(); + if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) || + O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) { + PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie); + PIC = PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic); + IsPICLevelTwo = O.matches(options::OPT_fPIE) || + O.matches(options::OPT_fPIC); + } else { + PIE = PIC = false; + } + } + // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness + // is forced, then neither PIC nor PIE flags will have no effect. + if (getToolChain().isPICDefaultForced()) { + PIE = false; + PIC = getToolChain().isPICDefault(); + IsPICLevelTwo = PIC; } + + // Inroduce a Darwin-specific hack. If the default is PIC but the flags + // specified while enabling PIC enabled level 1 PIC, just force it back to + // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my + // informal testing). + if (PIC && getToolChain().getTriple().isOSDarwin()) + IsPICLevelTwo |= getToolChain().isPICDefault(); + // Note that these flags are trump-cards. Regardless of the order w.r.t. the // PIC or PIE options above, if these show up, PIC is disabled. llvm::Triple Triple(TripleStr); @@ -1800,40 +1816,43 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.hasArg(options::OPT_fapple_kext)) && (Triple.getOS() != llvm::Triple::IOS || Triple.isOSVersionLT(6))) - PICDisabled = true; + PIC = PIE = false; if (Args.hasArg(options::OPT_static)) - PICDisabled = true; - bool DynamicNoPIC = Args.hasArg(options::OPT_mdynamic_no_pic); - - // Select the relocation model. - const char *Model = getToolChain().GetForcedPicModel(); - if (!Model) { - if (DynamicNoPIC) - Model = "dynamic-no-pic"; - else if (PICDisabled) - Model = "static"; - else if (PICEnabled) - Model = "pic"; - else - Model = getToolChain().GetDefaultRelocationModel(); - } - StringRef ModelStr = Model ? Model : ""; - if (Model && ModelStr != "pic") { - CmdArgs.push_back("-mrelocation-model"); - CmdArgs.push_back(Model); - } + PIC = PIE = false; + + if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) { + // This is a very special mode. It trumps the other modes, almost no one + // uses it, and it isn't even valid on any OS but Darwin. + if (!getToolChain().getTriple().isOSDarwin()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getSpelling() << getToolChain().getTriple().str(); - // Infer the __PIC__ and __PIE__ values. - if (ModelStr == "pic" && PICForPIE) { - CmdArgs.push_back("-pie-level"); - CmdArgs.push_back((LastPICArg && - LastPICArg->getOption().matches(options::OPT_fPIE)) ? - "2" : "1"); - } else if (ModelStr == "pic" || ModelStr == "dynamic-no-pic") { - CmdArgs.push_back("-pic-level"); - CmdArgs.push_back(((ModelStr != "dynamic-no-pic" && LastPICArg && - LastPICArg->getOption().matches(options::OPT_fPIC)) || - getToolChain().getTriple().isOSDarwin()) ? "2" : "1"); + // FIXME: Warn when this flag trumps some other PIC or PIE flag. + + CmdArgs.push_back("-mrelocation-model"); + CmdArgs.push_back("dynamic-no-pic"); + + // Only a forced PIC mode can cause the actual compile to have PIC defines + // etc., no flags are sufficient. This behavior was selected to closely + // match that of llvm-gcc and Apple GCC before that. + if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) { + CmdArgs.push_back("-pic-level"); + CmdArgs.push_back("2"); + } + } else { + // Currently, LLVM only knows about PIC vs. static; the PIE differences are + // handled in Clang's IRGen by the -pie-level flag. + CmdArgs.push_back("-mrelocation-model"); + CmdArgs.push_back(PIC ? "pic" : "static"); + + if (PIC) { + CmdArgs.push_back("-pic-level"); + CmdArgs.push_back(IsPICLevelTwo ? "2" : "1"); + if (PIE) { + CmdArgs.push_back("-pie-level"); + CmdArgs.push_back(IsPICLevelTwo ? "2" : "1"); + } + } } if (!Args.hasFlag(options::OPT_fmerge_all_constants, @@ -2715,6 +2734,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fobjc-default-synthesize-properties"); } + // -fencode-extended-block-signature=1 is default. + if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) { + CmdArgs.push_back("-fencode-extended-block-signature"); + } + // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc. // NOTE: This logic is duplicated in ToolChains.cpp. bool ARC = isObjCAutoRefCount(Args); @@ -4686,10 +4710,11 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); SanitizerArgs Sanitize(getToolChain().getDriver(), Args); - // If we're building a dynamic lib with -fsanitize=address, unresolved - // symbols may appear. Mark all of them as dynamic_lookup. - // Linking executables is handled in lib/Driver/ToolChains.cpp. - if (Sanitize.needsAsanRt()) { + // If we're building a dynamic lib with -fsanitize=address, or + // -fsanitize=undefined, unresolved symbols may appear. Mark all + // of them as dynamic_lookup. Linking executables is handled in + // lib/Driver/ToolChains.cpp. + if (Sanitize.needsAsanRt() || Sanitize.needsUbsanRt()) { if (Args.hasArg(options::OPT_dynamiclib) || Args.hasArg(options::OPT_bundle)) { CmdArgs.push_back("-undefined"); diff --git a/lib/Driver/WindowsToolChain.cpp b/lib/Driver/WindowsToolChain.cpp index ac6518712f..de2d5352b7 100644 --- a/lib/Driver/WindowsToolChain.cpp +++ b/lib/Driver/WindowsToolChain.cpp @@ -84,14 +84,12 @@ bool Windows::IsUnwindTablesDefault() const { return getArch() == llvm::Triple::x86_64; } -const char *Windows::GetDefaultRelocationModel() const { - return "static"; +bool Windows::isPICDefault() const { + return getArch() == llvm::Triple::x86_64; } -const char *Windows::GetForcedPicModel() const { - if (getArch() == llvm::Triple::x86_64) - return "pic"; - return 0; +bool Windows::isPICDefaultForced() const { + return getArch() == llvm::Triple::x86_64; } // FIXME: This probably should goto to some platform utils place. diff --git a/test/Driver/pic.c b/test/Driver/pic.c index 5b69dba36d..efe525e555 100644 --- a/test/Driver/pic.c +++ b/test/Driver/pic.c @@ -55,9 +55,11 @@ // RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-pie -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC // RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-pic -### 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-pic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE1 // RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-pie -### 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 // RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIC -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 // RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fpic -### 2>&1 \ @@ -67,6 +69,48 @@ // RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIC -fPIE -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIE2 // +// Cases where both pic and pie are specified +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fpie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fpie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fpic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fpic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fpie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fpie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE1 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fPIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fPIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE1 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// // Defaults change for Darwin. // RUN: %clang -c %s -target i386-apple-darwin -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 -- cgit v1.2.3 From e469f9723e7d6b659dcafa88fe4acaeefd9f5f29 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Wed, 21 Nov 2012 08:33:40 +0000 Subject: Merging r168063 into 3.2 release branch block extended signatur option. Change previous option to a cc1 -fencode-extended-block-signature and pass it to cc1 and recognize this option to produce extended block type signature. // rdar://12109031 git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_32@168419 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/LangOptions.def | 2 ++ include/clang/Driver/CC1Options.td | 2 ++ include/clang/Driver/ToolChain.h | 4 ++++ lib/AST/ASTContext.cpp | 14 ++++++++++++-- lib/Driver/ToolChains.h | 4 ++++ lib/Frontend/CompilerInvocation.cpp | 2 ++ test/Driver/rewrite-legacy-objc.m | 2 +- test/Driver/rewrite-objc.m | 2 +- 8 files changed, 28 insertions(+), 4 deletions(-) diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index 7e255c2102..dbc08c7dca 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -53,6 +53,8 @@ LANGOPT(ObjC1 , 1, 0, "Objective-C 1") LANGOPT(ObjC2 , 1, 0, "Objective-C 2") BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, "Objective-C auto-synthesized properties") +BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0, + "Encoding extended block type signature") BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1, "Objective-C related result type inference") LANGOPT(Trigraphs , 1, 0,"trigraphs") diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 61c3d4919f..3ff25494ff 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -404,6 +404,8 @@ def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">, HelpText<"Objective-C dispatch method to use">; def fobjc_default_synthesize_properties : Flag<["-"], "fobjc-default-synthesize-properties">, HelpText<"enable the default synthesis of Objective-C properties">; +def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">, + HelpText<"enable extended encoding of block type signature">; def pic_level : Separate<["-"], "pic-level">, HelpText<"Value for __PIC__">; def pie_level : Separate<["-"], "pie-level">, diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 919e880be0..509e08d67e 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -148,6 +148,10 @@ public: /// IsObjCDefaultSynthPropertiesDefault - Does this tool chain enable /// -fobjc-default-synthesize-properties by default. virtual bool IsObjCDefaultSynthPropertiesDefault() const { return false; } + + /// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable + /// -fencode-extended-block-signature by default. + virtual bool IsEncodeExtendedBlockSignatureDefault() const { return false; } /// IsObjCNonFragileABIDefault - Does this tool chain set /// -fobjc-nonfragile-abi by default. diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 2f7288109c..1506197a47 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4481,7 +4481,13 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { QualType BlockTy = Expr->getType()->getAs()->getPointeeType(); // Encode result type. - getObjCEncodingForType(BlockTy->getAs()->getResultType(), S); + if (getLangOpts().EncodeExtendedBlockSig) + getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, + BlockTy->getAs()->getResultType(), + S, true /*Extended*/); + else + getObjCEncodingForType(BlockTy->getAs()->getResultType(), + S); // Compute size of all parameters. // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! @@ -4516,7 +4522,11 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { PType = PVDecl->getType(); } else if (PType->isFunctionType()) PType = PVDecl->getType(); - getObjCEncodingForType(PType, S); + if (getLangOpts().EncodeExtendedBlockSig) + getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, PType, + S, true /*Extended*/); + else + getObjCEncodingForType(PType, S); S += charUnitsToString(ParmOffset); ParmOffset += getObjCEncodingTypeSize(PType); } diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 9ef027767e..4c267e8a8b 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -318,6 +318,10 @@ public: return true; } + virtual bool IsEncodeExtendedBlockSignatureDefault() const { + return true; + } + virtual bool IsObjCNonFragileABIDefault() const { // Non-fragile ABI is default for everything but i386. return getTriple().getArch() != llvm::Triple::x86; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 8baad79835..b9c198b111 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1213,6 +1213,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Args.getLastArgValue(OPT_fconstant_string_class); Opts.ObjCDefaultSynthProperties = Args.hasArg(OPT_fobjc_default_synthesize_properties); + Opts.EncodeExtendedBlockSig = + Args.hasArg(OPT_fencode_extended_block_signature); Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls); Opts.PackStruct = Args.getLastArgIntValue(OPT_fpack_struct_EQ, 0, Diags); Opts.PICLevel = Args.getLastArgIntValue(OPT_pic_level, 0, Diags); diff --git a/test/Driver/rewrite-legacy-objc.m b/test/Driver/rewrite-legacy-objc.m index a76175f68a..2e3f4218ef 100644 --- a/test/Driver/rewrite-legacy-objc.m +++ b/test/Driver/rewrite-legacy-objc.m @@ -3,5 +3,5 @@ // TEST0: clang{{.*}}" "-cc1" // TEST0: "-rewrite-objc" // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead. -// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime=macosx-fragile" "-fobjc-default-synthesize-properties" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option" +// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime=macosx-fragile" "-fobjc-default-synthesize-properties" "-fencode-extended-block-signature" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option" // TEST0: rewrite-legacy-objc.m" diff --git a/test/Driver/rewrite-objc.m b/test/Driver/rewrite-objc.m index ca578cf40e..fa159a6258 100644 --- a/test/Driver/rewrite-objc.m +++ b/test/Driver/rewrite-objc.m @@ -3,4 +3,4 @@ // TEST0: clang{{.*}}" "-cc1" // TEST0: "-rewrite-objc" // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead. -// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime=macosx" "-fobjc-dispatch-method=mixed" "-fobjc-default-synthesize-properties" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option" +// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime=macosx" "-fobjc-dispatch-method=mixed" "-fobjc-default-synthesize-properties" "-fencode-extended-block-signature" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option" -- cgit v1.2.3 From b5fa2f04f037a5d5caa858daf270f9b7406a7a36 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Thu, 22 Nov 2012 06:10:56 +0000 Subject: Merging r168355: into the 3.2 release branch. Update method calls to the new interface re r168354. git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_32@168487 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCall.cpp | 3 ++- lib/CodeGen/CodeGenModule.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 4fbf7bfdb0..2d1d152894 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -2177,7 +2177,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, unsigned CallingConv; CodeGen::AttributeListType AttributeList; CGM.ConstructAttributeList(CallInfo, TargetDecl, AttributeList, CallingConv); - llvm::AttrListPtr Attrs = llvm::AttrListPtr::get(AttributeList); + llvm::AttrListPtr Attrs = llvm::AttrListPtr::get(getLLVMContext(), + AttributeList); llvm::BasicBlock *InvokeDest = 0; if (!Attrs.getFnAttributes().hasAttribute(llvm::Attributes::NoUnwind)) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 8975e2f4c0..17972e29b6 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -533,7 +533,7 @@ void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D, unsigned CallingConv; AttributeListType AttributeList; ConstructAttributeList(Info, D, AttributeList, CallingConv); - F->setAttributes(llvm::AttrListPtr::get(AttributeList)); + F->setAttributes(llvm::AttrListPtr::get(getLLVMContext(), AttributeList)); F->setCallingConv(static_cast(CallingConv)); } @@ -1864,7 +1864,7 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, ArgList.clear(); if (!NewCall->getType()->isVoidTy()) NewCall->takeName(CI); - NewCall->setAttributes(llvm::AttrListPtr::get(AttrVec)); + NewCall->setAttributes(llvm::AttrListPtr::get(OldFn->getContext(), AttrVec)); NewCall->setCallingConv(CI->getCallingConv()); // Finally, remove the old call, replacing any uses with the new one. -- cgit v1.2.3