[llvm-commits] [llvm] r51732 - in /llvm/trunk: tools/llvmc2/AutoGenerated.cpp utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Thu May 29 23:12:24 PDT 2008


Author: foldr
Date: Fri May 30 01:12:24 2008
New Revision: 51732

URL: http://llvm.org/viewvc/llvm-project?rev=51732&view=rev
Log:
Add support for user-provided hooks and environment variable reads to the cmd_line tool property.

Used like this: (cmd_line "$CALL(MyHook) --option -o $ENV(VARIABLE) $CALL(AnotherHook)")
Also works with case expressions.

Hook declarations are auto-generated, the definitions should be provided by the user
(just drop a .cpp file in the tools/llvmc2 directory).

Hooks should live in the "hooks" namespace and have type std::string hooks::Hook(void).

Modified:
    llvm/trunk/tools/llvmc2/AutoGenerated.cpp
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Modified: llvm/trunk/tools/llvmc2/AutoGenerated.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/AutoGenerated.cpp?rev=51732&r1=51731&r2=51732&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/AutoGenerated.cpp (original)
+++ llvm/trunk/tools/llvmc2/AutoGenerated.cpp Fri May 30 01:12:24 2008
@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CommandLine.h"
 
+#include <cstdlib>
 #include <stdexcept>
 
 using namespace llvm;

Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=51732&r1=51731&r2=51732&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Fri May 30 01:12:24 2008
@@ -845,12 +845,32 @@
   O << Indent2 << "}\n";
 }
 
+/// SubstituteSpecialCommands - Perform string substitution for $CALL
+/// and $ENV. Helper function used by EmitCmdLineVecFill().
+std::string SubstituteSpecialCommands(const std::string& cmd) {
+ if (cmd.find("$CALL(") == 0) {
+   if (cmd.size() == 6)
+     throw std::string("$CALL invocation: empty argument list!");
+   return std::string("hooks::") + (cmd.c_str() + 6) + "()";
+ }
+ else if (cmd.find("$ENV(") == 0) {
+   if (cmd.size() == 5)
+     throw std::string("$ENV invocation: empty argument list!");
+   return std::string("std::getenv(\"") + (cmd.c_str() + 5) + "\")";
+ }
+ else {
+   throw "Unknown special command: " + cmd;
+ }
+}
+
+/// EmitCmdLineVecFill - Emit code that fills in the command line
+/// vector. Helper function used by EmitGenerateActionMethod().
 void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
                         bool Version, const char* IndentLevel,
                         std::ostream& O) {
   StrVector StrVec;
-  SplitString(InitPtrToString(CmdLine), StrVec);
-  if (InitPtrToString(CmdLine).empty())
+  SplitString(InitPtrToString(CmdLine), StrVec, ") ");
+  if (StrVec.empty())
     throw "Tool " + ToolName + " has empty command line!";
 
   StrVector::const_iterator I = StrVec.begin();
@@ -858,25 +878,36 @@
   for (StrVector::const_iterator E = StrVec.end(); I != E; ++I) {
     const std::string& cmd = *I;
     O << IndentLevel;
-    if (cmd == "$INFILE") {
-      if (Version)
-        O << "for (PathVector::const_iterator B = inFiles.begin()"
-          << ", E = inFiles.end();\n"
-          << IndentLevel << "B != E; ++B)\n"
-          << IndentLevel << Indent1 << "vec.push_back(B->toString());\n";
-      else
-        O << "vec.push_back(inFile.toString());\n";
-    }
-    else if (cmd == "$OUTFILE") {
-      O << "vec.push_back(outFile.toString());\n";
+    if (cmd.at(0) == '$') {
+      if (cmd == "$INFILE") {
+        if (Version)
+          O << "for (PathVector::const_iterator B = inFiles.begin()"
+            << ", E = inFiles.end();\n"
+            << IndentLevel << "B != E; ++B)\n"
+            << IndentLevel << Indent1 << "vec.push_back(B->toString());\n";
+        else
+          O << "vec.push_back(inFile.toString());\n";
+      }
+      else if (cmd == "$OUTFILE") {
+        O << "vec.push_back(outFile.toString());\n";
+      }
+      else {
+        O << "vec.push_back(" << SubstituteSpecialCommands(cmd) << ");\n";
+      }
     }
     else {
       O << "vec.push_back(\"" << cmd << "\");\n";
     }
   }
-  O << IndentLevel << "ret = Action(\"" << StrVec.at(0) << "\", vec);\n";
+  O << IndentLevel << "ret = Action("
+    << ((StrVec[0][0] == '$') ? SubstituteSpecialCommands(StrVec[0])
+        : "\"" + StrVec[0] + "\"")
+    << ", vec);\n";
 }
 
+/// EmitCmdLineVecFillCallback - A function object wrapper around
+/// EmitCmdLineVecFill(). Used by EmitGenerateActionMethod() as an
+/// argument to EmitCaseConstructHandler().
 class EmitCmdLineVecFillCallback {
   bool Version;
   const std::string& ToolName;
@@ -1150,7 +1181,8 @@
   }
 }
 
