Type * TypeCheck::visit(Declarator *ast) { FUNCLOG; assert(ast->type); if (ast->type->is(Type::VOID_T)) { SEMANTIC_ERROR(SE_VOID_DECL); } if (!ast->ptrs.empty()) { ast->type = makePointerType(ast->ptrs, ast->type); } if (ast->subDecl) { ast->subDecl->type = ast->type; ast->subDecl->accept(this); } else if (ast->declId) { if (ast->declId->scope) { //TODO: } Symbol *sym = Symbol::symbol(ast->declId->id->toSource()); if (!SymbolTable.addVar(ast->type, sym)) { SEMANTIC_ERROR(SE_DUPLICATE_SYMBOL); } } return ast->type; }
IHqlExpression * convertAddressToValue(IHqlExpression * address, ITypeInfo * columnType) { if (isTypePassedByAddress(columnType) && !columnType->isReference()) { Owned<ITypeInfo> refType = makeReferenceModifier(LINK(columnType)); assertex(address->getOperator() == no_externalcall || refType == address->queryType()); return createValue(no_implicitcast, LINK(refType), LINK(address)); } Owned<ITypeInfo> pointerType = makePointerType(LINK(columnType)); assertex(address->getOperator() == no_externalcall || pointerType == address->queryType()); IHqlExpression * temp = createValue(no_implicitcast, LINK(pointerType), LINK(address)); return createValue(no_deref, LINK(columnType), temp); }
Type * TypeCheck::visit(ArrayDeclarator *ast) { FUNCLOG; assert(ast->type); if (!ast->ptrs.empty()) { ast->type = makePointerType(ast->ptrs, ast->type); } ArrayType *arrayType; if (ast->constExp) { Type *indexType = ast->constExp->accept(this); if (!indexType->is(Type::INT_T)) { SEMANTIC_ERROR(SE_ARRAY_SIZE_NOT_CONST); } evaluator.init(); const int size = ast->constExp->accept(&evaluator); if (evaluator.isConstant()) { arrayType = new ArrayType(ast->type, size); } else { SEMANTIC_ERROR(SE_ARRAY_SIZE_NOT_CONST); } } else { arrayType = new ArrayType(ast->type, 0); } if (ast->next) { ast->next->type = arrayType; ast->next->accept(this); } if (ast->subDecl) { assert(0); //ast->subDecl->accept(this); } else if (ast->declId) { if (ast->declId->scope) { //TODO: } Symbol *sym = Symbol::symbol(ast->declId->id->toSource()); if (!SymbolTable.addVar(arrayType, sym)) { SEMANTIC_ERROR(SE_DUPLICATE_SYMBOL); } } ast->type = arrayType; return ast->type; }
Type * TypeCheck::visit(FunctionDeclarator *ast) { FUNCLOG; //In case of ctor, return type is null. Type *returnType = ast->type; if (!ast->ptrs.empty()) { returnType = makePointerType(ast->ptrs, returnType); } Symbol *funcName = ast->symbolName(); FuncType *funcType = new FuncType(funcName, returnType); SymbolTable.enterScope(SymbolTable::FUNCTION, funcName); if (ast->paramDecls) { ParameterDeclarationList *list = ast->paramDecls; List<ParameterDeclaration*>::iterator it = list->paramDecls.begin(); while (it != list->paramDecls.end()) { ParameterDeclaration *paramDecl = *it; Type *paramType = paramDecl->accept(this); assert(paramType); funcType->args.list.push_back(paramType); ++it; } } SymbolTable.updateScope(SymbolTable.currentScope, funcType->genMangledSymbol()); SymbolTable.leaveScope(); if (ast->subDecl) { ast->subDecl->type = funcType; ast->subDecl->accept(this); ast->type = ast->subDecl->type; } else if (ast->declId) { if (ast->declId->scope) { //TODO: } //function name is added to outer scope Type *preDeclared = NULL; if (!SymbolTable.addVar(funcType, funcType->name, false, &preDeclared)) { //already declared if (preDeclared->is(Type::FUNC_T)) { FuncType *ft = preDeclared->as<FuncType>(); //ft->mergeParams(funcType); ast->type = ft; return ast->type; } SEMANTIC_ERROR(SE_DUPLICATE_SYMBOL); } else { ast->type = funcType; } } if (ast->cvQuals) { Type *t = ast->cvQuals->accept(this); assert(t->isReadonly()); funcType->readonly(true); } return ast->type; }