QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const { switch (K) { case InvalidTy: assert(false && "No representative type for Invalid ArgTypeResult"); // Fall-through. case UnknownTy: return QualType(); case SpecificTy: return T; case CStrTy: return C.getPointerType(C.CharTy); case WCStrTy: return C.getPointerType(C.getWCharType()); case ObjCPointerTy: return C.ObjCBuiltinIdTy; case CPointerTy: return C.VoidPtrTy; case WIntTy: { QualType WC = C.getWCharType(); return WC->isPromotableIntegerType() ? C.getPromotedIntegerType(WC) : WC; } } // FIXME: Should be unreachable, but Clang is currently emitting // a warning. return QualType(); }
QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const { switch (K) { case InvalidTy: llvm_unreachable("No representative type for Invalid ArgTypeResult"); case UnknownTy: return QualType(); case AnyCharTy: return C.CharTy; case SpecificTy: return T; case CStrTy: return C.getPointerType(C.CharTy); case WCStrTy: return C.getPointerType(C.getWCharType()); case ObjCPointerTy: return C.ObjCBuiltinIdTy; case CPointerTy: return C.VoidPtrTy; case WIntTy: { return C.getWIntType(); } } llvm_unreachable("Invalid ArgTypeResult Kind!"); }
QualType ArgType::getRepresentativeType(ASTContext &C) const { QualType Res; switch (K) { case InvalidTy: llvm_unreachable("No representative type for Invalid ArgType"); case UnknownTy: llvm_unreachable("No representative type for Unknown ArgType"); case AnyCharTy: Res = C.CharTy; break; case SpecificTy: Res = T; break; case CStrTy: Res = C.getPointerType(C.CharTy); break; case WCStrTy: Res = C.getPointerType(C.getWCharType()); break; case ObjCPointerTy: Res = C.ObjCBuiltinIdTy; break; case CPointerTy: Res = C.VoidPtrTy; break; case WIntTy: { Res = C.getWIntType(); break; } } if (Ptr) Res = C.getPointerType(Res); return Res; }
QualType ScanfArgTypeResult::getRepresentativeType(ASTContext &C) const { switch (K) { case InvalidTy: llvm_unreachable("No representative type for Invalid ArgTypeResult"); case UnknownTy: return QualType(); case CStrTy: return C.getPointerType(C.CharTy); case WCStrTy: return C.getPointerType(C.getWCharType()); case PtrToArgTypeResultTy: return C.getPointerType(A.getRepresentativeType(C)); } llvm_unreachable("Invalid ScanfArgTypeResult Kind!"); }
ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { const ScanfConversionSpecifier &CS = getConversionSpecifier(); if (!CS.consumesDataArgument()) return ArgType::Invalid(); switch(CS.getKind()) { // Signed int. case ConversionSpecifier::dArg: case ConversionSpecifier::DArg: case ConversionSpecifier::iArg: switch (LM.getKind()) { case LengthModifier::None: return ArgType::PtrTo(Ctx.IntTy); case LengthModifier::AsChar: return ArgType::PtrTo(ArgType::AnyCharTy); case LengthModifier::AsShort: return ArgType::PtrTo(Ctx.ShortTy); case LengthModifier::AsLong: return ArgType::PtrTo(Ctx.LongTy); case LengthModifier::AsLongLong: case LengthModifier::AsQuad: return ArgType::PtrTo(Ctx.LongLongTy); case LengthModifier::AsIntMax: return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); case LengthModifier::AsSizeT: // FIXME: ssize_t. return ArgType(); case LengthModifier::AsPtrDiff: return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); case LengthModifier::AsLongDouble: // GNU extension. return ArgType::PtrTo(Ctx.LongLongTy); case LengthModifier::AsAllocate: return ArgType::Invalid(); case LengthModifier::AsMAllocate: return ArgType::Invalid(); } // Unsigned int. case ConversionSpecifier::oArg: case ConversionSpecifier::OArg: case ConversionSpecifier::uArg: case ConversionSpecifier::UArg: case ConversionSpecifier::xArg: case ConversionSpecifier::XArg: switch (LM.getKind()) { case LengthModifier::None: return ArgType::PtrTo(Ctx.UnsignedIntTy); case LengthModifier::AsChar: return ArgType::PtrTo(Ctx.UnsignedCharTy); case LengthModifier::AsShort: return ArgType::PtrTo(Ctx.UnsignedShortTy); case LengthModifier::AsLong: return ArgType::PtrTo(Ctx.UnsignedLongTy); case LengthModifier::AsLongLong: case LengthModifier::AsQuad: return ArgType::PtrTo(Ctx.UnsignedLongLongTy); case LengthModifier::AsIntMax: return ArgType::PtrTo(ArgType(Ctx.getUIntMaxType(), "uintmax_t")); case LengthModifier::AsSizeT: return ArgType::PtrTo(ArgType(Ctx.getSizeType(), "size_t")); case LengthModifier::AsPtrDiff: // FIXME: Unsigned version of ptrdiff_t? return ArgType(); case LengthModifier::AsLongDouble: // GNU extension. return ArgType::PtrTo(Ctx.UnsignedLongLongTy); case LengthModifier::AsAllocate: return ArgType::Invalid(); case LengthModifier::AsMAllocate: return ArgType::Invalid(); } // Float. case ConversionSpecifier::aArg: case ConversionSpecifier::AArg: case ConversionSpecifier::eArg: case ConversionSpecifier::EArg: case ConversionSpecifier::fArg: case ConversionSpecifier::FArg: case ConversionSpecifier::gArg: case ConversionSpecifier::GArg: switch (LM.getKind()) { case LengthModifier::None: return ArgType::PtrTo(Ctx.FloatTy); case LengthModifier::AsLong: return ArgType::PtrTo(Ctx.DoubleTy); case LengthModifier::AsLongDouble: return ArgType::PtrTo(Ctx.LongDoubleTy); default: return ArgType::Invalid(); } // Char, string and scanlist. case ConversionSpecifier::cArg: case ConversionSpecifier::sArg: case ConversionSpecifier::ScanListArg: switch (LM.getKind()) { case LengthModifier::None: return ArgType::PtrTo(ArgType::AnyCharTy); case LengthModifier::AsLong: return ArgType::PtrTo(ArgType(Ctx.getWCharType(), "wchar_t")); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: return ArgType::PtrTo(ArgType::CStrTy); default: return ArgType::Invalid(); } case ConversionSpecifier::CArg: case ConversionSpecifier::SArg: // FIXME: Mac OS X specific? switch (LM.getKind()) { case LengthModifier::None: return ArgType::PtrTo(ArgType(Ctx.getWCharType(), "wchar_t")); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: return ArgType::PtrTo(ArgType(ArgType::WCStrTy, "wchar_t *")); default: return ArgType::Invalid(); } // Pointer. case ConversionSpecifier::pArg: return ArgType::PtrTo(ArgType::CPointerTy); // Write-back. case ConversionSpecifier::nArg: switch (LM.getKind()) { case LengthModifier::None: return ArgType::PtrTo(Ctx.IntTy); case LengthModifier::AsChar: return ArgType::PtrTo(Ctx.SignedCharTy); case LengthModifier::AsShort: return ArgType::PtrTo(Ctx.ShortTy); case LengthModifier::AsLong: return ArgType::PtrTo(Ctx.LongTy); case LengthModifier::AsLongLong: case LengthModifier::AsQuad: return ArgType::PtrTo(Ctx.LongLongTy); case LengthModifier::AsIntMax: return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); case LengthModifier::AsSizeT: return ArgType(); // FIXME: ssize_t case LengthModifier::AsPtrDiff: return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); case LengthModifier::AsLongDouble: return ArgType(); // FIXME: Is this a known extension? case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: return ArgType::Invalid(); } default: break; } return ArgType(); }
bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const { switch (K) { case InvalidTy: llvm_unreachable("ArgTypeResult must be valid"); case UnknownTy: return true; case AnyCharTy: { if (const EnumType *ETy = argTy->getAs<EnumType>()) argTy = ETy->getDecl()->getIntegerType(); if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) switch (BT->getKind()) { default: break; case BuiltinType::Char_S: case BuiltinType::SChar: case BuiltinType::UChar: case BuiltinType::Char_U: return true; } return false; } case SpecificTy: { if (const EnumType *ETy = argTy->getAs<EnumType>()) argTy = ETy->getDecl()->getIntegerType(); argTy = C.getCanonicalType(argTy).getUnqualifiedType(); if (T == argTy) return true; // Check for "compatible types". if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) switch (BT->getKind()) { default: break; case BuiltinType::Char_S: case BuiltinType::SChar: case BuiltinType::Char_U: case BuiltinType::UChar: return T == C.UnsignedCharTy || T == C.SignedCharTy; case BuiltinType::Short: return T == C.UnsignedShortTy; case BuiltinType::UShort: return T == C.ShortTy; case BuiltinType::Int: return T == C.UnsignedIntTy; case BuiltinType::UInt: return T == C.IntTy; case BuiltinType::Long: return T == C.UnsignedLongTy; case BuiltinType::ULong: return T == C.LongTy; case BuiltinType::LongLong: return T == C.UnsignedLongLongTy; case BuiltinType::ULongLong: return T == C.LongLongTy; } return false; } case CStrTy: { const PointerType *PT = argTy->getAs<PointerType>(); if (!PT) return false; QualType pointeeTy = PT->getPointeeType(); if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) switch (BT->getKind()) { case BuiltinType::Void: case BuiltinType::Char_U: case BuiltinType::UChar: case BuiltinType::Char_S: case BuiltinType::SChar: return true; default: break; } return false; } case WCStrTy: { const PointerType *PT = argTy->getAs<PointerType>(); if (!PT) return false; QualType pointeeTy = C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); return pointeeTy == C.getWCharType(); } case WIntTy: { QualType PromoArg = argTy->isPromotableIntegerType() ? C.getPromotedIntegerType(argTy) : argTy; QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); // If the promoted argument is the corresponding signed type of the // wint_t type, then it should match. if (PromoArg->hasSignedIntegerRepresentation() && C.getCorrespondingUnsignedType(PromoArg) == WInt) return true; return WInt == PromoArg; } case CPointerTy: return argTy->isPointerType() || argTy->isObjCObjectPointerType() || argTy->isBlockPointerType() || argTy->isNullPtrType(); case ObjCPointerTy: { if (argTy->getAs<ObjCObjectPointerType>() || argTy->getAs<BlockPointerType>()) return true; // Handle implicit toll-free bridging. if (const PointerType *PT = argTy->getAs<PointerType>()) { // Things such as CFTypeRef are really just opaque pointers // to C structs representing CF types that can often be bridged // to Objective-C objects. Since the compiler doesn't know which // structs can be toll-free bridged, we just accept them all. QualType pointee = PT->getPointeeType(); if (pointee->getAsStructureType() || pointee->isVoidType()) return true; } return false; } } llvm_unreachable("Invalid ArgTypeResult Kind!"); }
bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const { switch (K) { case InvalidTy: assert(false && "ArgTypeResult must be valid"); return true; case UnknownTy: return true; case SpecificTy: { argTy = C.getCanonicalType(argTy).getUnqualifiedType(); if (T == argTy) return true; // Check for "compatible types". if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) switch (BT->getKind()) { default: break; case BuiltinType::Char_S: case BuiltinType::SChar: return T == C.UnsignedCharTy; case BuiltinType::Char_U: case BuiltinType::UChar: return T == C.SignedCharTy; case BuiltinType::Short: return T == C.UnsignedShortTy; case BuiltinType::UShort: return T == C.ShortTy; case BuiltinType::Int: return T == C.UnsignedIntTy; case BuiltinType::UInt: return T == C.IntTy; case BuiltinType::Long: return T == C.UnsignedLongTy; case BuiltinType::ULong: return T == C.LongTy; case BuiltinType::LongLong: return T == C.UnsignedLongLongTy; case BuiltinType::ULongLong: return T == C.LongLongTy; } return false; } case CStrTy: { const PointerType *PT = argTy->getAs<PointerType>(); if (!PT) return false; QualType pointeeTy = PT->getPointeeType(); if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) switch (BT->getKind()) { case BuiltinType::Void: case BuiltinType::Char_U: case BuiltinType::UChar: case BuiltinType::Char_S: case BuiltinType::SChar: return true; default: break; } return false; } case WCStrTy: { const PointerType *PT = argTy->getAs<PointerType>(); if (!PT) return false; QualType pointeeTy = C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); return pointeeTy == C.getWCharType(); } case WIntTy: { // Instead of doing a lookup for the definition of 'wint_t' (which // is defined by the system headers) instead see if wchar_t and // the argument type promote to the same type. QualType PromoWChar = C.getWCharType()->isPromotableIntegerType() ? C.getPromotedIntegerType(C.getWCharType()) : C.getWCharType(); QualType PromoArg = argTy->isPromotableIntegerType() ? C.getPromotedIntegerType(argTy) : argTy; PromoWChar = C.getCanonicalType(PromoWChar).getUnqualifiedType(); PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); return PromoWChar == PromoArg; } case CPointerTy: return argTy->isPointerType() || argTy->isObjCObjectPointerType() || argTy->isNullPtrType(); case ObjCPointerTy: return argTy->getAs<ObjCObjectPointerType>() != NULL; } // FIXME: Should be unreachable, but Clang is currently emitting // a warning. return false; }