diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-03-19 07:53:42 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-03-19 07:53:42 +0000 |
commit | 13e479b2b74771738a5e5c5dc1c270416924b126 (patch) | |
tree | aaae19db0db5691858c6017e4ee56e77317fb53d | |
parent | 0fdf06e5eef80ce56ce6499ba662453919b95af1 (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.h | 2 | ||||
-rw-r--r-- | Driver/HTMLPrint.cpp | 167 | ||||
-rw-r--r-- | Driver/clang.cpp | 6 | ||||
-rw-r--r-- | lib/Rewrite/HTMLRewrite.cpp | 9 |
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\"> </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>"; |