-// Helper function passed to EmitCaseConstructHandler by EmitEdgeClass.
+/// IncDecWeight - Helper function passed to EmitCaseConstructHandler()
+/// by EmitEdgeClass().
 void IncDecWeight (const Init* i, const char* IndentLevel,
                    std::ostream& O) {
   const DagInit& d = InitPtrToDagInitRef(i);
@@ -1192,7 +1224,7 @@
     << Indent1 << "};\n\n};\n\n";
 }
 
-// Emit Edge* classes that represent graph edges.
+/// EmitEdgeClasses - Emit Edge* classes that represent graph edges.
 void EmitEdgeClasses (Record* CompilationGraph,
                       const GlobalOptionDescriptions& OptDescs,
                       std::ostream& O) {
@@ -1256,6 +1288,68 @@
   O << "}\n\n";
 }
 
+/// ExtractHookNames - Extract the hook names from all instances of
+/// $CALL(HookName) in the provided command line string. Helper
+/// function used by FillInHookNames().
+void ExtractHookNames(const Init* CmdLine, StrVector& HookNames) {
+  StrVector cmds;
+  llvm::SplitString(InitPtrToString(CmdLine), cmds, ") ");
+  for (StrVector::const_iterator B = cmds.begin(), E = cmds.end();
+       B != E; ++B) {
+    const std::string& cmd = *B;
+    if (cmd.find("$CALL(") == 0) {
+      if (cmd.size() == 6)
+        throw std::string("$CALL invocation: empty argument list!");
+      HookNames.push_back(std::string(cmd.c_str() + 6));
+    }
+  }
+}
+
+/// FillInHookNames - Actually extract the hook names from all command
+/// line strings. Helper function used by EmitHookDeclarations().
+void FillInHookNames(const ToolPropertiesList& TPList,
+                     StrVector& HookNames) {
+  for (ToolPropertiesList::const_iterator B = TPList.begin(),
+         E = TPList.end(); B != E; ++B) {
+    const ToolProperties& P = *(*B);
+    if (!P.CmdLine)
+      continue;
+    if (typeid(*P.CmdLine) == typeid(StringInit)) {
+      // This is a string.
+      ExtractHookNames(P.CmdLine, HookNames);
+    }
+    else {
+      // This is a 'case' construct.
+      const DagInit& d = InitPtrToDagInitRef(P.CmdLine);
+      bool even = false;
+      for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end();
+           B != E; ++B) {
+        if (even)
+          ExtractHookNames(*B, HookNames);
+        even = !even;
+      }
+    }
+  }
+}
+
+/// EmitHookDeclarations - Parse CmdLine fields of all the tool
+/// property records and emit hook function declaration for each
+/// instance of $CALL(HookName).
+void EmitHookDeclarations(const ToolPropertiesList& ToolProps,
+                          std::ostream& O) {
+  StrVector HookNames;
+  FillInHookNames(ToolProps, HookNames);
+  if (HookNames.empty())
+    return;
+  std::sort(HookNames.begin(), HookNames.end());
+  StrVector::const_iterator E = std::unique(HookNames.begin(), HookNames.end());
+
+  O << "namespace hooks {\n";
+  for (StrVector::const_iterator B = HookNames.begin(); B != E; ++B)
+    O << Indent1 << "std::string " << *B << "();\n";
+
+  O << "}\n\n";
+}
 
 // End of anonymous namespace
 }
@@ -1279,6 +1373,9 @@
   // Emit global option registration code.
   EmitOptionDescriptions(opt_descs, O);
 
+  // Emit hook declarations.
+  EmitHookDeclarations(tool_props, O);
+
   // Emit PopulateLanguageMap() function
   // (a language map maps from file extensions to language names).
   EmitPopulateLanguageMap(Records, O);





More information about the llvm-commits mailing list