Exemple #1
0
ErrorOr<StringRef>
MachOLinkingContext::searchDirForLibrary(StringRef path,
        StringRef libName) const {
    SmallString<256> fullPath;
    if (libName.endswith(".o")) {
        // A request ending in .o is special: just search for the file directly.
        fullPath.assign(path);
        llvm::sys::path::append(fullPath, libName);
        if (fileExists(fullPath))
            return fullPath.str().copy(_allocator);
        return make_error_code(llvm::errc::no_such_file_or_directory);
    }

    // Search for dynamic library
    fullPath.assign(path);
    llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
    if (fileExists(fullPath))
        return fullPath.str().copy(_allocator);

    // If not, try for a static library
    fullPath.assign(path);
    llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
    if (fileExists(fullPath))
        return fullPath.str().copy(_allocator);

    return make_error_code(llvm::errc::no_such_file_or_directory);
}
Exemple #2
0
static void buildSearchPath(SmallString<128> &path, StringRef dir,
                            StringRef sysRoot) {
    if (dir.startswith("=/")) {
        // If a search directory begins with "=", "=" is replaced
        // with the sysroot path.
        path.assign(sysRoot);
        path.append(dir.substr(1));
    } else {
        path.assign(dir);
    }
}
Exemple #3
0
MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
    // See if already loaded.
    auto pos = _pathToDylibMap.find(path);
    if (pos != _pathToDylibMap.end())
        return pos->second;

    // Search -L paths if of the form "libXXX.dylib"
    std::pair<StringRef, StringRef> split = path.rsplit('/');
    StringRef leafName = split.second;
    if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
        // FIXME: Need to enhance searchLibrary() to only look for .dylib
        auto libPath = searchLibrary(leafName);
        if (!libPath.getError()) {
            return loadIndirectDylib(libPath.get());
        }
    }

    // Try full path with sysroot.
    for (StringRef sysPath : _syslibRoots) {
        SmallString<256> fullPath;
        fullPath.assign(sysPath);
        llvm::sys::path::append(fullPath, path);
        if (pathExists(fullPath))
            return loadIndirectDylib(fullPath);
    }

    // Try full path.
    if (pathExists(path)) {
        return loadIndirectDylib(path);
    }

    return nullptr;
}
ErrorOr<StringRef> ELFLinkingContext::searchLibrary(StringRef libName) const {
  bool foundFile = false;
  StringRef pathref;
  SmallString<128> path;
  for (StringRef dir : _inputSearchPaths) {
    // Search for dynamic library
    if (!_isStaticExecutable) {
      path.clear();
      if (dir.startswith("=/")) {
        path.assign(_sysrootPath);
        path.append(dir.substr(1));
      } else {
        path.assign(dir);
      }
      llvm::sys::path::append(path, Twine("lib") + libName + ".so");
      pathref = path.str();
      if (llvm::sys::fs::exists(pathref)) {
        foundFile = true;
      }
    }
    // Search for static libraries too
    if (!foundFile) {
      path.clear();
      if (dir.startswith("=/")) {
        path.assign(_sysrootPath);
        path.append(dir.substr(1));
      } else {
        path.assign(dir);
      }
      llvm::sys::path::append(path, Twine("lib") + libName + ".a");
      pathref = path.str();
      if (llvm::sys::fs::exists(pathref)) {
        foundFile = true;
      }
    }
    if (foundFile)
      return StringRef(*new (_allocator) std::string(pathref));
  }
  if (!llvm::sys::fs::exists(libName))
    return llvm::make_error_code(llvm::errc::no_such_file_or_directory);

  return libName;
}
Exemple #5
0
ErrorOr<StringRef> MachOLinkingContext::findPathForFramework(StringRef fwName) const {
    SmallString<256> fullPath;
    for (StringRef dir : frameworkDirs()) {
        fullPath.assign(dir);
        llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
        if (fileExists(fullPath))
            return fullPath.str().copy(_allocator);
    }

    return make_error_code(llvm::errc::no_such_file_or_directory);
}
ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
                     const ArgList &Args)
    : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
      CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
  SmallString<128> P;

  P.assign(D.ResourceDir);
  llvm::sys::path::append(P, D.getTargetTriple(), "lib");
  if (getVFS().exists(P))
    getLibraryPaths().push_back(P.str());

  P.assign(D.ResourceDir);
  llvm::sys::path::append(P, Triple.str(), "lib");
  if (getVFS().exists(P))
    getLibraryPaths().push_back(P.str());

  std::string CandidateLibPath = getArchSpecificLibPath();
  if (getVFS().exists(CandidateLibPath))
    getFilePaths().push_back(CandidateLibPath);
}
/// \brief Print the given string to a stream, word-wrapping it to
/// some number of columns in the process.
///
/// \param OS the stream to which the word-wrapping string will be
/// emitted.
/// \param Str the string to word-wrap and output.
/// \param Columns the number of columns to word-wrap to.
/// \param Column the column number at which the first character of \p
/// Str will be printed. This will be non-zero when part of the first
/// line has already been printed.
/// \param Bold if the current text should be bold
/// \param Indentation the number of spaces to indent any lines beyond
/// the first line.
/// \returns true if word-wrapping was required, or false if the
/// string fit on the first line.
static bool printWordWrapped(raw_ostream &OS, StringRef Str,
                             unsigned Columns,
                             unsigned Column = 0,
                             bool Bold = false,
                             unsigned Indentation = WordWrapIndentation) {
  const unsigned Length = std::min(Str.find('\n'), Str.size());
  bool TextNormal = true;

  // The string used to indent each line.
  SmallString<16> IndentStr;
  IndentStr.assign(Indentation, ' ');
  bool Wrapped = false;
  for (unsigned WordStart = 0, WordEnd; WordStart < Length;
       WordStart = WordEnd) {
    // Find the beginning of the next word.
    WordStart = skipWhitespace(WordStart, Str, Length);
    if (WordStart == Length)
      break;

    // Find the end of this word.
    WordEnd = findEndOfWord(WordStart, Str, Length, Column, Columns);

    // Does this word fit on the current line?
    unsigned WordLength = WordEnd - WordStart;
    if (Column + WordLength < Columns) {
      // This word fits on the current line; print it there.
      if (WordStart) {
        OS << ' ';
        Column += 1;
      }
      applyTemplateHighlighting(OS, Str.substr(WordStart, WordLength),
                                TextNormal, Bold);
      Column += WordLength;
      continue;
    }

    // This word does not fit on the current line, so wrap to the next
    // line.
    OS << '\n';
    OS.write(&IndentStr[0], Indentation);
    applyTemplateHighlighting(OS, Str.substr(WordStart, WordLength),
                              TextNormal, Bold);
    Column = Indentation + WordLength;
    Wrapped = true;
  }

  // Append any remaning text from the message with its existing formatting.
  applyTemplateHighlighting(OS, Str.substr(Length), TextNormal, Bold);

  assert(TextNormal && "Text highlighted at end of diagnostic message.");

  return Wrapped;
}
Exemple #8
0
/// Determine if the given invocation should run as a subcommand.
///
/// \param ExecName The name of the argv[0] we were invoked as.
/// \param SubcommandName On success, the full name of the subcommand to invoke.
/// \param Args On return, the adjusted program arguments to use.
/// \returns True if running as a subcommand.
static bool shouldRunAsSubcommand(StringRef ExecName,
                                  SmallString<256> &SubcommandName,
                                  const ArrayRef<const char *> Args,
                                  bool &isRepl) {
  assert(!Args.empty());

  // If we are not run as 'swift', don't do anything special. This doesn't work
  // with symlinks with alternate names, but we can't detect 'swift' vs 'swiftc'
  // if we try and resolve using the actual executable path.
  if (ExecName != "swift")
    return false;

  // If there are no program arguments, always invoke as normal.
  if (Args.size() == 1)
    return false;

  // Otherwise, we have a program argument. If it looks like an option or a
  // path, then invoke in interactive mode with the arguments as given.
  StringRef FirstArg(Args[1]);
  if (FirstArg.startswith("-") || FirstArg.find('.') != StringRef::npos ||
      FirstArg.find('/') != StringRef::npos)
    return false;

  // Otherwise, we should have some sort of subcommand. Get the subcommand name
  // and remove it from the program arguments.
  StringRef Subcommand = Args[1];

  // If the subcommand is the "built-in" 'repl', then use the
  // normal driver.
  if (Subcommand == "repl") {
    isRepl = true;
    return false;
  }

  // Form the subcommand name.
  SubcommandName.assign("swift-");
  SubcommandName.append(Subcommand);

  return true;
}
Exemple #9
0
ErrorOr<StringRef> ELFLinkingContext::searchFile(StringRef fileName,
        bool isSysRooted) const {
    SmallString<128> path;
    if (is_absolute(fileName) && isSysRooted) {
        path.assign(_sysrootPath);
        path.append(fileName);
        if (exists(path.str()))
            return path.str().copy(_allocator);
    } else if (exists(fileName)) {
        return fileName;
    }

    if (is_absolute(fileName))
        return make_error_code(llvm::errc::no_such_file_or_directory);

    for (StringRef dir : _inputSearchPaths) {
        buildSearchPath(path, dir, _sysrootPath);
        llvm::sys::path::append(path, fileName);
        if (exists(path.str()))
            return path.str().copy(_allocator);
    }
    return make_error_code(llvm::errc::no_such_file_or_directory);
}
Exemple #10
0
/// \brief returns a printable representation of first item from input range
///
/// This function returns a printable representation of the next item in a line
///  of source. If the next byte begins a valid and printable character, that
///  character is returned along with 'true'.
///
/// Otherwise, if the next byte begins a valid, but unprintable character, a
///  printable, escaped representation of the character is returned, along with
///  'false'. Otherwise a printable, escaped representation of the next byte
///  is returned along with 'false'.
///
/// \note The index is updated to be used with a subsequent call to
///        printableTextForNextCharacter.
///
/// \param SourceLine The line of source
/// \param i Pointer to byte index,
/// \param TabStop used to expand tabs
/// \return pair(printable text, 'true' iff original text was printable)
///
static std::pair<SmallString<16>, bool>
printableTextForNextCharacter(StringRef SourceLine, size_t *i,
                              unsigned TabStop) {
  assert(i && "i must not be null");
  assert(*i<SourceLine.size() && "must point to a valid index");
  
  if (SourceLine[*i]=='\t') {
    assert(0 < TabStop && TabStop <= DiagnosticOptions::MaxTabStop &&
           "Invalid -ftabstop value");
    unsigned col = bytesSincePreviousTabOrLineBegin(SourceLine, *i);
    unsigned NumSpaces = TabStop - col%TabStop;
    assert(0 < NumSpaces && NumSpaces <= TabStop
           && "Invalid computation of space amt");
    ++(*i);

    SmallString<16> expandedTab;
    expandedTab.assign(NumSpaces, ' ');
    return std::make_pair(expandedTab, true);
  }

  unsigned char const *begin, *end;
  begin = reinterpret_cast<unsigned char const *>(&*(SourceLine.begin() + *i));
  end = begin + (SourceLine.size() - *i);
  
  if (isLegalUTF8Sequence(begin, end)) {
    UTF32 c;
    UTF32 *cptr = &c;
    unsigned char const *original_begin = begin;
    unsigned char const *cp_end = begin+getNumBytesForUTF8(SourceLine[*i]);

    ConversionResult res = ConvertUTF8toUTF32(&begin, cp_end, &cptr, cptr+1,
                                              strictConversion);
    (void)res;
    assert(conversionOK==res);
    assert(0 < begin-original_begin
           && "we must be further along in the string now");
    *i += begin-original_begin;

    if (!llvm::sys::locale::isPrint(c)) {
      // If next character is valid UTF-8, but not printable
      SmallString<16> expandedCP("<U+>");
      while (c) {
        expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(c%16));
        c/=16;
      }
      while (expandedCP.size() < 8)
        expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(0));
      return std::make_pair(expandedCP, false);
    }

    // If next character is valid UTF-8, and printable
    return std::make_pair(SmallString<16>(original_begin, cp_end), true);

  }

  // If next byte is not valid UTF-8 (and therefore not printable)
  SmallString<16> expandedByte("<XX>");
  unsigned char byte = SourceLine[*i];
  expandedByte[1] = llvm::hexdigit(byte / 16);
  expandedByte[2] = llvm::hexdigit(byte % 16);
  ++(*i);
  return std::make_pair(expandedByte, false);
}
 static StringRef input(StringRef Scalar, void *, SmallString<U> &Value) {
   Value.assign(Scalar.begin(), Scalar.end());
   return StringRef();
 }