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