mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-21 02:29:22 +00:00
New experimental/undocumented feature: 'works_on_empty'.
For now, just enough support to make -filelist work. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96918 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9f2a0802e5
commit
be6ee7c116
@ -23,6 +23,7 @@ def output_suffix;
|
|||||||
def cmd_line;
|
def cmd_line;
|
||||||
def join;
|
def join;
|
||||||
def sink;
|
def sink;
|
||||||
|
def works_on_empty;
|
||||||
def actions;
|
def actions;
|
||||||
|
|
||||||
// Possible option types.
|
// Possible option types.
|
||||||
|
@ -28,7 +28,7 @@ namespace llvmc {
|
|||||||
typedef std::vector<llvm::sys::Path> PathVector;
|
typedef std::vector<llvm::sys::Path> PathVector;
|
||||||
typedef llvm::StringSet<> InputLanguagesSet;
|
typedef llvm::StringSet<> InputLanguagesSet;
|
||||||
|
|
||||||
/// Tool - A class
|
/// Tool - Represents a single tool.
|
||||||
class Tool : public llvm::RefCountedBaseVPTR<Tool> {
|
class Tool : public llvm::RefCountedBaseVPTR<Tool> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -51,6 +51,7 @@ namespace llvmc {
|
|||||||
virtual const char* OutputLanguage() const = 0;
|
virtual const char* OutputLanguage() const = 0;
|
||||||
|
|
||||||
virtual bool IsJoin() const = 0;
|
virtual bool IsJoin() const = 0;
|
||||||
|
virtual bool WorksOnEmpty() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// OutFileName - Generate the output file name.
|
/// OutFileName - Generate the output file name.
|
||||||
|
@ -313,7 +313,7 @@ int CompilationGraph::Build (const sys::Path& TempDir,
|
|||||||
JoinTool* JT = &dynamic_cast<JoinTool&>(*CurNode->ToolPtr.getPtr());
|
JoinTool* JT = &dynamic_cast<JoinTool&>(*CurNode->ToolPtr.getPtr());
|
||||||
|
|
||||||
// Are there any files in the join list?
|
// Are there any files in the join list?
|
||||||
if (JT->JoinListEmpty())
|
if (JT->JoinListEmpty() && !(JT->WorksOnEmpty() && InputFilenames.empty()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Action CurAction = JT->GenerateAction(CurNode->HasChildren(),
|
Action CurAction = JT->GenerateAction(CurNode->HasChildren(),
|
||||||
|
@ -126,10 +126,6 @@ int Main(int argc, char** argv) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InputFilenames.empty()) {
|
|
||||||
throw std::runtime_error("no input files");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Time) {
|
if (Time) {
|
||||||
GlobalTimeLog = new std::stringstream;
|
GlobalTimeLog = new std::stringstream;
|
||||||
GlobalTimeLog->precision(2);
|
GlobalTimeLog->precision(2);
|
||||||
|
@ -76,6 +76,8 @@ def OptList : OptionList<[
|
|||||||
(help "Specifies a framework to link against")),
|
(help "Specifies a framework to link against")),
|
||||||
(parameter_list_option "weak_framework",
|
(parameter_list_option "weak_framework",
|
||||||
(help "Specifies a framework to weakly link against"), (hidden)),
|
(help "Specifies a framework to weakly link against"), (hidden)),
|
||||||
|
(parameter_option "filelist", (hidden),
|
||||||
|
(help "Link the files listed in file")),
|
||||||
(prefix_list_option "F",
|
(prefix_list_option "F",
|
||||||
(help "Add a directory to framework search path")),
|
(help "Add a directory to framework search path")),
|
||||||
(prefix_list_option "I",
|
(prefix_list_option "I",
|
||||||
@ -242,6 +244,8 @@ class llvm_gcc_based_linker <string cmd_prefix> : Tool<
|
|||||||
(out_language "executable"),
|
(out_language "executable"),
|
||||||
(output_suffix "out"),
|
(output_suffix "out"),
|
||||||
(cmd_line !strconcat(cmd_prefix, " $INFILE -o $OUTFILE")),
|
(cmd_line !strconcat(cmd_prefix, " $INFILE -o $OUTFILE")),
|
||||||
|
(works_on_empty (case (not_empty "filelist"), true,
|
||||||
|
(default), false)),
|
||||||
(join),
|
(join),
|
||||||
(actions (case
|
(actions (case
|
||||||
(switch_on "pthread"), (append_cmd "-lpthread"),
|
(switch_on "pthread"), (append_cmd "-lpthread"),
|
||||||
@ -250,6 +254,7 @@ class llvm_gcc_based_linker <string cmd_prefix> : Tool<
|
|||||||
(not_empty "arch"), (forward "arch"),
|
(not_empty "arch"), (forward "arch"),
|
||||||
(not_empty "framework"), (forward "framework"),
|
(not_empty "framework"), (forward "framework"),
|
||||||
(not_empty "weak_framework"), (forward "weak_framework"),
|
(not_empty "weak_framework"), (forward "weak_framework"),
|
||||||
|
(not_empty "filelist"), (forward "filelist"),
|
||||||
(switch_on "m32"), (forward "m32"),
|
(switch_on "m32"), (forward "m32"),
|
||||||
(switch_on "m64"), (forward "m64"),
|
(switch_on "m64"), (forward "m64"),
|
||||||
(not_empty "l"), (forward "l"),
|
(not_empty "l"), (forward "l"),
|
||||||
|
@ -783,6 +783,7 @@ struct ToolDescription : public RefCountedBase<ToolDescription> {
|
|||||||
std::string OutLanguage;
|
std::string OutLanguage;
|
||||||
std::string OutputSuffix;
|
std::string OutputSuffix;
|
||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
|
const Init* OnEmpty;
|
||||||
|
|
||||||
// Various boolean properties
|
// Various boolean properties
|
||||||
void setSink() { Flags |= ToolFlags::Sink; }
|
void setSink() { Flags |= ToolFlags::Sink; }
|
||||||
@ -792,9 +793,9 @@ struct ToolDescription : public RefCountedBase<ToolDescription> {
|
|||||||
|
|
||||||
// Default ctor here is needed because StringMap can only store
|
// Default ctor here is needed because StringMap can only store
|
||||||
// DefaultConstructible objects
|
// DefaultConstructible objects
|
||||||
ToolDescription() : CmdLine(0), Actions(0), Flags(0) {}
|
ToolDescription() : CmdLine(0), Actions(0), Flags(0), OnEmpty(0) {}
|
||||||
ToolDescription (const std::string& n)
|
ToolDescription (const std::string& n)
|
||||||
: Name(n), CmdLine(0), Actions(0), Flags(0)
|
: Name(n), CmdLine(0), Actions(0), Flags(0), OnEmpty(0)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -831,6 +832,7 @@ public:
|
|||||||
AddHandler("out_language", &CollectToolProperties::onOutLanguage);
|
AddHandler("out_language", &CollectToolProperties::onOutLanguage);
|
||||||
AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix);
|
AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix);
|
||||||
AddHandler("sink", &CollectToolProperties::onSink);
|
AddHandler("sink", &CollectToolProperties::onSink);
|
||||||
|
AddHandler("works_on_empty", &CollectToolProperties::onWorksOnEmpty);
|
||||||
|
|
||||||
staticMembersInitialized_ = true;
|
staticMembersInitialized_ = true;
|
||||||
}
|
}
|
||||||
@ -907,6 +909,10 @@ private:
|
|||||||
toolDesc_.setSink();
|
toolDesc_.setSink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onWorksOnEmpty (const DagInit& d) {
|
||||||
|
toolDesc_.OnEmpty = d.getArg(0);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// CollectToolDescriptions - Gather information about tool properties
|
/// CollectToolDescriptions - Gather information about tool properties
|
||||||
@ -1509,7 +1515,7 @@ public:
|
|||||||
/// EmitCaseConstructHandler - Emit code that handles the 'case'
|
/// EmitCaseConstructHandler - Emit code that handles the 'case'
|
||||||
/// construct. Takes a function object that should emit code for every case
|
/// construct. Takes a function object that should emit code for every case
|
||||||
/// clause. Implemented on top of WalkCase.
|
/// clause. Implemented on top of WalkCase.
|
||||||
/// Callback's type is void F(Init* Statement, unsigned IndentLevel,
|
/// Callback's type is void F(const Init* Statement, unsigned IndentLevel,
|
||||||
/// raw_ostream& O).
|
/// raw_ostream& O).
|
||||||
/// EmitElseIf parameter controls the type of condition that is emitted ('if
|
/// EmitElseIf parameter controls the type of condition that is emitted ('if
|
||||||
/// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..) {..}
|
/// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..) {..}
|
||||||
@ -2221,6 +2227,29 @@ void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) {
|
|||||||
O.indent(Indent1) << "}\n\n";
|
O.indent(Indent1) << "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// EmitWorksOnEmptyCallback - Callback used by EmitWorksOnEmptyMethod in
|
||||||
|
/// conjunction with EmitCaseConstructHandler.
|
||||||
|
void EmitWorksOnEmptyCallback (const Init* Value,
|
||||||
|
unsigned IndentLevel, raw_ostream& O) {
|
||||||
|
CheckBooleanConstant(Value);
|
||||||
|
O.indent(IndentLevel) << "return " << Value->getAsString() << ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// EmitWorksOnEmptyMethod - Emit the WorksOnEmpty() method for a given Tool
|
||||||
|
/// class.
|
||||||
|
void EmitWorksOnEmptyMethod (const ToolDescription& D,
|
||||||
|
const OptionDescriptions& OptDescs,
|
||||||
|
raw_ostream& O)
|
||||||
|
{
|
||||||
|
O.indent(Indent1) << "bool WorksOnEmpty() const {\n";
|
||||||
|
if (D.OnEmpty == 0)
|
||||||
|
O.indent(Indent2) << "return false;\n";
|
||||||
|
else
|
||||||
|
EmitCaseConstructHandler(D.OnEmpty, Indent2, EmitWorksOnEmptyCallback,
|
||||||
|
/*EmitElseIf = */ true, OptDescs, O);
|
||||||
|
O.indent(Indent1) << "}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
/// EmitStaticMemberDefinitions - Emit static member definitions for a
|
/// EmitStaticMemberDefinitions - Emit static member definitions for a
|
||||||
/// given Tool class.
|
/// given Tool class.
|
||||||
void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) {
|
void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) {
|
||||||
@ -2255,6 +2284,7 @@ void EmitToolClassDefinition (const ToolDescription& D,
|
|||||||
EmitNameMethod(D, O);
|
EmitNameMethod(D, O);
|
||||||
EmitInOutLanguageMethods(D, O);
|
EmitInOutLanguageMethods(D, O);
|
||||||
EmitIsJoinMethod(D, O);
|
EmitIsJoinMethod(D, O);
|
||||||
|
EmitWorksOnEmptyMethod(D, OptDescs, O);
|
||||||
EmitGenerateActionMethods(D, OptDescs, O);
|
EmitGenerateActionMethods(D, OptDescs, O);
|
||||||
|
|
||||||
// Close class definition
|
// Close class definition
|
||||||
|
Loading…
Reference in New Issue
Block a user