summaryrefslogtreecommitdiffstats
path: root/tools/libclang/CIndexCodeCompletion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libclang/CIndexCodeCompletion.cpp')
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp108
1 files changed, 58 insertions, 50 deletions
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 46af661..f79de29 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -13,16 +13,16 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
-#include "CXTranslationUnit.h"
-#include "CXString.h"
+#include "CIndexDiagnostic.h"
+#include "CLog.h"
#include "CXCursor.h"
#include "CXString.h"
-#include "CIndexDiagnostic.h"
-#include "clang/AST/Type.h"
+#include "CXTranslationUnit.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/SourceManager.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -32,11 +32,12 @@
#include "llvm/Support/Atomic.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Program.h"
-#include <cstdlib>
#include <cstdio>
+#include <cstdlib>
+#include <string>
#ifdef UDP_CODE_COMPLETION_LOGGER
@@ -48,7 +49,7 @@
#endif
using namespace clang;
-using namespace clang::cxstring;
+using namespace clang::cxindex;
extern "C" {
@@ -111,7 +112,7 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
unsigned chunk_number) {
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr || chunk_number >= CCStr->size())
- return createCXString((const char*)0);
+ return cxstring::createNull();
switch ((*CCStr)[chunk_number].Kind) {
case CodeCompletionString::CK_TypedText:
@@ -134,11 +135,11 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
case CodeCompletionString::CK_Equal:
case CodeCompletionString::CK_HorizontalSpace:
case CodeCompletionString::CK_VerticalSpace:
- return createCXString((*CCStr)[chunk_number].Text, false);
+ return cxstring::createRef((*CCStr)[chunk_number].Text);
case CodeCompletionString::CK_Optional:
// Note: treated as an empty text block.
- return createCXString("");
+ return cxstring::createEmpty();
}
llvm_unreachable("Invalid CodeCompletionString Kind!");
@@ -209,8 +210,8 @@ unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
CXString clang_getCompletionAnnotation(CXCompletionString completion_string,
unsigned annotation_number) {
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
- return CCStr ? createCXString(CCStr->getAnnotation(annotation_number))
- : createCXString((const char *) 0);
+ return CCStr ? cxstring::createRef(CCStr->getAnnotation(annotation_number))
+ : cxstring::createNull();
}
CXString
@@ -221,9 +222,9 @@ clang_getCompletionParent(CXCompletionString completion_string,
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr)
- return createCXString((const char *)0);
+ return cxstring::createNull();
- return createCXString(CCStr->getParentContextName(), /*DupString=*/false);
+ return cxstring::createRef(CCStr->getParentContextName());
}
CXString
@@ -231,14 +232,20 @@ clang_getCompletionBriefComment(CXCompletionString completion_string) {
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr)
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
- return createCXString(CCStr->getBriefComment(), /*DupString=*/false);
+ return cxstring::createRef(CCStr->getBriefComment());
}
-
+namespace {
+
/// \brief The CXCodeCompleteResults structure we allocate internally;
/// the client only sees the initial CXCodeCompleteResults structure.
+///
+/// Normally, clients of CXString shouldn't care whether or not a CXString is
+/// managed by a pool or by explicitly malloc'ed memory. But
+/// AllocatedCXCodeCompleteResults outlives the CXTranslationUnit, so we can
+/// not rely on the StringPool in the TU.
struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
AllocatedCXCodeCompleteResults(const FileSystemOptions& FileSystemOpts);
~AllocatedCXCodeCompleteResults();
@@ -287,8 +294,10 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \brief The kind of the container for the current context for completions.
enum CXCursorKind ContainerKind;
+
/// \brief The USR of the container for the current context for completions.
- CXString ContainerUSR;
+ std::string ContainerUSR;
+
/// \brief a boolean value indicating whether there is complete information
/// about the container
unsigned ContainerIsIncomplete;
@@ -298,6 +307,8 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
std::string Selector;
};
+} // end anonymous namespace
+
/// \brief Tracks the number of code-completion result objects that are
/// currently active.
///
@@ -317,7 +328,6 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
Contexts(CXCompletionContext_Unknown),
ContainerKind(CXCursor_InvalidCode),
- ContainerUSR(createCXString("")),
ContainerIsIncomplete(1)
{
if (getenv("LIBCLANG_OBJTRACKING")) {
@@ -328,9 +338,7 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
delete [] Results;
-
- clang_disposeString(ContainerUSR);
-
+
for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
TemporaryFiles[I].eraseFromDisk();
for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
@@ -587,24 +595,13 @@ namespace {
if (D != NULL) {
CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
-
- CXCursorKind cursorKind = clang_getCursorKind(cursor);
- CXString cursorUSR = clang_getCursorUSR(cursor);
-
- // Normally, clients of CXString shouldn't care whether or not
- // a CXString is managed by a pool or by explicitly malloc'ed memory.
- // However, there are cases when AllocatedResults outlives the
- // CXTranslationUnit. This is a workaround that failure mode.
- if (cxstring::isManagedByPool(cursorUSR)) {
- CXString heapStr =
- cxstring::createCXString(clang_getCString(cursorUSR), true);
- clang_disposeString(cursorUSR);
- cursorUSR = heapStr;
- }
-
- AllocatedResults.ContainerKind = cursorKind;
- AllocatedResults.ContainerUSR = cursorUSR;
-
+
+ AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
+
+ CXString CursorUSR = clang_getCursorUSR(cursor);
+ AllocatedResults.ContainerUSR = clang_getCString(CursorUSR);
+ clang_disposeString(CursorUSR);
+
const Type *type = baseType.getTypePtrOrNull();
if (type != NULL) {
AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
@@ -615,7 +612,7 @@ namespace {
}
else {
AllocatedResults.ContainerKind = CXCursor_InvalidCode;
- AllocatedResults.ContainerUSR = createCXString("");
+ AllocatedResults.ContainerUSR.clear();
AllocatedResults.ContainerIsIncomplete = 1;
}
}
@@ -684,11 +681,11 @@ void clang_codeCompleteAt_Impl(void *UserData) {
bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
- ASTUnit *AST = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *AST = cxtu::getASTUnit(TU);
if (!AST)
return;
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
setThreadBackgroundPriority();
@@ -819,14 +816,25 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
struct CXUnsavedFile *unsaved_files,
unsigned num_unsaved_files,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << TU << ' '
+ << complete_filename << ':' << complete_line << ':' << complete_column;
+ }
+
CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
complete_column, unsaved_files, num_unsaved_files,
options, 0 };
+
+ if (getenv("LIBCLANG_NOTHREADS")) {
+ clang_codeCompleteAt_Impl(&CCAI);
+ return CCAI.result;
+ }
+
llvm::CrashRecoveryContext CRC;
if (!RunSafely(CRC, clang_codeCompleteAt_Impl, &CCAI)) {
fprintf(stderr, "libclang: crash detected in code completion\n");
- static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
+ cxtu::getASTUnit(TU)->setUnsafeToFree(true);
return 0;
} else if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
@@ -897,9 +905,9 @@ CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
AllocatedCXCodeCompleteResults *Results =
static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
if (!Results)
- return createCXString("");
-
- return createCXString(clang_getCString(Results->ContainerUSR));
+ return cxstring::createEmpty();
+
+ return cxstring::createRef(Results->ContainerUSR.c_str());
}
@@ -907,9 +915,9 @@ CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
AllocatedCXCodeCompleteResults *Results =
static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
if (!Results)
- return createCXString("");
+ return cxstring::createEmpty();
- return createCXString(Results->Selector);
+ return cxstring::createDup(Results->Selector);
}
} // end extern "C"
OpenPOWER on IntegriCloud