Synopsis - Cross-Reference
File: src/Synopsis/SymbolLookup/Walker.cc1// 2// Copyright (C) 2004 Stefan Seefeld 3// All rights reserved. 4// Licensed to the public under the terms of the GNU LGPL (>= 2), 5// see the file COPYING for details. 6// 7#include <Synopsis/SymbolLookup/Walker.hh> 8#include <Synopsis/PTree/Lists.hh> 9#include <Synopsis/PTree/TypeVisitor.hh> 10#include <Synopsis/Trace.hh> 11#include <Synopsis/PTree/Display.hh> 12#include <Synopsis/SymbolLookup/Scopes.hh> 13 14using namespace Synopsis; 15using namespace SymbolLookup; 16 17Walker::Walker(Scope *scope) 18{ 19 Trace trace("Walker::Walker", Trace::SYMBOLLOOKUP); 20 my_scopes.push(scope->ref()); 21} 22 23Walker::~Walker() 24{ 25 Trace trace("Walker::~Walker", Trace::SYMBOLLOOKUP); 26 Scope *scope = my_scopes.top(); 27 scope->unref(); 28 my_scopes.pop(); 29} 30 31void Walker::visit(PTree::List *node) 32{ 33 Trace trace("Walker::visit(List)", Trace::SYMBOLLOOKUP); 34 if (node->car()) node->car()->accept(this); 35 if (node->cdr()) node->cdr()->accept(this); 36} 37 38void Walker::visit(PTree::Block *node) 39{ 40 Trace trace("Walker::visit(Block)", Trace::SYMBOLLOOKUP); 41 Scope *scope = my_scopes.top()->find_scope(node); 42 if (!scope) 43 { 44 // Not all Blocks represent a scope... 45 visit_block(node); 46 } 47 else 48 { 49 scope->ref(); 50 my_scopes.push(scope); 51 visit_block(node); 52 leave_scope(); 53 } 54} 55 56void Walker::visit(PTree::TemplateDecl *tdecl) 57{ 58 Trace trace("Walker::visit(TemplateDecl)", Trace::SYMBOLLOOKUP); 59 traverse_parameters(tdecl); 60 // If we are in a template template parameter, the following 61 // is just the 'class' keyword. 62 // Else it is a Declaration, which we want to traverse. 63 PTree::Node *decl = PTree::nth(tdecl, 4); 64 if (!decl->is_atom()) decl->accept(this); 65 else 66 { 67 std::cout << "length " << PTree::length(tdecl) << std::endl; 68 } 69} 70 71void Walker::visit(PTree::NamespaceSpec *spec) 72{ 73 Trace trace("Walker::visit(NamespaceSpec)", Trace::SYMBOLLOOKUP); 74 traverse_body(spec); 75} 76 77void Walker::visit(PTree::FunctionDefinition *def) 78{ 79 Trace trace("Walker::visit(FunctionDefinition)", Trace::SYMBOLLOOKUP); 80 PTree::Node *decl = PTree::third(def); 81 visit(static_cast<PTree::Declarator *>(decl)); // visit the declarator 82 traverse_body(def); 83} 84 85void Walker::visit(PTree::ClassSpec *spec) 86{ 87 Trace trace("Walker::visit(ClassSpec)", Trace::SYMBOLLOOKUP); 88 traverse_body(spec); 89} 90 91void Walker::visit(PTree::DotMemberExpr *) 92{ 93 Trace trace("Walker::visit(DotMemberExpr)", Trace::SYMBOLLOOKUP); 94 std::cout << "Sorry: dot member expression (<postfix>.<name>) not yet supported" << std::endl; 95} 96 97void Walker::visit(PTree::ArrowMemberExpr *) 98{ 99 Trace trace("Walker::visit(ArrowMemberExpr)", Trace::SYMBOLLOOKUP); 100 std::cout << "Sorry: arrow member expression (<postfix>-><name>) not yet supported" << std::endl; 101} 102 103void Walker::traverse_body(PTree::NamespaceSpec *spec) 104{ 105 Trace trace("Walker::traverse_body(NamespaceSpec)", Trace::SYMBOLLOOKUP); 106 Scope *scope = my_scopes.top()->find_scope(spec); 107 assert(scope); 108 scope->ref(); 109 my_scopes.push(scope); 110 PTree::tail(spec, 2)->car()->accept(this); 111 leave_scope(); 112} 113 114void Walker::traverse_body(PTree::ClassSpec *spec) 115{ 116 Trace trace("Walker::traverse_body(ClassSpec)", Trace::SYMBOLLOOKUP); 117 if (PTree::ClassBody *body = spec->body()) 118 { 119 Scope *scope = my_scopes.top()->find_scope(spec); 120 assert(scope); 121 scope->ref(); 122 my_scopes.push(scope); 123 body->accept(this); 124 leave_scope(); 125 } 126} 127 128void Walker::traverse_parameters(PTree::TemplateDecl *decl) 129{ 130 Trace trace("Walker::traverse_body(TemplateDecl)", Trace::SYMBOLLOOKUP); 131 Scope *scope = my_scopes.top()->find_scope(decl); 132 scope->ref(); 133 my_scopes.push(scope); 134 // list of template parameters (TypeParameter or ParameterDeclaration) 135 PTree::third(decl)->accept(this); 136 leave_scope(); 137} 138 139void Walker::traverse_body(PTree::FunctionDefinition *def) 140{ 141 Trace trace("Walker::traverse_body(FunctionDefinition)", Trace::SYMBOLLOOKUP); 142 PTree::Node *decl = PTree::third(def); 143 144 Scope *scope = my_scopes.top(); 145 PTree::Encoding name = decl->encoded_name(); 146 if (name.is_qualified()) 147 { 148 SymbolSet symbols = scope->lookup(name, Scope::DECLARATION); 149 assert(!symbols.empty()); 150 // FIXME: We need type analysis / overload resolution 151 // here to take the right symbol / scope. 152 FunctionName const *symbol = dynamic_cast<FunctionName const *>(*symbols.begin()); 153 assert(symbol); 154 scope = symbol->as_scope(); 155 } 156 else 157 scope = my_scopes.top()->find_scope(def); 158 assert(scope); 159 scope->ref(); 160 my_scopes.push(scope); 161 visit_block(static_cast<PTree::Block *>(PTree::nth(def, 3))); 162 leave_scope(); 163} 164 165void Walker::visit_block(PTree::Block *node) 166{ 167 Trace trace("Walker::visit_block(Block)", Trace::SYMBOLLOOKUP); 168 visit(static_cast<PTree::List *>(node)); 169} 170 171void Walker::leave_scope() 172{ 173 Trace trace("Walker::leave_scope", Trace::SYMBOLLOOKUP); 174 Scope *top = my_scopes.top(); 175 my_scopes.pop(); 176 top->unref(); 177}
Generated on Tue May 13 02:39:15 2008 by
synopsis (version 0.10)
synopsis (version 0.10)