static uint64_t CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) { if (!E->isArray()) return 0; QualType T = E->getAllocatedType(); const RecordType *RT = T->getAs<RecordType>(); if (!RT) return 0; const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); if (!RD) return 0; // Check if the class has a trivial destructor. if (RD->hasTrivialDestructor()) { // FIXME: Check for a two-argument delete. return 0; } // Padding is the maximum of sizeof(size_t) and alignof(T) return std::max(Ctx.getTypeSize(Ctx.getSizeType()), static_cast<uint64_t>(Ctx.getTypeAlign(T))) / 8; }
ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, bool IsObjCLiteral) const { const PrintfConversionSpecifier &CS = getConversionSpecifier(); if (!CS.consumesDataArgument()) return ArgType::Invalid(); if (CS.getKind() == ConversionSpecifier::cArg) switch (LM.getKind()) { case LengthModifier::None: return Ctx.IntTy; case LengthModifier::AsLong: case LengthModifier::AsWide: return ArgType(ArgType::WIntTy, "wint_t"); case LengthModifier::AsShort: if (Ctx.getTargetInfo().getTriple().isOSMSVCRT()) return Ctx.IntTy; LLVM_FALLTHROUGH; default: return ArgType::Invalid(); } if (CS.isIntArg()) switch (LM.getKind()) { case LengthModifier::AsLongDouble: // GNU extension. return Ctx.LongLongTy; case LengthModifier::None: return Ctx.IntTy; case LengthModifier::AsInt32: return ArgType(Ctx.IntTy, "__int32"); case LengthModifier::AsChar: return ArgType::AnyCharTy; case LengthModifier::AsShort: return Ctx.ShortTy; case LengthModifier::AsLong: return Ctx.LongTy; case LengthModifier::AsLongLong: case LengthModifier::AsQuad: return Ctx.LongLongTy; case LengthModifier::AsInt64: return ArgType(Ctx.LongLongTy, "__int64"); case LengthModifier::AsIntMax: return ArgType(Ctx.getIntMaxType(), "intmax_t"); case LengthModifier::AsSizeT: // FIXME: How to get the corresponding signed version of size_t? return ArgType(); case LengthModifier::AsInt3264: return Ctx.getTargetInfo().getTriple().isArch64Bit() ? ArgType(Ctx.LongLongTy, "__int64") : ArgType(Ctx.IntTy, "__int32"); case LengthModifier::AsPtrDiff: return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: case LengthModifier::AsWide: return ArgType::Invalid(); } if (CS.isUIntArg()) switch (LM.getKind()) { case LengthModifier::AsLongDouble: // GNU extension. return Ctx.UnsignedLongLongTy; case LengthModifier::None: return Ctx.UnsignedIntTy; case LengthModifier::AsInt32: return ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); case LengthModifier::AsChar: return Ctx.UnsignedCharTy; case LengthModifier::AsShort: return Ctx.UnsignedShortTy; case LengthModifier::AsLong: return Ctx.UnsignedLongTy; case LengthModifier::AsLongLong: case LengthModifier::AsQuad: return Ctx.UnsignedLongLongTy; case LengthModifier::AsInt64: return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64"); case LengthModifier::AsIntMax: return ArgType(Ctx.getUIntMaxType(), "uintmax_t"); case LengthModifier::AsSizeT: return ArgType(Ctx.getSizeType(), "size_t"); case LengthModifier::AsInt3264: return Ctx.getTargetInfo().getTriple().isArch64Bit() ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64") : ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); case LengthModifier::AsPtrDiff: // FIXME: How to get the corresponding unsigned // version of ptrdiff_t? return ArgType(); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: case LengthModifier::AsWide: return ArgType::Invalid(); } if (CS.isDoubleArg()) { if (LM.getKind() == LengthModifier::AsLongDouble) return Ctx.LongDoubleTy; return Ctx.DoubleTy; } if (CS.getKind() == 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: case LengthModifier::AsInt32: case LengthModifier::AsInt3264: case LengthModifier::AsInt64: case LengthModifier::AsWide: return ArgType::Invalid(); } } switch (CS.getKind()) { case ConversionSpecifier::sArg: if (LM.getKind() == LengthModifier::AsWideChar) { if (IsObjCLiteral) return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), "const unichar *"); return ArgType(ArgType::WCStrTy, "wchar_t *"); } if (LM.getKind() == LengthModifier::AsWide) return ArgType(ArgType::WCStrTy, "wchar_t *"); return ArgType::CStrTy; case ConversionSpecifier::SArg: if (IsObjCLiteral) return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), "const unichar *"); if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() && LM.getKind() == LengthModifier::AsShort) return ArgType::CStrTy; return ArgType(ArgType::WCStrTy, "wchar_t *"); case ConversionSpecifier::CArg: if (IsObjCLiteral) return ArgType(Ctx.UnsignedShortTy, "unichar"); if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() && LM.getKind() == LengthModifier::AsShort) return Ctx.IntTy; return ArgType(Ctx.WideCharTy, "wchar_t"); case ConversionSpecifier::pArg: case ConversionSpecifier::PArg: return ArgType::CPointerTy; case ConversionSpecifier::ObjCObjArg: return ArgType::ObjCPointerTy; default: break; } // FIXME: Handle other cases. return ArgType(); }
ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const { const ScanfConversionSpecifier &CS = getConversionSpecifier(); if (!CS.consumesDataArgument()) return ScanfArgTypeResult::Invalid(); switch(CS.getKind()) { // Signed int. case ConversionSpecifier::dArg: case ConversionSpecifier::iArg: switch (LM.getKind()) { case LengthModifier::None: return ArgTypeResult(Ctx.IntTy); case LengthModifier::AsChar: return ArgTypeResult(ArgTypeResult::AnyCharTy); case LengthModifier::AsShort: return ArgTypeResult(Ctx.ShortTy); case LengthModifier::AsLong: return ArgTypeResult(Ctx.LongTy); case LengthModifier::AsLongLong: return ArgTypeResult(Ctx.LongLongTy); case LengthModifier::AsIntMax: return ScanfArgTypeResult(Ctx.getIntMaxType(), "intmax_t *"); case LengthModifier::AsSizeT: // FIXME: ssize_t. return ScanfArgTypeResult(); case LengthModifier::AsPtrDiff: return ScanfArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t *"); case LengthModifier::AsLongDouble: return ScanfArgTypeResult::Invalid(); case LengthModifier::AsAllocate: return ScanfArgTypeResult::Invalid(); case LengthModifier::AsMAllocate: return ScanfArgTypeResult::Invalid(); } // Unsigned int. case ConversionSpecifier::oArg: case ConversionSpecifier::uArg: case ConversionSpecifier::xArg: case ConversionSpecifier::XArg: switch (LM.getKind()) { case LengthModifier::None: return ArgTypeResult(Ctx.UnsignedIntTy); case LengthModifier::AsChar: return ArgTypeResult(Ctx.UnsignedCharTy); case LengthModifier::AsShort: return ArgTypeResult(Ctx.UnsignedShortTy); case LengthModifier::AsLong: return ArgTypeResult(Ctx.UnsignedLongTy); case LengthModifier::AsLongLong: return ArgTypeResult(Ctx.UnsignedLongLongTy); case LengthModifier::AsIntMax: return ScanfArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t *"); case LengthModifier::AsSizeT: return ScanfArgTypeResult(Ctx.getSizeType(), "size_t *"); case LengthModifier::AsPtrDiff: // FIXME: Unsigned version of ptrdiff_t? return ScanfArgTypeResult(); case LengthModifier::AsLongDouble: return ScanfArgTypeResult::Invalid(); case LengthModifier::AsAllocate: return ScanfArgTypeResult::Invalid(); case LengthModifier::AsMAllocate: return ScanfArgTypeResult::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 ArgTypeResult(Ctx.FloatTy); case LengthModifier::AsLong: return ArgTypeResult(Ctx.DoubleTy); case LengthModifier::AsLongDouble: return ArgTypeResult(Ctx.LongDoubleTy); default: return ScanfArgTypeResult::Invalid(); } // Char, string and scanlist. case ConversionSpecifier::cArg: case ConversionSpecifier::sArg: case ConversionSpecifier::ScanListArg: switch (LM.getKind()) { case LengthModifier::None: return ScanfArgTypeResult::CStrTy; case LengthModifier::AsLong: return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *"); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: return ScanfArgTypeResult(ArgTypeResult::CStrTy); default: return ScanfArgTypeResult::Invalid(); } case ConversionSpecifier::CArg: case ConversionSpecifier::SArg: // FIXME: Mac OS X specific? switch (LM.getKind()) { case LengthModifier::None: return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *"); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: return ScanfArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t **"); default: return ScanfArgTypeResult::Invalid(); } // Pointer. case ConversionSpecifier::pArg: return ScanfArgTypeResult(ArgTypeResult(ArgTypeResult::CPointerTy)); default: break; } return ScanfArgTypeResult(); }
ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const { const PrintfConversionSpecifier &CS = getConversionSpecifier(); if (!CS.consumesDataArgument()) return ArgTypeResult::Invalid(); if (CS.getKind() == ConversionSpecifier::cArg) switch (LM.getKind()) { case LengthModifier::None: return Ctx.IntTy; case LengthModifier::AsLong: return ArgTypeResult(ArgTypeResult::WIntTy, "wint_t"); default: return ArgTypeResult::Invalid(); } if (CS.isIntArg()) switch (LM.getKind()) { case LengthModifier::AsLongDouble: return ArgTypeResult::Invalid(); case LengthModifier::None: return Ctx.IntTy; case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy; case LengthModifier::AsShort: return Ctx.ShortTy; case LengthModifier::AsLong: return Ctx.LongTy; case LengthModifier::AsLongLong: return Ctx.LongLongTy; case LengthModifier::AsIntMax: return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t"); case LengthModifier::AsSizeT: // FIXME: How to get the corresponding signed version of size_t? return ArgTypeResult(); case LengthModifier::AsPtrDiff: return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t"); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: return ArgTypeResult::Invalid(); } if (CS.isUIntArg()) switch (LM.getKind()) { case LengthModifier::AsLongDouble: return ArgTypeResult::Invalid(); case LengthModifier::None: return Ctx.UnsignedIntTy; case LengthModifier::AsChar: return Ctx.UnsignedCharTy; case LengthModifier::AsShort: return Ctx.UnsignedShortTy; case LengthModifier::AsLong: return Ctx.UnsignedLongTy; case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy; case LengthModifier::AsIntMax: return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t"); case LengthModifier::AsSizeT: return ArgTypeResult(Ctx.getSizeType(), "size_t"); case LengthModifier::AsPtrDiff: // FIXME: How to get the corresponding unsigned // version of ptrdiff_t? return ArgTypeResult(); case LengthModifier::AsAllocate: case LengthModifier::AsMAllocate: return ArgTypeResult::Invalid(); } if (CS.isDoubleArg()) { if (LM.getKind() == LengthModifier::AsLongDouble) return Ctx.LongDoubleTy; return Ctx.DoubleTy; } switch (CS.getKind()) { case ConversionSpecifier::sArg: if (LM.getKind() == LengthModifier::AsWideChar) return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *"); return ArgTypeResult::CStrTy; case ConversionSpecifier::SArg: // FIXME: This appears to be Mac OS X specific. return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *"); case ConversionSpecifier::CArg: return ArgTypeResult(Ctx.WCharTy, "wchar_t"); case ConversionSpecifier::pArg: return ArgTypeResult::CPointerTy; default: break; } // FIXME: Handle other cases. return ArgTypeResult(); }
QualType SymbolExtent::getType(ASTContext &Ctx) const { return Ctx.getSizeType(); }
/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the /// pointer over the consumed characters. This returns the resultant type. static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context, Builtin::Context::GetBuiltinTypeError &Error, bool AllowTypeModifiers = true) { // Modifiers. int HowLong = 0; bool Signed = false, Unsigned = false; // Read the modifiers first. bool Done = false; while (!Done) { switch (*Str++) { default: Done = true; --Str; break; case 'S': assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!"); assert(!Signed && "Can't use 'S' modifier multiple times!"); Signed = true; break; case 'U': assert(!Signed && "Can't use both 'S' and 'U' modifiers!"); assert(!Unsigned && "Can't use 'S' modifier multiple times!"); Unsigned = true; break; case 'L': assert(HowLong <= 2 && "Can't have LLLL modifier"); ++HowLong; break; } } QualType Type; // Read the base type. switch (*Str++) { default: assert(0 && "Unknown builtin type letter!"); case 'v': assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers used with 'v'!"); Type = Context.VoidTy; break; case 'f': assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers used with 'f'!"); Type = Context.FloatTy; break; case 'd': assert(HowLong < 2 && !Signed && !Unsigned && "Bad modifiers used with 'd'!"); if (HowLong) Type = Context.LongDoubleTy; else Type = Context.DoubleTy; break; case 's': assert(HowLong == 0 && "Bad modifiers used with 's'!"); if (Unsigned) Type = Context.UnsignedShortTy; else Type = Context.ShortTy; break; case 'i': if (HowLong == 3) Type = Unsigned ? Context.UnsignedInt128Ty : Context.Int128Ty; else if (HowLong == 2) Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy; else if (HowLong == 1) Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy; else Type = Unsigned ? Context.UnsignedIntTy : Context.IntTy; break; case 'c': assert(HowLong == 0 && "Bad modifiers used with 'c'!"); if (Signed) Type = Context.SignedCharTy; else if (Unsigned) Type = Context.UnsignedCharTy; else Type = Context.CharTy; break; case 'b': // boolean assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!"); Type = Context.BoolTy; break; case 'z': // size_t. assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'z'!"); Type = Context.getSizeType(); break; case 'F': Type = Context.getCFConstantStringType(); break; case 'a': Type = Context.getBuiltinVaListType(); assert(!Type.isNull() && "builtin va list type not initialized!"); break; case 'A': // This is a "reference" to a va_list; however, what exactly // this means depends on how va_list is defined. There are two // different kinds of va_list: ones passed by value, and ones // passed by reference. An example of a by-value va_list is // x86, where va_list is a char*. An example of by-ref va_list // is x86-64, where va_list is a __va_list_tag[1]. For x86, // we want this argument to be a char*&; for x86-64, we want // it to be a __va_list_tag*. Type = Context.getBuiltinVaListType(); assert(!Type.isNull() && "builtin va list type not initialized!"); if (Type->isArrayType()) { Type = Context.getArrayDecayedType(Type); } else { Type = Context.getLValueReferenceType(Type); } break; case 'V': { char *End; unsigned NumElements = strtoul(Str, &End, 10); assert(End != Str && "Missing vector size"); Str = End; QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false); Type = Context.getVectorType(ElementType, NumElements); break; } case 'P': { IdentifierInfo *II = &Context.Idents.get("FILE"); DeclContext::lookup_result Lookup = Context.getTranslationUnitDecl()->lookup(Context, II); if (Lookup.first != Lookup.second && isa<TypeDecl>(*Lookup.first)) { Type = Context.getTypeDeclType(cast<TypeDecl>(*Lookup.first)); break; } else { Error = Builtin::Context::GE_Missing_FILE; return QualType(); } } } if (!AllowTypeModifiers) return Type; Done = false; while (!Done) { switch (*Str++) { default: Done = true; --Str; break; case '*': Type = Context.getPointerType(Type); break; case '&': Type = Context.getLValueReferenceType(Type); break; // FIXME: There's no way to have a built-in with an rvalue ref arg. case 'C': Type = Type.getQualifiedType(QualType::Const); break; } } return Type; }