Index: include/clang/AST/QualTypeNames.h =================================================================== --- include/clang/AST/QualTypeNames.h +++ include/clang/AST/QualTypeNames.h @@ -56,8 +56,8 @@ // // ===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H -#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H +#ifndef LLVM_CLANG_AST_QUALTYPENAMES_H +#define LLVM_CLANG_AST_QUALTYPENAMES_H #include "clang/AST/ASTContext.h" @@ -71,9 +71,20 @@ /// \param[in] Ctx - the ASTContext to be used. /// \param[in] WithGlobalNsPrefix - If true, then the global namespace /// specifier "::" will be prepended to the fully qualified name. -std::string getFullyQualifiedName(QualType QT, - const ASTContext &Ctx, +std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx, bool WithGlobalNsPrefix = false); -} // end namespace TypeName -} // end namespace clang -#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H + +/// \brief Generates a QualType that can be used to name the same type +/// if used at the end of the current translation unit. This ignores +/// issues such as type shadowing. +/// +/// \param[in] QT - the type for which the fully qualified type will be +/// returned. +/// \param[in] Ctx - the ASTContext to be used. +/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace +/// specifier "::" should be prepended or not. +QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx, + bool WithGlobalNsPrefix = false); +} // end namespace TypeName +} // end namespace clang +#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H Index: lib/AST/CMakeLists.txt =================================================================== --- lib/AST/CMakeLists.txt +++ lib/AST/CMakeLists.txt @@ -49,6 +49,7 @@ ODRHash.cpp OpenMPClause.cpp ParentMap.cpp + QualTypeNames.cpp RawCommentList.cpp RecordLayout.cpp RecordLayoutBuilder.cpp Index: lib/AST/QualTypeNames.cpp =================================================================== --- lib/AST/QualTypeNames.cpp +++ lib/AST/QualTypeNames.cpp @@ -9,11 +9,11 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/Core/QualTypeNames.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/GlobalDecl.h" #include "clang/AST/Mangle.h" +#include "clang/AST/QualTypeNames.h" #include #include @@ -21,17 +21,6 @@ namespace clang { namespace TypeName { -/// \brief Generates a QualType that can be used to name the same type -/// if used at the end of the current translation unit. This ignores -/// issues such as type shadowing. -/// -/// \param[in] QT - the type for which the fully qualified type will be -/// returned. -/// \param[in] Ctx - the ASTContext to be used. -/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace -/// specifier "::" should be prepended or not. -static QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx, - bool WithGlobalNsPrefix); /// \brief Create a NestedNameSpecifier for Namesp and its enclosing /// scopes. Index: lib/Sema/SemaCodeComplete.cpp =================================================================== --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -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 @@ Policy.AnonymousTagLocations = false; Policy.SuppressStrongLifetime = true; Policy.SuppressUnwrittenScope = true; + Policy.SuppressScope = true; return Policy; } @@ -2137,9 +2139,10 @@ T = Method->getSendResultType(BaseType); else T = Method->getReturnType(); - } else if (const EnumConstantDecl *Enumerator = dyn_cast(ND)) + } else if (const EnumConstantDecl *Enumerator = dyn_cast(ND)) { T = Context.getTypeDeclType(cast(Enumerator->getDeclContext())); - else if (isa(ND)) { + T = clang::TypeName::getFullyQualifiedType(T, Context); + } else if (isa(ND)) { /* Do nothing: ignore unresolved using declarations*/ } else if (const ObjCIvarDecl *Ivar = dyn_cast(ND)) { if (!BaseType.isNull()) Index: lib/Tooling/Core/CMakeLists.txt =================================================================== --- lib/Tooling/Core/CMakeLists.txt +++ lib/Tooling/Core/CMakeLists.txt @@ -3,7 +3,6 @@ add_clang_library(clangToolingCore Lookup.cpp Replacement.cpp - QualTypeNames.cpp Diagnostic.cpp LINK_LIBS Index: test/CodeCompletion/call.cpp =================================================================== --- test/CodeCompletion/call.cpp +++ test/CodeCompletion/call.cpp @@ -19,10 +19,10 @@ 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#>) } Index: test/CodeCompletion/qualifiers-as-written.cpp =================================================================== --- /dev/null +++ test/CodeCompletion/qualifiers-as-written.cpp @@ -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#> +} Index: test/CodeCompletion/uninstantiated_params.cpp =================================================================== --- test/CodeCompletion/uninstantiated_params.cpp +++ test/CodeCompletion/uninstantiated_params.cpp @@ -9,5 +9,5 @@ unique_ptr 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::pointer ptr = pointer()#>#}) + // CHECK-CC1: [#void#]reset({#<#pointer ptr = pointer()#>#}) } Index: test/Index/complete-cxx-inline-methods.cpp =================================================================== --- test/Index/complete-cxx-inline-methods.cpp +++ test/Index/complete-cxx-inline-methods.cpp @@ -25,7 +25,7 @@ // 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) Index: unittests/Tooling/QualTypeNamesTest.cpp =================================================================== --- unittests/Tooling/QualTypeNamesTest.cpp +++ unittests/Tooling/QualTypeNamesTest.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/Core/QualTypeNames.h" +#include "clang/AST/QualTypeNames.h" #include "TestVisitor.h" using namespace clang;