7 #include <clang-c/Index.h>
12 CYCXString(CXString value
) :
18 clang_disposeString(value_
);
21 operator const char *() const {
22 return clang_getCString(value_
);
27 std::ostringstream types
;
28 std::ostringstream names
;
31 static CXChildVisitResult
CYFieldVisit(CXCursor cursor
, CXCursor parent
, CXClientData arg
) {
32 CYFieldBaton
&baton(*static_cast<CYFieldBaton
*>(arg
));
34 if (clang_getCursorKind(cursor
) == CXCursor_FieldDecl
) {
35 CXType
type(clang_getCursorType(cursor
));
36 baton
.types
<< "(typedef " << CYCXString(clang_getTypeSpelling(type
)) << "),";
37 baton
.names
<< "'" << CYCXString(clang_getCursorSpelling(cursor
)) << "',";
40 return CXChildVisit_Continue
;
43 struct CYAttributeBaton
{
47 static CXChildVisitResult
CYAttributeVisit(CXCursor cursor
, CXCursor parent
, CXClientData arg
) {
48 CYAttributeBaton
&baton(*static_cast<CYAttributeBaton
*>(arg
));
50 if (clang_getCursorKind(cursor
) == CXCursor_AsmLabelAttr
)
51 baton
.label
= CYCXString(clang_getCursorSpelling(cursor
));
53 return CXChildVisit_Continue
;
56 typedef std::map
<std::string
, std::string
> CYKeyMap
;
59 CXTranslationUnit unit
;
62 CYChildBaton(CXTranslationUnit unit
, CYKeyMap
&keys
) :
70 CXTranslationUnit unit
;
74 CYTokens(CXTranslationUnit unit
, CXCursor cursor
) :
77 CXSourceRange
range(clang_getCursorExtent(cursor
));
78 clang_tokenize(unit
, range
, &tokens
, &count
);
82 clang_disposeTokens(unit
, tokens
, count
);
85 operator CXToken
*() const {
90 static CXChildVisitResult
CYChildVisit(CXCursor cursor
, CXCursor parent
, CXClientData arg
) {
91 CYChildBaton
&baton(*static_cast<CYChildBaton
*>(arg
));
92 CXTranslationUnit
&unit(baton
.unit
);
94 CYCXString
spelling(clang_getCursorSpelling(cursor
));
95 std::string
name(spelling
);
96 std::ostringstream value
;
98 /*CXSourceLocation location(clang_getCursorLocation(cursor));
104 clang_getSpellingLocation(location, &file, &line, &column, &offset);
107 CYCXString path(clang_getFileName(file));
108 std::cout << spelling << " " << path << ":" << line << std::endl;
111 switch (clang_getCursorKind(cursor
)) {
112 case CXCursor_EnumConstantDecl
: {
113 value
<< clang_getEnumConstantDeclValue(cursor
);
116 case CXCursor_MacroDefinition
: {
117 CYTokens
tokens(unit
, cursor
);
118 if (tokens
.count
<= 2)
121 CXCursor cursors
[tokens
.count
];
122 clang_annotateTokens(unit
, tokens
, tokens
.count
, cursors
);
124 for (unsigned i(1); i
!= tokens
.count
- 1; ++i
) {
125 CYCXString
token(clang_getTokenSpelling(unit
, tokens
[i
]));
128 else if (strcmp(token
, "(") == 0)
134 case CXCursor_StructDecl
: {
135 if (!clang_isCursorDefinition(cursor
))
137 if (spelling
[0] == '\0')
144 clang_visitChildren(cursor
, &CYFieldVisit
, &baton
);
149 value
<< "new Type(" << baton
.types
.str() << "," << baton
.names
.str() << ")";
152 case CXCursor_TypedefDecl
: {
153 CXType
type(clang_getTypedefDeclUnderlyingType(cursor
));
154 value
<< "(typedef " << CYCXString(clang_getTypeSpelling(type
)) << ")";
157 case CXCursor_FunctionDecl
:
158 case CXCursor_VarDecl
: {
159 CYAttributeBaton baton
;
160 clang_visitChildren(cursor
, &CYAttributeVisit
, &baton
);
162 if (baton
.label
.empty()) {
163 baton
.label
= spelling
;
164 baton
.label
= '_' + baton
.label
;
165 } else if (baton
.label
[0] != '_')
168 CXType
type(clang_getCursorType(cursor
));
169 value
<< "*(typedef " << CYCXString(clang_getTypeSpelling(type
)) << ").pointerTo()(dlsym(RTLD_DEFAULT,'" << baton
.label
.substr(1) << "'))";
173 return CXChildVisit_Recurse
;
177 baton
.keys
[name
] = value
.str();
180 return CXChildVisit_Continue
;
183 int main(int argc
, const char *argv
[]) {
184 CXIndex
index(clang_createIndex(0, 0));
186 const char *file(argv
[1]);
190 argv
[--offset
] = "-ObjC++";
193 CXTranslationUnit
unit(clang_parseTranslationUnit(index
, file
, argv
+ offset
, argc
- offset
, NULL
, 0, CXTranslationUnit_DetailedPreprocessingRecord
| CXTranslationUnit_SkipFunctionBodies
));
195 for (unsigned i(0), e(clang_getNumDiagnostics(unit
)); i
!= e
; ++i
) {
196 CXDiagnostic
diagnostic(clang_getDiagnostic(unit
, i
));
197 CYCXString
spelling(clang_getDiagnosticSpelling(diagnostic
));
198 std::cerr
<< spelling
<< std::endl
;
202 CYChildBaton
baton(unit
, keys
);
203 clang_visitChildren(clang_getTranslationUnitCursor(unit
), &CYChildVisit
, &baton
);
205 for (CYKeyMap::const_iterator
key(keys
.begin()); key
!= keys
.end(); ++key
) {
206 std::string
value(key
->second
);
207 for (size_t i(0), e(value
.size()); i
!= e
; ++i
)
208 if (value
[i
] <= 0 || value
[i
] >= 0x7f || value
[i
] == '\n')
210 std::cout
<< key
->first
<< "|\"" << value
<< "\"" << std::endl
;
213 clang_disposeTranslationUnit(unit
);
214 clang_disposeIndex(index
);