]> granicus.if.org Git - clang/commitdiff
Switch clang_createTranslationUnitFromSourceFile to use ASTUnit::LoadFromCommandLine.
authorDaniel Dunbar <daniel@zuster.org>
Thu, 3 Dec 2009 01:54:28 +0000 (01:54 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 3 Dec 2009 01:54:28 +0000 (01:54 +0000)
 - This is much faster, as it avoids the overhead of dumping an AST file to disk and reloading it.
 - For debugging purposes, there is a clang_setUseExternalASTGeneration hook which can be used to disable this.

On the Sketch Cocoa app, the speedup is pretty nice, especially when using a PCH file while scanning the source:

Wall time to c-index-test all files (no PCH):
Old: 23.4221
New: 12.3884

Wall time to c-index-test all files (with a PCH, and "local" mode):
Old: 10.9233
New:  1.9038

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90385 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang-c/Index.h
tools/CIndex/CIndex.cpp
tools/CIndex/CIndex.exports
tools/c-index-test/c-index-test.c

index 8e6eeb5422de63d0136f60d742d38c64cc29e8ec..4e768097c402cdb98d353e241f2d39aa8955b21c 100644 (file)
@@ -202,8 +202,22 @@ CINDEX_LINKAGE void clang_disposeString(CXString string);
  */
 CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
                           int displayDiagnostics);
-CINDEX_LINKAGE void clang_disposeIndex(CXIndex);
-CINDEX_LINKAGE CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
+CINDEX_LINKAGE void clang_disposeIndex(CXIndex index);
+CINDEX_LINKAGE CXString
+clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
+
+/* 
+ * \brief Request that AST's be generated external for API calls which parse
+ * source code on the fly, e.g. \see createTranslationUnitFromSourceFile.
+ *
+ * Note: This is for debugging purposes only, and may be removed at a later
+ * date.
+ *
+ * \param index - The index to update.
+ * \param value - The new flag value.
+ */
+CINDEX_LINKAGE void clang_setUseExternalASTGeneration(CXIndex index,
+                                                      int value);
 
 /* 
  * \brief Create a translation unit from an AST file (-emit-ast).
@@ -211,6 +225,7 @@ CINDEX_LINKAGE CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUni
 CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(
   CXIndex, const char *ast_filename
 );
+
 /**
  * \brief Destroy the specified CXTranslationUnit object.
  */ 
@@ -220,20 +235,25 @@ CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
  * \brief Return the CXTranslationUnit for a given source file and the provided
  * command line arguments one would pass to the compiler.
  *
- * Note: The 'source_filename' argument is optional.  If the caller provides a NULL pointer,
- *  the name of the source file is expected to reside in the specified command line arguments.
+ * Note: The 'source_filename' argument is optional.  If the caller provides a
+ * NULL pointer, the name of the source file is expected to reside in the
+ * specified command line arguments.
  *
- * Note: When encountered in 'clang_command_line_args', the following options are ignored:
+ * Note: When encountered in 'clang_command_line_args', the following options
+ * are ignored:
  *
  *   '-c'
  *   '-emit-ast'
  *   '-fsyntax-only'
  *   '-o <output file>'  (both '-o' and '<output file>' are ignored)
  *
+ *
+ * \param source_filename - The name of the source file to load, or NULL if the
+ * source file is included in clang_command_line_args.
  */
 CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
-  CXIndex CIdx, 
-  const char *source_filename /* specify NULL if the source file is in clang_command_line_args */,
+  CXIndex CIdx,
+  const char *source_filename,
   int num_clang_command_line_args, 
   const char **clang_command_line_args
 );
@@ -253,13 +273,14 @@ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
    }
    static void usage {
      clang_loadTranslationUnit(CXTranslationUnit, printObjCInterfaceNames);
-   }
+  }
 */
 typedef void *CXClientData;
 typedef void (*CXTranslationUnitIterator)(CXTranslationUnit, CXCursor, 
                                           CXClientData);
-CINDEX_LINKAGE void clang_loadTranslationUnit(CXTranslationUnit, CXTranslationUnitIterator,
-                               CXClientData);
+CINDEX_LINKAGE void clang_loadTranslationUnit(CXTranslationUnit,
+                                              CXTranslationUnitIterator,
+                                              CXClientData);
 
 /*
    Usage: clang_loadDeclaration(). Will load the declaration, issuing a 
@@ -320,8 +341,9 @@ CINDEX_LINKAGE CXFile clang_getDeclSourceFile(CXDecl);
    Usage: clang_getCursor() will translate a source/line/column position
    into an AST cursor (to derive semantic information from the source code).
  */
-CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, const char *source_name, 
-                         unsigned line, unsigned column);
+CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit,
+                                        const char *source_name, 
+                                        unsigned line, unsigned column);
                          
 CINDEX_LINKAGE CXCursor clang_getNullCursor(void);
 
@@ -634,11 +656,11 @@ clang_getNumCompletionChunks(CXCompletionString completion_string);
  * \param CIdx the \c CXIndex instance that will be used to perform code
  * completion.
  *
