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: