src/compiler/NameBinding.cpp
changeset 241 18f3010a358c
parent 237 c77540a61905
child 242 b7d14a8b918e
     1.1 --- a/src/compiler/NameBinding.cpp	Tue Dec 25 18:13:02 2012 -0800
     1.2 +++ b/src/compiler/NameBinding.cpp	Wed Dec 26 17:14:12 2012 -0800
     1.3 @@ -543,11 +543,14 @@
     1.4          if (node->initialization())
     1.5              node->initialization()->accept(this);
     1.6  
     1.7 -        Local<Type> type(zone_, bindType(node->type()));
     1.8 +        Local<Type> type(zone_, bindType(node->type(), node->quals()));
     1.9          if (!type)
    1.10              return;
    1.11  
    1.12 -        if (node->dims() || type->isArray()) {
    1.13 +        // We don't allow array typedefs yet.
    1.14 +        assert(!type->isArray());
    1.15 +
    1.16 +        if (node->dims()) {
    1.17              int dims[MAX_ARRAY_DEPTH];
    1.18              int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
    1.19              if (levels < 0)
    1.20 @@ -568,11 +571,25 @@
    1.21  
    1.22              // If we got extra dimensions, we need to build a new type.
    1.23              if (node->dims()) {
    1.24 -                if ((type = buildArrayType(type, dims, node->dims()->length())) == NULL)
    1.25 +                if ((type = buildArrayType(type, node->quals(), dims, node->dims()->length())) == NULL)
    1.26                      return;
    1.27              }
    1.28          }
    1.29  
    1.30 +        // If we're in global scope, and we received a |const| qualifier, then
    1.31 +        // we extend this to array reference as well. This is to sort of mimic
    1.32 +        // SP1 functionality, but also means that you cannot have changeable
    1.33 +        // const pointers in global scope.
    1.34 +        if ((node->quals() & TypeQual_Const) &&
    1.35 +            type->isArray() &&
    1.36 +            link_->scope()->kind() == Scope::GLOBAL)
    1.37 +        {
    1.38 +            if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
    1.39 +                return;
    1.40 +            if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
    1.41 +                return;
    1.42 +        }
    1.43 +
    1.44          // If the node already has a symbol (meaning it was a global), then
    1.45          // we don't have to do anything more.
    1.46          if (node->sym()) {
    1.47 @@ -817,15 +834,17 @@
    1.48          return true;
    1.49      }
    1.50  
    1.51 -    ArrayType *buildArrayType(Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
    1.52 +    ArrayType *buildArrayType(Handle<Type> contained, TypeQualifiers quals, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
    1.53          Local<Type> type(zone_, contained);
    1.54 +
    1.55          for (size_t i = postlevels - 1; i < postlevels; i--) {
    1.56              int size = dims[i] > 0
    1.57                         ? dims[i]
    1.58                         : ArrayType::DYNAMIC_ARRAY_SIZE;
    1.59              
    1.60 -            type = zone_->types()->newArray(contained, size);
    1.61 -            if (!type)
    1.62 +            if ((type = zone_->types()->newArray(contained, size)) == NULL)
    1.63 +                return NULL;
    1.64 +            if ((type = zone_->types()->qualify(type, quals)) == NULL)
    1.65                  return NULL;
    1.66          }
    1.67          return ArrayType::cast(type);
    1.68 @@ -834,7 +853,7 @@
    1.69      bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
    1.70          Local<Type> type(zone_);
    1.71          if (!fun->returnType()) {
    1.72 -            if ((type = bindType(sig.returnType())) == NULL)
    1.73 +            if ((type = bindType(sig.returnType(), TypeQual_None)) == NULL)
    1.74                  return false;
    1.75              fun->setReturnType(type);
    1.76          }
    1.77 @@ -845,10 +864,12 @@
    1.78  
    1.79          for (size_t i = 0; i < sig.parameters()->length(); i++) {
    1.80              Parameter *param = sig.parameters()->at(i);
    1.81 -            if ((type = bindType(param->type())) == NULL)
    1.82 +            if ((type = bindType(param->type(), param->quals())) == NULL)
    1.83                  return false;
    1.84  
    1.85 -            if (type->isArray() || param->dims()) {
    1.86 +            assert(!type->isArray());
    1.87 +
    1.88 +            if (param->dims()) {
    1.89                  int dims[MAX_ARRAY_DEPTH];
    1.90                  int levels = evaluateDimensions(param->pos(), type, param->dims(), dims);
    1.91                  if (levels < 0)
    1.92 @@ -858,7 +879,7 @@
    1.93                  // Unlike variables, we do not infer anything about array
    1.94                  // sizes from its default initializer.
    1.95                  if (param->dims()) {
    1.96 -                    if ((type = buildArrayType(type, dims, param->dims()->length())) == NULL)
    1.97 +                    if ((type = buildArrayType(type, param->quals(), dims, param->dims()->length())) == NULL)
    1.98                          return false;
    1.99                  }
   1.100  
   1.101 @@ -873,9 +894,19 @@
   1.102                      cc_.reportError(param->pos(), Message_ArrayCantBeReference);
   1.103                      return false;
   1.104                  }
   1.105 +                if (param->quals() & TypeQual_Const) {
   1.106 +                    cc_.reportError(param->pos(), Message_CannotConstReference);
   1.107 +                    return false;
   1.108 +                }
   1.109                  if ((type = zone_->types()->getReference(type, false)) == NULL)
   1.110                      return false;
   1.111              }
   1.112 +            if (param->quals() & TypeQual_Const) {
   1.113 +                if (!type->isArray() && !type->isStruct()) {
   1.114 +                    cc_.reportError(param->pos(), Message_InvalidConstOnFormal);
   1.115 +                    return false;
   1.116 +                }
   1.117 +            }
   1.118  
   1.119              if (type->isVoid()) {
   1.120                  cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   1.121 @@ -891,27 +922,31 @@
   1.122          return true;
   1.123      }
   1.124  
   1.125 -    Type *bindType(Expression *expr) {
   1.126 +    Type *bindType(Expression *expr, TypeQualifiers quals) {
   1.127 +        Local<Type> type(zone_);
   1.128 +
   1.129          if (!expr) {
   1.130              // If no type was declared, we return int32.
   1.131 -            return zone_->types()->getPrimitive(PrimitiveType_Int32);
   1.132 -        }
   1.133 -        
   1.134 -        expr->accept(this);
   1.135 +            type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   1.136 +        } else {
   1.137 +            expr->accept(this);
   1.138  
   1.139 -        NameProxy *proxy = expr->asNameProxy();
   1.140 -        assert(proxy);
   1.141 +            NameProxy *proxy = expr->asNameProxy();
   1.142 +            assert(proxy);
   1.143  
   1.144 -        Symbol *sym = proxy->sym();
   1.145 -        if (!sym)
   1.146 -            return NULL;
   1.147 +            Symbol *sym = proxy->sym();
   1.148 +            if (!sym)
   1.149 +                return NULL;
   1.150  
   1.151 -        if (!sym->isType()) {
   1.152 -            cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
   1.153 -            return NULL;
   1.154 +            if (!sym->isType()) {
   1.155 +                cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
   1.156 +                return NULL;
   1.157 +            }
   1.158 +
   1.159 +            type = sym->type();
   1.160          }
   1.161  
   1.162 -        return sym->type();
   1.163 +        return zone_->types()->qualify(type, quals);
   1.164      }
   1.165  
   1.166    private: