Пример #1
0
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
/// and the specified name as the global variable name.  GVName must not be
/// empty.
void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
                                const Twine &GVName, ManglerPrefixTy PrefixTy) {
  SmallString<256> TmpData;
  StringRef Name = GVName.toStringRef(TmpData);
  assert(!Name.empty() && "getNameWithPrefix requires non-empty name");

  // If the global name is not led with \1, add the appropriate prefixes.
  if (Name[0] == '\1') {
    Name = Name.substr(1);
  } else {
    if (PrefixTy == Mangler::Private) {
      const char *Prefix = DL->getPrivateGlobalPrefix();
      OutName.append(Prefix, Prefix+strlen(Prefix));
    } else if (PrefixTy == Mangler::LinkerPrivate) {
      const char *Prefix = DL->getLinkerPrivateGlobalPrefix();
      OutName.append(Prefix, Prefix+strlen(Prefix));
    }

    char Prefix = DL->getGlobalPrefix();
    if (Prefix != '\0')
      OutName.push_back(Prefix);
  }

  // If this is a simple string that doesn't need escaping, just append it.
  OutName.append(Name.begin(), Name.end());
}
Пример #2
0
static std::error_code getHostID(SmallVectorImpl<char> &HostID) {
    HostID.clear();

#if USE_OSX_GETHOSTUUID
    // On OS X, use the more stable hardware UUID instead of hostname.
    struct timespec wait = {1, 0}; // 1 second.
    uuid_t uuid;
    if (gethostuuid(uuid, &wait) != 0)
        return std::error_code(errno, std::system_category());

    uuid_string_t UUIDStr;
    uuid_unparse(uuid, UUIDStr);
    StringRef UUIDRef(UUIDStr);
    HostID.append(UUIDRef.begin(), UUIDRef.end());

#elif LLVM_ON_UNIX
    char HostName[256];
    HostName[255] = 0;
    HostName[0] = 0;
    gethostname(HostName, 255);
    StringRef HostNameRef(HostName);
    HostID.append(HostNameRef.begin(), HostNameRef.end());

#else
    StringRef Dummy("localhost");
    HostID.append(Dummy.begin(), Dummy.end());
#endif

    return std::error_code();
}
Пример #3
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");
}
Пример #4
0
static void constexprToEdges(CFLAAResult &Analysis,
                             ConstantExpr &CExprToCollapse,
                             SmallVectorImpl<Edge> &Results,
                             const TargetLibraryInfo &TLI) {
  SmallVector<ConstantExpr *, 4> Worklist;
  Worklist.push_back(&CExprToCollapse);

  SmallVector<Edge, 8> ConstexprEdges;
  SmallPtrSet<ConstantExpr *, 4> Visited;
  while (!Worklist.empty()) {
    auto *CExpr = Worklist.pop_back_val();

    if (!hasUsefulEdges(CExpr))
      continue;

    ConstexprEdges.clear();
    argsToEdges(Analysis, CExpr, ConstexprEdges, TLI);
    for (auto &Edge : ConstexprEdges) {
      if (auto *Nested = dyn_cast<ConstantExpr>(Edge.From))
        if (Visited.insert(Nested).second)
          Worklist.push_back(Nested);

      if (auto *Nested = dyn_cast<ConstantExpr>(Edge.To))
        if (Visited.insert(Nested).second)
          Worklist.push_back(Nested);
    }

    Results.append(ConstexprEdges.begin(), ConstexprEdges.end());
  }
}
Пример #5
0
StringRef HeaderMap::lookupFilename(StringRef Filename,
                                    SmallVectorImpl<char> &DestPath) const {
  const HMapHeader &Hdr = getHeader();
  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);

  // If the number of buckets is not a power of two, the headermap is corrupt.
  // Don't probe infinitely.
  if (NumBuckets & (NumBuckets-1))
    return StringRef();

  // Linearly probe the hash table.
  for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) {
    HMapBucket B = getBucket(Bucket & (NumBuckets-1));
    if (B.Key == HMAP_EmptyBucketKey) return StringRef(); // Hash miss.

    // See if the key matches.  If not, probe on.
    if (!Filename.equals_lower(getString(B.Key)))
      continue;

    // If so, we have a match in the hash table.  Construct the destination
    // path.
    StringRef Prefix = getString(B.Prefix);
    StringRef Suffix = getString(B.Suffix);
    DestPath.clear();
    DestPath.append(Prefix.begin(), Prefix.end());
    DestPath.append(Suffix.begin(), Suffix.end());
    return StringRef(DestPath.begin(), DestPath.size());
  }
}
Пример #6
0
StringRef HeaderMapImpl::lookupFilename(StringRef Filename,
                                        SmallVectorImpl<char> &DestPath) const {
  const HMapHeader &Hdr = getHeader();
  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);

  // Don't probe infinitely.  This should be checked before constructing.
  assert(llvm::isPowerOf2_32(NumBuckets) && "Expected power of 2");

  // Linearly probe the hash table.
  for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) {
    HMapBucket B = getBucket(Bucket & (NumBuckets-1));
    if (B.Key == HMAP_EmptyBucketKey) return StringRef(); // Hash miss.

    // See if the key matches.  If not, probe on.
    Optional<StringRef> Key = getString(B.Key);
    if (LLVM_UNLIKELY(!Key))
      continue;
    if (!Filename.equals_lower(*Key))
      continue;

    // If so, we have a match in the hash table.  Construct the destination
    // path.
    Optional<StringRef> Prefix = getString(B.Prefix);
    Optional<StringRef> Suffix = getString(B.Suffix);

    DestPath.clear();
    if (LLVM_LIKELY(Prefix && Suffix)) {
      DestPath.append(Prefix->begin(), Prefix->end());
      DestPath.append(Suffix->begin(), Suffix->end());
    }
    return StringRef(DestPath.begin(), DestPath.size());
  }
}
Пример #7
0
    // following functions are shamelessly copied from LLVM.
    bool isPotentiallyReachableFromMany(SmallVectorImpl<BasicBlock *> &Worklist, BasicBlock *StopBB) {

        // Limit the number of blocks we visit. The goal is to avoid run-away compile
        // times on large CFGs without hampering sensible code. Arbitrarily chosen.
        unsigned Limit = 32;
        SmallSet<const BasicBlock*, 64> Visited;
        do {
            BasicBlock *BB = Worklist.pop_back_val();
            if (!Visited.insert(BB).second)
                continue;
            if (BB == StopBB)
                return true;

            if (!--Limit) {
                // We haven't been able to prove it one way or the other. Conservatively
                // answer true -- that there is potentially a path.
                return true;
            }
            Worklist.append(succ_begin(BB), succ_end(BB));
        } while (!Worklist.empty());

        // We have exhausted all possible paths and are certain that 'To' can not be
        // reached from 'From'.
        return false;
    }
Пример #8
0
error_code llvmutil_createtemporaryfile(const Twine &Prefix, StringRef Suffix, SmallVectorImpl<char> &ResultPath) {
    llvm::sys::Path P("/tmp");
    P.appendComponent(Prefix.str());
    P.appendSuffix(Suffix);
    P.makeUnique(false,NULL);
    StringRef str = P.str();
    ResultPath.append(str.begin(),str.end());
    return error_code();
}
Пример #9
0
static void getPath(SmallVectorImpl<char> &Path, const MDNode *MD) {
	if(MD==NULL)
		return;
	StringRef Filename = DIScope(MD).getFilename();
	if (sys::path::is_absolute(Filename))
		Path.append(Filename.begin(), Filename.end());
	else
		sys::path::append(Path, DIScope(MD).getDirectory(), Filename);
}
Пример #10
0
static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
                               StringRef Modifier, StringRef Argument,
                               ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
                               SmallVectorImpl<char> &Output,
                               void *Cookie,
                               ArrayRef<intptr_t> QualTypeVals) {
    StringRef Str = "<can't format argument>";
    Output.append(Str.begin(), Str.end());
}
Пример #11
0
static std::error_code getRelocationValueString(const COFFObjectFile *Obj,
                                                const RelocationRef &Rel,
                                                SmallVectorImpl<char> &Result) {
  symbol_iterator SymI = Rel.getSymbol();
  StringRef SymName;
  if (std::error_code EC = SymI->getName(SymName))
    return EC;
  Result.append(SymName.begin(), SymName.end());
  return std::error_code();
}
Пример #12
0
/// Get the runtime library link path, which is platform-specific and found
/// relative to the compiler.
static void getRuntimeLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
                                  const llvm::opt::ArgList &args,
                                  const ToolChain &TC) {
  // FIXME: Duplicated from CompilerInvocation, but in theory the runtime
  // library link path and the standard library module import path don't
  // need to be the same.
  if (const Arg *A = args.getLastArg(options::OPT_resource_dir)) {
    StringRef value = A->getValue();
    runtimeLibPath.append(value.begin(), value.end());
  } else {
    auto programPath = TC.getDriver().getSwiftProgramPath();
    runtimeLibPath.append(programPath.begin(), programPath.end());
    llvm::sys::path::remove_filename(runtimeLibPath); // remove /swift
    llvm::sys::path::remove_filename(runtimeLibPath); // remove /bin
    llvm::sys::path::append(runtimeLibPath, "lib", "swift");
  }
  llvm::sys::path::append(runtimeLibPath,
                          getPlatformNameForTriple(TC.getTriple()));
}
Пример #13
0
static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
                               const char *Modifier, unsigned ML,
                               const char *Argument, unsigned ArgLen,
                               const DiagnosticsEngine::ArgumentValue *PrevArgs,
                               unsigned NumPrevArgs,
                               SmallVectorImpl<char> &Output,
                               void *Cookie,
                               ArrayRef<intptr_t> QualTypeVals) {
  const char *Str = "<can't format argument>";
  Output.append(Str, Str+strlen(Str));
}
Пример #14
0
StringRef camel_case::appendSentenceCase(SmallVectorImpl<char> &buffer,
                                         StringRef string) {
  // Trivial case: empty string.
  if (string.empty())
    return StringRef(buffer.data(), buffer.size());

  // Uppercase the first letter, append the rest.
  buffer.push_back(clang::toUppercase(string[0]));
  buffer.append(string.begin() + 1, string.end());
  return StringRef(buffer.data(), buffer.size());
}
Пример #15
0
/// FormatDiagnostic - Format this diagnostic into a string, substituting the
/// formal arguments into the %0 slots.  The result is appended onto the Str
/// array.
void Diagnostic::
FormatDiagnostic(SmallVectorImpl<char> &OutStr) const {
    if (!StoredDiagMessage.empty()) {
        OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end());
        return;
    }

    StringRef Diag =
        getDiags()->getDiagnosticIDs()->getDescription(getID());

    FormatDiagnostic(Diag.begin(), Diag.end(), OutStr);
}
Пример #16
0
StringRef EnumInfoCache::getEnumInfoKey(const clang::EnumDecl *decl,
                                        SmallVectorImpl<char> &scratch) {
  StringRef moduleName;
  if (auto moduleOpt = getClangSubmoduleForDecl(decl)) {
    if (*moduleOpt)
      moduleName = (*moduleOpt)->getTopLevelModuleName();
  }
  if (moduleName.empty())
    moduleName = decl->getASTContext().getLangOpts().CurrentModule;

  StringRef enumName = decl->getDeclName()
                           ? decl->getName()
                           : decl->getTypedefNameForAnonDecl()->getName();

  if (moduleName.empty())
    return enumName;

  scratch.append(moduleName.begin(), moduleName.end());
  scratch.push_back('.');
  scratch.append(enumName.begin(), enumName.end());
  return StringRef(scratch.data(), scratch.size());
}
Пример #17
0
void append(SmallVectorImpl<char> &path, Style style, const Twine &a,
            const Twine &b, const Twine &c, const Twine &d) {
  SmallString<32> a_storage;
  SmallString<32> b_storage;
  SmallString<32> c_storage;
  SmallString<32> d_storage;

  SmallVector<StringRef, 4> components;
  if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
  if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
  if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
  if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));

  for (auto &component : components) {
    bool path_has_sep =
        !path.empty() && is_separator(path[path.size() - 1], style);
    bool component_has_sep =
        !component.empty() && is_separator(component[0], style);
    bool is_root_name = has_root_name(component, style);

    if (path_has_sep) {
      // Strip separators from beginning of component.
      size_t loc = component.find_first_not_of(separators(style));
      StringRef c = component.substr(loc);

      // Append it.
      path.append(c.begin(), c.end());
      continue;
    }

    if (!component_has_sep && !(path.empty() || is_root_name)) {
      // Add a separator.
      path.push_back(preferred_separator(style));
    }

    path.append(component.begin(), component.end());
  }
}
Пример #18
0
StringRef camel_case::toSentencecase(StringRef string, 
                                     SmallVectorImpl<char> &scratch) {
  if (string.empty())
    return string;

  // Can't be uppercased.
  if (!clang::isLowercase(string[0]))
    return string;

  // Uppercase the first letter, append the rest.
  scratch.clear();
  scratch.push_back(clang::toUppercase(string[0]));
  scratch.append(string.begin() + 1, string.end());
  return StringRef(scratch.data(), scratch.size());  
}
Пример #19
0
void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,
                                       MDNode*> > &Result)const {
  assert(hasMetadata() && getContext().pImpl->MetadataStore.count(this) &&
         "Shouldn't have called this");
  const LLVMContextImpl::MDMapTy &Info =
    getContext().pImpl->MetadataStore.find(this)->second;
  assert(!Info.empty() && "Shouldn't have called this");

  Result.clear();
  Result.append(Info.begin(), Info.end());

  // Sort the resulting array so it is stable.
  if (Result.size() > 1)
    array_pod_sort(Result.begin(), Result.end());
}
Пример #20
0
/// \brief Escape diagnostic texts to avoid problems when they are fed into the
/// diagnostic formatter a second time.
static StringRef escapeDiag(StringRef Str, SmallVectorImpl<char> &Buf) {
  size_t Pos = Str.find('%');
  if (Pos == StringRef::npos)
    return Str;

  // We found a '%'. Replace this and all following '%' with '%%'.
  Buf.clear();
  Buf.append(Str.data(), Str.data() + Pos);
  for (size_t I = Pos, E = Str.size(); I != E; ++I) {
    if (Str[I] == '%')
      Buf.push_back('%');
    Buf.push_back(Str[I]);
  }

  return StringRef(Buf.data(), Buf.size());
}
bool ReplacementHandling::generateReplacementsFileName(
    StringRef DestinationDir, StringRef MainSourceFile,
    SmallVectorImpl<char> &Result, SmallVectorImpl<char> &Error) {

  Error.clear();
  SmallString<128> Prefix = DestinationDir;
  path::append(Prefix, path::filename(MainSourceFile));
  if (std::error_code EC =
          fs::createUniqueFile(Prefix + "_%%_%%_%%_%%_%%_%%.yaml", Result)) {
    const std::string &Msg = EC.message();
    Error.append(Msg.begin(), Msg.end());
    return false;
  }

  return true;
}
Пример #22
0
/// Collect all of the generic parameter types at every level in the generic
/// parameter list.
static void collectGenericParamTypes(
              GenericParamList *genericParams,
              GenericSignature *parentSig,
              SmallVectorImpl<GenericTypeParamType *> &allParams) {
  // If the parent context has a generic signature, add its generic parameters.
  if (parentSig) {
    allParams.append(parentSig->getGenericParams().begin(),
                     parentSig->getGenericParams().end());
  }

  if (genericParams) {
    // Add our parameters.
    for (auto param : *genericParams) {
      allParams.push_back(param->getDeclaredType()
                            ->castTo<GenericTypeParamType>());
    }
  }
}
Пример #23
0
void replace_extension(SmallVectorImpl<char> &path, const Twine &extension,
                       Style style) {
  StringRef p(path.begin(), path.size());
  SmallString<32> ext_storage;
  StringRef ext = extension.toStringRef(ext_storage);

  // Erase existing extension.
  size_t pos = p.find_last_of('.');
  if (pos != StringRef::npos && pos >= filename_pos(p, style))
    path.set_size(pos);

  // Append '.' if needed.
  if (ext.size() > 0 && ext[0] != '.')
    path.push_back('.');

  // Append extension.
  path.append(ext.begin(), ext.end());
}
Пример #24
0
void WasmObjectFile::getRelocationTypeName(
    DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
  const wasm::WasmRelocation& Rel = getWasmRelocation(Ref);
  StringRef Res = "Unknown";

#define WASM_RELOC(name, value)  \
  case wasm::name:              \
    Res = #name;               \
    break;

  switch (Rel.Type) {
#include "llvm/BinaryFormat/WasmRelocs/WebAssembly.def"
  }

#undef WASM_RELOC

  Result.append(Res.begin(), Res.end());
}
Пример #25
0
static bool isPotentiallyReachableInner(SmallVectorImpl<BasicBlock *> &Worklist,
                                        BasicBlock *StopBB,
                                        const DominatorTree *DT,
                                        const LoopInfo *LI) {
  // When the stop block is unreachable, it's dominated from everywhere,
  // regardless of whether there's a path between the two blocks.
  if (DT && !DT->isReachableFromEntry(StopBB))
    DT = 0;

  // Limit the number of blocks we visit. The goal is to avoid run-away compile
  // times on large CFGs without hampering sensible code. Arbitrarily chosen.
  unsigned Limit = 128;
  SmallSet<const BasicBlock*, 64> Visited;
  do {
    BasicBlock *BB = Worklist.pop_back_val();
    if (!Visited.insert(BB))
      continue;
    if (BB == StopBB)
      return true;
    if (DT && DT->dominates(BB, StopBB))
      return true;
    if (LI && loopContainsBoth(LI, BB, StopBB))
      return true;

    if (!--Limit) {
      // We haven't been able to prove it one way or the other. Conservatively
      // answer true -- that there is potentially a path.
      return true;
    }

    if (const Loop *Outer = LI ? getOutermostLoop(LI, BB) : 0) {
      // All blocks in a single loop are reachable from all other blocks. From
      // any of these blocks, we can skip directly to the exits of the loop,
      // ignoring any other blocks inside the loop body.
      Outer->getExitBlocks(Worklist);
    } else {
      Worklist.append(succ_begin(BB), succ_end(BB));
    }
  } while (!Worklist.empty());

  // We have exhausted all possible paths and are certain that 'To' can not be
  // reached from 'From'.
  return false;
}
Пример #26
0
StringRef camel_case::toLowercaseWord(StringRef string,
                                      SmallVectorImpl<char> &scratch) {
  if (string.empty())
    return string;

  // Already lowercase.
  if (!clang::isUppercase(string[0]))
    return string;

  // Acronym doesn't get lowercased.
  if (string.size() > 1 && clang::isUppercase(string[1]))
    return string;

  // Lowercase the first letter, append the rest.
  scratch.clear();
  scratch.push_back(clang::toLowercase(string[0]));
  scratch.append(string.begin() + 1, string.end());
  return StringRef(scratch.data(), scratch.size());
}
Пример #27
0
static ResolutionKind recordImportDecls(LazyResolver *typeResolver,
                                        SmallVectorImpl<ValueDecl *> &results,
                                        ArrayRef<ValueDecl *> newDecls,
                                        OverloadSetTy &overloads,
                                        ResolutionKind resolutionKind) {
  switch (resolutionKind) {
  case ResolutionKind::Overloadable: {
    // Add new decls if they provide a new overload. Note that the new decls
    // may be ambiguous with respect to each other, just not any existing decls.
    std::copy_if(newDecls.begin(), newDecls.end(), std::back_inserter(results),
                 [&](ValueDecl *result) -> bool {
      if (!result->hasInterfaceType()) {
        if (typeResolver) {
          typeResolver->resolveDeclSignature(result);
          if (result->isInvalid())
            return true;
        } else {
          return true;
        }
      }
      return isValidOverload(overloads, result);
    });

    // Update the overload set.
    bool stillOverloadable = updateOverloadSet(overloads, newDecls);
    return stillOverloadable ? ResolutionKind::Overloadable
                             : ResolutionKind::Exact;
  }

  case ResolutionKind::Exact:
    // Add all decls. If they're ambiguous, they're ambiguous.
    results.append(newDecls.begin(), newDecls.end());
    return ResolutionKind::Exact;

  case ResolutionKind::TypesOnly:
    // Add type decls only. If they're ambiguous, they're ambiguous.
    std::copy_if(newDecls.begin(), newDecls.end(), std::back_inserter(results),
                 [](const ValueDecl *VD) { return isa<TypeDecl>(VD); });
    return ResolutionKind::TypesOnly;
  }

  llvm_unreachable("bad ResolutionKind");
}
Пример #28
0
/// Compute substitutions for making a direct call to a SIL function with
/// @convention(witness_method) convention.
///
/// Such functions have a substituted generic signature where the
/// abstract `Self` parameter from the original type of the protocol
/// requirement is replaced by a concrete type.
///
/// Thus, the original substitutions of the apply instruction that
/// are written in terms of the requirement's generic signature need
/// to be remapped to substitutions suitable for the witness signature.
///
/// \param conformanceRef The (possibly-specialized) conformance
/// \param requirementSig The generic signature of the requirement
/// \param witnessThunkSig The generic signature of the witness method
/// \param origSubs The substitutions from the call instruction
/// \param newSubs New substitutions are stored here
static void getWitnessMethodSubstitutions(
    SILModule &M,
    ProtocolConformanceRef conformanceRef,
    GenericSignature *requirementSig,
    GenericSignature *witnessThunkSig,
    SubstitutionList origSubs,
    bool isDefaultWitness,
    SmallVectorImpl<Substitution> &newSubs) {

  if (witnessThunkSig == nullptr)
    return;

  if (isDefaultWitness) {
    newSubs.append(origSubs.begin(), origSubs.end());
    return;
  }

  assert(!conformanceRef.isAbstract());
  auto conformance = conformanceRef.getConcrete();

  // If `Self` maps to a bound generic type, this gives us the
  // substitutions for the concrete type's generic parameters.
  auto baseSubMap = getSubstitutionsForProtocolConformance(conformanceRef);

  unsigned baseDepth = 0;
  auto *rootConformance = conformance->getRootNormalConformance();
  if (auto *witnessSig = rootConformance->getGenericSignature())
    baseDepth = witnessSig->getGenericParams().back()->getDepth() + 1;

  auto origDepth = 1;
  auto origSubMap = requirementSig->getSubstitutionMap(origSubs);

  auto subMap =
    SubstitutionMap::combineSubstitutionMaps(baseSubMap,
                                             origSubMap, 
                                             CombineSubstitutionMaps::AtDepth,
                                             baseDepth,
                                             origDepth,
                                             witnessThunkSig);

  witnessThunkSig->getSubstitutions(subMap, newSubs);
}
Пример #29
0
/// Collect all of the generic parameter types at every level in the generic
/// parameter list.
static void collectGenericParamTypes(
              GenericParamList *genericParams,
              DeclContext *parentDC,
              SmallVectorImpl<GenericTypeParamType *> &allParams) {
  // If the parent context is a generic type (or nested type thereof),
  // add its generic parameters.
  if (parentDC->isTypeContext()) {
    if (auto parentSig = parentDC->getGenericSignatureOfContext()) {
      allParams.append(parentSig->getGenericParams().begin(),
                       parentSig->getGenericParams().end());
    }
  }
    
  if (genericParams) {
    // Add our parameters.
    for (auto param : *genericParams) {
      allParams.push_back(param->getDeclaredType()
                            ->castTo<GenericTypeParamType>());
    }
  }
}
Пример #30
0
/// fixupSubprogramName - Replace contains special characters used
/// in a typical Objective-C names with '.' in a given string.
static void fixupSubprogramName(DISubprogram Fn, SmallVectorImpl<char> &Out) {
  StringRef FName =
      Fn.getFunction() ? Fn.getFunction()->getName() : Fn.getName();
  FName = Function::getRealLinkageName(FName);

  StringRef Prefix("llvm.dbg.lv.");
  Out.reserve(FName.size() + Prefix.size());
  Out.append(Prefix.begin(), Prefix.end());

  bool isObjCLike = false;
  for (size_t i = 0, e = FName.size(); i < e; ++i) {
    char C = FName[i];
    if (C == '[')
      isObjCLike = true;

    if (isObjCLike && (C == '[' || C == ']' || C == ' ' || C == ':' ||
                       C == '+' || C == '(' || C == ')'))
      Out.push_back('.');
    else
      Out.push_back(C);
  }
}