@@ -7,17 +7,19 @@ import (
77 "strings"
88 "unsafe"
99
10- "github.com/goplus/llgo/c"
11- "github.com/goplus/llgo/c/cjson"
12- "github.com/goplus/llgo/c/clang"
1310 "github.com/goplus/llcppg/_xtool/llcppsymg/clangutils"
1411 "github.com/goplus/llcppg/ast"
1512 "github.com/goplus/llcppg/token"
13+ "github.com/goplus/llgo/c"
14+ "github.com/goplus/llgo/c/cjson"
15+ "github.com/goplus/llgo/c/clang"
1616)
1717
1818type FileEntry struct {
19- Path string
20- Doc * ast.File
19+ Path string
20+ IncPath string
21+ IsSys bool
22+ Doc * ast.File
2123}
2224
2325type Converter struct {
@@ -58,11 +60,14 @@ func NewConverter(config *clangutils.Config) (*Converter, error) {
5860 return nil , err
5961 }
6062
63+ files := initFileEntries (unit )
64+
6165 return & Converter {
62- Files : make ([] * FileEntry , 0 ) ,
66+ Files : files ,
6367 index : index ,
6468 unit : unit ,
6569 }, nil
70+
6671}
6772
6873func (ct * Converter ) Dispose () {
@@ -71,6 +76,26 @@ func (ct *Converter) Dispose() {
7176 ct .unit .Dispose ()
7277}
7378
79+ func initFileEntries (unit * clang.TranslationUnit ) []* FileEntry {
80+ files := make ([]* FileEntry , 0 )
81+ clangutils .GetInclusions (unit , func (inced clang.File , incins []clang.SourceLocation ) {
82+ loc := unit .GetLocation (inced , 1 , 1 )
83+ incedFile := toStr (inced .FileName ())
84+ var incPath string
85+ if len (incins ) > 0 {
86+ cur := unit .GetCursor (& incins [0 ])
87+ incPath = toStr (cur .String ())
88+ }
89+ files = append (files , & FileEntry {
90+ Path : incedFile ,
91+ IncPath : incPath ,
92+ IsSys : loc .IsInSystemHeader () != 0 ,
93+ Doc : & ast.File {},
94+ })
95+ })
96+ return files
97+ }
98+
7499func (ct * Converter ) GetTokens (cursor clang.Cursor ) []* ast.Token {
75100 ran := cursor .Extent ()
76101 var numTokens c.Uint
@@ -121,42 +146,40 @@ func (ct *Converter) logln(args ...interface{}) {
121146 }
122147}
123148
124- func (ct * Converter ) UpdateLoc (cursor clang.Cursor ) {
149+ func (ct * Converter ) GetCurFile (cursor clang.Cursor ) * ast. File {
125150 loc := cursor .Location ()
126151 var file clang.File
127152 loc .SpellingLocation (& file , nil , nil , nil )
128-
129153 filePath := toStr (file .FileName ())
130-
131154 if filePath == "" {
132155 //todo(zzy): For some built-in macros, there is no file.
133156 ct .curLoc = ast.Location {File : "" }
134- return
135- }
136- ct .curLoc = ast.Location {File : filePath }
137- }
138-
139- func (ct * Converter ) GetCurFile () * ast.File {
140- if ct .curLoc .File == "" {
141157 ct .logln ("GetCurFile: NO FILE" )
142158 return nil
143159 }
160+ ct .curLoc = ast.Location {File : filePath }
161+
144162 // todo(zzy): more efficient
145163 for i , entry := range ct .Files {
146- if entry .Path == ct . curLoc . File {
147- ct .logln ("GetCurFile: found" , ct . curLoc . File )
164+ if entry .Path == filePath {
165+ ct .logln ("GetCurFile: found" , filePath )
148166 return ct .Files [i ].Doc
149167 }
150168 }
151- ct .logln ("GetCurFile: Create New ast.File" , ct .curLoc .File )
152- newDoc := & ast.File {}
153- ct .Files = append (ct .Files , & FileEntry {Path : ct .curLoc .File , Doc : newDoc })
154- return newDoc
169+ ct .logln ("GetCurFile: Create New ast.File" , filePath )
170+ entry := & FileEntry {Path : filePath , Doc : & ast.File {}, IsSys : false }
171+ if loc .IsInSystemHeader () != 0 {
172+ entry .IsSys = true
173+ }
174+ ct .Files = append (ct .Files , entry )
175+ return entry .Doc
155176}
156177
157178func (ct * Converter ) CreateDeclBase (cursor clang.Cursor ) ast.DeclBase {
158179 base := ast.DeclBase {
159- Loc : & ct .curLoc ,
180+ Loc : & ast.Location {
181+ File : ct .curLoc .File ,
182+ },
160183 Parent : ct .BuildScopingExpr (cursor .SemanticParent ()),
161184 }
162185 commentGroup , isDoc := ct .ParseCommentGroup (cursor )
@@ -206,9 +229,7 @@ func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResul
206229 ct .incIndent ()
207230 defer ct .decIndent ()
208231
209- ct .UpdateLoc (cursor )
210-
211- curFile := ct .GetCurFile ()
232+ curFile := ct .GetCurFile (cursor )
212233
213234 name := toStr (cursor .String ())
214235 ct .logf ("visitTop: Cursor: %s\n " , name )
@@ -219,7 +240,11 @@ func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResul
219240
220241 switch cursor .Kind {
221242 case clang .CursorInclusionDirective :
222- include := ct .ProcessInclude (cursor )
243+ include , err := ct .ProcessInclude (cursor )
244+ if err != nil {
245+ ct .logln (err )
246+ return clang .ChildVisit_Continue
247+ }
223248 curFile .Includes = append (curFile .Includes , include )
224249 ct .logln ("visitTop: ProcessInclude END " , include .Path )
225250 case clang .CursorMacroDefinition :
@@ -276,27 +301,18 @@ func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResul
276301 curFile .Decls = append (curFile .Decls , typedefDecl )
277302 ct .logln ("visitTop: ProcessTypeDefDecl END" , typedefDecl .Name .Name )
278303 case clang .CursorNamespace :
279- VisitChildren (cursor , ct .visitTop )
304+ clangutils . VisitChildren (cursor , ct .visitTop )
280305 }
281306 return clang .ChildVisit_Continue
282307}
283308
284309func (ct * Converter ) Convert () ([]* FileEntry , error ) {
285310 cursor := ct .unit .Cursor ()
286311 // visit top decls (struct,class,function & macro,include)
287- VisitChildren (cursor , ct .visitTop )
312+ clangutils . VisitChildren (cursor , ct .visitTop )
288313 return ct .Files , nil
289314}
290315
291- type Visitor func (cursor , parent clang.Cursor ) clang.ChildVisitResult
292-
293- func VisitChildren (cursor clang.Cursor , fn Visitor ) c.Uint {
294- return clang .VisitChildren (cursor , func (cursor , parent clang.Cursor , clientData unsafe.Pointer ) clang.ChildVisitResult {
295- cfn := * (* Visitor )(clientData )
296- return cfn (cursor , parent )
297- }, unsafe .Pointer (& fn ))
298- }
299-
300316func (ct * Converter ) ProcessType (t clang.Type ) ast.Expr {
301317 ct .incIndent ()
302318 defer ct .decIndent ()
@@ -521,7 +537,7 @@ func (ct *Converter) ProcessMethodAttributes(cursor clang.Cursor, fn *ast.FuncDe
521537func (ct * Converter ) ProcessEnumType (cursor clang.Cursor ) * ast.EnumType {
522538 items := make ([]* ast.EnumItem , 0 )
523539
524- VisitChildren (cursor , func (cursor , parent clang.Cursor ) clang.ChildVisitResult {
540+ clangutils . VisitChildren (cursor , func (cursor , parent clang.Cursor ) clang.ChildVisitResult {
525541 if cursor .Kind == clang .CursorEnumConstantDecl {
526542 name := cursor .String ()
527543 defer name .Dispose ()
@@ -578,9 +594,14 @@ func (ct *Converter) ProcessMacro(cursor clang.Cursor) *ast.Macro {
578594 return macro
579595}
580596
581- func (ct * Converter ) ProcessInclude (cursor clang.Cursor ) * ast.Include {
597+ func (ct * Converter ) ProcessInclude (cursor clang.Cursor ) ( * ast.Include , error ) {
582598 name := toStr (cursor .String ())
583- return & ast.Include {Path : name }
599+ includedFile := cursor .IncludedFile ()
600+ includedPath := toStr (includedFile .FileName ())
601+ if includedPath == "" {
602+ return nil , fmt .Errorf ("%s: failed to get included file" , name )
603+ }
604+ return & ast.Include {Path : includedPath }, nil
584605}
585606
586607func (ct * Converter ) createBaseField (cursor clang.Cursor ) * ast.Field {
@@ -619,7 +640,7 @@ func (ct *Converter) ProcessFieldList(cursor clang.Cursor) *ast.FieldList {
619640
620641 params := & ast.FieldList {}
621642 ct .logln ("ProcessFieldList: VisitChildren" )
622- VisitChildren (cursor , func (subcsr , parent clang.Cursor ) clang.ChildVisitResult {
643+ clangutils . VisitChildren (cursor , func (subcsr , parent clang.Cursor ) clang.ChildVisitResult {
623644 switch subcsr .Kind {
624645 case clang .CursorParmDecl , clang .CursorFieldDecl :
625646 // In C language, parameter lists do not have similar parameter grouping in Go.
@@ -665,7 +686,7 @@ func (ct *Converter) ProcessFieldList(cursor clang.Cursor) *ast.FieldList {
665686// Note:Public Method is considered
666687func (ct * Converter ) ProcessMethods (cursor clang.Cursor ) []* ast.FuncDecl {
667688 methods := make ([]* ast.FuncDecl , 0 )
668- VisitChildren (cursor , func (subcsr , parent clang.Cursor ) clang.ChildVisitResult {
689+ clangutils . VisitChildren (cursor , func (subcsr , parent clang.Cursor ) clang.ChildVisitResult {
669690 if isMethod (subcsr ) && subcsr .CXXAccessSpecifier () == clang .CXXPublic {
670691 method := ct .ProcessFuncDecl (subcsr )
671692 if method != nil {
@@ -950,8 +971,7 @@ func isRangeChildOf(childRange, parentRange clang.SourceRange) bool {
950971}
951972
952973func getOffset (location clang.SourceLocation ) c.Uint {
953- var offset c.Uint
954- location .SpellingLocation (nil , nil , nil , & offset )
974+ _ , _ , _ , offset := clangutils .GetLocation (location )
955975 return offset
956976}
957977
0 commit comments