Guest User

Untitled

a guest
Dec 11th, 2017
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.15 KB | None | 0 0
  1. #include <clang/Frontend/FrontendPluginRegistry.h>
  2. #include <clang/Frontend/CompilerInstance.h>
  3. #include <clang/AST/ASTConsumer.h>
  4. #include <clang/Sema/Sema.h>
  5.  
  6. #include <stdio.h>
  7. #include <assert.h>
  8. #include <string>
  9.  
  10. namespace {
  11.  
  12. void cppvsprintf(std::string *out, const char *fmt, va_list va)
  13. {
  14. va_list va2;
  15. va_copy(va2, va);
  16.  
  17. int len = vsnprintf(0, 0, fmt, va);
  18. size_t size = out->size();
  19. out->resize(size + len);
  20. vsnprintf(&(*out)[size], len+1, fmt, va2);
  21.  
  22. va_end(va2);
  23. }
  24.  
  25. void cppsprintf(std::string *out, const char *fmt, ...)
  26. {
  27. va_list va;
  28. va_start(va, fmt);
  29. cppvsprintf(out, fmt, va);
  30. va_end(va);
  31. }
  32.  
  33. struct CToCrawlASTConsumer : clang::ASTConsumer {
  34. clang::ASTContext *ctx;
  35.  
  36. std::string clang_type_to_crawl(const clang::Type *t)
  37. {
  38. std::string out;
  39.  
  40. switch (t->getTypeClass()) {
  41. case clang::Type::Builtin:
  42. {
  43. const clang::BuiltinType *bt = cast<clang::BuiltinType>(t);
  44. if (bt->isInteger()) {
  45. if (bt->getKind() == clang::BuiltinType::Char_S ||
  46. bt->getKind() == clang::BuiltinType::Char_U)
  47. {
  48. out.append("uint8");
  49. return out;
  50. }
  51.  
  52. if (bt->isUnsignedInteger())
  53. out.append("u");
  54. switch (ctx->getTypeSize(bt)) {
  55. case 8: out.append("int8"); break;
  56. case 16: out.append("int16"); break;
  57. case 32: out.append("int32"); break;
  58. case 64: out.append("int64"); break;
  59. default:
  60. assert(!"unsupported integer type");
  61. }
  62. return out;
  63. } else if (bt->isFloatingPoint()) {
  64. switch (ctx->getTypeSize(bt)) {
  65. case 32: out.append("float32"); break;
  66. case 64: out.append("float64"); break;
  67. default:
  68. assert(!"unsupported floating point type");
  69. }
  70. return out;
  71. } else if (bt->getKind() == clang::BuiltinType::Void) {
  72. out.append("void");
  73. return out;
  74. }
  75. break;
  76. }
  77. case clang::Type::Pointer:
  78. {
  79. const clang::PointerType *pt = cast<clang::PointerType>(t);
  80. out += "*";
  81. out += clang_type_to_crawl(pt->getPointeeType().getTypePtr());
  82. return out;
  83. }
  84. case clang::Type::Typedef:
  85. {
  86. const clang::TypedefType *tt = cast<clang::TypedefType>(t);
  87. return tt->getDecl()->getDeclName().getAsString();
  88. }
  89. case clang::Type::Record:
  90. {
  91. const clang::RecordType *rt = cast<clang::RecordType>(t);
  92. clang::RecordDecl *rd = rt->getDecl();
  93. if (!rd->getName().empty()) {
  94. out += rd->getNameAsString();
  95. return out;
  96. }
  97.  
  98. out += "struct { ";
  99. clang::RecordDecl::field_iterator it, end;
  100. for (it = rd->field_begin(), end = rd->field_end(); it != end; ++it) {
  101. out += it->getNameAsString();
  102. out += " ";
  103. out += clang_type_to_crawl(it->getType().getTypePtr());
  104. out += "; ";
  105. }
  106. out += "}";
  107. return out;
  108. }
  109. case clang::Type::TypeOfExpr:
  110. {
  111. const clang::TypeOfExprType *tot = cast<clang::TypeOfExprType>(t);
  112. return clang_type_to_crawl(tot->getUnderlyingExpr()->getType().getTypePtr());
  113. }
  114. case clang::Type::ConstantArray:
  115. {
  116. const clang::ConstantArrayType *cat = cast<clang::ConstantArrayType>(t);
  117. cppsprintf(&out, "[%d]", cat->getSize().getZExtValue());
  118. out += clang_type_to_crawl(cat->getElementType().getTypePtr());
  119. return out;
  120. }
  121. default:
  122. break;
  123. }
  124.  
  125. printf("!!!!!!!!!!!!%s\n", t->getTypeClassName());
  126. return "???";
  127. }
  128.  
  129. void process_function_decl(clang::FunctionDecl *fd)
  130. {
  131. std::string out = "func ";
  132. out += fd->getDeclName().getAsString();
  133. out += "(";
  134. for (size_t i = 0, n = fd->getNumParams(); i < n; ++i) {
  135. clang::ParmVarDecl *arg = fd->getParamDecl(i);
  136. if (!arg->getName().empty()) {
  137. out += arg->getNameAsString();
  138. out += " ";
  139. }
  140. out += clang_type_to_crawl(arg->getType().getTypePtr());
  141. if (i != n-1)
  142. out += ", ";
  143. }
  144. if (fd->isVariadic())
  145. out += ", ...";
  146. out += ") ";
  147. out += clang_type_to_crawl(fd->getResultType().getTypePtr());
  148. printf("%s;\n", out.c_str());
  149. }
  150.  
  151. void process_typedef_decl(clang::TypedefDecl *td)
  152. {
  153. std::string out = "type ";
  154. out += td->getDeclName().getAsString();
  155. out += " ";
  156. out += clang_type_to_crawl(td->getUnderlyingType().getTypePtr());
  157. printf("%s;\n", out.c_str());
  158. }
  159.  
  160. void HandleTopLevelDecl(clang::DeclGroupRef d)
  161. {
  162. clang::DeclGroupRef::iterator it, end;
  163. for (it = d.begin(), end = d.end(); it != end; ++it) {
  164. switch ((*it)->getKind()) {
  165. case clang::Decl::Function:
  166. process_function_decl(cast<clang::FunctionDecl>(*it));
  167. break;
  168. case clang::Decl::Typedef:
  169. process_typedef_decl(cast<clang::TypedefDecl>(*it));
  170. break;
  171. default:
  172. break;
  173. }
  174.  
  175. }
  176. }
  177. };
  178.  
  179. struct CToCrawl : clang::PluginASTAction {
  180. clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef)
  181. {
  182. CToCrawlASTConsumer *consumer = new CToCrawlASTConsumer;
  183. consumer->ctx = &CI.getASTContext();
  184. return consumer;
  185. }
  186.  
  187. bool ParseArgs(const clang::CompilerInstance &CI,
  188. const std::vector<std::string> &args)
  189. {
  190. return true;
  191. }
  192.  
  193. void PrintHelp(llvm::raw_ostream &out)
  194. {
  195. out << "Help for CToCrawl goes here\n";
  196. }
  197. };
  198.  
  199. } // anonymous namespace
  200.  
  201. static clang::FrontendPluginRegistry::Add<CToCrawl>
  202. X("c-to-crawl", "convert C declarations to Crawl");
Add Comment
Please, Sign In to add comment