aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/DeclPrinter.cpp4
-rw-r--r--test/Index/comment-objc-decls.m30
-rw-r--r--test/Index/format-comment-cdecls.c100
-rw-r--r--test/Index/overriding-method-comments.mm10
-rw-r--r--tools/libclang/CIndex.cpp4
-rw-r--r--tools/libclang/CMakeLists.txt2
-rw-r--r--tools/libclang/CXComment.cpp74
-rw-r--r--tools/libclang/CXTranslationUnit.h2
-rw-r--r--tools/libclang/Makefile3
-rw-r--r--tools/libclang/SimpleFormatContext.h73
-rw-r--r--unittests/AST/DeclPrinterTest.cpp2
11 files changed, 277 insertions, 27 deletions
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 5cef00f187..34c69059c4 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -915,6 +915,8 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
OMD->getBody()->printPretty(Out, 0, Policy);
Out << '\n';
}
+ else
+ Out << ';';
}
void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
@@ -1093,7 +1095,7 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
(void) first; // Silence dead store warning due to idiomatic code.
Out << " )";
}
- Out << ' ' << PDecl->getType().getAsString(Policy) << ' ' << *PDecl;
+ Out << ' ' << PDecl->getType().getAsString(Policy) << ' ' << *PDecl << ';';
}
void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
diff --git a/test/Index/comment-objc-decls.m b/test/Index/comment-objc-decls.m
index 2894ee88f5..d037e05db2 100644
--- a/test/Index/comment-objc-decls.m
+++ b/test/Index/comment-objc-decls.m
@@ -31,9 +31,9 @@
+ ClassMethodMyProto;
@end
// CHECK: <Declaration>@protocol MyProto\n@end</Declaration>
-// CHECK: <Declaration>- (unsigned int) MethodMyProto:(id)anObject inRange:(unsigned int)range</Declaration>
-// CHECK: <Declaration>@optional\n@property ( readwrite,copy,atomic ) id PropertyMyProto</Declaration>
-// CHECK: <Declaration>+ (id) ClassMethodMyProto</Declaration>
+// CHECK: <Declaration>- (unsigned int) MethodMyProto:(id)anObject inRange:(unsigned int)range;</Declaration>
+// CHECK: <Declaration>@optional\n@property ( readwrite,copy,atomic ) id PropertyMyProto;</Declaration>
+// CHECK: <Declaration>+ (id) ClassMethodMyProto;</Declaration>
/**
* \brief NSObject is the root class.
@@ -75,9 +75,9 @@
@end
// CHECK: <Declaration>@interface MyClass : NSObject&lt;MyProto&gt; {\n id IvarMyClass;\n}\n@end</Declaration>
// CHECK: <Declaration>id IvarMyClass</Declaration>
-// CHECK: <Declaration>- (id) MethodMyClass</Declaration>
-// CHECK: <Declaration>+ (id) ClassMethodMyClass</Declaration>
-// CHECK: <Declaration>@property ( readwrite,copy,atomic ) id PropertyMyClass</Declaration
+// CHECK: <Declaration>- (id) MethodMyClass;</Declaration>
+// CHECK: <Declaration>+ (id) ClassMethodMyClass;</Declaration>
+// CHECK: <Declaration>@property ( readwrite,copy,atomic ) id PropertyMyClass;</Declaration
/**
* \brief - This is class extension of MyClass
@@ -109,10 +109,10 @@
@property (copy) id PropertyMyClassCategory;
@end
// CHECK: <Declaration>@interface MyClass(Category)\n@end</Declaration>
-// CHECK: <Declaration>- (void) MethodMyClassCategory</Declaration>
-// CHECK: <Declaration>@property ( readwrite,copy,atomic ) id PropertyMyClassCategory</Declaration>
-// CHECK: <Declaration>- (id) PropertyMyClassCategory</Declaration>
-// CHECK: <Declaration>- (void) setPropertyMyClassCategory:(id)arg</Declaration>
+// CHECK: <Declaration>- (void) MethodMyClassCategory;</Declaration>
+// CHECK: <Declaration>@property ( readwrite,copy,atomic ) id PropertyMyClassCategory;</Declaration>
+// CHECK: <Declaration>- (id) PropertyMyClassCategory;</Declaration>
+// CHECK: <Declaration>- (void) setPropertyMyClassCategory:(id)arg;</Declaration>
/// @implementation's
@@ -141,8 +141,8 @@
@end
// CHECK: <Declaration>@implementation MyClass{\n id IvarPrivateToMyClassImpl;\n id _PropertyMyClass;\n}\n@end</Declaration>
// CHECK: <Declaration>id IvarPrivateToMyClassImpl</Declaration>
-// CHECK: <Declaration>- (id) MethodMyClass</Declaration>
-// CHECK: <Declaration>+ (id) ClassMethodMyClass</Declaration>
+// CHECK: <Declaration>- (id) MethodMyClass;</Declaration>
+// CHECK: <Declaration>+ (id) ClassMethodMyClass;</Declaration>
/**
* \brief MyClass (Category) is implementation of private to MyClass.
@@ -163,9 +163,9 @@
- (void) setPropertyMyClassCategory : (id) arg {}
@end
// CHECK: <Declaration>@implementation MyClass(Category)\n@end</Declaration>
-// CHECK: <Declaration>- (void) MethodMyClassCategory</Declaration>
-// CHECK: <Declaration>- (id) PropertyMyClassCategory</Declaration>
-// CHECK: <Declaration>- (void) setPropertyMyClassCategory:(id)arg</Declaration>
+// CHECK: <Declaration>- (void) MethodMyClassCategory;</Declaration>
+// CHECK: <Declaration>- (id) PropertyMyClassCategory;</Declaration>
+// CHECK: <Declaration>- (void) setPropertyMyClassCategory:(id)arg;</Declaration>
/**
* \brief NSObject implementation
diff --git a/test/Index/format-comment-cdecls.c b/test/Index/format-comment-cdecls.c
new file mode 100644
index 0000000000..989ce5c022
--- /dev/null
+++ b/test/Index/format-comment-cdecls.c
@@ -0,0 +1,100 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: env LIBCLANG_ACTIVATE_FORMAT=1 \
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng -target x86_64-apple-darwin10 %s \
+// RUN: | FileCheck %s
+
+/**
+ * \brief Aaa.
+*/
+int global_function();
+// CHECK: <Declaration>int global_function()</Declaration>
+
+/**
+ * \param x1 Aaa.
+*/
+extern void external_function(int x1);
+// CHECK: <Declaration>extern void external_function(int x1)</Declaration>
+
+/**
+ * \brief global variable;
+*/
+int global_variable;
+// CHECK: <Declaration>int global_variable</Declaration>
+
+/**
+ * \brief local variable;
+*/
+static int static_variable;
+// CHECK: <Declaration>static int static_variable</Declaration>
+
+/**
+ * \brief external variable
+*/
+extern int external_variable;
+// CHECK: <Declaration>extern int external_variable</Declaration>
+
+int global_function() {
+ /**
+ * \brief a local variable
+ */
+ int local = 10;
+ return local;
+}
+// CHECK: <Declaration>int global_function()</Declaration>
+// CHECK: <Declaration>int local = 10</Declaration>
+
+/**
+ * \brief initialized decl.
+*/
+int initialized_global = 100;
+// CHECK: <Declaration>int initialized_global = 100</Declaration>
+
+/**
+ * \brief typedef example
+*/
+typedef int INT_T;
+// CHECK: <Declaration>typedef int INT_T</Declaration>
+
+/**
+ * \brief aggregate type example
+*/
+struct S {
+/**
+ * \brief iS1;
+*/
+ int iS1;
+/**
+ * \brief dS1;
+*/
+ double dS1;
+};
+// CHECK: <Declaration>struct S {\n}</Declaration>
+// CHECK: <Declaration>int iS1</Declaration>
+// CHECK: <Declaration>double dS1</Declaration>
+
+/**
+ * \brief enum e;
+*/
+enum e {
+ One,
+/**
+ * \brief Two;
+*/
+ Two,
+ Three
+};
+// CHECK: <Declaration>enum e {\n}</Declaration>
+// CHECK: <Declaration>Two</Declaration>
+
+/**
+ *\brief block declaration
+*/
+int (^Block) (int i, int j);
+// CHECK: <Declaration>int (^Block)(int, int)</Declaration>
+
+/**
+ *\brief block declaration
+*/
+int (^Block1) (int i, int j) = ^(int i, int j) { return i + j; };
+// CHECK: <Declaration>int (^ Block1) (int, int) = ^ (int i, int j) {\n}</Declaration>
diff --git a/test/Index/overriding-method-comments.mm b/test/Index/overriding-method-comments.mm
index 1641e85ef5..899b31d801 100644
--- a/test/Index/overriding-method-comments.mm
+++ b/test/Index/overriding-method-comments.mm
@@ -19,7 +19,7 @@
- (void)METH:(id)AAA;
@end
-// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Declaration>- (void) METH:(id)AAA</Declaration><Parameters><Parameter><Name>AAA</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Declaration>- (void) METH:(id)AAA;</Declaration><Parameters><Parameter><Name>AAA</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>]
@interface Sub : Root
@end
@@ -28,13 +28,13 @@
- (void)METH:(id)BBB;
@end
-// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Declaration>- (void) METH:(id)BBB</Declaration><Parameters><Parameter><Name>BBB</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Declaration>- (void) METH:(id)BBB;</Declaration><Parameters><Parameter><Name>BBB</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>]
@implementation Sub(CAT)
- (void)METH:(id)III {}
@end
-// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Declaration>- (void) METH:(id)III</Declaration><Parameters><Parameter><Name>III</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Declaration>- (void) METH:(id)III;</Declaration><Parameters><Parameter><Name>III</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>]
@interface Redec : Root
@end
@@ -48,13 +48,13 @@
- (void)EXT_METH:(id)AAA : (double)BBB : (int)CCC;
@end
-// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>EXT_METH:::</Name><USR>c:objc(cs)Redec(im)EXT_METH:::</USR><Declaration>- (void) EXT_METH:(id)AAA :(double)BBB :(int)CCC</Declaration><Parameters><Parameter><Name>AAA</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> input value </Para></Discussion></Parameter><Parameter><Name>BBB</Name><Index>1</Index><Direction isExplicit="1">in</Direction><Discussion><Para> 2nd input value is double </Para></Discussion></Parameter><Parameter><Name>CCC</Name><Index>2</Index><Direction isExplicit="1">out</Direction><Discussion><Para> output value is int </Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>EXT_METH:::</Name><USR>c:objc(cs)Redec(im)EXT_METH:::</USR><Declaration>- (void) EXT_METH:(id)AAA :(double)BBB :(int)CCC;</Declaration><Parameters><Parameter><Name>AAA</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> input value </Para></Discussion></Parameter><Parameter><Name>BBB</Name><Index>1</Index><Direction isExplicit="1">in</Direction><Discussion><Para> 2nd input value is double </Para></Discussion></Parameter><Parameter><Name>CCC</Name><Index>2</Index><Direction isExplicit="1">out</Direction><Discussion><Para> output value is int </Para></Discussion></Parameter></Parameters></Function>]
@implementation Redec
- (void)EXT_METH:(id)PPP : (double)QQQ : (int)RRR {}
@end
-// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>EXT_METH:::</Name><USR>c:objc(cs)Redec(im)EXT_METH:::</USR><Declaration>- (void) EXT_METH:(id)PPP :(double)QQQ :(int)RRR</Declaration><Parameters><Parameter><Name>PPP</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> input value </Para></Discussion></Parameter><Parameter><Name>QQQ</Name><Index>1</Index><Direction isExplicit="1">in</Direction><Discussion><Para> 2nd input value is double </Para></Discussion></Parameter><Parameter><Name>RRR</Name><Index>2</Index><Direction isExplicit="1">out</Direction><Discussion><Para> output value is int </Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-3]]" column="1"><Name>EXT_METH:::</Name><USR>c:objc(cs)Redec(im)EXT_METH:::</USR><Declaration>- (void) EXT_METH:(id)PPP :(double)QQQ :(int)RRR;</Declaration><Parameters><Parameter><Name>PPP</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> input value </Para></Discussion></Parameter><Parameter><Name>QQQ</Name><Index>1</Index><Direction isExplicit="1">in</Direction><Discussion><Para> 2nd input value is double </Para></Discussion></Parameter><Parameter><Name>RRR</Name><Index>2</Index><Direction isExplicit="1">out</Direction><Discussion><Para> output value is int </Para></Discussion></Parameter></Parameters></Function>]
struct Base {
/// \brief Does something.
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 3532abd363..177b3a6d51 100644
--- a/tools/libclang/CIndex.cpp
+++ b/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/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 1426c42b46..69480db4fe 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/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/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index 8c8fe74bba..070b8b8207 100644
--- a/tools/libclang/CXComment.cpp
+++ b/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/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index 37789aafb9..1c713bf2d6 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -21,6 +21,8 @@ struct CXTranslationUnitImpl {
void *StringPool;
void *Diagnostics;
void *OverridenCursorsPool;
+ void *FormatContext;
+ unsigned FormatInMemoryUniqueId;
};
}
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index 93f63cf86c..01223e0116 100644
--- a/tools/libclang/Makefile
+++ b/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/tools/libclang/SimpleFormatContext.h b/tools/libclang/SimpleFormatContext.h
new file mode 100644
index 0000000000..f322e63d06
--- /dev/null
+++ b/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
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
index 844b9a49e1..e9fc6fdea3 100644
--- a/unittests/AST/DeclPrinterTest.cpp
+++ b/unittests/AST/DeclPrinterTest.cpp
@@ -1234,6 +1234,6 @@ TEST(DeclPrinter, TestObjCMethod1) {
"@end\n",
namedDecl(hasName("A:inRange:"),
hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
- "- (int) A:(id)anObject inRange:(long)range"));
+ "- (int) A:(id)anObject inRange:(long)range;"));
}