src/compiler/NameBinding.cpp
author David Anderson <dvander@alliedmods.net>
Sat Dec 29 00:12:27 2012 -0800 (2012-12-29)
changeset 249 82b1f8bc93a9
parent 247 7721042bdb67
child 250 0998a43cc155
permissions -rw-r--r--
Infer fixed array types from string literals.
     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         if (node->type() == TOK_NEW) {
   339             // Don't create a symbol environment for this block, since it
   340             // was created solely to house multiple variable decls.
   341             for (size_t i = 0; i < node->statements()->length(); i++)
   342                 node->statements()->at(i)->accept(this);
   343         } else {
   344             assert(node->type() == TOK_LBRACE);
   345 
   346             SymbolEnv env(&env_);
   347 
   348             for (size_t i = 0; i < node->statements()->length(); i++)
   349                 node->statements()->at(i)->accept(this);
   350         
   351             if (node->type() == TOK_NEW) {
   352                 assert(!env.scope());
   353                 return;
   354             }
   355 
   356             node->setScope(env.scope());
   357         }
   358     }
   359     void visitIntegerLiteral(IntegerLiteral *node) {
   360     }
   361     void visitExpressionStatement(ExpressionStatement *node) {
   362         node->expression()->accept(this);
   363     }
   364     void visitCallExpression(CallExpression *node) {
   365         node->callee()->accept(this);
   366         for (size_t i = 0; i < node->arguments()->length(); i++)
   367             node->arguments()->at(i)->accept(this);
   368     }
   369     void visitIfStatement(IfStatement *node) {
   370         node->ifTrue()->accept(this);
   371         if (node->ifFalse())
   372             node->ifFalse()->accept(this);
   373     }
   374     void visitIndexExpression(IndexExpression *node) {
   375         node->left()->accept(this);
   376         node->right()->accept(this);
   377     }
   378     void visitFloatLiteral(FloatLiteral *node) {
   379     }
   380     void visitWhileStatement(WhileStatement *node) {
   381         node->condition()->accept(this);
   382         node->body()->accept(this);
   383     }
   384     void visitBreakStatement(BreakStatement *node) {
   385     }
   386     void visitContinueStatement(ContinueStatement *node) {
   387     }
   388     void visitStringLiteral(StringLiteral *node) {
   389     }
   390     void visitIncDecExpression(IncDecExpression *node) {
   391         node->expression()->accept(this);
   392     }
   393     void visitUnaryExpression(UnaryExpression *node) {
   394         node->expression()->accept(this);
   395     }
   396     void visitTernaryExpression(TernaryExpression *node) {
   397         assert(false);
   398     }
   399     void visitBooleanLiteral(BooleanLiteral *node) {
   400     }
   401     void visitFieldExpression(FieldExpression *node) {
   402     }
   403     void visitSwitchStatement(SwitchStatement *node) {
   404         if (node->defaultCase())
   405             node->defaultCase()->accept(this);
   406 
   407         for (size_t i = 0; i < node->cases()->length(); i++)
   408             node->cases()->at(i)->statement()->accept(this);
   409     }
   410     void visitArrayLiteral(ArrayLiteral *node) {
   411     }
   412     void visitImportStatement(ImportStatement *node) {
   413     }
   414 
   415   private:
   416     Scope *getGlobalOrCreateBlockScope() {
   417         if (env_->scope()) {
   418             assert(env_->scope()->kind() == Scope::BLOCK ||
   419                    env_->scope()->kind() == Scope::GLOBAL);
   420             return env_->scope();
   421         }
   422         return getOrCreateBlockScope();
   423     }
   424     Scope *getOrCreateBlockScope() {
   425         if (env_->scope()) {
   426             assert(env_->scope()->kind() == Scope::BLOCK);
   427             return env_->scope();
   428         }
   429         
   430         LocalScope *scope = LocalScope::New(pool_);
   431         if (!scope)
   432             return NULL;
   433 
   434         env_->setScope(scope);
   435         return scope;
   436     }
   437 
   438     bool registerName(Scope *scope, Symbol *sym) {
   439         if (!scope)
   440             return false;
   441 
   442         if (Symbol *other = scope->localLookup(sym->name())) {
   443             // Report, but allow errors to continue.
   444             cc_.reportError(sym->pos(), Message_RedeclaredName,
   445                             sym->name()->chars(),
   446                             other->pos().line,
   447                             other->pos().col);
   448             return true;
   449         }
   450 
   451         return scope->addSymbol(sym);
   452     }
   453 
   454     bool registerArguments(const FunctionSignature &sig) {
   455         if (!sig.parameters()->length())
   456             return true;
   457 
   458         ArgumentScope *argScope = ArgumentScope::New(pool_);
   459         if (!argScope)
   460             return false;
   461         env_->setScope(argScope);
   462 
   463         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   464             Parameter *param = sig.parameters()->at(i);
   465             VariableSymbol *sym = new (pool_) VariableSymbol(argScope, param->name(), param->pos());
   466             if (!registerName(env_->scope(), sym))
   467                 return false;
   468             param->setSymbol(sym);
   469         }
   470 
   471         return true;
   472     }
   473 
   474   private:
   475     Zone *zone_;
   476     PoolAllocator &pool_;
   477     CompileContext &cc_;
   478     TranslationUnit *unit_;
   479     SymbolEnv *env_;
   480     FunctionScope *fun_;
   481 };
   482 
   483 bool
   484 ke::PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   485 {
   486     NamePopulator populator(zone, cc, unit);
   487     return populator.analyze();
   488 }
   489 
   490 static const int INFER_ARRAY_SIZE = 0;
   491 static const int EVAL_ARRAY_SIZE = -1;
   492 static const int DYNAMIC_ARRAY_SIZE = -2;
   493 
   494 class NameBinder : public AstVisitor
   495 {
   496   public:
   497     class AutoLinkScope
   498     {
   499       public:
   500         AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
   501           : prevp_(prevp),
   502             prev_(*prevp),
   503             scope_(scope)
   504         {
   505             if (scope_) {
   506                 *prevp_ = this;
   507                 if (prev_)
   508                     scope_->setParent(prev_->scope());
   509             }
   510         }
   511         ~AutoLinkScope() {
   512             if (scope_) {
   513                 assert(*prevp_ == this);
   514                 *prevp_ = prev_;
   515             }
   516         }
   517         Scope *scope() const {
   518             return scope_;
   519         }
   520 
   521       private:
   522         AutoLinkScope **prevp_;
   523         AutoLinkScope *prev_;
   524         Scope *scope_;
   525     };
   526 
   527   public:
   528     NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   529       : zone_(zone),
   530         pool_(zone->pool()),
   531         cc_(cc),
   532         unit_(unit),
   533         link_(NULL)
   534     {
   535     }
   536 
   537     bool bind() {
   538         // Start with the import scope, and collect all imported names.
   539         AutoLinkScope importScope(&link_, unit_->importScope());
   540 
   541         for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
   542             unit_->tree()->imports()->at(i)->accept(this);
   543 
   544         // Next, enter the global scope and walk all statements.
   545         AutoLinkScope globalScope(&link_, unit_->globalScope());
   546         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   547             Statement *stmt = unit_->tree()->statements()->at(i);
   548             stmt->accept(this);
   549         }
   550 
   551         return true;
   552     }
   553 
   554     void visitVariableDeclaration(VariableDeclaration *node) {
   555         // Bind the initializer before registering the declaration, so that we
   556         // can error on bogus initializers (new x = x).
   557         if (node->initialization())
   558             node->initialization()->accept(this);
   559 
   560         Local<Type> type(zone_, bindType(node->type(), node->quals()));
   561         if (!type)
   562             return;
   563 
   564         // We don't allow array typedefs yet.
   565         assert(!type->isArray());
   566 
   567         if (node->dims()) {
   568             int dims[MAX_ARRAY_DEPTH];
   569             int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
   570             if (levels < 0)
   571                 return;
   572 
   573             // Do some extra inference based on the initializer, if present.
   574             Expression *init = node->initialization();
   575             if (init) {
   576                 if (init->isArrayLiteral() && init->toArrayLiteral()->isFixed()) {
   577                     Local<Type> contained(zone_, type->isArray()
   578                                                  ? ArrayType::cast(type)->contained()
   579                                                  : type);
   580                     if (!inferFixedArrayDimensions(init->toArrayLiteral(), contained, dims, levels))
   581                         return;
   582                 } else if (init->isStringLiteral()) {
   583                     dims[levels - 1] = init->toStringLiteral()->string()->length() + 1;
   584                 }
   585             }
   586 
   587             // If we got extra dimensions, we need to build a new type.
   588             if (node->dims()) {
   589                 if ((type = buildArrayType(type, node->quals(), dims, node->dims()->length())) == NULL)
   590                     return;
   591             }
   592         }
   593 
   594         // If we're in global scope, and we received a |const| qualifier, then
   595         // we extend this to array references as well. This is to sort of mimic
   596         // SP1 functionality, but also means that you cannot have changeable
   597         // const pointers in global scope.
   598         if ((node->quals() & TypeQual_Const) &&
   599             type->isArray() &&
   600             link_->scope()->kind() == Scope::GLOBAL)
   601         {
   602             if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
   603                 return;
   604         }
   605 
   606         // If the node already has a symbol (meaning it was a global), then
   607         // we don't have to do anything more.
   608         if (node->sym()) {
   609             assert(node->sym()->scope()->kind() == Scope::GLOBAL);
   610             node->sym()->setType(type);
   611             return;
   612         }
   613 
   614         VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
   615         node->setSymbol(sym);
   616        
   617         if (Symbol *other = link_->scope()->localLookup(sym->name())) {
   618             // Report, but allow errors to continue.
   619             cc_.reportError(sym->pos(), Message_RedeclaredName,
   620                             sym->name()->chars(),
   621                             other->pos().line,
   622                             other->pos().col);
   623             return;
   624         }
   625         
   626         link_->scope()->addSymbol(sym);
   627     }
   628     void visitEnumStatement(EnumStatement *node) {
   629     }
   630     void visitFunctionStatement(FunctionStatement *node) {
   631         AutoLinkScope argScope(&link_, node->argScope());
   632         AutoLinkScope varScope(&link_, node->varScope());
   633 
   634         Local<FunctionType> type(zone_, node->sym()->type());
   635         if (!fillFunctionType(type, node->signature()))
   636             return;
   637 
   638         if (node->body())
   639             node->body()->accept(this);
   640     }
   641     void visitStructureStatement(StructureStatement *node) {
   642         assert(false);
   643     }
   644     void visitFunctionTypeStatement(FunctionTypeStatement *node) {
   645         assert(false);
   646     }
   647 
   648     void visitNameProxy(NameProxy *proxy) {
   649         Scope *scope = link_->scope();
   650         Symbol *sym = scope->lookup(proxy->name());
   651         if (!sym)
   652             cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
   653         proxy->bind(sym);
   654     }
   655     void visitAssignment(Assignment *node) {
   656         node->lvalue()->accept(this);
   657         node->expression()->accept(this);
   658     }
   659     void visitBinaryExpression(BinaryExpression *node) {
   660         node->left()->accept(this);
   661         node->right()->accept(this);
   662     }
   663     void visitReturnStatement(ReturnStatement *node) {
   664         node->expression()->accept(this);
   665     }
   666     void visitForStatement(ForStatement *node) {
   667         AutoLinkScope scope(&link_, node->scope());
   668 
   669         if (node->initialization())
   670             node->initialization()->accept(this);
   671         if (node->condition())
   672             node->condition()->accept(this);
   673         if (node->update())
   674             node->update()->accept(this);
   675         node->body()->accept(this);
   676     }
   677     void visitBlockStatement(BlockStatement *node) {
   678         AutoLinkScope scope(&link_, node->scope());
   679         for (size_t i = 0; i < node->statements()->length(); i++)
   680             node->statements()->at(i)->accept(this);
   681     }
   682     void visitIntegerLiteral(IntegerLiteral *node) {
   683     }
   684     void visitExpressionStatement(ExpressionStatement *node) {
   685         node->expression()->accept(this);
   686     }
   687     void visitCallExpression(CallExpression *node) {
   688         node->callee()->accept(this);
   689         for (size_t i = 0; i < node->arguments()->length(); i++)
   690             node->arguments()->at(i)->accept(this);
   691     }
   692     void visitIfStatement(IfStatement *node) {
   693         node->condition()->accept(this);
   694         node->ifTrue()->accept(this);
   695         if (node->ifFalse())
   696             node->ifFalse()->accept(this);
   697     }
   698     void visitIndexExpression(IndexExpression *node) {
   699         node->left()->accept(this);
   700         node->right()->accept(this);
   701     }
   702     void visitFloatLiteral(FloatLiteral *node) {
   703     }
   704     void visitWhileStatement(WhileStatement *node) {
   705         node->condition()->accept(this);
   706         node->body()->accept(this);
   707     }
   708     void visitBreakStatement(BreakStatement *node) {
   709     }
   710     void visitContinueStatement(ContinueStatement *node) {
   711     }
   712     void visitStringLiteral(StringLiteral *node) {
   713     }
   714     void visitIncDecExpression(IncDecExpression *node) {
   715         node->expression()->accept(this);
   716     }
   717     void visitUnaryExpression(UnaryExpression *node) {
   718         if (node->tag())
   719             node->tag()->accept(this);
   720         node->expression()->accept(this);
   721     }
   722     void visitTernaryExpression(TernaryExpression *node) {
   723         node->condition()->accept(this);
   724         node->left()->accept(this);
   725         node->right()->accept(this);
   726     }
   727     void visitBooleanLiteral(BooleanLiteral *node) {
   728     }
   729     void visitFieldExpression(FieldExpression *node) {
   730         node->left()->accept(this);
   731     }
   732     void visitSwitchStatement(SwitchStatement *node) {
   733         node->expression()->accept(this);
   734         node->defaultCase()->accept(this);
   735         for (size_t i = 0; i < node->cases()->length(); i++) {
   736             // We don't test case expressions because they are literals.
   737             Case *c = node->cases()->at(i);
   738             c->statement()->accept(this);
   739         }
   740     }
   741     void visitArrayLiteral(ArrayLiteral *node) {
   742         for (size_t i = 0; i < node->expressions()->length(); i++)
   743             node->expressions()->at(i)->accept(this);
   744     }
   745     void visitImportStatement(ImportStatement *node) {
   746         if (node->suffix() == TOK_STAR) {
   747             // Import every name.
   748             assert(false);
   749         } else {
   750             GlobalScope *other = node->source()->globalScope();
   751             Symbol *sym = other->findPublic(node->name());
   752             if (!sym) {
   753                 cc_.reportError(node->pos(), Message_CannotResolveImport, node->name()->chars());
   754                 return;
   755             }
   756             link_->scope()->addSymbol(sym);
   757         }
   758     }
   759 
   760   private:
   761     int evaluateDimensions(const SourcePosition &pos, Handle<Type> typeArg, ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH]) {
   762         unsigned level = 0;
   763         Local<Type> type(zone_, typeArg);
   764         while (type->isArray()) {
   765             ArrayType *atype = ArrayType::cast(type);
   766             dims[level] = atype->isFixedLength()
   767                           ? atype->fixedLength()
   768                           : DYNAMIC_ARRAY_SIZE;
   769             type = atype->contained();
   770             level++;
   771         }
   772 
   773         if (!exprs)
   774             return level;
   775 
   776         if (level + exprs->length() > MAX_ARRAY_DEPTH) {
   777             cc_.reportError(pos, Message_MaximumArrayDepth);
   778             return -1;
   779         }
   780 
   781         bool hadEmptySize = false;
   782         for (size_t i = 0; i < exprs->length(); i++) {
   783             Expression *expr = exprs->at(i);
   784             if (!expr) {
   785                 dims[i] = INFER_ARRAY_SIZE;
   786                 hadEmptySize = true;
   787                 continue;
   788             }
   789 
   790             BoxedPrimitive box;
   791             if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   792                 int size = box.toInt();
   793                 if (size <= 0) {
   794                     cc_.reportError(expr->pos(), Message_BadArraySize);
   795                     return false;
   796                 }
   797 
   798                 dims[i] = size;
   799                 continue;
   800             }
   801 
   802             if (hadEmptySize) {
   803                 cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
   804                 return false;
   805             }
   806 
   807             dims[i] = EVAL_ARRAY_SIZE;
   808         }
   809 
   810         return level + exprs->length();
   811     }
   812 
   813     // This function computes missing dimension sizes based on a literal
   814     // initializer. We don't really handle any size rules here; we just
   815     // do a really dumb inference.
   816     bool inferFixedArrayDimensions(ArrayLiteral *lit, Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], int levels) {
   817         for (int i = 0; i < levels; i++) {
   818             if (dims[i] == EVAL_ARRAY_SIZE || dims[i] == DYNAMIC_ARRAY_SIZE) {
   819                 // The following are invalid:
   820                 //   new x[<expr>] = {...}
   821                 //   new Type:x = {...}  // where Type is a non-fixed array type
   822                 cc_.reportError(lit->pos(), Message_CannotInitializeEvalArray);
   823                 return false;
   824             }
   825 
   826             if (dims[i] == INFER_ARRAY_SIZE) {
   827                 // Character arrays are always dynamic when inferred from string literals.
   828                 if (i == levels - 1 && contained->isChar())
   829                     dims[i] = DYNAMIC_ARRAY_SIZE;
   830                 else
   831                     dims[i] = lit->expressions()->length();
   832             }
   833 
   834             if (i != levels - 1) {
   835                 // Fixed array literals are guaranteed to have at least one expression.
   836                 Expression *next = lit->expressions()->at(0);
   837                 if (!next->isArrayLiteral()) {
   838                     // Whelp... this array is just malformed. Not the best error message
   839                     // but whatever.
   840                     cc_.reportError(next->pos(), Message_ArraySizeCannotBeDetermined);
   841                     return false;
   842                 }
   843                 lit = next->toArrayLiteral();
   844             }
   845         }
   846 
   847         return true;
   848     }
   849 
   850     ArrayType *buildArrayType(Handle<Type> contained, TypeQualifiers quals, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
   851         Local<Type> type(zone_, contained);
   852 
   853         for (size_t i = postlevels - 1; i < postlevels; i--) {
   854             int size = dims[i] > 0
   855                        ? dims[i]
   856                        : ArrayType::DYNAMIC_ARRAY_SIZE;
   857             
   858             if ((type = zone_->types()->newArray(contained, size)) == NULL)
   859                 return NULL;
   860             if ((type = zone_->types()->qualify(type, quals)) == NULL)
   861                 return NULL;
   862         }
   863         return ArrayType::cast(type);
   864     }
   865 
   866     bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
   867         Local<Type> type(zone_);
   868         if (!fun->returnType()) {
   869             if ((type = bindType(sig.returnType(), TypeQual_None)) == NULL)
   870                 return false;
   871             fun->setReturnType(type);
   872         }
   873 
   874         if (sig.variadic())
   875             fun->setVariadic();
   876 
   877         Local<FixedArray> params(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
   878         if (!params)
   879             return false;
   880 
   881         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   882             Parameter *param = sig.parameters()->at(i);
   883             if ((type = bindType(param->type(), param->quals())) == NULL)
   884                 return false;
   885 
   886             assert(!type->isArray());
   887 
   888             if (param->dims()) {
   889                 int dims[MAX_ARRAY_DEPTH];
   890                 int levels = evaluateDimensions(param->pos(), type, param->dims(), dims);
   891                 if (levels < 0)
   892                     return false;
   893 
   894                 // If we got extra dimensions, we need to build a new type.
   895                 // Unlike variables, we do not infer anything about array
   896                 // sizes from its default initializer.
   897                 if (param->dims()) {
   898                     if ((type = buildArrayType(type, param->quals(), dims, param->dims()->length())) == NULL)
   899                         return false;
   900                 }
   901 
   902                 if (ArrayType::cast(type)->innermost()->isVoid()) {
   903                     cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   904                     return false;
   905                 }
   906             }
   907 
   908             if (param->reference()) {
   909                 if (!type->isPod()) {
   910                     cc_.reportError(param->pos(), Message_ArrayCantBeReference);
   911                     return false;
   912                 }
   913                 if (param->quals() & TypeQual_Const) {
   914                     cc_.reportError(param->pos(), Message_CannotConstReference);
   915                     return false;
   916                 }
   917                 if ((type = zone_->types()->getReference(type, false)) == NULL)
   918                     return false;
   919             }
   920             if (param->quals() & TypeQual_Const) {
   921                 if (!type->isArray() && !type->isStruct()) {
   922                     cc_.reportError(param->pos(), Message_InvalidConstOnFormal);
   923                     return false;
   924                 }
   925             }
   926 
   927             if (type->isVoid()) {
   928                 cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   929                 return false;
   930             }
   931 
   932             params->set(zone_, i, type);
   933             param->sym()->setType(type);
   934         }
   935 
   936         fun->setParameterTypes(params);
   937 
   938         return true;
   939     }
   940 
   941     Type *bindType(Expression *expr, TypeQualifiers quals) {
   942         Local<Type> type(zone_);
   943 
   944         if (!expr) {
   945             // If no type was declared, we return int32.
   946             type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   947         } else {
   948             expr->accept(this);
   949 
   950             NameProxy *proxy = expr->asNameProxy();
   951             assert(proxy);
   952 
   953             Symbol *sym = proxy->sym();
   954             if (!sym)
   955                 return NULL;
   956 
   957             if (!sym->isType()) {
   958                 cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
   959                 return NULL;
   960             }
   961 
   962             type = sym->type();
   963         }
   964 
   965         return zone_->types()->qualify(type, quals);
   966     }
   967 
   968   private:
   969     Zone *zone_;
   970     PoolAllocator &pool_;
   971     CompileContext &cc_;
   972     TranslationUnit *unit_;
   973     AutoLinkScope *link_;
   974 };
   975 
   976 bool
   977 ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   978 {
   979     NameBinder binder(zone, cc, unit);
   980     return binder.bind();
   981 }