Make struct and enum indexing more local
This commit is contained in:
committed by
SvyatoslavScherbina
parent
0b7aff3d11
commit
30bab17c21
+46
-37
@@ -53,12 +53,41 @@ internal class NativeIndexImpl(val language: Language) : NativeIndex() {
|
|||||||
private fun getStructDeclAt(cursor: CValue<CXCursor>): StructDeclImpl {
|
private fun getStructDeclAt(cursor: CValue<CXCursor>): StructDeclImpl {
|
||||||
val declId = getDeclarationId(cursor)
|
val declId = getDeclarationId(cursor)
|
||||||
|
|
||||||
return structById.getOrPut(declId) {
|
val structDecl = structById.getOrPut(declId) {
|
||||||
val cursorType = clang_getCursorType(cursor)
|
val cursorType = clang_getCursorType(cursor)
|
||||||
val typeSpelling = clang_getTypeSpelling(cursorType).convertAndDispose()
|
val typeSpelling = clang_getTypeSpelling(cursorType).convertAndDispose()
|
||||||
|
|
||||||
StructDeclImpl(typeSpelling)
|
StructDeclImpl(typeSpelling)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (structDecl.def == null) {
|
||||||
|
val definitionCursor = clang_getCursorDefinition(cursor)
|
||||||
|
if (clang_Cursor_isNull(definitionCursor) == 0) {
|
||||||
|
assert (clang_isCursorDefinition(definitionCursor) != 0)
|
||||||
|
createStructDef(structDecl, cursor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return structDecl
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createStructDef(structDecl: StructDeclImpl, cursor: CValue<CXCursor>) {
|
||||||
|
val type = clang_getCursorType(cursor)
|
||||||
|
val size = clang_Type_getSizeOf(type)
|
||||||
|
val align = clang_Type_getAlignOf(type).toInt()
|
||||||
|
val hasNaturalLayout = structHasNaturalLayout(cursor)
|
||||||
|
val structDef = StructDefImpl(size, align, structDecl, hasNaturalLayout)
|
||||||
|
structDecl.def = structDef
|
||||||
|
|
||||||
|
visitChildren(cursor) { childCursor: CValue<CXCursor>, _: CValue<CXCursor> ->
|
||||||
|
if (clang_getCursorKind(childCursor) == CXCursorKind.CXCursor_FieldDecl) {
|
||||||
|
val name = clang_getCursorSpelling(childCursor).convertAndDispose()
|
||||||
|
val fieldType = convertCursorType(childCursor)
|
||||||
|
val offset = clang_Cursor_getOffsetOfField(childCursor)
|
||||||
|
structDef.fields.add(Field(name, fieldType, offset))
|
||||||
|
}
|
||||||
|
CXChildVisitResult.CXChildVisit_Continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getEnumDefAt(cursor: CValue<CXCursor>): EnumDefImpl {
|
private fun getEnumDefAt(cursor: CValue<CXCursor>): EnumDefImpl {
|
||||||
@@ -74,7 +103,21 @@ internal class NativeIndexImpl(val language: Language) : NativeIndex() {
|
|||||||
|
|
||||||
val baseType = convertType(clang_getEnumDeclIntegerType(cursor)) as PrimitiveType
|
val baseType = convertType(clang_getEnumDeclIntegerType(cursor)) as PrimitiveType
|
||||||
|
|
||||||
EnumDefImpl(typeSpelling, baseType)
|
val enumDef = EnumDefImpl(typeSpelling, baseType)
|
||||||
|
|
||||||
|
visitChildren(cursor) { childCursor, _ ->
|
||||||
|
if (clang_getCursorKind(childCursor) == CXCursorKind.CXCursor_EnumConstantDecl) {
|
||||||
|
val name = clang_getCursorSpelling(childCursor).convertAndDispose()
|
||||||
|
val value = clang_getEnumConstantDeclValue(childCursor)
|
||||||
|
|
||||||
|
val constant = EnumConstant(name, value, isExplicitlyDefined = !childCursor.isLeaf())
|
||||||
|
enumDef.constants.add(constant)
|
||||||
|
}
|
||||||
|
|
||||||
|
CXChildVisitResult.CXChildVisit_Continue
|
||||||
|
}
|
||||||
|
|
||||||
|
enumDef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,25 +276,8 @@ internal class NativeIndexImpl(val language: Language) : NativeIndex() {
|
|||||||
val entityName = entityInfo.name.value?.toKString()
|
val entityName = entityInfo.name.value?.toKString()
|
||||||
val kind = entityInfo.kind.value
|
val kind = entityInfo.kind.value
|
||||||
when (kind) {
|
when (kind) {
|
||||||
CXIdxEntity_Field -> {
|
|
||||||
val name = entityName!!
|
|
||||||
val type = convertCursorType(cursor)
|
|
||||||
val offset = clang_Cursor_getOffsetOfField(cursor)
|
|
||||||
|
|
||||||
val container = info.semanticContainer.pointed!!
|
|
||||||
val structDef = getStructDeclAt(container.cursor.readValue()).def!!
|
|
||||||
structDef.fields.add(Field(name, type, offset))
|
|
||||||
}
|
|
||||||
|
|
||||||
CXIdxEntity_Struct, CXIdxEntity_Union -> {
|
CXIdxEntity_Struct, CXIdxEntity_Union -> {
|
||||||
val structDecl = getStructDeclAt(cursor)
|
getStructDeclAt(cursor)
|
||||||
if (clang_isCursorDefinition(cursor) != 0) {
|
|
||||||
val type = clang_getCursorType(cursor)
|
|
||||||
val size = clang_Type_getSizeOf(type)
|
|
||||||
val align = clang_Type_getAlignOf(type).toInt()
|
|
||||||
val hasNaturalLayout = structHasNaturalLayout(cursor)
|
|
||||||
structDecl.def = StructDefImpl(size, align, structDecl, hasNaturalLayout)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CXIdxEntity_Function -> {
|
CXIdxEntity_Function -> {
|
||||||
@@ -280,23 +306,6 @@ internal class NativeIndexImpl(val language: Language) : NativeIndex() {
|
|||||||
CXIdxEntity_Enum -> {
|
CXIdxEntity_Enum -> {
|
||||||
getEnumDefAt(cursor)
|
getEnumDefAt(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
CXIdxEntity_EnumConstant -> {
|
|
||||||
val container = info.semanticContainer.pointed!!
|
|
||||||
val name = entityName!!
|
|
||||||
val value = clang_getEnumConstantDeclValue(info.cursor.readValue())
|
|
||||||
|
|
||||||
val constants = getEnumDefAt(container.cursor.readValue()).constants
|
|
||||||
val existingConstant = constants.find { it.name == name }
|
|
||||||
if (existingConstant == null) {
|
|
||||||
val constant = EnumConstant(name, value, isExplicitlyDefined = !cursor.isLeaf())
|
|
||||||
constants.add(constant)
|
|
||||||
} else {
|
|
||||||
// in some cases Clang may index the same definition multiple times; ignore redeclaration
|
|
||||||
// TODO: implement the same fix for structs
|
|
||||||
assert (existingConstant.value == value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -581,7 +581,9 @@ class StubGenerator(
|
|||||||
out("")
|
out("")
|
||||||
out("companion object : Type(${def.size}, ${def.align})") // FIXME: align
|
out("companion object : Type(${def.size}, ${def.align})") // FIXME: align
|
||||||
out("")
|
out("")
|
||||||
def.fields.forEach { field ->
|
for (field in def.fields) {
|
||||||
|
if (field.name.isEmpty()) continue
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (field.offset < 0) throw NotImplementedError();
|
if (field.offset < 0) throw NotImplementedError();
|
||||||
assert(field.offset % 8 == 0L)
|
assert(field.offset % 8 == 0L)
|
||||||
|
|||||||
Reference in New Issue
Block a user