Example #1
0
Error MappedBlockStream::readBytes(uint32_t Offset,
                                   MutableArrayRef<uint8_t> Buffer) const {
  uint32_t BlockNum = Offset / Pdb.getBlockSize();
  uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();

  // Make sure we aren't trying to read beyond the end of the stream.
  if (Buffer.size() > Data->getLength())
    return make_error<RawError>(raw_error_code::insufficient_buffer);
  if (Offset > Data->getLength() - Buffer.size())
    return make_error<RawError>(raw_error_code::insufficient_buffer);

  uint32_t BytesLeft = Buffer.size();
  uint32_t BytesWritten = 0;
  uint8_t *WriteBuffer = Buffer.data();
  auto BlockList = Data->getStreamBlocks();
  while (BytesLeft > 0) {
    uint32_t StreamBlockAddr = BlockList[BlockNum];

    auto Data = Pdb.getBlockData(StreamBlockAddr, Pdb.getBlockSize());

    const uint8_t *ChunkStart = Data.data() + OffsetInBlock;
    uint32_t BytesInChunk =
        std::min(BytesLeft, Pdb.getBlockSize() - OffsetInBlock);
    ::memcpy(WriteBuffer + BytesWritten, ChunkStart, BytesInChunk);

    BytesWritten += BytesInChunk;
    BytesLeft -= BytesInChunk;
    ++BlockNum;
    OffsetInBlock = 0;
  }

  return Error::success();
}
Example #2
0
std::error_code ByteStream::readBytes(uint32_t Offset,
                                      MutableArrayRef<uint8_t> Buffer) const {
  if (Data.size() < Buffer.size() + Offset)
    return std::make_error_code(std::errc::bad_address);
  ::memcpy(Buffer.data(), Data.data() + Offset, Buffer.size());
  return std::error_code();
}
Example #3
0
Error MappedBlockStream::readBytes(uint32_t Offset,
                                   MutableArrayRef<uint8_t> Buffer) const {
  uint32_t BlockNum = Offset / BlockSize;
  uint32_t OffsetInBlock = Offset % BlockSize;

  // Make sure we aren't trying to read beyond the end of the stream.
  if (Buffer.size() > StreamLayout.Length)
    return make_error<MSFError>(msf_error_code::insufficient_buffer);
  if (Offset > StreamLayout.Length - Buffer.size())
    return make_error<MSFError>(msf_error_code::insufficient_buffer);

  uint32_t BytesLeft = Buffer.size();
  uint32_t BytesWritten = 0;
  uint8_t *WriteBuffer = Buffer.data();
  while (BytesLeft > 0) {
    uint32_t StreamBlockAddr = StreamLayout.Blocks[BlockNum];

    ArrayRef<uint8_t> BlockData;
    uint32_t Offset = blockToOffset(StreamBlockAddr, BlockSize);
    if (auto EC = MsfData.readBytes(Offset, BlockSize, BlockData))
      return EC;

    const uint8_t *ChunkStart = BlockData.data() + OffsetInBlock;
    uint32_t BytesInChunk = std::min(BytesLeft, BlockSize - OffsetInBlock);
    ::memcpy(WriteBuffer + BytesWritten, ChunkStart, BytesInChunk);

    BytesWritten += BytesInChunk;
    BytesLeft -= BytesInChunk;
    ++BlockNum;
    OffsetInBlock = 0;
  }

  return Error::success();
}
Example #4
0
Error ByteStream::readBytes(uint32_t Offset,
                            MutableArrayRef<uint8_t> Buffer) const {
  if (Data.size() < Buffer.size() + Offset)
    return make_error<RawError>(raw_error_code::insufficient_buffer);
  ::memcpy(Buffer.data(), Data.data() + Offset, Buffer.size());
  return Error::success();
}
Example #5
0
static Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Src,
                        MutableArrayRef<uint8_t> Dest) {
  if (Dest.size() < Src.size())
    return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
  if (Offset > Src.size() - Dest.size())
    return make_error<CodeViewError>(cv_error_code::insufficient_buffer);

  ::memcpy(Dest.data() + Offset, Src.data(), Src.size());
  return Error::success();
}
Example #6
0
size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
                            bool ShouldSkipSpace) {
  const char *SavedTokStart = TokStart;
  const char *SavedCurPtr = CurPtr;
  bool SavedAtStartOfLine = IsAtStartOfLine;
  bool SavedAtStartOfStatement = IsAtStartOfStatement;
  bool SavedSkipSpace = SkipSpace;

  std::string SavedErr = getErr();
  SMLoc SavedErrLoc = getErrLoc();

  SkipSpace = ShouldSkipSpace;

  size_t ReadCount;
  for (ReadCount = 0; ReadCount < Buf.size(); ++ReadCount) {
    AsmToken Token = LexToken();

    Buf[ReadCount] = Token;

    if (Token.is(AsmToken::Eof))
      break;
  }

  SetError(SavedErrLoc, SavedErr);

  SkipSpace = SavedSkipSpace;
  IsAtStartOfLine = SavedAtStartOfLine;
  IsAtStartOfStatement = SavedAtStartOfStatement;
  CurPtr = SavedCurPtr;
  TokStart = SavedTokStart;

  return ReadCount;
}
Example #7
0
void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                 const MCValue &Target,
                                 MutableArrayRef<char> Data, uint64_t Value,
                                 bool IsResolved,
                                 const MCSubtargetInfo *STI) const {
  MCContext &Ctx = Asm.getContext();
  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
  if (!Value)
    return; // Doesn't change encoding.
  // Apply any target-specific value adjustments.
  Value = adjustFixupValue(Fixup, Value, Ctx);

  // Shift the value into position.
  Value <<= Info.TargetOffset;

  unsigned Offset = Fixup.getOffset();
  unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8;

  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");

  // For each byte of the fragment that the fixup touches, mask in the
  // bits from the fixup value.
  for (unsigned i = 0; i != NumBytes; ++i) {
    Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
  }
}
Example #8
0
void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                   const MCValue &Target,
                                   MutableArrayRef<char> Data, uint64_t Value,
                                   bool IsResolved) const {
  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
  if (!Value)
    return; // Doesn't change encoding.
  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
  MCContext &Ctx = Asm.getContext();
  // Apply any target-specific value adjustments.
  Value = adjustFixupValue(Fixup, Value, Ctx);

  // Shift the value into position.
  Value <<= Info.TargetOffset;

  unsigned Offset = Fixup.getOffset();
  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");

  // Used to point to big endian bytes.
  unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(Fixup.getKind());

  // For each byte of the fragment that the fixup touches, mask in the
  // bits from the fixup value.
  if (FulleSizeInBytes == 0) {
    // Handle as little-endian
    for (unsigned i = 0; i != NumBytes; ++i) {
      Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
    }
  } else {
Example #9
0
void ABISignature::expand(GenIR &Reader,
                          ArrayRef<ABIArgInfo::Expansion> Expansions,
                          Value *Source, MutableArrayRef<Value *> Values,
                          MutableArrayRef<Type *> Types, bool IsResult) {
  assert(Source != nullptr);
  assert(Source->getType()->isPointerTy());
  assert(Reader.doesValueRepresentStruct(Source));
  assert(Expansions.size() > 0);
  assert((IsResult && Values.size() == 1) ||
         (Values.size() == Expansions.size()));

  LLVMContext &LLVMContext = *Reader.JitContext->LLVMContext;
  IRBuilder<> &Builder = *Reader.LLVMBuilder;

  Type *ResultType = nullptr;
  Value *ResultValue = nullptr;
  if (IsResult) {
    ResultType = getExpandedResultType(LLVMContext, Expansions);
    ResultValue = Constant::getNullValue(ResultType);
  }

  Type *BytePtrTy = Type::getInt8PtrTy(LLVMContext, 0);
  Value *SourcePtr = Builder.CreatePointerCast(Source, BytePtrTy);
  for (int32_t I = 0; I < static_cast<int32_t>(Expansions.size()); I++) {
    const ABIArgInfo::Expansion &Exp = Expansions[I];
    Value *LoadPtr = Builder.CreateConstGEP1_32(SourcePtr, Exp.Offset);
    LoadPtr = Builder.CreatePointerCast(LoadPtr, Exp.TheType->getPointerTo(0));
    const bool IsVolatile = false;
    Value *Value = Builder.CreateLoad(LoadPtr, IsVolatile);

    if (IsResult) {
      ResultValue = Builder.CreateInsertValue(ResultValue, Value, I);
    } else {
      Values[I] = Value;
    }

    if (Types.size() > 0) {
      Types[I] = Exp.TheType;
    }
  }

  if (IsResult) {
    Values[0] = ResultValue;
  }
}
Example #10
0
File: PDB.cpp Project: Leedehai/lld
static bool remapTypesInSymbolRecord(ObjectFile *File,
                                     MutableArrayRef<uint8_t> Contents,
                                     ArrayRef<TypeIndex> TypeIndexMap,
                                     ArrayRef<TiReference> TypeRefs) {
  for (const TiReference &Ref : TypeRefs) {
    unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
    if (Contents.size() < Ref.Offset + ByteSize) {
      log("ignoring short symbol record");
      return false;
    }
    MutableArrayRef<TypeIndex> TIs(
        reinterpret_cast<TypeIndex *>(Contents.data() + Ref.Offset), Ref.Count);
    for (TypeIndex &TI : TIs)
      if (!remapTypeIndex(TI, TypeIndexMap)) {
        log("ignoring symbol record in " + File->getName() +
            " with bad type index 0x" + utohexstr(TI.getIndex()));
        return false;
      }
  }
  return true;
}
Example #11
0
void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                  const MCValue &Target,
                                  MutableArrayRef<char> Data, uint64_t Value,
                                  bool IsResolved,
                                  const MCSubtargetInfo *STI) const {
  Value = adjustFixupValue(Fixup, Value, &Asm.getContext());
  if (!Value)
    return; // Doesn't change encoding.

  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());

  // Shift the value into position.
  Value <<= Info.TargetOffset;

  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
  uint32_t Offset = Fixup.getOffset();
  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");

  // For each byte of the fragment that the fixup touches, mask in the bits from
  // the fixup value.
  for (unsigned i = 0; i != NumBytes; ++i)
    Data[Offset + i] |= static_cast<uint8_t>((Value >> (i * 8)) & 0xff);
}
Example #12
0
CharTypeSet calculateRoles(StringRef Text, MutableArrayRef<CharRole> Roles) {
  assert(Text.size() == Roles.size());
  if (Text.size() == 0)
    return 0;
  CharType Type = packedLookup<CharType>(CharTypes, Text[0]);
  CharTypeSet TypeSet = 1 << Type;
  // Types holds a sliding window of (Prev, Curr, Next) types.
  // Initial value is (Empty, Empty, type of Text[0]).
  int Types = Type;
  // Rotate slides in the type of the next character.
  auto Rotate = [&](CharType T) { Types = ((Types << 2) | T) & 0x3f; };
  for (unsigned I = 0; I < Text.size() - 1; ++I) {
    // For each character, rotate in the next, and look up the role.
    Type = packedLookup<CharType>(CharTypes, Text[I + 1]);
    TypeSet |= 1 << Type;
    Rotate(Type);
    Roles[I] = packedLookup<CharRole>(CharRoles, Types);
  }
  // For the last character, the "next character" is Empty.
  Rotate(Empty);
  Roles[Text.size() - 1] = packedLookup<CharRole>(CharRoles, Types);
  return TypeSet;
}
Example #13
0
size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
                            bool ShouldSkipSpace) {
  SaveAndRestore<const char *> SavedTokenStart(TokStart);
  SaveAndRestore<const char *> SavedCurPtr(CurPtr);
  SaveAndRestore<bool> SavedAtStartOfLine(IsAtStartOfLine);
  SaveAndRestore<bool> SavedAtStartOfStatement(IsAtStartOfStatement);
  SaveAndRestore<bool> SavedSkipSpace(SkipSpace, ShouldSkipSpace);
  SaveAndRestore<bool> SavedIsPeeking(IsPeeking, true);
  std::string SavedErr = getErr();
  SMLoc SavedErrLoc = getErrLoc();

  size_t ReadCount;
  for (ReadCount = 0; ReadCount < Buf.size(); ++ReadCount) {
    AsmToken Token = LexToken();

    Buf[ReadCount] = Token;

    if (Token.is(AsmToken::Eof))
      break;
  }

  SetError(SavedErrLoc, SavedErr);
  return ReadCount;
}
Example #14
0
void Scope::popPreservingValues(ArrayRef<ManagedValue> innerValues,
                                MutableArrayRef<ManagedValue> outerValues) {
  auto &SGF = cleanups.SGF;
  assert(innerValues.size() == outerValues.size());

  // Record the cleanup information for each preserved value and deactivate its
  // cleanup.
  SmallVector<CleanupCloner, 4> cleanups;
  cleanups.reserve(innerValues.size());
  for (auto &mv : innerValues) {
    cleanups.emplace_back(SGF, mv);
    mv.forward(SGF);
  }

  // Pop any unpreserved cleanups.
  pop();

  // Create a managed value for each preserved value, cloning its cleanup.
  // Since the CleanupCloner does not remember its SILValue, grab it from the
  // original, now-deactivated managed value.
  for (auto index : indices(innerValues)) {
    outerValues[index] = cleanups[index].clone(innerValues[index].getValue());
  }
}
Example #15
0
bool swift::omitNeedlessWords(StringRef &baseName,
                              MutableArrayRef<StringRef> argNames,
                              StringRef firstParamName,
                              OmissionTypeName resultType,
                              OmissionTypeName contextType,
                              ArrayRef<OmissionTypeName> paramTypes,
                              bool returnsSelf,
                              bool isProperty,
                              const InheritedNameSet *allPropertyNames,
                              StringScratchSpace &scratch) {
  bool anyChanges = false;

  /// Local function that lowercases all of the base names and
  /// argument names before returning.
  auto lowercaseAcronymsForReturn = [&] {
    StringRef newBaseName = toLowercaseWordAndAcronym(baseName, scratch);
    if (baseName.data() != newBaseName.data()) {
      baseName = newBaseName;
      anyChanges = true;
    }

    for (StringRef &argName : argNames) {
      StringRef newArgName = toLowercaseWordAndAcronym(argName, scratch);
      if (argName.data() != newArgName.data()) {
        argName = newArgName;
        anyChanges = true;
      }
    }

    return anyChanges;
  };

  // If the result type matches the context, remove the context type from the
  // prefix of the name.
  bool resultTypeMatchesContext = returnsSelf || (resultType == contextType);
  if (resultTypeMatchesContext) {
    StringRef newBaseName = omitNeedlessWordsFromPrefix(baseName, contextType,
                                                        scratch);
    if (newBaseName != baseName) {
      baseName = newBaseName;
      anyChanges = true;
    }
  }

  // Strip the context type from the base name of a method.
  if (!isProperty) {
    StringRef newBaseName = ::omitNeedlessWords(baseName, contextType,
                                                NameRole::BaseNameSelf,
                                                nullptr, scratch);
    if (newBaseName != baseName) {
      baseName = newBaseName;
      anyChanges = true;
    }
  }

  if (paramTypes.empty()) {
    if (resultTypeMatchesContext) {
      StringRef newBaseName = ::omitNeedlessWords(
                                baseName,
                                returnsSelf ? contextType : resultType,
                                NameRole::Property,
                                allPropertyNames,
                                scratch);
      if (newBaseName != baseName) {
        baseName = newBaseName;
        anyChanges = true;
      }
    }

    return lowercaseAcronymsForReturn();
  }

  // Omit needless words based on parameter types.
  for (unsigned i = 0, n = argNames.size(); i != n; ++i) {
    // If there is no corresponding parameter, there is nothing to
    // omit.
    if (i >= paramTypes.size()) continue;

    // Omit needless words based on the type of the parameter.
    NameRole role = i > 0 ? NameRole::SubsequentParameter
      : argNames[0].empty() ? NameRole::BaseName
      : NameRole::FirstParameter;

    // Omit needless words from the name.
    StringRef name = role == NameRole::BaseName ? baseName : argNames[i];
    StringRef newName = ::omitNeedlessWords(name, paramTypes[i], role,
                                            role == NameRole::BaseName 
                                              ? allPropertyNames
                                              : nullptr,
                                            scratch);

    // Did the name change?
    if (name != newName)
      anyChanges = true;

    // If the first parameter has a default argument, and there is a
    // preposition in the base name, split the base name at that preposition.
    if (role == NameRole::BaseName && argNames[0].empty() &&
        paramTypes[0].hasDefaultArgument()) {
      // Scan backwards for a preposition.
      auto nameWords = camel_case::getWords(newName);
      auto nameWordRevIter = nameWords.rbegin(),
        nameWordRevIterEnd = nameWords.rend();
      bool found = false, done = false;
      while (nameWordRevIter != nameWordRevIterEnd && !done) {
        switch (getPartOfSpeech(*nameWordRevIter)) {
        case PartOfSpeech::Preposition:
          found = true;
          done = true;
          break;

        case PartOfSpeech::Verb:
        case PartOfSpeech::Gerund:
          // Don't skip over verbs or gerunds.
          done = true;
          break;

        case PartOfSpeech::Unknown:
          ++nameWordRevIter;
          break;
        }
      }

      // If we found a split point that's not at the beginning of the
      // name, split there.
      if (found) {
        ++nameWordRevIter;
        unsigned splitPos = nameWordRevIter.base().getPosition();
        if (splitPos > 0) {
          unsigned afterSplitPos = splitPos;

          // Create a first argument name with the remainder of the base name,
          // lowercased. If we would end up with a vacuous name, go
          // back and get the original.
          StringRef newArgName = newName.substr(afterSplitPos);
          if (isVacuousName(newArgName)) {
            size_t pos = name.rfind(newArgName);
            newArgName = name.substr(pos);
          }

          // If there is a leading "with" on the first argument, drop it.
          if (newArgName.size() > 4 &&
              camel_case::sameWordIgnoreFirstCase(
                camel_case::getFirstWord(newArgName),
                "with")) {
            newArgName = newArgName.substr(4);
          }

          argNames[0] = toLowercaseWord(newArgName, scratch);

          // Update the base name by splitting at the preposition.
          newName = newName.substr(0, splitPos);

          anyChanges = true;
        }
      }
    }

    if (name == newName) continue;

    // Record this change.
    if (role == NameRole::BaseName) {
      baseName = newName;
    } else {
      argNames[i] = newName;
    }
  }

  return lowercaseAcronymsForReturn();
}
Example #16
0
static void emitSubSwitch(IRGenFunction &IGF,
                    MutableArrayRef<EnumPayload::LazyValue> values,
                    APInt mask,
                    MutableArrayRef<std::pair<APInt, llvm::BasicBlock *>> cases,
                    SwitchDefaultDest dflt) {
recur:
  assert(!values.empty() && "didn't exit out when exhausting all values?!");
  
  assert(!cases.empty() && "switching with no cases?!");
  
  auto &DL = IGF.IGM.DataLayout;
  auto &pv = values.front();
  values = values.slice(1);
  auto payloadTy = getPayloadType(pv);
  unsigned size = DL.getTypeSizeInBits(payloadTy);
  
  // Grab a chunk of the mask.
  auto maskPiece = mask.zextOrTrunc(size);
  mask = mask.lshr(size);
  
  // If the piece is zero, this doesn't affect the switch. We can just move
  // forward and recur.
  if (maskPiece == 0) {
    for (auto &casePair : cases)
      casePair.first = casePair.first.lshr(size);
    goto recur;
  }
  
  // Force the value we will test.
  auto v = forcePayloadValue(pv);
  auto payloadIntTy = llvm::IntegerType::get(IGF.IGM.getLLVMContext(), size);
  
  // Need to coerce to integer for 'icmp eq' if it's not already an integer
  // or pointer. (Switching or masking will also require a cast to integer.)
  if (!isa<llvm::IntegerType>(v->getType())
      && !isa<llvm::PointerType>(v->getType()))
    v = IGF.Builder.CreateBitOrPointerCast(v, payloadIntTy);
  
  // Apply the mask if it's interesting.
  if (!maskPiece.isAllOnesValue()) {
    v = IGF.Builder.CreateBitOrPointerCast(v, payloadIntTy);
    auto maskConstant = llvm::ConstantInt::get(payloadIntTy, maskPiece);
    v = IGF.Builder.CreateAnd(v, maskConstant);
  }
  
  // Gather the values we will switch over for this payload chunk.
  // FIXME: std::map is lame. Should hash APInts.
  std::map<APInt, SmallVector<std::pair<APInt, llvm::BasicBlock*>, 2>, ult>
    subCases;
  
  for (auto casePair : cases) {
    // Grab a chunk of the value.
    auto valuePiece = casePair.first.zextOrTrunc(size);
    // Index the case according to this chunk.
    subCases[valuePiece].push_back({std::move(casePair.first).lshr(size),
                                    casePair.second});
  }
  
  bool needsAdditionalCases = !values.empty() && mask != 0;
  SmallVector<std::pair<llvm::BasicBlock *, decltype(cases)>, 2> recursiveCases;
  
  auto blockForCases
    = [&](MutableArrayRef<std::pair<APInt, llvm::BasicBlock*>> cases)
        -> llvm::BasicBlock *
    {
      // If we need to recur, emit a new block.
      if (needsAdditionalCases) {
        auto newBB = IGF.createBasicBlock("");
        recursiveCases.push_back({newBB, cases});
        return newBB;
      }
      // Otherwise, we can jump directly to the ultimate destination.
      assert(cases.size() == 1 && "more than one case for final destination?!");
      return cases.front().second;
    };
  
  // If there's only one case, do a cond_br.
  if (subCases.size() == 1) {
    auto &subCase = *subCases.begin();
    llvm::BasicBlock *block = blockForCases(subCase.second);
    // If the default case is unreachable, we don't need to conditionally
    // branch.
    if (dflt.getInt()) {
      IGF.Builder.CreateBr(block);
      goto next;
    }
  
    auto &valuePiece = subCase.first;
    llvm::Value *valueConstant = llvm::ConstantInt::get(payloadIntTy,
                                                        valuePiece);
    valueConstant = IGF.Builder.CreateBitOrPointerCast(valueConstant,
                                                       v->getType());
    auto cmp = IGF.Builder.CreateICmpEQ(v, valueConstant);
    IGF.Builder.CreateCondBr(cmp, block, dflt.getPointer());
    goto next;
  }
  
  // Otherwise, do a switch.
  {
    v = IGF.Builder.CreateBitOrPointerCast(v, payloadIntTy);
    auto swi = IGF.Builder.CreateSwitch(v, dflt.getPointer(), subCases.size());
    
    for (auto &subCase : subCases) {
      auto &valuePiece = subCase.first;
      auto valueConstant = llvm::ConstantInt::get(IGF.IGM.getLLVMContext(),
                                                  valuePiece);

      swi->addCase(valueConstant, blockForCases(subCase.second));
    }
  }
  
next:
  // Emit the recursive cases.
  for (auto &recursive : recursiveCases) {
    IGF.Builder.emitBlock(recursive.first);
    emitSubSwitch(IGF, values, mask, recursive.second, dflt);
  }
}
Example #17
0
bool TargetInfo::validateInputConstraint(
                              MutableArrayRef<ConstraintInfo> OutputConstraints,
                              ConstraintInfo &Info) const {
  const char *Name = Info.ConstraintStr.c_str();

  if (!*Name)
    return false;

  while (*Name) {
    switch (*Name) {
    default:
      // Check if we have a matching constraint
      if (*Name >= '0' && *Name <= '9') {
        const char *DigitStart = Name;
        while (Name[1] >= '0' && Name[1] <= '9')
          Name++;
        const char *DigitEnd = Name;
        unsigned i;
        if (StringRef(DigitStart, DigitEnd - DigitStart + 1)
                .getAsInteger(10, i))
          return false;

        // Check if matching constraint is out of bounds.
        if (i >= OutputConstraints.size()) return false;

        // A number must refer to an output only operand.
        if (OutputConstraints[i].isReadWrite())
          return false;

        // If the constraint is already tied, it must be tied to the
        // same operand referenced to by the number.
        if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
          return false;

        // The constraint should have the same info as the respective
        // output constraint.
        Info.setTiedOperand(i, OutputConstraints[i]);
      } else if (!validateAsmConstraint(Name, Info)) {
        // FIXME: This error return is in place temporarily so we can
        // add more constraints as we hit it.  Eventually, an unknown
        // constraint should just be treated as 'g'.
        return false;
      }
      break;
    case '[': {
      unsigned Index = 0;
      if (!resolveSymbolicName(Name, OutputConstraints, Index))
        return false;

      // If the constraint is already tied, it must be tied to the
      // same operand referenced to by the number.
      if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
        return false;

      // A number must refer to an output only operand.
      if (OutputConstraints[Index].isReadWrite())
        return false;

      Info.setTiedOperand(Index, OutputConstraints[Index]);
      break;
    }
    case '%': // commutative
      // FIXME: Fail if % is used with the last operand.
      break;
    case 'i': // immediate integer.
    case 'n': // immediate integer with a known value.
      break;
    case 'I':  // Various constant constraints with target-specific meanings.
    case 'J':
    case 'K':
    case 'L':
    case 'M':
    case 'N':
    case 'O':
    case 'P':
      if (!validateAsmConstraint(Name, Info))
        return false;
      break;
    case 'r': // general register.
      Info.setAllowsRegister();
      break;
    case 'm': // memory operand.
    case 'o': // offsettable memory operand.
    case 'V': // non-offsettable memory operand.
    case '<': // autodecrement memory operand.
    case '>': // autoincrement memory operand.
      Info.setAllowsMemory();
      break;
    case 'g': // general register, memory operand or immediate integer.
    case 'X': // any operand.
      Info.setAllowsRegister();
      Info.setAllowsMemory();
      break;
    case 'E': // immediate floating point.
    case 'F': // immediate floating point.
    case 'p': // address operand.
      break;
    case ',': // multiple alternative constraint.  Ignore comma.
      break;
    case '#': // Ignore as constraint.
      while (Name[1] && Name[1] != ',')
        Name++;
      break;
    case '?': // Disparage slightly code.
    case '!': // Disparage severely.
    case '*': // Ignore for choosing register preferences.
      break;  // Pass them.
    }

    Name++;
  }

  return true;
}
Example #18
0
WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
                                                 endianness Endian)
    : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
                          0, Data.size()) {}
