sammccall created this revision.
sammccall added reviewers: kadircet, lh123.
Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, 
ilya-biryukov.
Herald added a project: clang.

Semantically they're the same thing, and it's important when the underlying
struct is anonymous.

There doesn't seem to be a problem attaching the same comment to multiple things
as it already happens with `/** doc */ int a, b;`

This affects an Index test but the results look better (name present, USR points
to the typedef).

Fixes https://github.com/clangd/clangd/issues/189


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D70203

Files:
  clang-tools-extra/clangd/unittests/XRefsTests.cpp
  clang/lib/AST/ASTContext.cpp
  clang/test/Index/annotate-comments-typedef.m
  clang/test/Sema/warn-documentation.cpp


Index: clang/test/Sema/warn-documentation.cpp
===================================================================
--- clang/test/Sema/warn-documentation.cpp
+++ clang/test/Sema/warn-documentation.cpp
@@ -868,7 +868,7 @@
 /// \brief\author Aaa
 typedef struct test_noattach14 *test_attach15;
 
-// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+// expected-warning@+1 + {{empty paragraph passed to '\brief' command}}
 /// \brief\author Aaa
 typedef struct test_attach16 { int a; } test_attach17;
 
@@ -886,7 +886,7 @@
 /// \brief\author Aaa
 struct test_attach20;
 
-// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+// expected-warning@+1 + {{empty paragraph passed to '\brief' command}}
 /// \brief\author Aaa
 typedef struct test_attach21 {
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
Index: clang/test/Index/annotate-comments-typedef.m
===================================================================
--- clang/test/Index/annotate-comments-typedef.m
+++ clang/test/Index/annotate-comments-typedef.m
@@ -17,7 +17,7 @@
         MyEnumBar, /**< value Bar */
         MyEnumBaz, /**< value Baz */
 } MyEnum;
-// CHECK: TypedefDecl=MyEnum:[[@LINE-1]]:3 (Definition) FullCommentAsHTML=[<p 
class="para-brief"> Documentation for MyEnum </p>] FullCommentAsXML=[<Typedef 
file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-1]]" 
column="3"><Name>&lt;anonymous&gt;</Name><USR>c:@EA@MyEnum</USR><Declaration>typedef
 enum MyEnum MyEnum</Declaration><Abstract><Para> Documentation for MyEnum 
</Para></Abstract></Typedef>]
+// CHECK: TypedefDecl=MyEnum:[[@LINE-1]]:3 (Definition) {{.*}} 
FullCommentAsHTML=[<p class="para-brief"> Documentation for MyEnum </p>] 
FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" 
line="[[@LINE-1]]" 
column="3"><Name>MyEnum</Name><USR>c:@T@MyEnum</USR><Declaration>typedef enum 
MyEnum MyEnum</Declaration><Abstract><Para> Documentation for MyEnum 
</Para></Abstract></Typedef>]
 
 
 /** Documentation for E */
@@ -35,7 +35,7 @@
 typedef struct {
          int iii;
         } Foo;
-// CHECK: TypedefDecl=Foo:[[@LINE-1]]:11 (Definition) FullCommentAsHTML=[<p 
class="para-brief"> Comment about Foo </p>] FullCommentAsXML=[<Typedef 
file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-1]]" 
column="11"><Name>&lt;anonymous&gt;</Name><USR>c:@SA@Foo</USR><Declaration>typedef
 struct Foo Foo</Declaration><Abstract><Para> Comment about Foo 
</Para></Abstract></Typedef>]
+// CHECK: TypedefDecl=Foo:[[@LINE-1]]:11 (Definition) {{.*}} 
FullCommentAsHTML=[<p class="para-brief"> Comment about Foo </p>] 
FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" 
line="[[@LINE-1]]" 
column="11"><Name>Foo</Name><USR>c:@T@Foo</USR><Declaration>typedef struct Foo 
Foo</Declaration><Abstract><Para> Comment about Foo 
</Para></Abstract></Typedef>]
 // CHECK: StructDecl=:[[@LINE-4]]:9 (Definition) {{.*}} BriefComment=[Comment 
about Foo] FullCommentAsHTML=[<p class="para-brief"> Comment about Foo </p>] 
FullCommentAsXML=[<Class file="{{[^"]+}}annotate-comments-typedef.m" 
line="[[@LINE-4]]" 
column="9"><Name>&lt;anonymous&gt;</Name><USR>c:@SA@Foo</USR><Declaration>struct
 {}</Declaration><Abstract><Para> Comment about Foo </Para></Abstract></Class>]
 
 
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -163,7 +163,9 @@
   if (isa<ObjCMethodDecl>(D) || isa<ObjCContainerDecl>(D) ||
       isa<ObjCPropertyDecl>(D) ||
       isa<RedeclarableTemplateDecl>(D) ||
-      isa<ClassTemplateSpecializationDecl>(D))
+      isa<ClassTemplateSpecializationDecl>(D) ||
+      // Allow association with Y across {} in `typedef struct X {} Y`.
+      isa<TypedefDecl>(D))
     return D->getBeginLoc();
   else {
     const SourceLocation DeclLoc = D->getLocation();
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1260,6 +1260,19 @@
           "]\n"
           "text[Typedef]",
       },
