From 0a0bb128d6aaabfa3b74eb9d7e7624089155a972 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 6 Feb 2025 16:04:54 +0800 Subject: [PATCH] c/clang:presume location --- c/clang/_demo/symboldump/symboldump.go | 21 ++++++++---- c/clang/_wrap/cursor.cpp | 4 +++ c/clang/clang.go | 47 ++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/c/clang/_demo/symboldump/symboldump.go b/c/clang/_demo/symboldump/symboldump.go index 84b91a80b..0ec7ff4cb 100644 --- a/c/clang/_demo/symboldump/symboldump.go +++ b/c/clang/_demo/symboldump/symboldump.go @@ -36,13 +36,16 @@ var context = newContext() func printCursorLocation(cursor clang.Cursor) { loc := cursor.Location() var file clang.File - var line, column c.Uint + var line, column, presumedLine, presumedColumn c.Uint + var presumedFilename clang.String loc.SpellingLocation(&file, &line, &column, nil) + loc.PresumedLocation(&presumedFilename, &presumedLine, &presumedColumn) filename := file.FileName() defer filename.Dispose() - c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column) + c.Printf(c.Str("Location: %s:%d:%d\n"), filename.CStr(), line, column) + c.Printf(c.Str("Presumed Location: %s:%d:%d\n"), presumedFilename.CStr(), presumedLine, presumedColumn) } func printMarcoInfo(cursor clang.Cursor) { @@ -107,20 +110,26 @@ func printFuncInfo(cursor clang.Cursor) { } func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult { - if cursor.Kind == clang.CursorMacroDefinition { + switch cursor.Kind { + case clang.CursorMacroDefinition: printMarcoInfo(cursor) - } else if cursor.Kind == clang.CursorNamespace { + case clang.CursorNamespace: nameStr := cursor.String() context.setNamespaceName(c.GoString(nameStr.CStr())) clang.VisitChildren(cursor, visit, nil) context.setNamespaceName("") - } else if cursor.Kind == clang.CursorClassDecl { + case clang.CursorClassDecl: nameStr := cursor.String() context.setClassName(c.GoString(nameStr.CStr())) clang.VisitChildren(cursor, visit, nil) context.setClassName("") - } else if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl { + case clang.CursorCXXMethod, clang.CursorFunctionDecl: printFuncInfo(cursor) + case clang.CursorEnumDecl, clang.CursorStructDecl, clang.CursorUnionDecl, clang.CursorTypedefDecl: + nameStr := cursor.String() + printCursorLocation(cursor) + c.Printf(c.Str("Name: %s\n"), nameStr.CStr()) + println("--------------------------------") } return clang.ChildVisit_Continue diff --git a/c/clang/_wrap/cursor.cpp b/c/clang/_wrap/cursor.cpp index c4251ce4e..bec59d973 100644 --- a/c/clang/_wrap/cursor.cpp +++ b/c/clang/_wrap/cursor.cpp @@ -213,6 +213,10 @@ void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigne clang_getSpellingLocation(*loc, file, line, column, offset); } +void wrap_clang_getPresumedLocation(CXSourceLocation *loc, CXString *filename, unsigned *line, unsigned *column) { + clang_getPresumedLocation(*loc, filename, line, column); +} + void wrap_clang_getRangeStart(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeStart(*range); } void wrap_clang_getRangeEnd(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeEnd(*range); } diff --git a/c/clang/clang.go b/c/clang/clang.go index 556b3664a..dba77350c 100644 --- a/c/clang/clang.go +++ b/c/clang/clang.go @@ -2878,6 +2878,53 @@ func (l SourceLocation) Offset() (ret c.Uint) { return } +/** + * Retrieve the file, line and column represented by the given source + * location, as specified in a # line directive. + * + * Example: given the following source code in a file somefile.c + * + * \code + * #123 "dummy.c" 1 + * + * static int func(void) + * { + * return 0; + * } + * \endcode + * + * the location information returned by this function would be + * + * File: dummy.c Line: 124 Column: 12 + * + * whereas clang_getExpansionLocation would have returned + * + * File: somefile.c Line: 3 Column: 12 + * + * \param location the location within a source file that will be decomposed + * into its parts. + * + * \param filename [out] if non-NULL, will be set to the filename of the + * source location. Note that filenames returned will be for "virtual" files, + * which don't necessarily exist on the machine running clang - e.g. when + * parsing preprocessed output obtained from a different environment. If + * a non-NULL value is passed in, remember to dispose of the returned value + * using \c clang_disposeString() once you've finished with it. For an invalid + * source location, an empty string is returned. + * + * \param line [out] if non-NULL, will be set to the line number of the + * source location. For an invalid source location, zero is returned. + * + * \param column [out] if non-NULL, will be set to the column number of the + * source location. For an invalid source location, zero is returned. + */ +// llgo:link (*SourceLocation).wrapPresumedLocation C.wrap_clang_getPresumedLocation +func (l *SourceLocation) wrapPresumedLocation(filename *String, line, column *c.Uint) {} + +func (l SourceLocation) PresumedLocation(filename *String, line, column *c.Uint) { + l.wrapPresumedLocation(filename, line, column) +} + /** * Retrieve a source location representing the first character within a * source range.