From be6ee7c116f8f768a180df6eba6799a6660722e7 Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Tue, 23 Feb 2010 09:04:28 +0000 Subject: [PATCH] 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 --- include/llvm/CompilerDriver/Common.td | 1 + include/llvm/CompilerDriver/Tool.h | 3 +- lib/CompilerDriver/CompilationGraph.cpp | 2 +- lib/CompilerDriver/Main.cpp | 4 --- tools/llvmc/plugins/Base/Base.td.in | 5 +++ utils/TableGen/LLVMCConfigurationEmitter.cpp | 36 ++++++++++++++++++-- 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index 3ae77aeadf6..aa15482cfae 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -23,6 +23,7 @@ def output_suffix; def cmd_line; def join; def sink; +def works_on_empty; def actions; // Possible option types. diff --git a/include/llvm/CompilerDriver/Tool.h b/include/llvm/CompilerDriver/Tool.h index a982e2d397e..6fc0ae63914 100644 --- a/include/llvm/CompilerDriver/Tool.h +++ b/include/llvm/CompilerDriver/Tool.h @@ -28,7 +28,7 @@ namespace llvmc { typedef std::vector PathVector; typedef llvm::StringSet<> InputLanguagesSet; - /// Tool - A class + /// Tool - Represents a single tool. class Tool : public llvm::RefCountedBaseVPTR { public: @@ -51,6 +51,7 @@ namespace llvmc { virtual const char* OutputLanguage() const = 0; virtual bool IsJoin() const = 0; + virtual bool WorksOnEmpty() const = 0; protected: /// OutFileName - Generate the output file name. diff --git a/lib/CompilerDriver/CompilationGraph.cpp b/lib/CompilerDriver/CompilationGraph.cpp index 524607bee77..a36d3fb692a 100644 --- a/lib/CompilerDriver/CompilationGraph.cpp +++ b/lib/CompilerDriver/CompilationGraph.cpp @@ -313,7 +313,7 @@ int CompilationGraph::Build (const sys::Path& TempDir, JoinTool* JT = &dynamic_cast(*CurNode->ToolPtr.getPtr()); // Are there any files in the join list? - if (JT->JoinListEmpty()) + if (JT->JoinListEmpty() && !(JT->WorksOnEmpty() && InputFilenames.empty())) continue; Action CurAction = JT->GenerateAction(CurNode->HasChildren(), diff --git a/lib/CompilerDriver/Main.cpp b/lib/CompilerDriver/Main.cpp index 3a3487a0a9c..96877077cc8 100644 --- a/lib/CompilerDriver/Main.cpp +++ b/lib/CompilerDriver/Main.cpp @@ -126,10 +126,6 @@ int Main(int argc, char** argv) { return 0; } - if (InputFilenames.empty()) { - throw std::runtime_error("no input files"); - } - if (Time) { GlobalTimeLog = new std::stringstream; GlobalTimeLog->precision(2); diff --git a/tools/llvmc/plugins/Base/Base.td.in b/tools/llvmc/plugins/Base/Base.td.in index 284c5f95fbe..d36554c9da9 100644 --- a/tools/llvmc/plugins/Base/Base.td.in +++ b/tools/llvmc/plugins/Base/Base.td.in @@ -76,6 +76,8 @@ def OptList : OptionList<[ (help "Specifies a framework to link against")), (parameter_list_option "weak_framework", (help "Specifies a framework to weakly link against"), (hidden)), + (parameter_option "filelist", (hidden), + (help "Link the files listed in file")), (prefix_list_option "F", (help "Add a directory to framework search path")), (prefix_list_option "I", @@ -242,6 +244,8 @@ class llvm_gcc_based_linker : Tool< (out_language "executable"), (output_suffix "out"), (cmd_line !strconcat(cmd_prefix, " $INFILE -o $OUTFILE")), + (works_on_empty (case (not_empty "filelist"), true, + (default), false)), (join), (actions (case (switch_on "pthread"), (append_cmd "-lpthread"), @@ -250,6 +254,7 @@ class llvm_gcc_based_linker : Tool< (not_empty "arch"), (forward "arch"), (not_empty "framework"), (forward "framework"), (not_empty "weak_framework"), (forward "weak_framework"), + (not_empty "filelist"), (forward "filelist"), (switch_on "m32"), (forward "m32"), (switch_on "m64"), (forward "m64"), (not_empty "l"), (forward "l"), diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp index 98952606c9e..836a7750c71 100644 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -783,6 +783,7 @@ struct ToolDescription : public RefCountedBase { std::string OutLanguage; std::string OutputSuffix; unsigned Flags; + const Init* OnEmpty; // Various boolean properties void setSink() { Flags |= ToolFlags::Sink; } @@ -792,9 +793,9 @@ struct ToolDescription : public RefCountedBase { // Default ctor here is needed because StringMap can only store // DefaultConstructible objects - ToolDescription() : CmdLine(0), Actions(0), Flags(0) {} + ToolDescription() : CmdLine(0), Actions(0), Flags(0), OnEmpty(0) {} 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("output_suffix", &CollectToolProperties::onOutputSuffix); AddHandler("sink", &CollectToolProperties::onSink); + AddHandler("works_on_empty", &CollectToolProperties::onWorksOnEmpty); staticMembersInitialized_ = true; } @@ -907,6 +909,10 @@ private: toolDesc_.setSink(); } + void onWorksOnEmpty (const DagInit& d) { + toolDesc_.OnEmpty = d.getArg(0); + } + }; /// CollectToolDescriptions - Gather information about tool properties @@ -1509,7 +1515,7 @@ public: /// EmitCaseConstructHandler - Emit code that handles the 'case' /// construct. Takes a function object that should emit code for every case /// 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). /// EmitElseIf parameter controls the type of condition that is emitted ('if /// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..) {..} @@ -2221,6 +2227,29 @@ void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) { 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 /// given Tool class. void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) { @@ -2255,6 +2284,7 @@ void EmitToolClassDefinition (const ToolDescription& D, EmitNameMethod(D, O); EmitInOutLanguageMethods(D, O); EmitIsJoinMethod(D, O); + EmitWorksOnEmptyMethod(D, OptDescs, O); EmitGenerateActionMethods(D, OptDescs, O); // Close class definition -- 2.34.1