diff options
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 4 | ||||
-rw-r--r-- | test/Index/comment-objc-decls.m | 30 | ||||
-rw-r--r-- | test/Index/format-comment-cdecls.c | 100 | ||||
-rw-r--r-- | test/Index/overriding-method-comments.mm | 10 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 4 | ||||
-rw-r--r-- | tools/libclang/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tools/libclang/CXComment.cpp | 74 | ||||
-rw-r--r-- | tools/libclang/CXTranslationUnit.h | 2 | ||||
-rw-r--r-- | tools/libclang/Makefile | 3 | ||||
-rw-r--r-- | tools/libclang/SimpleFormatContext.h | 73 | ||||
-rw-r--r-- | unittests/AST/DeclPrinterTest.cpp | 2 |
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<MyProto> {\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;")); } |