11package config
22
33import (
4+ "maps"
45 "os"
56 "path/filepath"
7+ "slices"
8+ "sort"
69 "strings"
710
811 "github.com/goplus/lib/c/clang"
@@ -41,8 +44,6 @@ func PkgHfileInfo(includes []string, args []string, mix bool) *PkgHfilesInfo {
4144 }
4245 defer os .Remove (outfile .Name ())
4346
44- refMap := make (map [string ]int , len (includes ))
45-
4647 clangtool .ComposeIncludes (includes , outfile .Name ())
4748 index , unit , err := clangutils .CreateTranslationUnit (& clangutils.Config {
4849 File : outfile .Name (),
@@ -55,40 +56,49 @@ func PkgHfileInfo(includes []string, args []string, mix bool) *PkgHfilesInfo {
5556 panic (err )
5657 }
5758
59+ var headers []string
60+ inters := make (map [string ]struct {})
61+
5862 clangutils .GetInclusions (unit , func (inced clang.File , incins []clang.SourceLocation ) {
5963 // not in the first level include maybe impl or third hfile
6064 filename := filepath .Clean (clang .GoString (inced .FileName ()))
6165
62- if len (incins ) == 1 {
63- info .Inters = append (info .Inters , filename )
66+ // skip the composed header
67+ if filename == outfile .Name () {
68+ return
6469 }
70+ refcnt := len (incins )
6571
66- ref , ok := refMap [filename ]
67- if ! ok {
68- refMap [filename ] = len (incins )
69- return
72+ for _ , inc := range incins {
73+ // if current header is included by composed header, can skip
74+ if clang .GoString (inc .File ().FileName ()) == outfile .Name () {
75+ refcnt --
76+ }
77+ // it's included by internal headers, can skip.
78+ if _ , ok := inters [filename ]; ok {
79+ refcnt --
80+ }
7081 }
71- // Handle duplicate references: Retain only the reference with the smallest source location.
72- // Example:
73- // temp1.h: temp2 tempimpl.h
74- // temp2.h: temp2
75- // The reference count for temp2.h should be 1 (not 2).
76- // If its count is 2, decrement it to 1.
77- if len (incins ) < ref {
78- refMap [filename ] = len (incins )
82+
83+ if refcnt == 0 {
84+ inters [filename ] = struct {}{}
7985 }
86+ headers = append (headers , filename )
8087 })
8188
89+ info .Inters = slices .Collect (maps .Keys (inters ))
90+
91+ sort .Strings (info .Inters )
92+
8293 absLongestPrefix , err := filepath .Abs (CommonParentDir (info .Inters ))
8394 if err != nil {
8495 panic (err )
8596 }
8697
87- for filename , ref := range refMap {
88- if ref == 1 {
98+ for _ , filename := range headers {
99+ if _ , ok := inters [ filename ]; ok {
89100 continue
90101 }
91-
92102 if mix {
93103 info .Thirds = append (info .Thirds , filename )
94104 continue
0 commit comments