Example #1
0
static void ParseProgName(SmallVectorImpl<const char *> &ArgVector,
                          std::set<std::string> &SavedStrings) {
  // Try to infer frontend type and default target from the program name by
  // comparing it against DriverSuffixes in order.

  // If there is a match, the function tries to identify a target as prefix.
  // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target
  // prefix "x86_64-linux". If such a target prefix is found, is gets added via
  // -target as implicit first argument.

  std::string ProgName =llvm::sys::path::stem(ArgVector[0]);
#ifdef LLVM_ON_WIN32
  // Transform to lowercase for case insensitive file systems.
  ProgName = StringRef(ProgName).lower();
#endif

  StringRef ProgNameRef = ProgName;
  const DriverSuffix *DS = FindDriverSuffix(ProgNameRef);

  if (!DS) {
    // Try again after stripping any trailing version number:
    // clang++3.5 -> clang++
    ProgNameRef = ProgNameRef.rtrim("0123456789.");
    DS = FindDriverSuffix(ProgNameRef);
  }

  if (!DS) {
    // Try again after stripping trailing -component.
    // clang++-tot -> clang++
    ProgNameRef = ProgNameRef.slice(0, ProgNameRef.rfind('-'));
    DS = FindDriverSuffix(ProgNameRef);
  }

  if (DS) {
    if (const char *Flag = DS->ModeFlag) {
      // Add Flag to the arguments.
      auto it = ArgVector.begin();
      if (it != ArgVector.end())
        ++it;
      ArgVector.insert(it, Flag);
    }

    StringRef::size_type LastComponent = ProgNameRef.rfind(
        '-', ProgNameRef.size() - strlen(DS->Suffix));
    if (LastComponent == StringRef::npos)
      return;

    // Infer target from the prefix.
    StringRef Prefix = ProgNameRef.slice(0, LastComponent);
    std::string IgnoredError;
    if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
      auto it = ArgVector.begin();
      if (it != ArgVector.end())
        ++it;
      const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) };
      ArgVector.insert(it, std::begin(arr), std::end(arr));
    }
  }
}
/// \brief Parse \p Input as function head.
///
/// Parse one line of \p Input, and update function name in \p FName,
/// function's total sample count in \p NumSamples, function's entry
/// count in \p NumHeadSamples.
///
/// \returns true if parsing is successful.
static bool ParseHead(const StringRef &Input, StringRef &FName,
                      unsigned &NumSamples, unsigned &NumHeadSamples) {
  if (Input[0] == ' ')
    return false;
  size_t n2 = Input.rfind(':');
  size_t n1 = Input.rfind(':', n2 - 1);
  FName = Input.substr(0, n1);
  if (Input.substr(n1 + 1, n2 - n1 - 1).getAsInteger(10, NumSamples))
    return false;
  if (Input.substr(n2 + 1).getAsInteger(10, NumHeadSamples))
    return false;
  return true;
}
Example #3
0
static void insertArgsFromProgramName(StringRef ProgName,
                                      const DriverSuffix *DS,
                                      SmallVectorImpl<const char *> &ArgVector,
                                      std::set<std::string> &SavedStrings) {
  if (!DS)
    return;

  if (const char *Flag = DS->ModeFlag) {
    // Add Flag to the arguments.
    auto it = ArgVector.begin();
    if (it != ArgVector.end())
      ++it;
    ArgVector.insert(it, Flag);
  }

  StringRef::size_type LastComponent = ProgName.rfind(
      '-', ProgName.size() - strlen(DS->Suffix));
  if (LastComponent == StringRef::npos)
    return;

  // Infer target from the prefix.
  StringRef Prefix = ProgName.slice(0, LastComponent);
  std::string IgnoredError;
  if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
    auto it = ArgVector.begin();
    if (it != ArgVector.end())
      ++it;
    const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) };
    ArgVector.insert(it, std::begin(arr), std::end(arr));
  }
}
Example #4
0
BOZConstantExpr::BOZConstantExpr(ASTContext &C, SMLoc Loc, StringRef Data)
  : ConstantExpr(BOZConstant, C.IntegerTy, Loc) {
  unsigned Radix = 0;
  switch (Data[0]) {
  case 'B':
    Kind = Binary;
    Radix = 2;
    break;
  case 'O':
    Kind = Octal;
    Radix = 8;
    break;
  case 'Z': case 'X':
    Kind = Hexadecimal;
    Radix = 16;
    break;
  }

  size_t LastQuote = Data.rfind(Data[1]);
  assert(LastQuote == StringRef::npos && "Invalid BOZ constant!");
  llvm::StringRef NumStr = Data.slice(2, LastQuote);
  APInt Val;
  NumStr.getAsInteger(Radix, Val);
  Num.setValue(C, Val);
}
Example #5
0
void MinimalAction::ActOnImportSpec(SourceLocation PathLoc, StringRef ImportPath,
                                    IdentifierInfo *LocalName,
                                    bool IsLocal) {
  if (IsLocal)
    // FIXME: This should insert all exported symbols in ImportPath into the
    // current file's file scope.
    return;

  TypeNameInfoTable &TNIT = *getTable(TypeNameInfoTablePtr);

  if (LocalName) {
    // FIXME: This should insert all exported symbols in ImportPath into
    // LocalName's scope.
    TNIT.AddEntry(Action::IIT_Package, LocalName);
    TUScope->AddDecl(DeclPtrTy::make(LocalName));
    return;
  }

  // FIXME: The right thing to do here is to load the package file pointed to
  // by ImportPath and get the `package` identifier used therein. As an
  // approximation, just grab the last path component off ImportPath.
  ImportPath = ImportPath.slice(1, ImportPath.size() - 1);  // Strip ""
  size_t SlashPos = ImportPath.rfind('/');
  if (SlashPos != StringRef::npos)
    ImportPath = ImportPath.substr(SlashPos + 1);

  TNIT.AddEntry(Action::IIT_Package, &Idents.get(ImportPath));
  TUScope->AddDecl(DeclPtrTy::make(&Idents.get(ImportPath)));
}
Example #6
0
BreakableToken::Split getCommentSplit(StringRef Text,
                                      unsigned ContentStartColumn,
                                      unsigned ColumnLimit) {
  if (ColumnLimit <= ContentStartColumn + 1)
    return BreakableToken::Split(StringRef::npos, 0);

  unsigned MaxSplit = ColumnLimit - ContentStartColumn + 1;
  StringRef::size_type SpaceOffset = Text.rfind(' ', MaxSplit);
  if (SpaceOffset == StringRef::npos ||
      // Don't break at leading whitespace.
      Text.find_last_not_of(' ', SpaceOffset) == StringRef::npos) {
    // Make sure that we don't break at leading whitespace that
    // reaches past MaxSplit.
    StringRef::size_type FirstNonWhitespace = Text.find_first_not_of(" ");
    if (FirstNonWhitespace == StringRef::npos)
      // If the comment is only whitespace, we cannot split.
      return BreakableToken::Split(StringRef::npos, 0);
    SpaceOffset =
        Text.find(' ', std::max<unsigned>(MaxSplit, FirstNonWhitespace));
  }
  if (SpaceOffset != StringRef::npos && SpaceOffset != 0) {
    StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim();
    StringRef AfterCut = Text.substr(SpaceOffset).ltrim();
    return BreakableToken::Split(BeforeCut.size(),
                                 AfterCut.begin() - BeforeCut.end());
  }
  return BreakableToken::Split(StringRef::npos, 0);
}
Example #7
0
/// Turn an offset in Code into a [line, column] pair.
Position clangd::offsetToPosition(StringRef Code, size_t Offset) {
  StringRef JustBefore = Code.substr(0, Offset);
  // FIXME: \r\n
  // FIXME: UTF-8
  int Lines = JustBefore.count('\n');
  int Cols = JustBefore.size() - JustBefore.rfind('\n') - 1;
  return {Lines, Cols};
}
Example #8
0
bool Module::findPrimaryDefn() {
  StringRef primaryName = qname_;
  size_t dot = primaryName.rfind('.');
  if (dot != primaryName.npos) {
    primaryName = primaryName.substr(dot + 1, primaryName.npos);
  }

  return IterableScope::lookupMember(primaryName, primaryDefs_, false);
}
Example #9
0
// Returns a whole line containing the current token.
StringRef ScriptParserBase::getLine() {
  StringRef S = getCurrentMB().getBuffer();
  StringRef Tok = Tokens[Pos - 1];

  size_t Pos = S.rfind('\n', Tok.data() - S.data());
  if (Pos != StringRef::npos)
    S = S.substr(Pos + 1);
  return S.substr(0, S.find_first_of("\r\n"));
}
// If an input string is in the form of "foo.N" where N is a number,
// return N. Otherwise, returns 65536, which is one greater than the
// lowest priority.
int elf::getPriority(StringRef S) {
  size_t Pos = S.rfind('.');
  if (Pos == StringRef::npos)
    return 65536;
  int V;
  if (!to_integer(S.substr(Pos + 1), V, 10))
    return 65536;
  return V;
}
Example #11
0
// Returns the line that the character S[Pos] is in.
static StringRef getLine(StringRef S, size_t Pos) {
  size_t Begin = S.rfind('\n', Pos);
  size_t End = S.find('\n', Pos);
  Begin = (Begin == StringRef::npos) ? 0 : Begin + 1;
  if (End == StringRef::npos)
    End = S.size();
  // rtrim for DOS-style newlines.
  return S.substr(Begin, End - Begin).rtrim();
}
Example #12
0
void Module::setQualifiedName(StringRef qual) {
  qname_ = qual;
  size_t dot = qual.rfind('.');
  if (dot == qual.npos) {
    name_ = moduleStrings_.intern(qual);
    packageName_.clear();
  } else {
    name_ = moduleStrings_.intern(qual.substr(dot + 1, qual.npos));
    packageName_ = qual.substr(0, dot);
  }
}
Example #13
0
Symbol symbol(StringRef QName) {
  Symbol Sym;
  Sym.ID = SymbolID(QName.str());
  size_t Pos = QName.rfind("::");
  if (Pos == StringRef::npos) {
    Sym.Name = QName;
    Sym.Scope = "";
  } else {
    Sym.Name = QName.substr(Pos + 2);
    Sym.Scope = QName.substr(0, Pos + 2);
  }
  return Sym;
}
Example #14
0
BreakableToken::Split getStringSplit(StringRef Text,
                                     unsigned ContentStartColumn,
                                     unsigned ColumnLimit) {

  if (ColumnLimit <= ContentStartColumn)
    return BreakableToken::Split(StringRef::npos, 0);
  unsigned MaxSplit = ColumnLimit - ContentStartColumn;
  // FIXME: Reduce unit test case.
  if (Text.empty())
    return BreakableToken::Split(StringRef::npos, 0);
  MaxSplit = std::min<unsigned>(MaxSplit, Text.size() - 1);
  StringRef::size_type SpaceOffset = Text.rfind(' ', MaxSplit);
  if (SpaceOffset != StringRef::npos && SpaceOffset != 0)
    return BreakableToken::Split(SpaceOffset + 1, 0);
  StringRef::size_type SlashOffset = Text.rfind('/', MaxSplit);
  if (SlashOffset != StringRef::npos && SlashOffset != 0)
    return BreakableToken::Split(SlashOffset + 1, 0);
  StringRef::size_type SplitPoint = getStartOfCharacter(Text, MaxSplit);
  if (SplitPoint == StringRef::npos || SplitPoint == 0)
    return BreakableToken::Split(StringRef::npos, 0);
  return BreakableToken::Split(SplitPoint, 0);
}
bool ObjCRuntime::tryParse(StringRef input) {
  // Look for the last dash.
  std::size_t dash = input.rfind('-');

  // We permit dashes in the runtime name, and we also permit the
  // version to be omitted, so if we see a dash not followed by a
  // digit then we need to ignore it.
  if (dash != StringRef::npos && dash + 1 != input.size() &&
      (input[dash+1] < '0' || input[dash+1] > '9')) {
    dash = StringRef::npos;
  }

  // Everything prior to that must be a valid string name.
  Kind kind;
  StringRef runtimeName = input.substr(0, dash);
  Version = VersionTuple(0);
  if (runtimeName == "macosx") {
    kind = ObjCRuntime::MacOSX;
  } else if (runtimeName == "macosx-fragile") {
    kind = ObjCRuntime::FragileMacOSX;
  } else if (runtimeName == "ios") {
    kind = ObjCRuntime::iOS;
  } else if (runtimeName == "gnustep") {
    // If no version is specified then default to the most recent one that we
    // know about.
    Version = VersionTuple(1, 6);
    kind = ObjCRuntime::GNUstep;
  } else if (runtimeName == "gcc") {
    kind = ObjCRuntime::GCC;
  } else if (runtimeName == "objfw") {
    kind = ObjCRuntime::ObjFW;
    Version = VersionTuple(0, 8);
  } else if (runtimeName == "host") {
    kind = ObjCRuntime::Host;
  } else {
    return true;
  }
  TheKind = kind;

  if (dash != StringRef::npos) {
    StringRef verString = input.substr(dash + 1);
    if (Version.tryParse(verString))
      return true;
  }

  if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8))
    Version = VersionTuple(0, 8);

  return false;
}
Example #16
0
// Path fits in a Ustar header if
//
// - Path is less than 100 characters long, or
// - Path is in the form of "<prefix>/<name>" where <prefix> is less
//   than or equal to 155 characters long and <name> is less than 100
//   characters long. Both <prefix> and <name> can contain extra '/'.
//
// If Path fits in a Ustar header, updates Prefix and Name and returns true.
// Otherwise, returns false.
static bool splitUstar(StringRef Path, StringRef &Prefix, StringRef &Name) {
  if (Path.size() < sizeof(UstarHeader::Name)) {
    Prefix = "";
    Name = Path;
    return true;
  }

  size_t Sep = Path.rfind('/', sizeof(UstarHeader::Prefix) + 1);
  if (Sep == StringRef::npos)
    return false;
  if (Path.size() - Sep - 1 >= sizeof(UstarHeader::Name))
    return false;

  Prefix = Path.substr(0, Sep);
  Name = Path.substr(Sep + 1);
  return true;
}
Example #17
0
StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName,
                                            StringRef OptionName,
                                            StringRef Default,
                                            bool SearchInParents) {
  // Search for a package option if the option for the checker is not specified
  // and search in parents is enabled.
  ConfigTable::const_iterator E = Config.end();
  do {
    ConfigTable::const_iterator I =
        Config.find((Twine(CheckerName) + ":" + OptionName).str());
    if (I != E)
      return StringRef(I->getValue());
    size_t Pos = CheckerName.rfind('.');
    if (Pos == StringRef::npos)
      return Default;
    CheckerName = CheckerName.substr(0, Pos);
  } while (!CheckerName.empty() && SearchInParents);
  return Default;
}
Example #18
0
bool NyuziAsmParser::ParseInstruction(ParseInstructionInfo &Info,
                                      StringRef Name, SMLoc NameLoc,
                                      OperandVector &Operands) {
  size_t dotLoc = Name.find('.');
  StringRef stem = Name.substr(0, dotLoc);
  Operands.push_back(NyuziOperand::createToken(stem, NameLoc));
  if (dotLoc < Name.size()) {
    size_t dotLoc2 = Name.rfind('.');
    if (dotLoc == dotLoc2)
      Operands.push_back(
          NyuziOperand::createToken(Name.substr(dotLoc), NameLoc));
    else {
      Operands.push_back(NyuziOperand::createToken(
          Name.substr(dotLoc, dotLoc2 - dotLoc), NameLoc));
      Operands.push_back(
          NyuziOperand::createToken(Name.substr(dotLoc2), NameLoc));
    }
  }

  // If there are no more operands, then finish
  // XXX hash should start a comment, should the lexer just be consuming that?
  if (getLexer().is(AsmToken::EndOfStatement) || getLexer().is(AsmToken::Hash))
    return false;

  // parse operands
  for (;;) {
    if (ParseOperand(Operands, stem))
      return true;

    if (getLexer().isNot(AsmToken::Comma))
      break;

    // Consume comma token
    getLexer().Lex();
  }

  return false;
}
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 = 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 #20
0
// Drop directory components and replace extension with ".exe".
static std::string getOutputPath(StringRef Path) {
  auto P = Path.find_last_of("\\/");
  StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1);
  return (S.substr(0, S.rfind('.')) + ".exe").str();
}