aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-03-19 07:53:42 +0000
committerTed Kremenek <kremenek@apple.com>2008-03-19 07:53:42 +0000
commit13e479b2b74771738a5e5c5dc1c270416924b126 (patch)
treeaaae19db0db5691858c6017e4ee56e77317fb53d
parent0fdf06e5eef80ce56ce6499ba662453919b95af1 (diff)
Initial experimentation with adding boxed "annotations" to HTMLized source.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48540 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Driver/ASTConsumers.h2
-rw-r--r--Driver/HTMLPrint.cpp167
-rw-r--r--Driver/clang.cpp6
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp9
4 files changed, 175 insertions, 9 deletions
diff --git a/Driver/ASTConsumers.h b/Driver/ASTConsumers.h
index fd9651ded2..9c8ae4064c 100644
--- a/Driver/ASTConsumers.h
+++ b/Driver/ASTConsumers.h
@@ -54,7 +54,7 @@ ASTConsumer *CreateCodeRewriterTest(const std::string& InFile,
const LangOptions &LOpts);
ASTConsumer* CreateHTMLPrinter();
-
+ASTConsumer* CreateHTMLTest();
ASTConsumer *CreateSerializationTest(Diagnostic &Diags,
FileManager& FMgr,
diff --git a/Driver/HTMLPrint.cpp b/Driver/HTMLPrint.cpp
index a513bf975d..1108bc3bda 100644
--- a/Driver/HTMLPrint.cpp
+++ b/Driver/HTMLPrint.cpp
@@ -18,10 +18,17 @@
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/MemoryBuffer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Analysis/LocalCheckers.h"
+#include "clang/AST/CFG.h"
#include <sstream>
using namespace clang;
+//===----------------------------------------------------------------------===//
+// Functional HTML pretty-printing.
+//===----------------------------------------------------------------------===//
+
namespace {
class HTMLPrinter : public ASTConsumer {
Rewriter R;
@@ -40,14 +47,58 @@ void HTMLPrinter::Initialize(ASTContext &context) {
}
HTMLPrinter::~HTMLPrinter() {
+
unsigned FileID = R.getSourceMgr().getMainFileID();
-
- const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
- const char* FileStart = Buf->getBufferStart();
- const char* FileEnd = Buf->getBufferEnd();
- SourceLocation StartLoc = SourceLocation::getFileLoc(FileID, 0);
- SourceLocation EndLoc = SourceLocation::getFileLoc(FileID, FileEnd-FileStart);
+ html::EscapeText(R, FileID);
+ html::AddLineNumbers(R, FileID);
+ html::AddHeaderFooterInternalBuiltinCSS(R, FileID);
+ // Emit the HTML.
+
+ if (const RewriteBuffer *RewriteBuf = R.getRewriteBufferFor(FileID)) {
+ std::string S(RewriteBuf->begin(), RewriteBuf->end());
+ printf("%s\n", S.c_str());
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Other HTML pretty-printing code used to test new features.
+//===----------------------------------------------------------------------===//
+
+namespace {
+ class HTMLTest : public ASTConsumer {
+ Rewriter R;
+ ASTContext* Ctx;
+ public:
+ HTMLTest() : Ctx(NULL) {}
+ virtual ~HTMLTest();
+ virtual void HandleTopLevelDecl(Decl* D);
+
+ void Initialize(ASTContext &context);
+ void ProcessBody(Stmt* S);
+ };
+}
+
+ASTConsumer* clang::CreateHTMLTest() { return new HTMLTest(); }
+
+void HTMLTest::Initialize(ASTContext &context) {
+ Ctx = &context;
+ R.setSourceMgr(context.getSourceManager());
+}
+
+void HTMLTest::HandleTopLevelDecl(Decl* D) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (Stmt* B = FD->getBody()) {
+ SourceLocation L = B->getLocStart();
+
+ if (L.isFileID() && L.getFileID() == R.getSourceMgr().getMainFileID())
+ ProcessBody(B);
+ }
+}
+
+HTMLTest::~HTMLTest() {
+
+ unsigned FileID = R.getSourceMgr().getMainFileID();
html::EscapeText(R, FileID);
html::AddLineNumbers(R, FileID);
html::AddHeaderFooterInternalBuiltinCSS(R, FileID);
@@ -59,3 +110,107 @@ HTMLPrinter::~HTMLPrinter() {
printf("%s\n", S.c_str());
}
}
+
+namespace {
+ class HTMLDiagnostic : public DiagnosticClient {
+ Rewriter& R;
+ public:
+ HTMLDiagnostic(Rewriter& r) : R(r) {}
+ virtual void HandleDiagnostic(Diagnostic &Diags,
+ Diagnostic::Level DiagLevel,
+ FullSourceLoc Pos,
+ diag::kind ID,
+ const std::string *Strs,
+ unsigned NumStrs,
+ const SourceRange *Ranges,
+ unsigned NumRanges);
+ };
+}
+
+void HTMLTest::ProcessBody(Stmt* S) {
+ CFG* cfg = CFG::buildCFG(S);
+
+ if (!cfg)
+ return;
+
+ HTMLDiagnostic HD(R);
+ Diagnostic D(HD);
+
+ CheckDeadStores(*cfg, *Ctx, D);
+}
+
+void HTMLDiagnostic::HandleDiagnostic(Diagnostic &Diags,
+ Diagnostic::Level DiagLevel,
+ FullSourceLoc Pos,
+ diag::kind ID,
+ const std::string *Strs,
+ unsigned NumStrs,
+ const SourceRange *Ranges,
+ unsigned NumRanges) {
+
+ // For now, just draw a box above the line in question, and emit the
+ // warning.
+
+ if (!Pos.isValid())
+ return;
+
+ FullSourceLoc LPos = Pos.getLogicalLoc();
+ unsigned FileID = LPos.getLocation().getFileID();
+
+ if (FileID != LPos.getManager().getMainFileID())
+ return;
+
+
+ // Compute the column number. Rewind from the current position to the start
+ // of the line.
+
+ unsigned ColNo = LPos.getColumnNumber();
+ const char *TokLogicalPtr = LPos.getCharacterData();
+ const char *LineStart = TokLogicalPtr-ColNo;
+
+ // Ripped from TextDiagnostics::FormatDiagnostic:
+
+ std::string Msg = Diags.getDescription(ID);
+
+ for (unsigned i = 0; i < Msg.size() - 1; ++i) {
+ if (Msg[i] == '%' && isdigit(Msg[i + 1])) {
+ unsigned StrNo = Msg[i + 1] - '0';
+ Msg = std::string(Msg.begin(), Msg.begin() + i) +
+ (StrNo < NumStrs ? Strs[StrNo] : "<<<INTERNAL ERROR>>>") +
+ std::string(Msg.begin() + i + 2, Msg.end());
+ }
+ }
+
+ // Start making the div tag.
+
+ std::ostringstream os;
+
+ os << "\n<div class=\"codeline\"><div class=\"nums\">&nbsp;</div>"
+ << "<div class=\"lines\">";
+
+ for (unsigned i = 0; i < ColNo+1; ++i)
+ os << ' ';
+
+ os << "</div><span class=\"msg\">";
+
+ switch (DiagLevel) {
+ default: assert(0 && "Unknown diagnostic type!");
+ case Diagnostic::Note: os << "note: "; break;
+ case Diagnostic::Warning: os << "warning: "; break;
+ case Diagnostic::Error: os << "error: "; break;
+ case Diagnostic::Fatal: os << "fatal error: "; break;
+ break;
+ }
+
+ os << Msg; // FIXME: HTML escape "Msg"
+ os << "</span></div";
+
+ // Insert a div tag with the warning.
+
+ const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
+ const char* FileStart = Buf->getBufferStart();
+
+
+ R.InsertStrBefore(SourceLocation::getFileLoc(FileID, LineStart - FileStart),
+ os.str());
+}
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index 333ac6096a..b2852e2cd9 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -60,6 +60,7 @@ Stats("print-stats",
enum ProgActions {
RewriteTest, // Rewriter testing stuff.
+ HTMLTest, // HTML displayer testing stuff.
EmitLLVM, // Emit a .ll file.
EmitBC, // Emit a .bc file.
SerializeAST, // Emit a .ast file.
@@ -135,6 +136,8 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
"Build ASTs and emit .ast file"),
clEnumValN(RewriteTest, "rewrite-test",
"Playground for the code rewriter"),
+ clEnumValN(HTMLTest, "html-test",
+ "Playground for the HTML displayer"),
clEnumValEnd));
@@ -1002,6 +1005,9 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
case EmitHTML:
return CreateHTMLPrinter();
+ case HTMLTest:
+ return CreateHTMLTest();
+
case ParseCFGDump:
case ParseCFGView:
return CreateCFGDumper(ProgAction == ParseCFGView,
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index 9690ecb74a..dcbf181980 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -50,6 +50,8 @@ static void AddLineNumber(Rewriter& R, unsigned LineNo,
SourceLocation B, SourceLocation E) {
// Surround the line text with a div tag.
+
+ R.InsertCStrBefore(E, "</div>");
if (B == E) // Handle empty lines.
R.InsertCStrBefore(B, "<div class=\"lines\"> </div>");
@@ -68,7 +70,7 @@ static void AddLineNumber(Rewriter& R, unsigned LineNo,
// Now surround the whole line with another div tag.
R.InsertCStrBefore(B, "<div class=\"codeline\">");
- R.InsertCStrAfter(E, "</div>");
+
}
void html::AddLineNumbers(Rewriter& R, unsigned FileID) {
@@ -141,9 +143,12 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID) {
<< " .nums, .lines { float:left; height:100% }\n"
<< " .nums { background-color: #eeeeee }\n"
<< " .nums { font-size:smaller }\n"
- << " .nums { width:2.5em; padding-right:2ex; text-align:right }\n"
+ << " .nums { width:2.5em; padding-right:2ex; text-align:right }\n"
<< " .lines { padding-left: 1ex; border-left: 3px solid #ccc }\n"
<< " .lines { white-space: pre }\n"
+ << " .msg { background-color:#fcff4c; float:left }\n"
+ << " .msg { font-family:Helvetica, sans-serif; font-size: smaller }\n"
+ << " .msg { padding:5px; margin-top:10px; margin-bottom:10px }\n"
<< " </style>\n"
<< "</head>\n"
<< "<body>";