}
};
+static CYUTF8String CYCXPoolUTF8Range(CYPool &pool, CXSourceRange range) {
+ CYCXPosition<> start(clang_getRangeStart(range));
+ CYCXPosition<> end(clang_getRangeEnd(range));
+ CYCXString file(start.file_);
+ _assert(file == CYCXString(end.file_));
+
+ CYPool temp;
+ size_t size;
+ char *data(static_cast<char *>(CYPoolFile(temp, file, &size)));
+ _assert(start.offset_ <= size && end.offset_ <= size && start.offset_ <= end.offset_);
+
+ CYUTF8String code;
+ code.size = end.offset_ - start.offset_;
+ code.data = pool.strndup(data + start.offset_, code.size);
+ return code;
+}
+
static CYExpression *CYTranslateExpression(CXTranslationUnit unit, CXCursor cursor) {
switch (CXCursorKind kind = clang_getCursorKind(cursor)) {
case CXCursor_CallExpr: {
// the tokenizer freaks out and either fails with 0 tokens
// or returns some massive number of tokens ending here :/
- CXSourceRange range(clang_getCursorExtent(cursor));
- CYCXPosition<> start(clang_getRangeStart(range));
- CYCXPosition<> end(clang_getRangeEnd(range));
- CYCXString file(start.file_);
- _assert(file == CYCXString(end.file_));
-
- CYPool pool;
- size_t size;
- char *data(static_cast<char *>(CYPoolFile(pool, file, &size)));
- _assert(start.offset_ <= size && end.offset_ <= size && start.offset_ <= end.offset_);
-
- const char *token($pool.strndup(data + start.offset_, end.offset_ - start.offset_));
+ CYUTF8String token(CYCXPoolUTF8Range($pool, clang_getCursorExtent(cursor)));
double value(CYCastDouble(token));
- if (!std::isnan(value))
- return $ CYNumber(value);
-
- return $V(token);
+ if (std::isnan(value))
+ return $V(token.data);
+ return $ CYNumber(value);
} break;
case CXCursor_CStyleCastExpr:
CXCursor cursors[tokens.size()];
clang_annotateTokens(unit, tokens, tokens.size(), cursors);
- CYCXPosition<> start(clang_getRangeStart(range));
- CYCXString first(unit, tokens[1]);
- if (first == "(") {
- CYCXPosition<> paren(unit, tokens[1]);
- if (start.offset_ + strlen(spelling) == paren.offset_)
- _assert(false); // XXX: support parameterized macros
+ CYLocalPool local;
+ CYList<CYFunctionParameter> parameters;
+ unsigned offset(1);
+
+ if (tokens.size() != 1) {
+ CYCXPosition<> start(clang_getRangeStart(range));
+ CYCXString first(unit, tokens[offset]);
+ if (first == "(") {
+ CYCXPosition<> paren(unit, tokens[offset]);
+ if (start.offset_ + strlen(spelling) == paren.offset_) {
+ for (;;) {
+ _assert(++offset != tokens.size());
+ CYCXString token(unit, tokens[offset]);
+ parameters->*$P($B($I(token.Pool($pool))));
+ _assert(++offset != tokens.size());
+ CYCXString comma(unit, tokens[offset]);
+ if (comma == ")")
+ break;
+ _assert(comma == ",");
+ }
+ ++offset;
+ }
+ }
}
- for (unsigned i(1); i != tokens.size(); ++i) {
+ std::ostringstream body;
+ for (unsigned i(offset); i != tokens.size(); ++i) {
CYCXString token(unit, tokens[i]);
- if (i != 1)
- value << " ";
- value << token;
+ if (i != offset)
+ body << " ";
+ body << token;
+ }
+
+ if (!parameters)
+ value << body.str();
+ else {
+ CYOptions options;
+ CYOutput out(*value.rdbuf(), options);
+ out << '(' << "function" << '(';
+ out << parameters;
+ out << ')' << '{';
+ out << "return" << ' ';
+ value << body.str();
+ out << ';' << '}' << ')';
}
} catch (const CYException &error) {
CYPool pool;