[cfe-commits] r82251 - in /cfe/trunk: include/clang/Parse/Action.h include/clang/Sema/CodeCompleteConsumer.h lib/Parse/ParseDeclCXX.cpp lib/Sema/CodeCompleteConsumer.cpp lib/Sema/Sema.h lib/Sema/SemaCodeComplete.cpp test/CodeCompletion/namespace-alias.cpp test/CodeCompletion/namespace.cpp test/CodeCompletion/using-namespace.cpp test/CodeCompletion/using.cpp
Douglas Gregor
dgregor at apple.com
Fri Sep 18 12:03:05 PDT 2009
Author: dgregor
Date: Fri Sep 18 14:03:04 2009
New Revision: 82251
URL: http://llvm.org/viewvc/llvm-project?rev=82251&view=rev
Log:
Introduce four new code-completion hooks for C++:
- after "using", show anything that can be a nested-name-specifier.
- after "using namespace", show any visible namespaces or namespace aliases
- after "namespace", show any namespace definitions in the current scope
- after "namespace identifier = ", show any visible namespaces or
namespace aliases
Added:
cfe/trunk/test/CodeCompletion/namespace-alias.cpp (with props)
cfe/trunk/test/CodeCompletion/namespace.cpp (with props)
cfe/trunk/test/CodeCompletion/using-namespace.cpp (with props)
cfe/trunk/test/CodeCompletion/using.cpp (with props)
Modified:
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=82251&r1=82250&r2=82251&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Fri Sep 18 14:03:04 2009
@@ -2233,10 +2233,43 @@
///
/// \param SS the scope specifier ending with "::".
///
- /// \parameter EnteringContext whether we're entering the context of this
+ /// \parame EnteringContext whether we're entering the context of this
/// scope specifier.
virtual void CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
bool EnteringContext) { }
+
+ /// \brief Code completion for a C++ "using" declaration or directive.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the "using" keyword.
+ ///
+ /// \param S the scope in which the "using" occurs.
+ virtual void CodeCompleteUsing(Scope *S) { }
+
+ /// \brief Code completion for a C++ using directive.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "using namespace".
+ ///
+ /// \param S the scope in which the "using namespace" occurs.
+ virtual void CodeCompleteUsingDirective(Scope *S) { }
+
+ /// \brief Code completion for a C++ namespace declaration or namespace
+ /// alias declaration.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "namespace".
+ ///
+ /// \param S the scope in which the "namespace" token occurs.
+ virtual void CodeCompleteNamespaceDecl(Scope *S) { }
+
+ /// \brief Code completion for a C++ namespace alias declaration.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "namespace identifier = ".
+ ///
+ /// \param S the scope in which the namespace alias declaration occurs.
+ virtual void CodeCompleteNamespaceAliasDecl(Scope *S) { }
//@}
};
Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=82251&r1=82250&r2=82251&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Fri Sep 18 14:03:04 2009
@@ -187,6 +187,39 @@
/// the qualified-id.
virtual void CodeCompleteQualifiedId(Scope *S, NestedNameSpecifier *NNS,
bool EnteringContext);
+
+ /// \brief Code completion for a C++ "using" declaration or directive.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the "using" keyword.
+ ///
+ /// \param S the scope in which the "using" occurs.
+ virtual void CodeCompleteUsing(Scope *S);
+
+ /// \brief Code completion for a C++ using directive.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "using namespace".
+ ///
+ /// \param S the scope in which the "using namespace" occurs.
+ virtual void CodeCompleteUsingDirective(Scope *S);
+
+ /// \brief Code completion for a C++ namespace declaration or namespace
+ /// alias declaration.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "namespace".
+ ///
+ /// \param S the scope in which the "namespace" token occurs.
+ virtual void CodeCompleteNamespaceDecl(Scope *S);
+
+ /// \brief Code completion for a C++ namespace alias declaration.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after "namespace identifier = ".
+ ///
+ /// \param S the scope in which the namespace alias declaration occurs.
+ virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
//@}
/// \name Name lookup functions
@@ -213,6 +246,8 @@
bool IsEnum(NamedDecl *ND) const;
bool IsClassOrStruct(NamedDecl *ND) const;
bool IsUnion(NamedDecl *ND) const;
+ bool IsNamespace(NamedDecl *ND) const;
+ bool IsNamespaceOrAlias(NamedDecl *ND) const;
//@}
/// \name Utility functions
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=82251&r1=82250&r2=82251&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Sep 18 14:03:04 2009
@@ -47,6 +47,11 @@
assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteNamespaceDecl(CurScope);
+ ConsumeToken();
+ }
+
SourceLocation IdentLoc;
IdentifierInfo *Ident = 0;
@@ -115,6 +120,11 @@
ConsumeToken(); // eat the '='.
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteNamespaceAliasDecl(CurScope);
+ ConsumeToken();
+ }
+
CXXScopeSpec SS;
// Parse (optional) nested-name-specifier.
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
@@ -188,6 +198,11 @@
// Eat 'using'.
SourceLocation UsingLoc = ConsumeToken();
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteUsing(CurScope);
+ ConsumeToken();
+ }
+
if (Tok.is(tok::kw_namespace))
// Next token after 'using' is 'namespace' so it must be using-directive
return ParseUsingDirective(Context, UsingLoc, DeclEnd);
@@ -214,6 +229,11 @@
// Eat 'namespace'.
SourceLocation NamespcLoc = ConsumeToken();
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteUsingDirective(CurScope);
+ ConsumeToken();
+ }
+
CXXScopeSpec SS;
// Parse (optional) nested-name-specifier.
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
Modified: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp?rev=82251&r1=82250&r2=82251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Fri Sep 18 14:03:04 2009
@@ -118,6 +118,63 @@
ProcessCodeCompleteResults(Results.data(), Results.size());
}
+void CodeCompleteConsumer::CodeCompleteUsing(Scope *S) {
+ ResultSet Results(*this, &CodeCompleteConsumer::IsNestedNameSpecifier);
+
+ // If we aren't in class scope, we could see the "namespace" keyword.
+ if (!S->isClassScope())
+ Results.MaybeAddResult(Result("namespace", 0));
+
+ // After "using", we can see anything that would start a
+ // nested-name-specifier.
+ CollectLookupResults(S, 0, Results);
+
+ ProcessCodeCompleteResults(Results.data(), Results.size());
+}
+
+void CodeCompleteConsumer::CodeCompleteUsingDirective(Scope *S) {
+ // After "using namespace", we expect to see a namespace name or namespace
+ // alias.
+ ResultSet Results(*this, &CodeCompleteConsumer::IsNamespaceOrAlias);
+ CollectLookupResults(S, 0, Results);
+ ProcessCodeCompleteResults(Results.data(), Results.size());
+}
+
+void CodeCompleteConsumer::CodeCompleteNamespaceDecl(Scope *S) {
+ ResultSet Results(*this, &CodeCompleteConsumer::IsNamespace);
+ DeclContext *Ctx = (DeclContext *)S->getEntity();
+ if (!S->getParent())
+ Ctx = getSema().Context.getTranslationUnitDecl();
+
+ if (Ctx && Ctx->isFileContext()) {
+ // We only want to see those namespaces that have already been defined
+ // within this scope, because its likely that the user is creating an
+ // extended namespace declaration. Keep track of the most recent
+ // definition of each namespace.
+ std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
+ for (DeclContext::specific_decl_iterator<NamespaceDecl>
+ NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
+ NS != NSEnd; ++NS)
+ OrigToLatest[NS->getOriginalNamespace()] = *NS;
+
+ // Add the most recent definition (or extended definition) of each
+ // namespace to the list of results.
+ for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
+ NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
+ NS != NSEnd; ++NS)
+ Results.MaybeAddResult(Result(NS->second, 0));
+ }
+
+ ProcessCodeCompleteResults(Results.data(), Results.size());
+}
+
+void CodeCompleteConsumer::CodeCompleteNamespaceAliasDecl(Scope *S) {
+ // After "namespace", we expect to see a namespace or alias.
+ ResultSet Results(*this, &CodeCompleteConsumer::IsNamespaceOrAlias);
+ CollectLookupResults(S, 0, Results);
+ ProcessCodeCompleteResults(Results.data(), Results.size());
+}
+
void CodeCompleteConsumer::ResultSet::MaybeAddResult(Result R) {
if (R.Kind != Result::RK_Declaration) {
// For non-declaration results, just add the result.
@@ -454,6 +511,17 @@
return false;
}
+/// \brief Determines whether the given declaration is a namespace.
+bool CodeCompleteConsumer::IsNamespace(NamedDecl *ND) const {
+ return isa<NamespaceDecl>(ND);
+}
+
+/// \brief Determines whether the given declaration is a namespace or
+/// namespace alias.
+bool CodeCompleteConsumer::IsNamespaceOrAlias(NamedDecl *ND) const {
+ return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
+}
+
namespace {
struct VISIBILITY_HIDDEN SortCodeCompleteResult {
typedef CodeCompleteConsumer::Result Result;
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=82251&r1=82250&r2=82251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Sep 18 14:03:04 2009
@@ -3635,11 +3635,13 @@
virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
SourceLocation OpLoc,
bool IsArrow);
-
virtual void CodeCompleteTag(Scope *S, unsigned TagSpec);
-
virtual void CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
bool EnteringContext);
+ virtual void CodeCompleteUsing(Scope *S);
+ virtual void CodeCompleteUsingDirective(Scope *S);
+ virtual void CodeCompleteNamespaceDecl(Scope *S);
+ virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
//@}
//===--------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=82251&r1=82250&r2=82251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Fri Sep 18 14:03:04 2009
@@ -72,3 +72,33 @@
(NestedNameSpecifier *)SS.getScopeRep(),
EnteringContext);
}
+
+void Sema::CodeCompleteUsing(Scope *S) {
+ if (!CodeCompleter)
+ return;
+
+ CodeCompleter->CodeCompleteUsing(S);
+}
+
+void Sema::CodeCompleteUsingDirective(Scope *S) {
+ if (!CodeCompleter)
+ return;
+
+ CodeCompleter->CodeCompleteUsingDirective(S);
+}
+
+void Sema::CodeCompleteNamespaceDecl(Scope *S) {
+ if (!CodeCompleter)
+ return;
+
+ CodeCompleter->CodeCompleteNamespaceDecl(S);
+}
+
+void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
+ if (!CodeCompleter)
+ return;
+
+ CodeCompleter->CodeCompleteNamespaceAliasDecl(S);
+}
+
+
Added: cfe/trunk/test/CodeCompletion/namespace-alias.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/namespace-alias.cpp?rev=82251&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/namespace-alias.cpp (added)
+++ cfe/trunk/test/CodeCompletion/namespace-alias.cpp Fri Sep 18 14:03:04 2009
@@ -0,0 +1,22 @@
+// RUN: clang-cc -fsyntax-only -code-completion-dump=1 %s -o - | FileCheck -check-prefix=CC1 %s &&
+// RUN: true
+
+namespace N4 {
+ namespace N3 { }
+}
+
+class N3;
+
+namespace N2 {
+ namespace I1 { }
+ namespace I4 = I1;
+ namespace I5 { }
+ namespace I1 { }
+
+ // CHECK-CC1: I1 : 1
+ // CHECK-CC1: I4 : 1
+ // CHECK-CC1: I5 : 1
+ // CHECK-CC1: N2 : 2
+ // CHECK-NEXT-CC1: N4 : 2
+ namespace New =
+
Propchange: cfe/trunk/test/CodeCompletion/namespace-alias.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CodeCompletion/namespace-alias.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CodeCompletion/namespace-alias.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cfe/trunk/test/CodeCompletion/namespace.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/namespace.cpp?rev=82251&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/namespace.cpp (added)
+++ cfe/trunk/test/CodeCompletion/namespace.cpp Fri Sep 18 14:03:04 2009
@@ -0,0 +1,15 @@
+// RUN: clang-cc -fsyntax-only -code-completion-dump=1 %s -o - | FileCheck -check-prefix=CC1 %s &&
+// RUN: true
+
+namespace N3 {
+}
+
+namespace N2 {
+ namespace I1 { }
+ namespace I4 = I1;
+ namespace I5 { }
+ namespace I1 { }
+
+ // CHECK-CC1: I1 : 0
+ // CHECK-NEXT-CC1: I5 : 0
+ namespace
Propchange: cfe/trunk/test/CodeCompletion/namespace.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CodeCompletion/namespace.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CodeCompletion/namespace.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cfe/trunk/test/CodeCompletion/using-namespace.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/using-namespace.cpp?rev=82251&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/using-namespace.cpp (added)
+++ cfe/trunk/test/CodeCompletion/using-namespace.cpp Fri Sep 18 14:03:04 2009
@@ -0,0 +1,24 @@
+// RUN: clang-cc -fsyntax-only -code-completion-dump=1 %s -o - | FileCheck -check-prefix=CC1 %s &&
+// RUN: true
+
+namespace N4 {
+ namespace N3 { }
+}
+
+class N3;
+
+namespace N2 {
+ namespace I1 { }
+ namespace I4 = I1;
+ namespace I5 { }
+ namespace I1 { }
+
+ void foo() {
+ // CHECK-CC1: I1 : 2
+ // CHECK-CC1: I4 : 2
+ // CHECK-CC1: I5 : 2
+ // CHECK-CC1: N2 : 3
+ // CHECK-NEXT-CC1: N4 : 3
+ using namespace
+
+
Propchange: cfe/trunk/test/CodeCompletion/using-namespace.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CodeCompletion/using-namespace.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CodeCompletion/using-namespace.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cfe/trunk/test/CodeCompletion/using.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/using.cpp?rev=82251&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/using.cpp (added)
+++ cfe/trunk/test/CodeCompletion/using.cpp Fri Sep 18 14:03:04 2009
@@ -0,0 +1,27 @@
+// RUN: clang-cc -fsyntax-only -code-completion-dump=1 %s -o - | FileCheck -check-prefix=CC1 %s &&
+// RUN: true
+
+namespace N4 {
+ namespace N3 { }
+}
+
+class N3;
+
+namespace N2 {
+ namespace I1 { }
+ namespace I4 = I1;
+ namespace I5 { }
+ namespace I1 { }
+
+ void foo() {
+ int N3;
+
+ // CHECK-CC1: I1 : 2
+ // CHECK-CC1: I4 : 2
+ // CHECK-CC1: I5 : 2
+ // CHECK-CC1: N2 : 3
+ // CHECK-CC1: N3 : 3
+ // CHECK-NEXT-CC1: N4 : 3
+ using
+
+
Propchange: cfe/trunk/test/CodeCompletion/using.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CodeCompletion/using.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CodeCompletion/using.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list