зеркало из https://github.com/microsoft/clang-1.git
When printing a qualified type, look through a substituted template
parameter type to see what's behind it, so that we don't end up printing silly things like "float const *" when "const float *" would make more sense. Also, replace the pile of "isa" tests with a simple switch enumerating all of the cases, making a few more obvious cases use prefix qualifiers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125729 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
6810630bb0
Коммит
c6daf0b29d
|
@ -77,11 +77,61 @@ void TypePrinter::print(const Type *T, Qualifiers Quals, std::string &buffer) {
|
|||
// the type is complex. For example if the type is "int*", we *must* print
|
||||
// "int * const", printing "const int *" is different. Only do this when the
|
||||
// type expands to a simple string.
|
||||
bool CanPrefixQualifiers =
|
||||
isa<BuiltinType>(T) || isa<TypedefType>(T) || isa<TagType>(T) ||
|
||||
isa<ComplexType>(T) || isa<TemplateSpecializationType>(T) ||
|
||||
isa<ObjCObjectType>(T) || isa<ObjCInterfaceType>(T) ||
|
||||
T->isObjCIdType() || T->isObjCQualifiedIdType();
|
||||
bool CanPrefixQualifiers = false;
|
||||
|
||||
Type::TypeClass TC = T->getTypeClass();
|
||||
if (const SubstTemplateTypeParmType *Subst
|
||||
= dyn_cast<SubstTemplateTypeParmType>(T))
|
||||
TC = Subst->getReplacementType()->getTypeClass();
|
||||
|
||||
switch (TC) {
|
||||
case Type::Builtin:
|
||||
case Type::Complex:
|
||||
case Type::UnresolvedUsing:
|
||||
case Type::Typedef:
|
||||
case Type::TypeOfExpr:
|
||||
case Type::TypeOf:
|
||||
case Type::Decltype:
|
||||
case Type::Record:
|
||||
case Type::Enum:
|
||||
case Type::Elaborated:
|
||||
case Type::TemplateTypeParm:
|
||||
case Type::SubstTemplateTypeParmPack:
|
||||
case Type::TemplateSpecialization:
|
||||
case Type::InjectedClassName:
|
||||
case Type::DependentName:
|
||||
case Type::DependentTemplateSpecialization:
|
||||
case Type::ObjCObject:
|
||||
case Type::ObjCInterface:
|
||||
CanPrefixQualifiers = true;
|
||||
break;
|
||||
|
||||
case Type::ObjCObjectPointer:
|
||||
CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
|
||||
T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();
|
||||
break;
|
||||
|
||||
case Type::Pointer:
|
||||
case Type::BlockPointer:
|
||||
case Type::LValueReference:
|
||||
case Type::RValueReference:
|
||||
case Type::MemberPointer:
|
||||
case Type::ConstantArray:
|
||||
case Type::IncompleteArray:
|
||||
case Type::VariableArray:
|
||||
case Type::DependentSizedArray:
|
||||
case Type::DependentSizedExtVector:
|
||||
case Type::Vector:
|
||||
case Type::ExtVector:
|
||||
case Type::FunctionProto:
|
||||
case Type::FunctionNoProto:
|
||||
case Type::Paren:
|
||||
case Type::Attributed:
|
||||
case Type::PackExpansion:
|
||||
case Type::SubstTemplateTypeParm:
|
||||
CanPrefixQualifiers = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CanPrefixQualifiers && !Quals.empty()) {
|
||||
std::string qualsBuffer;
|
||||
|
|
|
@ -63,7 +63,7 @@ struct X0 {
|
|||
|
||||
template<typename T> operator const T*() const {
|
||||
T x = T();
|
||||
return x; // expected-error{{cannot initialize return object of type 'char const *' with an lvalue of type 'char'}}
|
||||
return x; // expected-error{{cannot initialize return object of type 'const char *' with an lvalue of type 'char'}}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ void test_f0() {
|
|||
X<Y&> xy2 = f0(lvalue<Y>());
|
||||
}
|
||||
|
||||
template<typename T> X<T> f1(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'int const &&' for 1st argument}} \
|
||||
// expected-note{{candidate function [with T = Y] not viable: no known conversion from 'Y' to 'Y const &&' for 1st argument}}
|
||||
template<typename T> X<T> f1(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument}} \
|
||||
// expected-note{{candidate function [with T = Y] not viable: no known conversion from 'Y' to 'const Y &&' for 1st argument}}
|
||||
|
||||
void test_f1() {
|
||||
X<int> xi0 = f1(prvalue<int>());
|
||||
|
@ -37,7 +37,7 @@ void test_f1() {
|
|||
|
||||
namespace std_example {
|
||||
template <class T> int f(T&&);
|
||||
template <class T> int g(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'int const &&' for 1st argument}}
|
||||
template <class T> int g(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument}}
|
||||
|
||||
int i;
|
||||
int n1 = f(i);
|
||||
|
|
|
@ -35,7 +35,7 @@ void g() {
|
|||
// CHECK-CC1: CXXConstructor:{TypedText string}{LeftParen (}{Placeholder const char *}{RightParen )} (50)
|
||||
// CHECK-CC1: CXXConstructor:{TypedText string}{LeftParen (}{Placeholder const char *}{Comma , }{Placeholder int n}{RightParen )} (50)
|
||||
// CHECK-CC1: ClassTemplate:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >} (50)
|
||||
// CHECK-CC1: CXXConstructor:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >}{LeftParen (}{Placeholder T const &}{Comma , }{Placeholder unsigned int n}{RightParen )} (50)
|
||||
// CHECK-CC1: CXXConstructor:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >}{LeftParen (}{Placeholder const T &}{Comma , }{Placeholder unsigned int n}{RightParen )} (50)
|
||||
// CHECK-CC1: FunctionTemplate:{ResultType void}{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >}{LeftParen (}{Placeholder InputIterator first}{Comma , }{Placeholder InputIterator last}{RightParen )} (50)
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:19:1 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
|
@ -49,5 +49,5 @@ void g() {
|
|||
// CHECK-CC3: FunctionDecl:{ResultType int}{TypedText foo}{LeftParen (}{RightParen )} (50)
|
||||
// CHECK-CC3: FunctionDecl:{ResultType void}{TypedText g}{LeftParen (}{RightParen )} (50)
|
||||
// CHECK-CC3: ClassTemplate:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >} (50)
|
||||
// CHECK-CC3: CXXConstructor:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >}{LeftParen (}{Placeholder T const &}{Comma , }{Placeholder unsigned int n}{RightParen )} (50)
|
||||
// CHECK-CC3: CXXConstructor:{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >}{LeftParen (}{Placeholder const T &}{Comma , }{Placeholder unsigned int n}{RightParen )} (50)
|
||||
// CHECK-CC3: FunctionTemplate:{ResultType void}{TypedText vector}{LeftAngle <}{Placeholder typename T}{RightAngle >}{LeftParen (}{Placeholder InputIterator first}{Comma , }{Placeholder InputIterator last}{RightParen )} (50)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
struct X0 { };
|
||||
struct X1 { };
|
||||
|
||||
template<typename T>
|
||||
void f0() {
|
||||
const T *t = (const X0*)0; // expected-error{{cannot initialize a variable of type 'const X1 *' with an rvalue of type 'const X0 *'}}
|
||||
}
|
||||
template void f0<X1>(); // expected-note{{instantiation of}}
|
|
@ -107,7 +107,7 @@ namespace PR7463 {
|
|||
}
|
||||
|
||||
namespace test0 {
|
||||
template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'T const' equal 'char'}}
|
||||
template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'const T' equal 'char'}}
|
||||
char *char_maker();
|
||||
void test() {
|
||||
make(char_maker); // expected-error {{no matching function for call to 'make'}}
|
||||
|
|
|
@ -11,7 +11,7 @@ X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>'
|
|||
|
||||
template<typename T>
|
||||
class Y {
|
||||
static const T value = 0; // expected-warning{{in-class initializer for static data member of type 'float const' is a C++0x extension}}
|
||||
static const T value = 0; // expected-warning{{in-class initializer for static data member of type 'const float' is a C++0x extension}}
|
||||
};
|
||||
|
||||
Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}}
|
||||
|
|
Загрузка…
Ссылка в новой задаче