[PATCH] Add the ability to set an output file.
Manuel Klimek
klimek at google.com
Fri Nov 15 02:29:49 PST 2013
- Add a test.
Hi pcc,
http://llvm-reviews.chandlerc.com/D2184
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D2184?vs=5562&id=5565#toc
Files:
clang-query/Query.cpp
clang-query/Query.h
clang-query/QueryParser.cpp
clang-query/QuerySession.h
clang-query/tool/ClangQuery.cpp
test/clang-query/output-file.c
Index: clang-query/Query.cpp
===================================================================
--- clang-query/Query.cpp
+++ clang-query/Query.cpp
@@ -40,7 +40,10 @@
" set output (diag|print|dump) "
"Set whether to print bindings as diagnostics,\n"
" "
- "AST pretty prints or AST dumps.\n\n";
+ "AST pretty prints or AST dumps.\n"
+ " set output-file <file-name> "
+ "Set an optional output file to write to.\n"
+ "\n";
return true;
}
Index: clang-query/Query.h
===================================================================
--- clang-query/Query.h
+++ clang-query/Query.h
@@ -30,7 +30,8 @@
QK_Help,
QK_Match,
QK_SetBool,
- QK_SetOutputKind
+ QK_SetOutputKind,
+ QK_SetString
};
class QuerySession;
@@ -96,6 +97,10 @@
static const QueryKind value = QK_SetOutputKind;
};
+template <> struct SetQueryKind<std::string> {
+ static const QueryKind value = QK_SetString;
+};
+
/// Query for "set VAR VALUE".
template <typename T> struct SetQuery : Query {
SetQuery(T QuerySession::*Var, T Value)
Index: clang-query/QueryParser.cpp
===================================================================
--- clang-query/QueryParser.cpp
+++ clang-query/QueryParser.cpp
@@ -57,6 +57,11 @@
return new SetQuery<bool>(Var, Value);
}
+static QueryRef ParseSetString(std::string QuerySession::*Var,
+ StringRef ValStr) {
+ return new SetQuery<std::string>(Var, ValStr);
+}
+
static QueryRef ParseSetOutputKind(StringRef ValStr) {
unsigned OutKind = StringSwitch<unsigned>(ValStr)
.Case("diag", OK_Diag)
@@ -89,7 +94,8 @@
enum ParsedQueryVariable {
PQV_Invalid,
PQV_Output,
- PQV_BindRoot
+ PQV_BindRoot,
+ PQV_SetOutputFile
};
QueryRef ParseQuery(StringRef Line) {
@@ -133,6 +139,7 @@
ParsedQueryVariable Var = StringSwitch<ParsedQueryVariable>(VarStr)
.Case("output", PQV_Output)
.Case("bind-root", PQV_BindRoot)
+ .Case("output-file", PQV_SetOutputFile)
.Default(PQV_Invalid);
if (Var == PQV_Invalid)
return new InvalidQuery("unknown variable: '" + VarStr + "'");
@@ -149,6 +156,9 @@
case PQV_BindRoot:
Q = ParseSetBool(&QuerySession::BindRoot, ValStr);
break;
+ case PQV_SetOutputFile:
+ Q = ParseSetString(&QuerySession::OutputFileName, ValStr);
+ break;
case PQV_Invalid:
llvm_unreachable("Invalid query kind");
}
Index: clang-query/QuerySession.h
===================================================================
--- clang-query/QuerySession.h
+++ clang-query/QuerySession.h
@@ -25,9 +25,33 @@
QuerySession(llvm::ArrayRef<ASTUnit *> ASTs)
: ASTs(ASTs), OutKind(OK_Diag), BindRoot(true) {}
+ bool run(QueryRef Query, llvm::raw_ostream &OS) {
+ if (OutputFileName.empty()) {
+ // If there is no output file, use the output stream directly, so
+ // we get colors if the stream supports it.
+ return Query->run(OS, *this);
+ }
+ std::string O;
+ llvm::raw_string_ostream SS(O);
+ bool Result = Query->run(SS, *this);
+ SS.flush();
+ OS << O;
+ std::string ErrorInfo;
+ llvm::raw_fd_ostream FS(OutputFileName.c_str(), ErrorInfo,
+ llvm::sys::fs::F_Append);
+ if (!ErrorInfo.empty()) {
+ OS << "\nWarning: Could not open output file \"" << OutputFileName
+ << "\".\n";
+ } else {
+ FS << O;
+ }
+ return Result;
+ }
+
llvm::ArrayRef<ASTUnit *> ASTs;
OutputKind OutKind;
bool BindRoot;
+ std::string OutputFileName;
};
} // namespace query
Index: clang-query/tool/ClangQuery.cpp
===================================================================
--- clang-query/tool/ClangQuery.cpp
+++ clang-query/tool/ClangQuery.cpp
@@ -104,7 +104,7 @@
E = Commands.end();
I != E; ++I) {
QueryRef Q = ParseQuery(I->c_str());
- if (!Q->run(llvm::outs(), QS))
+ if (!QS.run(Q, llvm::outs()))
return 1;
}
} else if (!CommandFiles.empty()) {
@@ -121,7 +121,7 @@
std::getline(Input, Line);
QueryRef Q = ParseQuery(Line.c_str());
- if (!Q->run(llvm::outs(), QS))
+ if (!QS.run(Q, llvm::outs()))
return 1;
}
}
@@ -143,7 +143,7 @@
history(Hist, &Event, H_ENTER, Line);
QueryRef Q = ParseQuery(Line);
- Q->run(llvm::outs(), QS);
+ QS.run(Q, llvm::outs());
}
history_end(Hist);
Index: test/clang-query/output-file.c
===================================================================
--- /dev/null
+++ test/clang-query/output-file.c
@@ -0,0 +1,6 @@
+// RUN: clang-query -c "set output-file %t" -c "match functionDecl()" %s --
+// RUN: FileCheck %s < %t
+// REQUIRES: libedit
+
+// CHECK: output-file.c:6:1: note: "root" binds here
+void foo(void) {}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2184.2.patch
Type: text/x-patch
Size: 4970 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131115/0e5c3bc2/attachment.bin>
More information about the cfe-commits
mailing list