[cfe-commits] r82231 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/Sema/CodeCompleteConsumer.h lib/Sema/CodeCompleteConsumer.cpp test/CodeCompletion/tag.cpp
Douglas Gregor
dgregor at apple.com
Fri Sep 18 10:42:30 PDT 2009
Author: dgregor
Date: Fri Sep 18 12:42:29 2009
New Revision: 82231
URL: http://llvm.org/viewvc/llvm-project?rev=82231&view=rev
Log:
For code completion in C++ member access expressions and tag names,
look into the current scope for anything that could start a
nested-names-specifier. These results are ranked worse than any of the
results actually found in the lexical scope.
Perform a little more pruning of the result set, eliminating
constructors, __va_list_tag, and any duplication of declarations in
the result set. For the latter, implemented
NamespaceDecl::getCanonicalDecl.
Added:
cfe/trunk/test/CodeCompletion/tag.cpp (with props)
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=82231&r1=82230&r2=82231&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Sep 18 12:42:29 2009
@@ -201,6 +201,8 @@
}
void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
+ virtual NamespaceDecl *getCanonicalDecl() { return OrigNamespace; }
+
virtual SourceRange getSourceRange() const {
return SourceRange(getLocation(), RBracLoc);
}
Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=82231&r1=82230&r2=82231&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Fri Sep 18 12:42:29 2009
@@ -15,6 +15,7 @@
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include <list>
#include <map>
#include <vector>
@@ -25,6 +26,7 @@
namespace clang {
+class Decl;
class DeclContext;
class NamedDecl;
class Scope;
@@ -89,6 +91,11 @@
/// \brief The actual results we have found.
std::vector<Result> Results;
+ /// \brief A record of all of the declarations we have found and placed
+ /// into the result set, used to ensure that no declaration ever gets into
+ /// the result set twice.
+ llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
+
/// \brief A mapping from declaration names to the declarations that have
/// this name within a particular scope and their index within the list of
/// results.
Modified: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp?rev=82231&r1=82230&r2=82231&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Fri Sep 18 12:42:29 2009
@@ -53,8 +53,10 @@
// The "template" keyword can follow "->" or "." in the grammar.
Results.MaybeAddResult(Result("template", NextRank++));
- // FIXME: For C++, we also need to look into the current scope, since
- // we could have the start of a nested-name-specifier.
+ // We could have the start of a nested-name-specifier. Add those
+ // results as well.
+ Results.setFilter(&CodeCompleteConsumer::IsNestedNameSpecifier);
+ CollectLookupResults(S, NextRank, Results);
}
// Hand off the results found for code completion.
@@ -83,10 +85,14 @@
}
ResultSet Results(*this, Filter);
- CollectLookupResults(S, 0, Results);
+ unsigned NextRank = CollectLookupResults(S, 0, Results);
- // FIXME: In C++, we could have the start of a nested-name-specifier.
- // Add those results (with a poorer rank, naturally).
+ if (getSema().getLangOptions().CPlusPlus) {
+ // We could have the start of a nested-name-specifier. Add those
+ // results as well.
+ Results.setFilter(&CodeCompleteConsumer::IsNestedNameSpecifier);
+ CollectLookupResults(S, NextRank, Results);
+ }
ProcessCodeCompleteResults(Results.data(), Results.size());
}
@@ -121,10 +127,6 @@
// FIXME: Using declarations
// FIXME: Separate overload sets
- // Filter out any unwanted results.
- if (Filter && !(Completer.*Filter)(R.Declaration))
- return;
-
Decl *CanonDecl = R.Declaration->getCanonicalDecl();
unsigned IDNS = CanonDecl->getIdentifierNamespace();
@@ -134,6 +136,23 @@
(IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
return;
+ if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
+ // __va_list_tag is a freak of nature. Find it and skip it.
+ if (Id->isStr("__va_list_tag"))
+ return;
+
+ // FIXME: Should we filter out other names in the implementation's
+ // namespace, e.g., those containing a __ or that start with _[A-Z]?
+ }
+
+ // C++ constructors are never found by name lookup.
+ if (isa<CXXConstructorDecl>(CanonDecl))
+ return;
+
+ // Filter out any unwanted results.
+ if (Filter && !(Completer.*Filter)(R.Declaration))
+ return;
+
ShadowMap &SMap = ShadowMaps.back();
ShadowMap::iterator I, IEnd;
for (llvm::tie(I, IEnd) = SMap.equal_range(R.Declaration->getDeclName());
@@ -187,6 +206,10 @@
}
}
+ // Make sure that any given declaration only shows up in the result set once.
+ if (!AllDeclsFound.insert(CanonDecl))
+ return;
+
// Insert this result into the set of results and into the current shadow
// map.
SMap.insert(std::make_pair(R.Declaration->getDeclName(),
Added: cfe/trunk/test/CodeCompletion/tag.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/tag.cpp?rev=82231&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/tag.cpp (added)
+++ cfe/trunk/test/CodeCompletion/tag.cpp Fri Sep 18 12:42:29 2009
@@ -0,0 +1,20 @@
+// RUN: clang-cc -fsyntax-only -code-completion-dump=1 %s -o - | FileCheck -check-prefix=CC1 %s &&
+// RUN: true
+
+class X { };
+struct Y { };
+
+namespace N {
+ template<typename> class Z;
+}
+
+namespace N {
+ class Y;
+
+ void test() {
+ // CHECK-CC1: Y : 2
+ // CHECK-CC1: Z : 2
+ // CHECK-CC1: X : 3
+ // CHECK-CC1: Y : 3
+ // CHECK-CC1: N : 6
+ class
Propchange: cfe/trunk/test/CodeCompletion/tag.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CodeCompletion/tag.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CodeCompletion/tag.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list