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