+      {
+          R"cpp(// Typedef with embedded definition
+            typedef struct Bar {} Foo;
+            int main() {
+              ^Foo bar;
+            }
+          )cpp",
+          "text[Declared in]code[global namespace]\n"
+          "codeblock(cpp) [\n"
+          "typedef struct Bar Foo\n"
+          "]\n"
+          "text[Typedef with embedded definition]",
+      },
       {
           R"cpp(// Namespace
             namespace ns {


Index: clang/test/Sema/warn-documentation.cpp
===================================================================
--- clang/test/Sema/warn-documentation.cpp
+++ clang/test/Sema/warn-documentation.cpp
@@ -868,7 +868,7 @@
 /// \brief\author Aaa
 typedef struct test_noattach14 *test_attach15;
 
-// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+// expected-warning@+1 + {{empty paragraph passed to '\brief' command}}
 /// \brief\author Aaa
 typedef struct test_attach16 { int a; } test_attach17;
 
@@ -886,7 +886,7 @@
 /// \brief\author Aaa
 struct test_attach20;
 
-// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+// expected-warning@+1 + {{empty paragraph passed to '\brief' command}}
 /// \brief\author Aaa
 typedef struct test_attach21 {
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
Index: clang/test/Index/annotate-comments-typedef.m
===================================================================
--- clang/test/Index/annotate-comments-typedef.m
+++ clang/test/Index/annotate-comments-typedef.m
@@ -17,7 +17,7 @@
         MyEnumBar, /**< value Bar */
         MyEnumBaz, /**< value Baz */
 } MyEnum;
-// CHECK: TypedefDecl=MyEnum:[[@LINE-1]]:3 (Definition) FullCommentAsHTML=[<p class="para-brief"> Documentation for MyEnum </p>] FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-1]]" column="3"><Name>&lt;anonymous&gt;</Name><USR>c:@EA@MyEnum</USR><Declaration>typedef enum MyEnum MyEnum</Declaration><Abstract><Para> Documentation for MyEnum </Para></Abstract></Typedef>]
+// CHECK: TypedefDecl=MyEnum:[[@LINE-1]]:3 (Definition) {{.*}} FullCommentAsHTML=[<p class="para-brief"> Documentation for MyEnum </p>] FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-1]]" column="3"><Name>MyEnum</Name><USR>c:@T@MyEnum</USR><Declaration>typedef enum MyEnum MyEnum</Declaration><Abstract><Para> Documentation for MyEnum </Para></Abstract></Typedef>]
 
 
 /** Documentation for E */
@@ -35,7 +35,7 @@
 typedef struct {
          int iii;
         } Foo;
-// CHECK: TypedefDecl=Foo:[[@LINE-1]]:11 (Definition) FullCommentAsHTML=[<p class="para-brief"> Comment about Foo </p>] FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-1]]" column="11"><Name>&lt;anonymous&gt;</Name><USR>c:@SA@Foo</USR><Declaration>typedef struct Foo Foo</Declaration><Abstract><Para> Comment about Foo </Para></Abstract></Typedef>]
+// CHECK: TypedefDecl=Foo:[[@LINE-1]]:11 (Definition) {{.*}} FullCommentAsHTML=[<p class="para-brief"> Comment about Foo </p>] FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-1]]" column="11"><Name>Foo</Name><USR>c:@T@Foo</USR><Declaration>typedef struct Foo Foo</Declaration><Abstract><Para> Comment about Foo </Para></Abstract></Typedef>]
 // CHECK: StructDecl=:[[@LINE-4]]:9 (Definition) {{.*}} BriefComment=[Comment about Foo] FullCommentAsHTML=[<p class="para-brief"> Comment about Foo </p>] FullCommentAsXML=[<Class file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-4]]" column="9"><Name>&lt;anonymous&gt;</Name><USR>c:@SA@Foo</USR><Declaration>struct {}</Declaration><Abstract><Para> Comment about Foo </Para></Abstract></Class>]
 
 
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -163,7 +163,9 @@
   if (isa<ObjCMethodDecl>(D) || isa<ObjCContainerDecl>(D) ||
       isa<ObjCPropertyDecl>(D) ||
       isa<RedeclarableTemplateDecl>(D) ||
-      isa<ClassTemplateSpecializationDecl>(D))
+      isa<ClassTemplateSpecializationDecl>(D) ||
+      // Allow association with Y across {} in `typedef struct X {} Y`.
+      isa<TypedefDecl>(D))
     return D->getBeginLoc();
   else {
     const SourceLocation DeclLoc = D->getLocation();
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1260,6 +1260,19 @@
           "]\n"
           "text[Typedef]",
       },
+      {
+          R"cpp(// Typedef with embedded definition
+            typedef struct Bar {} Foo;
+            int main() {
+              ^Foo bar;
+            }
+          )cpp",
+          "text[Declared in]code[global namespace]\n"
+          "codeblock(cpp) [\n"
+          "typedef struct Bar Foo\n"
+          "]\n"
+          "text[Typedef with embedded definition]",
+      },
       {
           R"cpp(// Namespace
             namespace ns {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to