Synopsis - Cross-Reference
File: /tests/Cxx/src/TypeAnalysis.cc1#include <Synopsis/Trace.hh> 2#include <Synopsis/Buffer.hh> 3#include <Synopsis/Lexer.hh> 4#include <Synopsis/Parser.hh> 5#include <Synopsis/PTree.hh> 6#include <Synopsis/PTree/Display.hh> 7#include <Synopsis/PTree/Writer.hh> 8#include <Synopsis/SymbolLookup.hh> 9#include <Synopsis/TypeAnalysis.hh> 10#include <iostream> 11#include <iomanip> 12#include <fstream> 13 14using namespace Synopsis; 15 16//. Evaluating types of expressions may involve 17//. overload resolution, if the types of the subexpressions 18//. are user defined (enums, classes). 19//. As this is a unit test for type evaluation, not overload 20//. resolution, we restrict ourselfs to builtin types. 21//. 22//. Test input should be a set of declarations where 23//. the initializers are expressions which we look up 24//. the type for. 25class InitializerFinder : private SymbolLookup::Walker 26{ 27public: 28 InitializerFinder(SymbolLookup::Scope *scope, std::ostream &os) 29 : SymbolLookup::Walker(scope), my_os(os) {} 30 void find(PTree::Node *node) { node->accept(this);} 31 32private: 33 virtual void visit(PTree::Declaration *node) 34 { 35 PTree::Node *type = PTree::second(node); 36 type->accept(this); 37 PTree::Node *rest = PTree::third(node); 38 if (rest->is_atom()) return; // ';' 39 for (; rest; rest = rest->cdr()) 40 { 41 PTree::Node *p = rest->car(); 42 p->accept(this); 43 } 44 } 45 virtual void visit(PTree::Declarator *decl) 46 { 47 size_t length = PTree::length(decl); 48 if (length >= 2 && *PTree::nth(decl, length - 2) == '=') 49 { 50 PTree::Node *init = PTree::tail(decl, length - 1)->car(); 51 // do the type evaluation here... 52 std::cout << "Expression : " << PTree::reify(init) << std::endl; 53 TypeAnalysis::Type const *type = TypeAnalysis::type_of(init, current_scope()); 54// std::cout << "Type : " << type << std::endl; 55// std::cout << "Type : " << type.is_const() << std::endl; 56// std::cout << "Type : " << type.is_builtin_type() << std::endl; 57// std::cout << "Type : " << type << std::endl; 58 } 59 } 60 61 std::ostream &my_os; 62}; 63 64int main(int argc, char **argv) 65{ 66 if (argc < 3) 67 { 68 std::cerr << "Usage: " << argv[0] << " [-d] <output> <input>" << std::endl; 69 exit(-1); 70 } 71 try 72 { 73 std::string output; 74 std::string input; 75 if (argv[1] == std::string("-d")) 76 { 77 Trace::enable(Trace::ALL); 78 output = argv[2]; 79 input = argv[3]; 80 } 81 else 82 { 83 output = argv[1]; 84 input = argv[2]; 85 } 86 std::ofstream ofs(output.c_str()); 87 std::ifstream ifs(input.c_str()); 88 Buffer buffer(ifs.rdbuf(), input); 89 Lexer lexer(&buffer); 90 SymbolFactory symbols; 91 Parser parser(lexer, symbols); 92 PTree::Node *node = parser.parse(); 93 InitializerFinder finder(symbols.current_scope(), ofs); 94 finder.find(node); 95 } 96 catch (std::exception const &e) 97 { 98 std::cerr << "Caught exception : " << e.what() << std::endl; 99 } 100}