bool PgSQLType::canCastTo(PgSQLType type) { // If the types are the same of belongs to the same category they naturally can be casted if(this->type_idx==type.type_idx || (isCharacterType() && type.isCharacterType()) || (isDateTimeType() && type.isDateTimeType()) || (isNumericType() && type.isNumericType()) || (isNetworkType() && type.isNetworkType()) || //Polymorphics anyarray, anyrange, anynoarray, anyenum to anyelement ((isPolymorphicType() && type==QString("anyelement")) || ((*this)==QString("anyelement") && type.isPolymorphicType())) || //Character to network address ((isCharacterType() || isNetworkType()) && (type.isCharacterType() || type.isNetworkType())) || //Integer to OID ((isIntegerType() || isOIDType()) && (type.isIntegerType() || type.isOIDType())) || //abstime to integer ((((*this)==QString("integer") || (*this)==QString("int4")) && type==QString("abstime")) || (((*this)==QString("abstime") && (type==QString("integer") || type==QString("int4")))))) return(true); return(false); }
// FIXME: add support for derived types. // FIXME: check default character kind. bool Sema::CheckEquivalenceType(QualType ExpectedType, const Expr *E) { auto ObjectType = E->getType(); if(ObjectType->isArrayType()) ObjectType = ObjectType->asArrayType()->getElementType(); if(ExpectedType->isCharacterType()) { if(!ObjectType->isCharacterType()) { Diags.Report(E->getLocation(), diag::err_typecheck_expected_char_expr) << ObjectType << E->getSourceRange(); return true; } } else if(ExpectedType->isBuiltinType()) { if(IsDefaultBuiltinOrDoublePrecisionType(ExpectedType)) { if(!IsDefaultBuiltinOrDoublePrecisionType(ObjectType)) { Diags.Report(E->getLocation(), diag::err_typecheck_expected_default_kind_expr) << ObjectType << E->getSourceRange(); return true; } } else { if(!AreTypesOfSameKind(ExpectedType, ObjectType)) { Diags.Report(E->getLocation(), diag::err_typecheck_expected_expr_of_type) << ExpectedType << ObjectType << E->getSourceRange(); return true; } } } return false; }
ExprResult DataStmtEngine::getAndCheckAnyValue(QualType LHSType, const Expr *LHS) { auto Val = getAndCheckValue(LHSType, LHS); auto ET = LHSType.getSelfOrArrayElementType(); if(ET->isCharacterType() && Val.isUsable()) { assert(isa<CharacterConstantExpr>(Val.get())); return cast<CharacterConstantExpr>(Val.get())->CreateCopyWithCompatibleLength(Context, ET); } return Val; }
/// ParseDesignator - Parse a designator. Return null if current token is not a /// designator. /// /// [R601]: /// designator := /// object-name /// or array-element /// or array-section /// or coindexed-named-object /// or complex-part-designator /// or structure-component /// or substring /// /// FIXME: substring for a character array ExprResult Parser::ParseDesignator(bool IsLvalue) { auto E = ParseNameOrCall(); struct ScopedFlag { bool value; bool &dest; ScopedFlag(bool &flag) : dest(flag) { value = flag; } ~ScopedFlag() { dest = value; } }; ScopedFlag Flag(DontResolveIdentifiers); if(DontResolveIdentifiersInSubExpressions) DontResolveIdentifiers = true; while(true) { if(!E.isUsable()) break; if(IsPresent(tok::l_paren)) { auto EType = E.get()->getType(); if(EType->isArrayType()) E = ParseArraySubscript(E); else if(EType->isCharacterType()) E = ParseSubstring(E); else { Diag.Report(Tok.getLocation(), diag::err_unexpected_lparen); return ExprError(); } } else if(IsPresent(tok::percent)) { auto EType = E.get()->getType(); if(EType->isRecordType()) E = ParseStructureComponent(E); else { Diag.Report(Tok.getLocation(), diag::err_unexpected_percent); return ExprError(); } } else if(IsPresent(tok::period)) { auto EType = E.get()->getType(); if(EType->isRecordType()) E = ParseStructureComponent(E); else { Diag.Report(Tok.getLocation(), diag::err_unexpected_period); return ExprError(); } } else break; } return E; }
RValueTy CodeGenFunction::EmitRValue(const Expr *E) { auto EType = E->getType(); if(EType->isComplexType()) return EmitComplexExpr(E); else if(EType->isCharacterType()) return EmitCharacterExpr(E); else if(EType->isLogicalType()) return EmitLogicalValueExpr(E); else if(EType->isRecordType()) return EmitAggregateExpr(E); else return EmitScalarExpr(E); }
llvm::Constant *CodeGenFunction::EmitConstantExpr(const Expr *E) { auto T = E->getType(); if(T->isComplexType()) return CreateComplexConstant(EmitComplexExpr(E)); else if(T->isCharacterType()) //FIXME ;//;return CreateCharacterConstant(EmitCharacterExpr(E)); else if(T->isLogicalType()) return cast<llvm::Constant>(EmitLogicalValueExpr(E)); else if(T->isArrayType()) return EmitConstantArrayExpr(dyn_cast<ArrayConstructorExpr>(E)); else return cast<llvm::Constant>(EmitScalarExpr(E)); }
Decl *Sema::ActOnEntityDecl(ASTContext &C, const QualType &T, SourceLocation IDLoc, const IdentifierInfo *IDInfo) { auto Quals = T.getQualifiers(); if(Quals.hasAttributeSpec(Qualifiers::AS_external)) return ActOnExternalEntityDecl(C, T, IDLoc, IDInfo); else if(Quals.hasAttributeSpec(Qualifiers::AS_intrinsic)) return ActOnIntrinsicEntityDecl(C, T, IDLoc, IDInfo); if (auto Prev = LookupIdentifier(IDInfo)) { FunctionDecl *FD = dyn_cast<FunctionDecl>(Prev); if(auto VD = dyn_cast<VarDecl>(Prev)) { if(VD->isArgument() && VD->getType().isNull()) { VD->setType(T); return VD; } else if(VD->isFunctionResult()) FD = CurrentContextAsFunction(); } if(FD && (FD->isNormalFunction() || FD->isExternal())) { if(FD->getType().isNull() || FD->getType()->isVoidType()) { SetFunctionType(FD, T, IDLoc, SourceRange()); //Fixme: proper loc and range return FD; } else { Diags.Report(IDLoc, diag::err_func_return_type_already_specified) << IDInfo; return nullptr; } } Diags.Report(IDLoc, diag::err_redefinition) << IDInfo; Diags.Report(Prev->getLocation(), diag::note_previous_definition); return nullptr; } VarDecl *VD = VarDecl::Create(C, CurContext, IDLoc, IDInfo, T); CurContext->addDecl(VD); if(!T.isNull()) { auto SubT = T; if(T->isArrayType()) { CheckArrayTypeDeclarationCompability(T->asArrayType(), VD); SubT = T->asArrayType()->getElementType(); VD->MarkUsedAsVariable(IDLoc); } else if(SubT->isCharacterType()) CheckCharacterLengthDeclarationCompability(SubT, VD); } return VD; }