forked from OSchip/llvm-project
Avoid printing some redundant name qualifiers in completion
Summary: Adjusted PrintingPolicy inside code completion to avoid printing some redundant name qualifiers. Before this change, typedefs that were written unqualified in source code were printed with qualifiers in completion. For example, in the following code struct foo { typedef int type; type method(); }; completion item for `method` had return type of `foo::type`, even though the original code used `type` without qualifiers. After this change, the completion item has return type `type`, as originally written in the source code. Note that this change does not suppress qualifiers written by the user. For example, in the following code typedef int type; struct foo { typedef int type; ::type method(foo::type); }; completion item for `method` has return type of `::type` and parameter type of `foo::type`, as originally written in the source code. Reviewers: arphaman, bkramer, klimek Reviewed By: arphaman Subscribers: mgorny, eraman, cfe-commits Differential Revision: https://reviews.llvm.org/D38538 llvm-svn: 317677
This commit is contained in:
parent
cc3cf58cd2
commit
b5da91c875
|
@ -14,6 +14,7 @@
|
|||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/ExprObjC.h"
|
||||
#include "clang/AST/QualTypeNames.h"
|
||||
#include "clang/Basic/CharInfo.h"
|
||||
#include "clang/Lex/HeaderSearch.h"
|
||||
#include "clang/Lex/MacroInfo.h"
|
||||
|
@ -1495,6 +1496,7 @@ static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
|
|||
Policy.AnonymousTagLocations = false;
|
||||
Policy.SuppressStrongLifetime = true;
|
||||
Policy.SuppressUnwrittenScope = true;
|
||||
Policy.SuppressScope = true;
|
||||
return Policy;
|
||||
}
|
||||
|
||||
|
@ -2139,9 +2141,10 @@ static void AddResultTypeChunk(ASTContext &Context,
|
|||
T = Method->getSendResultType(BaseType);
|
||||
else
|
||||
T = Method->getReturnType();
|
||||
} else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
|
||||
} else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) {
|
||||
T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
|
||||
else if (isa<UnresolvedUsingValueDecl>(ND)) {
|
||||
T = clang::TypeName::getFullyQualifiedType(T, Context);
|
||||
} else if (isa<UnresolvedUsingValueDecl>(ND)) {
|
||||
/* Do nothing: ignore unresolved using declarations*/
|
||||
} else if (const ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(ND)) {
|
||||
if (!BaseType.isNull())
|
||||
|
|
|
@ -19,10 +19,10 @@ void test() {
|
|||
f(Y(), 0, 0);
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: COMPLETION: Pattern : dynamic_cast<<#type#>>(<#expression#>)
|
||||
// CHECK-CC1: f(N::Y y, <#int ZZ#>)
|
||||
// CHECK-CC1: f(Y y, <#int ZZ#>)
|
||||
// CHECK-CC1-NEXT: f(int i, <#int j#>, int k)
|
||||
// CHECK-CC1-NEXT: f(float x, <#float y#>)
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:13 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2-NOT: f(N::Y y, int ZZ)
|
||||
// CHECK-CC2-NOT: f(Y y, int ZZ)
|
||||
// CHECK-CC2: f(int i, int j, <#int k#>)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
struct foo {
|
||||
typedef int type;
|
||||
|
||||
type method(type, foo::type, ::foo::type, ::foo::foo::type);
|
||||
};
|
||||
|
||||
namespace ns {
|
||||
struct bar {
|
||||
};
|
||||
|
||||
struct baz {
|
||||
};
|
||||
|
||||
int func(foo::type a, bar b, baz c);
|
||||
}
|
||||
|
||||
typedef ns::bar bar;
|
||||
|
||||
int func(foo a, bar b, ns::bar c, ns::baz d);
|
||||
using ns::func;
|
||||
|
||||
void test() {
|
||||
foo().method(0, 0, 0, 0);
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:9 %s -o - | FileCheck %s --check-prefix=CHECK-1
|
||||
// CHECK-1: COMPLETION: method : [#type#]method(<#type#>, <#foo::type#>, <#::foo::type#>, <#::foo::foo::type#>)
|
||||
f
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:26:3 %s -o - | FileCheck %s --check-prefix=CHECK-2
|
||||
// CHECK-2: COMPLETION: func : [#int#]func(<#foo a#>, <#bar b#>, <#ns::bar c#>, <#ns::baz d#>
|
||||
// CHECK-2: COMPLETION: func : [#int#]func(<#foo::type a#>, <#bar b#>, <#baz c#>
|
||||
}
|
|
@ -9,5 +9,5 @@ void test() {
|
|||
unique_ptr<int> x;
|
||||
x.
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:5 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: [#void#]reset({#<#unique_ptr<int>::pointer ptr = pointer()#>#})
|
||||
// CHECK-CC1: [#void#]reset({#<#pointer ptr = pointer()#>#})
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ private:
|
|||
|
||||
// RUN: c-index-test -code-completion-at=%s:4:9 -std=c++98 %s | FileCheck %s
|
||||
// RUN: c-index-test -code-completion-at=%s:13:7 -std=c++98 %s | FileCheck %s
|
||||
// CHECK: CXXMethod:{ResultType MyCls::Vec &}{TypedText operator=}{LeftParen (}{Placeholder const MyCls::Vec &}{RightParen )} (79)
|
||||
// CHECK: CXXMethod:{ResultType Vec &}{TypedText operator=}{LeftParen (}{Placeholder const Vec &}{RightParen )} (79)
|
||||
// CHECK-NEXT: StructDecl:{TypedText Vec}{Text ::} (75)
|
||||
// CHECK-NEXT: FieldDecl:{ResultType int}{TypedText x} (35)
|
||||
// CHECK-NEXT: FieldDecl:{ResultType int}{TypedText y} (35)
|
||||
|
|
Loading…
Reference in New Issue