path = llvm::sys::path;
70size_tmatchingPrefix(StringRef L, StringRef R) {
71 size_tLimit = std::min(L.size(), R.size());
72 for(
size_tI = 0; I < Limit; ++I)
80template<
boolPrefix>
struct Less{
81 booloperator()(StringRef Key, std::pair<StringRef, size_t>
Value)
const{
82StringRef
V= Prefix ?
Value.first.substr(0, Key.size()) :
Value.first;
85 booloperator()(std::pair<StringRef, size_t>
Value, StringRef Key)
const{
86StringRef
V= Prefix ?
Value.first.substr(0, Key.size()) :
Value.first;
107 casetypes::TY_CHeader:
110 casetypes::TY_ObjCHeader:
111 returntypes::TY_ObjC;
113 casetypes::TY_CXXHeader:
114 returntypes::TY_CXX;
115 casetypes::TY_ObjCXX:
116 casetypes::TY_ObjCXXHeader:
117 returntypes::TY_ObjCXX;
119 casetypes::TY_CUDA_DEVICE:
120 returntypes::TY_CUDA;
127structTransferableCommand {
131std::optional<types::ID>
Type;
137TransferableCommand(CompileCommand
C)
139std::vector<std::string> OldArgs = std::move(
Cmd.CommandLine);
140 Cmd.CommandLine.clear();
143llvm::opt::InputArgList ArgList;
146 for(
conststd::string &S : OldArgs)
147TmpArgv.push_back(S.c_str());
151ArgList = {TmpArgv.begin(), TmpArgv.end()};
159 if(!OldArgs.empty())
160 Cmd.CommandLine.emplace_back(OldArgs.front());
161 for(
unsignedPos = 1; Pos < OldArgs.size();) {
162 using namespacedriver::options;
164 const unsignedOldPos = Pos;
165std::unique_ptr<llvm::opt::Arg> Arg(OptTable.ParseOneArg(
167llvm::opt::Visibility(
ClangCLMode? CLOption : ClangOption)));
172 constllvm::opt::Option &Opt = Arg->getOption();
175 if(Opt.matches(OPT_INPUT) || Opt.matches(OPT_o) ||
177Opt.matches(OPT__SLASH_Fe) ||
178Opt.matches(OPT__SLASH_Fi) ||
179Opt.matches(OPT__SLASH_Fo))))
183 if(Opt.matches(OPT__DASH_DASH))
187 if(
const autoGivenType = tryParseTypeArg(*Arg)) {
193 if(
const autoGivenStd = tryParseStdArg(*Arg)) {
199 Cmd.CommandLine.insert(
Cmd.CommandLine.end(),
200OldArgs.data() + OldPos, OldArgs.data() + Pos);
214CompileCommand transferTo(StringRef
Filename) && {
215CompileCommand
Result= std::move(Cmd);
216 Result.Heuristic =
"inferred from "+
Result.Filename;
219 autoTargetType = guessType(
Filename, &TypeCertain);
221 if((!TargetType || !TypeCertain) && Type) {
229 constStringRef Flag = toCLFlag(TargetType);
231 Result.CommandLine.push_back(std::string(Flag));
233 Result.CommandLine.push_back(
"-x");
240 Result.CommandLine.emplace_back((
241llvm::Twine(ClangCLMode ?
"/std:":
"-std=") +
244 Result.CommandLine.push_back(
"--");
256 returntypes::TY_CXX;
258 returntypes::TY_ObjC;
260 returntypes::TY_ObjCXX;
267 staticStringRef toCLFlag(
types::IDType) {
270 casetypes::TY_CHeader:
273 casetypes::TY_CXXHeader:
281std::optional<types::ID> tryParseTypeArg(
constllvm::opt::Arg &Arg) {
282 constllvm::opt::Option &Opt = Arg.getOption();
283 using namespacedriver::options;
285 if(Opt.matches(OPT__SLASH_TC) || Opt.matches(OPT__SLASH_Tc))
287 if(Opt.matches(OPT__SLASH_TP) || Opt.matches(OPT__SLASH_Tp))
288 returntypes::TY_CXX;
290 if(Opt.matches(driver::options::OPT_x))
297std::optional<LangStandard::Kind> tryParseStdArg(
constllvm::opt::Arg &Arg) {
298 using namespacedriver::options;
299 if(Arg.getOption().matches(ClangCLMode ? OPT__SLASH_std : OPT_std_EQ))
318FileIndex(std::vector<std::string> Files)
319: OriginalPaths(
std::move(Files)), Strings(Arena) {
321llvm::sort(OriginalPaths);
322Paths.reserve(OriginalPaths.size());
323Types.reserve(OriginalPaths.size());
324Stems.reserve(OriginalPaths.size());
325 for(
size_tI = 0; I < OriginalPaths.size(); ++I) {
326StringRef
Path= Strings.save(StringRef(OriginalPaths[I]).lower());
328Paths.emplace_back(
Path, I);
329Types.push_back(foldType(guessType(OriginalPaths[I])));
330Stems.emplace_back(sys::path::stem(
Path), I);
331 autoDir = ++sys::path::rbegin(
Path), DirEnd = sys::path::rend(
Path);
332 for(
intJ = 0; J < DirectorySegmentsIndexed && Dir != DirEnd; ++J, ++Dir)
333 if(Dir->size() > ShortDirectorySegment)
334Components.emplace_back(*Dir, I);
338llvm::sort(Components);
341 boolempty()
const{
returnPaths.empty(); }
346StringRef chooseProxy(StringRef OriginalFilename,
348assert(!empty() &&
"need at least one candidate!");
349std::string
Filename= OriginalFilename.lower();
350 autoCandidates = scoreCandidates(
Filename);
351std::pair<size_t, int> Best =
352pickWinner(Candidates,
Filename, PreferLanguage);
356llvm::dbgs() <<
"interpolate: chose "<< OriginalPaths[Best.first]
357<<
" as proxy for "<< OriginalFilename <<
" preferring " 361<<
" score="<< Best.second <<
"\n");
362 returnOriginalPaths[Best.first];
366 usingSubstringAndIndex = std::pair<StringRef, size_t>;
370 constexpr static intDirectorySegmentsIndexed = 4;
371 constexpr static intDirectorySegmentsQueried = 2;
372 constexpr static intShortDirectorySegment = 1;
376DenseMap<size_t, int> scoreCandidates(StringRef
Filename)
const{
380StringRef Stem = sys::path::stem(
Filename);
382llvm::StringRef Prefix;
383 autoDir = ++sys::path::rbegin(
Filename),
384DirEnd = sys::path::rend(
Filename);
385 for(
intI = 0; I < DirectorySegmentsQueried && Dir != DirEnd; ++I, ++Dir) {
386 if(Dir->size() > ShortDirectorySegment)
387Dirs.push_back(*Dir);
388Prefix =
Filename.substr(0, Dir - DirEnd);
392DenseMap<size_t, int> Candidates;
394 for(
const auto&Entry : Range)
395Candidates[Entry.second] += Points;
399Award(1, indexLookup</*Prefix=*/true>(Stem, Stems));
400Award(1, indexLookup</*Prefix=*/false>(Stem, Stems));
403 for(StringRef Dir : Dirs)
404Award(1, indexLookup</*Prefix=*/false>(Dir, Components));
406 if(sys::path::root_directory(Prefix) != Prefix)
407Award(1, indexLookup</*Prefix=*/true>(Prefix, Paths));
413std::pair<size_t, int> pickWinner(
constDenseMap<size_t, int> &Candidates,
416 structScoredCandidate {
423ScoredCandidate Best = {
size_t(-1),
false, 0, 0};
424 for(
const auto&Candidate : Candidates) {
426S.Index = Candidate.first;
428PreferredLanguage == Types[S.Index];
429S.Points = Candidate.second;
430 if(!S.Preferred && Best.Preferred)
432 if(S.Preferred == Best.Preferred) {
433 if(S.Points < Best.Points)
435 if(S.Points == Best.Points) {
436S.PrefixLength = matchingPrefix(
Filename, Paths[S.Index].first);
437 if(S.PrefixLength < Best.PrefixLength)
440 if(S.PrefixLength == Best.PrefixLength)
441 if(S.Index > Best.Index)
447S.PrefixLength = matchingPrefix(
Filename, Paths[S.Index].first);
452 if(Best.Index ==
size_t(-1))
453 return{longestMatch(
Filename, Paths).second, 0};
454 return{Best.Index, Best.Points};
459 template<
boolPrefix>
463 auto Range= std::equal_range(Idx.data(), Idx.data() + Idx.size(), Key,
469SubstringAndIndex longestMatch(StringRef Key,
471assert(!Idx.empty());
473 autoIt = llvm::lower_bound(Idx, SubstringAndIndex{Key, 0});
474 if(It == Idx.begin())
479 size_tPrefix = matchingPrefix(Key, It->first);
480 size_tPrevPrefix = matchingPrefix(Key, (It - 1)->first);
481 returnPrefix > PrevPrefix ? *It : *--It;
485std::vector<std::string> OriginalPaths;
486BumpPtrAllocator Arena;
490std::vector<SubstringAndIndex> Paths;
493std::vector<types::ID> Types;
494std::vector<SubstringAndIndex> Stems;
495std::vector<SubstringAndIndex> Components;
501classInterpolatingCompilationDatabase :
publicCompilationDatabase {
503InterpolatingCompilationDatabase(std::unique_ptr<CompilationDatabase> Inner)
504: Inner(
std::move(Inner)), Index(this->Inner->getAllFiles()) {}
506std::vector<CompileCommand>
507getCompileCommands(StringRef
Filename)
const override{
508 autoKnown = Inner->getCompileCommands(
Filename);
509 if(Index.empty() || !Known.empty())
516Inner->getCompileCommands(Index.chooseProxy(
Filename, foldType(Lang)));
517 if(ProxyCommands.empty())
522std::vector<std::string> getAllFiles()
const override{
523 returnInner->getAllFiles();
526std::vector<CompileCommand> getAllCompileCommands()
const override{
527 returnInner->getAllCompileCommands();
531std::unique_ptr<CompilationDatabase> Inner;
537std::unique_ptr<CompilationDatabase>
539 returnstd::make_unique<InterpolatingCompilationDatabase>(std::move(Inner));
544 returnTransferableCommand(std::move(
Cmd)).transferTo(
Filename);
static std::string getName(const CallEvent &Call)
ID lookupTypeForTypeSpecifier(const char *Name)
lookupTypeForTypSpecifier - Lookup the type to use for a user specified type name.
bool onlyPrecompileType(ID Id)
onlyPrecompileType - Should this type only be precompiled.
const char * getTypeName(ID Id)
getTypeName - Return the name of the type for Id.
ID lookupHeaderTypeForSourceType(ID Id)
Lookup header file input type that corresponds to given source file type (used for clang-cl emulation...
ID lookupTypeForExtension(llvm::StringRef Ext)
lookupTypeForExtension - Lookup the type to use for the file extension Ext.
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
const llvm::opt::OptTable & getDriverOptTable()
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
The JSON file list parser is used to communicate input to InstallAPI.
Language
The language for the input, used to select and validate the language standard and possible actions.
@ C
Languages that the frontend can parse and compile.
@ Result
The result type of a method or function.
Diagnostic wrappers for TextAPI types for error reporting.
static const LangStandard & getLangStandardForKind(Kind K)
static Kind getLangKind(StringRef Name)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4