llvm-project/clang-tools-extra/pp-trace/PPTrace.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

169 lines
5.3 KiB
C++
Raw Normal View History

//===--- tools/pp-trace/PPTrace.cpp - Clang preprocessor tracer -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements pp-trace, a tool for displaying a textual trace
// of the Clang preprocessor activity. It's based on a derivation of the
// PPCallbacks class, that once registerd with Clang, receives callback calls
// to its virtual members, and outputs the information passed to the callbacks
// in a high-level YAML format.
//
// The pp-trace tool also serves as the basis for a test of the PPCallbacks
// mechanism.
//
// The pp-trace tool supports the following general command line format:
//
// pp-trace [options] file... [-- compiler options]
//
// Basically you put the pp-trace options first, then the source file or files,
// and then -- followed by any options you want to pass to the compiler.
//
//===----------------------------------------------------------------------===//
#include "PPCallbacksTracker.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/Execution.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/GlobPattern.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include <string>
#include <vector>
using namespace llvm;
namespace clang {
namespace pp_trace {
static cl::OptionCategory Cat("pp-trace options");
static cl::opt<std::string> Callbacks(
"callbacks", cl::init("*"),
cl::desc("Comma-separated list of globs describing the list of callbacks "
"to output. Globs are processed in order of appearance. Globs "
"with the '-' prefix remove callbacks from the set. e.g. "
"'*,-Macro*'."),
cl::cat(Cat));
static cl::opt<std::string> OutputFileName(
"output", cl::init("-"),
cl::desc("Output trace to the given file name or '-' for stdout."),
cl::cat(Cat));
[[noreturn]] static void error(Twine Message) {
WithColor::error() << Message << '\n';
exit(1);
}
namespace {
class PPTraceAction : public ASTFrontendAction {
public:
PPTraceAction(const FilterType &Filters, raw_ostream &OS)
: Filters(Filters), OS(OS) {}
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override {
Preprocessor &PP = CI.getPreprocessor();
PP.addPPCallbacks(
std::make_unique<PPCallbacksTracker>(Filters, CallbackCalls, PP));
return std::make_unique<ASTConsumer>();
}
void EndSourceFileAction() override {
OS << "---\n";
for (const CallbackCall &Callback : CallbackCalls) {
OS << "- Callback: " << Callback.Name << "\n";
for (const Argument &Arg : Callback.Arguments)
OS << " " << Arg.Name << ": " << Arg.Value << "\n";
}
OS << "...\n";
CallbackCalls.clear();
}
private:
const FilterType &Filters;
raw_ostream &OS;
std::vector<CallbackCall> CallbackCalls;
};
class PPTraceFrontendActionFactory : public tooling::FrontendActionFactory {
public:
PPTraceFrontendActionFactory(const FilterType &Filters, raw_ostream &OS)
: Filters(Filters), OS(OS) {}
std::unique_ptr<FrontendAction> create() override {
return std::make_unique<PPTraceAction>(Filters, OS);
}
private:
const FilterType &Filters;
raw_ostream &OS;
};
} // namespace
} // namespace pp_trace
} // namespace clang
int main(int argc, const char **argv) {
using namespace clang::pp_trace;
InitLLVM X(argc, argv);
auto OptionsParser = clang::tooling::CommonOptionsParser::create(
argc, argv, Cat, llvm::cl::ZeroOrMore);
if (!OptionsParser)
error(toString(OptionsParser.takeError()));
// Parse the IgnoreCallbacks list into strings.
SmallVector<StringRef, 32> Patterns;
FilterType Filters;
StringRef(Callbacks).split(Patterns, ",",
/*MaxSplit=*/-1, /*KeepEmpty=*/false);
for (StringRef Pattern : Patterns) {
Pattern = Pattern.trim();
bool Enabled = !Pattern.consume_front("-");
Expected<GlobPattern> Pat = GlobPattern::create(Pattern);
if (Pat)
Filters.emplace_back(std::move(*Pat), Enabled);
else
error(toString(Pat.takeError()));
}
// Create the tool and run the compilation.
clang::tooling::ClangTool Tool(OptionsParser->getCompilations(),
OptionsParser->getSourcePathList());
std::error_code EC;
[SystemZ][z/OS][Windows] Add new OF_TextWithCRLF flag and use this flag instead of OF_Text Problem: On SystemZ we need to open text files in text mode. On Windows, files opened in text mode adds a CRLF '\r\n' which may not be desirable. Solution: This patch adds two new flags - OF_CRLF which indicates that CRLF translation is used. - OF_TextWithCRLF = OF_Text | OF_CRLF indicates that the file is text and uses CRLF translation. Developers should now use either the OF_Text or OF_TextWithCRLF for text files and OF_None for binary files. If the developer doesn't want carriage returns on Windows, they should use OF_Text, if they do want carriage returns on Windows, they should use OF_TextWithCRLF. So this is the behaviour per platform with my patch: z/OS: OF_None: open in binary mode OF_Text : open in text mode OF_TextWithCRLF: open in text mode Windows: OF_None: open file with no carriage return OF_Text: open file with no carriage return OF_TextWithCRLF: open file with carriage return The Major change is in llvm/lib/Support/Windows/Path.inc to only set text mode if the OF_CRLF is set. ``` if (Flags & OF_CRLF) CrtOpenFlags |= _O_TEXT; ``` These following files are the ones that still use OF_Text which I left unchanged. I modified all these except raw_ostream.cpp in recent patches so I know these were previously in Binary mode on Windows. ./llvm/lib/Support/raw_ostream.cpp ./llvm/lib/TableGen/Main.cpp ./llvm/tools/dsymutil/DwarfLinkerForBinary.cpp ./llvm/unittests/Support/Path.cpp ./clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp ./clang/lib/Frontend/CompilerInstance.cpp ./clang/lib/Driver/Driver.cpp ./clang/lib/Driver/ToolChains/Clang.cpp Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D99426
2021-04-06 19:22:41 +08:00
llvm::ToolOutputFile Out(OutputFileName, EC, llvm::sys::fs::OF_TextWithCRLF);
if (EC)
error(EC.message());
PPTraceFrontendActionFactory Factory(Filters, Out.os());
int HadErrors = Tool.run(&Factory);
// If we had errors, exit early.
if (HadErrors)
return HadErrors;
Out.keep();
return 0;
}