Driver: Handle "linker input" arguments.

- Make InputInfo a variant of filename, pipe, input argument,
   nothing.

 - Leave a FIXME in InputInfo that this should be revisited.

llvm-svn: 67292
This commit is contained in:
Daniel Dunbar 2009-03-19 07:29:38 +00:00
parent 0e227785cb
commit 5cdf3e0fb9
3 changed files with 69 additions and 31 deletions

View file

@ -697,12 +697,15 @@ void Driver::BuildJobsForAction(Compilation &C,
UsePipes = false;
if (const InputAction *IA = dyn_cast<InputAction>(A)) {
// FIXME: This is broken, linker inputs won't work here.
assert(isa<PositionalArg>(IA->getInputArg()) && "FIXME: Linker inputs");
IA->getInputArg().claim();
const char *Name = IA->getInputArg().getValue(C.getArgs());
Result = InputInfo(Name, A->getType(), Name);
// FIXME: It would be nice to not claim this here; maybe the old
// scheme of just using Args was better?
const Arg &Input = IA->getInputArg();
Input.claim();
if (isa<PositionalArg>(Input)) {
const char *Name = Input.getValue(C.getArgs());
Result = InputInfo(Name, A->getType(), Name);
} else
Result = InputInfo(&Input, A->getType(), "");
return;
}

View file

@ -21,37 +21,61 @@ namespace driver {
/// InputInfo - Wrapper for information about an input source.
class InputInfo {
// FIXME: The distinction between filenames and inputarg here is
// gross; we should probably drop the idea of a "linker
// input". Doing so means tweaking pipelining to still create link
// steps when it sees linker inputs (but not treat them as
// arguments), and making sure that arguments get rendered
// correctly.
enum Class {
Nothing,
Filename,
InputArg,
Pipe
};
union {
const char *Filename;
const Arg *InputArg;
PipedJob *Pipe;
} Data;
bool IsPipe;
Class Kind;
types::ID Type;
const char *BaseInput;
public:
InputInfo() {}
InputInfo(types::ID _Type, const char *_BaseInput)
: IsPipe(false), Type(_Type), BaseInput(_BaseInput) {
Data.Filename = 0;
: Kind(Nothing), Type(_Type), BaseInput(_BaseInput) {
}
InputInfo(const char *Filename, types::ID _Type, const char *_BaseInput)
: IsPipe(false), Type(_Type), BaseInput(_BaseInput) {
Data.Filename = Filename;
InputInfo(const char *_Filename, types::ID _Type, const char *_BaseInput)
: Kind(Filename), Type(_Type), BaseInput(_BaseInput) {
Data.Filename = _Filename;
}
InputInfo(PipedJob *Pipe, types::ID _Type, const char *_BaseInput)
: IsPipe(true), Type(_Type), BaseInput(_BaseInput) {
Data.Pipe = Pipe;
InputInfo(const Arg *_InputArg, types::ID _Type, const char *_BaseInput)
: Kind(InputArg), Type(_Type), BaseInput(_BaseInput) {
Data.InputArg = _InputArg;
}
InputInfo(PipedJob *_Pipe, types::ID _Type, const char *_BaseInput)
: Kind(Pipe), Type(_Type), BaseInput(_BaseInput) {
Data.Pipe = _Pipe;
}
bool isPipe() const { return IsPipe; }
bool isNothing() const { return Kind == Nothing; }
bool isFilename() const { return Kind == Filename; }
bool isInputArg() const { return Kind == InputArg; }
bool isPipe() const { return Kind == Pipe; }
types::ID getType() const { return Type; }
const char *getBaseInput() const { return BaseInput; }
const char *getInputFilename() const {
assert(!isPipe() && "Invalid accessor.");
const char *getFilename() const {
assert(isFilename() && "Invalid accessor.");
return Data.Filename;
}
const Arg &getInputArg() const {
assert(isInputArg() && "Invalid accessor.");
return *Data.InputArg;
}
PipedJob &getPipe() const {
assert(isPipe() && "Invalid accessor.");
return *Data.Pipe;
@ -62,8 +86,10 @@ public:
std::string getAsString() const {
if (isPipe())
return "(pipe)";
else if (const char *N = getInputFilename())
return std::string("\"") + N + '"';
else if (isFilename())
return std::string("\"") + getFilename() + '"';
else if (isInputArg())
return "(input arg)";
else
return "(nothing)";
}

View file

@ -49,10 +49,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// FIXME: This is a total hack. Copy the input header file
// to the output, so that it can be -include'd by clang.
assert(Inputs.size() == 1 && "Cannot make PCH with multiple inputs.");
assert(!Output.isPipe() && "Unexpected pipe");
assert(Output.isFilename() && "Unexpected output");
assert(!Inputs[0].isPipe() && "Unexpected pipe");
const char *InputPath = Inputs[0].getInputFilename();
llvm::sys::Path OutputPath(Output.getInputFilename());
assert(Inputs[0].isFilename() && "Unexpected input");
const char *InputPath = Inputs[0].getFilename();
llvm::sys::Path OutputPath(Output.getFilename());
OutputPath.eraseComponent();
if (OutputPath.empty())
OutputPath = llvm::sys::Path(InputPath).getLast();
@ -317,9 +318,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Output.isPipe()) {
CmdArgs.push_back("-o");
CmdArgs.push_back("-");
} else if (const char *N = Output.getInputFilename()) {
} else if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(N);
CmdArgs.push_back(Output.getFilename());
} else {
assert(Output.isNothing() && "Invalid output.");
}
for (InputInfoList::const_iterator
@ -329,8 +332,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(types::getTypeName(II.getType()));
if (II.isPipe())
CmdArgs.push_back("-");
else if (II.isFilename())
CmdArgs.push_back(II.getFilename());
else
CmdArgs.push_back(II.getInputFilename());
II.getInputArg().renderAsInput(Args, CmdArgs);
}
const char *Exec =
@ -364,11 +369,13 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
if (Output.isPipe()) {
CmdArgs.push_back("-o");
CmdArgs.push_back("-");
} else if (const char *N = Output.getInputFilename()) {
} else if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(N);
} else
CmdArgs.push_back(Output.getFilename());
} else {
assert(Output.isNothing() && "Unexpected output");
CmdArgs.push_back("-fsyntax-only");
}
// Only pass -x if gcc will understand it; otherwise hope gcc
@ -389,9 +396,11 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
if (II.isPipe())
CmdArgs.push_back("-");
else if (II.isFilename())
CmdArgs.push_back(II.getFilename());
else
// FIXME: Linker inputs
CmdArgs.push_back(II.getInputFilename());
// Don't render as input, we need gcc to do the translations.
II.getInputArg().render(Args, CmdArgs);
}
const char *Exec =