static std::pair<size_t, bool> GetIntegralTypeInfo(TypeIndex ti, TpiStream &tpi) { if (ti.isSimple()) { SimpleTypeKind stk = ti.getSimpleKind(); return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)}; } CVType cvt = tpi.getType(ti); switch (cvt.kind()) { case LF_MODIFIER: { ModifierRecord mfr; llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr)); return GetIntegralTypeInfo(mfr.ModifiedType, tpi); } case LF_POINTER: { PointerRecord pr; llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr)); return GetIntegralTypeInfo(pr.ReferentType, tpi); } case LF_ENUM: { EnumRecord er; llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); return GetIntegralTypeInfo(er.UnderlyingType, tpi); } default: assert(false && "Type is not integral!"); return {0, false}; } }
StringRef CVTypeDumper::getTypeName(TypeIndex TI) { if (TI.isNoType()) return "<no type>"; if (TI.isSimple()) { // This is a simple type. for (const auto &SimpleTypeName : SimpleTypeNames) { if (SimpleTypeName.Value == TI.getSimpleKind()) { if (TI.getSimpleMode() == SimpleTypeMode::Direct) return SimpleTypeName.Name.drop_back(1); // Otherwise, this is a pointer type. We gloss over the distinction // between near, far, 64, 32, etc, and just give a pointer type. return SimpleTypeName.Name; } } return "<unknown simple type>"; } // User-defined type. StringRef UDTName; unsigned UDTIndex = TI.getIndex() - 0x1000; if (UDTIndex < CVUDTNames.size()) return CVUDTNames[UDTIndex]; return "<unknown UDT>"; }
static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) { if (TI.isSimple()) return true; if (TI.toArrayIndex() >= TypeIndexMap.size()) return false; TI = TypeIndexMap[TI.toArrayIndex()]; return true; }
void CVTypeDumper::printTypeIndex(StringRef FieldName, TypeIndex TI) { StringRef TypeName; if (!TI.isNoType()) TypeName = getTypeName(TI); if (!TypeName.empty()) W.printHex(FieldName, TypeName, TI.getIndex()); else W.printHex(FieldName, TI.getIndex()); }
void CVTypeDumper::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeDatabase &DB) { StringRef TypeName; if (!TI.isNoneType()) TypeName = DB.getTypeName(TI); if (!TypeName.empty()) Printer.printHex(FieldName, TypeName, TI.getIndex()); else Printer.printHex(FieldName, TI.getIndex()); }
unsigned UserDefinedCodeViewTypesBuilder::GetPointerTypeIndex(const PointerTypeDescriptor& PointerDescriptor) { uint32_t elementType = PointerDescriptor.ElementType; PointerKind pointerKind = PointerDescriptor.Is64Bit ? PointerKind::Near64 : PointerKind::Near32; PointerMode pointerMode = PointerDescriptor.IsReference ? PointerMode::LValueReference : PointerMode::Pointer; PointerOptions pointerOptions = PointerDescriptor.IsConst ? PointerOptions::Const : PointerOptions::None; PointerRecord PointerToClass(TypeIndex(elementType), pointerKind, pointerMode, pointerOptions, 0); TypeIndex PointerIndex = TypeTable.writeKnownType(PointerToClass); return PointerIndex.getIndex(); }
void TraceDbImpl::register_type_index(TypeIndex type) { if (!has_type_index(type)) { run_void(insert_type_index, { {"Id", (int)type.get_id()}, {"Description", type.description()} }); set_has_type_index(type); } }
SymIndexId SymbolCache::createSimpleType(TypeIndex Index, ModifierOptions Mods) { if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) return createSymbol<NativeTypePointer>(Index); const auto Kind = Index.getSimpleKind(); const auto It = std::find_if( std::begin(BuiltinTypes), std::end(BuiltinTypes), [Kind](const BuiltinTypeEntry &Builtin) { return Builtin.Kind == Kind; }); if (It == std::end(BuiltinTypes)) return 0; return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size); }
unsigned UserDefinedCodeViewTypesBuilder::GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, const DataFieldDescriptor *FieldsDescriptors, const StaticDataFieldDescriptor *StaticsDescriptors) { FieldListRecordBuilder FLBR(TypeTable); FLBR.begin(); uint16_t memberCount = 0; if (!ClassDescriptor.IsStruct) { memberCount++; AddClassVTShape(FLBR); } if (ClassDescriptor.BaseClassId != 0) { memberCount++; AddBaseClass(FLBR, ClassDescriptor.BaseClassId); } for (int i = 0; i < ClassFieldsDescriptor.FieldsCount; ++i) { DataFieldDescriptor desc = FieldsDescriptors[i]; MemberAccess Access = MemberAccess::Public; TypeIndex MemberBaseType(desc.FieldTypeIndex); if (desc.Offset == 0xFFFFFFFF) { StaticDataMemberRecord SDMR(Access, MemberBaseType, desc.Name); FLBR.writeMemberType(SDMR); } else { int MemberOffsetInBytes = desc.Offset; DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes, desc.Name); FLBR.writeMemberType(DMR); } memberCount++; } TypeIndex FieldListIndex = FLBR.end(true); TypeRecordKind Kind = ClassDescriptor.IsStruct ? TypeRecordKind::Struct : TypeRecordKind::Class; ClassOptions CO = GetCommonClassOptions(); ClassRecord CR(Kind, memberCount, CO, FieldListIndex, TypeIndex(), TypeIndex(), ClassFieldsDescriptor.Size, ClassDescriptor.Name, StringRef()); TypeIndex ClassIndex = TypeTable.writeKnownType(CR); UserDefinedTypes.push_back(std::make_pair(ClassDescriptor.Name, ClassIndex.getIndex())); return ClassIndex.getIndex(); }
void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt, const InlineSite &Site) { MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(), *InlineEnd = MMI->getContext().createTempSymbol(); assert(SubprogramToFuncId.count(Site.Inlinee)); TypeIndex InlineeIdx = SubprogramToFuncId[Site.Inlinee]; // SymbolRecord OS.AddComment("Record length"); OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 2); // RecordLength OS.EmitLabel(InlineBegin); OS.AddComment("Record kind: S_INLINESITE"); OS.EmitIntValue(SymbolRecordKind::S_INLINESITE, 2); // RecordKind OS.AddComment("PtrParent"); OS.EmitIntValue(0, 4); OS.AddComment("PtrEnd"); OS.EmitIntValue(0, 4); OS.AddComment("Inlinee type index"); OS.EmitIntValue(InlineeIdx.getIndex(), 4); unsigned FileId = maybeRecordFile(Site.Inlinee->getFile()); unsigned StartLineNum = Site.Inlinee->getLine(); SmallVector<unsigned, 3> SecondaryFuncIds; collectInlineSiteChildren(SecondaryFuncIds, FI, Site); OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum, FI.Begin, FI.End, SecondaryFuncIds); OS.EmitLabel(InlineEnd); for (const LocalVariable &Var : Site.InlinedLocals) emitLocalVariable(Var); // Recurse on child inlined call sites before closing the scope. for (const DILocation *ChildSite : Site.ChildSites) { auto I = FI.InlineSites.find(ChildSite); assert(I != FI.InlineSites.end() && "child site not in function inline site map"); emitInlinedCallSite(FI, ChildSite, I->second); } // Close the scope. OS.AddComment("Record length"); OS.EmitIntValue(2, 2); // RecordLength OS.AddComment("Record kind: S_INLINESITE_END"); OS.EmitIntValue(SymbolRecordKind::S_INLINESITE_END, 2); // RecordKind }
void llvm::codeview::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeCollection &Types) { StringRef TypeName; if (!TI.isNoneType()) { if (TI.isSimple()) TypeName = TypeIndex::simpleTypeName(TI); else TypeName = Types.getTypeName(TI); } if (!TypeName.empty()) Printer.printHex(FieldName, TypeName, TI.getIndex()); else Printer.printHex(FieldName, TI.getIndex()); }
bool TypeStreamMerger::remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map) { // Simple types are unchanged. if (Idx.isSimple()) return true; // Check if this type index refers to a record we've already translated // successfully. If it refers to a type later in the stream or a record we // had to defer, defer it until later pass. unsigned MapPos = slotForIndex(Idx); if (MapPos < Map.size() && Map[MapPos] != Untranslated) { Idx = Map[MapPos]; return true; } // If this is the second pass and this index isn't in the map, then it points // outside the current type stream, and this is a corrupt record. if (IsSecondPass && MapPos >= Map.size()) { // FIXME: Print a more useful error. We can give the current record and the // index that we think its pointing to. LastError = joinErrors(std::move(*LastError), errorCorruptRecord()); } ++NumBadIndices; // This type index is invalid. Remap this to "not translated by cvpack", // and return failure. Idx = Untranslated; return false; }
StringRef ScalarTraits<TypeIndex>::input(StringRef Scalar, void *Ctx, TypeIndex &S) { uint32_t I; StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I); S.setIndex(I); return Result; }
unsigned UserDefinedCodeViewTypesBuilder::GetEnumFieldListType( uint64 Count, const EnumRecordTypeDescriptor *TypeRecords) { FieldListRecordBuilder FLRB(TypeTable); FLRB.begin(); #ifndef NDEBUG uint64 MaxInt = (unsigned int)-1; assert(Count <= MaxInt && "There are too many fields inside enum"); #endif for (int i = 0; i < (int)Count; ++i) { EnumRecordTypeDescriptor record = TypeRecords[i]; EnumeratorRecord ER(MemberAccess::Public, APSInt::getUnsigned(record.Value), record.Name); FLRB.writeMemberType(ER); } TypeIndex Type = FLRB.end(true); return Type.getIndex(); }
unsigned UserDefinedCodeViewTypesBuilder::GetEnumTypeIndex( const EnumTypeDescriptor &TypeDescriptor, const EnumRecordTypeDescriptor *TypeRecords) { ClassOptions CO = GetCommonClassOptions(); unsigned FieldListIndex = GetEnumFieldListType(TypeDescriptor.ElementCount, TypeRecords); TypeIndex FieldListIndexType = TypeIndex(FieldListIndex); TypeIndex ElementTypeIndex = TypeIndex(TypeDescriptor.ElementType); EnumRecord EnumRecord(TypeDescriptor.ElementCount, CO, FieldListIndexType, TypeDescriptor.Name, StringRef(), ElementTypeIndex); TypeIndex Type = TypeTable.writeKnownType(EnumRecord); UserDefinedTypes.push_back(std::make_pair(TypeDescriptor.Name, Type.getIndex())); return Type.getIndex(); }
void TypeSystemInstance::add_converter_variations(TypeIndex from, TypeIndex to, p_conv_t conv) { this->conv_graph.add_conv(from, to, conv); /* // Add converters to make either type const. this->add_ptr_convs(from); this->add_ptr_convs(to); */ auto from_info = from.get_info(); auto to_info = to.get_info(); // Reuse this converter for just the "to" obj const this->conv_graph.add_conv(from, get_index(to_info.as_const_value()), conv); // Reuse this converter for both from and to as const this->conv_graph.add_conv(get_index(from_info.as_const_value()), get_index(to_info.as_const_value()), conv); }
bool TraceDbImpl::has_type_index(TypeIndex type) { size_t id = type.get_id(); if (id >= saved_type_indices.size()) return false; else return saved_type_indices[id]; }
Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) { W->startLine() << getLeafTypeName(Record.Type); W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")"; W->getOStream() << " {\n"; W->indent(); W->printEnum("TypeLeafKind", unsigned(Record.Type), makeArrayRef(LeafTypeNames)); return Error::success(); }
void TraceDbImpl::set_has_type_index(TypeIndex type) { size_t id = type.get_id(); if (id >= saved_type_indices.size()) saved_type_indices.resize(id+1); saved_type_indices[id] = true; }
void TypeSystemInstance::add_converter_simple(TypeIndex from_type, TypeIndex to_type, p_conv_t conv) { if (from_type.get_info().is_restricted) { stringstream msg; msg << "add_converter_simple error from_type is restricted " << from_type.description() << " " << from_type.get_id() << " to " << to_type.description() << " " << to_type.get_id() << " conv='" << conv->description() << "'"; cout << msg.str() << endl; throw std::logic_error(msg.str()); } this->conv_graph.add_conv(from_type, to_type, conv); //this->conv_graph.add_conv(from_type, get_index(from_type.get_info().as_restricted()), conv); //this->conv_graph.add_conv(to_type, get_index(to_type.get_info().as_restricted()), conv); if (!this->conv_graph.has_type(from_type)) { stringstream msg; msg << "add_converter_simple missing just-added from type for conversion from " << from_type.description() << " " << from_type.get_id() << " to " << to_type.description() << " " << to_type.get_id() << " conv='" << conv->description() << "'"; cout << msg.str() << endl; //throw std::logic_error(msg.str()); } if (!this->conv_graph.has_type(to_type)) { stringstream msg; msg << "add_converter_simple missing just-added to type for conversion from " << from_type.description() << " " << from_type.get_id() << " to " << to_type.description() << " " << to_type.get_id() << " conv='" << conv->description() << "'"; cout << msg.str() << endl; //throw std::logic_error(msg.str()); } if (!has_conv(from_type, to_type)) { bool test_again = has_conv(from_type, to_type); stringstream msg; msg << test_again; msg << "add_converter_simple missing just-added conversion from " << from_type.description() << " " << from_type.get_id() << " to " << to_type.description() << " " << to_type.get_id() << " conv='" << conv->description() << "'"; cout << msg.str() << endl; //throw std::logic_error(msg.str()); } }
void TraceDbImpl::new_Expr(void const* addr, TypeIndex type, void const* value_ptr) { register_type_index(type); run_void(insert_expr, { {"Sequence", ++sequence}, {"Address", format_ptr(addr)}, {"TypeIndex", (int)type.get_id()}, {"ValuePtr", format_ptr(value_ptr)} }); }
StringRef TypeIndex::simpleTypeName(TypeIndex TI) { assert(TI.isNoneType() || TI.isSimple()); if (TI.isNoneType()) return "<no type>"; if (TI == TypeIndex::NullptrT()) return "std::nullptr_t"; // This is a simple type. for (const auto &SimpleTypeName : SimpleTypeNames) { if (SimpleTypeName.Kind == TI.getSimpleKind()) { if (TI.getSimpleMode() == SimpleTypeMode::Direct) return SimpleTypeName.Name.drop_back(1); // Otherwise, this is a pointer type. We gloss over the distinction // between near, far, 64, 32, etc, and just give a pointer type. return SimpleTypeName.Name; } } return "<unknown simple type>"; }
unsigned UserDefinedCodeViewTypesBuilder::GetClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor) { TypeRecordKind Kind = ClassDescriptor.IsStruct ? TypeRecordKind::Struct : TypeRecordKind::Class; ClassOptions CO = ClassOptions::ForwardReference | GetCommonClassOptions(); TypeIndex FieldListIndex = TypeIndex(); uint16_t memberCount = 0; if (!ClassDescriptor.IsStruct) { FieldListRecordBuilder FLBR(TypeTable); FLBR.begin(); memberCount++; AddClassVTShape(FLBR); FieldListIndex = FLBR.end(true); } ClassRecord CR(Kind, memberCount, CO, FieldListIndex, TypeIndex(), TypeIndex(), 0, ClassDescriptor.Name, StringRef()); TypeIndex FwdDeclTI = TypeTable.writeKnownType(CR); return FwdDeclTI.getIndex(); }
void CodeViewDebug::emitInlineeLinesSubsection() { if (InlinedSubprograms.empty()) return; MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(), *InlineEnd = MMI->getContext().createTempSymbol(); OS.AddComment("Inlinee lines subsection"); OS.EmitIntValue(unsigned(ModuleSubstreamKind::InlineeLines), 4); OS.AddComment("Subsection size"); OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 4); OS.EmitLabel(InlineBegin); // We don't provide any extra file info. // FIXME: Find out if debuggers use this info. OS.AddComment("Inlinee lines signature"); OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4); for (const DISubprogram *SP : InlinedSubprograms) { OS.AddBlankLine(); TypeIndex TypeId = SubprogramToFuncId[SP]; unsigned FileId = maybeRecordFile(SP->getFile()); OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " + SP->getFilename() + Twine(':') + Twine(SP->getLine())); OS.AddBlankLine(); // The filechecksum table uses 8 byte entries for now, and file ids start at // 1. unsigned FileOffset = (FileId - 1) * 8; OS.AddComment("Type index of inlined function"); OS.EmitIntValue(TypeId.getIndex(), 4); OS.AddComment("Offset into filechecksum table"); OS.EmitIntValue(FileOffset, 4); OS.AddComment("Starting line number"); OS.EmitIntValue(SP->getLine(), 4); } OS.EmitLabel(InlineEnd); }
StringRef TypeDatabase::getTypeName(TypeIndex Index) const { if (Index.isNoneType()) return "<no type>"; if (Index.isSimple()) { // This is a simple type. for (const auto &SimpleTypeName : SimpleTypeNames) { if (SimpleTypeName.Kind == Index.getSimpleKind()) { if (Index.getSimpleMode() == SimpleTypeMode::Direct) return SimpleTypeName.Name.drop_back(1); // Otherwise, this is a pointer type. We gloss over the distinction // between near, far, 64, 32, etc, and just give a pointer type. return SimpleTypeName.Name; } } return "<unknown simple type>"; } uint32_t I = Index.getIndex() - TypeIndex::FirstNonSimpleIndex; if (I < CVUDTNames.size()) return CVUDTNames[I]; return "<unknown UDT>"; }
unsigned UserDefinedCodeViewTypesBuilder::GetMemberFunctionTypeIndex(const MemberFunctionTypeDescriptor& MemberDescriptor, uint32_t const *const ArgumentTypes) { std::vector<TypeIndex> argumentTypes; argumentTypes.reserve(MemberDescriptor.NumberOfArguments); for (uint16_t iArgument = 0; iArgument < MemberDescriptor.NumberOfArguments; iArgument++) { argumentTypes.emplace_back(ArgumentTypes[iArgument]); } ArgListRecord ArgList(TypeRecordKind::ArgList, argumentTypes); TypeIndex ArgumentList = TypeTable.writeKnownType(ArgList); MemberFunctionRecord MemberFunction(TypeIndex(MemberDescriptor.ReturnType), TypeIndex(MemberDescriptor.ContainingClass), TypeIndex(MemberDescriptor.TypeIndexOfThisPointer), CallingConvention(MemberDescriptor.CallingConvention), FunctionOptions::None, MemberDescriptor.NumberOfArguments, ArgumentList, MemberDescriptor.ThisAdjust); TypeIndex MemberFunctionIndex = TypeTable.writeKnownType(MemberFunction); return MemberFunctionIndex.getIndex(); }
void add_ptr_convs(TypeIndex index) { TypeInfo bare = index.get_info().class_type(); //add_conv_track<void>(bare); //add_conv_track<void const>(bare.as_const_value()); auto bottom_ptr_type = create_type_mirror("BottomPtr", size_t(0), create_bottom_ptr_type_index(), type_system->global_namespace().get_class_type()); type_system->add_class(create_bottom_ptr_type_index(), bottom_ptr_type, type_system->global_namespace()); // allow unsafe_ptr_cast to convert to any type and nil (NULL) to any pointer type add_nochange_conv(create_bottom_ptr_type_info(), bare.as_ptr_to_nonconst(), "bottom ptr unsafe cast to any ptr"); add_nochange_conv(create_bottom_ptr_type_info(), bare.as_ptr_to_const(), "bottom ptr unsafe cast to any const ptr"); // allow any ptr to be converted to void* or void const* add_nochange_conv(bare.as_ptr_to_nonconst(), TypId<void*>::restricted().get_info(), "any ptr to void ptr"); add_nochange_conv(bare.as_ptr_to_const(), TypId<void const*>::restricted().get_info(), "any ptr to const void ptr"); }
void TypeSystemInstance::add_common_conversions(TypeIndex type) { TypeInfo type_info = type.get_info(); TypeInfo value_nonconst = type_info.as_nonconst_value(); TypeInfo value_const = type_info.as_const_value(); add_conv(value_nonconst, value_nonconst.as_restricted()); add_conv(value_nonconst, value_const.as_restricted()); add_conv(value_const, value_const.as_restricted()); TypeInfo ptr_to_nonconst = type_info.as_ptr_to_nonconst(); TypeInfo ref_to_nonconst = type_info.as_ref_to_nonconst(); add_conv(ptr_to_nonconst, ref_to_nonconst.as_restricted()); add_conv(ref_to_nonconst, ptr_to_nonconst.as_restricted()); TypeInfo ptr_to_const = type_info.as_ptr_to_const(); TypeInfo ref_to_const = type_info.as_ref_to_const(); add_conv(ptr_to_const, ref_to_const.as_restricted()); add_conv(ref_to_const, ptr_to_const.as_restricted()); add_conv(ptr_to_nonconst, ref_to_const.as_restricted()); add_conv(ref_to_nonconst, ptr_to_const.as_restricted()); add_conv(ptr_to_const, ptr_to_const.as_restricted()); add_conv(ref_to_const, ref_to_const.as_restricted()); add_conv(ptr_to_nonconst, ptr_to_nonconst.as_restricted()); add_conv(ref_to_nonconst, ref_to_nonconst.as_restricted()); TypeInfo const_ref_to_ptr_to_nonconst = ptr_to_nonconst.as_ref_to_nonconst(); TypeInfo const_ref_to_ptr_to_const = ptr_to_nonconst.as_ref_to_const(); add_conv(ptr_to_nonconst, const_ref_to_ptr_to_nonconst.as_restricted()); add_conv(ptr_to_nonconst, const_ref_to_ptr_to_const.as_restricted()); add_conv(ptr_to_const, const_ref_to_ptr_to_const.as_restricted()); // These have to be restricted because if refs can be converted // to value then they can be auto-converted to script which we don't want. add_conv(ref_to_const, value_nonconst.as_restricted()); add_conv(ref_to_const, value_const.as_restricted()); add_conv(ref_to_nonconst, value_nonconst.as_restricted()); add_conv(ref_to_nonconst, value_const.as_restricted()); add_conv(ptr_to_const, value_nonconst.as_restricted()); add_conv(ptr_to_const, value_const.as_restricted()); add_conv(ptr_to_nonconst, value_nonconst.as_restricted()); add_conv(ptr_to_nonconst, value_const.as_restricted()); // These are allowed because Term<T> can be called as ref. add_conv(value_nonconst, ref_to_nonconst.as_restricted()); add_conv(value_nonconst, ref_to_const.as_restricted()); add_conv(value_const, ref_to_const.as_restricted()); add_conv(value_nonconst, ptr_to_nonconst.as_restricted()); add_conv(value_nonconst, ptr_to_const.as_restricted()); add_conv(value_const, ptr_to_const.as_restricted()); // Anything can be converted to it's const form without restriction. add_conv(ref_to_nonconst, ref_to_const); add_conv(ptr_to_nonconst, ptr_to_const); add_conv(value_nonconst, value_const); add_conv(ref_to_nonconst, ref_to_const.as_restricted()); add_conv(ptr_to_nonconst, ptr_to_const.as_restricted()); TypeInfo nil_expr_type = create_bottom_ptr_type_info(); add_conv(nil_expr_type, ptr_to_nonconst.as_restricted()); add_conv(nil_expr_type, ptr_to_const.as_restricted()); }
void ScalarTraits<TypeIndex>::output(const TypeIndex &S, void *, llvm::raw_ostream &OS) { OS << S.getIndex(); }
void TypeRecordBuilder::writeTypeIndex(TypeIndex TypeInd) { writeUInt32(TypeInd.getIndex()); }