mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Use (actions) instead of option properties, support external options.
Also includes a major refactoring. See documentation for more information. llvm-svn: 60656
This commit is contained in:
parent
16ea827dfd
commit
f01331152a
@ -27,14 +27,22 @@ namespace llvmc {
|
|||||||
std::string Command_;
|
std::string Command_;
|
||||||
/// Args_ - Command arguments. Stdout redirection ("> file") is allowed.
|
/// Args_ - Command arguments. Stdout redirection ("> file") is allowed.
|
||||||
std::vector<std::string> Args_;
|
std::vector<std::string> Args_;
|
||||||
|
/// StopCompilation_ - Should we stop compilation after executing
|
||||||
|
/// this action?
|
||||||
|
bool StopCompilation_;
|
||||||
|
/// OutFile_ - The output file name.
|
||||||
|
std::string OutFile_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Action() {}
|
Action (const std::string& C, const StrVector& A,
|
||||||
Action (const std::string& C, const StrVector& A)
|
bool S, const std::string& O)
|
||||||
: Command_(C), Args_(A)
|
: Command_(C), Args_(A), StopCompilation_(S), OutFile_(O)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// Execute - Executes the represented action.
|
/// Execute - Executes the represented action.
|
||||||
int Execute() const;
|
int Execute () const;
|
||||||
|
bool StopCompilation () const { return StopCompilation_; }
|
||||||
|
const std::string& OutFile() { return OutFile_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class Tool<list<dag> l> {
|
|||||||
list<dag> properties = l;
|
list<dag> properties = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Possible Tool properties
|
// Possible Tool properties.
|
||||||
|
|
||||||
def in_language;
|
def in_language;
|
||||||
def out_language;
|
def out_language;
|
||||||
@ -23,8 +23,9 @@ def output_suffix;
|
|||||||
def cmd_line;
|
def cmd_line;
|
||||||
def join;
|
def join;
|
||||||
def sink;
|
def sink;
|
||||||
|
def actions;
|
||||||
|
|
||||||
// Possible option types
|
// Possible option types.
|
||||||
|
|
||||||
def alias_option;
|
def alias_option;
|
||||||
def switch_option;
|
def switch_option;
|
||||||
@ -33,17 +34,16 @@ def parameter_list_option;
|
|||||||
def prefix_option;
|
def prefix_option;
|
||||||
def prefix_list_option;
|
def prefix_list_option;
|
||||||
|
|
||||||
// Possible option properties
|
def extern_switch;
|
||||||
|
def extern_parameter;
|
||||||
|
def extern_list;
|
||||||
|
|
||||||
|
// Possible option properties.
|
||||||
|
|
||||||
def append_cmd;
|
|
||||||
def forward;
|
|
||||||
def forward_as;
|
|
||||||
def help;
|
def help;
|
||||||
def hidden;
|
def hidden;
|
||||||
def really_hidden;
|
def really_hidden;
|
||||||
def required;
|
def required;
|
||||||
def stop_compilation;
|
|
||||||
def unpack_values;
|
|
||||||
|
|
||||||
// Empty DAG marker.
|
// Empty DAG marker.
|
||||||
def empty;
|
def empty;
|
||||||
@ -51,6 +51,10 @@ def empty;
|
|||||||
// The 'case' construct.
|
// The 'case' construct.
|
||||||
def case;
|
def case;
|
||||||
|
|
||||||
|
// Boolean operators.
|
||||||
|
def and;
|
||||||
|
def or;
|
||||||
|
|
||||||
// Primitive tests.
|
// Primitive tests.
|
||||||
def switch_on;
|
def switch_on;
|
||||||
def parameter_equals;
|
def parameter_equals;
|
||||||
@ -59,9 +63,13 @@ def input_languages_contain;
|
|||||||
def not_empty;
|
def not_empty;
|
||||||
def default;
|
def default;
|
||||||
|
|
||||||
// Boolean operators.
|
// Possible actions.
|
||||||
def and;
|
|
||||||
def or;
|
def append_cmd;
|
||||||
|
def forward;
|
||||||
|
def forward_as;
|
||||||
|
def stop_compilation;
|
||||||
|
def unpack_values;
|
||||||
|
|
||||||
// Increase/decrease the edge weight.
|
// Increase/decrease the edge weight.
|
||||||
def inc_weight;
|
def inc_weight;
|
||||||
|
@ -36,22 +36,29 @@ namespace llvmc {
|
|||||||
virtual ~Tool() {}
|
virtual ~Tool() {}
|
||||||
|
|
||||||
virtual Action GenerateAction (const PathVector& inFiles,
|
virtual Action GenerateAction (const PathVector& inFiles,
|
||||||
const llvm::sys::Path& outFile,
|
bool HasChildren,
|
||||||
|
const llvm::sys::Path& TempDir,
|
||||||
const InputLanguagesSet& InLangs,
|
const InputLanguagesSet& InLangs,
|
||||||
const LanguageMap& LangMap) const = 0;
|
const LanguageMap& LangMap) const = 0;
|
||||||
|
|
||||||
virtual Action GenerateAction (const llvm::sys::Path& inFile,
|
virtual Action GenerateAction (const llvm::sys::Path& inFile,
|
||||||
const llvm::sys::Path& outFile,
|
bool HasChildren,
|
||||||
|
const llvm::sys::Path& TempDir,
|
||||||
const InputLanguagesSet& InLangs,
|
const InputLanguagesSet& InLangs,
|
||||||
const LanguageMap& LangMap) const = 0;
|
const LanguageMap& LangMap) const = 0;
|
||||||
|
|
||||||
virtual const char* Name() const = 0;
|
virtual const char* Name() const = 0;
|
||||||
virtual const char** InputLanguages() const = 0;
|
virtual const char** InputLanguages() const = 0;
|
||||||
virtual const char* OutputLanguage() const = 0;
|
virtual const char* OutputLanguage() const = 0;
|
||||||
virtual const char* OutputSuffix() const = 0;
|
|
||||||
|
|
||||||
virtual bool IsLast() const = 0;
|
|
||||||
virtual bool IsJoin() const = 0;
|
virtual bool IsJoin() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// OutFileName - Generate the output file name.
|
||||||
|
llvm::sys::Path OutFilename(const llvm::sys::Path& In,
|
||||||
|
const llvm::sys::Path& TempDir,
|
||||||
|
bool StopCompilation,
|
||||||
|
const char* OutputSuffix) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// JoinTool - A Tool that has an associated input file list.
|
/// JoinTool - A Tool that has an associated input file list.
|
||||||
@ -61,10 +68,11 @@ namespace llvmc {
|
|||||||
void ClearJoinList() { JoinList_.clear(); }
|
void ClearJoinList() { JoinList_.clear(); }
|
||||||
bool JoinListEmpty() const { return JoinList_.empty(); }
|
bool JoinListEmpty() const { return JoinList_.empty(); }
|
||||||
|
|
||||||
Action GenerateAction(const llvm::sys::Path& outFile,
|
Action GenerateAction(bool HasChildren,
|
||||||
|
const llvm::sys::Path& TempDir,
|
||||||
const InputLanguagesSet& InLangs,
|
const InputLanguagesSet& InLangs,
|
||||||
const LanguageMap& LangMap) const {
|
const LanguageMap& LangMap) const {
|
||||||
return GenerateAction(JoinList_, outFile, InLangs, LangMap);
|
return GenerateAction(JoinList_, HasChildren, TempDir, InLangs, LangMap);
|
||||||
}
|
}
|
||||||
// We shouldn't shadow base class's version of GenerateAction.
|
// We shouldn't shadow base class's version of GenerateAction.
|
||||||
using Tool::GenerateAction;
|
using Tool::GenerateAction;
|
||||||
|
@ -11,6 +11,35 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def OptList : OptionList<[
|
||||||
|
(switch_option "emit-llvm",
|
||||||
|
(help "Emit LLVM bitcode files instead of native object files")),
|
||||||
|
(switch_option "E",
|
||||||
|
(help "Stop after the preprocessing stage, do not run the compiler")),
|
||||||
|
(switch_option "fsyntax-only",
|
||||||
|
(help "Stop after checking the input for syntax errors")),
|
||||||
|
(switch_option "opt",
|
||||||
|
(help "Enable opt")),
|
||||||
|
(switch_option "S",
|
||||||
|
(help "Stop after compilation, do not assemble")),
|
||||||
|
(switch_option "c",
|
||||||
|
(help "Compile and assemble, but do not link")),
|
||||||
|
(parameter_option "linker",
|
||||||
|
(help "Choose linker (possible values: gcc, g++)")),
|
||||||
|
(parameter_list_option "include",
|
||||||
|
(help "Include the named file prior to preprocessing")),
|
||||||
|
(prefix_list_option "I",
|
||||||
|
(help "Add a directory to include path")),
|
||||||
|
(prefix_list_option "Wa,",
|
||||||
|
(help "Pass options to assembler")),
|
||||||
|
(prefix_list_option "L",
|
||||||
|
(help "Add a directory to link path")),
|
||||||
|
(prefix_list_option "l",
|
||||||
|
(help "Search a library when linking")),
|
||||||
|
(prefix_list_option "Wl,",
|
||||||
|
(help "Pass options to linker"))
|
||||||
|
]>;
|
||||||
|
|
||||||
class llvm_gcc_based <string cmd_prefix, string in_lang> : Tool<
|
class llvm_gcc_based <string cmd_prefix, string in_lang> : Tool<
|
||||||
[(in_language in_lang),
|
[(in_language in_lang),
|
||||||
(out_language "llvm-bitcode"),
|
(out_language "llvm-bitcode"),
|
||||||
@ -25,16 +54,13 @@ class llvm_gcc_based <string cmd_prefix, string in_lang> : Tool<
|
|||||||
!strconcat(cmd_prefix, " -fsyntax-only $INFILE"),
|
!strconcat(cmd_prefix, " -fsyntax-only $INFILE"),
|
||||||
(default),
|
(default),
|
||||||
!strconcat(cmd_prefix, " -c $INFILE -o $OUTFILE -emit-llvm"))),
|
!strconcat(cmd_prefix, " -c $INFILE -o $OUTFILE -emit-llvm"))),
|
||||||
(switch_option "emit-llvm", (stop_compilation),
|
(actions
|
||||||
(help "Emit LLVM intermediate files instead of native object files")),
|
(case
|
||||||
(switch_option "E", (stop_compilation),
|
(switch_on "emit-llvm"), (stop_compilation),
|
||||||
(help "Stop after the preprocessing stage, do not run the compiler")),
|
(switch_on "E"), (stop_compilation),
|
||||||
(switch_option "fsyntax-only", (stop_compilation),
|
(switch_on "fsyntax-only"), (stop_compilation),
|
||||||
(help "Stop after checking the input for syntax errors")),
|
(not_empty "include"), (forward "include"),
|
||||||
(parameter_list_option "include", (forward),
|
(not_empty "I"), (forward "include"))),
|
||||||
(help "Include the named file prior to preprocessing")),
|
|
||||||
(prefix_list_option "I", (forward),
|
|
||||||
(help "Add a directory to include path")),
|
|
||||||
(sink)
|
(sink)
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
@ -46,7 +72,6 @@ def llvm_gcc_mxx : llvm_gcc_based<"llvm-gcc -x objective-c++", "objective-c++">;
|
|||||||
def opt : Tool<
|
def opt : Tool<
|
||||||
[(in_language "llvm-bitcode"),
|
[(in_language "llvm-bitcode"),
|
||||||
(out_language "llvm-bitcode"),
|
(out_language "llvm-bitcode"),
|
||||||
(switch_option "opt", (help "Enable opt")),
|
|
||||||
(output_suffix "bc"),
|
(output_suffix "bc"),
|
||||||
(cmd_line "opt -f $INFILE -o $OUTFILE")
|
(cmd_line "opt -f $INFILE -o $OUTFILE")
|
||||||
]>;
|
]>;
|
||||||
@ -62,8 +87,8 @@ def llc : Tool<
|
|||||||
[(in_language "llvm-bitcode"),
|
[(in_language "llvm-bitcode"),
|
||||||
(out_language "assembler"),
|
(out_language "assembler"),
|
||||||
(output_suffix "s"),
|
(output_suffix "s"),
|
||||||
(switch_option "S", (stop_compilation),
|
(actions (case
|
||||||
(help "Stop after compilation, do not assemble")),
|
(switch_on "S"), (stop_compilation))),
|
||||||
(cmd_line "llc -f $INFILE -o $OUTFILE")
|
(cmd_line "llc -f $INFILE -o $OUTFILE")
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
@ -72,36 +97,28 @@ def llvm_gcc_assembler : Tool<
|
|||||||
(out_language "object-code"),
|
(out_language "object-code"),
|
||||||
(output_suffix "o"),
|
(output_suffix "o"),
|
||||||
(cmd_line "llvm-gcc -c -x assembler $INFILE -o $OUTFILE"),
|
(cmd_line "llvm-gcc -c -x assembler $INFILE -o $OUTFILE"),
|
||||||
(switch_option "c", (stop_compilation),
|
(actions (case
|
||||||
(help "Compile and assemble, but do not link")),
|
(switch_on "c"), (stop_compilation),
|
||||||
(prefix_list_option "Wa,", (unpack_values), (help "Pass options to assembler"))
|
(not_empty "Wa,"), (unpack_values "Wa,")))
|
||||||
|
]>;
|
||||||
|
|
||||||
|
// Base class for linkers
|
||||||
|
class llvm_gcc_based_linker <string cmd_prefix> : Tool<
|
||||||
|
[(in_language "object-code"),
|
||||||
|
(out_language "executable"),
|
||||||
|
(output_suffix "out"),
|
||||||
|
(cmd_line !strconcat(cmd_prefix, " $INFILE -o $OUTFILE")),
|
||||||
|
(join),
|
||||||
|
(actions (case
|
||||||
|
(not_empty "L"), (forward "L"),
|
||||||
|
(not_empty "l"), (forward "l"),
|
||||||
|
(not_empty "Wl,"), (unpack_values "Wl,")))
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
// Default linker
|
// Default linker
|
||||||
def llvm_gcc_linker : Tool<
|
def llvm_gcc_linker : llvm_gcc_based_linker<"llvm-gcc">;
|
||||||
[(in_language "object-code"),
|
|
||||||
(out_language "executable"),
|
|
||||||
(output_suffix "out"),
|
|
||||||
(cmd_line "llvm-gcc $INFILE -o $OUTFILE"),
|
|
||||||
(join),
|
|
||||||
(prefix_list_option "L", (forward), (help "Add a directory to link path")),
|
|
||||||
(prefix_list_option "l", (forward), (help "Search a library when linking")),
|
|
||||||
(prefix_list_option "Wl,", (unpack_values), (help "Pass options to linker"))
|
|
||||||
]>;
|
|
||||||
|
|
||||||
// Alternative linker for C++
|
// Alternative linker for C++
|
||||||
def llvm_gcc_cpp_linker : Tool<
|
def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"llvm-g++">;
|
||||||
[(in_language "object-code"),
|
|
||||||
(out_language "executable"),
|
|
||||||
(output_suffix "out"),
|
|
||||||
(cmd_line "llvm-g++ $INFILE -o $OUTFILE"),
|
|
||||||
(join),
|
|
||||||
(parameter_option "linker",
|
|
||||||
(help "Choose linker (possible values: gcc, g++)")),
|
|
||||||
(prefix_list_option "L", (forward)),
|
|
||||||
(prefix_list_option "l", (forward)),
|
|
||||||
(prefix_list_option "Wl,", (unpack_values))
|
|
||||||
]>;
|
|
||||||
|
|
||||||
// Language map
|
// Language map
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ using namespace llvm;
|
|||||||
using namespace llvmc;
|
using namespace llvmc;
|
||||||
|
|
||||||
extern cl::list<std::string> InputFilenames;
|
extern cl::list<std::string> InputFilenames;
|
||||||
extern cl::opt<std::string> OutputFilename;
|
|
||||||
extern cl::list<std::string> Languages;
|
extern cl::list<std::string> Languages;
|
||||||
|
|
||||||
namespace llvmc {
|
namespace llvmc {
|
||||||
@ -143,30 +142,6 @@ void CompilationGraph::insertEdge(const std::string& A, Edge* Edg) {
|
|||||||
B.IncrInEdges();
|
B.IncrInEdges();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName,
|
|
||||||
const std::string& Suffix) {
|
|
||||||
sys::Path Out;
|
|
||||||
|
|
||||||
// Make sure we don't end up with path names like '/file.o' if the
|
|
||||||
// TempDir is empty.
|
|
||||||
if (TempDir.empty()) {
|
|
||||||
Out.set(BaseName);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Out = TempDir;
|
|
||||||
Out.appendComponent(BaseName);
|
|
||||||
}
|
|
||||||
Out.appendSuffix(Suffix);
|
|
||||||
// NOTE: makeUnique always *creates* a unique temporary file,
|
|
||||||
// which is good, since there will be no races. However, some
|
|
||||||
// tools do not like it when the output file already exists, so
|
|
||||||
// they have to be placated with -f or something like that.
|
|
||||||
Out.makeUnique(true, NULL);
|
|
||||||
return Out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass input file through the chain until we bump into a Join node or
|
// Pass input file through the chain until we bump into a Join node or
|
||||||
// a node that says that it is the last.
|
// a node that says that it is the last.
|
||||||
void CompilationGraph::PassThroughGraph (const sys::Path& InFile,
|
void CompilationGraph::PassThroughGraph (const sys::Path& InFile,
|
||||||
@ -174,12 +149,10 @@ void CompilationGraph::PassThroughGraph (const sys::Path& InFile,
|
|||||||
const InputLanguagesSet& InLangs,
|
const InputLanguagesSet& InLangs,
|
||||||
const sys::Path& TempDir,
|
const sys::Path& TempDir,
|
||||||
const LanguageMap& LangMap) const {
|
const LanguageMap& LangMap) const {
|
||||||
bool Last = false;
|
|
||||||
sys::Path In = InFile;
|
sys::Path In = InFile;
|
||||||
const Node* CurNode = StartNode;
|
const Node* CurNode = StartNode;
|
||||||
|
|
||||||
while(!Last) {
|
while(true) {
|
||||||
sys::Path Out;
|
|
||||||
Tool* CurTool = CurNode->ToolPtr.getPtr();
|
Tool* CurTool = CurNode->ToolPtr.getPtr();
|
||||||
|
|
||||||
if (CurTool->IsJoin()) {
|
if (CurTool->IsJoin()) {
|
||||||
@ -188,32 +161,19 @@ void CompilationGraph::PassThroughGraph (const sys::Path& InFile,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since toolchains do not have to end with a Join node, we should
|
Action CurAction = CurTool->GenerateAction(In, CurNode->HasChildren(),
|
||||||
// check if this Node is the last.
|
TempDir, InLangs, LangMap);
|
||||||
if (!CurNode->HasChildren() || CurTool->IsLast()) {
|
|
||||||
if (!OutputFilename.empty()) {
|
|
||||||
Out.set(OutputFilename);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Out.set(In.getBasename());
|
|
||||||
Out.appendSuffix(CurTool->OutputSuffix());
|
|
||||||
}
|
|
||||||
Last = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Out = MakeTempFile(TempDir, In.getBasename(), CurTool->OutputSuffix());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (int ret = CurTool->GenerateAction(In, Out, InLangs, LangMap).Execute())
|
if (int ret = CurAction.Execute())
|
||||||
throw error_code(ret);
|
throw error_code(ret);
|
||||||
|
|
||||||
if (Last)
|
if (CurAction.StopCompilation())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CurNode = &getNode(ChooseEdge(CurNode->OutEdges,
|
CurNode = &getNode(ChooseEdge(CurNode->OutEdges,
|
||||||
InLangs,
|
InLangs,
|
||||||
CurNode->Name())->ToolName());
|
CurNode->Name())->ToolName());
|
||||||
In = Out; Out.clear();
|
In = CurAction.OutFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,36 +311,24 @@ int CompilationGraph::Build (const sys::Path& TempDir,
|
|||||||
sys::Path Out;
|
sys::Path Out;
|
||||||
const Node* CurNode = *B;
|
const Node* CurNode = *B;
|
||||||
JoinTool* JT = &dynamic_cast<JoinTool&>(*CurNode->ToolPtr.getPtr());
|
JoinTool* JT = &dynamic_cast<JoinTool&>(*CurNode->ToolPtr.getPtr());
|
||||||
bool IsLast = false;
|
|
||||||
|
|
||||||
// Are there any files in the join list?
|
// Are there any files in the join list?
|
||||||
if (JT->JoinListEmpty())
|
if (JT->JoinListEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Is this the last tool in the toolchain?
|
Action CurAction = JT->GenerateAction(CurNode->HasChildren(),
|
||||||
// NOTE: we can process several toolchains in parallel.
|
TempDir, InLangs, LangMap);
|
||||||
if (!CurNode->HasChildren() || JT->IsLast()) {
|
|
||||||
if (OutputFilename.empty()) {
|
|
||||||
Out.set("a");
|
|
||||||
Out.appendSuffix(JT->OutputSuffix());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Out.set(OutputFilename);
|
|
||||||
IsLast = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Out = MakeTempFile(TempDir, "tmp", JT->OutputSuffix());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (int ret = JT->GenerateAction(Out, InLangs, LangMap).Execute())
|
if (int ret = CurAction.Execute())
|
||||||
throw error_code(ret);
|
throw error_code(ret);
|
||||||
|
|
||||||
if (!IsLast) {
|
if (CurAction.StopCompilation())
|
||||||
const Node* NextNode =
|
return 0;
|
||||||
&getNode(ChooseEdge(CurNode->OutEdges, InLangs,
|
|
||||||
CurNode->Name())->ToolName());
|
const Node* NextNode =
|
||||||
|
&getNode(ChooseEdge(CurNode->OutEdges, InLangs,
|
||||||
|
CurNode->Name())->ToolName());
|
||||||
PassThroughGraph(Out, NextNode, InLangs, TempDir, LangMap);
|
PassThroughGraph(Out, NextNode, InLangs, TempDir, LangMap);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
74
tools/llvmc/driver/Tool.cpp
Normal file
74
tools/llvmc/driver/Tool.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
//===--- Tool.cpp - The LLVM Compiler Driver --------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open
|
||||||
|
// Source License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Tool base class - implementation details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/CompilerDriver/Tool.h"
|
||||||
|
|
||||||
|
#include "llvm/System/Path.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace llvmc;
|
||||||
|
|
||||||
|
extern cl::opt<std::string> OutputFilename;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName,
|
||||||
|
const std::string& Suffix) {
|
||||||
|
sys::Path Out;
|
||||||
|
|
||||||
|
// Make sure we don't end up with path names like '/file.o' if the
|
||||||
|
// TempDir is empty.
|
||||||
|
if (TempDir.empty()) {
|
||||||
|
Out.set(BaseName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Out = TempDir;
|
||||||
|
Out.appendComponent(BaseName);
|
||||||
|
}
|
||||||
|
Out.appendSuffix(Suffix);
|
||||||
|
// NOTE: makeUnique always *creates* a unique temporary file,
|
||||||
|
// which is good, since there will be no races. However, some
|
||||||
|
// tools do not like it when the output file already exists, so
|
||||||
|
// they have to be placated with -f or something like that.
|
||||||
|
Out.makeUnique(true, NULL);
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sys::Path Tool::OutFilename(const sys::Path& In,
|
||||||
|
const sys::Path& TempDir,
|
||||||
|
bool StopCompilation,
|
||||||
|
const char* OutputSuffix) const {
|
||||||
|
sys::Path Out;
|
||||||
|
|
||||||
|
if (StopCompilation) {
|
||||||
|
if (!OutputFilename.empty()) {
|
||||||
|
Out.set(OutputFilename);
|
||||||
|
}
|
||||||
|
else if (IsJoin()) {
|
||||||
|
Out.set("a");
|
||||||
|
Out.appendSuffix(OutputSuffix);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Out.set(In.getBasename());
|
||||||
|
Out.appendSuffix(OutputSuffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (IsJoin())
|
||||||
|
Out = MakeTempFile(TempDir, "tmp", OutputSuffix);
|
||||||
|
else
|
||||||
|
Out = MakeTempFile(TempDir, In.getBasename(), OutputSuffix);
|
||||||
|
}
|
||||||
|
return Out;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user