;
27using namespacedriver;
28using namespacellvm::sys;
31StringRef IncludeSuffix,
const flags_list&Flags,
32StringRef ExclusiveGroup, std::optional<StringRef> Error)
33: GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix),
34Flags(Flags), ExclusiveGroup(ExclusiveGroup), Error(Error) {
35assert(GCCSuffix.empty() ||
36(StringRef(GCCSuffix).front() ==
'/'&& GCCSuffix.size() > 1));
37assert(OSSuffix.empty() ||
38(StringRef(OSSuffix).front() ==
'/'&& OSSuffix.size() > 1));
39assert(IncludeSuffix.empty() ||
40(StringRef(IncludeSuffix).front() ==
'/'&& IncludeSuffix.size() > 1));
48 if(GCCSuffix.empty())
51OS << StringRef(GCCSuffix).drop_front();
54 for(StringRef Flag : Flags) {
55 if(Flag.front() ==
'-')
56OS <<
"@"<< Flag.substr(1);
63llvm::StringSet<> MyFlags;
64 for(
const auto&Flag : Flags)
67 for(
const auto&Flag :
Other.Flags)
68 if(!MyFlags.contains(Flag))
89llvm::erase_if(Multilibs, F);
98 structEditDistanceInfo {
100 unsignedEditDistance;
102 const unsignedMaxEditDistance = 5;
104 for(StringRef Unclaimed : UnclaimedCustomFlagValues) {
105std::optional<EditDistanceInfo> BestCandidate;
106 for(
const auto&
Decl: CustomFlagDecls) {
107 for(
const auto&
Value:
Decl.ValueList) {
108 conststd::string &FlagValueName =
Value.Name;
109 unsignedEditDistance =
110Unclaimed.edit_distance(FlagValueName,
true,
112 if(!BestCandidate || (EditDistance <= MaxEditDistance &&
113EditDistance < BestCandidate->EditDistance)) {
114BestCandidate = {FlagValueName, EditDistance};
119 D.Diag(clang::diag::err_drv_unsupported_opt)
122 D.Diag(clang::diag::err_drv_unsupported_opt_with_suggestion)
135 template<
typenameIt>
137 for(
autoDeclIt = FlagDeclsBegin; DeclIt != FlagDeclsEnd; ++DeclIt) {
139 for(
const auto&
Value:
Decl.ValueList)
145 auto Iter= llvm::find_if(
146Mapping, [&](
const auto&Pair) {
returnPair.first == Key; });
147 return Iter!= Mapping.end() ?
Iter->second :
nullptr;
152std::pair<Multilib::flags_list, SmallVector<StringRef>>
166CustomFlagDecls.begin(), CustomFlagDecls.end());
168 for(StringRef Flag : Flags) {
170 Result.push_back(Flag.str());
176ValueNameToValueDetail.get(CustomFlagValueStr);
178ClaimedCustomFlagValues.push_back(Detail);
180UnclaimedCustomFlagValueStrs.push_back(CustomFlagValueStr);
191 for(
auto*CustomFlagValue : llvm::reverse(ClaimedCustomFlagValues)) {
192 if(!TriggeredCustomFlagDecls.insert(CustomFlagValue->Decl).second)
195 if(CustomFlagValue->MacroDefines)
196MacroDefines.append(CustomFlagValue->MacroDefines->begin(),
197CustomFlagValue->MacroDefines->end());
201 for(
const auto&
Decl: CustomFlagDecls) {
202 if(TriggeredCustomFlagDecls.contains(&
Decl))
205 Decl.ValueList[*
Decl.DefaultValueIdx];
208MacroDefines.append(CustomFlagValue.
MacroDefines->begin(),
215 return{
Result, MacroDefines};
223llvm::StringSet<> FlagSet(
expandFlags(FlagsWithCustom));
225 boolAnyErrors =
false;
231 if(CustomFlagMacroDefines)
232*CustomFlagMacroDefines = std::move(CFMacroDefines);
235llvm::DenseSet<StringRef> ExclusiveGroupsSelected;
236 for(
const Multilib&M : llvm::reverse(Multilibs)) {
238 if(!llvm::all_of(M.flags(), [&FlagSet](
conststd::string &F) {
239return FlagSet.contains(F);
243 conststd::string &group = M.exclusiveGroup();
244 if(!group.empty()) {
251 auto[It, Inserted] = ExclusiveGroupsSelected.insert(group);
263Selected.push_back(M);
268std::reverse(Selected.begin(), Selected.end());
270 return!AnyErrors && !Selected.empty();
275llvm::StringSet<>
Result;
276 for(
const auto&F : InFlags)
279std::string RegexString(M.Match);
282 if(!StringRef(M.Match).starts_with(
"^"))
283RegexString.insert(RegexString.begin(),
'^');
284 if(!StringRef(M.Match).ends_with(
"$"))
285RegexString.push_back(
'$');
287 constllvm::Regex Regex(RegexString);
288assert(Regex.isValid());
289 if(llvm::any_of(InFlags,
290[&Regex](StringRef F) {
returnRegex.match(F); })) {
291 Result.insert(M.Flags.begin(), M.Flags.end());
300static constVersionTuple MultilibVersionCurrent(1, 0);
302structMultilibSerialization {
305std::vector<std::string> Flags;
309enum classMultilibGroupType {
331structMultilibGroupSerialization {
333MultilibGroupType
Type;
336structMultilibSetSerialization {
337llvm::VersionTuple MultilibVersion;
346LLVM_YAML_IS_SEQUENCE_VECTOR(MultilibSerialization)
347LLVM_YAML_IS_SEQUENCE_VECTOR(MultilibGroupSerialization)
352template <> struct
llvm::yaml::MappingTraits<MultilibSerialization> {
353 static void mapping(llvm::yaml::IO &io, MultilibSerialization &
V) {
354io.mapOptional(
"Dir",
V.Dir);
355io.mapOptional(
"Error",
V.Error);
356io.mapRequired(
"Flags",
V.Flags);
357io.mapOptional(
"Group",
V.Group);
359 staticstd::string
validate(IO &io, MultilibSerialization &
V) {
360 if(
V.Dir.empty() &&
V.Error.empty())
361 return "one of the 'Dir' and 'Error' keys must be specified";
362 if(!
V.Dir.empty() && !
V.Error.empty())
363 return "the 'Dir' and 'Error' keys may not both be specified";
364 if(StringRef(
V.Dir).starts_with(
"/"))
365 return "paths must be relative but \""+
V.Dir +
"\" starts with \"/\"";
366 returnstd::string{};
370template<>
structllvm::yaml::ScalarEnumerationTraits<MultilibGroupType> {
372io.enumCase(Val,
"Exclusive", MultilibGroupType::Exclusive);
376template<>
structllvm::yaml::MappingTraits<MultilibGroupSerialization> {
377 static void mapping(llvm::yaml::IO &io, MultilibGroupSerialization &
V) {
378io.mapRequired(
"Name",
V.Name);
379io.mapRequired(
"Type",
V.Type);
383template<>
structllvm::yaml::MappingTraits<
MultilibSet::FlagMatcher> {
385io.mapRequired(
"Match", M.
Match);
386io.mapRequired(
"Flags", M.
Flags);
389llvm::Regex Regex(M.
Match);
390std::string RegexError;
391 if(!Regex.isValid(RegexError))
393 if(M.
Flags.empty())
394 return "value required for 'Flags'";
395 returnstd::string{};
400structllvm::yaml::MappingContextTraits<custom_flag::ValueDetail,
401llvm::SmallSet<std::string, 32>> {
403llvm::SmallSet<std::string, 32> &) {
404io.mapRequired(
"Name",
V.Name);
405io.mapOptional(
"MacroDefines",
V.MacroDefines);
408llvm::SmallSet<std::string, 32> &NameSet) {
409 if(
V.Name.empty())
410 return "custom flag value requires a name";
411 if(!NameSet.insert(
V.Name).second)
412 return "duplicate custom flag value name: \""+
V.Name +
"\"";
418structllvm::yaml::MappingContextTraits<custom_flag::
Declaration,
419llvm::SmallSet<std::string, 32>> {
421llvm::SmallSet<std::string, 32> &NameSet) {
422io.mapRequired(
"Name",
V.Name);
423io.mapRequired(
"Values",
V.ValueList, NameSet);
424std::string DefaultValueName;
425io.mapRequired(
"Default", DefaultValueName);
427 for(
auto[Idx,
Value] : llvm::enumerate(
V.ValueList)) {
429 if(
Value.Name == DefaultValueName) {
430assert(!
V.DefaultValueIdx);
431 V.DefaultValueIdx = Idx;
436llvm::SmallSet<std::string, 32> &) {
437 if(
V.Name.empty())
438 return "custom flag requires a name";
439 if(
V.ValueList.empty())
440 return "custom flag must have at least one value";
441 if(!
V.DefaultValueIdx)
442 return "custom flag must have a default value";
447template<>
structllvm::yaml::MappingTraits<MultilibSetSerialization> {
448 static void mapping(llvm::yaml::IO &io, MultilibSetSerialization &M) {
449io.mapRequired(
"MultilibVersion", M.MultilibVersion);
450io.mapRequired(
"Variants", M.Multilibs);
451io.mapOptional(
"Groups", M.Groups);
452llvm::SmallSet<std::string, 32> NameSet;
453io.mapOptionalWithContext(
"Flags", M.CustomFlagDeclarations, NameSet);
454io.mapOptional(
"Mappings", M.FlagMatchers);
456 staticstd::string
validate(IO &io, MultilibSetSerialization &M) {
457 if(M.MultilibVersion.empty())
458 return "missing required key 'MultilibVersion'";
459 if(M.MultilibVersion.getMajor() != MultilibVersionCurrent.getMajor())
460 return "multilib version "+ M.MultilibVersion.getAsString() +
462 if(M.MultilibVersion.getMinor() > MultilibVersionCurrent.getMinor())
463 return "multilib version "+ M.MultilibVersion.getAsString() +
465 for(
constMultilibSerialization &Lib : M.Multilibs) {
466 if(!Lib.Group.empty()) {
468 for(
constMultilibGroupSerialization &Group : M.Groups)
469 if(Group.Name == Lib.Group) {
474 return "multilib \""+ Lib.Dir +
475 "\" specifies undefined group name \""+ Lib.Group +
"\"";
478 returnstd::string{};
482llvm::ErrorOr<MultilibSet>
484llvm::SourceMgr::DiagHandlerTy DiagHandler,
485 void*DiagHandlerCtxt) {
486MultilibSetSerialization MS;
487llvm::yaml::Input YamlInput(Input,
nullptr, DiagHandler, DiagHandlerCtxt);
489 if(YamlInput.error())
490 returnYamlInput.error();
493Multilibs.reserve(MS.Multilibs.size());
494 for(
const auto&M : MS.Multilibs) {
495 if(!M.Error.empty()) {
496Multilibs.emplace_back(
"",
"",
"", M.Flags, M.Group, M.Error);
505Multilibs.emplace_back(Dir, Dir, Dir, M.Flags, M.Group);
509 return MultilibSet(std::move(Multilibs), std::move(MS.FlagMatchers),
510std::move(MS.CustomFlagDeclarations));
514 print(llvm::errs());
518 for(
const auto&M : *
this)
530DefaultValueIdx(
Other.DefaultValueIdx) {
537DefaultValueIdx(
std::move(
Other.DefaultValueIdx)) {
543 if(
this== &
Other)
554 if(
this== &
Other)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static void DiagnoseUnclaimedMultilibCustomFlags(const Driver &D, const SmallVector< StringRef > &UnclaimedCustomFlagValues, const SmallVector< custom_flag::Declaration > &CustomFlagDecls)
Decl - This represents one declaration (or definition), e.g.
The base class of the type hierarchy.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
See also MultilibSetBuilder for combining multilibs into a set.
bool select(const Driver &D, const Multilib::flags_list &Flags, llvm::SmallVectorImpl< Multilib > &, llvm::SmallVector< StringRef > *=nullptr) const
Select compatible variants,.
LLVM_DUMP_METHOD void dump() const
llvm::function_ref< bool(const Multilib &)> FilterCallback
static llvm::ErrorOr< MultilibSet > parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy=nullptr, void *DiagHandlerCtxt=nullptr)
void print(raw_ostream &OS) const
MultilibSet & FilterOut(FilterCallback F)
Filter out some subset of the Multilibs using a user defined callback.
std::vector< Multilib > multilib_list
llvm::StringSet expandFlags(const Multilib::flags_list &) const
Get the given flags plus flags found by matching them against the FlagMatchers and choosing the Flags...
void push_back(const Multilib &M)
Add a completed Multilib to the set.
std::pair< Multilib::flags_list, SmallVector< StringRef > > processCustomFlags(const Driver &D, const Multilib::flags_list &Flags) const
Process custom flags from Flags and returns an expanded flags list and a list of macro defines.
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
const std::string & osSuffix() const
Get the detected os path suffix for the multi-arch target variant.
std::vector< std::string > flags_list
Multilib(StringRef GCCSuffix={}, StringRef OSSuffix={}, StringRef IncludeSuffix={}, const flags_list &Flags=flags_list(), StringRef ExclusiveGroup={}, std::optional< StringRef > Error=std::nullopt)
GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the sysroot string so they must eith...
const std::string & includeSuffix() const
Get the include directory suffix.
LLVM_DUMP_METHOD void dump() const
void print(raw_ostream &OS) const
print summary of the Multilib
bool operator==(const Multilib &Other) const
ValueNameToDetailMap(It FlagDeclsBegin, It FlagDeclsEnd)
const ValueDetail * get(StringRef Key) const
static constexpr StringRef Prefix
raw_ostream & operator<<(raw_ostream &OS, const Multilib &M)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
Uses regular expressions to simplify flags used for multilib selection.
std::vector< std::string > Flags
Declaration & operator=(const Declaration &)
std::optional< size_t > DefaultValueIdx
std::optional< SmallVector< std::string > > MacroDefines
static std::string validate(IO &io, custom_flag::Declaration &V, llvm::SmallSet< std::string, 32 > &)
static void mapping(llvm::yaml::IO &io, custom_flag::Declaration &V, llvm::SmallSet< std::string, 32 > &NameSet)
static void mapping(llvm::yaml::IO &io, custom_flag::ValueDetail &V, llvm::SmallSet< std::string, 32 > &)
static std::string validate(IO &io, custom_flag::ValueDetail &V, llvm::SmallSet< std::string, 32 > &NameSet)
static void mapping(llvm::yaml::IO &io, MultilibGroupSerialization &V)
static void mapping(llvm::yaml::IO &io, MultilibSerialization &V)
static std::string validate(IO &io, MultilibSerialization &V)
static void mapping(llvm::yaml::IO &io, MultilibSetSerialization &M)
static std::string validate(IO &io, MultilibSetSerialization &M)
static std::string validate(IO &io, MultilibSet::FlagMatcher &M)
static void mapping(llvm::yaml::IO &io, MultilibSet::FlagMatcher &M)
static void enumeration(IO &io, MultilibGroupType &Val)
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