Beispiel #1
0
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();
}
Beispiel #2
0
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!");
}
Beispiel #3
0
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;
}
Beispiel #4
0
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();
}
Beispiel #6
0
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!");
}
Beispiel #7
0
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;
}