Hans Wennborg <[email protected]> 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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
