void DeclarationBuilder::visitAliasStatement(Ast *node) { Ast *right = new Ast(node->tree->r, node->context); QualifiedIdentifier id = QualifiedIdentifier(QString(right->tree->name)); const RangeInRevision &range = editorFindRange(right, right); DeclarationPointer decl = getDeclaration(id, range, DUContextPointer(currentContext())); if (is_global_var(node->tree->l) && is_global_var(right->tree)) { DUChainWriteLocker wlock; // If the global variable on the right is not declared, declare it as nil if (!decl) { AbstractType::Ptr type = topContext()->findDeclarations(QualifiedIdentifier("NilClass")).first()->abstractType(); VariableDeclaration *vDecl = openDefinition<VariableDeclaration>(id, range); vDecl->setVariableKind(right->tree); vDecl->setKind(Declaration::Instance); vDecl->setType(type); eventuallyAssignInternalContext(); DeclarationBuilderBase::closeDeclaration(); decl = vDecl; } node->tree = node->tree->l; QualifiedIdentifier aid = getIdentifier(node); AbstractType::Ptr type = decl->abstractType(); declareVariable(aid, type, node); } else if (decl && decl->isFunctionDeclaration()) { DUChainWriteLocker wlock; MethodDeclaration *md = dynamic_cast<MethodDeclaration *>(decl.data()); node->tree = node->tree->l; const RangeInRevision & arange = editorFindRange(node, node); QualifiedIdentifier aid = getIdentifier(node); aliasMethodDeclaration(aid, arange, md); } else appendProblem(node->tree, i18n("undefined method `%1'", id.toString())); }
size_t UnionDeclaration::getSize() const { size_t sz = 0; VariableDeclaration *vd; for(int i = 0; i < members.size(); i++){ vd = members[i]->variableDeclaration(); if(vd->getType()->getSize() > sz) sz = vd->getType()->getSize(); } return sz; }
Statement *TypeCompiler::visit(VariableStatement *statement) { for (unsigned int i = 0; i < statement->declarations->size(); i++) { VariableDeclaration *d = statement->declarations->at(i); d->visitExpression(this); } return statement; }
void ParserTest::parsePositioning() { CREATE_PARSER(par); VariableDeclaration var; par >> var; QFETCH(int, start); QCOMPARE(var.startPos(), start); QFETCH(int, end); QCOMPARE(var.endPos(), end); }
void ParserTest::parseVariableDeclaration() { CREATE_PARSER( par ); VariableDeclaration var; par >> var; COMPARE_STRING(var.type().name(), "NSData***"); QCOMPARE((int)var.type().starNumber(), 3); QTRUE(var.type().isPointer()); COMPARE_STRING(var.objectName(), "data"); }
Expression *TypeCompiler::visit(VariableExpression *expression) { for (UTsize i = 0; i < expression->declarations->size(); i++) { VariableDeclaration *v = expression->declarations->at(i); v->visitExpression(this); expression->e = v->identifier->e; } return expression; }
bool ASTPrinter::visit(VariableDeclaration const& _node) { writeLine("VariableDeclaration \"" + _node.name() + "\""); *m_ostream << indentation() << ( _node.annotation().type ? string(" Type: ") + _node.annotation().type->toString() : string(" Type unknown.") ) << "\n"; printSourcePart(_node); return goDeeper(); }
size_t UserTypeDeclaration::getAlign() const { size_t align = 0; VariableDeclaration *vd; for(int i = 0; i < members.size(); i++){ vd = members[i]->variableDeclaration(); assert(vd && "expected variable decl, found something else"); if(vd->getType()->getAlign() > align) align = vd->getType()->getAlign(); } if(align == 0) return 1; // TODO: empty struct, bad! return align; //TODO: handle packed }
size_t StructDeclaration::getSize() const { size_t sz = 0; VariableDeclaration *vd; unsigned align; for(int i = 0; i < members.size(); i++) { vd = members[i]->variableDeclaration(); if(!vd) continue; align = vd->getType()->getAlign(); if(!packed && sz % align) sz += (align - (sz % align)); sz += vd->type->getSize(); } return sz; }
void DeclarationBuilder::visitExprMax(ExprMaxAst* node) { if (node->var) { SimpleRange range = editorFindRange(node->var, node->var); VariableDeclaration *dec = openDeclaration<VariableDeclaration>(identifierForNode(node->var), range); dec->setKind(Declaration::Instance); eventuallyAssignInternalContext(); closeDeclaration(); } else { DeclarationBuilderBase::visitExprMax(node); } }
size_t ClassDeclaration::getSize() const { size_t sz = base ? base->getDeclaredType()->getSize() : 0; VariableDeclaration *vd; unsigned align = base ? 8 : 1; //TODO: proper padding past base? if(sz % align) sz += (align - (sz % align)); for(int i = 0; i < members.size(); i++) { vd = members[i]->variableDeclaration(); if(!vd) continue; align = vd->getType()->getAlign(); if(sz % align) sz += (align - (sz % align)); //reference types treated as pointers if(vd->getType()->isReference()) sz += 8; else sz += vd->type->getSize(); } return sz; }
void CompilerContext::addAndInitializeVariable(VariableDeclaration const& _declaration) { addVariable(_declaration); unsigned const size = _declaration.getType()->getSizeOnStack(); for (unsigned i = 0; i < size; ++i) *this << u256(0); m_asm.adjustDeposit(-size); }
const GLuint Program::uniformLocation(const VariableDeclaration& u) const { auto it = handles_.uniforms.find(u); if(it == handles_.uniforms.end()) { std::cerr << u.name() << std::endl; throw Exception("unknown uniform"); } else { return it->second; } }
bool Compiler::visit(VariableDeclaration const& _variableDeclaration) { solAssert(_variableDeclaration.isStateVariable(), "Compiler visit to non-state variable declaration."); CompilerContext::LocationSetter locationSetter(m_context, _variableDeclaration); m_context.startFunction(_variableDeclaration); m_breakTags.clear(); m_continueTags.clear(); ExpressionCompiler(m_context, m_optimize).appendStateVariableAccessor(_variableDeclaration); return false; }
StackVariable::StackVariable(CompilerContext& _compilerContext, VariableDeclaration const& _declaration): LValue(_compilerContext, _declaration.annotation().type.get()), m_baseStackOffset(m_context.baseStackOffsetOfVariable(_declaration)), m_size(m_dataType->sizeOnStack()) { }
StorageItem::StorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration): StorageItem(_compilerContext, *_declaration.annotation().type) { auto const& location = m_context.storageLocationOfVariable(_declaration); m_context << location.first << u256(location.second); }
bool ASTPrinter::visit(VariableDeclaration const& _node) { writeLine("VariableDeclaration \"" + _node.getName() + "\""); printSourcePart(_node); return goDeeper(); }
void Compiler::appendStackVariableInitialisation(VariableDeclaration const& _variable) { CompilerContext::LocationSetter location(m_context, _variable); m_context.addVariable(_variable); CompilerUtils(m_context).pushZeroValue(*_variable.getType()); }
void CompilerContext::addStateVariable(VariableDeclaration const& _declaration) { m_stateVariables[&_declaration] = m_stateVariablesSize; m_stateVariablesSize += _declaration.getType()->getStorageSize(); }
void CompilerContext::addVariable(VariableDeclaration const& _declaration) { m_localVariables[&_declaration] = m_localVariablesSize; m_localVariablesSize += _declaration.getType()->getSizeOnStack(); }
Method* addDivBySix(Model::Model* model, Class* parent) { Method* divbysix = nullptr; if (!parent) divbysix = dynamic_cast<Method*> (model->createRoot("Method")); model->beginModification(parent? static_cast<Model::Node*> (parent) : divbysix, "Adding a divBySix method."); if (!divbysix) { divbysix = new Method(); parent->methods()->append(divbysix); } divbysix->setName("findDivBySix"); FormalResult* divbysixResult = new FormalResult(); divbysixResult->setType(new PrimitiveType(PrimitiveType::INT)); divbysix->results()->append(divbysixResult); FormalArgument* arg = new FormalArgument(); divbysix->arguments()->append(arg); arg->setName("numbers"); ArrayType* argType = new ArrayType(); argType->setType(new PrimitiveType(PrimitiveType::INT)); arg->setType(argType); ExpressionStatement* es = new ExpressionStatement(); es->setExpression( new EmptyExpression()); divbysix->items()->append(es); VariableDeclaration* exprtest = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest)); exprtest->setName("exprtest"); exprtest->setType(new PrimitiveType(PrimitiveType::INT)); exprtest->setInitialValue( OOExpressionBuilder::getOOExpression("+aa++&b,*e/d-#") ); VariableDeclaration* exprtest2 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest2)); exprtest2->setName("exprtest2"); exprtest2->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest2->setInitialValue( OOExpressionBuilder::getOOExpression("a*b+c/e-d++%--e*-f==g") ); VariableDeclaration* exprtest3 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest3)); exprtest3->setName("exprtest3"); exprtest3->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest3->setInitialValue( OOExpressionBuilder::getOOExpression("a<b||c>d&&e<=f|g&h^~i") ); VariableDeclaration* exprtest4 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest4)); exprtest4->setName("exprtest4"); exprtest4->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest4->setInitialValue( OOExpressionBuilder::getOOExpression("new value[5]") ); VariableDeclaration* exprtest5 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest5)); exprtest5->setName("exprtest5"); exprtest5->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest5->setInitialValue( OOExpressionBuilder::getOOExpression("(castto)object") ); VariableDeclaration* exprtest6 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest6)); exprtest6->setName("exprtest6"); exprtest6->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest6->setInitialValue( OOExpressionBuilder::getOOExpression("{a,bb,ccc}") ); VariableDeclaration* exprtest7 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest7)); exprtest7->setName("exprtest7"); exprtest7->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest7->setInitialValue( OOExpressionBuilder::getOOExpression("{{123,hello},{2,b}}") ); VariableDeclaration* exprtest8 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest8)); exprtest8->setName("exprtest8"); exprtest8->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest8->setInitialValue( OOExpressionBuilder::getOOExpression("a.b+c.d[i].f") ); VariableDeclaration* exprtest9 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest9)); exprtest9->setName("exprtest9"); exprtest9->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest9->setInitialValue( OOExpressionBuilder::getOOExpression("a()+a.b()+a.b[i].f().g()") ); VariableDeclaration* exprtest10 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest10)); exprtest10->setName("exprtest10"); exprtest10->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest10->setInitialValue( OOExpressionBuilder::getOOExpression("this.b(a,b,c,123,false)") ); VariableDeclaration* exprtest11 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest11)); exprtest11->setName("exprtest11"); exprtest11->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest11->setInitialValue( OOExpressionBuilder::getOOExpression("a+\"hello world\"") ); VariableDeclaration* exprtest12 = new VariableDeclaration(); divbysix->items()->append(new ExpressionStatement(exprtest12)); exprtest12->setName("exprtest12"); exprtest12->setType(new PrimitiveType(PrimitiveType::VOID)); exprtest12->setInitialValue( OOExpressionBuilder::getOOExpression("int[]") ); auto exprtest13 = dynamic_cast<AssignmentExpression*>( OOExpressionBuilder::getOOExpression("a=b%=c>>>=d+C")); divbysix->items()->append(new ExpressionStatement(exprtest13)); divbysix->items()->append(new ExpressionStatement( OOExpressionBuilder::getOOExpression("int abc"))); divbysix->items()->append(new ExpressionStatement( OOExpressionBuilder::getOOExpression("int abc=5+3"))); divbysix->items()->append(new ExpressionStatement( OOExpressionBuilder::getOOExpression("int cond=abc<50?42:b+c"))); VariableDeclaration* result = new VariableDeclaration(); divbysix->items()->append( new ExpressionStatement(result) ); result->setName("result"); result->setType(new PrimitiveType(PrimitiveType::INT)); result->setInitialValue(new IntegerLiteral(-1)); LoopStatement* sixloop = new LoopStatement(); divbysix->items()->append(sixloop); VariableDeclaration* sixLoopInit = new VariableDeclaration(); sixloop->setInitStep(sixLoopInit); sixLoopInit->setName("i"); sixLoopInit->setType(new PrimitiveType(PrimitiveType::INT)); sixLoopInit->setInitialValue(new IntegerLiteral(0)); BinaryOperation* sixLoopCond = new BinaryOperation(); sixloop->setCondition(sixLoopCond); sixLoopCond->setLeft(new VariableAccess("local:i")); sixLoopCond->setOp(BinaryOperation::LESS); MethodCallExpression* sizeCall = new MethodCallExpression(); sixLoopCond->setRight(sizeCall); sizeCall->ref()->set("size"); sizeCall->setPrefix(new VariableAccess("local:numbers")); //TODO test the visualization without the remaining parts of this method AssignmentExpression* sixLoopUpdate = new AssignmentExpression(); sixloop->setUpdateStep(sixLoopUpdate); sixLoopUpdate->setLeft(new VariableAccess("local:i")); sixLoopUpdate->setOp(AssignmentExpression::PLUS_ASSIGN); sixLoopUpdate->setRight(new IntegerLiteral(1)); VariableDeclaration* n = new VariableDeclaration(); sixloop->body()->append(new ExpressionStatement(n)); n->setName("n"); n->setType(new PrimitiveType(PrimitiveType::INT)); BinaryOperation* item = new BinaryOperation(); n->setInitialValue(item); item->setLeft(new VariableAccess("local:numbers")); item->setOp(BinaryOperation::ARRAY_INDEX); item->setRight(new VariableAccess("local:i")); IfStatement* ifdiv2 = new IfStatement(); sixloop->body()->append(ifdiv2); BinaryOperation* eq0 = new BinaryOperation(); ifdiv2->setCondition(eq0); eq0->setOp(BinaryOperation::EQUALS); eq0->setRight(new IntegerLiteral(0)); BinaryOperation* div2 = new BinaryOperation(); eq0->setLeft(div2); div2->setLeft(new VariableAccess("local:n")); div2->setOp(BinaryOperation::REMAINDER); div2->setRight(new IntegerLiteral(2)); ifdiv2->elseBranch()->append(new ContinueStatement()); IfStatement* ifdiv3 = new IfStatement(); ifdiv2->thenBranch()->append(ifdiv3); eq0 = new BinaryOperation(); ifdiv3->setCondition(eq0); eq0->setOp(BinaryOperation::EQUALS); eq0->setRight(new IntegerLiteral(0)); BinaryOperation* div3 = new BinaryOperation(); eq0->setLeft(div3); div3->setLeft(new VariableAccess("local:n")); div3->setOp(BinaryOperation::REMAINDER); div3->setRight(new IntegerLiteral(3)); AssignmentExpression* resultFound = new AssignmentExpression(); ifdiv3->thenBranch()->append(resultFound); resultFound->setLeft(new VariableAccess("local:result")); resultFound->setOp(AssignmentExpression::ASSIGN); resultFound->setRight(new VariableAccess("local:i")); ifdiv3->thenBranch()->append(new BreakStatement()); ReturnStatement* divbysixReturn = new ReturnStatement(); divbysixReturn->values()->append(new VariableAccess("local:result")); divbysix->items()->append(divbysixReturn); model->endModification(); return divbysix; }
void ReferencesResolver::endVisit(VariableDeclaration const& _variable) { if (_variable.annotation().type) return; TypePointer type; if (_variable.typeName()) { type = _variable.typeName()->annotation().type; using Location = VariableDeclaration::Location; Location varLoc = _variable.referenceLocation(); DataLocation typeLoc = DataLocation::Memory; // References are forced to calldata for external function parameters (not return) // and memory for parameters (also return) of publicly visible functions. // They default to memory for function parameters and storage for local variables. // As an exception, "storage" is allowed for library functions. if (auto ref = dynamic_cast<ReferenceType const*>(type.get())) { bool isPointer = true; if (_variable.isExternalCallableParameter()) { auto const& contract = dynamic_cast<ContractDefinition const&>(*_variable.scope()->scope()); if (contract.isLibrary()) { if (varLoc == Location::Memory) fatalTypeError(_variable.location(), "Location has to be calldata or storage for external " "library functions (remove the \"memory\" keyword)." ); } else { // force location of external function parameters (not return) to calldata if (varLoc != Location::Default) fatalTypeError(_variable.location(), "Location has to be calldata for external functions " "(remove the \"memory\" or \"storage\" keyword)." ); } if (varLoc == Location::Default) typeLoc = DataLocation::CallData; else typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage; } else if (_variable.isCallableParameter() && _variable.scope()->isPublic()) { auto const& contract = dynamic_cast<ContractDefinition const&>(*_variable.scope()->scope()); // force locations of public or external function (return) parameters to memory if (varLoc == Location::Storage && !contract.isLibrary()) fatalTypeError(_variable.location(), "Location has to be memory for publicly visible functions " "(remove the \"storage\" keyword)." ); if (varLoc == Location::Default || !contract.isLibrary()) typeLoc = DataLocation::Memory; else typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage; } else { if (_variable.isConstant()) { if (varLoc != Location::Default && varLoc != Location::Memory) fatalTypeError( _variable.location(), "Storage location has to be \"memory\" (or unspecified) for constants." ); typeLoc = DataLocation::Memory; } else if (varLoc == Location::Default) typeLoc = _variable.isCallableParameter() ? DataLocation::Memory : DataLocation::Storage; else typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage; isPointer = !_variable.isStateVariable(); } type = ref->copyForLocation(typeLoc, isPointer); } else if (varLoc != Location::Default && !ref) fatalTypeError(_variable.location(), "Storage location can only be given for array or struct types."); if (!type) fatalTypeError(_variable.location(), "Invalid type name."); } else if (!_variable.canHaveAutoType()) fatalTypeError(_variable.location(), "Explicit type needed."); // otherwise we have a "var"-declaration whose type is resolved by the first assignment _variable.annotation().type = type; }
VariableDeclaration::VariableDeclaration(const VariableDeclaration &rhs) : KDevelop::Declaration(*new VariableDeclarationData(*rhs.d_func())) { }