mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-23 19:59:48 +00:00
4b3deaca42
With this, `clang-cl /source-charset:utf-16 test.cc` now prints `invalid value 'utf-16' in '/source-charset:utf-16'` instead of `invalid value 'utf-16' in '-finput-charset=utf-16'` before, and several other clang-cl flags produce much less confusing output as well. Fixes PR29106. Since an arg and its alias can have different arg types (joined vs not) and different values (because of AliasArgs<>), I chose to give the Alias its own Arg object. For convenience, I just store the alias directly in the unaliased arg – there aren't many arg objects at runtime, so that seems ok. Finally, I changed Arg::getAsString() to use the alias's representation if it's present – that function was already documented as being the suitable function for diagnostics, and most callers already used it for diagnostics. Implementation-wise, Arg::accept() previously used to parse things as the unaliased option. The core of that switch is now extracted into a new function acceptInternal() which parses as the _aliased_ option, and the previously-intermingled unaliasing is now done as an explicit step afterwards. (This also changes one place in lld that didn't use getAsString() for diagnostics, so that that one place now also prints the flag as the user wrote it, not as it looks after it went through unaliasing.) Differential Revision: https://reviews.llvm.org/D64253 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365413 91177308-0d34-0410-b5e6-96231b3b80d8
126 lines
3.3 KiB
C++
126 lines
3.3 KiB
C++
//===- Arg.cpp - Argument Implementations ---------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/SmallString.h"
|
|
#include "llvm/Config/llvm-config.h"
|
|
#include "llvm/Option/Arg.h"
|
|
#include "llvm/Option/ArgList.h"
|
|
#include "llvm/Option/Option.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::opt;
|
|
|
|
Arg::Arg(const Option Opt, StringRef S, unsigned Index, const Arg *BaseArg)
|
|
: Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false),
|
|
OwnsValues(false) {}
|
|
|
|
Arg::Arg(const Option Opt, StringRef S, unsigned Index, const char *Value0,
|
|
const Arg *BaseArg)
|
|
: Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false),
|
|
OwnsValues(false) {
|
|
Values.push_back(Value0);
|
|
}
|
|
|
|
Arg::Arg(const Option Opt, StringRef S, unsigned Index, const char *Value0,
|
|
const char *Value1, const Arg *BaseArg)
|
|
: Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false),
|
|
OwnsValues(false) {
|
|
Values.push_back(Value0);
|
|
Values.push_back(Value1);
|
|
}
|
|
|
|
Arg::~Arg() {
|
|
if (OwnsValues) {
|
|
for (unsigned i = 0, e = Values.size(); i != e; ++i)
|
|
delete[] Values[i];
|
|
}
|
|
}
|
|
|
|
void Arg::print(raw_ostream& O) const {
|
|
O << "<";
|
|
|
|
O << " Opt:";
|
|
Opt.print(O);
|
|
|
|
O << " Index:" << Index;
|
|
|
|
O << " Values: [";
|
|
for (unsigned i = 0, e = Values.size(); i != e; ++i) {
|
|
if (i) O << ", ";
|
|
O << "'" << Values[i] << "'";
|
|
}
|
|
|
|
O << "]>\n";
|
|
}
|
|
|
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
|
LLVM_DUMP_METHOD void Arg::dump() const { print(dbgs()); }
|
|
#endif
|
|
|
|
std::string Arg::getAsString(const ArgList &Args) const {
|
|
if (Alias)
|
|
return Alias->getAsString(Args);
|
|
|
|
SmallString<256> Res;
|
|
raw_svector_ostream OS(Res);
|
|
|
|
ArgStringList ASL;
|
|
render(Args, ASL);
|
|
for (ArgStringList::iterator
|
|
it = ASL.begin(), ie = ASL.end(); it != ie; ++it) {
|
|
if (it != ASL.begin())
|
|
OS << ' ';
|
|
OS << *it;
|
|
}
|
|
|
|
return OS.str();
|
|
}
|
|
|
|
void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const {
|
|
if (!getOption().hasNoOptAsInput()) {
|
|
render(Args, Output);
|
|
return;
|
|
}
|
|
|
|
Output.append(Values.begin(), Values.end());
|
|
}
|
|
|
|
void Arg::render(const ArgList &Args, ArgStringList &Output) const {
|
|
switch (getOption().getRenderStyle()) {
|
|
case Option::RenderValuesStyle:
|
|
Output.append(Values.begin(), Values.end());
|
|
break;
|
|
|
|
case Option::RenderCommaJoinedStyle: {
|
|
SmallString<256> Res;
|
|
raw_svector_ostream OS(Res);
|
|
OS << getSpelling();
|
|
for (unsigned i = 0, e = getNumValues(); i != e; ++i) {
|
|
if (i) OS << ',';
|
|
OS << getValue(i);
|
|
}
|
|
Output.push_back(Args.MakeArgString(OS.str()));
|
|
break;
|
|
}
|
|
|
|
case Option::RenderJoinedStyle:
|
|
Output.push_back(Args.GetOrMakeJoinedArgString(
|
|
getIndex(), getSpelling(), getValue(0)));
|
|
Output.append(Values.begin() + 1, Values.end());
|
|
break;
|
|
|
|
case Option::RenderSeparateStyle:
|
|
Output.push_back(Args.MakeArgString(getSpelling()));
|
|
Output.append(Values.begin(), Values.end());
|
|
break;
|
|
}
|
|
}
|