[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-26 Thread Dana Jansens via Phabricator via cfe-commits
danakj added a comment.

I tried modifying the test to pass an AIX target, running on Linux:

  // RUN: %clang_cc1 -triple powerpc64-ibm-aix -emit-pch -o %t/out.pch -F 
%S/Inputs/Frameworks %s
  // RUN: %clang_cc1 -triple powerpc64-ibm-aix -include-pch %t/out.pch -F 
%S/Inputs/Frameworks -fsyntax-only %s

However the test passes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-26 Thread Dana Jansens via Phabricator via cfe-commits
danakj added a comment.

I am not sure how to debug further for AIX, do you have any suggestion?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-26 Thread Dana Jansens via Phabricator via cfe-commits
danakj added a comment.

Here's the relevant part of the test:

  #define DECLARE_ENUMS(name) \
/** enumFromMacro IS_DOXYGEN_SINGLE */ \
enum enumFromMacro { A }; \
/** namedEnumFromMacro IS_DOXYGEN_SINGLE */ \
enum name { B };
  
  /// IS_DOXYGEN_NOT_ATTACHED
  DECLARE_ENUMS(namedEnumFromMacro)

From the error I see:

- The Decl is `enum namedEnumFromMacro`, which has a source location at 74:1, 
and has a spelling location at 74:15.

  DECLARE_ENUMS(namedEnumFromMacro)
  ^ source  ^ spelling

- We then call Decl::getBeginLoc(), which doesn't move the source location 
itself, but does move spelling location.

  #define DECLARE_ENUMS(name) \
/** enumFromMacro IS_DOXYGEN_SINGLE */ \
enum enumFromMacro { A }; \
/** namedEnumFromMacro IS_DOXYGEN_SINGLE */ \
enum name { B };
^ spelling
  
  /// IS_DOXYGEN_NOT_ATTACHED
  DECLARE_ENUMS(namedEnumFromMacro)
  ^ source

It seems that Decl::getBeginLoc() does not have the correct spelling location 
in this test, on AIX. It is staying at the original source location at the 
macro expansion.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-25 Thread Dana Jansens via Phabricator via cfe-commits
danakj updated this revision to Diff 492181.
danakj added a comment.

Add tests for enums inside a macro, other than NS_ENUM and NS_OPTIONS


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/Index/annotate-comments-objc.m

Index: clang/test/Index/annotate-comments-objc.m
===
--- clang/test/Index/annotate-comments-objc.m
+++ clang/test/Index/annotate-comments-objc.m
@@ -48,17 +48,31 @@
 // attach unrelated comments in the following cases where tag decls are
 // embedded in declarators.
 
-#define DECLARE_FUNCTION() \
+#define DECLARE_FUNCTIONS(suffix) \
+/** functionFromMacro IS_DOXYGEN_SINGLE */ \
 void functionFromMacro(void) { \
   typedef struct Struct_notdoxy Struct_notdoxy; \
+} \
+/** functionFromMacroWithSuffix IS_DOXYGEN_SINGLE */ \
+void functionFromMacro##suffix(void) { \
+  typedef struct Struct_notdoxy Struct_notdoxy; \
 }
 
 /// IS_DOXYGEN_NOT_ATTACHED
-DECLARE_FUNCTION()
+DECLARE_FUNCTIONS(WithSuffix)
 
 /// typedef_isdoxy1 IS_DOXYGEN_SINGLE
 typedef struct Struct_notdoxy *typedef_isdoxy1;
 
+#define DECLARE_ENUMS(name) \
+  /** enumFromMacro IS_DOXYGEN_SINGLE */ \
+  enum enumFromMacro { A }; \
+  /** namedEnumFromMacro IS_DOXYGEN_SINGLE */ \
+  enum name { B };
+
+/// IS_DOXYGEN_NOT_ATTACHED
+DECLARE_ENUMS(namedEnumFromMacro)
+
 #endif
 
 // RUN: rm -rf %t
@@ -121,5 +135,8 @@
 // CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: TypedefDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:60:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
