Esempio n. 1
0
static uint32_t getPicFlags(ArrayRef<FileFlags> Files) {
  // Check PIC/non-PIC compatibility.
  bool IsPic = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
  for (const FileFlags &F : Files.slice(1)) {
    bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
    if (IsPic && !IsPic2)
      warn(toString(F.File) +
           ": linking non-abicalls code with abicalls code " +
           toString(Files[0].File));
    if (!IsPic && IsPic2)
      warn(toString(F.File) +
           ": linking abicalls code with non-abicalls code " +
           toString(Files[0].File));
  }

  // Compute the result PIC/non-PIC flag.
  uint32_t Ret = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
  for (const FileFlags &F : Files.slice(1))
    Ret &= F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);

  // PIC code is inherently CPIC and may not set CPIC flag explicitly.
  if (Ret & EF_MIPS_PIC)
    Ret |= EF_MIPS_CPIC;
  return Ret;
}
Esempio n. 2
0
static void copyOrInitValuesInto(Initialization *init,
                                 ArrayRef<ManagedValue> &values, CanType type,
                                 SILLocation loc, SILGenFunction &gen) {
  static_assert(KIND == ImplodeKind::Forward ||
                KIND == ImplodeKind::Copy, "Not handled by init");
  bool isInit = (KIND == ImplodeKind::Forward);
  
  // If the element has non-tuple type, just serve it up to the initialization.
  auto tupleType = dyn_cast<TupleType>(type);
  if (!tupleType) {
    // We take the first value.
    ManagedValue result = values[0];
    values = values.slice(1);
    init->copyOrInitValueInto(gen, loc, result, isInit);
    init->finishInitialization(gen);
    return;
  }
  
  bool implodeTuple = false;

  if (auto Address = init->getAddressOrNull()) {
    if (isa<GlobalAddrInst>(Address) &&
        gen.getTypeLowering(type).getLoweredType().isTrivial(gen.SGM.M)) {
      // Implode tuples in initialization of globals if they are
      // of trivial types.
      implodeTuple = true;
    }
  }
  
  // If we can satisfy the tuple type by breaking up the aggregate
  // initialization, do so.
  if (!implodeTuple && init->canSplitIntoTupleElements()) {
    SmallVector<InitializationPtr, 4> subInitBuf;
    auto subInits = init->splitIntoTupleElements(gen, loc, type, subInitBuf);
    
    assert(subInits.size() == tupleType->getNumElements() &&
           "initialization does not match tuple?!");
    
    for (unsigned i = 0, e = subInits.size(); i < e; ++i)
      copyOrInitValuesInto<KIND>(subInits[i].get(), values,
                                 tupleType.getElementType(i), loc, gen);

    init->finishInitialization(gen);
    return;
  }
  
  // Otherwise, process this by turning the values corresponding to the tuple
  // into a single value (through an implosion) and then binding that value to
  // our initialization.
  SILValue scalar = implodeTupleValues<KIND>(values, gen, type, loc);
  
  // This will have just used up the first values in the list, pop them off.
  values = values.slice(getRValueSize(type));
  
  init->copyOrInitValueInto(gen, loc, ManagedValue::forUnmanaged(scalar),
                            isInit);
  init->finishInitialization(gen);
}
Esempio n. 3
0
std::pair<ArrayRef<Value *>, ArrayRef<Value *>>
Vectorizer::splitOddVectorElts(ArrayRef<Value *> Chain,
                               unsigned ElementSizeBits) {
  unsigned ElemSizeInBytes = ElementSizeBits / 8;
  unsigned SizeInBytes = ElemSizeInBytes * Chain.size();
  unsigned NumRight = (SizeInBytes % 4) / ElemSizeInBytes;
  unsigned NumLeft = Chain.size() - NumRight;
  return std::make_pair(Chain.slice(0, NumLeft), Chain.slice(NumLeft));
}
Esempio n. 4
0
static int ExecuteCC1Tool(ArrayRef<const char *> argv, StringRef Tool) {
  void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath;
  if (Tool == "")
    return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
  if (Tool == "as")
    return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);

  // Reject unknown tools.
  llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
  return 1;
}
Esempio n. 5
0
DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
                                                ArrayRef<uint8_t> Bytes_,
                                                uint64_t Address,
                                                raw_ostream &WS,
                                                raw_ostream &CS) const {
  CommentStream = &CS;

  // ToDo: AMDGPUDisassembler supports only VI ISA.
  assert(AMDGPU::isVI(STI) && "Can disassemble only VI ISA.");

  const unsigned MaxInstBytesNum = (std::min)((size_t)8, Bytes_.size());
  Bytes = Bytes_.slice(0, MaxInstBytesNum);

  DecodeStatus Res = MCDisassembler::Fail;
  do {
    // ToDo: better to switch encoding length using some bit predicate
    // but it is unknown yet, so try all we can

    // Try to decode DPP and SDWA first to solve conflict with VOP1 and VOP2
    // encodings
    if (Bytes.size() >= 8) {
      const uint64_t QW = eatBytes<uint64_t>(Bytes);
      Res = tryDecodeInst(DecoderTableDPP64, MI, QW, Address);
      if (Res) break;

      Res = tryDecodeInst(DecoderTableSDWA64, MI, QW, Address);
      if (Res) break;
    }

    // Reinitialize Bytes as DPP64 could have eaten too much
    Bytes = Bytes_.slice(0, MaxInstBytesNum);

    // Try decode 32-bit instruction
    if (Bytes.size() < 4) break;
    const uint32_t DW = eatBytes<uint32_t>(Bytes);
    Res = tryDecodeInst(DecoderTableVI32, MI, DW, Address);
    if (Res) break;

    Res = tryDecodeInst(DecoderTableAMDGPU32, MI, DW, Address);
    if (Res) break;

    if (Bytes.size() < 4) break;
    const uint64_t QW = ((uint64_t)eatBytes<uint32_t>(Bytes) << 32) | DW;
    Res = tryDecodeInst(DecoderTableVI64, MI, QW, Address);
    if (Res) break;

    Res = tryDecodeInst(DecoderTableAMDGPU64, MI, QW, Address);
  } while (false);

  Size = Res ? (MaxInstBytesNum - Bytes.size()) : 0;
  return Res;
}
Esempio n. 6
0
void EhInputSection<ELFT>::split(ArrayRef<RelTy> Rels) {
  ArrayRef<uint8_t> Data = this->getSectionData();
  unsigned RelI = 0;
  for (size_t Off = 0, End = Data.size(); Off != End;) {
    size_t Size = readEhRecordSize<ELFT>(Data.slice(Off));
    this->Pieces.emplace_back(Off, Data.slice(Off, Size),
                              getReloc(Off, Size, Rels, RelI));
    // The empty record is the end marker.
    if (Size == 4)
      break;
    Off += Size;
  }
}
Esempio n. 7
0
template <class ELFT> uint8_t getFdeEncoding(ArrayRef<uint8_t> D) {
  if (D.size() < 8)
    fatal("CIE too small");
  D = D.slice(8);

  uint8_t Version = readByte(D);
  if (Version != 1 && Version != 3)
    fatal("FDE version 1 or 3 expected, but got " + Twine((unsigned)Version));

  const unsigned char *AugEnd = std::find(D.begin(), D.end(), '\0');
  if (AugEnd == D.end())
    fatal("corrupted CIE");
  StringRef Aug(reinterpret_cast<const char *>(D.begin()), AugEnd - D.begin());
  D = D.slice(Aug.size() + 1);

  // Code alignment factor should always be 1 for .eh_frame.
  if (readByte(D) != 1)
    fatal("CIE code alignment must be 1");

  // Skip data alignment factor.
  skipLeb128(D);

  // Skip the return address register. In CIE version 1 this is a single
  // byte. In CIE version 3 this is an unsigned LEB128.
  if (Version == 1)
    readByte(D);
  else
    skipLeb128(D);

  // We only care about an 'R' value, but other records may precede an 'R'
  // record. Unfortunately records are not in TLV (type-length-value) format,
  // so we need to teach the linker how to skip records for each type.
  for (char C : Aug) {
    if (C == 'R')
      return readByte(D);
    if (C == 'z') {
      skipLeb128(D);
      continue;
    }
    if (C == 'P') {
      skipAugP<ELFT>(D);
      continue;
    }
    if (C == 'L') {
      readByte(D);
      continue;
    }
    fatal("unknown .eh_frame augmentation string: " + Aug);
  }
  return DW_EH_PE_absptr;
}
static InitializationPtr
prepareIndirectResultInit(SILGenFunction &gen, CanType resultType,
                          ArrayRef<SILResultInfo> &allResults,
                          MutableArrayRef<SILValue> &directResults,
                          ArrayRef<SILArgument*> &indirectResultAddrs,
                          SmallVectorImpl<CleanupHandle> &cleanups) {
  // Recursively decompose tuple types.
  if (auto resultTupleType = dyn_cast<TupleType>(resultType)) {
    auto tupleInit = new TupleInitialization();
    tupleInit->SubInitializations.reserve(resultTupleType->getNumElements());

    for (auto resultEltType : resultTupleType.getElementTypes()) {
      auto eltInit = prepareIndirectResultInit(gen, resultEltType, allResults,
                                               directResults,
                                               indirectResultAddrs, cleanups);
      tupleInit->SubInitializations.push_back(std::move(eltInit));
    }

    return InitializationPtr(tupleInit);
  }

  // Okay, pull the next result off the list of results.
  auto result = allResults[0];
  allResults = allResults.slice(1);

  // If it's indirect, we should be emitting into an argument.
  if (result.isIndirect()) {
    // Pull off the next indirect result argument.
    SILValue addr = indirectResultAddrs.front();
    indirectResultAddrs = indirectResultAddrs.slice(1);

    // Create an initialization which will initialize it.
    auto &resultTL = gen.getTypeLowering(addr->getType());
    auto temporary = gen.useBufferAsTemporary(addr, resultTL);

    // Remember the cleanup that will be activated.
    auto cleanup = temporary->getInitializedCleanup();
    if (cleanup.isValid())
      cleanups.push_back(cleanup);

    return InitializationPtr(temporary.release());
  }

  // Otherwise, make an Initialization that stores the value in the
  // next element of the directResults array.
  auto init = new StoreResultInitialization(directResults[0], cleanups);
  directResults = directResults.slice(1);
  return InitializationPtr(init);
}
Esempio n. 9
0
// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
static std::vector<SectionPiece> splitStrings(ArrayRef<uint8_t> Data,
                                              size_t EntSize) {
  std::vector<SectionPiece> V;
  size_t Off = 0;
  while (!Data.empty()) {
    size_t End = findNull(Data, EntSize);
    if (End == StringRef::npos)
      fatal("string is not null terminated");
    size_t Size = End + EntSize;
    V.emplace_back(Off, Data.slice(0, Size));
    Data = Data.slice(Size);
    Off += Size;
  }
  return V;
}
Esempio n. 10
0
std::pair<ArrayRef<Instruction *>, ArrayRef<Instruction *>>
Vectorizer::splitOddVectorElts(ArrayRef<Instruction *> Chain,
                               unsigned ElementSizeBits) {
  unsigned ElementSizeBytes = ElementSizeBits / 8;
  unsigned SizeBytes = ElementSizeBytes * Chain.size();
  unsigned NumLeft = (SizeBytes - (SizeBytes % 4)) / ElementSizeBytes;
  if (NumLeft == Chain.size()) {
    if ((NumLeft & 1) == 0)
      NumLeft /= 2; // Split even in half
    else
      --NumLeft;    // Split off last element
  } else if (NumLeft == 0)
    NumLeft = 1;
  return std::make_pair(Chain.slice(0, NumLeft), Chain.slice(NumLeft));
}
Esempio n. 11
0
static ManagedValue emitBuiltinAssign(SILGenFunction &gen,
                                      SILLocation loc,
                                      SubstitutionList substitutions,
                                      ArrayRef<ManagedValue> args,
                                      CanFunctionType formalApplyType,
                                      SGFContext C) {
  assert(args.size() >= 2 && "assign should have two arguments");
  assert(substitutions.size() == 1 &&
         "assign should have a single substitution");

  // The substitution determines the type of the thing we're destroying.
  CanType assignFormalType = substitutions[0].getReplacement()->getCanonicalType();
  SILType assignType = gen.getLoweredType(assignFormalType);
  
  // Convert the destination pointer argument to a SIL address.
  SILValue addr = gen.B.createPointerToAddress(loc,
                                               args.back().getUnmanagedValue(),
                                               assignType.getAddressType(),
                                               /*isStrict*/ true);
  
  // Build the value to be assigned, reconstructing tuples if needed.
  auto src = RValue::withPreExplodedElements(args.slice(0, args.size() - 1),
                                             assignFormalType);
  
  std::move(src).assignInto(gen, loc, addr);

  return ManagedValue::forUnmanaged(gen.emitEmptyTuple(loc));
}
Esempio n. 12
0
static void addParameters(ArrayRef<Identifier> &ArgNames,
                          const ParameterList *paramList,
                          TextEntity &Ent,
                          SourceManager &SM,
                          unsigned BufferID) {
  for (auto &param : *paramList) {
    StringRef Arg;
    if (!ArgNames.empty()) {
      Identifier Id = ArgNames.front();
      Arg = Id.empty() ? "_" : Id.str();
      ArgNames = ArgNames.slice(1);
    }

    if (auto typeRepr = param->getTypeLoc().getTypeRepr()) {
      SourceRange TypeRange = param->getTypeLoc().getSourceRange();
      if (auto InOutTyR = dyn_cast_or_null<InOutTypeRepr>(typeRepr))
        TypeRange = InOutTyR->getBase()->getSourceRange();
      if (TypeRange.isInvalid())
        continue;
      
      unsigned StartOffs = SM.getLocOffsetInBuffer(TypeRange.Start, BufferID);
      unsigned EndOffs =
        SM.getLocOffsetInBuffer(Lexer::getLocForEndOfToken(SM, TypeRange.End),
                                BufferID);
      TextRange TR{ StartOffs, EndOffs-StartOffs };
      TextEntity Param(param, Arg, TR, StartOffs);
      Ent.SubEntities.push_back(std::move(Param));
    }
  }
}
Esempio n. 13
0
TypeSubstitutionMap
GenericSignature::getSubstitutionMap(ArrayRef<Substitution> args) const {
  TypeSubstitutionMap subs;
  
  // An empty parameter list gives an empty map.
  if (getGenericParams().empty()) {
    assert(args.empty() && "substitutions but no generic params?!");
    return subs;
  }
  
  // Seed the type map with pre-existing substitutions.
  for (auto depTy : getAllDependentTypes()) {
    auto replacement = args.front().getReplacement();
    args = args.slice(1);
    
    if (auto subTy = depTy->getAs<SubstitutableType>()) {
      subs[subTy->getCanonicalType().getPointer()] = replacement;
    }
    else if (auto dTy = depTy->getAs<DependentMemberType>()) {
      subs[dTy->getCanonicalType().getPointer()] = replacement;
    }
  }
  
  assert(args.empty() && "did not use all substitutions?!");
  return subs;
}
Esempio n. 14
0
// Read a byte and advance D by one byte.
static uint8_t readByte(ArrayRef<uint8_t> &D) {
  if (D.empty())
    fatal("corrupted or unsupported CIE information");
  uint8_t B = D.front();
  D = D.slice(1);
  return B;
}
Esempio n. 15
0
static ManagedValue emitBuiltinAssign(SILGenFunction &SGF,
                                      SILLocation loc,
                                      SubstitutionMap substitutions,
                                      ArrayRef<ManagedValue> args,
                                      SGFContext C) {
  assert(args.size() >= 2 && "assign should have two arguments");
  assert(substitutions.getReplacementTypes().size() == 1 &&
         "assign should have a single substitution");

  // The substitution determines the type of the thing we're destroying.
  CanType assignFormalType =
    substitutions.getReplacementTypes()[0]->getCanonicalType();
  SILType assignType = SGF.getLoweredType(assignFormalType);
  
  // Convert the destination pointer argument to a SIL address.
  SILValue addr = SGF.B.createPointerToAddress(loc,
                                               args.back().getUnmanagedValue(),
                                               assignType.getAddressType(),
                                               /*isStrict*/ true,
                                               /*isInvariant*/ false);
  
  // Build the value to be assigned, reconstructing tuples if needed.
  auto src = RValue(SGF, args.slice(0, args.size() - 1), assignFormalType);
  
  std::move(src).ensurePlusOne(SGF, loc).assignInto(SGF, loc, addr);

  return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc));
}
Esempio n. 16
0
std::error_code
IndexedInstrProfReader::readNextRecord(InstrProfRecord &Record) {
  // Are we out of records?
  if (RecordIterator == Index->data_end())
    return error(instrprof_error::eof);

  // Record the current function name.
  Record.Name = (*RecordIterator).Name;

  ArrayRef<uint64_t> Data = (*RecordIterator).Data;
  // Valid data starts with a hash and either a count or the number of counts.
  if (CurrentOffset + 1 > Data.size())
    return error(instrprof_error::malformed);
  // First we have a function hash.
  Record.Hash = Data[CurrentOffset++];
  // In version 1 we knew the number of counters implicitly, but in newer
  // versions we store the number of counters next.
  uint64_t NumCounts =
      FormatVersion == 1 ? Data.size() - CurrentOffset : Data[CurrentOffset++];
  if (CurrentOffset + NumCounts > Data.size())
    return error(instrprof_error::malformed);
  // And finally the counts themselves.
  Record.Counts = Data.slice(CurrentOffset, NumCounts);

  // If we've exhausted this function's data, increment the record.
  CurrentOffset += NumCounts;
  if (CurrentOffset == Data.size()) {
    ++RecordIterator;
    CurrentOffset = 0;
  }

  return success();
}
Esempio n. 17
0
std::error_code IndexedInstrProfReader::getFunctionCounts(
    StringRef FuncName, uint64_t FuncHash, std::vector<uint64_t> &Counts) {
  auto Iter = Index->find(FuncName);
  if (Iter == Index->end())
    return error(instrprof_error::unknown_function);

  // Found it. Look for counters with the right hash.
  ArrayRef<uint64_t> Data = (*Iter).Data;
  uint64_t NumCounts;
  for (uint64_t I = 0, E = Data.size(); I != E; I += NumCounts) {
    // The function hash comes first.
    uint64_t FoundHash = Data[I++];
    // In v1, we have at least one count. Later, we have the number of counts.
    if (I == E)
      return error(instrprof_error::malformed);
    NumCounts = FormatVersion == 1 ? E - I : Data[I++];
    // If we have more counts than data, this is bogus.
    if (I + NumCounts > E)
      return error(instrprof_error::malformed);
    // Check for a match and fill the vector if there is one.
    if (FoundHash == FuncHash) {
      Counts = Data.slice(I, NumCounts);
      return success();
    }
  }
  return error(instrprof_error::hash_mismatch);
}
Esempio n. 18
0
ErrorOr<const typename MipsELFFile<ELFT>::Elf_Mips_RegInfo *>
MipsELFFile<ELFT>::findRegInfoSec() const {
  using namespace llvm::ELF;
  if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) {
    auto contents = this->getSectionContents(sec);
    if (std::error_code ec = contents.getError())
      return ec;

    ArrayRef<uint8_t> raw = contents.get();
    while (!raw.empty()) {
      if (raw.size() < sizeof(Elf_Mips_Options))
        return make_dynamic_error_code(
            StringRef("Invalid size of MIPS_OPTIONS section"));

      const auto *opt = reinterpret_cast<const Elf_Mips_Options *>(raw.data());
      if (opt->kind == ODK_REGINFO)
        return &opt->getRegInfo();
      raw = raw.slice(opt->size);
    }
  } else if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_REGINFO)) {
    auto contents = this->getSectionContents(sec);
    if (std::error_code ec = contents.getError())
      return ec;

    ArrayRef<uint8_t> raw = contents.get();
    if (raw.size() != sizeof(Elf_Mips_RegInfo))
      return make_dynamic_error_code(
          StringRef("Invalid size of MIPS_REGINFO section"));

    return reinterpret_cast<const Elf_Mips_RegInfo *>(raw.data());
  }
  return nullptr;
}
Esempio n. 19
0
static std::error_code getSymbolAuxData(const COFFObjectFile *Obj,
                                        COFFSymbolRef Symbol,
                                        uint8_t AuxSymbolIdx, const T *&Aux) {
  ArrayRef<uint8_t> AuxData = Obj->getSymbolAuxData(Symbol);
  AuxData = AuxData.slice(AuxSymbolIdx * Obj->getSymbolTableEntrySize());
  Aux = reinterpret_cast<const T*>(AuxData.data());
  return readobj_error::success;
}
Esempio n. 20
0
File: PDB.cpp Progetto: Leedehai/lld
static ArrayRef<uint8_t> consumeDebugMagic(ArrayRef<uint8_t> Data,
                                           StringRef SecName) {
  // First 4 bytes are section magic.
  if (Data.size() < 4)
    fatal(SecName + " too short");
  if (support::endian::read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
    fatal(SecName + " has an invalid magic");
  return Data.slice(4);
}
Esempio n. 21
0
// Skip an integer encoded in the LEB128 format.
// Actual number is not of interest because only the runtime needs it.
// But we need to be at least able to skip it so that we can read
// the field that follows a LEB128 number.
static void skipLeb128(ArrayRef<uint8_t> &D) {
  while (!D.empty()) {
    uint8_t Val = D.front();
    D = D.slice(1);
    if ((Val & 0x80) == 0)
      return;
  }
  fatal("corrupted or unsupported CIE information");
}
Esempio n. 22
0
ArrayRef<typename elf::ObjectFile<ELFT>::Elf_Word>
elf::ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
  const ELFFile<ELFT> &Obj = this->ELFObj;
  ArrayRef<Elf_Word> Entries =
      check(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec));
  if (Entries.empty() || Entries[0] != GRP_COMDAT)
    fatal("unsupported SHT_GROUP format");
  return Entries.slice(1);
}
Esempio n. 23
0
template <class ELFT> static void skipAugP(ArrayRef<uint8_t> &D) {
  uint8_t Enc = readByte(D);
  if ((Enc & 0xf0) == DW_EH_PE_aligned)
    fatal("DW_EH_PE_aligned encoding is not supported");
  size_t Size = getAugPSize<ELFT>(Enc);
  if (Size >= D.size())
    fatal("corrupted CIE");
  D = D.slice(Size);
}
Esempio n. 24
0
// Split non-SHF_STRINGS section. Such section is a sequence of
// fixed size records.
static std::vector<SectionPiece> splitNonStrings(ArrayRef<uint8_t> Data,
                                                 size_t EntSize) {
  std::vector<SectionPiece> V;
  size_t Size = Data.size();
  assert((Size % EntSize) == 0);
  for (unsigned I = 0, N = Size; I != N; I += EntSize)
    V.emplace_back(I, Data.slice(I, EntSize));
  return V;
}
Esempio n. 25
0
// Split non-SHF_STRINGS section. Such section is a sequence of
// fixed size records.
void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data,
                                        size_t EntSize) {
  size_t Size = Data.size();
  assert((Size % EntSize) == 0);
  bool IsAlloc = Flags & SHF_ALLOC;

  for (size_t I = 0; I != Size; I += EntSize)
    Pieces.emplace_back(I, xxHash64(toStringRef(Data.slice(I, EntSize))),
                        !IsAlloc);
}
Esempio n. 26
0
void CorDisasm::printInstruction(const MCInst *MI, size_t Address,
                                 size_t InstSize,
                                 ArrayRef<uint8_t> Bytes) const {
  outs() << format("%8" PRIx64 ":", Address);
  outs() << "\t";
  dumpBytes(Bytes.slice(0, InstSize), outs());

  IP->printInst(MI, outs(), "", *STI);
  outs() << "\n";
}
Esempio n. 27
0
void GenericEnvironment::
getSubstitutionMap(ModuleDecl *mod,
                   GenericSignature *sig,
                   ArrayRef<Substitution> subs,
                   SubstitutionMap &result) const {
  for (auto depTy : sig->getAllDependentTypes()) {

    // Map the interface type to a context type.
    auto contextTy = depTy.subst(mod, InterfaceToArchetypeMap, SubstOptions());
    auto *archetype = contextTy->castTo<ArchetypeType>();

    auto sub = subs.front();
    subs = subs.slice(1);

    // Record the replacement type and its conformances.
    result.addSubstitution(CanType(archetype), sub.getReplacement());
    result.addConformances(CanType(archetype), sub.getConformances());
  }

  for (auto reqt : sig->getRequirements()) {
    if (reqt.getKind() != RequirementKind::SameType)
      continue;

    auto first = reqt.getFirstType()->getAs<DependentMemberType>();
    auto second = reqt.getSecondType()->getAs<DependentMemberType>();

    if (!first || !second)
      continue;

    auto archetype = mapTypeIntoContext(mod, first)->getAs<ArchetypeType>();
    if (!archetype)
      continue;

    auto firstBase = first->getBase();
    auto secondBase = second->getBase();

    auto firstBaseArchetype = mapTypeIntoContext(mod, firstBase)->getAs<ArchetypeType>();
    auto secondBaseArchetype = mapTypeIntoContext(mod, secondBase)->getAs<ArchetypeType>();

    if (!firstBaseArchetype || !secondBaseArchetype)
      continue;

    if (archetype->getParent() != firstBaseArchetype)
      result.addParent(CanType(archetype),
                       CanType(firstBaseArchetype),
                       first->getAssocType());
    if (archetype->getParent() != secondBaseArchetype)
      result.addParent(CanType(archetype),
                       CanType(secondBaseArchetype),
                       second->getAssocType());
  }

  assert(subs.empty() && "did not use all substitutions?!");
}
Esempio n. 28
0
// The length of the header data is always going to be 4 + 4 + 4*NumAtoms.
DwarfAccelTable::DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom> atomList,
                                 bool UseDieOffsets, bool UseStringOffsets)
    : Header(8 + (atomList.size() * 4)), HeaderData(atomList),
      Entries(Allocator), AtomsSize(0), UseDieOffsets(UseDieOffsets),
      UseStringOffsets(UseStringOffsets) {
  assert((atomList[0].type == dwarf::DW_ATOM_ext_types ||
          atomList[0].type == dwarf::DW_ATOM_die_offset) &&
           atomList[0].form == dwarf::DW_FORM_data4);
  for (const auto &Atom : atomList.slice(1))
    AtomsSize += getSizeForForm(Atom.form);
}
Esempio n. 29
0
static void getWitnessMethodSubstitutions(ApplySite AI, SILFunction *F,
                                          ArrayRef<Substitution> Subs,
                                          SmallVectorImpl<Substitution> &NewSubs) {
  auto &Module = AI.getModule();

  auto CalleeCanType = F->getLoweredFunctionType();

  ProtocolDecl *proto = nullptr;
  if (CalleeCanType->getRepresentation() ==
      SILFunctionTypeRepresentation::WitnessMethod) {
    proto = CalleeCanType->getDefaultWitnessMethodProtocol(
        *Module.getSwiftModule());
  }

  ArrayRef<Substitution> origSubs = AI.getSubstitutions();

  if (proto != nullptr) {
    // If the callee is a default witness method thunk, preserve substitutions
    // from the call site.
    NewSubs.append(origSubs.begin(), origSubs.end());
    return;
  }

  // If the callee is a concrete witness method thunk, apply substitutions
  // from the conformance, and drop any substitutions derived from the Self
  // type.
  NewSubs.append(Subs.begin(), Subs.end());

  if (auto generics = AI.getOrigCalleeType()->getGenericSignature()) {
    for (auto genericParam : generics->getAllDependentTypes()) {
      auto origSub = origSubs.front();
      origSubs = origSubs.slice(1);

      // If the callee is a concrete witness method thunk, we ignore
      // generic parameters derived from 'self', the generic parameter at
      // depth 0, index 0.
      auto type = genericParam->getCanonicalType();
      while (auto memberType = dyn_cast<DependentMemberType>(type)) {
        type = memberType.getBase();
      }
      auto paramType = cast<GenericTypeParamType>(type);
      if (paramType->getDepth() == 0) {
        // There shouldn't be any other parameters at this depth.
        assert(paramType->getIndex() == 0);
        continue;
      }

      // Okay, remember this substitution.
      NewSubs.push_back(origSub);
    }
  }

  assert(origSubs.empty() && "subs not parallel to dependent types");
}
Esempio n. 30
0
Expr *TypeChecker::foldSequence(SequenceExpr *expr, DeclContext *dc) {
  ArrayRef<Expr*> Elts = expr->getElements();
  assert(Elts.size() > 1 && "inadequate number of elements in sequence");
  assert((Elts.size() & 1) == 1 && "even number of elements in sequence");

  Expr *LHS = Elts[0];
  Elts = Elts.slice(1);

  Expr *Result = ::foldSequence(*this, dc, LHS, Elts, /*min precedence*/ 0);
  assert(Elts.empty());
  return Result;
}