summaryrefslogtreecommitdiffstats
path: root/clang/tools
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-12-18 23:02:59 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-12-18 23:02:59 +0000
commit9b7ab87738a6e4225005cff36e7aa1e735df5236 (patch)
tree27497a1cc82347f49b5669a2e807a97152c3520b /clang/tools
parentdfc9430bc7536c9f4599d586afce43606337dedb (diff)
downloadbcm5719-llvm-9b7ab87738a6e4225005cff36e7aa1e735df5236.tar.gz
bcm5719-llvm-9b7ab87738a6e4225005cff36e7aa1e735df5236.zip
This is the libclang patch providing minimal API to
use clang's formatter. Currently, formatter is used to format declaration tags for xml comments. Since formatter is in flux and its change will break several of the clang comment tests, only a single tests is formatted using this facility. Doug has reviewed and approved it for check-in. llvm-svn: 170467
Diffstat (limited to 'clang/tools')
-rw-r--r--clang/tools/libclang/CIndex.cpp4
-rw-r--r--clang/tools/libclang/CMakeLists.txt2
-rw-r--r--clang/tools/libclang/CXComment.cpp74
-rw-r--r--clang/tools/libclang/CXTranslationUnit.h2
-rw-r--r--clang/tools/libclang/Makefile3
-rw-r--r--clang/tools/libclang/SimpleFormatContext.h73
6 files changed, 153 insertions, 5 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 3532abd3630..177b3a6d51e 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -21,6 +21,7 @@
#include "CXTranslationUnit.h"
#include "CXType.h"
#include "CursorVisitor.h"
+#include "SimpleFormatContext.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/Version.h"
@@ -61,6 +62,8 @@ CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *TU) {
D->StringPool = createCXStringPool();
D->Diagnostics = 0;
D->OverridenCursorsPool = createOverridenCXCursorsPool();
+ D->FormatContext = 0;
+ D->FormatInMemoryUniqueId = 0;
return D;
}
@@ -2779,6 +2782,7 @@ void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
disposeCXStringPool(CTUnit->StringPool);
delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
+ delete static_cast<SimpleFormatContext*>(CTUnit->FormatContext);
delete CTUnit;
}
}
diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt
index 1426c42b462..69480db4fed 100644
--- a/clang/tools/libclang/CMakeLists.txt
+++ b/clang/tools/libclang/CMakeLists.txt
@@ -38,6 +38,7 @@ set(SOURCES
Indexing.cpp
IndexingContext.cpp
IndexingContext.h
+ SimpleFormatContext.h
../../include/clang-c/Index.h
)
@@ -54,6 +55,7 @@ set(LIBRARIES
clangLex
clangTooling
clangBasic
+ clangFormat
)
set(GENERATED_HEADERS
diff --git a/clang/tools/libclang/CXComment.cpp b/clang/tools/libclang/CXComment.cpp
index 8c8fe74bba5..070b8b8207d 100644
--- a/clang/tools/libclang/CXComment.cpp
+++ b/clang/tools/libclang/CXComment.cpp
@@ -15,13 +15,17 @@
#include "CXComment.h"
#include "CXCursor.h"
#include "CXString.h"
+#include "SimpleFormatContext.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/Decl.h"
#include "clang/AST/PrettyPrinter.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "clang/Format/Format.h"
+#include "clang/Lex/Lexer.h"
#include <climits>
using namespace clang;
@@ -856,8 +860,12 @@ public:
CommentASTToXMLConverter(const FullComment *FC,
SmallVectorImpl<char> &Str,
const CommandTraits &Traits,
- const SourceManager &SM) :
- FC(FC), Result(Str), Traits(Traits), SM(SM) { }
+ const SourceManager &SM,
+ SimpleFormatContext &RTC,
+ unsigned FUID) :
+ FC(FC), Result(Str), Traits(Traits), SM(SM),
+ FormatRewriterContext(RTC),
+ FormatInMemoryUniqueId(FUID) { }
// Inline content.
void visitTextComment(const TextComment *C);
@@ -878,6 +886,10 @@ public:
// Helpers.
void appendToResultWithXMLEscaping(StringRef S);
+
+ unsigned getFormatInMemoryUniqueId() { return FormatInMemoryUniqueId; }
+ SimpleFormatContext &getFormatRewriterContext()
+ { return FormatRewriterContext; }
private:
const FullComment *FC;
@@ -887,6 +899,8 @@ private:
const CommandTraits &Traits;
const SourceManager &SM;
+ SimpleFormatContext &FormatRewriterContext;
+ unsigned FormatInMemoryUniqueId;
};
void getSourceTextOfDeclaration(const DeclInfo *ThisDecl,
@@ -900,6 +914,43 @@ void getSourceTextOfDeclaration(const DeclInfo *ThisDecl,
ThisDecl->CurrentDecl->print(OS, PPolicy,
/*Indentation*/0, /*PrintInstantiation*/true);
}
+
+void formatTextOfDeclaration(CommentASTToXMLConverter *C,
+ const DeclInfo *DI,
+ SmallString<128> &Declaration) {
+ // FIXME. This conditional is TEMPORARY. We don't want to break multiple
+ // large tests each time Format.cpp changes. This condition will
+ // go away and formatting will happen for all declarations.
+ if (getenv("LIBCLANG_ACTIVATE_FORMAT")) {
+ SimpleFormatContext &FormatRewriterContext =
+ C->getFormatRewriterContext();
+ // FIXME. formatting API expects null terminated input string.
+ // There might be more efficient way of doing this.
+ std::string StringDecl = Declaration.str();
+
+ // Formatter specific code.
+ // Form a unique in memory buffer name.
+ llvm::SmallString<128> filename;
+ filename += "xmldecl";
+ filename += llvm::utostr(C->getFormatInMemoryUniqueId());
+ filename += ".xd";
+ FileID ID = FormatRewriterContext.createInMemoryFile(filename, StringDecl);
+ SourceLocation Start =
+ FormatRewriterContext.Sources.getLocForStartOfFile(ID).getLocWithOffset(0);
+ unsigned Length = Declaration.size();
+
+ std::vector<CharSourceRange>
+ Ranges(1, CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length)));
+ ASTContext &Context = DI->CurrentDecl->getASTContext();
+ const LangOptions &LangOpts = Context.getLangOpts();
+ Lexer Lex(ID, FormatRewriterContext.Sources.getBuffer(ID),
+ FormatRewriterContext.Sources, LangOpts);
+ tooling::Replacements Replace =
+ reformat(format::getLLVMStyle(), Lex, FormatRewriterContext.Sources, Ranges);
+ applyAllReplacements(Replace, FormatRewriterContext.Rewrite);
+ Declaration = FormatRewriterContext.getRewrittenText(ID);
+ }
+}
} // end unnamed namespace
@@ -1165,7 +1216,9 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
Result << "<Declaration>";
SmallString<128> Declaration;
getSourceTextOfDeclaration(DI, Declaration);
+ formatTextOfDeclaration(this, DI, Declaration);
appendToResultWithXMLEscaping(Declaration);
+
Result << "</Declaration>";
}
@@ -1320,12 +1373,25 @@ CXString clang_FullComment_getAsXML(CXComment CXC) {
const FullComment *FC = getASTNodeAs<FullComment>(CXC);
if (!FC)
return createCXString((const char *) 0);
-
+ ASTContext &Context = FC->getDeclInfo()->CurrentDecl->getASTContext();
CXTranslationUnit TU = CXC.TranslationUnit;
SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager();
+
+ SimpleFormatContext *SFC =
+ static_cast<SimpleFormatContext*>(TU->FormatContext);
+ if (!SFC) {
+ SFC = new SimpleFormatContext(Context.getLangOpts());
+ TU->FormatContext = SFC;
+ }
+ else if ((TU->FormatInMemoryUniqueId % 10) == 0) {
+ delete SFC;
+ SFC = new SimpleFormatContext(Context.getLangOpts());
+ TU->FormatContext = SFC;
+ }
SmallString<1024> XML;
- CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM);
+ CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM,
+ *SFC, TU->FormatInMemoryUniqueId++);
Converter.visit(FC);
return createCXString(XML.str(), /* DupString = */ true);
}
diff --git a/clang/tools/libclang/CXTranslationUnit.h b/clang/tools/libclang/CXTranslationUnit.h
index 37789aafb9d..1c713bf2d60 100644
--- a/clang/tools/libclang/CXTranslationUnit.h
+++ b/clang/tools/libclang/CXTranslationUnit.h
@@ -21,6 +21,8 @@ struct CXTranslationUnitImpl {
void *StringPool;
void *Diagnostics;
void *OverridenCursorsPool;
+ void *FormatContext;
+ unsigned FormatInMemoryUniqueId;
};
}
diff --git a/clang/tools/libclang/Makefile b/clang/tools/libclang/Makefile
index 93f63cf86c8..01223e0116e 100644
--- a/clang/tools/libclang/Makefile
+++ b/clang/tools/libclang/Makefile
@@ -21,7 +21,8 @@ USEDLIBS = clangARCMigrate.a clangRewriteCore.a clangRewriteFrontend.a \
clangFrontend.a clangDriver.a \
clangSerialization.a \
clangParse.a clangSema.a clangEdit.a clangAnalysis.a \
- clangAST.a clangLex.a clangTooling.a clangBasic.a
+ clangAST.a clangLex.a clangTooling.a clangBasic.a \
+ clangFormat.a
include $(CLANG_LEVEL)/Makefile
diff --git a/clang/tools/libclang/SimpleFormatContext.h b/clang/tools/libclang/SimpleFormatContext.h
new file mode 100644
index 00000000000..f322e63d060
--- /dev/null
+++ b/clang/tools/libclang/SimpleFormatContext.h
@@ -0,0 +1,73 @@
+//===--- SimpleFormatContext.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a utility class for Rewriter related tests.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SIMPLE_FORM_CONTEXT_H
+#define LLVM_CLANG_SIMPLE_FORM_CONTEXT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+/// \brief A small class to be used by libclang clients to format
+/// a declaration string in memory. This object is instantiated once
+/// and used each time a formatting is needed.
+class SimpleFormatContext {
+ public:
+ SimpleFormatContext(LangOptions Options)
+ : DiagOpts(new DiagnosticOptions()),
+ Diagnostics(new DiagnosticsEngine(new DiagnosticIDs,
+ DiagOpts.getPtr())),
+ Files((FileSystemOptions())),
+ Sources(*Diagnostics, Files),
+ Rewrite(Sources, Options) {
+ Diagnostics->setClient(new IgnoringDiagConsumer, true);
+ }
+
+ ~SimpleFormatContext() { }
+
+ FileID createInMemoryFile(StringRef Name, StringRef Content) {
+ const llvm::MemoryBuffer *Source =
+ llvm::MemoryBuffer::getMemBuffer(Content);
+ const FileEntry *Entry =
+ Files.getVirtualFile(Name, Source->getBufferSize(), 0);
+ Sources.overrideFileContents(Entry, Source, true);
+ assert(Entry != NULL);
+ return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
+ }
+
+ std::string getRewrittenText(FileID ID) {
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ Rewrite.getEditBuffer(ID).write(OS);
+ OS.flush();
+ return Result;
+ }
+
+ llvm::IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
+ FileManager Files;
+ SourceManager Sources;
+ Rewriter Rewrite;
+};
+
+} // end namespace clang
+
+#endif
OpenPOWER on IntegriCloud