[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros
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() {} +// +//
[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros
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 +// wh
[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros
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
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 na
[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros
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
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 macr
[PATCH] D142560: Allow getRawCommentForDecl to find comments in macros
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
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
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
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