Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <clang/Frontend/FrontendPluginRegistry.h>
- #include <clang/Frontend/CompilerInstance.h>
- #include <clang/AST/ASTConsumer.h>
- #include <clang/Sema/Sema.h>
- #include <stdio.h>
- #include <assert.h>
- #include <string>
- namespace {
- void cppvsprintf(std::string *out, const char *fmt, va_list va)
- {
- va_list va2;
- va_copy(va2, va);
- int len = vsnprintf(0, 0, fmt, va);
- size_t size = out->size();
- out->resize(size + len);
- vsnprintf(&(*out)[size], len+1, fmt, va2);
- va_end(va2);
- }
- void cppsprintf(std::string *out, const char *fmt, ...)
- {
- va_list va;
- va_start(va, fmt);
- cppvsprintf(out, fmt, va);
- va_end(va);
- }
- struct CToCrawlASTConsumer : clang::ASTConsumer {
- clang::ASTContext *ctx;
- std::string clang_type_to_crawl(const clang::Type *t)
- {
- std::string out;
- switch (t->getTypeClass()) {
- case clang::Type::Builtin:
- {
- const clang::BuiltinType *bt = cast<clang::BuiltinType>(t);
- if (bt->isInteger()) {
- if (bt->getKind() == clang::BuiltinType::Char_S ||
- bt->getKind() == clang::BuiltinType::Char_U)
- {
- out.append("uint8");
- return out;
- }
- if (bt->isUnsignedInteger())
- out.append("u");
- switch (ctx->getTypeSize(bt)) {
- case 8: out.append("int8"); break;
- case 16: out.append("int16"); break;
- case 32: out.append("int32"); break;
- case 64: out.append("int64"); break;
- default:
- assert(!"unsupported integer type");
- }
- return out;
- } else if (bt->isFloatingPoint()) {
- switch (ctx->getTypeSize(bt)) {
- case 32: out.append("float32"); break;
- case 64: out.append("float64"); break;
- default:
- assert(!"unsupported floating point type");
- }
- return out;
- } else if (bt->getKind() == clang::BuiltinType::Void) {
- out.append("void");
- return out;
- }
- break;
- }
- case clang::Type::Pointer:
- {
- const clang::PointerType *pt = cast<clang::PointerType>(t);
- out += "*";
- out += clang_type_to_crawl(pt->getPointeeType().getTypePtr());
- return out;
- }
- case clang::Type::Typedef:
- {
- const clang::TypedefType *tt = cast<clang::TypedefType>(t);
- return tt->getDecl()->getDeclName().getAsString();
- }
- case clang::Type::Record:
- {
- const clang::RecordType *rt = cast<clang::RecordType>(t);
- clang::RecordDecl *rd = rt->getDecl();
- if (!rd->getName().empty()) {
- out += rd->getNameAsString();
- return out;
- }
- out += "struct { ";
- clang::RecordDecl::field_iterator it, end;
- for (it = rd->field_begin(), end = rd->field_end(); it != end; ++it) {
- out += it->getNameAsString();
- out += " ";
- out += clang_type_to_crawl(it->getType().getTypePtr());
- out += "; ";
- }
- out += "}";
- return out;
- }
- case clang::Type::TypeOfExpr:
- {
- const clang::TypeOfExprType *tot = cast<clang::TypeOfExprType>(t);
- return clang_type_to_crawl(tot->getUnderlyingExpr()->getType().getTypePtr());
- }
- case clang::Type::ConstantArray:
- {
- const clang::ConstantArrayType *cat = cast<clang::ConstantArrayType>(t);
- cppsprintf(&out, "[%d]", cat->getSize().getZExtValue());
- out += clang_type_to_crawl(cat->getElementType().getTypePtr());
- return out;
- }
- default:
- break;
- }
- printf("!!!!!!!!!!!!%s\n", t->getTypeClassName());
- return "???";
- }
- void process_function_decl(clang::FunctionDecl *fd)
- {
- std::string out = "func ";
- out += fd->getDeclName().getAsString();
- out += "(";
- for (size_t i = 0, n = fd->getNumParams(); i < n; ++i) {
- clang::ParmVarDecl *arg = fd->getParamDecl(i);
- if (!arg->getName().empty()) {
- out += arg->getNameAsString();
- out += " ";
- }
- out += clang_type_to_crawl(arg->getType().getTypePtr());
- if (i != n-1)
- out += ", ";
- }
- if (fd->isVariadic())
- out += ", ...";
- out += ") ";
- out += clang_type_to_crawl(fd->getResultType().getTypePtr());
- printf("%s;\n", out.c_str());
- }
- void process_typedef_decl(clang::TypedefDecl *td)
- {
- std::string out = "type ";
- out += td->getDeclName().getAsString();
- out += " ";
- out += clang_type_to_crawl(td->getUnderlyingType().getTypePtr());
- printf("%s;\n", out.c_str());
- }
- void HandleTopLevelDecl(clang::DeclGroupRef d)
- {
- clang::DeclGroupRef::iterator it, end;
- for (it = d.begin(), end = d.end(); it != end; ++it) {
- switch ((*it)->getKind()) {
- case clang::Decl::Function:
- process_function_decl(cast<clang::FunctionDecl>(*it));
- break;
- case clang::Decl::Typedef:
- process_typedef_decl(cast<clang::TypedefDecl>(*it));
- break;
- default:
- break;
- }
- }
- }
- };
- struct CToCrawl : clang::PluginASTAction {
- clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef)
- {
- CToCrawlASTConsumer *consumer = new CToCrawlASTConsumer;
- consumer->ctx = &CI.getASTContext();
- return consumer;
- }
- bool ParseArgs(const clang::CompilerInstance &CI,
- const std::vector<std::string> &args)
- {
- return true;
- }
- void PrintHelp(llvm::raw_ostream &out)
- {
- out << "Help for CToCrawl goes here\n";
- }
- };
- } // anonymous namespace
- static clang::FrontendPluginRegistry::Add<CToCrawl>
- X("c-to-crawl", "convert C declarations to Crawl");
Add Comment
Please, Sign In to add comment