llcppsigfetch:typedef anonymous record type correct refer by __ANONY_ name
This commit is contained in:
@@ -43,6 +43,13 @@ type Converter struct {
|
|||||||
anonyTypeMap map[string]string // cursorUsr -> anonyname
|
anonyTypeMap map[string]string // cursorUsr -> anonyname
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tagMap = map[string]ast.Tag{
|
||||||
|
"struct": ast.Struct,
|
||||||
|
"union": ast.Union,
|
||||||
|
"enum": ast.Enum,
|
||||||
|
"class": ast.Class,
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
File string
|
File string
|
||||||
Temp bool
|
Temp bool
|
||||||
@@ -169,7 +176,22 @@ func (ct *Converter) GetCurFile() *ast.File {
|
|||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ct *Converter) AddTypeDecl(cursor clang.Cursor, decl ast.Decl) {
|
func (ct *Converter) SetAnonyType(cursor clang.Cursor, anonyname string) {
|
||||||
|
usr := cursor.USR()
|
||||||
|
usrStr := c.GoString(usr.CStr())
|
||||||
|
defer usr.Dispose()
|
||||||
|
ct.anonyTypeMap[usrStr] = anonyname
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ct *Converter) GetAnonyType(cursor clang.Cursor) (string, bool) {
|
||||||
|
usr := cursor.USR()
|
||||||
|
usrStr := c.GoString(usr.CStr())
|
||||||
|
defer usr.Dispose()
|
||||||
|
anonyname, ok := ct.anonyTypeMap[usrStr]
|
||||||
|
return anonyname, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ct *Converter) SetTypeDecl(cursor clang.Cursor, decl ast.Decl) {
|
||||||
usr := cursor.USR()
|
usr := cursor.USR()
|
||||||
usrStr := c.GoString(usr.CStr())
|
usrStr := c.GoString(usr.CStr())
|
||||||
ct.typeDecls[usrStr] = decl
|
ct.typeDecls[usrStr] = decl
|
||||||
@@ -190,7 +212,7 @@ func (ct *Converter) CreateDeclBase(cursor clang.Cursor) ast.DeclBase {
|
|||||||
|
|
||||||
res := ast.DeclBase{
|
res := ast.DeclBase{
|
||||||
Loc: &ct.curLoc,
|
Loc: &ct.curLoc,
|
||||||
Parent: buildScopingExpr(cursor.SemanticParent()),
|
Parent: ct.BuildScopingExpr(cursor.SemanticParent()),
|
||||||
}
|
}
|
||||||
|
|
||||||
commentGroup := &ast.CommentGroup{}
|
commentGroup := &ast.CommentGroup{}
|
||||||
@@ -334,23 +356,7 @@ func (ct *Converter) ProcessTypeDefDecl(cursor clang.Cursor) *ast.TypedefDecl {
|
|||||||
name := cursor.String()
|
name := cursor.String()
|
||||||
defer name.Dispose()
|
defer name.Dispose()
|
||||||
|
|
||||||
var typ ast.Expr
|
typ := ct.ProcessUnderlyingType(cursor)
|
||||||
underlyingTyp := cursor.TypedefDeclUnderlyingType()
|
|
||||||
if underlyingTyp.Kind != clang.TypeElaborated {
|
|
||||||
typ = ct.ProcessType(underlyingTyp)
|
|
||||||
} else {
|
|
||||||
typ = ct.ProcessElaboratedType(underlyingTyp)
|
|
||||||
referTypeCursor := underlyingTyp.TypeDeclaration()
|
|
||||||
if _, ok := typ.(*ast.TagExpr); ok && isCursorChildOf(referTypeCursor, cursor) {
|
|
||||||
// Handle unexpected named structures generated from anonymous RecordTypes in Typedefs
|
|
||||||
// In this case, libclang incorrectly reports an anonymous struct as a named struct
|
|
||||||
// The reference style is TagRefer, for example: struct MyStruct
|
|
||||||
sourceCode := ct.GetTokens(referTypeCursor)
|
|
||||||
if sourceCode[0].Token == token.KEYWORD && (sourceCode[1].Token == token.PUNCT && sourceCode[1].Lit == "{") {
|
|
||||||
println("todo:unexpected named decl in typedef anonymous decl")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
decl := &ast.TypedefDecl{
|
decl := &ast.TypedefDecl{
|
||||||
DeclBase: ct.CreateDeclBase(cursor),
|
DeclBase: ct.CreateDeclBase(cursor),
|
||||||
@@ -358,10 +364,59 @@ func (ct *Converter) ProcessTypeDefDecl(cursor clang.Cursor) *ast.TypedefDecl {
|
|||||||
Type: typ,
|
Type: typ,
|
||||||
}
|
}
|
||||||
|
|
||||||
ct.AddTypeDecl(cursor, decl)
|
ct.SetTypeDecl(cursor, decl)
|
||||||
return decl
|
return decl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ct *Converter) ProcessUnderlyingType(cursor clang.Cursor) ast.Expr {
|
||||||
|
underlyingTyp := cursor.TypedefDeclUnderlyingType()
|
||||||
|
if underlyingTyp.Kind != clang.TypeElaborated {
|
||||||
|
return ct.ProcessType(underlyingTyp)
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := ct.ProcessElaboratedType(underlyingTyp)
|
||||||
|
referTypeCursor := underlyingTyp.TypeDeclaration()
|
||||||
|
|
||||||
|
// If the type decl for the reference already exists in anonyTypeMap
|
||||||
|
// then the refer has been processed in ProcessElaboratedType
|
||||||
|
if _, ok := ct.GetAnonyType(referTypeCursor); !ok && isCursorChildOf(referTypeCursor, cursor) {
|
||||||
|
// Handle unexpected named structures generated from anonymous RecordTypes in Typedefs
|
||||||
|
// In this case, libclang incorrectly reports an anonymous struct as a named struct
|
||||||
|
sourceCode := ct.GetTokens(referTypeCursor)
|
||||||
|
if isAnonymousStructure(sourceCode) {
|
||||||
|
anonyName := ct.GenerateAnonymousName(referTypeCursor)
|
||||||
|
// update reference's name
|
||||||
|
setInnerName(typ, anonyName)
|
||||||
|
ct.SetAnonyType(referTypeCursor, anonyName)
|
||||||
|
typ, isValidType := ct.GetTypeDecl(referTypeCursor)
|
||||||
|
if isValidType {
|
||||||
|
// There will be no anonymous classes,here will execute enum,union,struct
|
||||||
|
switch declType := typ.(type) {
|
||||||
|
case *ast.EnumTypeDecl:
|
||||||
|
declType.Name.Name = anonyName
|
||||||
|
case *ast.TypeDecl:
|
||||||
|
if declType.Type.Tag != ast.Class {
|
||||||
|
declType.Name.Name = anonyName
|
||||||
|
} else {
|
||||||
|
// Unreachable: There should be no anonymous classes in this context
|
||||||
|
fmt.Fprintln(os.Stderr, "unexpect typedef anonymous class %s", declType.Name.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Unreachable:When referencing an anonymous node, its collection must have been completed beforehand
|
||||||
|
fmt.Fprintln(os.Stderr, "anonymous node not collected before reference")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
|
||||||
|
// generates a name for an anonymous structure like:__ANONY_A_B_MYSTRUCT
|
||||||
|
func (ct *Converter) GenerateAnonymousName(cursor clang.Cursor) string {
|
||||||
|
return fmt.Sprintf("__ANONY_%s", strings.Join(ct.BuildScopingParts(cursor), "_"))
|
||||||
|
}
|
||||||
|
|
||||||
// converts functions, methods, constructors, destructors (including out-of-class decl) to ast.FuncDecl nodes.
|
// converts functions, methods, constructors, destructors (including out-of-class decl) to ast.FuncDecl nodes.
|
||||||
func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
|
func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
|
||||||
name := cursor.String()
|
name := cursor.String()
|
||||||
@@ -394,7 +449,7 @@ func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ct.AddTypeDecl(cursor, funcDecl)
|
ct.SetTypeDecl(cursor, funcDecl)
|
||||||
|
|
||||||
return funcDecl
|
return funcDecl
|
||||||
}
|
}
|
||||||
@@ -402,7 +457,7 @@ func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl {
|
|||||||
// get Methods Attributes
|
// get Methods Attributes
|
||||||
func (ct *Converter) ProcessMethodAttributes(cursor clang.Cursor, fn *ast.FuncDecl) {
|
func (ct *Converter) ProcessMethodAttributes(cursor clang.Cursor, fn *ast.FuncDecl) {
|
||||||
if parent := cursor.SemanticParent(); parent.Equal(cursor.LexicalParent()) != 1 {
|
if parent := cursor.SemanticParent(); parent.Equal(cursor.LexicalParent()) != 1 {
|
||||||
fn.DeclBase.Parent = buildScopingExpr(cursor.SemanticParent())
|
fn.DeclBase.Parent = ct.BuildScopingExpr(cursor.SemanticParent())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch cursor.Kind {
|
switch cursor.Kind {
|
||||||
@@ -480,7 +535,7 @@ func (ct *Converter) ProcessEnumDecl(cursor clang.Cursor) *ast.EnumTypeDecl {
|
|||||||
Name: &ast.Ident{Name: c.GoString(name.CStr())},
|
Name: &ast.Ident{Name: c.GoString(name.CStr())},
|
||||||
Type: ct.ProcessEnumType(cursor),
|
Type: ct.ProcessEnumType(cursor),
|
||||||
}
|
}
|
||||||
ct.AddTypeDecl(cursor, decl)
|
ct.SetTypeDecl(cursor, decl)
|
||||||
return decl
|
return decl
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,7 +669,7 @@ func (ct *Converter) ProcessRecordDecl(cursor clang.Cursor) *ast.TypeDecl {
|
|||||||
Name: name,
|
Name: name,
|
||||||
Type: ct.ProcessRecordType(cursor),
|
Type: ct.ProcessRecordType(cursor),
|
||||||
}
|
}
|
||||||
ct.AddTypeDecl(cursor, decl)
|
ct.SetTypeDecl(cursor, decl)
|
||||||
|
|
||||||
return decl
|
return decl
|
||||||
}
|
}
|
||||||
@@ -637,7 +692,7 @@ func (ct *Converter) ProcessClassDecl(cursor clang.Cursor) *ast.TypeDecl {
|
|||||||
Name: &ast.Ident{Name: c.GoString(cursor.String().CStr())},
|
Name: &ast.Ident{Name: c.GoString(cursor.String().CStr())},
|
||||||
Type: typ,
|
Type: typ,
|
||||||
}
|
}
|
||||||
ct.AddTypeDecl(cursor, decl)
|
ct.SetTypeDecl(cursor, decl)
|
||||||
|
|
||||||
return decl
|
return decl
|
||||||
}
|
}
|
||||||
@@ -677,16 +732,8 @@ func (ct *Converter) ProcessElaboratedType(t clang.Type) ast.Expr {
|
|||||||
return ct.ProcessRecordType(decl)
|
return ct.ProcessRecordType(decl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// type name refer
|
|
||||||
typeName := c.GoString(name.CStr())
|
typeName := c.GoString(name.CStr())
|
||||||
|
|
||||||
tagMap := map[string]ast.Tag{
|
|
||||||
"struct": ast.Struct,
|
|
||||||
"union": ast.Union,
|
|
||||||
"enum": ast.Enum,
|
|
||||||
"class": ast.Class,
|
|
||||||
}
|
|
||||||
|
|
||||||
// for elaborated type, it could have a tag description
|
// for elaborated type, it could have a tag description
|
||||||
// like struct A, union B, class C, enum D
|
// like struct A, union B, class C, enum D
|
||||||
parts := strings.SplitN(typeName, " ", 2)
|
parts := strings.SplitN(typeName, " ", 2)
|
||||||
@@ -694,12 +741,12 @@ func (ct *Converter) ProcessElaboratedType(t clang.Type) ast.Expr {
|
|||||||
if tagValue, ok := tagMap[parts[0]]; ok {
|
if tagValue, ok := tagMap[parts[0]]; ok {
|
||||||
return &ast.TagExpr{
|
return &ast.TagExpr{
|
||||||
Tag: tagValue,
|
Tag: tagValue,
|
||||||
Name: buildScopingExpr(t.TypeDeclaration()),
|
Name: ct.BuildScopingExpr(decl),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildScopingExpr(t.TypeDeclaration())
|
return ct.BuildScopingExpr(decl)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType {
|
func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType {
|
||||||
@@ -772,6 +819,32 @@ func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructs a complete scoping expression by traversing the semantic parents, starting from the given clang.Cursor
|
||||||
|
// For anonymous decl of typedef references, use their anonymous name
|
||||||
|
func (ct *Converter) BuildScopingExpr(cursor clang.Cursor) ast.Expr {
|
||||||
|
parts := ct.BuildScopingParts(cursor)
|
||||||
|
return buildScopingFromParts(parts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ct *Converter) BuildScopingParts(cursor clang.Cursor) []string {
|
||||||
|
var parts []string
|
||||||
|
// Traverse up the semantic parents
|
||||||
|
for cursor.IsNull() != 1 && cursor.Kind != clang.CursorTranslationUnit {
|
||||||
|
var qualified string
|
||||||
|
// anonymous decl quote
|
||||||
|
if anonyName, ok := ct.GetAnonyType(cursor); ok {
|
||||||
|
qualified = anonyName
|
||||||
|
} else {
|
||||||
|
name := cursor.String()
|
||||||
|
qualified = c.GoString(name.CStr())
|
||||||
|
name.Dispose()
|
||||||
|
}
|
||||||
|
parts = append([]string{qualified}, parts...)
|
||||||
|
cursor = cursor.SemanticParent()
|
||||||
|
}
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
|
||||||
func (ct *Converter) MarshalASTFiles() *cjson.JSON {
|
func (ct *Converter) MarshalASTFiles() *cjson.JSON {
|
||||||
return MarshalASTFiles(ct.Files)
|
return MarshalASTFiles(ct.Files)
|
||||||
}
|
}
|
||||||
@@ -798,22 +871,6 @@ func isMethod(cursor clang.Cursor) bool {
|
|||||||
return cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor
|
return cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a complete scoping expression by traversing the semantic parents, starting from the given clang.Cursor
|
|
||||||
func buildScopingExpr(cursor clang.Cursor) ast.Expr {
|
|
||||||
var parts []string
|
|
||||||
|
|
||||||
// Traverse up the semantic parents
|
|
||||||
for cursor.IsNull() != 1 && cursor.Kind != clang.CursorTranslationUnit {
|
|
||||||
name := cursor.String()
|
|
||||||
qualified := c.GoString(name.CStr())
|
|
||||||
parts = append([]string{qualified}, parts...)
|
|
||||||
cursor = cursor.SemanticParent()
|
|
||||||
name.Dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildScopingFromParts(parts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildScopingFromParts(parts []string) ast.Expr {
|
func buildScopingFromParts(parts []string) ast.Expr {
|
||||||
if len(parts) == 0 {
|
if len(parts) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@@ -847,3 +904,24 @@ func getOffset(location clang.SourceLocation) c.Uint {
|
|||||||
location.SpellingLocation(nil, nil, nil, &offset)
|
location.SpellingLocation(nil, nil, nil, &offset)
|
||||||
return offset
|
return offset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setTagName updates the name of the innermost Ident in a Name Expr
|
||||||
|
func setInnerName(expr ast.Expr, name string) {
|
||||||
|
switch e := expr.(type) {
|
||||||
|
case *ast.TagExpr:
|
||||||
|
setInnerName(e.Name, name)
|
||||||
|
case *ast.ScopingExpr:
|
||||||
|
setInnerName(e.X, name)
|
||||||
|
case *ast.Ident:
|
||||||
|
e.Name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks if the source code represents an actual anonymous structure
|
||||||
|
func isAnonymousStructure(sourceCode []*ast.Token) bool {
|
||||||
|
_, isValidTag := tagMap[sourceCode[0].Lit]
|
||||||
|
return sourceCode[0].Token == token.KEYWORD &&
|
||||||
|
isValidTag &&
|
||||||
|
sourceCode[1].Token == token.PUNCT &&
|
||||||
|
sourceCode[1].Lit == "{"
|
||||||
|
}
|
||||||
|
|||||||
@@ -472,6 +472,589 @@ TestTypeDefDecl Case 6:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestTypeDefDecl Case 7:
|
||||||
|
{
|
||||||
|
"temp.h": {
|
||||||
|
"_Type": "File",
|
||||||
|
"decls": [{
|
||||||
|
"_Type": "TypeDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyStruct"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "RecordType",
|
||||||
|
"Tag": 0,
|
||||||
|
"Fields": {
|
||||||
|
"_Type": "FieldList",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": null,
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "x"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Methods": []
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "MyStruct"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyStruct"
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"includes": [],
|
||||||
|
"macros": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestTypeDefDecl Case 8:
|
||||||
|
{
|
||||||
|
"temp.h": {
|
||||||
|
"_Type": "File",
|
||||||
|
"decls": [{
|
||||||
|
"_Type": "TypeDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyUnion"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "RecordType",
|
||||||
|
"Tag": 1,
|
||||||
|
"Fields": {
|
||||||
|
"_Type": "FieldList",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": null,
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "x"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Methods": []
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "MyUnion"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyUnion"
|
||||||
|
},
|
||||||
|
"Tag": 1
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"includes": [],
|
||||||
|
"macros": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestTypeDefDecl Case 9:
|
||||||
|
{
|
||||||
|
"temp.h": {
|
||||||
|
"_Type": "File",
|
||||||
|
"decls": [{
|
||||||
|
"_Type": "EnumTypeDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyEnum"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "EnumType",
|
||||||
|
"Items": [{
|
||||||
|
"_Type": "EnumItem",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "RED"
|
||||||
|
},
|
||||||
|
"Value": {
|
||||||
|
"_Type": "BasicLit",
|
||||||
|
"Kind": 0,
|
||||||
|
"Value": "0"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "EnumItem",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "GREEN"
|
||||||
|
},
|
||||||
|
"Value": {
|
||||||
|
"_Type": "BasicLit",
|
||||||
|
"Kind": 0,
|
||||||
|
"Value": "1"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "EnumItem",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "BLUE"
|
||||||
|
},
|
||||||
|
"Value": {
|
||||||
|
"_Type": "BasicLit",
|
||||||
|
"Kind": 0,
|
||||||
|
"Value": "2"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "MyEnum"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyEnum"
|
||||||
|
},
|
||||||
|
"Tag": 2
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"includes": [],
|
||||||
|
"macros": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestTypeDefDecl Case 10:
|
||||||
|
{
|
||||||
|
"temp.h": {
|
||||||
|
"_Type": "File",
|
||||||
|
"decls": [{
|
||||||
|
"_Type": "TypeDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyStruct"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "RecordType",
|
||||||
|
"Tag": 0,
|
||||||
|
"Fields": {
|
||||||
|
"_Type": "FieldList",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": null,
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "x"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Methods": []
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "MyStruct"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyStruct"
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "MyStruct2"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyStruct"
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "StructPtr"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "PointerType",
|
||||||
|
"X": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyStruct"
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": null,
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "StructArr"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "ArrayType",
|
||||||
|
"Elt": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_MyStruct"
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
},
|
||||||
|
"Len": null
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"includes": [],
|
||||||
|
"macros": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestTypeDefDecl Case 11:
|
||||||
|
{
|
||||||
|
"temp.h": {
|
||||||
|
"_Type": "File",
|
||||||
|
"decls": [{
|
||||||
|
"_Type": "TypeDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_A_B_MyStruct"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "RecordType",
|
||||||
|
"Tag": 0,
|
||||||
|
"Fields": {
|
||||||
|
"_Type": "FieldList",
|
||||||
|
"List": [{
|
||||||
|
"_Type": "Field",
|
||||||
|
"Type": {
|
||||||
|
"_Type": "BuiltinType",
|
||||||
|
"Kind": 6,
|
||||||
|
"Flags": 0
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Comment": null,
|
||||||
|
"IsStatic": false,
|
||||||
|
"Access": 1,
|
||||||
|
"Names": [{
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "x"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"Methods": []
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "MyStruct"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_A_B_MyStruct"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "MyStruct2"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_A_B_MyStruct"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "StructPtr"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "PointerType",
|
||||||
|
"X": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_A_B_MyStruct"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"_Type": "TypedefDecl",
|
||||||
|
"Loc": {
|
||||||
|
"_Type": "Location",
|
||||||
|
"File": "temp.h"
|
||||||
|
},
|
||||||
|
"Doc": null,
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Name": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "StructArr"
|
||||||
|
},
|
||||||
|
"Type": {
|
||||||
|
"_Type": "ArrayType",
|
||||||
|
"Elt": {
|
||||||
|
"_Type": "TagExpr",
|
||||||
|
"Name": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "__ANONY_A_B_MyStruct"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "ScopingExpr",
|
||||||
|
"X": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "B"
|
||||||
|
},
|
||||||
|
"Parent": {
|
||||||
|
"_Type": "Ident",
|
||||||
|
"Name": "A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Tag": 0
|
||||||
|
},
|
||||||
|
"Len": null
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"includes": [],
|
||||||
|
"macros": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#stderr
|
#stderr
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,30 @@ func TestTypeDefDecl() {
|
|||||||
int x;
|
int x;
|
||||||
} MyClass,*MyClassPtr,MyClassArray[];
|
} MyClass,*MyClassPtr,MyClassArray[];
|
||||||
}`,
|
}`,
|
||||||
|
|
||||||
|
`typedef struct {
|
||||||
|
int x;
|
||||||
|
} MyStruct`,
|
||||||
|
`typedef union {
|
||||||
|
int x;
|
||||||
|
} MyUnion`,
|
||||||
|
`typedef enum {
|
||||||
|
RED,
|
||||||
|
GREEN,
|
||||||
|
BLUE
|
||||||
|
} MyEnum`,
|
||||||
|
|
||||||
|
`typedef struct {
|
||||||
|
int x;
|
||||||
|
} MyStruct,MyStruct2,*StructPtr, StructArr[];`,
|
||||||
|
|
||||||
|
`namespace A{
|
||||||
|
namespace B{
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
} MyStruct,MyStruct2,*StructPtr, StructArr[];
|
||||||
|
}
|
||||||
|
}`,
|
||||||
}
|
}
|
||||||
test.RunTest("TestTypeDefDecl", testCases)
|
test.RunTest("TestTypeDefDecl", testCases)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user