c/clang:marco info
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
|||||||
type Context struct {
|
type Context struct {
|
||||||
namespaceName string
|
namespaceName string
|
||||||
className string
|
className string
|
||||||
|
unit *clang.TranslationUnit
|
||||||
}
|
}
|
||||||
|
|
||||||
func newContext() *Context {
|
func newContext() *Context {
|
||||||
@@ -26,23 +27,50 @@ func (c *Context) setClassName(name string) {
|
|||||||
c.className = name
|
c.className = name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Context) setUnit(unit *clang.TranslationUnit) {
|
||||||
|
c.unit = unit
|
||||||
|
}
|
||||||
|
|
||||||
var context = newContext()
|
var context = newContext()
|
||||||
|
|
||||||
func print_cursor_info(cursor clang.Cursor) {
|
func printCursorLocation(cursor clang.Cursor) {
|
||||||
loc := cursor.Location()
|
loc := cursor.Location()
|
||||||
var file clang.File
|
var file clang.File
|
||||||
var line, column c.Uint
|
var line, column c.Uint
|
||||||
|
|
||||||
loc.SpellingLocation(&file, &line, &column, nil)
|
loc.SpellingLocation(&file, &line, &column, nil)
|
||||||
filename := file.FileName()
|
filename := file.FileName()
|
||||||
|
defer filename.Dispose()
|
||||||
|
|
||||||
c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column)
|
c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column)
|
||||||
|
}
|
||||||
|
|
||||||
|
func printMarcoInfo(cursor clang.Cursor) {
|
||||||
|
printCursorLocation(cursor)
|
||||||
|
name := cursor.String()
|
||||||
|
c.Printf(c.Str("Marco Name: %s\n"), name.CStr())
|
||||||
|
ran := cursor.Extent()
|
||||||
|
var numTokens c.Uint
|
||||||
|
var tokens *clang.Token
|
||||||
|
context.unit.Tokenize(ran, &tokens, &numTokens)
|
||||||
|
c.Printf(c.Str("Content: "))
|
||||||
|
|
||||||
|
tokensSlice := unsafe.Slice(tokens, int(numTokens))
|
||||||
|
for _, tok := range tokensSlice {
|
||||||
|
tokStr := context.unit.Token(tok)
|
||||||
|
c.Printf(c.Str("%s "), tokStr.CStr())
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Printf(c.Str("\n"))
|
||||||
|
println("--------------------------------")
|
||||||
|
}
|
||||||
|
func printFuncInfo(cursor clang.Cursor) {
|
||||||
|
printCursorLocation(cursor)
|
||||||
|
|
||||||
cursorStr := cursor.String()
|
cursorStr := cursor.String()
|
||||||
symbol := cursor.Mangling()
|
symbol := cursor.Mangling()
|
||||||
defer symbol.Dispose()
|
defer symbol.Dispose()
|
||||||
defer cursorStr.Dispose()
|
defer cursorStr.Dispose()
|
||||||
defer filename.Dispose()
|
|
||||||
|
|
||||||
if context.namespaceName != "" && context.className != "" {
|
if context.namespaceName != "" && context.className != "" {
|
||||||
fmt.Printf("%s:%s:", context.namespaceName, context.className)
|
fmt.Printf("%s:%s:", context.namespaceName, context.className)
|
||||||
@@ -78,7 +106,9 @@ func print_cursor_info(cursor clang.Cursor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
|
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
|
||||||
if cursor.Kind == clang.Namespace {
|
if cursor.Kind == clang.MacroDefinition {
|
||||||
|
printMarcoInfo(cursor)
|
||||||
|
} else if cursor.Kind == clang.Namespace {
|
||||||
nameStr := cursor.String()
|
nameStr := cursor.String()
|
||||||
context.setNamespaceName(c.GoString(nameStr.CStr()))
|
context.setNamespaceName(c.GoString(nameStr.CStr()))
|
||||||
clang.VisitChildren(cursor, visit, nil)
|
clang.VisitChildren(cursor, visit, nil)
|
||||||
@@ -89,7 +119,7 @@ func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitRe
|
|||||||
clang.VisitChildren(cursor, visit, nil)
|
clang.VisitChildren(cursor, visit, nil)
|
||||||
context.setClassName("")
|
context.setClassName("")
|
||||||
} else if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl {
|
} else if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl {
|
||||||
print_cursor_info(cursor)
|
printFuncInfo(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
return clang.ChildVisit_Continue
|
return clang.ChildVisit_Continue
|
||||||
@@ -105,7 +135,7 @@ func parse(filename *c.Char) {
|
|||||||
filename,
|
filename,
|
||||||
unsafe.SliceData(args), 3,
|
unsafe.SliceData(args), 3,
|
||||||
nil, 0,
|
nil, 0,
|
||||||
clang.TranslationUnit_None,
|
clang.DetailedPreprocessingRecord,
|
||||||
)
|
)
|
||||||
|
|
||||||
if unit == nil {
|
if unit == nil {
|
||||||
@@ -113,6 +143,7 @@ func parse(filename *c.Char) {
|
|||||||
c.Exit(1)
|
c.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context.setUnit(unit)
|
||||||
cursor := unit.Cursor()
|
cursor := unit.Cursor()
|
||||||
|
|
||||||
clang.VisitChildren(cursor, visit, nil)
|
clang.VisitChildren(cursor, visit, nil)
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_g
|
|||||||
|
|
||||||
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
|
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
|
||||||
|
|
||||||
|
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {
|
||||||
|
return clang_getTokenSpelling(unit, *token);
|
||||||
|
}
|
||||||
|
|
||||||
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
|
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
|
||||||
|
|
||||||
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
|
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
|
||||||
@@ -42,6 +46,12 @@ void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigne
|
|||||||
clang_getSpellingLocation(*loc, file, line, column, offset);
|
clang_getSpellingLocation(*loc, file, line, column, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wrap_clang_getCursorExtent(CXCursor *cur, CXSourceRange *range) { *range = clang_getCursorExtent(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_tokenize(CXTranslationUnit unit, CXSourceRange *Range, CXToken **Tokens, unsigned *NumTokens) {
|
||||||
|
clang_tokenize(unit, *Range, Tokens, NumTokens);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor, CXClientData client_data) {
|
unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor, CXClientData client_data) {
|
||||||
wrap_data data = {client_data, visitor};
|
wrap_data data = {client_data, visitor};
|
||||||
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
|
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
|
||||||
|
|||||||
142
c/clang/clang.go
142
c/clang/clang.go
@@ -1225,7 +1225,22 @@ func (*Index) Dispose() {}
|
|||||||
* constructing the translation unit.
|
* constructing the translation unit.
|
||||||
*/
|
*/
|
||||||
const (
|
const (
|
||||||
|
/**
|
||||||
|
* Used to indicate that no special translation-unit options are
|
||||||
|
* needed.
|
||||||
|
*/
|
||||||
TranslationUnit_None = 0x0
|
TranslationUnit_None = 0x0
|
||||||
|
/**
|
||||||
|
* Used to indicate that the parser should construct a "detailed"
|
||||||
|
* preprocessing record, including all macro definitions and instantiations.
|
||||||
|
*
|
||||||
|
* Constructing a detailed preprocessing record requires more memory
|
||||||
|
* and time to parse, since the information contained in the record
|
||||||
|
* is usually not retained. However, it can be useful for
|
||||||
|
* applications that require more detailed information about the
|
||||||
|
* behavior of the preprocessor.
|
||||||
|
*/
|
||||||
|
DetailedPreprocessingRecord = 0x01
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1330,6 +1345,53 @@ type SourceLocation struct {
|
|||||||
intData c.Uint
|
intData c.Uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies a half-open character range in the source code.
|
||||||
|
*
|
||||||
|
* Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
|
||||||
|
* starting and end locations from a source range, respectively.
|
||||||
|
*/
|
||||||
|
type SourceRange struct {
|
||||||
|
ptrData [2]c.Pointer
|
||||||
|
beginIntData c.Uint
|
||||||
|
endIntData c.Uint
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes a kind of token.
|
||||||
|
*/
|
||||||
|
|
||||||
|
type TokenKind c.Int
|
||||||
|
|
||||||
|
const (
|
||||||
|
/**
|
||||||
|
* A token that contains some kind of punctuation.
|
||||||
|
*/
|
||||||
|
Punctuation TokenKind = iota
|
||||||
|
/**
|
||||||
|
* A language keyword.
|
||||||
|
*/
|
||||||
|
Keyword
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An identifier (that is not a keyword).
|
||||||
|
*/
|
||||||
|
Identifier
|
||||||
|
/**
|
||||||
|
* A numeric, string, or character literal.
|
||||||
|
*/
|
||||||
|
Literal
|
||||||
|
/**
|
||||||
|
* A comment.
|
||||||
|
*/
|
||||||
|
Comment
|
||||||
|
)
|
||||||
|
|
||||||
|
type Token struct {
|
||||||
|
intData [4]c.Uint
|
||||||
|
ptrData c.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a name for the entity referenced by this cursor.
|
* Retrieve a name for the entity referenced by this cursor.
|
||||||
*/
|
*/
|
||||||
@@ -1417,6 +1479,86 @@ func (c Cursor) Location() (loc SourceLocation) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the physical extent of the source construct referenced by
|
||||||
|
* the given cursor.
|
||||||
|
*
|
||||||
|
* The extent of a cursor starts with the file/line/column pointing at the
|
||||||
|
* first character within the source construct that the cursor refers to and
|
||||||
|
* ends with the last character within that source construct. For a
|
||||||
|
* declaration, the extent covers the declaration itself. For a reference,
|
||||||
|
* the extent covers the location of the reference (e.g., where the referenced
|
||||||
|
* entity was actually used).
|
||||||
|
*/
|
||||||
|
// llgo:link (*Cursor).wrapExtent C.wrap_clang_getCursorExtent
|
||||||
|
func (c *Cursor) wrapExtent(loc *SourceRange) {}
|
||||||
|
|
||||||
|
func (c Cursor) Extent() (loc SourceRange) {
|
||||||
|
c.wrapExtent(&loc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tokenize the source code described by the given range into raw
|
||||||
|
* lexical tokens.
|
||||||
|
*
|
||||||
|
* \param TU the translation unit whose text is being tokenized.
|
||||||
|
*
|
||||||
|
* \param Range the source range in which text should be tokenized. All of the
|
||||||
|
* tokens produced by tokenization will fall within this source range,
|
||||||
|
*
|
||||||
|
* \param Tokens this pointer will be set to point to the array of tokens
|
||||||
|
* that occur within the given source range. The returned pointer must be
|
||||||
|
* freed with clang_disposeTokens() before the translation unit is destroyed.
|
||||||
|
*
|
||||||
|
* \param NumTokens will be set to the number of tokens in the \c *Tokens
|
||||||
|
* array.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// llgo:link (*TranslationUnit).wrapTokenize C.wrap_clang_tokenize
|
||||||
|
func (t *TranslationUnit) wrapTokenize(ran *SourceRange, tokens **Token, numTokens *c.Uint) {}
|
||||||
|
|
||||||
|
func (t TranslationUnit) Tokenize(ran SourceRange, tokens **Token, numTokens *c.Uint) {
|
||||||
|
t.wrapTokenize(&ran, tokens, numTokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the spelling of the given token.
|
||||||
|
*
|
||||||
|
* The spelling of a token is the textual representation of that token, e.g.,
|
||||||
|
* the text of an identifier or keyword.
|
||||||
|
*/
|
||||||
|
// llgo:link (*TranslationUnit).wrapToken C.wrap_clang_getTokenSpelling
|
||||||
|
func (*TranslationUnit) wrapToken(token *Token) (ret String) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c TranslationUnit) Token(token Token) (ret String) {
|
||||||
|
return c.wrapToken(&token)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the file, line, column, and offset represented by
|
||||||
|
* the given source location.
|
||||||
|
*
|
||||||
|
* If the location refers into a macro instantiation, return where the
|
||||||
|
* location was originally spelled in the source file.
|
||||||
|
*
|
||||||
|
* \param location the location within a source file that will be decomposed
|
||||||
|
* into its parts.
|
||||||
|
*
|
||||||
|
* \param file [out] if non-NULL, will be set to the file to which the given
|
||||||
|
* source location points.
|
||||||
|
*
|
||||||
|
* \param line [out] if non-NULL, will be set to the line to which the given
|
||||||
|
* source location points.
|
||||||
|
*
|
||||||
|
* \param column [out] if non-NULL, will be set to the column to which the given
|
||||||
|
* source location points.
|
||||||
|
*
|
||||||
|
* \param offset [out] if non-NULL, will be set to the offset into the
|
||||||
|
* buffer to which the given source location points.
|
||||||
|
*/
|
||||||
// llgo:link (*SourceLocation).wrapSpellingLocation C.wrap_clang_getSpellingLocation
|
// llgo:link (*SourceLocation).wrapSpellingLocation C.wrap_clang_getSpellingLocation
|
||||||
func (l *SourceLocation) wrapSpellingLocation(file *File, line, column, offset *c.Uint) {}
|
func (l *SourceLocation) wrapSpellingLocation(file *File, line, column, offset *c.Uint) {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user