diff options
-rw-r--r-- | include/clang/Basic/TargetInfo.h | 28 | ||||
-rw-r--r-- | include/clang/Driver/Options.def | 42 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 97 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 98 | ||||
-rw-r--r-- | test/CodeGen/mmintrin-test.c | 4 | ||||
-rw-r--r-- | test/Driver/analyze.c | 2 | ||||
-rw-r--r-- | test/Driver/clang-translation.c | 4 | ||||
-rw-r--r-- | test/Sema/carbon-pth.c | 6 | ||||
-rw-r--r-- | test/Sema/carbon.c | 3 | ||||
-rw-r--r-- | test/SemaCXX/carbon.cpp | 2 | ||||
-rw-r--r-- | test/SemaObjC/cocoa-pth.m | 6 | ||||
-rw-r--r-- | test/SemaObjC/cocoa.m | 3 | ||||
-rw-r--r-- | test/SemaObjCXX/cocoa.mm | 2 | ||||
-rw-r--r-- | tools/clang-cc/clang-cc.cpp | 101 |
14 files changed, 217 insertions, 181 deletions
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 94fa0d4aea..ce54db7581 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_BASIC_TARGETINFO_H #define LLVM_CLANG_BASIC_TARGETINFO_H +// FIXME: Daniel isn't smart enough to use a prototype for this. +#include "llvm/ADT/StringMap.h" #include "llvm/Support/DataTypes.h" #include <cassert> #include <vector> @@ -334,22 +336,16 @@ public: /// options. virtual void getDefaultLangOptions(LangOptions &Opts) {} - /// HandleTargetFeatures - Handle target-specific options like -mattr=+sse2 - /// and friends. An array of arguments is passed in: if they are all valid, - /// this should handle them and return -1. If there is an error, the index of - /// the invalid argument should be returned along with an optional error - /// string. - /// - /// Note that the driver should have already consolidated all the - /// target-feature settings and passed them to us in the -mattr list. The - /// -mattr list is treated by the code generator as a diff against the -mcpu - /// setting, but the driver should pass all enabled options as "+" settings. - /// This means that the target should only look at + settings. - virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs, - std::string &ErrorReason) { - if (NumStrs == 0) - return -1; - return 0; + /// getDefaultFeatures - Get the default set of target features for + /// the \args CPU; this should include all legal feature strings on + /// the target. + virtual void getDefaultFeatures(const std::string &CPU, + llvm::StringMap<bool> &Features) { + } + + /// HandleTargetOptions - Perform initialization based on the user + /// configured set of features. + virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features) { } // getRegParmMax - Returns maximal number of args passed in registers. diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def index 5d35602e5b..cf077be969 100644 --- a/include/clang/Driver/Options.def +++ b/include/clang/Driver/Options.def @@ -108,6 +108,7 @@ OPTION("<g group>", g_Group, Group, INVALID, INVALID, "", 0, 0, 0) OPTION("<i group>", i_Group, Group, INVALID, INVALID, "", 0, 0, 0) OPTION("<clang i group>", clang_i_Group, Group, i_Group, INVALID, "", 0, 0, 0) OPTION("<m group>", m_Group, Group, INVALID, INVALID, "", 0, 0, 0) +OPTION("<m x86 features group>", m_x86_Features_Group, Group, INVALID, INVALID, "", 0, 0, 0) OPTION("<u group>", u_Group, Group, INVALID, INVALID, "", 0, 0, 0) OPTION("<pedantic group>", pedantic_Group, Group, INVALID, INVALID, "", 0, 0, 0) @@ -477,41 +478,42 @@ OPTION("-i", i, Joined, i_Group, INVALID, "", 0, 0, 0) OPTION("-keep_private_externs", keep__private__externs, Flag, INVALID, INVALID, "", 0, 0, 0) OPTION("-l", l, JoinedOrSeparate, INVALID, INVALID, "l", 0, 0, 0) OPTION("-m32", m32, Flag, m_Group, INVALID, "d", 0, 0, 0) -OPTION("-m3dnowa", m3dnowa, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-m3dnow", m3dnow, Flag, m_Group, INVALID, "", 0, 0, 0) +OPTION("-m3dnowa", m3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-m3dnow", m3dnow, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) OPTION("-m64", m64, Flag, m_Group, INVALID, "d", 0, 0, 0) +OPTION("-march=", march_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0) OPTION("-mconstant-cfstrings", mconstant_cfstrings, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0) OPTION("-mdynamic-no-pic", mdynamic_no_pic, Joined, m_Group, INVALID, "q", 0, 0, 0) OPTION("-mfix-and-continue", mfix_and_continue, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0) OPTION("-miphoneos-version-min=", miphoneos_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0) OPTION("-mkernel", mkernel, Flag, m_Group, INVALID, "", 0, 0, 0) OPTION("-mmacosx-version-min=", mmacosx_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mmmx", mmmx, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-3dnowa", mno_3dnowa, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-3dnow", mno_3dnow, Flag, m_Group, INVALID, "", 0, 0, 0) +OPTION("-mmmx", mmmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-3dnowa", mno_3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-3dnow", mno_3dnow, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) OPTION("-mno-constant-cfstrings", mno_constant_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-mmx", mno_mmx, Flag, m_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-mmx", mno_mmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) OPTION("-mno-pascal-strings", mno_pascal_strings, Flag, m_Group, INVALID, "", 0, 0, 0) OPTION("-mno-red-zone", mno_red_zone, Flag, m_Group, INVALID, "", 0, 0, 0) OPTION("-mno-soft-float", mno_soft_float, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-sse2", mno_sse2, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-sse3", mno_sse3, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-sse41", mno_sse41, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-sse42", mno_sse42, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-sse4a", mno_sse4a, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-sse", mno_sse, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mno-ssse3", mno_ssse3, Flag, m_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-sse2", mno_sse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-sse3", mno_sse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-sse41", mno_sse41, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-sse42", mno_sse42, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-sse4a", mno_sse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-sse", mno_sse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mno-ssse3", mno_ssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) OPTION("-mno-warn-nonportable-cfstrings", mno_warn_nonportable_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0) OPTION("-mpascal-strings", mpascal_strings, Flag, m_Group, INVALID, "", 0, 0, 0) OPTION("-mred-zone", mred_zone, Flag, m_Group, INVALID, "", 0, 0, 0) OPTION("-msoft-float", msoft_float, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-msse2", msse2, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-msse3", msse3, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-msse41", msse41, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-msse42", msse42, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-msse4a", msse4a, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-msse", msse, Flag, m_Group, INVALID, "", 0, 0, 0) -OPTION("-mssse3", mssse3, Flag, m_Group, INVALID, "", 0, 0, 0) +OPTION("-msse2", msse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-msse3", msse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-msse41", msse41, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-msse42", msse42, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-msse4a", msse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-msse", msse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) +OPTION("-mssse3", mssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0) OPTION("-mtune=", mtune_EQ, Joined, m_Group, INVALID, "", 0, 0, 0) OPTION("-multi_module", multi__module, Flag, INVALID, INVALID, "", 0, 0, 0) OPTION("-multiply_defined_unused", multiply__defined__unused, Separate, INVALID, INVALID, "", 0, 0, 0) diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index e0db82d2a8..bb568b149b 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -503,10 +503,7 @@ class X86TargetInfo : public TargetInfo { } SSELevel; public: X86TargetInfo(const std::string& triple) - : TargetInfo(triple), - // FIXME: hard coding to SSE2 for now. This should change to NoMMXSSE so - // that the driver controls this. - SSELevel(SSE2) { + : TargetInfo(triple), SSELevel(NoMMXSSE) { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } virtual void getTargetBuiltins(const Builtin::Info *&Records, @@ -536,49 +533,59 @@ public: virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const; - virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs, - std::string &ErrorReason); + virtual void getDefaultFeatures(const std::string &CPU, + llvm::StringMap<bool> &Features); + virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features); }; -/// HandleTargetOptions - Handle target-specific options like -msse2 and -/// friends. An array of arguments is passed in: if they are all valid, this -/// should handle them and return -1. If there is an error, the index of the -/// invalid argument should be returned along with an optional error string. -int X86TargetInfo::HandleTargetFeatures(std::string *StrArray, unsigned NumStrs, - std::string &ErrorReason) { - for (unsigned i = 0; i != NumStrs; ++i) { - const std::string &Feature = StrArray[i]; - if (Feature.size() < 2) return i; - // Ignore explicitly disabled features. - if (Feature[0] == '-') continue; - - // Feature strings are of the form "+feature". - if (Feature[0] != '+') return i; - - // The set of supported subtarget features is defined in - // lib/Target/X86/X86.td. Here we recognize and map onto our internal - // state. - if (Feature == "+mmx") - SSELevel = std::max(SSELevel, MMX); - else if (Feature == "+sse") - SSELevel = std::max(SSELevel, SSE1); - else if (Feature == "+sse2") - SSELevel = std::max(SSELevel, SSE2); - else if (Feature == "+sse3") - SSELevel = std::max(SSELevel, SSE3); - else if (Feature == "+ssse3") - SSELevel = std::max(SSELevel, SSSE3); - else if (Feature == "+sse41") - SSELevel = std::max(SSELevel, SSE41); - else if (Feature == "+sse42") - SSELevel = std::max(SSELevel, SSE42); - else if (Feature == "+64bit" || Feature == "+slow-bt-mem") - // Ignore these features. - continue; - else - return i; - } - return -1; +void X86TargetInfo::getDefaultFeatures(const std::string &CPU, + llvm::StringMap<bool> &Features) { + // FIXME: This should not be here. + Features["3dnow"] = false; + Features["3dnowa"] = false; + Features["mmx"] = false; + Features["sse"] = false; + Features["sse2"] = false; + Features["sse3"] = false; + Features["ssse3"] = false; + Features["sse41"] = false; + Features["sse42"] = false; + + // LLVM does not currently recognize this. + // Features["sse4a"] = false; + + // FIXME: This *really* should not be here. + + // X86_64 always has SSE2. + if (PointerWidth == 64) + Features["sse2"] = Features["sse"] = Features["mmx"] = true; + + // FIXME: LLVM says core2 has SSSE3, but gcc doesn't define + // __SSSE3__ with it? What else is going on here? + if (CPU == "core2") + Features["ssse3"] = Features["sse3"] = Features["sse2"] = Features["sse"] = + Features["mmx"] = true; + else if (CPU == "pentium4") + Features["sse2"] = Features["sse"] = Features["mmx"] = true; +} + +/// HandleTargetOptions - Perform initialization based on the user +/// configured set of features. +void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) { + if (Features.lookup("sse42")) + SSELevel = SSE42; + else if (Features.lookup("sse41")) + SSELevel = SSE41; + else if (Features.lookup("ssse3")) + SSELevel = SSSE3; + else if (Features.lookup("sse3")) + SSELevel = SSE3; + else if (Features.lookup("sse2")) + SSELevel = SSE2; + else if (Features.lookup("sse")) + SSELevel = SSE1; + else if (Features.lookup("mmx")) + SSELevel = MMX; } /// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 2a959b3c55..a52498dc95 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -31,6 +31,13 @@ using namespace clang::driver; using namespace clang::driver::tools; +static const char *MakeFormattedString(const ArgList &Args, + const llvm::format_object_base &Fmt) { + std::string Str; + llvm::raw_string_ostream(Str) << Fmt; + return Args.MakeArgString(Str.c_str()); +} + void Clang::AddPreprocessingOptions(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs, @@ -318,52 +325,48 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("--soft-float"); - // FIXME: Need target hooks. - if (memcmp(getToolChain().getPlatform().c_str(), "darwin", 6) == 0) { - if (getToolChain().getArchName() == "x86_64") - CmdArgs.push_back("--mcpu=core2"); - else if (getToolChain().getArchName() == "i386") - CmdArgs.push_back("--mcpu=yonah"); - } - - // FIXME: Ignores ordering. Also, we need to find a realistic - // solution for this. - static const struct { - options::ID Pos, Neg; - const char *Name; - } FeatureOptions[] = { - { options::OPT_mmmx, options::OPT_mno_mmx, "mmx" }, - { options::OPT_msse, options::OPT_mno_sse, "sse" }, - { options::OPT_msse2, options::OPT_mno_sse2, "sse2" }, - { options::OPT_msse3, options::OPT_mno_sse3, "sse3" }, - { options::OPT_mssse3, options::OPT_mno_ssse3, "ssse3" }, - { options::OPT_msse41, options::OPT_mno_sse41, "sse41" }, - { options::OPT_msse42, options::OPT_mno_sse42, "sse42" }, - { options::OPT_msse4a, options::OPT_mno_sse4a, "sse4a" }, - { options::OPT_m3dnow, options::OPT_mno_3dnow, "3dnow" }, - { options::OPT_m3dnowa, options::OPT_mno_3dnowa, "3dnowa" } - }; - const unsigned NumFeatureOptions = - sizeof(FeatureOptions)/sizeof(FeatureOptions[0]); - - // FIXME: Avoid std::string - std::string Attrs; - for (unsigned i=0; i < NumFeatureOptions; ++i) { - if (Args.hasArg(FeatureOptions[i].Pos)) { - if (!Attrs.empty()) - Attrs += ','; - Attrs += '+'; - Attrs += FeatureOptions[i].Name; - } else if (Args.hasArg(FeatureOptions[i].Neg)) { - if (!Attrs.empty()) - Attrs += ','; - Attrs += '-'; - Attrs += FeatureOptions[i].Name; + // FIXME: Handle -mtune=. + (void) Args.hasArg(options::OPT_mtune_EQ); + + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { + // FIXME: We made need some translation here from the options gcc + // takes to names the LLVM backend understand? + CmdArgs.push_back("-mcpu"); + CmdArgs.push_back(A->getValue(Args)); + } else { + // Select default CPU. + + // FIXME: Need target hooks. + if (memcmp(getToolChain().getOS().c_str(), "darwin", 6) == 0) { + if (getToolChain().getArchName() == "x86_64") + CmdArgs.push_back("--mcpu=core2"); + else if (getToolChain().getArchName() == "i386") + CmdArgs.push_back("--mcpu=pentium4"); } } - if (!Attrs.empty()) { - CmdArgs.push_back("--mattr"); - CmdArgs.push_back(Args.MakeArgString(Attrs.c_str())); + + // FIXME: Use iterator. + for (ArgList::const_iterator + it = Args.begin(), ie = Args.end(); it != ie; ++it) { + const Arg *A = *it; + if (A->getOption().matches(options::OPT_m_x86_Features_Group)) { + const char *Name = A->getOption().getName(); + + // Skip over "-m". + assert(Name[0] == '-' && Name[1] == 'm' && "Invalid feature name."); + Name += 2; + + bool IsNegative = memcmp(Name, "no-", 3) == 0; + if (IsNegative) + Name += 3; + + A->claim(); + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back(MakeFormattedString(Args, + llvm::format("%c%s", + IsNegative ? '-' : '+', + Name))); + } } if (Args.hasFlag(options::OPT_fmath_errno, @@ -1215,13 +1218,6 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, Dest.addCommand(new Command(Exec, CmdArgs)); } -static const char *MakeFormattedString(const ArgList &Args, - const llvm::format_object_base &Fmt) { - std::string Str; - llvm::raw_string_ostream(Str) << Fmt; - return Args.MakeArgString(Str.c_str()); -} - /// Helper routine for seeing if we should use dsymutil; this is a /// gcc compatible hack, we should remove it and use the input /// type information. diff --git a/test/CodeGen/mmintrin-test.c b/test/CodeGen/mmintrin-test.c index 97f3b3b67c..2a9ab56723 100644 --- a/test/CodeGen/mmintrin-test.c +++ b/test/CodeGen/mmintrin-test.c @@ -1,6 +1,6 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm -o %t %s && +// RUN: clang-cc -triple i386-apple-darwin9 -mcpu=pentium4 -emit-llvm -o %t %s && // RUN: grep define %t | count 1 && -// RUN: clang-cc -triple i386-apple-darwin9 -g -emit-llvm -o %t %s && +// RUN: clang-cc -triple i386-apple-darwin9 -mcpu=pentium4 -g -emit-llvm -o %t %s && // RUN: grep define %t | count 1 #include <mmintrin.h> diff --git a/test/Driver/analyze.c b/test/Driver/analyze.c index f82199d356..338c6148c1 100644 --- a/test/Driver/analyze.c +++ b/test/Driver/analyze.c @@ -4,6 +4,6 @@ // RUN: clang -ccc-host-triple i386-apple-darwin9 -### --analyze -o /dev/null %s -msse 2> %t.log && // RUN: grep '"-analyze"' %t.log && // RUN: grep '"--fmath-errno=0"' %t.log && -// RUN: grep '"--mattr" "+sse"' %t.log && +// RUN: grep '"-target-feature" "+sse"' %t.log && // RUN: grep '"-mmacosx-version-min=10.5.0"' %t.log diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c index 2421bd1f3a..6d523954c7 100644 --- a/test/Driver/clang-translation.c +++ b/test/Driver/clang-translation.c @@ -9,4 +9,8 @@ // RUN: grep '"-Os"' %t.log && // RUN: grep '"-o" .*clang-translation\.c\.out\.tmp\.s' %t.log && // RUN: grep '"--asm-verbose"' %t.log && +// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -S %s -o %t.s 2> %t.log +// RUN: grep '"--mcpu=pentium4"' %t.log && +// RUN: clang -ccc-host-triple x86_64-apple-darwin9 -### -S %s -o %t.s 2> %t.log +// RUN: grep '"--mcpu=core2"' %t.log && // RUN: true diff --git a/test/Sema/carbon-pth.c b/test/Sema/carbon-pth.c index ebc8840545..c956d2a7a1 100644 --- a/test/Sema/carbon-pth.c +++ b/test/Sema/carbon-pth.c @@ -1,6 +1,6 @@ -// RUN: clang-cc -emit-pth -o %t %s && -// RUN: clang-cc -token-cache %t %s && -// RUN: clang-cc -token-cache %t %s -E %s -o /dev/null +// RUN: clang-cc -mcpu=pentium4 -emit-pth -o %t %s && +// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s && +// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s -E %s -o /dev/null #ifdef __APPLE__ #include <Carbon/Carbon.h> #endif diff --git a/test/Sema/carbon.c b/test/Sema/carbon.c index 8e6837f125..5eda4385ac 100644 --- a/test/Sema/carbon.c +++ b/test/Sema/carbon.c @@ -1,5 +1,4 @@ -// RUN: clang-cc %s -print-stats && -// RUN: clang-cc %s -disable-free +// RUN: clang-cc -mcpu=pentium4 %s -print-stats #ifdef __APPLE__ #include <Carbon/Carbon.h> #endif diff --git a/test/SemaCXX/carbon.cpp b/test/SemaCXX/carbon.cpp index 983a000b2c..0e7570f335 100644 --- a/test/SemaCXX/carbon.cpp +++ b/test/SemaCXX/carbon.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc %s -fsyntax-only -print-stats +// RUN: clang-cc -mcpu=pentium4 %s -fsyntax-only -print-stats #ifdef __APPLE__ #include <Carbon/Carbon.h> #endif diff --git a/test/SemaObjC/cocoa-pth.m b/test/SemaObjC/cocoa-pth.m index 24b0579a24..dc806dfb7c 100644 --- a/test/SemaObjC/cocoa-pth.m +++ b/test/SemaObjC/cocoa-pth.m @@ -1,6 +1,6 @@ -// RUN: clang-cc -emit-pth -o %t %s && -// RUN: clang-cc -token-cache %t %s && -// RUN: clang-cc -token-cache %t %s -E %s -o /dev/null +// RUN: clang-cc -mcpu=pentium4 -emit-pth -o %t %s && +// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s && +// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s -E %s -o /dev/null #ifdef __APPLE__ #include <Cocoa/Cocoa.h> #endif diff --git a/test/SemaObjC/cocoa.m b/test/SemaObjC/cocoa.m index 153c46e103..b73b3c4ccd 100644 --- a/test/SemaObjC/cocoa.m +++ b/test/SemaObjC/cocoa.m @@ -1,5 +1,4 @@ -// RUN: clang-cc %s -print-stats && -// RUN: clang-cc %s -disable-free +// RUN: clang-cc -mcpu=pentium4 %s -print-stats #ifdef __APPLE__ #include <Cocoa/Cocoa.h> #endif diff --git a/test/SemaObjCXX/cocoa.mm b/test/SemaObjCXX/cocoa.mm index dd9684ce06..c061d4e096 100644 --- a/test/SemaObjCXX/cocoa.mm +++ b/test/SemaObjCXX/cocoa.mm @@ -1,4 +1,4 @@ -// RUN: clang-cc %s -print-stats +// RUN: clang-cc -mcpu=pentium4 %s -print-stats #ifdef __APPLE__ #include <Cocoa/Cocoa.h> #endif diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index 17eeac776c..3726f1c738 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -50,6 +50,7 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/config.h" #include "llvm/Support/CommandLine.h" @@ -663,10 +664,6 @@ NeXTRuntime("fnext-runtime", static llvm::cl::opt<bool> Trigraphs("trigraphs", llvm::cl::desc("Process trigraph sequences")); -static llvm::cl::list<std::string> -TargetFeatures("mattr", llvm::cl::CommaSeparated, - llvm::cl::desc("Target specific attributes (-mattr=help for details)")); - static llvm::cl::opt<unsigned> TemplateDepth("ftemplate-depth", llvm::cl::init(99), llvm::cl::desc("Maximum depth of recursive template " @@ -711,30 +708,14 @@ static llvm::cl::opt<bool> StaticDefine("static-define", llvm::cl::desc("Should __STATIC__ be defined")); static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, - TargetInfo *Target) { + TargetInfo *Target, + const llvm::StringMap<bool> &Features) { // Allow the target to set the default the langauge options as it sees fit. Target->getDefaultLangOptions(Options); - - // If there are any -mattr options, pass them to the target for validation and - // processing. The driver should have already consolidated all the - // target-feature settings and passed them to us in the -mattr list. The - // -mattr list is treated by the code generator as a diff against the -mcpu - // setting, but the driver should pass all enabled options as "+" settings. - // This means that the target should only look at + settings. - if (!TargetFeatures.empty()) { - std::string ErrorStr; - int Opt = Target->HandleTargetFeatures(&TargetFeatures[0], - TargetFeatures.size(), ErrorStr); - if (Opt != -1) { - if (ErrorStr.empty()) - fprintf(stderr, "invalid feature '%s'\n", - TargetFeatures[Opt].c_str()); - else - fprintf(stderr, "feature '%s': %s\n", - TargetFeatures[Opt].c_str(), ErrorStr.c_str()); - exit(1); - } - } + + // Pass the map of target features to the target for validation and + // processing. + Target->HandleTargetFeatures(Features); if (LangStd == lang_unspecified) { // Based on the base language, pick one. @@ -1429,8 +1410,47 @@ static llvm::cl::opt<std::string> TargetCPU("mcpu", llvm::cl::desc("Target a specific cpu type (-mcpu=help for details)")); +static llvm::cl::list<std::string> +TargetFeatures("target-feature", llvm::cl::desc("Target specific attributes")); + +/// ComputeTargetFeatures - Recompute the target feature list to only +/// be the list of things that are enabled, based on the target cpu +/// and feature list. +static void ComputeFeatureMap(TargetInfo *Target, + llvm::StringMap<bool> &Features) { + assert(Features.empty() && "invalid map"); + + // Initialize the feature map based on the target. + Target->getDefaultFeatures(TargetCPU, Features); + + // Apply the user specified deltas. + for (llvm::cl::list<std::string>::iterator it = TargetFeatures.begin(), + ie = TargetFeatures.end(); it != ie; ++it) { + const char *Name = it->c_str(); + + // FIXME: Don't handle errors like this. + if (Name[0] != '-' && Name[0] != '+') { + fprintf(stderr, "error: clang-cc: invalid target feature string: %s\n", + Name); + exit(1); + } + + llvm::StringMap<bool>::iterator it = Features.find(Name + 1); + if (it == Features.end()) { + fprintf(stderr, "error: clang-cc: invalid target feature string: %s\n", + Name); + exit(1); + } + + // FIXME: Actually, we need to apply all the features implied by + // this feature. + it->second = (Name[0] == '+'); + } +} + static void InitializeCompileOptions(CompileOptions &Opts, - const LangOptions &LangOpts) { + const LangOptions &LangOpts, + const llvm::StringMap<bool> &Features) { Opts.OptimizeSize = OptSize; Opts.DebugInfo = GenerateDebugInfo; if (OptSize) { @@ -1451,8 +1471,15 @@ static void InitializeCompileOptions(CompileOptions &Opts, #endif Opts.CPU = TargetCPU; - Opts.Features.insert(Opts.Features.end(), - TargetFeatures.begin(), TargetFeatures.end()); + Opts.Features.clear(); + for (llvm::StringMap<bool>::const_iterator it = Features.begin(), + ie = Features.end(); it != ie; ++it) { + // FIXME: If we are completely confident that we have the right + // set, we only need to pass the minuses. + std::string Name(it->second ? "+" : "-"); + Name += it->first(); + Opts.Features.push_back(Name); + } Opts.NoCommon = NoCommon | LangOpts.CPlusPlus; @@ -1556,6 +1583,7 @@ static void SetUpBuildDumpLog(unsigned argc, char **argv, static ASTConsumer *CreateASTConsumer(const std::string& InFile, Diagnostic& Diag, FileManager& FileMgr, const LangOptions& LangOpts, + const llvm::StringMap<bool>& Features, Preprocessor *PP, PreprocessorFactory *PPF) { switch (ProgAction) { @@ -1598,7 +1626,7 @@ static ASTConsumer *CreateASTConsumer(const std::string& InFile, Act = Backend_EmitBC; CompileOptions Opts; - InitializeCompileOptions(Opts, LangOpts); + InitializeCompileOptions(Opts, LangOpts, Features); return CreateBackendConsumer(Act, Diag, LangOpts, Opts, InFile, OutputFile); } @@ -1620,7 +1648,8 @@ static ASTConsumer *CreateASTConsumer(const std::string& InFile, /// ProcessInputFile - Process a single input file with the specified state. /// static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, - const std::string &InFile, ProgActions PA) { + const std::string &InFile, ProgActions PA, + const llvm::StringMap<bool> &Features) { llvm::OwningPtr<ASTConsumer> Consumer; bool ClearSourceMgr = false; FixItRewriter *FixItRewrite = 0; @@ -1630,7 +1659,7 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, default: Consumer.reset(CreateASTConsumer(InFile, PP.getDiagnostics(), PP.getFileManager(), PP.getLangOptions(), - &PP, &PPF)); + Features, &PP, &PPF)); if (!Consumer) { fprintf(stderr, "Unexpected program action!\n"); @@ -1999,6 +2028,10 @@ int main(int argc, char **argv) { // Create a file manager object to provide access to and cache the filesystem. FileManager FileMgr; + // Compute the feature set, unfortunately this effects the language! + llvm::StringMap<bool> Features; + ComputeFeatureMap(Target.get(), Features); + for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) { const std::string &InFile = InputFilenames[i]; @@ -2016,7 +2049,7 @@ int main(int argc, char **argv) { InitializeBaseLanguage(); LangKind LK = GetLanguage(InFile); InitializeLangOptions(LangInfo, LK); - InitializeLanguageStandard(LangInfo, LK, Target.get()); + InitializeLanguageStandard(LangInfo, LK, Target.get(), Features); // Process the -I options and set them in the HeaderInfo. HeaderSearch HeaderInfo(FileMgr); @@ -2041,7 +2074,7 @@ int main(int argc, char **argv) { ((PathDiagnosticClient*)DiagClient.get())->SetPreprocessor(PP.get()); // Process the source file. - ProcessInputFile(*PP, PPFactory, InFile, ProgAction); + ProcessInputFile(*PP, PPFactory, InFile, ProgAction, Features); HeaderInfo.ClearFileInfo(); DiagClient->setLangOptions(0); |