Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Objective-C/C++ parser not generating "signature:" field for C functions #907

Open
siegel opened this issue Apr 28, 2016 · 8 comments

Comments

Projects
None yet
4 participants
@siegel
Copy link
Contributor

commented Apr 28, 2016

See the attached "foo.mm", which contains a static C function as well as an interface and implementation section for an Objective-C class. foo.mm.zip

cd to where the file is, and then run this command:

ctags --excmd=number --tag-relative=no --fields=+a+m+n+S foo.mm

Then examine the resulting tags file. (Attached here:
tags.zip.)

The entry for foo has the following form:

foo foo.mm 2;" f line:2 interface:

Note that the signature field is missing for foo().

Now, rename foo.mm to foo.cp and run the above command again:

ctags --excmd=number --tag-relative=no --fields=+a+m+n+S foo.cp

Examine the generated tags again, and you'll see the expected entry for foo():

foo foo.cp 2;" f line:2 typeref:typename:void file: signature:(int a, int b, int c)

I have a hack on the old Exuberant Ctags source, which "supports" Objective-C/C++ by routing through the C parser, and then following up with some lightweight parsing to find Objective-C structures. It's different enough from the current code that it's probably impractical to integrate, but the overall strategy (layering Objective-C/C++ support on top of the C/C++ parser) might be feasible anyway.

@siegel

This comment has been minimized.

Copy link
Contributor Author

commented Apr 28, 2016

Here's the original "objc.c" from our hack on the old exuberant ctags source, in case that helps.
objc.c.zip

@masatake

This comment has been minimized.

Copy link
Member

commented May 2, 2016

(About foo.mm.zip and tags.zip we want you to put them inline. I don't want to open zip.)

C++/C parsers completely rewritten by @pragmaware. As far as I can remember he started this work
to sp;lit them from Java/C#/D/Vala parsers. All of them are implemented in a source file and it was too complicated for maintaining.

Implementing ObjC parser based on the current C++/C parser looks natural for me because they really share their syntax. However, I'm not sure how @pragmaware will say about this.

If I am @pragmaware, I will say that I will accept reimplementing ObjC parser based on C++/C with following conditions:
(0) the copyright of code is clarified,
(1) you will maintaine the code,
(2) compatiblity with old ObjC parser is considered well (breaking the compatibility is acceptable if there are enough reason,
(3) you will provide enough test cases.

@siegel

This comment has been minimized.

Copy link
Contributor Author

commented May 2, 2016

Here are the referenced files inline:

foo.mm/foo.cp:

static
void    foo(int a, int b, int c)
{

}

@interface XYZ : NSObject

-(instancetype)initWithMumble: (NSObject*)mumble;

@end

@implementation XYZ


-(instancetype)initWithMumble: (NSObject*)mumble;

@end

Tags output for foo.mm:

!_TAG_FILE_FORMAT       2       /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED       1       /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR    Universal Ctags Team    //
!_TAG_PROGRAM_NAME      Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL       https://ctags.io/       /official site/
!_TAG_PROGRAM_VERSION   0.0.0   /9434eb3/
XYZ     foo.mm  13;"    I       line:13 interface:
XYZ     foo.mm  7;"     i       line:7  interface:
foo     foo.mm  2;"     f       line:2  interface:
initWithMumble: foo.mm  16;"    m       line:16 implementation:XYZ
initWithMumble: foo.mm  9;"     m       line:9  interface:XYZ

Tags output for foo.cp:

!_TAG_FILE_FORMAT       2       /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED       1       /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR    Universal Ctags Team    //
!_TAG_PROGRAM_NAME      Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL       https://ctags.io/       /official site/
!_TAG_PROGRAM_VERSION   0.0.0   /9434eb3/
foo     foo.cp  2;"     f       line:2  typeref:typename:void   file:   signature:(int a, int b, int c)
@masatake

This comment has been minimized.

Copy link
Member

commented May 2, 2016

BTW, inteface: field of foo, XYZ (implementation)and XYZ(interface) are broken.

static void prepareTag (tagEntryInfo * tag, vString const *name, objcKind kind)
{
    initTagEntry (tag, vStringValue (name), &(ObjcKinds[kind]));

    if (parentName != NULL)
    {

This condition is not enough. vStringLength (parentName) > 0 is needed as additional condition.

@pragmaware

This comment has been minimized.

Copy link
Contributor

commented Jun 5, 2016

I've been thinking a bit about this.

It's probably better to hack-in Objective-C support right into the new parser than doing a two pass analysis. Local variables, for instance, may appear both in C and Objective-C scopes. With two passes scoping will be just wrong.

I have done a couple of tests and it's rather feasible. However the C parser needs some refactoring before work on Objective-C can begin. The tag kinds are currently shared between C and C++ and I think they need to be split so, say, C enums are different from C++ enums and later Objective-C enums... (#977)

@siegel

This comment has been minimized.

Copy link
Contributor Author

commented Jun 10, 2016

I think the approach you describe sounds reasonable.

As to enums, I'm not clear on what the issues are there. I know there's an "NS_ENUM" macro and a related "CF_ENUM" macro, which both do the same thing, and which both subtly alter the structure and discovery of enum detection. If that's what you meant by "Objective-C enums", then yeah, I agree there might be some additional work needed there.

It occurred to me that libclang might be useful for writing a tags generator, but there are some real risks there; for one thing, it drags in an awful lot of external code; and for another, in my own experimentation I've seen some very strange (unexpected) results from parsing files with libclang. (Digging into that is on my to-do list, but I'm also trying to find someone who knows how libclang works to find some relevant expertise.)

@masatake masatake modified the milestone: Mn for 6.0 May 31, 2017

masatake added a commit to masatake/ctags that referenced this issue Jun 26, 2017

ObjectiveC: don't emit empty scopes
This bug was found in universal-ctags#907.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>

@masatake masatake modified the milestone: Mn for 6.0 Jun 26, 2017

@k-takata

This comment has been minimized.

Copy link
Contributor

commented Jul 2, 2017

From #1486:

This doesn't close #907.

So, reopen.

@k-takata k-takata reopened this Jul 2, 2017

@masatake

This comment has been minimized.

Copy link
Member

commented Jul 2, 2017

@k-takata, thank you.

@masatake masatake added C/C++ and removed C/C++ labels Jan 24, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.