aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaCodeComplete.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r--lib/Sema/SemaCodeComplete.cpp78
1 files changed, 68 insertions, 10 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 61c17c89bd..1d91c3fa81 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -239,6 +239,7 @@ namespace {
bool IsMember(NamedDecl *ND) const;
bool IsObjCIvar(NamedDecl *ND) const;
bool IsObjCMessageReceiver(NamedDecl *ND) const;
+ bool IsObjCCollection(NamedDecl *ND) const;
//@}
};
}
@@ -366,8 +367,12 @@ getRequiredQualification(ASTContext &Context,
DeclContext *Parent = TargetParents.back();
TargetParents.pop_back();
- if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
+ if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
+ if (!Namespace->getIdentifier())
+ continue;
+
Result = NestedNameSpecifier::Create(Context, Result, Namespace);
+ }
else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
Result = NestedNameSpecifier::Create(Context, Result,
false,
@@ -946,6 +951,20 @@ bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
return isObjCReceiverType(SemaRef.Context, T);
}
+bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
+ if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
+ (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
+ return false;
+
+ QualType T = getDeclUsageType(SemaRef.Context, ND);
+ if (T.isNull())
+ return false;
+
+ T = SemaRef.Context.getBaseElementType(T);
+ return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
+ T->isObjCIdType() ||
+ (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
+}
/// \rief Determines whether the given declaration is an Objective-C
/// instance variable.
@@ -2303,23 +2322,42 @@ void Sema::CodeCompleteDeclarator(Scope *S,
Results.data(), Results.size());
}
+struct Sema::CodeCompleteExpressionData {
+ CodeCompleteExpressionData(QualType PreferredType = QualType())
+ : PreferredType(PreferredType), IntegralConstantExpression(false),
+ ObjCCollection(false) { }
+
+ QualType PreferredType;
+ bool IntegralConstantExpression;
+ bool ObjCCollection;
+ llvm::SmallVector<Decl *, 4> IgnoreDecls;
+};
+
/// \brief Perform code-completion in an expression context when we know what
/// type we're looking for.
///
/// \param IntegralConstantExpression Only permit integral constant
/// expressions.
-void Sema::CodeCompleteExpression(Scope *S, QualType T,
- bool IntegralConstantExpression) {
+void Sema::CodeCompleteExpression(Scope *S,
+ const CodeCompleteExpressionData &Data) {
typedef CodeCompleteConsumer::Result Result;
ResultBuilder Results(*this);
- if (IntegralConstantExpression)
+ if (Data.ObjCCollection)
+ Results.setFilter(&ResultBuilder::IsObjCCollection);
+ else if (Data.IntegralConstantExpression)
Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Results.setFilter(&ResultBuilder::IsOrdinaryName);
else
Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
- Results.setPreferredType(T.getNonReferenceType());
+
+ if (!Data.PreferredType.isNull())
+ Results.setPreferredType(Data.PreferredType.getNonReferenceType());
+
+ // Ignore any declarations that we were told that we don't care about.
+ for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
+ Results.Ignore(Data.IgnoreDecls[I]);
CodeCompletionDeclConsumer Consumer(Results, CurContext);
LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
@@ -2330,14 +2368,16 @@ void Sema::CodeCompleteExpression(Scope *S, QualType T,
Results.ExitScope();
bool PreferredTypeIsPointer = false;
- if (!T.isNull())
- PreferredTypeIsPointer = T->isAnyPointerType() ||
- T->isMemberPointerType() || T->isBlockPointerType();
+ if (!Data.PreferredType.isNull())
+ PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
+ || Data.PreferredType->isMemberPointerType()
+ || Data.PreferredType->isBlockPointerType();
if (CodeCompleter->includeMacros())
AddMacroResults(PP, Results, PreferredTypeIsPointer);
HandleCodeCompleteResults(this, CodeCompleter,
- CodeCompletionContext(CodeCompletionContext::CCC_Expression, T),
+ CodeCompletionContext(CodeCompletionContext::CCC_Expression,
+ Data.PreferredType),
Results.data(),Results.size());
}
@@ -2534,7 +2574,9 @@ void Sema::CodeCompleteCase(Scope *S) {
SwitchStmt *Switch = getSwitchStack().back();
if (!Switch->getCond()->getType()->isEnumeralType()) {
- CodeCompleteExpression(S, Switch->getCond()->getType(), true);
+ CodeCompleteExpressionData Data(Switch->getCond()->getType());
+ Data.IntegralConstantExpression = true;
+ CodeCompleteExpression(S, Data);
return;
}
@@ -3752,6 +3794,22 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
Results.data(),Results.size());
}
+void Sema::CodeCompleteObjCForCollection(Scope *S,
+ DeclGroupPtrTy IterationVar) {
+ CodeCompleteExpressionData Data;
+ Data.ObjCCollection = true;
+
+ if (IterationVar.getAsOpaquePtr()) {
+ DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
+ for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
+ if (*I)
+ Data.IgnoreDecls.push_back(*I);
+ }
+ }
+
+ CodeCompleteExpression(S, Data);
+}
+
/// \brief Add all of the protocol declarations that we find in the given
/// (translation unit) context.
static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,