-
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacro:{{.*}} BriefComment=[functionFromMacro IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacroWithSuffix:{{.*}} BriefComment=[functionFromMacroWithSuffix IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:65:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:74:1: EnumDecl=enumFromMacro:{{.*}} BriefComment=[enumFromMacro IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:74:15: EnumDecl=namedEnumFromMacro:{{.*}} BriefComment=[namedEnumFromMacro IS_DOXYGEN_SINGLE]
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -181,22 +181,96 @@
 
   const SourceLocation DeclLoc = D->getLocation();
   if (DeclLoc.isMacroID()) {
-if (isa(D)) {
-  // If location of the typedef name is in a macro, it is because being
-  // declared via a macro. Try using declaration's starting location as
-  // the "declaration location".
-  return D->getBeginLoc();
-}
-
-if (const auto *TD = dyn_cast(D)) {
-  // If location of the tag decl is inside a macro, but the spelling of
-  // the tag name comes from a macro argument, it looks like a special
-  // macro like NS_ENUM is being used to define the tag decl.  In that
-  // case, adjust the source location to the expansion loc so that we can
-  // attach the comment to the tag decl.
-  if (SourceMgr.isMacroArgExpansion(DeclLoc) && TD->isCompleteDefinition())
-return SourceMgr.getExpansionLoc(DeclLoc);
+// There are (at least) three types of macros we care about here.
+//
+// 1. Macros that are used in the definition of a type outside the macro,
+//with a comment attached at the macro call site.
+//```
+//#define MAKE_NAME(Foo) Name##Foo
+//
+///// Comment is here, where we use the macro.
+//struct MAKE_NAME(Foo) {
+//int a;
+//int b;
+//};
+//```
+// 2. Macros that define whole things along with the comment.
+//```
+//#define MAKE_METHOD(name) \
+//  /** Comment is here, inside the macro. */ \
+//  void name() {}
+//
+//struct S {
+//  MAKE_METHOD(f)
+//}
+//```
+// 3. Macros that both declare a type and name a decl outside the macro.
+//```
+///// Comment is here, where we use the macro.
+//typedef NS_ENUM(NSInteger, Size) {
+//SizeWidth,
+//SizeHeight
+//};
+//```
+//In this case NS_ENUM declares am enum type, and uses the same name for
+//the typedef declaration that appears outside the macro. The comment
+//here should be applied to both declarations inside and outside the
+//macro.
+//
+

[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-25 Thread Dana Jansens via Phabricator via cfe-commits
danakj updated this revision to Diff 492176.
danakj added a comment.

Improve the comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/Index/annotate-comments-objc.m

Index: clang/test/Index/annotate-comments-objc.m
===
--- clang/test/Index/annotate-comments-objc.m
+++ clang/test/Index/annotate-comments-objc.m
@@ -48,13 +48,18 @@
 // attach unrelated comments in the following cases where tag decls are
 // embedded in declarators.
 
-#define DECLARE_FUNCTION() \
+#define DECLARE_FUNCTIONS(suffix) \
+/** functionFromMacro IS_DOXYGEN_SINGLE */ \
 void functionFromMacro(void) { \
   typedef struct Struct_notdoxy Struct_notdoxy; \
+} \
+/** functionFromMacroWithSuffix IS_DOXYGEN_SINGLE */ \
+void functionFromMacro##suffix(void) { \
+  typedef struct Struct_notdoxy Struct_notdoxy; \
 }
 
 /// IS_DOXYGEN_NOT_ATTACHED
-DECLARE_FUNCTION()
+DECLARE_FUNCTIONS(WithSuffix)
 
 /// typedef_isdoxy1 IS_DOXYGEN_SINGLE
 typedef struct Struct_notdoxy *typedef_isdoxy1;
@@ -121,5 +126,6 @@
 // CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: TypedefDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:60:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
-
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacro:{{.*}} BriefComment=[functionFromMacro IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacroWithSuffix:{{.*}} BriefComment=[functionFromMacroWithSuffix IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:65:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -181,22 +181,96 @@
 
   const SourceLocation DeclLoc = D->getLocation();
   if (DeclLoc.isMacroID()) {
-if (isa(D)) {
-  // If location of the typedef name is in a macro, it is because being
-  // declared via a macro. Try using declaration's starting location as
-  // the "declaration location".
-  return D->getBeginLoc();
-}
-
-if (const auto *TD = dyn_cast(D)) {
-  // If location of the tag decl is inside a macro, but the spelling of
-  // the tag name comes from a macro argument, it looks like a special
-  // macro like NS_ENUM is being used to define the tag decl.  In that
-  // case, adjust the source location to the expansion loc so that we can
-  // attach the comment to the tag decl.
-  if (SourceMgr.isMacroArgExpansion(DeclLoc) && TD->isCompleteDefinition())
-return SourceMgr.getExpansionLoc(DeclLoc);
+// There are (at least) three types of macros we care about here.
+//
+// 1. Macros that are used in the definition of a type outside the macro,
+//with a comment attached at the macro call site.
+//```
+//#define MAKE_NAME(Foo) Name##Foo
+//
+///// Comment is here, where we use the macro.
+//struct MAKE_NAME(Foo) {
+//int a;
+//int b;
+//};
+//```
+// 2. Macros that define whole things along with the comment.
+//```
+//#define MAKE_METHOD(name) \
+//  /** Comment is here, inside the macro. */ \
+//  void name() {}
+//
+//struct S {
+//  MAKE_METHOD(f)
+//}
+//```
+// 3. Macros that both declare a type and name a decl outside the macro.
+//```
+///// Comment is here, where we use the macro.
+//typedef NS_ENUM(NSInteger, Size) {
+//SizeWidth,
+//SizeHeight
+//};
+//```
+//In this case NS_ENUM declares am enum type, and uses the same name for
+//the typedef declaration that appears outside the macro. The comment
+//here should be applied to both declarations inside and outside the
+//macro.
+//
+// We have found a Decl name that comes from inside a macro, but
+// Decl::getLocation() returns the place where the macro is being called.
+// If the declaration (and not just the name) resides inside the macro,
+// then we want to map Decl::getLocation() into the macro to where the
+// declaration and its attached comment (if any) were written.
+//
+// This mapping into the macro is done by mapping the location to its
+// spelling location, however even if the declaration is inside a macro,
+// the name's spelling can come from a 

[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-25 Thread Dana Jansens via Phabricator via cfe-commits
danakj added inline comments.



Comment at: clang/test/Index/annotate-comments-objc.m:121
 // CHECK: annotate-comments-objc.m:32:9: 
ObjCInstanceMethodDecl=method1_isdoxy4:{{.*}} method1_isdoxy4 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} 
An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: 
TypedefDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE

danakj wrote:
> The comment is no longer attached to the enums generated by NS_ENUM, it is 
> attached to the decl which is found in the text directly after the comment, 
> which is the typedef, only.
Restored binding the comment outside the macro to the enums defined inside 
NS_ENUM() and NS_OPTIONS()


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-25 Thread Dana Jansens via Phabricator via cfe-commits
danakj updated this revision to Diff 492172.
danakj added a comment.

Ensure the comment outside the macro is attached to enums defined
inside NS_ENUM() and NS_OPTIONS() macros.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/Index/annotate-comments-objc.m

Index: clang/test/Index/annotate-comments-objc.m
===
--- clang/test/Index/annotate-comments-objc.m
+++ clang/test/Index/annotate-comments-objc.m
@@ -48,13 +48,18 @@
 // attach unrelated comments in the following cases where tag decls are
 // embedded in declarators.
 
-#define DECLARE_FUNCTION() \
+#define DECLARE_FUNCTIONS(suffix) \
+/** functionFromMacro IS_DOXYGEN_SINGLE */ \
 void functionFromMacro(void) { \
   typedef struct Struct_notdoxy Struct_notdoxy; \
+} \
+/** functionFromMacroWithSuffix IS_DOXYGEN_SINGLE */ \
+void functionFromMacro##suffix(void) { \
+  typedef struct Struct_notdoxy Struct_notdoxy; \
 }
 
 /// IS_DOXYGEN_NOT_ATTACHED
-DECLARE_FUNCTION()
+DECLARE_FUNCTIONS(WithSuffix)
 
 /// typedef_isdoxy1 IS_DOXYGEN_SINGLE
 typedef struct Struct_notdoxy *typedef_isdoxy1;
@@ -121,5 +126,6 @@
 // CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: TypedefDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:60:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
-
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacro:{{.*}} BriefComment=[functionFromMacro IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacroWithSuffix:{{.*}} BriefComment=[functionFromMacroWithSuffix IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:65:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -181,22 +181,94 @@
 
   const SourceLocation DeclLoc = D->getLocation();
   if (DeclLoc.isMacroID()) {
-if (isa(D)) {
-  // If location of the typedef name is in a macro, it is because being
-  // declared via a macro. Try using declaration's starting location as
-  // the "declaration location".
-  return D->getBeginLoc();
-}
-
-if (const auto *TD = dyn_cast(D)) {
-  // If location of the tag decl is inside a macro, but the spelling of
-  // the tag name comes from a macro argument, it looks like a special
-  // macro like NS_ENUM is being used to define the tag decl.  In that
-  // case, adjust the source location to the expansion loc so that we can
-  // attach the comment to the tag decl.
-  if (SourceMgr.isMacroArgExpansion(DeclLoc) && TD->isCompleteDefinition())
-return SourceMgr.getExpansionLoc(DeclLoc);
+// There are (at least) three types of macros we care about here.
+//
+// 1. Macros that are used in the definition of a type outside the macro,
+//with a comment attached at the macro call site.
+//```
+//// Comment is here, where we use the macro.
+//struct MAKE_NAME(Foo) {
+//int a;
+//int b;
+//};
+//```
+// 2. Macros that define whole things along with the comment.
+//```
+//#define MAKE_METHOD(name) \
+//  /** Comment is here, inside the macro. */ \
+//  void name() {}
+//
+//struct S {
+//  MAKE_METHOD(f)
+//}
+//```
+// 3. Macros that both declare a type and name a decl outside the macro.
+//```
+//// Comment is here, where we use the macro.
+//typedef NS_ENUM(NSInteger, Size) {
+//SizeWidth,
+//SizeHeight
+//};
+//```
+//In this case NS_ENUM declares am enum type, and uses the same name for
+//the typedef declaration that appears outside the macro. The comment
+//here should be applied to both declarations inside and outside the
+//macro.
+//
+// We have found a Decl name that comes from inside a macro, but
+// Decl::getLocation() returns the place where the macro is being called.
+// If the declaration (and not just the name) resides inside the macro,
+// then we want to map Decl::getLocation() into the macro to where the
+// declaration and its attached comment (if any) were written.
+//
+// This mapping into the macro is done by mapping the location to its
+// spelling location, however even if the declaration is inside a macro,
+// the 

[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-25 Thread Dana Jansens via Phabricator via cfe-commits
danakj added inline comments.



Comment at: clang/test/Index/annotate-comments-objc.m:121
 // CHECK: annotate-comments-objc.m:32:9: 
ObjCInstanceMethodDecl=method1_isdoxy4:{{.*}} method1_isdoxy4 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} 
An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: 
TypedefDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE

The comment is no longer attached to the enums generated by NS_ENUM, it is 
attached to the decl which is found in the text directly after the comment, 
which is the typedef, only.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-25 Thread Dana Jansens via Phabricator via cfe-commits
danakj updated this revision to Diff 492141.
danakj added a comment.

Adding back a period that was removed from a comment.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142560/new/

https://reviews.llvm.org/D142560

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/Index/annotate-comments-objc.m

Index: clang/test/Index/annotate-comments-objc.m
===
--- clang/test/Index/annotate-comments-objc.m
+++ clang/test/Index/annotate-comments-objc.m
@@ -48,13 +48,18 @@
 // attach unrelated comments in the following cases where tag decls are
 // embedded in declarators.
 
-#define DECLARE_FUNCTION() \
+#define DECLARE_FUNCTIONS(suffix) \
+/** functionFromMacro IS_DOXYGEN_SINGLE */ \
 void functionFromMacro(void) { \
   typedef struct Struct_notdoxy Struct_notdoxy; \
+} \
+/** functionFromMacroWithSuffix IS_DOXYGEN_SINGLE */ \
+void functionFromMacro##suffix(void) { \
+  typedef struct Struct_notdoxy Struct_notdoxy; \
 }
 
 /// IS_DOXYGEN_NOT_ATTACHED
-DECLARE_FUNCTION()
+DECLARE_FUNCTIONS(WithSuffix)
 
 /// typedef_isdoxy1 IS_DOXYGEN_SINGLE
 typedef struct Struct_notdoxy *typedef_isdoxy1;
@@ -118,8 +123,7 @@
 // CHECK: annotate-comments-objc.m:30:9: ObjCInstanceMethodDecl=method1_isdoxy2:{{.*}} method1_isdoxy2 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:31:9: ObjCInstanceMethodDecl=method1_isdoxy3:{{.*}} method1_isdoxy3 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:32:9: ObjCInstanceMethodDecl=method1_isdoxy4:{{.*}} method1_isdoxy4 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: TypedefDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:60:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
-
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacro:{{.*}} BriefComment=[functionFromMacro IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacroWithSuffix:{{.*}} BriefComment=[functionFromMacroWithSuffix IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:65:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -181,22 +181,56 @@
 
   const SourceLocation DeclLoc = D->getLocation();
   if (DeclLoc.isMacroID()) {
-if (isa(D)) {
-  // If location of the typedef name is in a macro, it is because being
-  // declared via a macro. Try using declaration's starting location as
-  // the "declaration location".
-  return D->getBeginLoc();
-}
-
-if (const auto *TD = dyn_cast(D)) {
-  // If location of the tag decl is inside a macro, but the spelling of
-  // the tag name comes from a macro argument, it looks like a special
-  // macro like NS_ENUM is being used to define the tag decl.  In that
-  // case, adjust the source location to the expansion loc so that we can
-  // attach the comment to the tag decl.
-  if (SourceMgr.isMacroArgExpansion(DeclLoc) && TD->isCompleteDefinition())
-return SourceMgr.getExpansionLoc(DeclLoc);
-}
+// There are (at least) two types of macros we care about here.
+//
+// 1. Macros that are used to define a type, with a comment attached at
+//the macro call site.
+//```
+//// Comment is here, where we use the macro.
+//typedef NS_ENUM(NSInteger, Size) {
+//SizeWidth,
+//SizeHeight
+//};
+//```
+// 2. Macros that define whole things along with the comment.
+//```
+//#define MAKE_METHOD(name) \
+//  /** Comment is here, inside the macro. */ \
+//  void name() {}
+//
+//struct S {
+//  MAKE_METHOD(f)
+//}
+//```
+//
+// We have found a Decl name that comes from inside a macro, but
+// Decl::getLocation() returns the place where the macro is being called.
+// If the declaration (and not just the name) resides inside the macro,
+// then we want to map Decl::getLocation() into the macro to where the
+// declaration and its attached comment (if any) were written.
+//
+// This mapping into the macro is done by mapping the location to its
+// spelling location, however even if the declaration is inside a macro,
+// the name's spelling can come from a macro argument (case 2 above). In
+// this case mapping the location to the spelling location finds the
+// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not
+// 

[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros

2023-01-25 Thread Dana Jansens via Phabricator via cfe-commits
danakj created this revision.
Herald added a subscriber: arphaman.
Herald added a project: All.
danakj requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The key part of getRawCommentForDecl() required to find a comment
is determining where to look for it. The location of the decl
itself is usually right, except when macros get involved. The
comment in the macro is stored in RawCommentList at the spelling
location of the decl, not at the place where the decl comes into
being as the macro is instantiated.

getDeclLocForCommentSearch() already contained to branches to try
handle comments inside macros, and we are able to replace them
and handle more cases as well, by returning the spelling location
of the decl's begin location. That is:

  SourceMgr.getSpellingLoc(D->getBeginLoc())


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142560

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/Index/annotate-comments-objc.m

Index: clang/test/Index/annotate-comments-objc.m
===
--- clang/test/Index/annotate-comments-objc.m
+++ clang/test/Index/annotate-comments-objc.m
@@ -46,15 +46,20 @@
 // NS_ENUM macro, it is tempting to use the fact that enum decl is embedded in
 // the typedef.  Make sure that the heuristic is strong enough that it does not
 // attach unrelated comments in the following cases where tag decls are
-// embedded in declarators.
+// embedded in declarators
 
-#define DECLARE_FUNCTION() \
+#define DECLARE_FUNCTIONS(suffix) \
+/** functionFromMacro IS_DOXYGEN_SINGLE */ \
 void functionFromMacro(void) { \
   typedef struct Struct_notdoxy Struct_notdoxy; \
+} \
+/** functionFromMacroWithSuffix IS_DOXYGEN_SINGLE */ \
+void functionFromMacro##suffix(void) { \
+  typedef struct Struct_notdoxy Struct_notdoxy; \
 }
 
 /// IS_DOXYGEN_NOT_ATTACHED
-DECLARE_FUNCTION()
+DECLARE_FUNCTIONS(WithSuffix)
 
 /// typedef_isdoxy1 IS_DOXYGEN_SINGLE
 typedef struct Struct_notdoxy *typedef_isdoxy1;
@@ -118,8 +123,7 @@
 // CHECK: annotate-comments-objc.m:30:9: ObjCInstanceMethodDecl=method1_isdoxy2:{{.*}} method1_isdoxy2 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:31:9: ObjCInstanceMethodDecl=method1_isdoxy3:{{.*}} method1_isdoxy3 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:32:9: ObjCInstanceMethodDecl=method1_isdoxy4:{{.*}} method1_isdoxy4 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
 // CHECK: annotate-comments-objc.m:43:22: TypedefDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:60:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
-
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacro:{{.*}} BriefComment=[functionFromMacro IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:62:1: FunctionDecl=functionFromMacroWithSuffix:{{.*}} BriefComment=[functionFromMacroWithSuffix IS_DOXYGEN_SINGLE]
+// CHECK: annotate-comments-objc.m:65:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -181,22 +181,56 @@
 
   const SourceLocation DeclLoc = D->getLocation();
   if (DeclLoc.isMacroID()) {
-if (isa(D)) {
-  // If location of the typedef name is in a macro, it is because being
-  // declared via a macro. Try using declaration's starting location as
-  // the "declaration location".
-  return D->getBeginLoc();
-}
-
-if (const auto *TD = dyn_cast(D)) {
-  // If location of the tag decl is inside a macro, but the spelling of
-  // the tag name comes from a macro argument, it looks like a special
-  // macro like NS_ENUM is being used to define the tag decl.  In that
-  // case, adjust the source location to the expansion loc so that we can
-  // attach the comment to the tag decl.
-  if (SourceMgr.isMacroArgExpansion(DeclLoc) && TD->isCompleteDefinition())
-return SourceMgr.getExpansionLoc(DeclLoc);
-}
+// There are (at least) two types of macros we care about here.
+//
+// 1. Macros that are used to define a type, with a comment attached at
+//the macro call site.
+//```
+//// Comment is here, where we use the macro.
+//typedef NS_ENUM(NSInteger, Size) {
+//SizeWidth,
+//SizeHeight
+//};
+//```
+// 2. Macros that define whole things along with the comment.
+//```
+//#define MAKE_METHOD(name) \
+//  /** Comment is here, inside the macro. */ \
+//  void name() {}
+//
+//