예제 #1
0
FileLocation findDefinitionLocation(const FileLocation& location)
{
   // bail if we aren't initialized
   if (!s_initialized)
      return FileLocation();

   // get the definition cursor for this file location
   Cursor cursor = rSourceIndex().referencedCursorForFileLocation(location);
   if (cursor.isNull())
      return FileLocation();

   // get the USR for the cursor and search for it
   std::string USR = cursor.getUSR();
   if (!USR.empty())
   {
      // first inspect translation units we have an in-memory index for
      TranslationUnits units = rSourceIndex().getIndexedTranslationUnits();
      BOOST_FOREACH(const TranslationUnits::value_type& unit, units)
      {
         // search for the definition
         CppDefinition def;
         DefinitionVisitor visitor = boost::bind(findUSR, USR, _1, &def);

         // visit the cursors
         libclang::clang().visitChildren(
              libclang::clang().getTranslationUnitCursor(
                     unit.second.getCXTranslationUnit()),
              cursorVisitor,
              (CXClientData)&visitor);

         // return the definition if we found it
         if (!def.empty())
            return def.location;
      }
예제 #2
0
core::Error findReferences(const core::libclang::FileLocation& location,
                           std::string* pSpelling,
                           std::vector<core::libclang::FileRange>* pRefs)
{
   Cursor cursor = rSourceIndex().referencedCursorForFileLocation(location);
   if (!cursor.isValid() || !cursor.isDeclaration())
      return Success();

   // get it's USR (bail if it doesn't have one)
   std::string USR = cursor.getUSR();
   if (USR.empty())
      return Success();

   // determine what translation units to look in -- if this is a package
   // then we look throughout all the source code in the package.
   if (rCompilationDatabase().hasTranslationUnit(
                                         location.filePath.absolutePath()))
   {
      // get all translation units to search
      std::vector<std::string> files = rCompilationDatabase()
                                                .translationUnits();

      // get translation units we've already indexed
      std::map<std::string,TranslationUnit> indexedUnits =
                           rSourceIndex().getIndexedTranslationUnits();

      for (const std::string& filename : files)
      {
         // first look in already indexed translation units
         // (this will pickup unsaved files)
         std::map<std::string,TranslationUnit>::iterator it =
                                                   indexedUnits.find(filename);
         if (it != indexedUnits.end())
         {
            findReferences(USR,
                           it->second.getCXTranslationUnit(),
                           pSpelling,
                           pRefs);
         }
         else
         {
            // get the compilation arguments for this file and use them to
            // create a temporary translation unit to search
            std::vector<std::string> compileArgs =
               rCompilationDatabase().compileArgsForTranslationUnit(filename,
                                                                    true);

            if (compileArgs.empty())
               continue;

            // create temporary index
            CXIndex index = libclang::clang().createIndex(
                              1 /* Exclude PCH */,
                              (rSourceIndex().verbose() > 0) ? 1 : 0);

            // get args in form clang expects
            core::system::ProcessArgs argsArray(compileArgs);

            // parse the translation unit
            CXTranslationUnit tu = libclang::clang().parseTranslationUnit(
                                  index,
                                  filename.c_str(),
                                  argsArray.args(),
                                  gsl::narrow_cast<int>(argsArray.argCount()),
                                  nullptr, 0, // no unsaved files
                                  CXTranslationUnit_None |
                                  CXTranslationUnit_Incomplete);

            // find references
            findReferences(USR, tu, pSpelling, pRefs);

            // dispose translation unit and index
            libclang::clang().disposeTranslationUnit(tu);
            libclang::clang().disposeIndex(index);
         }
      }
   }
   // not a package, just search locally
   else
   {
      TranslationUnit tu = rSourceIndex().getTranslationUnit(
                                             location.filePath.absolutePath(),
                                             true);
      if (!tu.empty())
         findReferences(USR, tu.getCXTranslationUnit(), pSpelling, pRefs);
   }

   return Success();

}