- * \param source_filename the name of the source file that should be parsed
- * to perform code-completion. This source file must be the same as or
- * include the filename described by \p complete_filename, or no code-completion
- * results will be produced.  NOTE: One can also specify NULL for this argument if
- * the source file is included in command_line_args.
+ * \param source_filename the name of the source file that should be parsed to
+ * perform code-completion. This source file must be the same as or include the
+ * filename described by \p complete_filename, or no code-completion results
+ * will be produced.  NOTE: One can also specify NULL for this argument if the
+ * source file is included in command_line_args.
  *
  * \param num_command_line_args the number of command-line arguments stored in
  * \p command_line_args.
index a5b7e996229a763ae9156dc1d6f9109ad77ef490..8ef9fb5ca090149f04d917c303639426ce23135b 100644 (file)
@@ -324,6 +324,11 @@ public:
     DisplayDiagnostics = Display;
   }
 
+  bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; }
+  void setUseExternalASTGeneration(bool Value) {
+    UseExternalASTGeneration = Value;
+  }
+
   Diagnostic &getDiags() {
     return DisplayDiagnostics ? *TextDiags : IgnoreDiags;
   }
@@ -466,6 +471,12 @@ void clang_disposeIndex(CXIndex CIdx) {
   delete static_cast<CIndexer *>(CIdx);
 }
 
+void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) {
+  assert(CIdx && "Passed null CXIndex");
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+  CXXIdx->setUseExternalASTGeneration(value);
+}
+
 // FIXME: need to pass back error info.
 CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
                                               const char *ast_filename) {
@@ -485,6 +496,24 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
   assert(CIdx && "Passed null CXIndex");
   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
 
+  if (!CXXIdx->getUseExternalASTGeneration()) {
+    llvm::SmallVector<const char *, 16> Args;
+
+    // The 'source_filename' argument is optional.  If the caller does not
+    // specify it then it is assumed that the source file is specified
+    // in the actual argument list.
+    if (source_filename)
+      Args.push_back(source_filename);
+    Args.insert(Args.end(), command_line_args,
+                command_line_args + num_command_line_args);
+
+    void *MainAddr = (void *)(uintptr_t)clang_createTranslationUnit;
+    return ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
+                                        CXXIdx->getDiags(), "<clang>", MainAddr,
+                                        CXXIdx->getOnlyLocalDecls(),
+                                        /* UseBumpAllocator = */ true);
+  }
+
   // Build up the arguments for invoking 'clang'.
   std::vector<const char *> argv;
 
@@ -572,8 +601,18 @@ void clang_loadTranslationUnit(CXTranslationUnit CTUnit,
   ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
   ASTContext &Ctx = CXXUnit->getASTContext();
 
-  TUVisitor DVisit(CTUnit, callback, CData,
-                   CXXUnit->getOnlyLocalDecls()? 1 : Decl::MaxPCHLevel);
+  unsigned PCHLevel = Decl::MaxPCHLevel;
+
+  // Set the PCHLevel to filter out unwanted decls if requested.
+  if (CXXUnit->getOnlyLocalDecls()) {
+    PCHLevel = 0;
+
+    // If the main input was an AST, bump the level.
+    if (CXXUnit->isMainFileAST())
+      ++PCHLevel;
+  }
+
+  TUVisitor DVisit(CTUnit, callback, CData, PCHLevel);
   DVisit.Visit(Ctx.getTranslationUnitDecl());
 }
 
index 2892ce50e70d54be4e5a1486b6b63cd4b09f53f3..458ad1028359c732a49afc2ee0c5c87d954c07dc 100644 (file)
@@ -6,6 +6,7 @@ _clang_disposeIndex
 _clang_disposeString
 _clang_disposeTranslationUnit
 _clang_equalCursors
+_clang_getCString
 _clang_getCompletionChunkCompletionString
 _clang_getCompletionChunkKind
 _clang_getCompletionChunkText
@@ -19,7 +20,6 @@ _clang_getCursorLine
 _clang_getCursorSource
 _clang_getCursorSourceFile
 _clang_getCursorSpelling
-_clang_getCString
 _clang_getDeclColumn
 _clang_getDeclLine
 _clang_getDeclSource
@@ -41,3 +41,4 @@ _clang_isInvalid
 _clang_isReference
 _clang_loadDeclaration
 _clang_loadTranslationUnit
+_clang_setUseExternalASTGeneration
index efff1ae3188cedb794dd04cc542f69a2bb755171..7300585a1d8836408b8a7401ad4bf4430754c913 100644 (file)
@@ -179,12 +179,17 @@ int perform_test_load_tu(const char *file, const char *filter) {
 }
 
 int perform_test_load_source(int argc, const char **argv, const char *filter) {
+  const char *UseExternalASTs =
+    getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION");
   CXIndex Idx;
   CXTranslationUnit TU;
   Idx = clang_createIndex(/* excludeDeclsFromPCH */
                           !strcmp(filter, "local") ? 1 : 0,
                           /* displayDiagnostics */ 1);
 
+  if (UseExternalASTs && strlen(UseExternalASTs))
+    clang_setUseExternalASTGeneration(Idx, 1);
+
   TU = clang_createTranslationUnitFromSourceFile(Idx, 0, argc, argv);
   if (!TU) {
     fprintf(stderr, "Unable to load translation unit!\n");