src/compiler/NameBinding.cpp
author David Anderson <dvander@alliedmods.net>
Wed Dec 26 17:14:12 2012 -0800 (2012-12-26)
changeset 241 18f3010a358c
parent 237 c77540a61905
child 242 b7d14a8b918e
permissions -rw-r--r--
Implement |const| keyword.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include "../Strings.h"
    20 #include "../Zone.h"
    21 #include "../TypeManager.h"
    22 #include "NameBinding.h"
    23 #include "Scopes.h"
    24 #include "ConstantEvaluator.h"
    25 #include "../Spaces-inl.h"
    26 #include "../Heap-inl.h"
    27 
    28 using namespace ke;
    29 
    30 // Create symbol tables and symbols for every scope and declaration. For type
    31 // declarations and methods, we also pre-allocate a Type object, so that
    32 // circular dependencies between types will work.
    33 class NamePopulator : public AstVisitor
    34 {
    35   private:
    36     // This class is analagous to a Scope, however, it allows us to create
    37     // scopes lazily. If a scope is requested, and the current environment
    38     // has no scope, then a scope is created. If no scope is ever requested,
    39     // a scope does not need to be created.
    40     class SymbolEnv
    41     {
    42       public:
    43         SymbolEnv(SymbolEnv **prevp, Scope *scope = NULL)
    44           : envp_(prevp),
    45             prev_(*prevp),
    46             scope_(scope)
    47         {
    48             *envp_ = this;
    49         }
    50         ~SymbolEnv() {
    51             *envp_ = prev_;
    52         }
    53 
    54         Scope *scope() {
    55             return scope_;
    56         }
    57         void setScope(Scope *scope) {
    58             assert(!scope_);
    59             scope_ = scope;
    60         }
    61         SymbolEnv *prev() const {
    62             return prev_;
    63         }
    64 
    65       private:
    66         SymbolEnv **envp_;
    67         SymbolEnv *prev_;
    68         Scope *scope_;
    69     };
    70 
    71     enum ReturnStatus {
    72         NoReturn,
    73         VoidReturn,
    74         ValueReturn
    75     };
    76 
    77     class FunctionScope
    78     {
    79       public:
    80         FunctionScope(FunctionScope **prevp)
    81           : prevp_(prevp),
    82             prev_(*prevp),
    83             status_(NoReturn)
    84         {
    85             *prevp_ = this;
    86         }
    87         ~FunctionScope() {
    88             *prevp_ = prev_;
    89         }
    90         ReturnStatus returns() const {
    91             return status_;
    92         }
    93         void returns(ReturnStatus status) {
    94             if (status > status_)
    95                 status_ = status;
    96         }
    97       private:
    98         FunctionScope **prevp_;
    99         FunctionScope *prev_;
   100         ReturnStatus status_;
   101     };
   102 
   103   public:
   104     NamePopulator(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   105       : zone_(zone),
   106         pool_(zone->pool()),
   107         cc_(cc),
   108         unit_(unit),
   109         env_(NULL),
   110         fun_(NULL)
   111     {
   112     }
   113 
   114     bool analyze() {
   115         ImportScope *importScope = ImportScope::New(pool_);
   116         if (!importScope)
   117             return false;
   118 
   119         // At the import level, we declare system types.
   120         if (!declareSystemTypes(importScope))
   121             return false;
   122 
   123         GlobalScope *globalScope = GlobalScope::New(pool_, importScope);
   124         if (!globalScope)
   125             return false;
   126 
   127         unit_->setImportScope(importScope);
   128         unit_->setGlobalScope(globalScope);
   129 
   130         SymbolEnv env(&env_, globalScope);
   131 
   132         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   133             Statement *stmt = unit_->tree()->statements()->at(i);
   134             stmt->accept(this);
   135         }
   136 
   137         return true;
   138     }
   139 
   140     bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> type) {
   141         Local<String> tag(zone_, zone_->makeSymbol(name));
   142         if (!tag)
   143             return false;
   144 
   145         TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type);
   146         return scope->addSymbol(sym);
   147     }
   148 
   149     bool declareSystemType(ImportScope *scope, const char *name, PrimitiveType prim) {
   150         Local<Type> primitive(zone_, zone_->types()->getPrimitive(prim));
   151         assert(primitive);
   152         return declareSystemType(scope, name, primitive);
   153     }
   154 
   155     bool declareSystemTypes(ImportScope *scope) {
   156         if (!declareSystemType(scope, "float", PrimitiveType_Float))
   157             return false;
   158         if (!declareSystemType(scope, "_", PrimitiveType_Int32))
   159             return false;
   160         if (!declareSystemType(scope, "int", PrimitiveType_Int32))
   161             return false;
   162         if (!declareSystemType(scope, "bool", PrimitiveType_Bool))
   163             return false;
   164         if (!declareSystemType(scope, "char", PrimitiveType_Char))
   165             return false;
   166 
   167         Local<Type> voidType(zone_, zone_->types()->getVoid());
   168         if (!declareSystemType(scope, "void", voidType))
   169             return false;
   170 
   171         return true;
   172     }
   173 
   174     void visitVariableDeclaration(VariableDeclaration *node) {
   175         Scope *scope = env_->scope();
   176         if (!scope || scope->kind() != Scope::GLOBAL) {
   177             if ((scope = getOrCreateBlockScope()) == NULL)
   178                 return;
   179         }
   180 
   181         if (scope->kind() == Scope::GLOBAL) {
   182             // The symbol must be added now, since it could be an export.
   183             VariableSymbol *sym = new (pool_) VariableSymbol(scope, node->name(), node->pos());
   184             node->setSymbol(sym);
   185 
   186             if (!registerName(scope, sym))
   187                 return;
   188         } else {
   189             // We ensure the scope will exist at the name binding phase, but
   190             // we don't actually register the variable symbol yet. Otherwise,
   191             // when binding the initializer, we could encounter:
   192             //    new x = x;
   193             //
   194             // And we don't necessarily want this to bind.
   195         }
   196 
   197         if (node->initialization())
   198             node->initialization()->accept(this);
   199     }
   200     void visitEnumStatement(EnumStatement *node) {
   201         Local<String> name(zone_, node->name());
   202         Local<Type> type(zone_);
   203         if (name)
   204             type = zone_->types()->newEnum(name);
   205         else
   206             type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   207 
   208         if (!type)
   209             return;
   210 
   211         Scope *scope = getGlobalOrCreateBlockScope();
   212         if (!scope)
   213             return;
   214 
   215         if (name) {
   216             TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, type);
   217             if (!registerName(scope, sym))
   218                 return;
   219         }
   220 
   221         int value = 0;
   222         for (size_t i = 0; i < node->entries()->length(); i++) {
   223             EnumStatement::Entry &entry = node->entries()->at(i);
   224             BoxedPrimitive box = BoxedPrimitive::Int(value);
   225             if (entry.expr) {
   226                 if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
   227                     cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
   228                     return;
   229                 }
   230 
   231                 assert(box.type() == PrimitiveType_Int32);
   232                 value = box.toInt();
   233             }
   234             
   235             ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
   236             if (!registerName(scope, sym))
   237                 return;
   238 
   239             value++;
   240         }
   241     }
   242     void visitFunctionStatement(FunctionStatement *node) {
   243         // We create function types ahead of time, not for any particular
   244         // reason. It makes things consistent with FunctionTypeStatement,
   245         // which actually does produce a type.
   246         Local<FunctionType> type(zone_, FunctionType::New(zone_, node->name(), node->token()));
   247         if (!type)
   248             return;
   249 
   250         assert(env_->scope());
   251 
   252         // Function statements are always named, so add the name to the outer scope.
   253         FunctionSymbol *sym = new (pool_) FunctionSymbol(env_->scope(), node->name(), node->pos(), type);
   254         if (!registerName(env_->scope(), sym))
   255             return;
   256 
   257         if (node->token() == TOK_PUBLIC ||
   258             node->token() == TOK_FORWARD ||
   259             node->token() == TOK_NATIVE)
   260         {
   261             // We're in the global scope, for sure.
   262             assert(env_->scope()->kind() == Scope::GLOBAL);
   263             GlobalScope *globals = (GlobalScope *)env_->scope();
   264             if (!globals->addPublic(sym))
   265                 return;
   266         }
   267 
   268         node->setSymbol(sym);
   269 
   270         // Scope for the function's arguments.
   271         SymbolEnv argEnv(&env_);
   272         if (!registerArguments(node->signature()))
   273             return;
   274 
   275         // Scope for function body.
   276         SymbolEnv localEnv(&env_);
   277         FunctionScope fun(&fun_);
   278         if (node->body())
   279             node->body()->accept(this);
   280 
   281         // Function statements have quirky semantics around their return
   282         // type. For reasonable compatibility with SP1, we use the following
   283         // heuristics for when no explicit type is declared.
   284         if (!node->signature().returnType()) {
   285             Local<Type> type(zone_);
   286             if (node->token() == TOK_FORWARD || node->token() == TOK_NATIVE) {
   287                 // If the function type is a native or forward, we always
   288                 // assume it returns an int32.
   289                 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   290             } else if (fun.returns() != ValueReturn) {
   291                 // This function never returns a value, so mark it as
   292                 // returning void.
   293                 type = zone_->types()->getVoid();
   294             }
   295             // No need to NULL check here, we'll catch OOM later.
   296             node->sym()->type()->setReturnType(type);
   297         }
   298 
   299         node->setScopes(argEnv.scope(), localEnv.scope());
   300     }
   301     void visitStructureStatement(StructureStatement *node) {
   302         assert(false);
   303     }
   304     void visiFunctionTypeStatementt(FunctionTypeStatement *node) {
   305         assert(false);
   306     }
   307 
   308     void visitNameProxy(NameProxy *name) {
   309     }
   310     void visitAssignment(Assignment *node) {
   311         node->lvalue()->accept(this);
   312         node->expression()->accept(this);
   313     }
   314     void visitBinaryExpression(BinaryExpression *node) {
   315         node->left()->accept(this);
   316         node->right()->accept(this);
   317     }
   318     void visitReturnStatement(ReturnStatement *node) {
   319         if (node->expression())
   320             fun_->returns(ValueReturn);
   321         else
   322             fun_->returns(VoidReturn);
   323     }
   324     void visitForStatement(ForStatement *node) {
   325         SymbolEnv env(&env_);
   326 
   327         if (node->initialization())
   328             node->initialization()->accept(this);
   329         if (node->condition())
   330             node->condition()->accept(this);
   331         if (node->update())
   332             node->update()->accept(this);
   333         node->body()->accept(this);
   334 
   335         node->setScope(env.scope());
   336     }
   337     void visitBlockStatement(BlockStatement *node) {
   338         SymbolEnv env(&env_);
   339 
   340         for (size_t i = 0; i < node->statements()->length(); i++)
   341             node->statements()->at(i)->accept(this);
   342 
   343         node->setScope(env.scope());
   344     }
   345     void visitIntegerLiteral(IntegerLiteral *node) {
   346     }
   347     void visitExpressionStatement(ExpressionStatement *node) {
   348         node->expression()->accept(this);
   349     }
   350     void visitCallExpression(CallExpression *node) {
   351         node->callee()->accept(this);
   352         for (size_t i = 0; i < node->arguments()->length(); i++)
   353             node->arguments()->at(i)->accept(this);
   354     }
   355     void visitIfStatement(IfStatement *node) {
   356         node->ifTrue()->accept(this);
   357         if (node->ifFalse())
   358             node->ifFalse()->accept(this);
   359     }
   360     void visitIndexExpression(IndexExpression *node) {
   361         node->left()->accept(this);
   362         node->right()->accept(this);
   363     }
   364     void visitFloatLiteral(FloatLiteral *node) {
   365     }
   366     void visitWhileStatement(WhileStatement *node) {
   367         node->condition()->accept(this);
   368         node->body()->accept(this);
   369     }
   370     void visitBreakStatement(BreakStatement *node) {
   371     }
   372     void visitContinueStatement(ContinueStatement *node) {
   373     }
   374     void visitStringLiteral(StringLiteral *node) {
   375     }
   376     void visitIncDecExpression(IncDecExpression *node) {
   377         node->expression()->accept(this);
   378     }
   379     void visitUnaryExpression(UnaryExpression *node) {
   380         assert(false);
   381     }
   382     void visitTernaryExpression(TernaryExpression *node) {
   383         assert(false);
   384     }
   385     void visitBooleanLiteral(BooleanLiteral *node) {
   386     }
   387     void visitFieldExpression(FieldExpression *node) {
   388     }
   389     void visitSwitchStatement(SwitchStatement *node) {
   390         if (node->defaultCase())
   391             node->defaultCase()->accept(this);
   392 
   393         for (size_t i = 0; i < node->cases()->length(); i++)
   394             node->cases()->at(i)->statement()->accept(this);
   395     }
   396     void visitArrayLiteral(ArrayLiteral *node) {
   397     }
   398     void visitImportStatement(ImportStatement *node) {
   399     }
   400 
   401   private:
   402     Scope *getGlobalOrCreateBlockScope() {
   403         if (env_->scope()) {
   404             assert(env_->scope()->kind() == Scope::BLOCK ||
   405                    env_->scope()->kind() == Scope::GLOBAL);
   406             return env_->scope();
   407         }
   408         return getOrCreateBlockScope();
   409     }
   410     Scope *getOrCreateBlockScope() {
   411         if (env_->scope()) {
   412             assert(env_->scope()->kind() == Scope::BLOCK);
   413             return env_->scope();
   414         }
   415         
   416         LocalScope *scope = LocalScope::New(pool_);
   417         if (!scope)
   418             return NULL;
   419 
   420         env_->setScope(scope);
   421         return scope;
   422     }
   423 
   424     bool registerName(Scope *scope, Symbol *sym) {
   425         if (!scope)
   426             return false;
   427 
   428         if (Symbol *other = scope->localLookup(sym->name())) {
   429             // Report, but allow errors to continue.
   430             cc_.reportError(sym->pos(), Message_RedeclaredName,
   431                             sym->name()->chars(),
   432                             other->pos().line,
   433                             other->pos().col);
   434             return true;
   435         }
   436 
   437         return scope->addSymbol(sym);
   438     }
   439 
   440     bool registerArguments(const FunctionSignature &sig) {
   441         if (!sig.parameters()->length())
   442             return true;
   443 
   444         ArgumentScope *argScope = ArgumentScope::New(pool_);
   445         if (!argScope)
   446             return false;
   447         env_->setScope(argScope);
   448 
   449         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   450             Parameter *param = sig.parameters()->at(i);
   451             VariableSymbol *sym = new (pool_) VariableSymbol(argScope, param->name(), param->pos());
   452             if (!registerName(env_->scope(), sym))
   453                 return false;
   454             param->setSymbol(sym);
   455         }
   456 
   457         return true;
   458     }
   459 
   460   private:
   461     Zone *zone_;
   462     PoolAllocator &pool_;
   463     CompileContext &cc_;
   464     TranslationUnit *unit_;
   465     SymbolEnv *env_;
   466     FunctionScope *fun_;
   467 };
   468 
   469 bool
   470 ke::PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   471 {
   472     NamePopulator populator(zone, cc, unit);
   473     return populator.analyze();
   474 }
   475 
   476 static const int INFER_ARRAY_SIZE = 0;
   477 static const int EVAL_ARRAY_SIZE = -1;
   478 static const int DYNAMIC_ARRAY_SIZE = -2;
   479 
   480 class NameBinder : public AstVisitor
   481 {
   482   public:
   483     class AutoLinkScope
   484     {
   485       public:
   486         AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
   487           : prevp_(prevp),
   488             prev_(*prevp),
   489             scope_(scope)
   490         {
   491             if (scope_) {
   492                 *prevp_ = this;
   493                 if (prev_)
   494                     scope_->setParent(prev_->scope());
   495             }
   496         }
   497         ~AutoLinkScope() {
   498             if (scope_) {
   499                 assert(*prevp_ == this);
   500                 *prevp_ = prev_;
   501             }
   502         }
   503         Scope *scope() const {
   504             return scope_;
   505         }
   506 
   507       private:
   508         AutoLinkScope **prevp_;
   509         AutoLinkScope *prev_;
   510         Scope *scope_;
   511     };
   512 
   513   public:
   514     NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   515       : zone_(zone),
   516         pool_(zone->pool()),
   517         cc_(cc),
   518         unit_(unit),
   519         link_(NULL)
   520     {
   521     }
   522 
   523     bool bind() {
   524         // Start with the import scope, and collect all imported names.
   525         AutoLinkScope importScope(&link_, unit_->importScope());
   526 
   527         for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
   528             unit_->tree()->imports()->at(i)->accept(this);
   529 
   530         // Next, enter the global scope and walk all statements.
   531         AutoLinkScope globalScope(&link_, unit_->globalScope());
   532         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   533             Statement *stmt = unit_->tree()->statements()->at(i);
   534             stmt->accept(this);
   535         }
   536 
   537         return true;
   538     }
   539 
   540     void visitVariableDeclaration(VariableDeclaration *node) {
   541         // Bind the initializer before registering the declaration, so that we
   542         // can error on bogus initializers (new x = x).
   543         if (node->initialization())
   544             node->initialization()->accept(this);
   545 
   546         Local<Type> type(zone_, bindType(node->type(), node->quals()));
   547         if (!type)
   548             return;
   549 
   550         // We don't allow array typedefs yet.
   551         assert(!type->isArray());
   552 
   553         if (node->dims()) {
   554             int dims[MAX_ARRAY_DEPTH];
   555             int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
   556             if (levels < 0)
   557                 return;
   558 
   559             // Do some extra inference based on the initializer, if present.
   560             Expression *init = node->initialization();
   561             if (init &&
   562                 init->isArrayLiteral() &&
   563                 init->toArrayLiteral()->isFixed())
   564             {
   565                 Local<Type> contained(zone_, type->isArray()
   566                                              ? ArrayType::cast(type)->contained()
   567                                              : type);
   568                 if (!inferFixedArrayDimensions(init->toArrayLiteral(), contained, dims, levels))
   569                     return;
   570             }
   571 
   572             // If we got extra dimensions, we need to build a new type.
   573             if (node->dims()) {
   574                 if ((type = buildArrayType(type, node->quals(), dims, node->dims()->length())) == NULL)
   575                     return;
   576             }
   577         }
   578 
   579         // If we're in global scope, and we received a |const| qualifier, then
   580         // we extend this to array reference as well. This is to sort of mimic
   581         // SP1 functionality, but also means that you cannot have changeable
   582         // const pointers in global scope.
   583         if ((node->quals() & TypeQual_Const) &&
   584             type->isArray() &&
   585             link_->scope()->kind() == Scope::GLOBAL)
   586         {
   587             if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
   588                 return;
   589             if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
   590                 return;
   591         }
   592 
   593         // If the node already has a symbol (meaning it was a global), then
   594         // we don't have to do anything more.
   595         if (node->sym()) {
   596             assert(node->sym()->scope()->kind() == Scope::GLOBAL);
   597             node->sym()->setType(type);
   598             return;
   599         }
   600 
   601         VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
   602         node->setSymbol(sym);
   603        
   604         if (Symbol *other = link_->scope()->localLookup(sym->name())) {
   605             // Report, but allow errors to continue.
   606             cc_.reportError(sym->pos(), Message_RedeclaredName,
   607                             sym->name()->chars(),
   608                             other->pos().line,
   609                             other->pos().col);
   610             return;
   611         }
   612         
   613         link_->scope()->addSymbol(sym);
   614     }
   615     void visitEnumStatement(EnumStatement *node) {
   616     }
   617     void visitFunctionStatement(FunctionStatement *node) {
   618         AutoLinkScope argScope(&link_, node->argScope());
   619         AutoLinkScope varScope(&link_, node->varScope());
   620 
   621         Local<FunctionType> type(zone_, node->sym()->type());
   622         if (!fillFunctionType(type, node->signature()))
   623             return;
   624 
   625         if (node->body())
   626             node->body()->accept(this);
   627     }
   628     void visitStructureStatement(StructureStatement *node) {
   629         assert(false);
   630     }
   631     void visitFunctionTypeStatement(FunctionTypeStatement *node) {
   632         assert(false);
   633     }
   634 
   635     void visitNameProxy(NameProxy *proxy) {
   636         Scope *scope = link_->scope();
   637         Symbol *sym = scope->lookup(proxy->name());
   638         if (!sym)
   639             cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
   640         proxy->bind(sym);
   641     }
   642     void visitAssignment(Assignment *node) {
   643         node->lvalue()->accept(this);
   644         node->expression()->accept(this);
   645     }
   646     void visitBinaryExpression(BinaryExpression *node) {
   647         node->left()->accept(this);
   648         node->right()->accept(this);
   649     }
   650     void visitReturnStatement(ReturnStatement *node) {
   651         node->expression()->accept(this);
   652     }
   653     void visitForStatement(ForStatement *node) {
   654         AutoLinkScope scope(&link_, node->scope());
   655 
   656         if (node->initialization())
   657             node->initialization()->accept(this);
   658         if (node->condition())
   659             node->condition()->accept(this);
   660         if (node->update())
   661             node->update()->accept(this);
   662         node->body()->accept(this);
   663     }
   664     void visitBlockStatement(BlockStatement *node) {
   665         AutoLinkScope scope(&link_, node->scope());
   666         for (size_t i = 0; i < node->statements()->length(); i++)
   667             node->statements()->at(i)->accept(this);
   668     }
   669     void visitIntegerLiteral(IntegerLiteral *node) {
   670     }
   671     void visitExpressionStatement(ExpressionStatement *node) {
   672         node->expression()->accept(this);
   673     }
   674     void visitCallExpression(CallExpression *node) {
   675         node->callee()->accept(this);
   676         for (size_t i = 0; i < node->arguments()->length(); i++)
   677             node->arguments()->at(i)->accept(this);
   678     }
   679     void visitIfStatement(IfStatement *node) {
   680         node->condition()->accept(this);
   681         node->ifTrue()->accept(this);
   682         if (node->ifFalse())
   683             node->ifFalse()->accept(this);
   684     }
   685     void visitIndexExpression(IndexExpression *node) {
   686         node->left()->accept(this);
   687         node->right()->accept(this);
   688     }
   689     void visitFloatLiteral(FloatLiteral *node) {
   690     }
   691     void visitWhileStatement(WhileStatement *node) {
   692         node->condition()->accept(this);
   693         node->body()->accept(this);
   694     }
   695     void visitBreakStatement(BreakStatement *node) {
   696     }
   697     void visitContinueStatement(ContinueStatement *node) {
   698     }
   699     void visitStringLiteral(StringLiteral *node) {
   700     }
   701     void visitIncDecExpression(IncDecExpression *node) {
   702         node->expression()->accept(this);
   703     }
   704     void visitUnaryExpression(UnaryExpression *node) {
   705         if (node->tag())
   706             node->tag()->accept(this);
   707         node->expression()->accept(this);
   708     }
   709     void visitTernaryExpression(TernaryExpression *node) {
   710         node->condition()->accept(this);
   711         node->left()->accept(this);
   712         node->right()->accept(this);
   713     }
   714     void visitBooleanLiteral(BooleanLiteral *node) {
   715     }
   716     void visitFieldExpression(FieldExpression *node) {
   717         node->left()->accept(this);
   718     }
   719     void visitSwitchStatement(SwitchStatement *node) {
   720         node->expression()->accept(this);
   721         node->defaultCase()->accept(this);
   722         for (size_t i = 0; i < node->cases()->length(); i++) {
   723             // We don't test case expressions because they are literals.
   724             Case *c = node->cases()->at(i);
   725             c->statement()->accept(this);
   726         }
   727     }
   728     void visitArrayLiteral(ArrayLiteral *node) {
   729         for (size_t i = 0; i < node->expressions()->length(); i++)
   730             node->expressions()->at(i)->accept(this);
   731     }
   732     void visitImportStatement(ImportStatement *node) {
   733         if (node->suffix() == TOK_STAR) {
   734             // Import every name.
   735             assert(false);
   736         } else {
   737             GlobalScope *other = node->source()->globalScope();
   738             Symbol *sym = other->findPublic(node->name());
   739             if (!sym) {
   740                 cc_.reportError(node->pos(), Message_CannotResolveImport, node->name()->chars());
   741                 return;
   742             }
   743             link_->scope()->addSymbol(sym);
   744         }
   745     }
   746 
   747   private:
   748     int evaluateDimensions(const SourcePosition &pos, Handle<Type> typeArg, ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH]) {
   749         unsigned level = 0;
   750         Local<Type> type(zone_, typeArg);
   751         while (type->isArray()) {
   752             ArrayType *atype = ArrayType::cast(type);
   753             dims[level] = atype->isFixedLength()
   754                           ? atype->fixedLength()
   755                           : DYNAMIC_ARRAY_SIZE;
   756             type = atype->contained();
   757             level++;
   758         }
   759 
   760         if (!exprs)
   761             return level;
   762 
   763         if (level + exprs->length() > MAX_ARRAY_DEPTH) {
   764             cc_.reportError(pos, Message_MaximumArrayDepth);
   765             return -1;
   766         }
   767 
   768         bool hadEmptySize = false;
   769         for (size_t i = 0; i < exprs->length(); i++) {
   770             Expression *expr = exprs->at(i);
   771             if (!expr) {
   772                 dims[i] = INFER_ARRAY_SIZE;
   773                 hadEmptySize = true;
   774                 continue;
   775             }
   776 
   777             BoxedPrimitive box;
   778             if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   779                 int size = box.toInt();
   780                 if (size <= 0) {
   781                     cc_.reportError(expr->pos(), Message_BadArraySize);
   782                     return false;
   783                 }
   784 
   785                 dims[i] = size;
   786                 continue;
   787             }
   788 
   789             if (hadEmptySize) {
   790                 cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
   791                 return false;
   792             }
   793 
   794             dims[i] = EVAL_ARRAY_SIZE;
   795         }
   796 
   797         return level + exprs->length();
   798     }
   799 
   800     // This function computes missing dimension sizes based on a literal
   801     // initializer. We don't really handle any size rules here; we just
   802     // do a really dumb inference.
   803     bool inferFixedArrayDimensions(ArrayLiteral *lit, Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], int levels) {
   804         for (int i = 0; i < levels; i++) {
   805             if (dims[i] == EVAL_ARRAY_SIZE || dims[i] == DYNAMIC_ARRAY_SIZE) {
   806                 // The following are invalid:
   807                 //   new x[<expr>] = {...}
   808                 //   new Type:x = {...}  // where Type is a non-fixed array type
   809                 cc_.reportError(lit->pos(), Message_CannotInitializeEvalArray);
   810                 return false;
   811             }
   812 
   813             if (dims[i] == INFER_ARRAY_SIZE) {
   814                 // Character arrays are always dynamic when inferred from string literals.
   815                 if (i == levels - 1 && contained->isChar())
   816                     dims[i] = DYNAMIC_ARRAY_SIZE;
   817                 else
   818                     dims[i] = lit->expressions()->length();
   819             }
   820 
   821             if (i != levels - 1) {
   822                 // Fixed array literals are guaranteed to have at least one expression.
   823                 Expression *next = lit->expressions()->at(0);
   824                 if (!next->isArrayLiteral()) {
   825                     // Whelp... this array is just malformed. Not the best error message
   826                     // but whatever.
   827                     cc_.reportError(next->pos(), Message_ArraySizeCannotBeDetermined);
   828                     return false;
   829                 }
   830                 lit = next->toArrayLiteral();
   831             }
   832         }
   833 
   834         return true;
   835     }
   836 
   837     ArrayType *buildArrayType(Handle<Type> contained, TypeQualifiers quals, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
   838         Local<Type> type(zone_, contained);
   839 
   840         for (size_t i = postlevels - 1; i < postlevels; i--) {
   841             int size = dims[i] > 0
   842                        ? dims[i]
   843                        : ArrayType::DYNAMIC_ARRAY_SIZE;
   844             
   845             if ((type = zone_->types()->newArray(contained, size)) == NULL)
   846                 return NULL;
   847             if ((type = zone_->types()->qualify(type, quals)) == NULL)
   848                 return NULL;
   849         }
   850         return ArrayType::cast(type);
   851     }
   852 
   853     bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
   854         Local<Type> type(zone_);
   855         if (!fun->returnType()) {
   856             if ((type = bindType(sig.returnType(), TypeQual_None)) == NULL)
   857                 return false;
   858             fun->setReturnType(type);
   859         }
   860 
   861         Local<FixedArray> params(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
   862         if (!params)
   863             return false;
   864 
   865         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   866             Parameter *param = sig.parameters()->at(i);
   867             if ((type = bindType(param->type(), param->quals())) == NULL)
   868                 return false;
   869 
   870             assert(!type->isArray());
   871 
   872             if (param->dims()) {
   873                 int dims[MAX_ARRAY_DEPTH];
   874                 int levels = evaluateDimensions(param->pos(), type, param->dims(), dims);
   875                 if (levels < 0)
   876                     return false;
   877 
   878                 // If we got extra dimensions, we need to build a new type.
   879                 // Unlike variables, we do not infer anything about array
   880                 // sizes from its default initializer.
   881                 if (param->dims()) {
   882                     if ((type = buildArrayType(type, param->quals(), dims, param->dims()->length())) == NULL)
   883                         return false;
   884                 }
   885 
   886                 if (ArrayType::cast(type)->innermost()->isVoid()) {
   887                     cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   888                     return false;
   889                 }
   890             }
   891 
   892             if (param->reference()) {
   893                 if (!type->isPod()) {
   894                     cc_.reportError(param->pos(), Message_ArrayCantBeReference);
   895                     return false;
   896                 }
   897                 if (param->quals() & TypeQual_Const) {
   898                     cc_.reportError(param->pos(), Message_CannotConstReference);
   899                     return false;
   900                 }
   901                 if ((type = zone_->types()->getReference(type, false)) == NULL)
   902                     return false;
   903             }
   904             if (param->quals() & TypeQual_Const) {
   905                 if (!type->isArray() && !type->isStruct()) {
   906                     cc_.reportError(param->pos(), Message_InvalidConstOnFormal);
   907                     return false;
   908                 }
   909             }
   910 
   911             if (type->isVoid()) {
   912                 cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   913                 return false;
   914             }
   915 
   916             params->set(zone_, i, type);
   917             param->sym()->setType(type);
   918         }
   919 
   920         fun->setParameterTypes(params);
   921 
   922         return true;
   923     }
   924 
   925     Type *bindType(Expression *expr, TypeQualifiers quals) {
   926         Local<Type> type(zone_);
   927 
   928         if (!expr) {
   929             // If no type was declared, we return int32.
   930             type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   931         } else {
   932             expr->accept(this);
   933 
   934             NameProxy *proxy = expr->asNameProxy();
   935             assert(proxy);
   936 
   937             Symbol *sym = proxy->sym();
   938             if (!sym)
   939                 return NULL;
   940 
   941             if (!sym->isType()) {
   942                 cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
   943                 return NULL;
   944             }
   945 
   946             type = sym->type();
   947         }
   948 
   949         return zone_->types()->qualify(type, quals);
   950     }
   951 
   952   private:
   953     Zone *zone_;
   954     PoolAllocator &pool_;
   955     CompileContext &cc_;
   956     TranslationUnit *unit_;
   957     AutoLinkScope *link_;
   958 };
   959 
   960 bool
   961 ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   962 {
   963     NameBinder binder(zone, cc, unit);
   964     return binder.bind();
   965 }