void ContextBuilder::addBaseType( KDevelop::BaseClassInstance base, BaseSpecifierAST *node ) { DUChainWriteLocker lock(DUChain::lock()); addImportedContexts(); //Make sure the template-contexts are imported first, before any parent-class contexts. Q_ASSERT(currentContext()->type() == DUContext::Class); AbstractType::Ptr baseClass = base.baseClass.abstractType(); IdentifiedType* idType = dynamic_cast<IdentifiedType*>(baseClass.unsafeData()); Declaration* idDecl = 0; if( idType && (idDecl = idType->declaration(currentContext()->topContext())) ) { DUContext* ctx = idDecl->logicalInternalContext(currentContext()->topContext()); if(ctx) { currentContext()->addImportedParentContext( ctx ); }else{ currentContext()->addIndirectImport( DUContext::Import(idType->declarationId()) ); QString text = i18n("Could not resolve base class, adding it indirectly: %1", (base.baseClass ? base.baseClass.abstractType()->toString() : QString())); lock.unlock(); createUserProblem(node, text); } } else if( !baseClass.cast<DelayedType>() ) { QString text = i18n("Invalid base class: %1", (base.baseClass ? base.baseClass.abstractType()->toString() : QString())); lock.unlock(); createUserProblem(node, text); } }
AbstractType::Ptr binaryOperatorReturnType(AbstractType::Ptr left, AbstractType::Ptr right, int tokenKind) { if(!left || !right) return AbstractType::Ptr(); IntegralType* leftIntegral = dynamic_cast<IntegralType*>(left.unsafeData()); IntegralType* rightIntegral = dynamic_cast<IntegralType*>(right.unsafeData()); PointerType* leftPointer = dynamic_cast<PointerType*>(right.unsafeData()); AbstractType::Ptr ret; //Constantly evaluate integral expressions ConstantIntegralType* leftConstantIntegral = dynamic_cast<ConstantIntegralType*>(left.unsafeData()); ConstantIntegralType* rightConstantIntegral = dynamic_cast<ConstantIntegralType*>(right.unsafeData()); if(leftIntegral && rightIntegral) { if(tokenKind == '+' || tokenKind == '-' || tokenKind == '*' || tokenKind == '/' || tokenKind == '%' || tokenKind == '^' || tokenKind == '&' || tokenKind == '|' || tokenKind == '~' || tokenKind == Token_shift) { if(moreExpressiveThan(leftIntegral, rightIntegral)) ret = left; else ret = right; } if(tokenKind == '<' || tokenKind == '>' || tokenKind == Token_eq || tokenKind == Token_not_eq || tokenKind == Token_leq || tokenKind == Token_geq || tokenKind == Token_not_eq || tokenKind == Token_and || tokenKind == Token_or) ret = AbstractType::Ptr(new IntegralType(IntegralType::TypeBoolean)); } if(leftPointer && rightIntegral && (tokenKind == '+' || tokenKind == '-')) ret = left; IntegralType* retIntegral = dynamic_cast<IntegralType*>(ret.unsafeData()); ///We have determined the resulting type now. If both sides are constant, also evaluate the resulting value. if(ret && retIntegral && leftConstantIntegral && rightConstantIntegral) { switch( retIntegral->dataType() ) { case IntegralType::TypeFloat: { ConstantBinaryExpressionEvaluator<float> evaluator( retIntegral->dataType(), retIntegral->modifiers(), tokenKind, leftConstantIntegral, rightConstantIntegral ); return evaluator.createType(); } case IntegralType::TypeDouble: { ConstantBinaryExpressionEvaluator<double> evaluator( retIntegral->dataType(), retIntegral->modifiers(), tokenKind, leftConstantIntegral, rightConstantIntegral ); return evaluator.createType(); } default: if( leftConstantIntegral->modifiers() & AbstractType::UnsignedModifier ) { ConstantBinaryExpressionEvaluator<quint64> evaluator( retIntegral->dataType(), retIntegral->modifiers(), tokenKind, leftConstantIntegral, rightConstantIntegral); return evaluator.createType(); } else { ConstantBinaryExpressionEvaluator<qint64> evaluator( retIntegral->dataType(), retIntegral->modifiers(), tokenKind, leftConstantIntegral, rightConstantIntegral); return evaluator.createType(); } break; } } return ret; }