[cfe-commits] r93428 - in /cfe/trunk/lib/Sema: Lookup.h SemaCodeComplete.cpp SemaLookup.cpp
Douglas Gregor
dgregor at apple.com
Thu Jan 14 07:47:36 PST 2010
Author: dgregor
Date: Thu Jan 14 09:47:35 2010
New Revision: 93428
URL: http://llvm.org/viewvc/llvm-project?rev=93428&view=rev
Log:
Switch the remaining code completions over to LookupVisibleDecls,
after adding the ability to determine whether our lookup is a
base-class lookup. Eliminate CollectMemberLookupResults, since it is
no longer used (yay).
Modified:
cfe/trunk/lib/Sema/Lookup.h
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
Modified: cfe/trunk/lib/Sema/Lookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Lookup.h?rev=93428&r1=93427&r2=93428&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Lookup.h (original)
+++ cfe/trunk/lib/Sema/Lookup.h Thu Jan 14 09:47:35 2010
@@ -524,7 +524,11 @@
///
/// \param Hiding a declaration that hides the declaration \p ND,
/// or NULL if no such declaration exists.
- virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding) = 0;
+ ///
+ /// \param InBaseClass whether this declaration was found in base
+ /// class of the context we searched.
+ virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
+ bool InBaseClass) = 0;
};
}
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=93428&r1=93427&r2=93428&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Jan 14 09:47:35 2010
@@ -178,7 +178,11 @@
/// \param CurContext the context in which this result will be named.
///
/// \param Hiding the declaration that hides the result.
- void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding);
+ ///
+ /// \param InBaseClass whether the result was found in a base
+ /// class of the searched context.
+ void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
+ bool InBaseClass);
/// \brief Enter into a new scope.
void EnterNewScope();
@@ -543,7 +547,7 @@
}
void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
- NamedDecl *Hiding) {
+ NamedDecl *Hiding, bool InBaseClass = false) {
assert(R.Kind == Result::RK_Declaration &&
"Only declaration results are supported");
@@ -568,7 +572,11 @@
// nested-name-specifier.
if (AsNestedNameSpecifier)
R.StartsNestedNameSpecifier = true;
-
+ else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
+ isa<CXXRecordDecl>(R.Declaration->getDeclContext()
+ ->getLookupContext()))
+ R.QualifierIsInformative = true;
+
// If this result is supposed to have an informative qualifier, add one.
if (R.QualifierIsInformative && !R.Qualifier &&
!R.StartsNestedNameSpecifier) {
@@ -703,112 +711,12 @@
CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
: Results(Results), CurContext(CurContext) { }
- virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding) {
- Results.AddResult(ND, CurContext, Hiding);
+ virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
+ Results.AddResult(ND, CurContext, Hiding, InBaseClass);
}
};
}
-/// \brief Collect the results of searching for members within the given
-/// declaration context.
-///
-/// \param Ctx the declaration context from which we will gather results.
-///
-/// \param Visited the set of declaration contexts that have already been
-/// visited. Declaration contexts will only be visited once.
-///
-/// \param Results the result set that will be extended with any results
-/// found within this declaration context (and, for a C++ class, its bases).
-///
-/// \param InBaseClass whether we are in a base class.
-static void CollectMemberLookupResults(DeclContext *Ctx,
- DeclContext *CurContext,
- llvm::SmallPtrSet<DeclContext *, 16> &Visited,
- ResultBuilder &Results,
- bool InBaseClass = false) {
- // Make sure we don't visit the same context twice.
- if (!Visited.insert(Ctx->getPrimaryContext()))
- return;
-
- // Enumerate all of the results in this context.
- typedef CodeCompleteConsumer::Result Result;
- Results.EnterNewScope();
- for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
- CurCtx = CurCtx->getNextContext()) {
- for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
- DEnd = CurCtx->decls_end();
- D != DEnd; ++D) {
- if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
- Results.MaybeAddResult(Result(ND, 0, InBaseClass), CurContext);
-
- // Visit transparent contexts inside this context.
- if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
- if (InnerCtx->isTransparentContext())
- CollectMemberLookupResults(InnerCtx, CurContext, Visited,
- Results, InBaseClass);
- }
- }
- }
-
- // Traverse the contexts of inherited classes.
- if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
- for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
- BEnd = Record->bases_end();
- B != BEnd; ++B) {
- QualType BaseType = B->getType();
-
- // Don't look into dependent bases, because name lookup can't look
- // there anyway.
- if (BaseType->isDependentType())
- continue;
-
- const RecordType *Record = BaseType->getAs<RecordType>();
- if (!Record)
- continue;
-
- // FIXME: It would be nice to be able to determine whether referencing
- // a particular member would be ambiguous. For example, given
- //
- // struct A { int member; };
- // struct B { int member; };
- // struct C : A, B { };
- //
- // void f(C *c) { c->### }
- // accessing 'member' would result in an ambiguity. However, code
- // completion could be smart enough to qualify the member with the
- // base class, e.g.,
- //
- // c->B::member
- //
- // or
- //
- // c->A::member
-
- // Collect results from this base class (and its bases).
- CollectMemberLookupResults(Record->getDecl(), CurContext, Visited,
- Results, /*InBaseClass=*/true);
- }
- }
-
- // FIXME: Look into base classes in Objective-C!
-
- Results.ExitScope();
-}
-
-/// \brief Collect the results of searching for members within the given
-/// declaration context.
-///
-/// \param Ctx the declaration context from which we will gather results.
-///
-/// \param Results the result set that will be extended with any results
-/// found within this declaration context (and, for a C++ class, its bases).
-static void CollectMemberLookupResults(DeclContext *Ctx,
- DeclContext *CurContext,
- ResultBuilder &Results) {
- llvm::SmallPtrSet<DeclContext *, 16> Visited;
- CollectMemberLookupResults(Ctx, CurContext, Visited, Results);
-}
-
/// \brief Add type specifiers for the current language as keyword results.
static void AddTypeSpecifierResults(const LangOptions &LangOpts,
ResultBuilder &Results) {
@@ -2086,7 +1994,8 @@
if (const RecordType *Record = BaseType->getAs<RecordType>()) {
// Access to a C/C++ class, struct, or union.
Results.allowNestedNameSpecifiers();
- CollectMemberLookupResults(Record->getDecl(), Record->getDecl(), Results);
+ CodeCompletionDeclConsumer Consumer(Results, CurContext);
+ LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
if (getLangOptions().CPlusPlus) {
if (!Results.empty()) {
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=93428&r1=93427&r2=93428&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Jan 14 09:47:35 2010
@@ -1942,10 +1942,12 @@
(*I)->getIdentifierNamespace() != IDNS)
continue;
- // Functions and function templates overload rather than hide.
- // FIXME: Look for hiding based on function signatures!
+ // Functions and function templates in the same scope overload
+ // rather than hide. FIXME: Look for hiding based on function
+ // signatures!
if ((*I)->isFunctionOrFunctionTemplate() &&
- ND->isFunctionOrFunctionTemplate())
+ ND->isFunctionOrFunctionTemplate() &&
+ SM == ShadowMaps.rbegin())
continue;
// We've found a declaration that hides this one.
@@ -1958,6 +1960,7 @@
static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
bool QualifiedNameLookup,
+ bool InBaseClass,
VisibleDeclConsumer &Consumer,
VisibleDeclsRecord &Visited) {
// Make sure we don't visit the same context twice.
@@ -1972,14 +1975,14 @@
D != DEnd; ++D) {
if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
if (Result.isAcceptableDecl(ND)) {
- Consumer.FoundDecl(ND, Visited.checkHidden(ND));
+ Consumer.FoundDecl(ND, Visited.checkHidden(ND), InBaseClass);
Visited.add(ND);
}
// Visit transparent contexts inside this context.
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
if (InnerCtx->isTransparentContext())
- LookupVisibleDecls(InnerCtx, Result, QualifiedNameLookup,
+ LookupVisibleDecls(InnerCtx, Result, QualifiedNameLookup, InBaseClass,
Consumer, Visited);
}
}
@@ -1991,7 +1994,7 @@
DeclContext::udir_iterator I, E;
for (llvm::tie(I, E) = Ctx->getUsingDirectives(); I != E; ++I) {
LookupVisibleDecls((*I)->getNominatedNamespace(), Result,
- QualifiedNameLookup, Consumer, Visited);
+ QualifiedNameLookup, InBaseClass, Consumer, Visited);
}
}
@@ -2033,7 +2036,7 @@
// Find results in this base class (and its bases).
ShadowContextRAII Shadow(Visited);
LookupVisibleDecls(Record->getDecl(), Result, QualifiedNameLookup,
- Consumer, Visited);
+ true, Consumer, Visited);
}
}
@@ -2043,34 +2046,37 @@
for (ObjCCategoryDecl *Category = IFace->getCategoryList();
Category; Category = Category->getNextClassCategory()) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(Category, Result, QualifiedNameLookup, Consumer,
- Visited);
+ LookupVisibleDecls(Category, Result, QualifiedNameLookup, false,
+ Consumer, Visited);
}
// Traverse protocols.
for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
E = IFace->protocol_end(); I != E; ++I) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+ LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+ Visited);
}
// Traverse the superclass.
if (IFace->getSuperClass()) {
ShadowContextRAII Shadow(Visited);
LookupVisibleDecls(IFace->getSuperClass(), Result, QualifiedNameLookup,
- Consumer, Visited);
+ true, Consumer, Visited);
}
} else if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Ctx)) {
for (ObjCProtocolDecl::protocol_iterator I = Protocol->protocol_begin(),
E = Protocol->protocol_end(); I != E; ++I) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+ LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+ Visited);
}
} else if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Ctx)) {
for (ObjCCategoryDecl::protocol_iterator I = Category->protocol_begin(),
E = Category->protocol_end(); I != E; ++I) {
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+ LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+ Visited);
}
}
}
@@ -2089,7 +2095,7 @@
D != DEnd; ++D) {
if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
if (Result.isAcceptableDecl(ND)) {
- Consumer.FoundDecl(ND, Visited.checkHidden(ND));
+ Consumer.FoundDecl(ND, Visited.checkHidden(ND), false);
Visited.add(ND);
}
}
@@ -2112,7 +2118,7 @@
Result.getNameLoc(), Sema::LookupMemberName);
ObjCInterfaceDecl *IFace = Method->getClassInterface();
LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false,
- Consumer, Visited);
+ /*InBaseClass=*/false, Consumer, Visited);
}
// We've already performed all of the name lookup that we need
@@ -2125,7 +2131,7 @@
continue;
LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/false,
- Consumer, Visited);
+ /*InBaseClass=*/false, Consumer, Visited);
}
} else if (!S->getParent()) {
// Look into the translation unit scope. We walk through the translation
@@ -2139,7 +2145,7 @@
// in DeclContexts unless we have to" optimization), we can eliminate this.
Entity = Result.getSema().Context.getTranslationUnitDecl();
LookupVisibleDecls(Entity, Result, /*QualifiedNameLookup=*/false,
- Consumer, Visited);
+ /*InBaseClass=*/false, Consumer, Visited);
}
if (Entity) {
@@ -2149,8 +2155,8 @@
llvm::tie(UI, UEnd) = UDirs.getNamespacesFor(Entity);
for (; UI != UEnd; ++UI)
LookupVisibleDecls(const_cast<DeclContext *>(UI->getNominatedNamespace()),
- Result, /*QualifiedNameLookup=*/false, Consumer,
- Visited);
+ Result, /*QualifiedNameLookup=*/false,
+ /*InBaseClass=*/false, Consumer, Visited);
}
// Lookup names in the parent scope.
@@ -2185,8 +2191,8 @@
LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
VisibleDeclsRecord Visited;
ShadowContextRAII Shadow(Visited);
- ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true, Consumer,
- Visited);
+ ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true,
+ /*InBaseClass=*/false, Consumer, Visited);
}
//----------------------------------------------------------------------------
@@ -2209,7 +2215,7 @@
explicit TypoCorrectionConsumer(IdentifierInfo *Typo)
: Typo(Typo->getName()) { }
- virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding);
+ virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass);
typedef llvm::SmallVector<NamedDecl *, 4>::const_iterator iterator;
iterator begin() const { return BestResults.begin(); }
@@ -2221,7 +2227,8 @@
}
-void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding) {
+void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
+ bool InBaseClass) {
// Don't consider hidden names for typo correction.
if (Hiding)
return;
More information about the cfe-commits
mailing list