Example #19
0
bool swift::omitNeedlessWords(StringRef &baseName,
                              MutableArrayRef<StringRef> argNames,
                              StringRef firstParamName,
                              OmissionTypeName resultType,
                              OmissionTypeName contextType,
                              ArrayRef<OmissionTypeName> paramTypes,
                              bool returnsSelf,
                              bool isProperty,
                              const InheritedNameSet *allPropertyNames,
                              StringScratchSpace &scratch) {
  bool anyChanges = false;

  /// Local function that lowercases all of the base names and
  /// argument names before returning.
  auto lowercaseAcronymsForReturn = [&] {
    StringRef newBaseName = toLowercaseInitialisms(baseName, scratch);
    if (baseName.data() != newBaseName.data()) {
      baseName = newBaseName;
      anyChanges = true;
    }

    for (StringRef &argName : argNames) {
      StringRef newArgName = toLowercaseInitialisms(argName, scratch);
      if (argName.data() != newArgName.data()) {
        argName = newArgName;
        anyChanges = true;
      }
    }

    return anyChanges;
  };

  // If the result type matches the context, remove the context type from the
  // prefix of the name.
  bool resultTypeMatchesContext = returnsSelf || (resultType == contextType);
  if (resultTypeMatchesContext) {
    StringRef newBaseName = omitNeedlessWordsFromPrefix(baseName, contextType,
                                                        scratch);
    if (newBaseName != baseName) {
      baseName = newBaseName;
      anyChanges = true;
    }
  }

  // Strip the context type from the base name of a method.
  if (!isProperty) {
    StringRef newBaseName = ::omitNeedlessWords(baseName, contextType,
                                                NameRole::BaseNameSelf,
                                                allPropertyNames, scratch);
    if (newBaseName != baseName) {
      baseName = newBaseName;
      anyChanges = true;
    }
  }

  if (paramTypes.empty()) {
    if (resultTypeMatchesContext) {
      StringRef newBaseName = ::omitNeedlessWords(
                                baseName,
                                returnsSelf ? contextType : resultType,
                                NameRole::Property,
                                allPropertyNames,
                                scratch);
      if (newBaseName != baseName) {
        baseName = newBaseName;
        anyChanges = true;
      }
    }

    return lowercaseAcronymsForReturn();
  }

  // If needed, split the base name.
  if (!argNames.empty() &&
      splitBaseName(baseName, argNames[0], paramTypes[0], firstParamName))
    anyChanges = true;

  // Omit needless words based on parameter types.
  for (unsigned i = 0, n = argNames.size(); i != n; ++i) {
    // If there is no corresponding parameter, there is nothing to
    // omit.
    if (i >= paramTypes.size()) continue;

    // Omit needless words based on the type of the parameter.
    NameRole role = i > 0 ? NameRole::SubsequentParameter
      : argNames[0].empty() ? NameRole::BaseName
      : baseName == "init" ? NameRole::SubsequentParameter
      : NameRole::FirstParameter;

    // Omit needless words from the name.
    StringRef name = role == NameRole::BaseName ? baseName : argNames[i];
    StringRef newName = ::omitNeedlessWords(name, paramTypes[i], role,
                                            role == NameRole::BaseName 
                                              ? allPropertyNames
                                              : nullptr,
                                            scratch);

    if (name == newName) continue;

    // Record this change.
    anyChanges = true;
    if (role == NameRole::BaseName) {
      baseName = newName;
    } else {
      argNames[i] = newName;
    }
  }

  return lowercaseAcronymsForReturn();
}