10621cb2eSAlp Toker //===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
20621cb2eSAlp Toker //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60621cb2eSAlp Toker //
70621cb2eSAlp Toker //===----------------------------------------------------------------------===//
80621cb2eSAlp Toker //
90621cb2eSAlp Toker // Pretty-printing of source code to HTML.
100621cb2eSAlp Toker //
110621cb2eSAlp Toker //===----------------------------------------------------------------------===//
120621cb2eSAlp Toker
130621cb2eSAlp Toker #include "clang/AST/ASTConsumer.h"
140621cb2eSAlp Toker #include "clang/AST/ASTContext.h"
150621cb2eSAlp Toker #include "clang/AST/Decl.h"
160621cb2eSAlp Toker #include "clang/Basic/Diagnostic.h"
170621cb2eSAlp Toker #include "clang/Basic/FileManager.h"
180621cb2eSAlp Toker #include "clang/Basic/SourceManager.h"
190621cb2eSAlp Toker #include "clang/Lex/Preprocessor.h"
200621cb2eSAlp Toker #include "clang/Rewrite/Core/HTMLRewrite.h"
210621cb2eSAlp Toker #include "clang/Rewrite/Core/Rewriter.h"
229670f847SMehdi Amini #include "clang/Rewrite/Frontend/ASTConsumers.h"
230621cb2eSAlp Toker #include "llvm/Support/raw_ostream.h"
240621cb2eSAlp Toker using namespace clang;
250621cb2eSAlp Toker
260621cb2eSAlp Toker //===----------------------------------------------------------------------===//
270621cb2eSAlp Toker // Functional HTML pretty-printing.
280621cb2eSAlp Toker //===----------------------------------------------------------------------===//
290621cb2eSAlp Toker
300621cb2eSAlp Toker namespace {
310621cb2eSAlp Toker class HTMLPrinter : public ASTConsumer {
320621cb2eSAlp Toker Rewriter R;
3303f8907fSPeter Collingbourne std::unique_ptr<raw_ostream> Out;
340621cb2eSAlp Toker Preprocessor &PP;
350621cb2eSAlp Toker bool SyntaxHighlight, HighlightMacros;
360621cb2eSAlp Toker
370621cb2eSAlp Toker public:
HTMLPrinter(std::unique_ptr<raw_ostream> OS,Preprocessor & pp,bool _SyntaxHighlight,bool _HighlightMacros)3803f8907fSPeter Collingbourne HTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &pp,
390621cb2eSAlp Toker bool _SyntaxHighlight, bool _HighlightMacros)
4003f8907fSPeter Collingbourne : Out(std::move(OS)), PP(pp), SyntaxHighlight(_SyntaxHighlight),
410621cb2eSAlp Toker HighlightMacros(_HighlightMacros) {}
420621cb2eSAlp Toker
430621cb2eSAlp Toker void Initialize(ASTContext &context) override;
440621cb2eSAlp Toker void HandleTranslationUnit(ASTContext &Ctx) override;
450621cb2eSAlp Toker };
46ab9db510SAlexander Kornienko }
470621cb2eSAlp Toker
4803f8907fSPeter Collingbourne std::unique_ptr<ASTConsumer>
CreateHTMLPrinter(std::unique_ptr<raw_ostream> OS,Preprocessor & PP,bool SyntaxHighlight,bool HighlightMacros)4903f8907fSPeter Collingbourne clang::CreateHTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &PP,
5003f8907fSPeter Collingbourne bool SyntaxHighlight, bool HighlightMacros) {
512b3d49b6SJonas Devlieghere return std::make_unique<HTMLPrinter>(std::move(OS), PP, SyntaxHighlight,
526beb6aa8SDavid Blaikie HighlightMacros);
530621cb2eSAlp Toker }
540621cb2eSAlp Toker
Initialize(ASTContext & context)550621cb2eSAlp Toker void HTMLPrinter::Initialize(ASTContext &context) {
560621cb2eSAlp Toker R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
570621cb2eSAlp Toker }
580621cb2eSAlp Toker
HandleTranslationUnit(ASTContext & Ctx)590621cb2eSAlp Toker void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
600621cb2eSAlp Toker if (PP.getDiagnostics().hasErrorOccurred())
610621cb2eSAlp Toker return;
620621cb2eSAlp Toker
630621cb2eSAlp Toker // Format the file.
640621cb2eSAlp Toker FileID FID = R.getSourceMgr().getMainFileID();
650621cb2eSAlp Toker const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
6699d1b295SMehdi Amini StringRef Name;
670621cb2eSAlp Toker // In some cases, in particular the case where the input is from stdin,
680621cb2eSAlp Toker // there is no entry. Fall back to the memory buffer for a name in those
690621cb2eSAlp Toker // cases.
700621cb2eSAlp Toker if (Entry)
710621cb2eSAlp Toker Name = Entry->getName();
720621cb2eSAlp Toker else
73*63af2422SDuncan P. N. Exon Smith Name = R.getSourceMgr().getBufferOrFake(FID).getBufferIdentifier();
740621cb2eSAlp Toker
750621cb2eSAlp Toker html::AddLineNumbers(R, FID);
760621cb2eSAlp Toker html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name);
770621cb2eSAlp Toker
780621cb2eSAlp Toker // If we have a preprocessor, relex the file and syntax highlight.
790621cb2eSAlp Toker // We might not have a preprocessor if we come from a deserialized AST file,
800621cb2eSAlp Toker // for example.
810621cb2eSAlp Toker
820621cb2eSAlp Toker if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP);
830621cb2eSAlp Toker if (HighlightMacros) html::HighlightMacros(R, FID, PP);
840621cb2eSAlp Toker html::EscapeText(R, FID, false, true);
850621cb2eSAlp Toker
860621cb2eSAlp Toker // Emit the HTML.
870621cb2eSAlp Toker const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
8852525730SSerge Pavlov std::unique_ptr<char[]> Buffer(new char[RewriteBuf.size()]);
8952525730SSerge Pavlov std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer.get());
9052525730SSerge Pavlov Out->write(Buffer.get(), RewriteBuf.size());
910621cb2eSAlp Toker }
92