namespace {
- /// ChooseEdge - Return the edge with the maximum weight.
+ /// ChooseEdge - Return the edge with the maximum weight. Returns 0 on error.
template <class C>
const Edge* ChooseEdge(const C& EdgesContainer,
const InputLanguagesSet& InLangs,
const std::string& NodeName = "root") {
const Edge* MaxEdge = 0;
- unsigned MaxWeight = 0;
+ int MaxWeight = 0;
bool SingleMax = true;
+ // TODO: fix calculation of SingleMax.
for (typename C::const_iterator B = EdgesContainer.begin(),
E = EdgesContainer.end(); B != E; ++B) {
const Edge* e = B->getPtr();
- unsigned EW = e->Weight(InLangs);
+ int EW = e->Weight(InLangs);
+ if (EW < 0) {
+ // (error) invocation in TableGen -> we don't need to print an error
+ // message.
+ return 0;
+ }
if (EW > MaxWeight) {
MaxEdge = e;
MaxWeight = EW;
int CompilationGraph::insertEdge(const std::string& A, Edge* Edg) {
Node* B = getNode(Edg->ToolName());
if (B == 0)
- return -1;
+ return 1;
if (A == "root") {
const char** InLangs = B->ToolPtr->InputLanguages();
else {
Node* N = getNode(A);
if (N == 0)
- return -1;
+ return 1;
N->AddEdge(Edg);
}
const Edge* Edg = ChooseEdge(CurNode->OutEdges, InLangs, CurNode->Name());
if (Edg == 0)
- return -1;
+ return 1;
CurNode = getNode(Edg->ToolName());
if (CurNode == 0)
- return -1;
+ return 1;
In = CurAction.OutFile();
}
InputLanguagesSet& InLangs, const LanguageMap& LangMap) const {
// Determine the input language.
- const std::string* InLang = LangMap.GetLanguage(In);
+ const std::string* InLang = (ForceLanguage ? ForceLanguage
+ : LangMap.GetLanguage(In));
if (InLang == 0)
return 0;
- const std::string& InLanguage = (ForceLanguage ? *ForceLanguage : *InLang);
+ const std::string& InLanguage = *InLang;
// Add the current input language to the input language set.
InLangs.insert(InLanguage);
// Find the toolchain corresponding to this file.
const Node* N = FindToolChain(In, xLanguage, InLangs, LangMap);
if (N == 0)
- return -1;
+ return 1;
// Pass file through the chain starting at head.
if (int ret = PassThroughGraph(In, N, InLangs, TempDir, LangMap))
return ret;
Node* Root = getNode("root");
if (Root == 0)
- return -1;
+ return 1;
Q.push(Root);
EB != EE; ++EB) {
Node* B = getNode((*EB)->ToolName());
if (B == 0)
- return -1;
+ return 1;
B->DecrInEdges();
if (B->HasNoInEdges())
int CompilationGraph::Build (const sys::Path& TempDir,
const LanguageMap& LangMap) {
InputLanguagesSet InLangs;
+ bool WasSomeActionGenerated = !InputFilenames.empty();
// Traverse initial parts of the toolchains and fill in InLangs.
if (int ret = BuildInitial(InLangs, TempDir, LangMap))
if (JT->JoinListEmpty() && !(JT->WorksOnEmpty() && InputFilenames.empty()))
continue;
+ WasSomeActionGenerated = true;
Action CurAction;
if (int ret = JT->GenerateAction(CurAction, CurNode->HasChildren(),
TempDir, InLangs, LangMap)) {
const Edge* Edg = ChooseEdge(CurNode->OutEdges, InLangs, CurNode->Name());
if (Edg == 0)
- return -1;
+ return 1;
const Node* NextNode = getNode(Edg->ToolName());
if (NextNode == 0)
- return -1;
+ return 1;
if (int ret = PassThroughGraph(sys::Path(CurAction.OutFile()), NextNode,
InLangs, TempDir, LangMap)) {
}
}
+ if (!WasSomeActionGenerated) {
+ PrintError("no input files");
+ return 1;
+ }
+
return 0;
}
EB != EE; ++EB) {
const Node* N2 = this->getNode((*EB)->ToolName());
if (N2 == 0)
- return -1;
+ return 1;
if (!N2->ToolPtr) {
++ret;
continue;
}
- const char* OutLang = N1.ToolPtr->OutputLanguage();
+ const char** OutLangs = N1.ToolPtr->OutputLanguages();
const char** InLangs = N2->ToolPtr->InputLanguages();
bool eq = false;
- for (;*InLangs; ++InLangs) {
- if (std::strcmp(OutLang, *InLangs) == 0) {
- eq = true;
- break;
+ const char* OutLang = 0;
+ for (;*OutLangs; ++OutLangs) {
+ OutLang = *OutLangs;
+ for (;*InLangs; ++InLangs) {
+ if (std::strcmp(OutLang, *InLangs) == 0) {
+ eq = true;
+ break;
+ }
}
}
for (const_nodes_iterator B = this->NodesMap.begin(),
E = this->NodesMap.end(); B != E; ++B) {
const Node& N = B->second;
- unsigned MaxWeight = 0;
+ int MaxWeight = -1024;
// Ignore the root node.
if (!N.ToolPtr)
for (Node::const_iterator EB = N.EdgesBegin(), EE = N.EdgesEnd();
EB != EE; ++EB) {
- unsigned EdgeWeight = (*EB)->Weight(Dummy);
+ int EdgeWeight = (*EB)->Weight(Dummy);
if (EdgeWeight > MaxWeight) {
MaxWeight = EdgeWeight;
}
Node* Root = getNode("root");
if (Root == 0)
- return -1;
+ return 1;
Q.push(Root);
EB != EE; ++EB) {
Node* B = getNode((*EB)->ToolName());
if (B == 0)
- return -1;
+ return 1;
B->DecrInEdges();
if (B->HasNoInEdges())
// Check that output/input language names match.
ret = this->CheckLanguageNames();
if (ret < 0)
- return -1;
+ return 1;
errs += ret;
// Check for multiple default edges.
ret = this->CheckMultipleDefaultEdges();
if (ret < 0)
- return -1;
+ return 1;
errs += ret;
// Check for cycles.
ret = this->CheckCycles();
if (ret < 0)
- return -1;
+ return 1;
errs += ret;
return errs;
// Code related to graph visualization.
+namespace {
+
+std::string SquashStrArray (const char** StrArr) {
+ std::string ret;
+
+ for (; *StrArr; ++StrArr) {
+ if (*(StrArr + 1)) {
+ ret += *StrArr;
+ ret += ", ";
+ }
+ else {
+ ret += *StrArr;
+ }
+ }
+
+ return ret;
+}
+
+} // End anonymous namespace.
+
namespace llvm {
template <>
struct DOTGraphTraits<llvmc::CompilationGraph*>
if (N->ToolPtr->IsJoin())
return N->Name() + "\n (join" +
(N->HasChildren() ? ")"
- : std::string(": ") + N->ToolPtr->OutputLanguage() + ')');
+ : std::string(": ") +
+ SquashStrArray(N->ToolPtr->OutputLanguages()) + ')');
else
return N->Name();
else
template<typename EdgeIter>
static std::string getEdgeSourceLabel(const Node* N, EdgeIter I) {
if (N->ToolPtr) {
- return N->ToolPtr->OutputLanguage();
+ return SquashStrArray(N->ToolPtr->OutputLanguages());
}
else {
- const char** InLangs = I->ToolPtr->InputLanguages();
- std::string ret;
-
- for (; *InLangs; ++InLangs) {
- if (*(InLangs + 1)) {
- ret += *InLangs;
- ret += ", ";
- }
- else {
- ret += *InLangs;
- }
- }
-
- return ret;
+ return SquashStrArray(I->ToolPtr->InputLanguages());
}
}
};
-}
+} // End namespace llvm
int CompilationGraph::writeGraph(const std::string& OutputFilename) {
std::string ErrorInfo;
}
else {
PrintError("Error opening file '" + OutputFilename + "' for writing!");
- return -1;
+ return 1;
}
return 0;