Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
261edfd7
Y
YTBP
项目概览
YottaChain
/
YTBP
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
YTBP
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
261edfd7
编写于
2月 28, 2018
作者:
M
Matias Romeo
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add vector support to ABI generator
上级
844586a7
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
272 addition
and
132 deletion
+272
-132
libraries/abi_generator/abi_generator.cpp
libraries/abi_generator/abi_generator.cpp
+242
-120
libraries/abi_generator/include/eosio/abi_generator/abi_generator.hpp
...i_generator/include/eosio/abi_generator/abi_generator.hpp
+25
-5
programs/eosio-abigen/main.cpp
programs/eosio-abigen/main.cpp
+5
-7
未找到文件。
libraries/abi_generator/abi_generator.cpp
浏览文件 @
261edfd7
...
...
@@ -27,18 +27,29 @@ void abi_generator::set_compiler_instance(CompilerInstance& compiler_instance) {
}
void
abi_generator
::
handle_tagdecl_definition
(
TagDecl
*
tag_decl
)
{
ASTContext
&
ctx
=
tag_decl
->
getASTContext
();
auto
decl_location
=
tag_decl
->
getLocation
().
printToString
(
ctx
.
getSourceManager
());
ast_context
=
&
tag_decl
->
getASTContext
();
auto
decl_location
=
tag_decl
->
getLocation
().
printToString
(
ast_context
->
getSourceManager
());
try
{
handle_decl
(
tag_decl
);
}
FC_CAPTURE_AND_RETHROW
((
decl_location
))
}
string
abi_generator
::
remove_namespace
(
const
string
&
full_name
)
{
string
type_name
=
full_name
;
auto
pos
=
type_name
.
find_last_of
(
"::"
);
if
(
pos
!=
string
::
npos
)
type_name
=
type_name
.
substr
(
pos
+
1
);
return
type_name
;
int
i
=
full_name
.
size
();
int
on_spec
=
0
;
int
colons
=
0
;
while
(
--
i
>=
0
)
{
if
(
full_name
[
i
]
==
'>'
)
{
++
on_spec
;
colons
=
0
;
}
else
if
(
full_name
[
i
]
==
'<'
)
{
--
on_spec
;
colons
=
0
;
}
else
if
(
full_name
[
i
]
==
':'
&&
!
on_spec
)
{
if
(
++
colons
==
2
)
return
full_name
.
substr
(
i
+
2
);
}
else
{
colons
=
0
;
}
}
return
full_name
;
}
bool
abi_generator
::
is_builtin_type
(
const
string
&
type_name
)
{
...
...
@@ -70,13 +81,14 @@ void abi_generator::handle_decl(const Decl* decl) { try {
ABI_ASSERT
(
decl
!=
nullptr
);
ABI_ASSERT
(
output
!=
nullptr
);
ABI_ASSERT
(
ast_context
!=
nullptr
);
ASTContext
&
ctx
=
decl
->
getASTContext
();
const
RawComment
*
raw_comment
=
ctx
.
getRawCommentForDeclNoCache
(
decl
);
//
ASTContext& ctx = decl->getASTContext();
const
RawComment
*
raw_comment
=
ast_context
->
getRawCommentForDeclNoCache
(
decl
);
if
(
!
raw_comment
)
return
;
SourceManager
&
source_manager
=
ctx
.
getSourceManager
();
SourceManager
&
source_manager
=
ast_context
->
getSourceManager
();
auto
file_name
=
source_manager
.
getFilename
(
raw_comment
->
getLocStart
());
if
(
!
abi_context
.
empty
()
&&
!
file_name
.
startswith
(
abi_context
)
)
{
return
;
...
...
@@ -105,7 +117,7 @@ void abi_generator::handle_decl(const Decl* decl) { try {
auto
qt
=
action_decl
->
getTypeForDecl
()
->
getCanonicalTypeInternal
();
auto
type_name
=
remove_namespace
(
add_struct
(
qt
)
);
auto
type_name
=
add_struct
(
qt
);
ABI_ASSERT
(
!
is_builtin_type
(
type_name
),
"A built-in type with the same name exists, try using another name: ${type_name}"
,
(
"type_name"
,
type_name
));
...
...
@@ -128,7 +140,7 @@ void abi_generator::handle_decl(const Decl* decl) { try {
ABI_ASSERT
(
table_decl
!=
nullptr
);
auto
qt
=
table_decl
->
getTypeForDecl
()
->
getCanonicalTypeInternal
();
auto
type_name
=
remove_namespace
(
add_struct
(
qt
)
);
auto
type_name
=
add_struct
(
qt
);
ABI_ASSERT
(
!
is_builtin_type
(
type_name
),
"A built-in type with the same name exists, try using another name: ${type_name}"
,
(
"type_name"
,
type_name
));
...
...
@@ -140,16 +152,16 @@ void abi_generator::handle_decl(const Decl* decl) { try {
table
.
name
=
boost
::
algorithm
::
to_lower_copy
(
boost
::
erase_all_copy
(
type_name
,
"_"
));
table
.
type
=
type_name
;
if
(
params
.
size
()
>=
1
)
table
.
index_type
=
params
[
0
];
if
(
params
.
size
()
>=
1
)
{
table
.
name
=
params
[
0
];
}
if
(
params
.
size
()
>=
2
)
table
.
index_type
=
params
[
1
];
else
{
try
{
guess_index_type
(
table
,
*
s
);
}
FC_CAPTURE_AND_RETHROW
(
(
type_name
)
)
}
if
(
params
.
size
()
>=
2
)
{
table
.
name
=
params
[
1
];
}
try
{
guess_key_names
(
table
,
*
s
);
}
FC_CAPTURE_AND_RETHROW
(
(
type_name
)
)
...
...
@@ -181,9 +193,11 @@ bool abi_generator::is_string(const string& type) {
void
abi_generator
::
get_all_fields
(
const
struct_def
&
s
,
vector
<
field_def
>&
fields
)
{
abi_serializer
abis
(
*
output
);
for
(
const
auto
&
field
:
s
.
fields
)
{
fields
.
push_back
(
field
);
}
if
(
s
.
base
.
size
())
{
const
auto
*
base
=
find_struct
(
s
.
base
);
ABI_ASSERT
(
base
,
"Unable to find base type ${type}"
,(
"type"
,
s
.
base
));
...
...
@@ -211,7 +225,7 @@ void abi_generator::guess_index_type(table_def& table, const struct_def s) {
vector
<
field_def
>
fields
;
get_all_fields
(
s
,
fields
);
if
(
is_str_index
(
fields
)
)
{
table
.
index_type
=
"str"
;
}
else
if
(
is_i64i64i64_index
(
fields
)
)
{
...
...
@@ -230,15 +244,28 @@ void abi_generator::guess_key_names(table_def& table, const struct_def s) {
vector
<
field_def
>
fields
;
get_all_fields
(
s
,
fields
);
if
(
table
.
index_type
==
"i64i64i64"
&&
is_i64i64i64_index
(
fields
)
)
{
table
.
key_names
=
vector
<
field_name
>
{
fields
[
0
].
name
,
fields
[
1
].
name
,
fields
[
2
].
name
};
table
.
key_types
=
vector
<
type_name
>
{
fields
[
0
].
type
,
fields
[
1
].
type
,
fields
[
2
].
type
};
}
else
if
(
table
.
index_type
==
"i128i128"
&&
is_i128i128_index
(
fields
)
)
{
table
.
key_names
=
vector
<
field_name
>
{
fields
[
0
].
name
,
fields
[
1
].
name
};
table
.
key_types
=
vector
<
type_name
>
{
fields
[
0
].
type
,
fields
[
1
].
type
};
}
else
if
(
table
.
index_type
==
"i64"
&&
is_i64_index
(
fields
)
)
{
table
.
key_names
=
vector
<
field_name
>
{
fields
[
0
].
name
};
table
.
key_types
=
vector
<
type_name
>
{
fields
[
0
].
type
};
if
(
table
.
index_type
==
"i64i64i64"
||
table
.
index_type
==
"i128i128"
||
table
.
index_type
==
"i64"
)
{
table
.
key_names
.
clear
();
table
.
key_types
.
clear
();
unsigned
int
key_size
=
0
;
bool
valid_key
=
false
;
for
(
auto
&
f
:
fields
)
{
table
.
key_names
.
emplace_back
(
f
.
name
);
table
.
key_types
.
emplace_back
(
f
.
type
);
key_size
+=
type_size
[
f
.
type
]
/
8
;
if
((
table
.
index_type
==
"i64i64i64"
&&
key_size
>=
sizeof
(
uint64_t
)
*
3
)
||
(
table
.
index_type
==
"i64"
&&
key_size
>=
sizeof
(
uint64_t
))
||
(
table
.
index_type
==
"i128i128"
&&
key_size
>=
sizeof
(
__int128
)
*
2
))
{
valid_key
=
true
;
break
;
}
}
ABI_ASSERT
(
valid_key
,
"Unable to guess key names"
);
}
else
if
(
table
.
index_type
==
"str"
&&
is_str_index
(
fields
)
)
{
table
.
key_names
=
vector
<
field_name
>
{
fields
[
0
].
name
};
table
.
key_types
=
vector
<
type_name
>
{
fields
[
0
].
type
};
...
...
@@ -298,95 +325,196 @@ bool abi_generator::is_one_filed_no_base(const string& type_name) {
}
string
abi_generator
::
decl_to_string
(
clang
::
Decl
*
d
)
{
ASTContext
&
ctx
=
d
->
getASTContext
();
const
auto
&
sm
=
ctx
.
getSourceManager
();
//
ASTContext& ctx = d->getASTContext();
const
auto
&
sm
=
ast_context
->
getSourceManager
();
clang
::
SourceLocation
b
(
d
->
getLocStart
()),
_e
(
d
->
getLocEnd
());
clang
::
SourceLocation
e
(
clang
::
Lexer
::
getLocForEndOfToken
(
_e
,
0
,
sm
,
compiler_instance
->
getLangOpts
()));
return
string
(
sm
.
getCharacterData
(
b
),
sm
.
getCharacterData
(
e
)
-
sm
.
getCharacterData
(
b
));
}
void
abi_generator
::
add_typedef
(
const
clang
::
TypedefType
*
typeDef
)
{
bool
abi_generator
::
is_typedef
(
const
clang
::
QualType
&
qt
)
{
return
isa
<
TypedefType
>
(
qt
.
getTypePtr
());
}
vector
<
type_def
>
types_to_add
;
while
(
typeDef
!=
nullptr
)
{
const
auto
*
typedef_decl
=
typeDef
->
getDecl
();
auto
qt
=
typedef_decl
->
getUnderlyingType
().
getUnqualifiedType
();
bool
abi_generator
::
is_elaborated
(
const
clang
::
QualType
&
qt
)
{
return
isa
<
ElaboratedType
>
(
qt
.
getTypePtr
());
}
auto
full_name
=
translate_type
(
qt
.
getAsString
(
compiler_instance
->
getLangOpts
()));
bool
abi_generator
::
is_vector
(
const
clang
::
QualType
&
vqt
)
{
QualType
qt
(
vqt
);
//HACK: We need to think another way to stop importing the "typedef chain"
if
(
full_name
.
find
(
"<"
)
!=
string
::
npos
)
{
break
;
}
if
(
is_elaborated
(
qt
)
)
qt
=
qt
->
getAs
<
clang
::
ElaboratedType
>
()
->
getNamedType
();
auto
new_type_name
=
translate_type
(
typedef_decl
->
getName
().
str
());
if
(
is_builtin_type
(
new_type_name
))
{
break
;
}
return
isa
<
clang
::
TemplateSpecializationType
>
(
qt
.
getTypePtr
())
\
&&
boost
::
starts_with
(
get_type_name
(
qt
,
false
),
"vector"
);
}
bool
abi_generator
::
is_vector
(
const
string
&
type_name
)
{
return
boost
::
ends_with
(
type_name
,
"[]"
);
}
//TODO: ABI_ASSERT TypeName length for typedef
type_def
abi_typedef
;
abi_typedef
.
new_type_name
=
new_type_name
;
abi_typedef
.
type
=
remove_namespace
(
full_name
);
bool
abi_generator
::
is_struct_specialization
(
const
clang
::
QualType
&
qt
)
{
return
is_struct
(
qt
)
&&
isa
<
clang
::
TemplateSpecializationType
>
(
qt
.
getTypePtr
());
}
const
auto
*
td
=
find_type
(
abi_typedef
.
new_type_name
);
if
(
td
)
{
ABI_ASSERT
(
abi_typedef
.
type
==
td
->
type
);
typeDef
=
qt
->
getAs
<
clang
::
TypedefType
>
();
continue
;
}
bool
abi_generator
::
is_struct
(
const
clang
::
QualType
&
sqt
)
{
clang
::
QualType
qt
(
sqt
);
const
auto
*
type
=
qt
.
getTypePtr
();
return
!
is_vector
(
qt
)
&&
(
type
->
isStructureType
()
||
type
->
isClassType
());
}
clang
::
QualType
abi_generator
::
get_vector_element_type
(
const
clang
::
QualType
&
qt
)
{
const
auto
*
tst
=
clang
::
dyn_cast
<
const
clang
::
TemplateSpecializationType
>
(
qt
.
getTypePtr
());
ABI_ASSERT
(
tst
!=
nullptr
);
const
clang
::
TemplateArgument
&
arg0
=
tst
->
getArg
(
0
);
return
arg0
.
getAsType
();
}
string
abi_generator
::
get_vector_element_type
(
const
string
&
type_name
)
{
if
(
is_vector
(
type_name
)
)
return
type_name
.
substr
(
0
,
type_name
.
size
()
-
2
);
return
type_name
;
}
string
abi_generator
::
get_type_name
(
const
clang
::
QualType
&
qt
,
bool
with_namespace
=
false
)
{
auto
name
=
clang
::
TypeName
::
getFullyQualifiedName
(
qt
,
*
ast_context
);
if
(
!
with_namespace
)
name
=
remove_namespace
(
name
);
return
name
;
}
clang
::
QualType
abi_generator
::
add_typedef
(
const
clang
::
QualType
&
tqt
)
{
//ilog("addTypeDef => ${a} ${b} [${c}]", ("a",abi_typedef.new_type_name)("b",abi_typedef.type)("c",getFullScope(qt)));
ABI_ASSERT
(
abi_typedef
.
new_type_name
!=
abi_typedef
.
type
,
"Unable to export typedef `${td}` at ${at}"
,
(
"td"
,
decl_to_string
(
typeDef
->
getDecl
()))
(
"at"
,
typeDef
->
getDecl
()
->
getLocation
().
printToString
(
typeDef
->
getDecl
()
->
getASTContext
().
getSourceManager
()))
);
clang
::
QualType
qt
(
get_named_type_if_elaborated
(
tqt
));
types_to_add
.
push_back
(
abi_typedef
);
typeDef
=
qt
->
getAs
<
clang
::
TypedefType
>
();
const
auto
*
td_decl
=
qt
->
getAs
<
clang
::
TypedefType
>
()
->
getDecl
();
auto
underlying_type
=
td_decl
->
getUnderlyingType
().
getUnqualifiedType
();
auto
new_type_name
=
td_decl
->
getName
().
str
();
auto
underlying_type_name
=
get_type_name
(
underlying_type
);
if
(
is_vector
(
underlying_type
)
)
{
underlying_type_name
=
add_vector
(
underlying_type
);
}
type_def
abi_typedef
;
abi_typedef
.
new_type_name
=
new_type_name
;
abi_typedef
.
type
=
translate_type
(
underlying_type_name
);
const
auto
*
td
=
find_type
(
abi_typedef
.
new_type_name
);
if
(
!
td
&&
!
is_struct_specialization
(
underlying_type
)
)
{
output
->
types
.
push_back
(
abi_typedef
);
}
else
{
if
(
td
)
ABI_ASSERT
(
abi_typedef
.
type
==
td
->
type
);
}
std
::
reverse
(
types_to_add
.
begin
(),
types_to_add
.
end
());
output
->
types
.
insert
(
output
->
types
.
end
(),
types_to_add
.
begin
(),
types_to_add
.
end
());
if
(
is_typedef
(
underlying_type
)
&&
!
is_builtin_type
(
get_type_name
(
underlying_type
))
)
return
add_typedef
(
underlying_type
);
return
underlying_type
;
}
string
abi_generator
::
get_name_to_add
(
const
clang
::
QualType
&
qual_type
)
{
clang
::
CXXRecordDecl
::
base_class_range
abi_generator
::
get_struct_bases
(
const
clang
::
QualType
&
sqt
)
{
auto
type_name
=
qual_type
.
getAsString
(
compiler_instance
->
getLangOpts
());
const
auto
*
typedef_type
=
qual_type
->
getAs
<
clang
::
TypedefType
>
();
if
(
!
is_builtin_type
(
type_name
)
&&
typedef_type
!=
nullptr
)
{
add_typedef
(
typedef_type
);
}
clang
::
QualType
qt
(
sqt
);
if
(
is_typedef
(
qt
))
{
const
auto
*
td_decl
=
qt
->
getAs
<
clang
::
TypedefType
>
()
->
getDecl
();
qt
=
td_decl
->
getUnderlyingType
().
getUnqualifiedType
();
}
const
auto
*
record_type
=
qt
->
getAs
<
clang
::
RecordType
>
();
ABI_ASSERT
(
record_type
!=
nullptr
);
auto
cxxrecord_decl
=
clang
::
dyn_cast
<
CXXRecordDecl
>
(
record_type
->
getDecl
());
ABI_ASSERT
(
cxxrecord_decl
!=
nullptr
);
//record_type->getCanonicalTypeInternal().dump();
return
type_name
;
auto
bases
=
cxxrecord_decl
->
bases
();
return
bases
;
}
string
abi_generator
::
add_struct
(
const
clang
::
QualType
&
qual_type
)
{
const
clang
::
RecordDecl
::
field_range
abi_generator
::
get_struct_fields
(
const
clang
::
QualType
&
sqt
)
{
clang
::
QualType
qt
(
sqt
);
ABI_ASSERT
(
output
!=
nullptr
);
if
(
is_typedef
(
qt
))
{
const
auto
*
td_decl
=
qt
->
getAs
<
clang
::
TypedefType
>
()
->
getDecl
();
qt
=
td_decl
->
getUnderlyingType
().
getUnqualifiedType
();
}
const
auto
*
record_type
=
q
ual_type
->
getAs
<
clang
::
RecordType
>
();
const
auto
*
record_type
=
q
t
->
getAs
<
clang
::
RecordType
>
();
ABI_ASSERT
(
record_type
!=
nullptr
);
return
record_type
->
getDecl
()
->
fields
();
}
string
abi_generator
::
add_vector
(
const
clang
::
QualType
&
vqt
)
{
clang
::
QualType
qt
(
get_named_type_if_elaborated
(
vqt
));
auto
vector_element_type
=
get_vector_element_type
(
qt
);
ABI_ASSERT
(
!
is_vector
(
vector_element_type
),
"Only one-dimensional arrays are supported"
);
const
auto
*
record_decl
=
clang
::
cast_or_null
<
clang
::
CXXRecordDecl
>
(
record_type
->
getDecl
()
->
getDefinition
());
ABI_ASSERT
(
record_decl
!=
nullptr
);
add_type
(
vector_element_type
);
auto
vector_element_type_str
=
translate_type
(
get_type_name
(
vector_element_type
));
vector_element_type_str
+=
"[]"
;
ASTContext
&
ctx
=
record_decl
->
getASTContext
();
return
vector_element_type_str
;
}
auto
full_name
=
get_name_to_add
(
qual_type
);
string
abi_generator
::
add_type
(
const
clang
::
QualType
&
tqt
)
{
auto
name
=
remove_namespace
(
full_name
);
clang
::
QualType
qt
(
get_named_type_if_elaborated
(
tqt
)
);
//Only export user defined types
if
(
is_builtin_type
(
name
)
)
{
return
name
;
string
full_type_name
=
translate_type
(
get_type_name
(
qt
,
true
));
string
type_name
=
translate_type
(
get_type_name
(
qt
));
bool
is_type_def
=
false
;
if
(
is_builtin_type
(
type_name
)
)
{
return
type_name
;
}
if
(
is_typedef
(
qt
)
)
{
qt
=
add_typedef
(
qt
);
if
(
is_builtin_type
(
translate_type
(
get_type_name
(
qt
)))
)
{
return
type_name
;
}
is_type_def
=
true
;
}
if
(
is_vector
(
qt
)
)
{
auto
vector_type_name
=
add_vector
(
qt
);
return
is_type_def
?
type_name
:
vector_type_name
;
}
if
(
is_struct
(
qt
)
)
{
return
add_struct
(
qt
,
full_type_name
);
}
ABI_ASSERT
(
false
,
"types can only be: vector, struct, class or a built-in type. (${type}) "
,
(
"type"
,
get_type_name
(
qt
)));
return
type_name
;
}
clang
::
QualType
abi_generator
::
get_named_type_if_elaborated
(
const
clang
::
QualType
&
qt
)
{
if
(
is_elaborated
(
qt
)
)
{
return
qt
->
getAs
<
clang
::
ElaboratedType
>
()
->
getNamedType
();
}
return
qt
;
}
const
auto
*
type
=
qual_type
.
getTypePtr
();
string
abi_generator
::
add_struct
(
const
clang
::
QualType
&
sqt
,
string
full_name
)
{
clang
::
QualType
qt
(
get_named_type_if_elaborated
(
sqt
));
if
(
full_name
.
empty
()
)
{
full_name
=
get_type_name
(
qt
,
true
);
}
ABI_ASSERT
(
type
->
isStructureType
()
||
type
->
isClassType
(),
"Only struct and class are supported. ${full_name}"
,(
"full_name"
,
full_name
));
auto
name
=
remove_namespace
(
full_name
);
ABI_ASSERT
(
is_struct
(
qt
),
"Only struct and class are supported. ${full_name}"
,(
"full_name"
,
full_name
));
ABI_ASSERT
(
name
.
size
()
<=
sizeof
(
type_name
),
"Type name > ${maxsize}, ${name}"
,
...
...
@@ -400,58 +528,52 @@ string abi_generator::add_struct(const clang::QualType& qual_type) {
return
name
;
}
auto
bases
=
record_decl
->
bases
();
auto
total_bases
=
distance
(
bases
.
begin
(),
bases
.
end
());
if
(
total_bases
>
1
)
{
ABI_ASSERT
(
false
,
"Multiple inheritance not supported - ${type}"
,
(
"type"
,
full_name
));
}
auto
bases
=
get_struct_bases
(
qt
);
auto
bitr
=
bases
.
begin
();
int
total_bases
=
0
;
string
base_name
;
if
(
total_bases
==
1
)
{
auto
qt
=
bases
.
begin
()
->
getType
();
base_name
=
add_struct
(
qt
);
while
(
bitr
!=
bases
.
end
()
)
{
auto
base_qt
=
bitr
->
getType
();
const
auto
*
record_type
=
base_qt
->
getAs
<
clang
::
RecordType
>
();
if
(
record_type
&&
is_struct
(
base_qt
)
&&
!
record_type
->
getDecl
()
->
field_empty
()
)
{
ABI_ASSERT
(
total_bases
==
0
,
"Multiple inheritance not supported - ${type}"
,
(
"type"
,
full_name
));
base_name
=
add_type
(
base_qt
);
++
total_bases
;
}
++
bitr
;
}
struct_def
abi_struct
;
for
(
const
auto
&
field
:
record_decl
->
fields
())
{
field_def
struct_field
;
for
(
const
clang
::
FieldDecl
*
field
:
get_struct_fields
(
qt
)
)
{
clang
::
QualType
qt
=
field
->
getType
();
string
field_name
=
field
->
getNameAsString
();
string
field_type_name
=
add_type
(
qt
);
auto
field_type
=
translate_type
(
remove_namespace
(
get_name_to_add
(
qt
.
getUnqualifiedType
())));
ABI_ASSERT
(
field_type
.
size
()
<=
sizeof
(
decltype
(
struct_field
.
type
)),
"Type name > ${maxsize}, ${type}::${name}"
,
(
"type"
,
full_name
)(
"name"
,
field_type
)(
"maxsize"
,
sizeof
(
decltype
(
struct_field
.
type
))));
field_def
struct_field
{
field_name
,
field_type_name
};
ABI_ASSERT
(
is_builtin_type
(
get_vector_element_type
(
struct_field
.
type
))
||
find_struct
(
get_vector_element_type
(
struct_field
.
type
))
||
find_type
(
get_vector_element_type
(
struct_field
.
type
))
,
"Unknown type ${type} [${abi}]"
,(
"type"
,
struct_field
.
type
)(
"abi"
,
*
output
));
ABI_ASSERT
(
field
->
getNameAsString
().
size
()
<=
sizeof
(
decltype
(
struct_field
.
name
))
,
"Field name > ${maxsize}, ${type}::${name}"
,
(
"type"
,
full_name
)(
"name"
,
field
->
getNameAsString
())(
"maxsize"
,
sizeof
(
decltype
(
struct_field
.
name
))));
if
(
qt
->
getAs
<
clang
::
RecordType
>
()
)
{
add_struct
(
qt
);
//TODO: simplify if OPT_SINGLE_FIELD_STRUCT is enabled
}
struct_field
.
name
=
field
->
getNameAsString
();
struct_field
.
type
=
field_type
;
ABI_ASSERT
(
struct_field
.
type
.
size
()
<=
sizeof
(
decltype
(
struct_field
.
type
)),
"Type name > ${maxsize}, ${type}::${name}"
,
(
"type"
,
struct_field
.
type
)(
"name"
,
struct_field
.
name
)(
"maxsize"
,
sizeof
(
decltype
(
struct_field
.
type
))));
ABI_ASSERT
(
is_builtin_type
(
struct_field
.
type
)
||
find_struct
(
struct_field
.
type
),
"Unknown type ${type} ${name} ${ttt} ${sss}"
,
(
"type"
,
struct_field
.
type
)(
"name"
,
struct_field
.
name
)(
"types"
,
output
->
types
)(
"structs"
,
output
->
structs
));
ABI_ASSERT
(
field
->
getNameAsString
().
size
()
<=
sizeof
(
decltype
(
struct_field
.
name
))
,
"Field name > ${maxsize}, ${type}::${name}"
,
(
"type"
,
struct_field
.
type
)(
"name"
,
struct_field
.
name
)(
"maxsize"
,
sizeof
(
decltype
(
struct_field
.
type
))));
type_size
[
string
(
struct_field
.
type
)]
=
ctx
.
getTypeSize
(
qt
);
type_size
[
string
(
struct_field
.
type
)]
=
is_vector
(
struct_field
.
type
)
?
0
:
ast_context
->
getTypeSize
(
qt
);
abi_struct
.
fields
.
push_back
(
struct_field
);
}
abi_struct
.
name
=
resolve_type
(
name
);
abi_struct
.
base
=
remove_namespace
(
base_name
);
output
->
structs
.
push_back
(
abi_struct
);
if
(
verbose
)
{
cerr
<<
"Adding type "
<<
resolve_type
(
name
)
<<
" ("
<<
full_name
<<
")
\n
"
;
}
abi_struct
.
base
=
base_name
;
output
->
structs
.
push_back
(
abi_struct
);
full_types
[
name
]
=
full_name
;
return
full_
name
;
return
name
;
}
}
\ No newline at end of file
libraries/abi_generator/include/eosio/abi_generator/abi_generator.hpp
浏览文件 @
261edfd7
...
...
@@ -19,6 +19,7 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Core/QualTypeNames.h"
#include "llvm/Support/raw_ostream.h"
#include <boost/algorithm/string.hpp>
...
...
@@ -60,7 +61,7 @@ namespace eosio {
map
<
string
,
uint64_t
>
type_size
;
map
<
string
,
string
>
full_types
;
string
abi_context
;
clang
::
ASTContext
*
ast_context
;
public:
enum
optimization
{
...
...
@@ -70,7 +71,8 @@ namespace eosio {
abi_generator
()
:
optimizations
(
0
)
,
output
(
nullptr
)
,
compiler_instance
(
nullptr
)
,
compiler_instance
(
nullptr
)
,
ast_context
(
nullptr
)
{}
~
abi_generator
()
{}
...
...
@@ -161,11 +163,29 @@ namespace eosio {
string
decl_to_string
(
clang
::
Decl
*
d
);
void
add_typedef
(
const
clang
::
TypedefType
*
typeDef
);
bool
is_typedef
(
const
clang
::
QualType
&
qt
);
QualType
add_typedef
(
const
clang
::
QualType
&
qt
);
bool
is_vector
(
const
clang
::
QualType
&
qt
);
bool
is_vector
(
const
string
&
type_name
);
string
add_vector
(
const
clang
::
QualType
&
qt
);
bool
is_struct
(
const
clang
::
QualType
&
qt
);
string
add_struct
(
const
clang
::
QualType
&
qt
,
string
full_type_name
=
""
);
string
get_type_name
(
const
clang
::
QualType
&
qt
,
bool
no_namespace
);
string
add_type
(
const
clang
::
QualType
&
tqt
);
bool
is_elaborated
(
const
clang
::
QualType
&
qt
);
bool
is_struct_specialization
(
const
clang
::
QualType
&
qt
);
string
get_name_to_add
(
const
clang
::
QualType
&
qual_type
);
QualType
get_vector_element_type
(
const
clang
::
QualType
&
qt
);
string
get_vector_element_type
(
const
string
&
type_name
);
clang
::
QualType
get_named_type_if_elaborated
(
const
clang
::
QualType
&
qt
);
string
add_struct
(
const
clang
::
QualType
&
qual_type
);
const
clang
::
RecordDecl
::
field_range
get_struct_fields
(
const
clang
::
QualType
&
qt
);
clang
::
CXXRecordDecl
::
base_class_range
get_struct_bases
(
const
clang
::
QualType
&
qt
);
};
struct
abi_generator_astconsumer
:
public
ASTConsumer
{
...
...
programs/eosio-abigen/main.cpp
浏览文件 @
261edfd7
...
...
@@ -42,16 +42,14 @@ static cl::opt<bool> abi_opt_sfs(
cl
::
desc
(
"Optimize single field struct"
),
cl
::
cat
(
abi_generator_category
));
int
main
(
int
argc
,
const
char
**
argv
)
{
try
{
int
main
(
int
argc
,
const
char
**
argv
)
{
abi_def
output
;
try
{
CommonOptionsParser
op
(
argc
,
argv
,
abi_generator_category
);
ClangTool
Tool
(
op
.
getCompilations
(),
op
.
getSourcePathList
());
abi_def
abi
;
int
result
=
Tool
.
run
(
create_factory
(
abi_verbose
,
abi_opt_sfs
,
abi_context
,
abi
).
get
());
int
result
=
Tool
.
run
(
create_factory
(
abi_verbose
,
abi_opt_sfs
,
abi_context
,
output
).
get
());
if
(
!
result
)
{
abi_serializer
(
abi
).
validate
();
fc
::
json
::
save_to_file
<
abi_def
>
(
abi
,
abi_destination
,
true
);
abi_serializer
(
output
).
validate
();
fc
::
json
::
save_to_file
<
abi_def
>
(
output
,
abi_destination
,
true
);
}
return
result
;
}
FC_CAPTURE_AND_LOG
(());
return
-
1
;
}
}
FC_CAPTURE_AND_LOG
((
output
));
return
-
1
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录