aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Driver/ASTConsumers.h4
-rw-r--r--Driver/HTMLPrint.cpp15
-rw-r--r--Driver/clang.cpp11
-rw-r--r--include/clang/Rewrite/HTMLRewrite.h8
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp45
5 files changed, 69 insertions, 14 deletions
diff --git a/Driver/ASTConsumers.h b/Driver/ASTConsumers.h
index 91ee8fbf93..6054fdf443 100644
--- a/Driver/ASTConsumers.h
+++ b/Driver/ASTConsumers.h
@@ -27,6 +27,7 @@ class ASTConsumer;
class Diagnostic;
class FileManager;
struct LangOptions;
+class Preprocessor;
ASTConsumer *CreateASTPrinter(std::ostream* OS = NULL);
@@ -57,7 +58,8 @@ ASTConsumer *CreateCodeRewriterTest(const std::string& InFile,
Diagnostic &Diags,
const LangOptions &LOpts);
- ASTConsumer* CreateHTMLPrinter(const std::string &OutFile, Diagnostic &D);
+ASTConsumer* CreateHTMLPrinter(const std::string &OutFile, Diagnostic &D,
+ Preprocessor *PP);
ASTConsumer *CreateSerializationTest(Diagnostic &Diags,
FileManager& FMgr,
diff --git a/Driver/HTMLPrint.cpp b/Driver/HTMLPrint.cpp
index 44cd6244ec..cb32afd817 100644
--- a/Driver/HTMLPrint.cpp
+++ b/Driver/HTMLPrint.cpp
@@ -30,9 +30,10 @@ namespace {
Rewriter R;
std::string OutFilename;
Diagnostic &Diags;
+ Preprocessor *PP;
public:
- HTMLPrinter(const std::string &OutFile, Diagnostic &D)
- : OutFilename(OutFile), Diags(D) {}
+ HTMLPrinter(const std::string &OutFile, Diagnostic &D, Preprocessor *pp)
+ : OutFilename(OutFile), Diags(D), PP(pp) {}
virtual ~HTMLPrinter();
void Initialize(ASTContext &context);
@@ -40,8 +41,8 @@ namespace {
}
ASTConsumer* clang::CreateHTMLPrinter(const std::string &OutFile,
- Diagnostic &D) {
- return new HTMLPrinter(OutFile, D);
+ Diagnostic &D, Preprocessor *PP) {
+ return new HTMLPrinter(OutFile, D, PP);
}
void HTMLPrinter::Initialize(ASTContext &context) {
@@ -58,6 +59,12 @@ HTMLPrinter::~HTMLPrinter() {
html::AddLineNumbers(R, FileID);
html::AddHeaderFooterInternalBuiltinCSS(R, FileID);
+ // If we have a preprocessor, relex the file and syntax hilight. We might not
+ // have a preprocessor if we come from a deserialized AST file, for example.
+ if (PP)
+ html::SyntaxHighlight(R, FileID, *PP);
+
+
// Open the output.
FILE *OutputFILE;
if (OutFilename.empty() || OutFilename == "-")
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index 09140c942e..a9ae98e555 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -1033,6 +1033,7 @@ static void ParseFile(Preprocessor &PP, MinimalAction *PA){
static ASTConsumer* CreateASTConsumer(const std::string& InFile,
Diagnostic& Diag, FileManager& FileMgr,
const LangOptions& LangOpts,
+ Preprocessor *PP,
llvm::Module *&DestModule) {
switch (ProgAction) {
default:
@@ -1048,7 +1049,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
return CreateASTViewer();
case EmitHTML:
- return CreateHTMLPrinter(OutputFile, Diag);
+ return CreateHTMLPrinter(OutputFile, Diag, PP);
case ParseCFGDump:
case ParseCFGView:
@@ -1099,10 +1100,8 @@ static void ProcessInputFile(Preprocessor &PP, const std::string &InFile) {
switch (ProgAction) {
default:
- Consumer = CreateASTConsumer(InFile,
- PP.getDiagnostics(),
- PP.getFileManager(),
- PP.getLangOptions(),
+ Consumer = CreateASTConsumer(InFile, PP.getDiagnostics(),
+ PP.getFileManager(), PP.getLangOptions(), &PP,
CodeGenModule);
if (!Consumer) {
@@ -1242,7 +1241,7 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
// translation unit, rather than InFile.
llvm::Module *DestModule;
llvm::OwningPtr<ASTConsumer>
- Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOpts(),
+ Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOpts(), 0,
DestModule));
if (!Consumer) {
diff --git a/include/clang/Rewrite/HTMLRewrite.h b/include/clang/Rewrite/HTMLRewrite.h
index d5bdc89070..520030fcdf 100644
--- a/include/clang/Rewrite/HTMLRewrite.h
+++ b/include/clang/Rewrite/HTMLRewrite.h
@@ -21,6 +21,7 @@
namespace clang {
class Rewriter;
+class Preprocessor;
namespace html {
@@ -42,7 +43,12 @@ namespace html {
void AddLineNumbers(Rewriter& R, unsigned FileID);
void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID);
-
+
+ /// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
+ /// information about keywords, macro expansions etc. This uses the macro
+ /// table state from the end of the file, so it won't be perfectly perfect,
+ /// but it will be reasonably close.
+ void SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP);
} // end html namespace
} // end clang namespace
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index 9ed5953c60..e35664f546 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -14,11 +14,11 @@
#include "clang/Rewrite/Rewriter.h"
#include "clang/Rewrite/HTMLRewrite.h"
+#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/MemoryBuffer.h"
#include <sstream>
-
using namespace clang;
void html::EscapeText(Rewriter& R, unsigned FileID,
@@ -176,7 +176,6 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID) {
SourceLocation EndLoc = SourceLocation::getFileLoc(FileID, FileEnd-FileStart);
// Generate header
-
R.InsertCStrBefore(StartLoc,
"<html>\n<head>\n"
"<style type=\"text/css\">\n"
@@ -186,6 +185,7 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID) {
" .code { border-spacing:0px; width:100%; }\n"
" .code { font-family: \"Andale Mono\", monospace; font-size:10pt }\n"
" .code { line-height: 1.2em }\n"
+ " .comment { color:#A0A0A0 }\n"
" .num { width:2.5em; padding-right:2ex; background-color:#eeeeee }\n"
" .num { text-align:right; font-size: smaller }\n"
" .num { color:#444444 }\n"
@@ -217,3 +217,44 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID) {
R.InsertCStrAfter(EndLoc, "</body></html>\n");
}
+
+/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
+/// information about keywords, macro expansions etc. This uses the macro
+/// table state from the end of the file, so it won't be perfectly perfect,
+/// but it will be reasonably close.
+void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) {
+ RewriteBuffer &RB = R.getEditBuffer(FileID);
+
+ // Inform the preprocessor that we want to retain comments as tokens, so we
+ // can highlight them.
+ PP.SetCommentRetentionState(true, false);
+
+ // Start parsing the specified input file.
+ PP.EnterMainSourceFile();
+
+ // Lex all the tokens.
+ const SourceManager &SourceMgr = PP.getSourceManager();
+ Token Tok;
+ do {
+ PP.Lex(Tok);
+ // Ignore tokens whose logical location was not the main file.
+ SourceLocation LLoc = SourceMgr.getLogicalLoc(Tok.getLocation());
+ std::pair<unsigned, unsigned> LLocInfo =
+ SourceMgr.getDecomposedFileLoc(LLoc);
+
+ if (LLocInfo.first != FileID)
+ continue;
+
+ unsigned TokOffs = LLocInfo.second;
+ unsigned TokLen = Tok.getLength();
+ switch (Tok.getKind()) {
+ default: break;
+ case tok::comment:
+ RB.InsertTextAfter(TokOffs, "<span class='comment'>",
+ strlen("<span class='comment'>"));
+ RB.InsertTextBefore(TokOffs+TokLen, "</span>", strlen("</span>"));
+ break;
+ }
+
+ } while (Tok.isNot(tok::eof));
+}