Ejemplo n.º 1
0
std::string Context::getThunkTarget(llvm::StringRef MangledName) {
  if (!isThunkSymbol(MangledName))
    return std::string();

  if (isMangledName(MangledName)) {
    // The targets of those thunks not derivable from the mangling.
    if (MangledName.endswith("TR") ||
        MangledName.endswith("Tr") ||
        MangledName.endswith("TW") )
      return std::string();

    if (MangledName.endswith("fC")) {
      std::string target = MangledName.str();
      target[target.size() - 1] = 'c';
      return target;
    }

    return MangledName.substr(0, MangledName.size() - 2).str();
  }
  // Old mangling.
  assert(MangledName.startswith("_T"));
  StringRef Remaining = MangledName.substr(2);
  if (Remaining.startswith("PA_"))
    return Remaining.substr(3).str();
  if (Remaining.startswith("PAo_"))
    return Remaining.substr(4).str();
  assert(Remaining.startswith("To") || Remaining.startswith("TO"));
  return std::string("_T") + Remaining.substr(2).str();
}
Ejemplo n.º 2
0
bool MocPPCallbacks::FileNotFound(llvm::StringRef FileName, llvm::SmallVectorImpl< char >& RecoveryPath) {
    if (FileName.endswith(".moc") || FileName.endswith("_moc.cpp") || FileName.startswith("moc_")) {
        if (!PP.GetSuppressIncludeNotFoundError()) {
            PP.SetSuppressIncludeNotFoundError(true);
            IncludeNotFoundSupressed = true;
        }
    } else {
        if (IncludeNotFoundSupressed) {
            PP.SetSuppressIncludeNotFoundError(false);
            IncludeNotFoundSupressed = false;
        } else {
            ShouldWarnHeaderNotFound = true;
        }
    }
    return false;
}
Ejemplo n.º 3
0
bool Context::isThunkSymbol(llvm::StringRef MangledName) {
  if (isMangledName(MangledName)) {
    // First do a quick check
    if (MangledName.endswith("TA") ||  // partial application forwarder
        MangledName.endswith("Ta") ||  // ObjC partial application forwarder
        MangledName.endswith("To") ||  // swift-as-ObjC thunk
        MangledName.endswith("TO") ||  // ObjC-as-swift thunk
        MangledName.endswith("TR") ||  // reabstraction thunk helper function
        MangledName.endswith("Tr") ||  // reabstraction thunk
        MangledName.endswith("TW") ||  // protocol witness thunk
        MangledName.endswith("fC")) {  // allocating constructor

      // To avoid false positives, we need to fully demangle the symbol.
      NodePointer Nd = D->demangleSymbol(MangledName);
      if (!Nd || Nd->getKind() != Node::Kind::Global ||
          Nd->getNumChildren() == 0)
        return false;

      switch (Nd->getFirstChild()->getKind()) {
        case Node::Kind::ObjCAttribute:
        case Node::Kind::NonObjCAttribute:
        case Node::Kind::PartialApplyObjCForwarder:
        case Node::Kind::PartialApplyForwarder:
        case Node::Kind::ReabstractionThunkHelper:
        case Node::Kind::ReabstractionThunk:
        case Node::Kind::ProtocolWitness:
        case Node::Kind::Allocator:
          return true;
        default:
          break;
      }
    }
    return false;
  }

  if (MangledName.startswith("_T")) {
    // Old mangling.
    StringRef Remaining = MangledName.substr(2);
    if (Remaining.startswith("To") ||   // swift-as-ObjC thunk
        Remaining.startswith("TO") ||   // ObjC-as-swift thunk
        Remaining.startswith("PA_") ||  // partial application forwarder
        Remaining.startswith("PAo_")) { // ObjC partial application forwarder
      return true;
    }
  }
  return false;
}
Ejemplo n.º 4
0
void MocPPCallbacks::EnterMainFile(llvm::StringRef Name)
{
    if (Name.endswith("global/qnamespace.h")) {
        // qnamsepace.h is a bit special because it contains all the Qt namespace enums
        // but all the Q_ENUMS are within a Q_MOC_RUN scope, which also do all sort of things.

        clang::MacroInfo *MI = PP.AllocateMacroInfo({});
        MI->setIsBuiltinMacro();
#if CLANG_VERSION_MAJOR != 3 || CLANG_VERSION_MINOR > 2
        PP.appendDefMacroDirective(PP.getIdentifierInfo("Q_MOC_RUN"), MI);
#else
        PP.setMacroInfo(PP.getIdentifierInfo("Q_MOC_RUN"), MI);
#endif
        InjectQObjectDefs({});
    }
}
Ejemplo n.º 5
0
bool SplitPaths(llvm::StringRef PathStr,
                llvm::SmallVectorImpl<llvm::StringRef>& Paths,
                SplitMode Mode, llvm::StringRef Delim, bool Verbose) {
  assert(Delim.size() && "Splitting without a delimiter");

#if defined(LLVM_ON_WIN32)
  // Support using a ':' delimiter on Windows.
  const bool WindowsColon = Delim.equals(":");
#endif

  bool AllExisted = true;
  for (std::pair<llvm::StringRef, llvm::StringRef> Split = PathStr.split(Delim);
       !Split.second.empty(); Split = PathStr.split(Delim)) {

    if (!Split.first.empty()) {
      bool Exists = llvm::sys::fs::is_directory(Split.first);

#if defined(LLVM_ON_WIN32)
    // Because drive letters will have a colon we have to make sure the split
    // occurs at a colon not followed by a path separator.
    if (!Exists && WindowsColon && Split.first.size()==1) {
      // Both clang and cl.exe support '\' and '/' path separators.
      if (Split.second.front() == '\\' || Split.second.front() == '/') {
          const std::pair<llvm::StringRef, llvm::StringRef> Tmp =
              Split.second.split(Delim);
          // Split.first = 'C', but we want 'C:', so Tmp.first.size()+2
          Split.first =
              llvm::StringRef(Split.first.data(), Tmp.first.size() + 2);
          Split.second = Tmp.second;
          Exists = llvm::sys::fs::is_directory(Split.first);
      }
    }
#endif

      AllExisted = AllExisted && Exists;

      if (!Exists) {
        if (Mode == kFailNonExistant) {
          if (Verbose) {
            // Exiting early, but still log all non-existant paths that we have
            LogNonExistantDirectory(Split.first);
            while (!Split.second.empty()) {
              Split = PathStr.split(Delim);
              if (llvm::sys::fs::is_directory(Split.first)) {
                llvm::errs() << "  ignoring directory that exists \""
                             << Split.first << "\"\n";
              } else
                LogNonExistantDirectory(Split.first);
              Split = Split.second.split(Delim);
            }
            if (!llvm::sys::fs::is_directory(Split.first))
              LogNonExistantDirectory(Split.first);
          }
          return false;
        } else if (Mode == kAllowNonExistant)
          Paths.push_back(Split.first);
        else if (Verbose)
          LogNonExistantDirectory(Split.first);
      } else
        Paths.push_back(Split.first);
    }

    PathStr = Split.second;
  }

  // Trim trailing sep in case of A:B:C:D:
  if (!PathStr.empty() && PathStr.endswith(Delim))
    PathStr = PathStr.substr(0, PathStr.size()-Delim.size());

  if (!PathStr.empty()) {
    if (!llvm::sys::fs::is_directory(PathStr)) {
      AllExisted = false;
      if (Mode == kAllowNonExistant)
        Paths.push_back(PathStr);
      else if (Verbose)
        LogNonExistantDirectory(PathStr);
    } else
      Paths.push_back(PathStr);
  }

  return AllExisted;
}
Ejemplo n.º 6
0
/// ApplyQAOverride - Apply a list of edits to the input argument lists.
///
/// The input string is a space separate list of edits to perform,
/// they are applied in order to the input argument lists. Edits
/// should be one of the following forms:
///
///  '#': Silence information about the changes to the command line arguments.
///
///  '^': Add FOO as a new argument at the beginning of the command line.
///
///  '+': Add FOO as a new argument at the end of the command line.
///
///  's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
///  line.
///
///  'xOPTION': Removes all instances of the literal argument OPTION.
///
///  'XOPTION': Removes all instances of the literal argument OPTION,
///  and the following argument.
///
///  'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
///  at the end of the command line.
///
/// \param OS - The stream to write edit information to.
/// \param Args - The vector of command line arguments.
/// \param Edit - The override command to perform.
/// \param SavedStrings - Set to use for storing string representations.
static void ApplyOneQAOverride(llvm::raw_ostream &OS,
                               llvm::SmallVectorImpl<const char*> &Args,
                               llvm::StringRef Edit,
                               std::set<std::string> &SavedStrings) {
  // This does not need to be efficient.

  if (Edit[0] == '^') {
    const char *Str =
      SaveStringInSet(SavedStrings, Edit.substr(1));
    OS << "### Adding argument " << Str << " at beginning\n";
    Args.insert(Args.begin() + 1, Str);
  } else if (Edit[0] == '+') {
    const char *Str =
      SaveStringInSet(SavedStrings, Edit.substr(1));
    OS << "### Adding argument " << Str << " at end\n";
    Args.push_back(Str);
  } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
             Edit.slice(2, Edit.size()-1).find('/') != llvm::StringRef::npos) {
    llvm::StringRef MatchPattern = Edit.substr(2).split('/').first;
    llvm::StringRef ReplPattern = Edit.substr(2).split('/').second;
    ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1);

    for (unsigned i = 1, e = Args.size(); i != e; ++i) {
      std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);

      if (Repl != Args[i]) {
        OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n";
        Args[i] = SaveStringInSet(SavedStrings, Repl);
      }
    }
  } else if (Edit[0] == 'x' || Edit[0] == 'X') {
    std::string Option = Edit.substr(1, std::string::npos);
    for (unsigned i = 1; i < Args.size();) {
      if (Option == Args[i]) {
        OS << "### Deleting argument " << Args[i] << '\n';
        Args.erase(Args.begin() + i);
        if (Edit[0] == 'X') {
          if (i < Args.size()) {
            OS << "### Deleting argument " << Args[i] << '\n';
            Args.erase(Args.begin() + i);
          } else
            OS << "### Invalid X edit, end of command line!\n";
        }
      } else
        ++i;
    }
  } else if (Edit[0] == 'O') {
    for (unsigned i = 1; i < Args.size();) {
      const char *A = Args[i];
      if (A[0] == '-' && A[1] == 'O' &&
          (A[2] == '\0' ||
           (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
                             ('0' <= A[2] && A[2] <= '9'))))) {
        OS << "### Deleting argument " << Args[i] << '\n';
        Args.erase(Args.begin() + i);
      } else
        ++i;
    }
    OS << "### Adding argument " << Edit << " at end\n";
    Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str()));
  } else {
    OS << "### Unrecognized edit: " << Edit << "\n";
  }
}