summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-08-16 18:08:11 +0000
committerDouglas Gregor <dgregor@apple.com>2010-08-16 18:08:11 +0000
commitb61c07aca03841b461bc8f9b44c93be9abc0c640 (patch)
tree6d22032ef78a7331f93e4832aa8cdcf1608a92dd /clang/lib
parent8be0196afeed5dd738fce4c7df950f205e462c13 (diff)
downloadbcm5719-llvm-b61c07aca03841b461bc8f9b44c93be9abc0c640.tar.gz
bcm5719-llvm-b61c07aca03841b461bc8f9b44c93be9abc0c640.zip
When caching code completions for global declarations, keep track of
the usage type of each declaration result, then compare those types to the preferred type of the completion. This provides parity in the priority calculation between the code-completion results produced directly from Sema and those cached by ASTUnit. For the standard Cocoa.h (+ others) example, there's a penalty of 3-4 hundredeths of a second when caching the global results (for ~31,000 results), because we need an ASTContext-agnostic representation of types for the comparison, and therefore we use... strings. Eventually, we'd like to implement a more efficient ASTContext-agnostic encoding of types. llvm-svn: 111165
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp46
1 files changed, 38 insertions, 8 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index b54162f8d7d..86588c93752 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/TypeOrdering.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
@@ -182,6 +183,8 @@ void ASTUnit::CacheCodeCompletionResults() {
TheSema->GatherGlobalCodeCompletions(Results);
// Translate global code completions into cached completions.
+ llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
+
for (unsigned I = 0, N = Results.size(); I != N; ++I) {
switch (Results[I].Kind) {
case Result::RK_Declaration: {
@@ -192,13 +195,30 @@ void ASTUnit::CacheCodeCompletionResults() {
CachedResult.Priority = Results[I].Priority;
CachedResult.Kind = Results[I].CursorKind;
+ // Keep track of the type of this completion in an ASTContext-agnostic
+ // way.
QualType UsageType = getDeclUsageType(*Ctx, Results[I].Declaration);
- if (UsageType.isNull())
+ if (UsageType.isNull()) {
CachedResult.TypeClass = STC_Void;
- else {
- CachedResult.TypeClass
- = getSimplifiedTypeClass(Ctx->getCanonicalType(UsageType));
+ CachedResult.Type = 0;
+ } else {
+ CanQualType CanUsageType
+ = Ctx->getCanonicalType(UsageType.getUnqualifiedType());
+ CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType);
+
+ // Determine whether we have already seen this type. If so, we save
+ // ourselves the work of formatting the type string by using the
+ // temporary, CanQualType-based hash table to find the associated value.
+ unsigned &TypeValue = CompletionTypes[CanUsageType];
+ if (TypeValue == 0) {
+ TypeValue = CompletionTypes.size();
+ CachedCompletionTypes[QualType(CanUsageType).getAsString()]
+ = TypeValue;
+ }
+
+ CachedResult.Type = TypeValue;
}
+
CachedCompletionResults.push_back(CachedResult);
break;
}
@@ -224,6 +244,7 @@ void ASTUnit::CacheCodeCompletionResults() {
CachedResult.Priority = Results[I].Priority;
CachedResult.Kind = Results[I].CursorKind;
CachedResult.TypeClass = STC_Void;
+ CachedResult.Type = 0;
CachedCompletionResults.push_back(CachedResult);
break;
}
@@ -239,6 +260,7 @@ void ASTUnit::ClearCachedCompletionResults() {
for (unsigned I = 0, N = CachedCompletionResults.size(); I != N; ++I)
delete CachedCompletionResults[I].Completion;
CachedCompletionResults.clear();
+ CachedCompletionTypes.clear();
}
namespace {
@@ -1432,13 +1454,21 @@ namespace {
if (C->Kind == CXCursor_MacroDefinition) {
Priority = getMacroUsagePriority(C->Completion->getTypedText(),
Context.getPreferredType()->isAnyPointerType());
- } else {
+ } else if (C->Type) {
CanQualType Expected
- = S.Context.getCanonicalType(Context.getPreferredType());
+ = S.Context.getCanonicalType(
+ Context.getPreferredType().getUnqualifiedType());
SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected);
if (ExpectedSTC == C->TypeClass) {
- // FIXME: How can we check for an exact match?
- Priority /= CCF_SimilarTypeMatch;
+ // We know this type is similar; check for an exact match.
+ llvm::StringMap<unsigned> &CachedCompletionTypes
+ = AST.getCachedCompletionTypes();
+ llvm::StringMap<unsigned>::iterator Pos
+ = CachedCompletionTypes.find(QualType(Expected).getAsString());
+ if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
+ Priority /= CCF_ExactTypeMatch;
+ else
+ Priority /= CCF_SimilarTypeMatch;
}
}
}
OpenPOWER on IntegriCloud