r220052 - Driver: support detecting driver mode when clang has a version suffix without dash (PR21094)
Justin Bogner
mail at justinbogner.com
Fri Oct 17 13:46:11 PDT 2014
Hans Wennborg <hans at hanshq.net> writes:
> Author: hans
> Date: Fri Oct 17 12:07:59 2014
> New Revision: 220052
>
> URL: http://llvm.org/viewvc/llvm-project?rev=220052&view=rev
> Log:
> Driver: support detecting driver mode when clang has a version suffix
> without dash (PR21094)
>
> Clang would previously not get into C++ mode when invoked as 'clang++3.6'
> (though clang++-3.6 would work).
>
> I found the previous loop logic in this function confusing; hopefully this
> makes it a little clearer.
Looks like the new tests here are failing on darwin:
http://lab.llvm.org:8013/builders/clang-x86_64-darwin11-nobootstrap-RAincremental/builds/5667
Can you take a look?
> Differential Revision: http://reviews.llvm.org/D5833
>
> Added:
> cfe/trunk/test/Driver/parse-progname.c
> Modified:
> cfe/trunk/tools/driver/driver.cpp
>
> Added: cfe/trunk/test/Driver/parse-progname.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/parse-progname.c?rev=220052&view=auto
> ==============================================================================
> --- cfe/trunk/test/Driver/parse-progname.c (added)
> +++ cfe/trunk/test/Driver/parse-progname.c Fri Oct 17 12:07:59 2014
> @@ -0,0 +1,56 @@
> +// REQUIRES: shell, arm-registered-target
> +
> +
> +
> +// RUN: ln -fs %clang %T/clang++
> +// RUN: ln -fs %clang %T/clang++3.5.0
> +// RUN: ln -fs %clang %T/clang++-3.5
> +// RUN: ln -fs %clang %T/clang++-tot
> +// RUN: ln -fs %clang %T/clang-c++
> +// RUN: ln -fs %clang %T/clang-g++
> +// RUN: ln -fs %clang %T/c++
> +// RUN: ln -fs %clang %T/foo-clang++
> +// RUN: ln -fs %clang %T/foo-clang++-3.5
> +// RUN: ln -fs %clang %T/foo-clang++3.5
> +// RUN: %T/clang++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/clang++3.5.0 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/clang++-3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/clang++-tot -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/clang-c++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/clang-g++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/c++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/foo-clang++ -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/foo-clang++-3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// RUN: %T/foo-clang++3.5 -### %s 2>&1 | FileCheck -check-prefix=CXXMODE %s
> +// CXXMODE: "-x" "c++"
> +
> +
> +// RUN: ln -fs %clang %T/clang-cl
> +// RUN: ln -fs %clang %T/cl
> +// RUN: ln -fs %clang %T/cl.exe
> +// RUN: ln -fs %clang %T/clang-cl3.5
> +// RUN: ln -fs %clang %T/clang-cl-3.5
> +// RUN: %T/clang-cl -### %s 2>&1 | FileCheck -check-prefix=CLMODE %s
> +// RUN: %T/cl -### %s 2>&1 | FileCheck -check-prefix=CLMODE %s
> +// RUN: %T/cl.exe -### %s 2>&1 | FileCheck -check-prefix=CLMODE %s
> +// RUN: %T/clang-cl3.5 -### %s 2>&1 | FileCheck -check-prefix=CLMODE %s
> +// RUN: %T/clang-cl-3.5 -### %s 2>&1 | FileCheck -check-prefix=CLMODE %s
> +// CLMODE: "-fdiagnostics-format" "msvc"
> +
> +
> +// RUN: ln -fs %clang %T/clang-cpp
> +// RUN: ln -fs %clang %T/cpp
> +// RUN: %T/clang-cpp -### %s 2>&1 | FileCheck -check-prefix=CPPMODE %s
> +// RUN: %T/cpp -### %s 2>&1 | FileCheck -check-prefix=CPPMODE %s
> +// CPPMODE: "-E"
> +
> +
> +// RUN: ln -fs %clang %T/cl-clang
> +// RUN: %T/cl-clang -### %s 2>&1 | FileCheck -check-prefix=CMODE %s
> +// CMODE: "-x" "c"
> +// CMODE-NOT: "-fdiagnostics-format" "msvc"
> +
> +
> +// RUN: ln -fs %clang %T/arm-linux-gnueabi-clang
> +// RUN: %T/arm-linux-gnueabi-clang -### %s 2>&1 | FileCheck -check-prefix=TARGET %s
> +// TARGET: Target: arm--linux-gnueabi
>
> Modified: cfe/trunk/tools/driver/driver.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/driver.cpp?rev=220052&r1=220051&r2=220052&view=diff
> ==============================================================================
> --- cfe/trunk/tools/driver/driver.cpp (original)
> +++ cfe/trunk/tools/driver/driver.cpp Fri Oct 17 12:07:59 2014
> @@ -198,88 +198,93 @@ extern int cc1_main(ArrayRef<const char
> extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
> void *MainAddr);
>
> -static void ParseProgName(SmallVectorImpl<const char *> &ArgVector,
> - std::set<std::string> &SavedStrings,
> - Driver &TheDriver)
> -{
> - // Try to infer frontend type and default target from the program name.
> -
> - // suffixes[] contains the list of known driver suffixes.
> - // Suffixes are compared against the program name in order.
> - // If there is a match, the frontend type is updated as necessary (CPP/C++).
> - // If there is no match, a second round is done after stripping the last
> - // hyphen and everything following it. This allows using something like
> - // "clang++-2.9".
> -
> - // If there is a match in either the first or second round,
> - // the function tries to identify a target as prefix. E.g.
> - // "x86_64-linux-clang" as interpreted as suffix "clang" with
> - // target prefix "x86_64-linux". If such a target prefix is found,
> - // is gets added via -target as implicit first argument.
> - static const struct {
> - const char *Suffix;
> - const char *ModeFlag;
> - } suffixes [] = {
> - { "clang", nullptr },
> - { "clang++", "--driver-mode=g++" },
> - { "clang-c++", "--driver-mode=g++" },
> - { "clang-cc", nullptr },
> - { "clang-cpp", "--driver-mode=cpp" },
> - { "clang-g++", "--driver-mode=g++" },
> - { "clang-gcc", nullptr },
> - { "clang-cl", "--driver-mode=cl" },
> - { "cc", nullptr },
> - { "cpp", "--driver-mode=cpp" },
> - { "cl" , "--driver-mode=cl" },
> - { "++", "--driver-mode=g++" },
> +struct DriverSuffix {
> + const char *Suffix;
> + const char *ModeFlag;
> +};
> +
> +static const DriverSuffix *FindDriverSuffix(StringRef ProgName) {
> + // A list of known driver suffixes. Suffixes are compared against the
> + // program name in order. If there is a match, the frontend type if updated as
> + // necessary by applying the ModeFlag.
> + static const DriverSuffix DriverSuffixes[] = {
> + {"clang", nullptr},
> + {"clang++", "--driver-mode=g++"},
> + {"clang-c++", "--driver-mode=g++"},
> + {"clang-cc", nullptr},
> + {"clang-cpp", "--driver-mode=cpp"},
> + {"clang-g++", "--driver-mode=g++"},
> + {"clang-gcc", nullptr},
> + {"clang-cl", "--driver-mode=cl"},
> + {"cc", nullptr},
> + {"cpp", "--driver-mode=cpp"},
> + {"cl", "--driver-mode=cl"},
> + {"++", "--driver-mode=g++"},
> };
> - std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
> +
> + for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i)
> + if (ProgName.endswith(DriverSuffixes[i].Suffix))
> + return &DriverSuffixes[i];
> + return nullptr;
> +}
> +
> +static void ParseProgName(SmallVectorImpl<const char *> &ArgVector,
> + std::set<std::string> &SavedStrings) {
> + // Try to infer frontend type and default target from the program name by
> + // comparing it against DriverSuffixes in order.
> +
> + // If there is a match, the function tries to identify a target as prefix.
> + // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
> + // prefix "x86_64-linux". If such a target prefix is found, is gets added via
> + // -target as implicit first argument.
> +
> + std::string ProgName =llvm::sys::path::stem(ArgVector[0]);
> #ifdef LLVM_ON_WIN32
> // Transform to lowercase for case insensitive file systems.
> - std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
> - toLowercase);
> + ProgName = StringRef(ProgName).lower();
> #endif
> - StringRef ProgNameRef(ProgName);
> - StringRef Prefix;
>
> - for (int Components = 2; Components; --Components) {
> - auto I = std::find_if(std::begin(suffixes), std::end(suffixes),
> - [&](decltype(suffixes[0]) &suffix) {
> - return ProgNameRef.endswith(suffix.Suffix);
> - });
> -
> - if (I != std::end(suffixes)) {
> - if (I->ModeFlag) {
> - auto it = ArgVector.begin();
> - if (it != ArgVector.end())
> - ++it;
> - ArgVector.insert(it, I->ModeFlag);
> - }
> - StringRef::size_type LastComponent = ProgNameRef.rfind('-',
> - ProgNameRef.size() - strlen(I->Suffix));
> - if (LastComponent != StringRef::npos)
> - Prefix = ProgNameRef.slice(0, LastComponent);
> - break;
> - }
> + StringRef ProgNameRef = ProgName;
> + const DriverSuffix *DS = FindDriverSuffix(ProgNameRef);
>
> - StringRef::size_type LastComponent = ProgNameRef.rfind('-');
> - if (LastComponent == StringRef::npos)
> - break;
> - ProgNameRef = ProgNameRef.slice(0, LastComponent);
> + if (!DS) {
> + // Try again after stripping any trailing version number:
> + // clang++3.5 -> clang++
> + ProgNameRef = ProgNameRef.rtrim("0123456789.");
> + DS = FindDriverSuffix(ProgNameRef);
> + }
> +
> + if (!DS) {
> + // Try again after stripping trailing -component.
> + // clang++-tot -> clang++
> + ProgNameRef = ProgNameRef.slice(0, ProgNameRef.rfind('-'));
> + DS = FindDriverSuffix(ProgNameRef);
> }
>
> - if (Prefix.empty())
> - return;
> + if (DS) {
> + if (const char *Flag = DS->ModeFlag) {
> + // Add Flag to the arguments.
> + auto it = ArgVector.begin();
> + if (it != ArgVector.end())
> + ++it;
> + ArgVector.insert(it, Flag);
> + }
> +
> + StringRef::size_type LastComponent = ProgNameRef.rfind(
> + '-', ProgNameRef.size() - strlen(DS->Suffix));
> + if (LastComponent == StringRef::npos)
> + return;
>
> - std::string IgnoredError;
> - if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
> - auto it = ArgVector.begin();
> - if (it != ArgVector.end())
> - ++it;
> - const char* Strings[] =
> - { GetStableCStr(SavedStrings, std::string("-target")),
> - GetStableCStr(SavedStrings, Prefix) };
> - ArgVector.insert(it, std::begin(Strings), std::end(Strings));
> + // Infer target from the prefix.
> + StringRef Prefix = ProgNameRef.slice(0, LastComponent);
> + std::string IgnoredError;
> + if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
> + auto it = ArgVector.begin();
> + if (it != ArgVector.end())
> + ++it;
> + const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) };
> + ArgVector.insert(it, std::begin(arr), std::end(arr));
> + }
> }
> }
>
> @@ -446,7 +451,7 @@ int main(int argc_, const char **argv_)
> SetInstallDir(argv, TheDriver);
>
> llvm::InitializeAllTargets();
> - ParseProgName(argv, SavedStrings, TheDriver);
> + ParseProgName(argv, SavedStrings);
>
> SetBackdoorDriverOutputsFromEnvVars(TheDriver);
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list