[PATCH] D27382: Add a new clang-format style option ObjCBlockResetsIndent.
yixiang added a reviewer: djasper. yixiang added a subscriber: cfe-commits. yixiang updated this revision to Diff 80174. https://reviews.llvm.org/D27382 Files: docs/ClangFormatStyleOptions.rst include/clang/Format/Format.h lib/Format/ContinuationIndenter.cpp lib/Format/Format.cpp Index: lib/Format/Format.cpp === --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -322,6 +322,7 @@ IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth); +IO.mapOptional("ObjCBlockResetsIndent", Style.ObjCBlockResetsIndent); IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); IO.mapOptional("ObjCSpaceBeforeProtocolList", Style.ObjCSpaceBeforeProtocolList); Index: lib/Format/ContinuationIndenter.cpp === --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -1037,6 +1037,13 @@ } void ContinuationIndenter::moveStateToNewBlock(LineState &State) { + // For ObjC blocks, reset the indent to that of the owner block if the style + // tells us to do so. + if (Style.ObjCBlockResetsIndent && State.NextToken->is(TT_ObjCBlockLBrace)) { +State.Stack.back().Indent = State.Stack.front().Indent; +State.Stack.back().NestedBlockIndent = +State.Stack.front().NestedBlockIndent; + } unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent; // ObjC block sometimes follow special indentation rules. unsigned NewIndent = Index: include/clang/Format/Format.h === --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -500,6 +500,9 @@ /// \brief The number of characters to use for indentation of ObjC blocks. unsigned ObjCBlockIndentWidth; + /// \brief Whether ObjC blocks resets the indent to that of its owner block. + bool ObjCBlockResetsIndent = false; + /// \brief Add a space after ``@property`` in Objective-C, i.e. use /// ``@property (readonly)`` instead of ``@property(readonly)``. bool ObjCSpaceAfterProperty; Index: docs/ClangFormatStyleOptions.rst === --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -618,6 +618,9 @@ **ObjCBlockIndentWidth** (``unsigned``) The number of characters to use for indentation of ObjC blocks. +**ObjCBlockResetsIndent** (``bool``) + Whether ObjC blocks resets the indent to that of its owner block. + **ObjCSpaceAfterProperty** (``bool``) Add a space after ``@property`` in Objective-C, i.e. use ``@property (readonly)`` instead of ``@property(readonly)``. Index: lib/Format/Format.cpp === --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -322,6 +322,7 @@ IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth); +IO.mapOptional("ObjCBlockResetsIndent", Style.ObjCBlockResetsIndent); IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); IO.mapOptional("ObjCSpaceBeforeProtocolList", Style.ObjCSpaceBeforeProtocolList); Index: lib/Format/ContinuationIndenter.cpp === --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -1037,6 +1037,13 @@ } void ContinuationIndenter::moveStateToNewBlock(LineState &State) { + // For ObjC blocks, reset the indent to that of the owner block if the style + // tells us to do so. + if (Style.ObjCBlockResetsIndent && State.NextToken->is(TT_ObjCBlockLBrace)) { +State.Stack.back().Indent = State.Stack.front().Indent; +State.Stack.back().NestedBlockIndent = +State.Stack.front().NestedBlockIndent; + } unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent; // ObjC block sometimes follow special indentation rules. unsigned NewIndent = Index: include/clang/Format/Format.h === --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -500,6 +500,9 @@ /// \brief The number of characters to use for indentation of ObjC blocks. unsigned ObjCBlockIndentWidth; + /// \brief Whether ObjC blocks resets the indent to that of its owner block. + bool ObjCBlockResetsIndent = false; + /// \brief Add a space after ``@property`` in Objective-C, i.e. use /// ``@property (readonly)`` instead of ``@property(readonly)``. bool ObjCSpaceAfterProperty; Index: docs/ClangFormatStyleOptions.rst
[PATCH] D27383: Add a new clang-format style option ObjCBlockResetsIndent.
yixiang created this revision. yixiang added a reviewer: djasper. yixiang added subscribers: cfe-commits, klimek. Add a new clang-format style option ObjCBlockResetsIndent of type bool. It defaults to false. When true, ObjC blocks resets indentation to that of its owner block. The resetting behavior is often desirable, as it leaves more columns for the content of the ObjC block. E.g. for an unformatted file test.m like this: - (void)test { [self callAVeryVeryVeryVeryVeryVeryLongAsyncMethodWith:@"Some param" completionHandler:^() { [self callAnotherLongMethodHereWith:@"param"]; }]; } The formatted result with ObjCBlockResetsIndent=false (or omitted) is this: // clang-format -style='{BasedOnStyle: Google, ObjCBlockResetsIndent: false}' test.m // OR // clang-format -style='{BasedOnStyle: Google}' test.m - (void)test { [self callAVeryVeryVeryVeryVeryVeryLongAsyncMethodWith:@"Some param" completionHandler:^() { [self callAnotherLongMethodHereWith: @"param"]; }]; } The formatted result with ObjCBlockResetsIndent=true is this: // clang-format -style='{BasedOnStyle: Google, ObjCBlockResetsIndent: true}' test.m - (void)test { [self callAVeryVeryVeryVeryVeryVeryLongAsyncMethodWith:@"Some param" completionHandler:^() { [self callAnotherLongMethodHereWith:@"param"]; }]; } https://reviews.llvm.org/D27383 Files: docs/ClangFormatStyleOptions.rst include/clang/Format/Format.h lib/Format/ContinuationIndenter.cpp lib/Format/Format.cpp Index: lib/Format/Format.cpp === --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -322,6 +322,7 @@ IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth); +IO.mapOptional("ObjCBlockResetsIndent", Style.ObjCBlockResetsIndent); IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); IO.mapOptional("ObjCSpaceBeforeProtocolList", Style.ObjCSpaceBeforeProtocolList); Index: lib/Format/ContinuationIndenter.cpp === --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -1037,6 +1037,13 @@ } void ContinuationIndenter::moveStateToNewBlock(LineState &State) { + // For ObjC blocks, reset the indent to that of the owner block if the style + // tells us to do so. + if (Style.ObjCBlockResetsIndent && State.NextToken->is(TT_ObjCBlockLBrace)) { +State.Stack.back().Indent = State.Stack.front().Indent; +State.Stack.back().NestedBlockIndent = +State.Stack.front().NestedBlockIndent; + } unsigned NestedBlockIndent = State.Stack.back().NestedBlockIndent; // ObjC block sometimes follow special indentation rules. unsigned NewIndent = Index: include/clang/Format/Format.h === --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -500,6 +500,9 @@ /// \brief The number of characters to use for indentation of ObjC blocks. unsigned ObjCBlockIndentWidth; + /// \brief Whether ObjC blocks resets the indent to that of its owner block. + bool ObjCBlockResetsIndent = false; + /// \brief Add a space after ``@property`` in Objective-C, i.e. use /// ``@property (readonly)`` instead of ``@property(readonly)``. bool ObjCSpaceAfterProperty; Index: docs/ClangFormatStyleOptions.rst === --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -618,6 +618,9 @@ **ObjCBlockIndentWidth** (``unsigned``) The number of characters to use for indentation of ObjC blocks. +**ObjCBlockResetsIndent** (``bool``) + Whether ObjC blocks resets the indent to that of its owner block. + **ObjCSpaceAfterProperty** (``bool``) Add a space after ``@property`` in Objective-C, i.e. use ``@property (readonly)`` instead of ``@property(readonly)``. Index: lib/Format/Format.cpp === --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -322,6 +322,7 @@ IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth); +IO.mapOptional("ObjCBlockResetsIndent", Style.ObjCBlockResetsIndent); IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); IO.mapOptional("ObjCSpaceBeforeProtocolList", Style.ObjCSpaceBeforeProtocolList); Index: l
[PATCH] D27382: [OBSOLETE] Add a new clang-format style option ObjCBlockResetsIndent.
yixiang abandoned this revision. yixiang added a comment. Sending as another diff using arcanist. This one doesn't have proper file context for reviewing. https://reviews.llvm.org/D27382 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27383: Add a new clang-format style option ObjCBlockResetsIndent.
djasper added a comment. I think generally, this makes sense. Can you add tests in unittests/Format/FormatTest.cpp (probably next to TEST_F(FormatTest, FormatsBlocks) {..})? What's the behavior when there is more than one block? Also note that we have some requirements for additional options (mainly to ensure long-term maintainability): http://clang.llvm.org/docs/ClangFormatStyleOptions.html#adding-additional-style-options https://reviews.llvm.org/D27383 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27383: Add a new clang-format style option ObjCBlockResetsIndent.
yixiang updated this revision to Diff 80176. yixiang added a comment. - Added unit test for ObjCBlockResetsIndent. https://reviews.llvm.org/D27383 Files: docs/ClangFormatStyleOptions.rst include/clang/Format/Format.h lib/Format/ContinuationIndenter.cpp lib/Format/Format.cpp unittests/Format/FormatTest.cpp Index: unittests/Format/FormatTest.cpp === --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -11263,6 +11263,128 @@ FourIndent); } +TEST_F(FormatTest, FormatsBlocksWithIndentResetting) { + FormatStyle ShortBlocks = getLLVMStyle(); + ShortBlocks.AllowShortBlocksOnASingleLine = true; + ShortBlocks.ObjCBlockResetsIndent = true; + + verifyFormat("int (^Block)(int, int);", ShortBlocks); + verifyFormat("int (^Block1)(int, int) = ^(int i, int j)", ShortBlocks); + verifyFormat("void (^block)(int) = ^(id test) { int i; };", ShortBlocks); + verifyFormat("void (^block)(int) = ^(int test) { int i; };", ShortBlocks); + verifyFormat("void (^block)(int) = ^id(int test) { int i; };", ShortBlocks); + verifyFormat("void (^block)(int) = ^int(int test) { int i; };", ShortBlocks); + + verifyFormat("foo(^{ bar(); });", ShortBlocks); + verifyFormat("foo(a, ^{ bar(); });", ShortBlocks); + verifyFormat("{ void (^block)(Object *x); }", ShortBlocks); + + verifyFormat("[operation setCompletionBlock:^{\n" + " [self onOperationDone];\n" + "}];"); + verifyFormat("int i = {[operation setCompletionBlock:^{\n" + " [self onOperationDone];\n" + "}]};"); + + verifyFormat("[operation setCompletionBlock:^(int *i) {\n" + " f();\n" + "}];"); + + verifyFormat("int a = [operation block:^int(int *i) {\n" + " return 1;\n" + "}];"); + + FormatStyle ResetsIndent = getLLVMStyle(); + ResetsIndent.ObjCBlockResetsIndent = true; + verifyFormat("[myObject doSomethingWith:arg1\n" + " aaa:^int(int *a) {\n" + " return 1;\n" + "}\n" + " bbb:f(a * )];", + ResetsIndent); + + verifyFormat("[operation setCompletionBlock:^{\n" + " [self.delegate newDataAvailable];\n" + "}];", + ResetsIndent); + verifyFormat("dispatch_async(_fileIOQueue, ^{\n" + " NSString *path = [self sessionFilePath];\n" + " if (path) {\n" + "// ...\n" + " }\n" + "});", + ResetsIndent); + verifyFormat("[[SessionService sharedService]\n" + "loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" + " if (window) {\n" + "[self windowDidLoad:window];\n" + " } else {\n" + "[self errorLoadingWindow];\n" + " }\n" + "}];", + ResetsIndent); + verifyFormat("void (^largeBlock)(void) = ^{\n" + " // ...\n" + "};\n", + ResetsIndent); + + FormatStyle ResetsIndent60 = getLLVMStyleWithColumns(60); + ResetsIndent60.ObjCBlockResetsIndent = true; + verifyFormat("[[SessionService sharedService]\n" + "loadWindowWithCompletionBlock: //\n" + "^(SessionWindow *window) {\n" + " if (window) {\n" + "[self windowDidLoad:window];\n" + " } else {\n" + "[self errorLoadingWindow];\n" + " }\n" + "}];", + ResetsIndent60); + + verifyFormat("[myObject doSomethingWith:arg1\n" + "firstBlock:^(Foo *a) {\n" + " // ...\n" + " int i;\n" + "}\n" + "secondBlock:^(Bar *b) {\n" + " // ...\n" + " int i;\n" + "}\n" + "thirdBlock:^Foo(Bar *b) {\n" + " // ...\n" + " int i;\n" + "}];", + ResetsIndent); + verifyFormat("[myObject doSomethingWith:arg1\n" + " firstBlock:-1\n" + " secondBlock:^(Bar *b) {\n" + " // ...\n" + " int i;\n" + "}];", + ResetsIndent); + + verifyFormat("f(^{\n" + " @autoreleasepool {\n" + "if (a) {\n" + " g();\n" + "}\n" + " }\n" + "});", + ResetsIndent); + verifyFormat("Block b = ^int *(A *a, B *b) {}", ResetsIndent); + verifyFormat("BOOL (^aaa)(void) = ^BOOL {\n" + "};", + ResetsIndent); + + FormatStyle FourIndent = getLLVMStyle(); + FourIndent.ObjCBlockIndentWidth = 4; + FourIndent.ObjCBlockResetsIndent = true; + verifyFormat("[operation setComp
[PATCH] D27383: Add a new clang-format style option ObjCBlockResetsIndent.
yixiang added a comment. > Can you add tests in unittests/Format/FormatTest.cpp (probably next to > TEST_F(FormatTest, FormatsBlocks) {..})? > What's the behavior when there is more than one block? Unit tests added. > Also note that we have some requirements for additional options (mainly to > ensure long-term maintainability): > > http://clang.llvm.org/docs/ClangFormatStyleOptions.html#adding-additional-style-options Thanks for pointing that out to me. https://reviews.llvm.org/D27383 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27210: [clang-tidy] misc-string-compare. Adding a new check to clang-tidy
madsravn updated this revision to Diff 80177. madsravn added a comment. Did as comments suggested: Fixed the description about compare returning -1, 0 or 1. Fixed the ast matcher to only find compare with one argument. Clang-formatted everything. Added a new test (str.compare("foo")) and wrote a FIXME for the fixit. https://reviews.llvm.org/D27210 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/MiscTidyModule.cpp clang-tidy/misc/StringCompareCheck.cpp clang-tidy/misc/StringCompareCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-string-compare.rst test/clang-tidy/misc-string-compare.cpp Index: test/clang-tidy/misc-string-compare.cpp === --- test/clang-tidy/misc-string-compare.cpp +++ test/clang-tidy/misc-string-compare.cpp @@ -0,0 +1,72 @@ +// RUN: %check_clang_tidy %s misc-string-compare %t -- -- -std=c++11 + +namespace std { +template +class allocator {}; +template +class char_traits {}; +template , typename A = std::allocator> +struct basic_string { + basic_string(); + basic_string(const C *, unsigned int size); + int compare(const basic_string &str); + int compare(const C *); + bool empty(); +}; +bool operator==(const basic_string &lhs, const basic_string &rhs); +bool operator!=(const basic_string &lhs, const basic_string &rhs); +typedef basic_string string; +} + +void func(bool b); + +void Test() { + std::string str1("a", 1); + std::string str2("b", 1); + + if (str1.compare(str2)) { + } + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use compare to test equality of strings; use the string equality operator instead [misc-string-compare] + if (!str1.compare(str2)) { + } + // CHECK-MESSAGES: [[@LINE-2]]:8: warning: do not use compare to test equality of strings; use the string equality operator instead [misc-string-compare] + if (str1.compare("foo")) { + } + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use compare to test equality of strings; + if (str1.compare(str2) == 0) { + } + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use compare to test equality of strings; + if (str1.compare(str2) != 0) { + } + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use compare to test equality of strings; + if (0 == str1.compare(str2)) { + } + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use compare to test equality of strings; + if (0 != str1.compare(str2)) { + } + // CHECK-MESSAGES: [[@LINE-2]]:7: warning: do not use compare to test equality of strings; + func(str1.compare(str2)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: do not use compare to test equality of strings; + if (str2.empty() || str1.compare(str2) != 0) { + } + // CHECK-MESSAGES: [[@LINE-2]]:23: warning: do not use compare to test equality of strings; +} + +void Valid() { + std::string str1("a", 1); + std::string str2("b", 1); + if (str1 == str2) { + } + if (str1 != str2) { + } + if (str1.compare(str2) == 1) { + } + if (str1.compare(str2) == str1.compare(str2)) { + } + if (0 == 0) { + } + if (1 == str1.compare(str2)) { + } + if (str1.compare(str2) > 0) { + } +} Index: docs/clang-tidy/checks/misc-string-compare.rst === --- docs/clang-tidy/checks/misc-string-compare.rst +++ docs/clang-tidy/checks/misc-string-compare.rst @@ -0,0 +1,47 @@ +.. title:: clang-tidy - misc-string-compare + +misc-string-compare +=== + +Finds string comparisons using the compare method. + +A common mistake is to use the string's ``compare`` method instead of using the +equality or inequality operators. The compare method is intended for sorting +functions and thus returns a negative number, a positive number or +zero depending on the lexicographical relationship between the strings compared. +If an equality or inequality check can suffice, that is recommended. + +Examples: + +.. code-block:: c++ + + std::string str1{"a"}; + std::string str2{"b"}; + + // use str1 != str2 instead. + if (str1.compare(str2)) { + } + + // use str1 == str2 instead. + if (!str1.compare(str2)) { + } + + // use str1 == str2 instead. + if (str1.compare(str2) == 0) { + } + + // use str1 != str2 instead. + if (str1.compare(str2) != 0) { + } + + // use str1 == str2 instead. + if (0 == str1.compare(str2)) { + } + + // use str1 != str2 instead. + if (0 != str1.compare(str2)) { + } + +The above code examples shows the list of if-statements that this check will +give a warning for. All of them uses ``compare`` to check if equality or +inequality of two strings instead of using the correct operators. Index: docs/clang-tidy/checks/list.rst === --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -80,6 +80,7 @@ misc-sizeof-container misc-sizeof-expression misc-static-assert + misc-string-compare misc-string-co
r288582 - [libclang] Fix python tests
Author: skalinichev Date: Sat Dec 3 06:53:06 2016 New Revision: 288582 URL: http://llvm.org/viewvc/llvm-project?rev=288582&view=rev Log: [libclang] Fix python tests It was broken in r286421 Modified: cfe/trunk/bindings/python/tests/cindex/test_cursor.py cfe/trunk/bindings/python/tests/cindex/test_tokens.py Modified: cfe/trunk/bindings/python/tests/cindex/test_cursor.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/tests/cindex/test_cursor.py?rev=288582&r1=288581&r2=288582&view=diff == --- cfe/trunk/bindings/python/tests/cindex/test_cursor.py (original) +++ cfe/trunk/bindings/python/tests/cindex/test_cursor.py Sat Dec 3 06:53:06 2016 @@ -375,7 +375,7 @@ def test_get_tokens(): foo = get_cursor(tu, 'foo') tokens = list(foo.get_tokens()) -assert len(tokens) == 7 +assert len(tokens) == 6 assert tokens[0].spelling == 'int' assert tokens[1].spelling == 'foo' Modified: cfe/trunk/bindings/python/tests/cindex/test_tokens.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/tests/cindex/test_tokens.py?rev=288582&r1=288581&r2=288582&view=diff == --- cfe/trunk/bindings/python/tests/cindex/test_tokens.py (original) +++ cfe/trunk/bindings/python/tests/cindex/test_tokens.py Sat Dec 3 06:53:06 2016 @@ -14,7 +14,7 @@ def test_token_to_cursor(): r = tu.get_extent('t.c', (0, 9)) tokens = list(tu.get_tokens(extent=r)) -assert len(tokens) == 5 +assert len(tokens) == 4 assert tokens[1].spelling == 'i' assert tokens[1].kind == TokenKind.IDENTIFIER ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27384: [libclang] Restore clang_getNumTemplateArguments/clang_getTemplateArgumentAsType functionality
skalinichev created this revision. skalinichev added a subscriber: cfe-commits. Herald added a reviewer: EricWF. This was accidentally broken in r287024 https://reviews.llvm.org/D27384 Files: test/Index/print-type.cpp tools/libclang/CXType.cpp Index: tools/libclang/CXType.cpp === --- tools/libclang/CXType.cpp +++ tools/libclang/CXType.cpp @@ -143,6 +143,17 @@ return static_cast(CT.data[1]); } +template +static CXType GetTemplateArgumentType(const T& TA, unsigned i, CXTranslationUnit TU) +{ + if (TA.size() <= i) +return MakeCXType(QualType(), TU); + const TemplateArgument &A = TA[i]; + if (A.getKind() != TemplateArgument::Type) +return MakeCXType(QualType(), TU); + return MakeCXType(A.getAsType(), TU); +} + extern "C" { CXType clang_getCursorType(CXCursor C) { @@ -926,9 +937,16 @@ return -1; const TemplateSpecializationType *Specialization = T->getAs(); - if (!Specialization) + if (Specialization) +return Specialization->template_arguments().size(); + const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl(); + if (!RecordDecl) + return -1; + const ClassTemplateSpecializationDecl *TemplateDecl = +dyn_cast(RecordDecl); + if (!TemplateDecl) return -1; - return Specialization->template_arguments().size(); + return TemplateDecl->getTemplateArgs().size(); } CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) { @@ -938,15 +956,19 @@ const TemplateSpecializationType *Specialization = T->getAs(); - if (!Specialization) -return MakeCXType(QualType(), GetTU(CT)); - auto TA = Specialization->template_arguments(); - if (TA.size() <= i) + if (Specialization) { +auto TA = Specialization->template_arguments(); +return GetTemplateArgumentType(TA, i, GetTU(CT)); + } + const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl(); + if (!RecordDecl) return MakeCXType(QualType(), GetTU(CT)); - const TemplateArgument &A = TA[i]; - if (A.getKind() != TemplateArgument::Type) + const ClassTemplateSpecializationDecl *TemplateDecl = +dyn_cast(RecordDecl); + if (!TemplateDecl) return MakeCXType(QualType(), GetTU(CT)); - return MakeCXType(A.getAsType(), GetTU(CT)); + const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs(); + return GetTemplateArgumentType(TA, i, GetTU(CT)); } unsigned clang_Type_visitFields(CXType PT, Index: test/Index/print-type.cpp === --- test/Index/print-type.cpp +++ test/Index/print-type.cpp @@ -61,6 +61,15 @@ struct TypeAliasUser { TypeAlias foo; }; +template +struct Specialization {}; + +template<> +struct Specialization; + +Specialization& > templRefParam; +auto autoTemplRefParam = templRefParam; + // RUN: c-index-test -test-print-type %s -std=c++14 | FileCheck %s // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0] @@ -157,3 +166,14 @@ // CHECK: TemplateTypeParameter=T:59:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0] // CHECK: FieldDecl=foo:62:39 (Definition) [type=TypeAlias] [typekind=Unexposed] [canonicaltype=outer::Qux] [canonicaltypekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=1] // CHECK: TemplateRef=TypeAlias:60:1 [type=] [typekind=Invalid] [isPOD=0] +// CHECK: ClassTemplate=Specialization:65:8 (Definition) [type=] [typekind=Invalid] [isPOD=0] +// CHECK: TemplateTypeParameter=T:64:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0] +// CHECK: StructDecl=Specialization:68:8 [Specialization of Specialization:65:8] [type=Specialization] [typekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0] +// CHECK: VarDecl=templRefParam:70:40 (Definition) [type=Specialization &>] [typekind=Unexposed] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: TemplateRef=Specialization:65:8 [type=] [typekind=Invalid] [isPOD=0] +// CHECK: TemplateRef=Specialization:65:8 [type=] [typekind=Invalid] [isPOD=0] +// CHECK: CallExpr=Specialization:65:8 [type=Specialization &>] [typekind=Unexposed] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: VarDecl=autoTemplRefParam:71:6 (Definition) [type=Specialization &>] [typekind=Auto] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: CallExpr=Specialization:65:8 [type=Specialization &>] [typekind=Auto] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueRefer
[PATCH] D27384: [libclang] Restore clang_getNumTemplateArguments/clang_getTemplateArgumentAsType functionality
skalinichev added a project: clang-c. skalinichev updated this revision to Diff 80179. https://reviews.llvm.org/D27384 Files: test/Index/print-type.cpp tools/libclang/CXType.cpp Index: tools/libclang/CXType.cpp === --- tools/libclang/CXType.cpp +++ tools/libclang/CXType.cpp @@ -143,6 +143,16 @@ return static_cast(CT.data[1]); } +template +static CXType GetTemplateArgumentType(const T &TA, unsigned i, CXTranslationUnit TU) { + if (TA.size() <= i) +return MakeCXType(QualType(), TU); + const TemplateArgument &A = TA[i]; + if (A.getKind() != TemplateArgument::Type) +return MakeCXType(QualType(), TU); + return MakeCXType(A.getAsType(), TU); +} + extern "C" { CXType clang_getCursorType(CXCursor C) { @@ -926,9 +936,16 @@ return -1; const TemplateSpecializationType *Specialization = T->getAs(); - if (!Specialization) + if (Specialization) +return Specialization->template_arguments().size(); + const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl(); + if (!RecordDecl) return -1; - return Specialization->template_arguments().size(); + const ClassTemplateSpecializationDecl *TemplateDecl = +dyn_cast(RecordDecl); + if (!TemplateDecl) +return -1; + return TemplateDecl->getTemplateArgs().size(); } CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) { @@ -938,15 +955,19 @@ const TemplateSpecializationType *Specialization = T->getAs(); - if (!Specialization) -return MakeCXType(QualType(), GetTU(CT)); - auto TA = Specialization->template_arguments(); - if (TA.size() <= i) + if (Specialization) { +auto TA = Specialization->template_arguments(); +return GetTemplateArgumentType(TA, i, GetTU(CT)); + } + const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl(); + if (!RecordDecl) return MakeCXType(QualType(), GetTU(CT)); - const TemplateArgument &A = TA[i]; - if (A.getKind() != TemplateArgument::Type) + const ClassTemplateSpecializationDecl *TemplateDecl = +dyn_cast(RecordDecl); + if (!TemplateDecl) return MakeCXType(QualType(), GetTU(CT)); - return MakeCXType(A.getAsType(), GetTU(CT)); + const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs(); + return GetTemplateArgumentType(TA, i, GetTU(CT)); } unsigned clang_Type_visitFields(CXType PT, Index: test/Index/print-type.cpp === --- test/Index/print-type.cpp +++ test/Index/print-type.cpp @@ -61,6 +61,15 @@ struct TypeAliasUser { TypeAlias foo; }; +template +struct Specialization {}; + +template<> +struct Specialization; + +Specialization& > templRefParam; +auto autoTemplRefParam = templRefParam; + // RUN: c-index-test -test-print-type %s -std=c++14 | FileCheck %s // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0] @@ -157,3 +166,14 @@ // CHECK: TemplateTypeParameter=T:59:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0] // CHECK: FieldDecl=foo:62:39 (Definition) [type=TypeAlias] [typekind=Unexposed] [canonicaltype=outer::Qux] [canonicaltypekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=1] // CHECK: TemplateRef=TypeAlias:60:1 [type=] [typekind=Invalid] [isPOD=0] +// CHECK: ClassTemplate=Specialization:65:8 (Definition) [type=] [typekind=Invalid] [isPOD=0] +// CHECK: TemplateTypeParameter=T:64:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0] +// CHECK: StructDecl=Specialization:68:8 [Specialization of Specialization:65:8] [type=Specialization] [typekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0] +// CHECK: VarDecl=templRefParam:70:40 (Definition) [type=Specialization &>] [typekind=Unexposed] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: TemplateRef=Specialization:65:8 [type=] [typekind=Invalid] [isPOD=0] +// CHECK: TemplateRef=Specialization:65:8 [type=] [typekind=Invalid] [isPOD=0] +// CHECK: CallExpr=Specialization:65:8 [type=Specialization &>] [typekind=Unexposed] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: VarDecl=autoTemplRefParam:71:6 (Definition) [type=Specialization &>] [typekind=Auto] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: CallExpr=Specialization:65:8 [type=Specialization &>] [typekind=Auto] [canonicaltype=Specialization &>] [canonicaltypekind=Record] [templateargs/1= [type=Specialization &] [typekind=LValueReference]] [isPOD=1] +// CHECK: UnexposedExpr=templRefParam:70:40 [type=const S
[PATCH] D27384: [libclang] Restore clang_getNumTemplateArguments/clang_getTemplateArgumentAsType functionality
EricWF added a comment. Sorry about Herald adding me as a reviewer. I need to fix my filters. https://reviews.llvm.org/D27384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r288586 - [clang-move] don't miss ', ' in json output when there are duplicate elements.
Author: ioeric Date: Sat Dec 3 09:28:03 2016 New Revision: 288586 URL: http://llvm.org/viewvc/llvm-project?rev=288586&view=rev Log: [clang-move] don't miss ',' in json output when there are duplicate elements. Modified: clang-tools-extra/trunk/clang-move/tool/ClangMoveMain.cpp Modified: clang-tools-extra/trunk/clang-move/tool/ClangMoveMain.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-move/tool/ClangMoveMain.cpp?rev=288586&r1=288585&r2=288586&view=diff == --- clang-tools-extra/trunk/clang-move/tool/ClangMoveMain.cpp (original) +++ clang-tools-extra/trunk/clang-move/tool/ClangMoveMain.cpp Sat Dec 3 09:28:03 2016 @@ -144,15 +144,13 @@ int main(int argc, const char **argv) { if (DumpDecls) { llvm::outs() << "[\n"; const auto &Declarations = Reporter.getDeclarationList(); -for (auto DeclPair : Declarations) { +for (auto I = Declarations.begin(), E = Declarations.end(); I != E; ++I) { llvm::outs() << " {\n"; - llvm::outs() << "\"DeclarationName\": \"" << DeclPair.first - << "\",\n"; - llvm::outs() << "\"DeclarationType\": \"" << DeclPair.second - << "\"\n"; + llvm::outs() << "\"DeclarationName\": \"" << I->first << "\",\n"; + llvm::outs() << "\"DeclarationType\": \"" << I->second << "\"\n"; llvm::outs() << " }"; // Don't print trailing "," at the end of last element. - if (DeclPair != *(--Declarations.end())) + if (I != std::prev(E)) llvm::outs() << ",\n"; } llvm::outs() << "\n]\n"; @@ -196,10 +194,10 @@ int main(int argc, const char **argv) { Files.insert(it.first); auto WriteToJson = [&](llvm::raw_ostream &OS) { OS << "[\n"; - for (auto File : Files) { + for (auto I = Files.begin(), E = Files.end(); I != E; ++I) { OS << " {\n"; -OS << "\"FilePath\": \"" << File << "\",\n"; -const auto *Entry = FileMgr.getFile(File); +OS << "\"FilePath\": \"" << *I << "\",\n"; +const auto *Entry = FileMgr.getFile(*I); auto ID = SM.translateFile(Entry); std::string Content; llvm::raw_string_ostream ContentStream(Content); @@ -207,7 +205,7 @@ int main(int argc, const char **argv) { OS << "\"SourceText\": \"" << llvm::yaml::escape(ContentStream.str()) << "\"\n"; OS << " }"; -if (File != *(--Files.end())) +if (I != std::prev(E)) OS << ",\n"; } OS << "\n]\n"; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27365: [analyzer] Print type for SymbolRegionValues when dumping to stream
ddcc added a comment. Yeah, I had to implement implicit type promotion and conversion, because Z3 checks expression types pretty strictly. https://reviews.llvm.org/D27365 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27387: [libc++] Add a key function for bad_function_call
smeenai created this revision. smeenai added reviewers: EricWF, mclow.lists. smeenai added a subscriber: cfe-commits. Herald added a subscriber: mgorny. bad_function_call is currently an empty class, so any object files using that class will end up with their own copy of its typeinfo, typeinfo name and vtable, leading to unnecessary duplication that has to be resolved by the dynamic linker. Instead, give bad_function_call a key function and put a definition for that key function in libc++ itself, to centralize the typeinfo and vtable. This is consistent with the behavior for other exception classes. The key functions are defined in libc++ rather than libc++abi since the class is defined in the libc++ versioning namespace, so ABI compatibility with libstdc++ is not a concern. https://reviews.llvm.org/D27387 Files: include/functional lib/CMakeLists.txt lib/abi/x86_64-apple-darwin16.0.0.abilist lib/abi/x86_64-unknown-linux-gnu.abilist src/functional.cpp Index: src/functional.cpp === --- /dev/null +++ src/functional.cpp @@ -0,0 +1,24 @@ +//===--- functional.cpp ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +#include "functional" + +_LIBCPP_BEGIN_NAMESPACE_STD + +bad_function_call::~bad_function_call() _NOEXCEPT +{ +} + +const char* +bad_function_call::what() const _NOEXCEPT +{ +return "std::bad_function_call"; +} + +_LIBCPP_END_NAMESPACE_STD Index: lib/abi/x86_64-unknown-linux-gnu.abilist === --- lib/abi/x86_64-unknown-linux-gnu.abilist +++ lib/abi/x86_64-unknown-linux-gnu.abilist @@ -172,6 +172,7 @@ {'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__115basic_streambufIcNS_11char_traitsIcEEE6getlocEv'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__115basic_streambufIwNS_11char_traitsIwEEE6getlocEv'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__115error_condition7messageEv'} +{'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__117bad_function_call4whatEv'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE11do_groupingEv'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_neg_formatEv'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__117moneypunct_bynameIcLb0EE13do_pos_formatEv'} @@ -1073,6 +1074,9 @@ {'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117__widen_from_utf8ILm32EED0Ev'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117__widen_from_utf8ILm32EED1Ev'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117__widen_from_utf8ILm32EED2Ev'} +{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117bad_function_callD0Ev'} +{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117bad_function_callD1Ev'} +{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117bad_function_callD2Ev'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117declare_reachableEPv'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117iostream_categoryEv'} {'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc'} @@ -1545,6 +1549,7 @@ {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__117__assoc_sub_stateE', 'size': 24} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__117__widen_from_utf8ILm16EEE', 'size': 24} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__117__widen_from_utf8ILm32EEE', 'size': 24} +{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__117bad_function_callE', 'size': 24} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__117moneypunct_bynameIcLb0EEE', 'size': 24} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__117moneypunct_bynameIcLb1EEE', 'size': 24} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__117moneypunct_bynameIwLb0EEE', 'size': 24} @@ -1670,6 +1675,7 @@ {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__117__assoc_sub_stateE', 'size': 28} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__117__widen_from_utf8ILm16EEE', 'size': 35} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__117__widen_from_utf8ILm32EEE', 'size': 35} +{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__117bad_function_callE', 'size': 28} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__117moneypunct_bynameIcLb0EEE', 'size': 35} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__117moneypunct_bynameIcLb1EEE', 'size': 35} {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__117moneypunct_bynameIwLb0EEE', 'size': 35} @@ -1785,6 +1791,7 @@ {'is_defined': True, 'type': 'OBJECT', 'name': '_ZTVNSt3__117__assoc_sub_stateE
[PATCH] D27387: [libc++] Add a key function for bad_function_call
smeenai added inline comments. Comment at: lib/CMakeLists.txt:162 -# Add a object library that contains the compiled source files. +# Add an object library that contains the compiled source files. add_library(cxx_objects OBJECT ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) This may seem like a completely unrelated change, but it's actually important to force cmake to get re-run so that the glob for source files picks up on the new file. https://reviews.llvm.org/D27387 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27387: [libc++] Add a key function for bad_function_call
smeenai added inline comments. Comment at: src/functional.cpp:1 +//===--- functional.cpp ---===// +// Should I clang-format new files? I based the style of this file on the existing source files, but clang-format suggests something very different. https://reviews.llvm.org/D27387 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27383: Add a new clang-format style option ObjCBlockResetsIndent.
yixiang updated this revision to Diff 80192. yixiang added a comment. - Don't reset indent for statements with multiple blocks. https://reviews.llvm.org/D27383 Files: docs/ClangFormatStyleOptions.rst include/clang/Format/Format.h lib/Format/ContinuationIndenter.cpp lib/Format/Format.cpp unittests/Format/FormatTest.cpp Index: unittests/Format/FormatTest.cpp === --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -11263,6 +11263,128 @@ FourIndent); } +TEST_F(FormatTest, FormatsBlocksWithIndentResetting) { + FormatStyle ShortBlocks = getLLVMStyle(); + ShortBlocks.AllowShortBlocksOnASingleLine = true; + ShortBlocks.ObjCBlockResetsIndent = true; + + verifyFormat("int (^Block)(int, int);", ShortBlocks); + verifyFormat("int (^Block1)(int, int) = ^(int i, int j)", ShortBlocks); + verifyFormat("void (^block)(int) = ^(id test) { int i; };", ShortBlocks); + verifyFormat("void (^block)(int) = ^(int test) { int i; };", ShortBlocks); + verifyFormat("void (^block)(int) = ^id(int test) { int i; };", ShortBlocks); + verifyFormat("void (^block)(int) = ^int(int test) { int i; };", ShortBlocks); + + verifyFormat("foo(^{ bar(); });", ShortBlocks); + verifyFormat("foo(a, ^{ bar(); });", ShortBlocks); + verifyFormat("{ void (^block)(Object *x); }", ShortBlocks); + + verifyFormat("[operation setCompletionBlock:^{\n" + " [self onOperationDone];\n" + "}];"); + verifyFormat("int i = {[operation setCompletionBlock:^{\n" + " [self onOperationDone];\n" + "}]};"); + + verifyFormat("[operation setCompletionBlock:^(int *i) {\n" + " f();\n" + "}];"); + + verifyFormat("int a = [operation block:^int(int *i) {\n" + " return 1;\n" + "}];"); + + FormatStyle ResetsIndent = getLLVMStyle(); + ResetsIndent.ObjCBlockResetsIndent = true; + verifyFormat("[myObject doSomethingWith:arg1\n" + " aaa:^int(int *a) {\n" + " return 1;\n" + "}\n" + " bbb:f(a * )];", + ResetsIndent); + + verifyFormat("[operation setCompletionBlock:^{\n" + " [self.delegate newDataAvailable];\n" + "}];", + ResetsIndent); + verifyFormat("dispatch_async(_fileIOQueue, ^{\n" + " NSString *path = [self sessionFilePath];\n" + " if (path) {\n" + "// ...\n" + " }\n" + "});", + ResetsIndent); + verifyFormat("[[SessionService sharedService]\n" + "loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" + " if (window) {\n" + "[self windowDidLoad:window];\n" + " } else {\n" + "[self errorLoadingWindow];\n" + " }\n" + "}];", + ResetsIndent); + verifyFormat("void (^largeBlock)(void) = ^{\n" + " // ...\n" + "};\n", + ResetsIndent); + + FormatStyle ResetsIndent60 = getLLVMStyleWithColumns(60); + ResetsIndent60.ObjCBlockResetsIndent = true; + verifyFormat("[[SessionService sharedService]\n" + "loadWindowWithCompletionBlock: //\n" + "^(SessionWindow *window) {\n" + " if (window) {\n" + "[self windowDidLoad:window];\n" + " } else {\n" + "[self errorLoadingWindow];\n" + " }\n" + "}];", + ResetsIndent60); + + verifyFormat("[myObject doSomethingWith:arg1\n" + "firstBlock:^(Foo *a) {\n" + " // ...\n" + " int i;\n" + "}\n" + "secondBlock:^(Bar *b) {\n" + " // ...\n" + " int i;\n" + "}\n" + "thirdBlock:^Foo(Bar *b) {\n" + " // ...\n" + " int i;\n" + "}];", + ResetsIndent); + verifyFormat("[myObject doSomethingWith:arg1\n" + " firstBlock:-1\n" + " secondBlock:^(Bar *b) {\n" + " // ...\n" + " int i;\n" + "}];", + ResetsIndent); + + verifyFormat("f(^{\n" + " @autoreleasepool {\n" + "if (a) {\n" + " g();\n" + "}\n" + " }\n" + "});", + ResetsIndent); + verifyFormat("Block b = ^int *(A *a, B *b) {}", ResetsIndent); + verifyFormat("BOOL (^aaa)(void) = ^BOOL {\n" + "};", + ResetsIndent); + + FormatStyle FourIndent = getLLVMStyle(); + FourIndent.ObjCBlockIndentWidth = 4; + FourIndent.ObjCBlockResetsI
r288604 - [WebAssembly] Revert r288447.
Author: djg Date: Sat Dec 3 17:03:52 2016 New Revision: 288604 URL: http://llvm.org/viewvc/llvm-project?rev=288604&view=rev Log: [WebAssembly] Revert r288447. Revert r288447 which introduced -mdirect. It turns out we don't need a custom flag for this, as the information we need is in the target triple. Modified: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/Basic/Targets.cpp Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=288604&r1=288603&r2=288604&view=diff == --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Sat Dec 3 17:03:52 2016 @@ -1613,8 +1613,6 @@ def ffixed_x18 : Flag<["-"], "ffixed-x18 def msimd128 : Flag<["-"], "msimd128">, Group; def mno_simd128 : Flag<["-"], "mno-simd128">, Group; -def mdirect : Flag<["-"], "mdirect">, Group; -def mno_direct : Flag<["-"], "mno-direct">, Group; def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">, Flags<[HelpHidden]>, Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=288604&r1=288603&r2=288604&view=diff == --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Sat Dec 3 17:03:52 2016 @@ -8019,10 +8019,6 @@ private: SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1)); continue; } - if (Feature == "+direct") -continue; - if (Feature == "-direct") -continue; Diags.Report(diag::err_opt_not_valid_with_opt) << Feature << "-target-feature"; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r288605 - Add the --no-color option to the git call in the doc when using clang-format-diff
Author: sylvestre Date: Sat Dec 3 17:22:45 2016 New Revision: 288605 URL: http://llvm.org/viewvc/llvm-project?rev=288605&view=rev Log: Add the --no-color option to the git call in the doc when using clang-format-diff Modified: cfe/trunk/docs/ClangFormat.rst cfe/trunk/tools/clang-format/clang-format-diff.py Modified: cfe/trunk/docs/ClangFormat.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormat.rst?rev=288605&r1=288604&r2=288605&view=diff == --- cfe/trunk/docs/ClangFormat.rst (original) +++ cfe/trunk/docs/ClangFormat.rst Sat Dec 3 17:22:45 2016 @@ -184,7 +184,7 @@ So to reformat all the lines in the late .. code-block:: console - git diff -U0 HEAD^ | clang-format-diff.py -i -p1 + git diff -U0 --no-color HEAD^ | clang-format-diff.py -i -p1 In an SVN client, you can do: Modified: cfe/trunk/tools/clang-format/clang-format-diff.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/clang-format-diff.py?rev=288605&r1=288604&r2=288605&view=diff == --- cfe/trunk/tools/clang-format/clang-format-diff.py (original) +++ cfe/trunk/tools/clang-format/clang-format-diff.py Sat Dec 3 17:22:45 2016 @@ -17,7 +17,7 @@ This script reads input from a unified d lines. This is useful to reformat all the lines touched by a specific patch. Example usage for git/svn users: - git diff -U0 HEAD^ | clang-format-diff.py -p1 -i + git diff -U0 --no-color HEAD^ | clang-format-diff.py -p1 -i svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i """ ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26657: [Sema] Respect DLL attributes more faithfully
smeenai updated this revision to Diff 80193. smeenai added a comment. Addressing comments https://reviews.llvm.org/D26657 Files: lib/Sema/SemaTemplate.cpp test/CodeGenCXX/dllexport.cpp test/CodeGenCXX/windows-itanium-dllexport.cpp Index: test/CodeGenCXX/windows-itanium-dllexport.cpp === --- test/CodeGenCXX/windows-itanium-dllexport.cpp +++ test/CodeGenCXX/windows-itanium-dllexport.cpp @@ -23,3 +23,8 @@ // CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcEaSERKS0_ // CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv +c g; +template class __declspec(dllexport) c; + +// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdEaSERKS0_ +// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv Index: test/CodeGenCXX/dllexport.cpp === --- test/CodeGenCXX/dllexport.cpp +++ test/CodeGenCXX/dllexport.cpp @@ -771,6 +771,13 @@ // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ" // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclExportedDefTemplateIiE1fEv +template struct ImplicitInstantiationExplicitInstantiationDefExportedTemplate { void f() {} }; +ImplicitInstantiationExplicitInstantiationDefExportedTemplate ImplicitInstantiationExplicitInstantiationDefExportedTemplateInstance; +template class __declspec(dllexport) ImplicitInstantiationExplicitInstantiationDefExportedTemplate; +USEMEMFUNC(ImplicitInstantiationExplicitInstantiationDefExportedTemplate, f); +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExplicitInstantiationDefExportedTemplate@H@@QAEXXZ" +// G32-DAG: define weak_odr x86_thiscallcc void @_ZN61ImplicitInstantiationExplicitInstantiationDefExportedTemplateIiE1fEv + namespace { struct InternalLinkageType {}; } struct __declspec(dllexport) PR23308 { void f(InternalLinkageType*); Index: lib/Sema/SemaTemplate.cpp === --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -7435,6 +7435,30 @@ return false; } +/// Make a dllexport or dllimport attr on a class template specialization take +/// effect. +static void dllExportImportClassTemplateSpecialization( +Sema &S, ClassTemplateSpecializationDecl *Def) { + auto *A = cast_or_null(getDLLAttr(Def)); + assert(A && "dllExportImportClassTemplateSpecialization called " + "on Def without dllexport or dllimport"); + + // We reject explicit instantiations in class scope, so there should + // never be any delayed exported classes to worry about. + assert(S.DelayedDllExportClasses.empty() && + "delayed exports present at explicit instantiation"); + S.checkClassLevelDLLAttribute(Def); + + // Propagate attribute to base class templates. + for (auto &B : Def->bases()) { +if (auto *BT = dyn_cast_or_null( +B.getType()->getAsCXXRecordDecl())) + S.propagateDLLAttrToBaseClassTemplate(Def, A, BT, B.getLocStart()); + } + + S.referenceDLLExportedClassMethods(); +} + // Explicit instantiation of a class template specialization DeclResult Sema::ActOnExplicitInstantiation(Scope *S, @@ -7681,24 +7705,33 @@ getDLLAttr(Specialization)->clone(getASTContext())); A->setInherited(true); Def->addAttr(A); - -// We reject explicit instantiations in class scope, so there should -// never be any delayed exported classes to worry about. -assert(DelayedDllExportClasses.empty() && - "delayed exports present at explicit instantiation"); -checkClassLevelDLLAttribute(Def); - -// Propagate attribute to base class templates. -for (auto &B : Def->bases()) { - if (auto *BT = dyn_cast_or_null( - B.getType()->getAsCXXRecordDecl())) -propagateDLLAttrToBaseClassTemplate(Def, A, BT, B.getLocStart()); -} - -referenceDLLExportedClassMethods(); +dllExportImportClassTemplateSpecialization(*this, Def); } } +// Fix a TSK_ImplicitInstantiation followed by a +// TSK_ExplicitInstantiationDefinition +if (Old_TSK == TSK_ImplicitInstantiation && +Specialization->hasAttr() && +(Context.getTargetInfo().getCXXABI().isMicrosoft() || + Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) { + // In the MS ABI, an explicit instantiation definition can add a dll + // attribute to a template with a previous implicit instantiation. + // MinGW doesn't allow this. We limit clang to only adding dllexport, to + // avoid potentially strange codegen behavior. For example, if we extend + // this conditional to dllimport, and we have a source file calling a + // method on an implicitly instantiated template class instance and then +
[PATCH] D26657: [Sema] Respect DLL attributes more faithfully
smeenai added inline comments. Comment at: lib/Sema/SemaTemplate.cpp:7710 +(Context.getTargetInfo().getCXXABI().isMicrosoft() || + Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) { + // In the MS ABI, an explicit instantiation definition can add a dll hans wrote: > smeenai wrote: > > hans wrote: > > > Why the isWindowsItaniumEnvironment check? I'd expect checking for the MS > > > ABI is sufficient? > > windows-itanium in general tries to stick to MSVC semantics for > > dllexport/import annotations (unlike Cygwin and MinGW which kinda do their > > own thing). This is consistent with the conditional for the previous case > > (lines 7691 to 7693 in this diff). > Oh I see, this seems to be a new thing, starting with e.g. r284288. > > Seems fine then, but I'm a little worried that we're adding another variable > into the matrix here. IIRC, we key dll attribute behaviour off > `getCXXABI().isMicrosoft()` in lots of places. You're right; the current situation isn't ideal. I can clean that up in a follow-up. https://reviews.llvm.org/D26657 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27384: [libclang] Restore clang_getNumTemplateArguments/clang_getTemplateArgumentAsType functionality
compnerd added inline comments. Comment at: tools/libclang/CXType.cpp:151-153 + if (A.getKind() != TemplateArgument::Type) +return MakeCXType(QualType(), TU); + return MakeCXType(A.getAsType(), TU); Isn't this more compact as: return MakeCXType(A.getKind() == TemplateArgument::Type ? A.getAsType() : QualType(), TU); Comment at: tools/libclang/CXType.cpp:961 +return GetTemplateArgumentType(TA, i, GetTU(CT)); + } + const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl(); Why not inline the template arguments? Comment at: tools/libclang/CXType.cpp:965 return MakeCXType(QualType(), GetTU(CT)); - const TemplateArgument &A = TA[i]; - if (A.getKind() != TemplateArgument::Type) + const ClassTemplateSpecializationDecl *TemplateDecl = +dyn_cast(RecordDecl); Use `auto`, the type is obvious. Comment at: tools/libclang/CXType.cpp:970 + const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs(); + return GetTemplateArgumentType(TA, i, GetTU(CT)); } Similar. https://reviews.llvm.org/D27384 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r288614 - TableGen: Adapt to llvm r288612
Author: matze Date: Sat Dec 3 23:55:09 2016 New Revision: 288614 URL: http://llvm.org/viewvc/llvm-project?rev=288614&view=rev Log: TableGen: Adapt to llvm r288612 Modified: cfe/trunk/utils/TableGen/ClangASTNodesEmitter.cpp cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Modified: cfe/trunk/utils/TableGen/ClangASTNodesEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangASTNodesEmitter.cpp?rev=288614&r1=288613&r2=288614&view=diff == --- cfe/trunk/utils/TableGen/ClangASTNodesEmitter.cpp (original) +++ cfe/trunk/utils/TableGen/ClangASTNodesEmitter.cpp Sat Dec 3 23:55:09 2016 @@ -47,7 +47,7 @@ class ClangASTNodesEmitter { if (&R == &Root && !BaseSuffix.empty()) return BaseSuffix; -return R.getName() + BaseSuffix; +return R.getName().str() + BaseSuffix; } std::pair EmitNode (const ChildMap &Tree, raw_ostream& OS, Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=288614&r1=288613&r2=288614&view=diff == --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original) +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Sat Dec 3 23:55:09 2016 @@ -2695,7 +2695,7 @@ static std::string GetSubjectWithSuffix( static std::string GenerateCustomAppertainsTo(const Record &Subject, raw_ostream &OS) { - std::string FnName = "is" + Subject.getName(); + std::string FnName = "is" + Subject.getName().str(); // If this code has already been generated, simply return the previous // instance of it. @@ -2744,7 +2744,7 @@ static std::string GenerateAppertainsTo( // Otherwise, generate an appertainsTo check specific to this attribute which // checks all of the given subjects against the Decl passed in. Return the // name of that check to the caller. - std::string FnName = "check" + Attr.getName() + "AppertainsTo"; + std::string FnName = "check" + Attr.getName().str() + "AppertainsTo"; std::stringstream SS; SS << "static bool " << FnName << "(Sema &S, const AttributeList &Attr, "; SS << "const Decl *D) {\n"; @@ -2915,7 +2915,7 @@ static std::string GenerateSpellingIndex // Generate the enumeration we will use for the mapping. SemanticSpellingMap SemanticToSyntacticMap; std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap); - std::string Name = Attr.getName() + "AttrSpellingMap"; + std::string Name = Attr.getName().str() + "AttrSpellingMap"; OS << "static unsigned " << Name << "(const AttributeList &Attr) {\n"; OS << Enum; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits