[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
//===--- CompileCommands.h - Manipulation of compile flags -------*- C++-*-===//
|
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2019-12-06 19:27:15 +08:00
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILECOMMANDS_H
|
|
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILECOMMANDS_H
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
|
2020-06-10 04:54:42 +08:00
|
|
|
#include "support/Threading.h"
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
#include "clang/Tooling/ArgumentsAdjusters.h"
|
2020-06-10 04:54:42 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
2021-07-26 02:38:00 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2020-07-15 17:03:11 +08:00
|
|
|
#include <deque>
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
|
|
|
|
|
|
|
// CommandMangler transforms compile commands from some external source
|
|
|
|
// for use in clangd. This means:
|
|
|
|
// - running the frontend only, stripping args regarding output files etc
|
|
|
|
// - forcing the use of clangd's builtin headers rather than clang's
|
|
|
|
// - resolving argv0 as cc1 expects
|
|
|
|
// - injecting -isysroot flags on mac as the system clang does
|
|
|
|
struct CommandMangler {
|
|
|
|
// Absolute path to clang.
|
|
|
|
llvm::Optional<std::string> ClangPath;
|
|
|
|
// Directory containing builtin headers.
|
|
|
|
llvm::Optional<std::string> ResourceDir;
|
|
|
|
// Root for searching for standard library (passed to -isysroot).
|
|
|
|
llvm::Optional<std::string> Sysroot;
|
|
|
|
|
|
|
|
// A command-mangler that doesn't know anything about the system.
|
|
|
|
// This is hermetic for unit-tests, but won't work well in production.
|
|
|
|
static CommandMangler forTests();
|
|
|
|
// Probe the system and build a command-mangler that knows the toolchain.
|
|
|
|
// - try to find clang on $PATH, otherwise fake a path near clangd
|
|
|
|
// - find the resource directory installed near clangd
|
|
|
|
// - on mac, find clang and isysroot by querying the `xcrun` launcher
|
|
|
|
static CommandMangler detect();
|
|
|
|
|
2021-07-26 02:38:00 +08:00
|
|
|
void adjust(std::vector<std::string> &Cmd, llvm::StringRef File) const;
|
2020-06-10 04:54:42 +08:00
|
|
|
explicit operator clang::tooling::ArgumentsAdjuster() &&;
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
CommandMangler() = default;
|
2020-06-10 04:54:42 +08:00
|
|
|
Memoize<llvm::StringMap<std::string>> ResolvedDrivers;
|
|
|
|
Memoize<llvm::StringMap<std::string>> ResolvedDriversNoFollow;
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
};
|
|
|
|
|
[clangd] Add library to semantically strip flags by name.
Summary:
This is designed for tweaking compile commands by specifying flags to add/remove
in a config file. Something like:
CompileFlags: { Remove: -fcolor-diagnostics }
Having users tweak raw argv (e.g. with a regex) is going to end in tears: bugs
around clang-cl, xclang, aliases, joined-vs-separate args etc are inevitable.
This isn't in tooling because of the performance choices: build a big table
up-front to make subsequent actions fast. Maybe it should be though.
Reviewers: adamcz, hokein
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D81958
2020-06-17 03:21:32 +08:00
|
|
|
// Removes args from a command-line in a semantically-aware way.
|
|
|
|
//
|
|
|
|
// Internally this builds a large (0.5MB) table of clang options on first use.
|
|
|
|
// Both strip() and process() are fairly cheap after that.
|
|
|
|
//
|
|
|
|
// FIXME: this reimplements much of OptTable, it might be nice to expose more.
|
|
|
|
// The table-building strategy may not make sense outside clangd.
|
|
|
|
class ArgStripper {
|
|
|
|
public:
|
2020-07-14 02:37:54 +08:00
|
|
|
ArgStripper() = default;
|
|
|
|
ArgStripper(ArgStripper &&) = default;
|
|
|
|
ArgStripper(const ArgStripper &) = delete;
|
|
|
|
ArgStripper &operator=(ArgStripper &&) = default;
|
|
|
|
ArgStripper &operator=(const ArgStripper &) = delete;
|
|
|
|
|
[clangd] Add library to semantically strip flags by name.
Summary:
This is designed for tweaking compile commands by specifying flags to add/remove
in a config file. Something like:
CompileFlags: { Remove: -fcolor-diagnostics }
Having users tweak raw argv (e.g. with a regex) is going to end in tears: bugs
around clang-cl, xclang, aliases, joined-vs-separate args etc are inevitable.
This isn't in tooling because of the performance choices: build a big table
up-front to make subsequent actions fast. Maybe it should be though.
Reviewers: adamcz, hokein
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D81958
2020-06-17 03:21:32 +08:00
|
|
|
// Adds the arg to the set which should be removed.
|
|
|
|
//
|
|
|
|
// Recognized clang flags are stripped semantically. When "-I" is stripped:
|
|
|
|
// - so is its value (either as -Ifoo or -I foo)
|
|
|
|
// - aliases like --include-directory=foo are also stripped
|
|
|
|
// - CL-style /Ifoo will be removed if the args indicate MS-compatible mode
|
|
|
|
// Compile args not recognized as flags are removed literally, except:
|
|
|
|
// - strip("ABC*") will remove any arg with an ABC prefix.
|
|
|
|
//
|
|
|
|
// In either case, the -Xclang prefix will be dropped if present.
|
|
|
|
void strip(llvm::StringRef Arg);
|
|
|
|
// Remove the targets from a compile command, in-place.
|
|
|
|
void process(std::vector<std::string> &Args) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Deletion rules, to be checked for each arg.
|
|
|
|
struct Rule {
|
|
|
|
llvm::StringRef Text; // Rule applies only if arg begins with Text.
|
|
|
|
unsigned char Modes = 0; // Rule applies only in specified driver modes.
|
|
|
|
uint16_t Priority = 0; // Lower is better.
|
|
|
|
uint16_t ExactArgs = 0; // Num args consumed when Arg == Text.
|
|
|
|
uint16_t PrefixArgs = 0; // Num args consumed when Arg starts with Text.
|
|
|
|
};
|
|
|
|
static llvm::ArrayRef<Rule> rulesFor(llvm::StringRef Arg);
|
|
|
|
const Rule *matchingRule(llvm::StringRef Arg, unsigned Mode,
|
|
|
|
unsigned &ArgCount) const;
|
2020-12-10 20:36:35 +08:00
|
|
|
llvm::SmallVector<Rule> Rules;
|
2020-07-15 17:03:11 +08:00
|
|
|
std::deque<std::string> Storage; // Store strings not found in option table.
|
[clangd] Add library to semantically strip flags by name.
Summary:
This is designed for tweaking compile commands by specifying flags to add/remove
in a config file. Something like:
CompileFlags: { Remove: -fcolor-diagnostics }
Having users tweak raw argv (e.g. with a regex) is going to end in tears: bugs
around clang-cl, xclang, aliases, joined-vs-separate args etc are inevitable.
This isn't in tooling because of the performance choices: build a big table
up-front to make subsequent actions fast. Maybe it should be though.
Reviewers: adamcz, hokein
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D81958
2020-06-17 03:21:32 +08:00
|
|
|
};
|
|
|
|
|
2021-01-31 23:37:42 +08:00
|
|
|
// Renders an argv list, with arguments separated by spaces.
|
|
|
|
// Where needed, arguments are "quoted" and escaped.
|
|
|
|
std::string printArgv(llvm::ArrayRef<llvm::StringRef> Args);
|
|
|
|
std::string printArgv(llvm::ArrayRef<std::string> Args);
|
|
|
|
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|
2019-12-06 19:27:15 +08:00
|
|
|
|
|
|
|
#endif
|