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 typedef std::map
<std::string
, std::string
> CYKeyMap
;
46 CXTranslationUnit unit
;
49 CYChildBaton(CXTranslationUnit unit
, CYKeyMap
&keys
) :
57 CXTranslationUnit unit
;
61 CYTokens(CXTranslationUnit unit
, CXCursor cursor
) :
64 CXSourceRange
range(clang_getCursorExtent(cursor
));
65 clang_tokenize(unit
, range
, &tokens
, &count
);
69 clang_disposeTokens(unit
, tokens
, count
);
72 operator CXToken
*() const {
77 static CXChildVisitResult
CYChildVisit(CXCursor cursor
, CXCursor parent
, CXClientData arg
) {
78 CYChildBaton
&baton(*static_cast<CYChildBaton
*>(arg
));
79 CXTranslationUnit
&unit(baton
.unit
);
81 CYCXString
spelling(clang_getCursorSpelling(cursor
));
82 std::string
name(spelling
);
83 std::ostringstream value
;
85 /*CXSourceLocation location(clang_getCursorLocation(cursor));
91 clang_getSpellingLocation(location, &file, &line, &column, &offset);
94 CYCXString path(clang_getFileName(file));
95 std::cout << spelling << " " << path << ":" << line << std::endl;
98 switch (clang_getCursorKind(cursor
)) {
99 case CXCursor_EnumConstantDecl
: {
100 value
<< clang_getEnumConstantDeclValue(cursor
);
103 case CXCursor_MacroDefinition
: {
104 CYTokens
tokens(unit
, cursor
);
105 if (tokens
.count
<= 2)
108 CXCursor cursors
[tokens
.count
];
109 clang_annotateTokens(unit
, tokens
, tokens
.count
, cursors
);
111 for (unsigned i(1); i
!= tokens
.count
- 1; ++i
) {
112 CYCXString
token(clang_getTokenSpelling(unit
, tokens
[i
]));
115 else if (strcmp(token
, "(") == 0)
121 case CXCursor_StructDecl
: {
122 if (!clang_isCursorDefinition(cursor
))
124 if (spelling
[0] == '\0')
131 clang_visitChildren(cursor
, &CYFieldVisit
, &baton
);
136 value
<< "new Type(" << baton
.types
.str() << "," << baton
.names
.str() << ")";
139 case CXCursor_TypedefDecl
: {
140 CXType
type(clang_getTypedefDeclUnderlyingType(cursor
));
141 value
<< "(typedef " << CYCXString(clang_getTypeSpelling(type
)) << ")";
144 case CXCursor_FunctionDecl
:
145 case CXCursor_VarDecl
: {
146 CXType
type(clang_getCursorType(cursor
));
147 value
<< "*(typedef " << CYCXString(clang_getTypeSpelling(type
)) << ").pointerTo()(dlsym(RTLD_DEFAULT,'" << spelling
<< "'))";
151 return CXChildVisit_Recurse
;
155 baton
.keys
[name
] = value
.str();
158 return CXChildVisit_Continue
;
161 int main(int argc
, const char *argv
[]) {
162 CXIndex
index(clang_createIndex(0, 0));
164 const char *file(argv
[1]);
168 argv
[--offset
] = "-ObjC++";
171 CXTranslationUnit
unit(clang_parseTranslationUnit(index
, file
, argv
+ offset
, argc
- offset
, NULL
, 0, CXTranslationUnit_DetailedPreprocessingRecord
| CXTranslationUnit_SkipFunctionBodies
));
173 for (unsigned i(0), e(clang_getNumDiagnostics(unit
)); i
!= e
; ++i
) {
174 CXDiagnostic
diagnostic(clang_getDiagnostic(unit
, i
));
175 CYCXString
spelling(clang_getDiagnosticSpelling(diagnostic
));
176 std::cerr
<< spelling
<< std::endl
;
180 CYChildBaton
baton(unit
, keys
);
181 clang_visitChildren(clang_getTranslationUnitCursor(unit
), &CYChildVisit
, &baton
);
183 for (CYKeyMap::const_iterator
key(keys
.begin()); key
!= keys
.end(); ++key
) {
184 std::string
value(key
->second
);
185 for (size_t i(0), e(value
.size()); i
!= e
; ++i
)
186 if (value
[i
] <= 0 || value
[i
] >= 0x7f || value
[i
] == '\n')
188 std::cout
<< key
->first
<< "|\"" << value
<< "\"" << std::endl
;
191 clang_disposeTranslationUnit(unit
);
192 clang_disposeIndex(index
);