r331137 - Fix printing of reference-to-reference types.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 28 22:33:38 PDT 2018
Author: rsmith
Date: Sat Apr 28 22:33:38 2018
New Revision: 331137
URL: http://llvm.org/viewvc/llvm-project?rev=331137&view=rev
Log:
Fix printing of reference-to-reference types.
Previously we would sometimes print these as 'T &&&' or even 'T &&&&'.
Modified:
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/test/SemaCXX/references.cpp
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=331137&r1=331136&r2=331137&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Sat Apr 28 22:33:38 2018
@@ -385,14 +385,23 @@ void TypePrinter::printBlockPointerAfter
printAfter(T->getPointeeType(), OS);
}
+// When printing a reference, the referenced type might also be a reference.
+// If so, we want to skip that before printing the inner type.
+static QualType skipTopLevelReferences(QualType T) {
+ if (auto *Ref = T->getAs<ReferenceType>())
+ return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
+ return T;
+}
+
void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
- printBefore(T->getPointeeTypeAsWritten(), OS);
+ QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
+ printBefore(Inner, OS);
// Handle things like 'int (&A)[4];' correctly.
// FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+ if (isa<ArrayType>(Inner))
OS << '(';
OS << '&';
}
@@ -401,21 +410,23 @@ void TypePrinter::printLValueReferenceAf
raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
+ QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
// Handle things like 'int (&A)[4];' correctly.
// FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+ if (isa<ArrayType>(Inner))
OS << ')';
- printAfter(T->getPointeeTypeAsWritten(), OS);
+ printAfter(Inner, OS);
}
void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
- printBefore(T->getPointeeTypeAsWritten(), OS);
+ QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
+ printBefore(Inner, OS);
// Handle things like 'int (&&A)[4];' correctly.
// FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+ if (isa<ArrayType>(Inner))
OS << '(';
OS << "&&";
}
@@ -424,11 +435,12 @@ void TypePrinter::printRValueReferenceAf
raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
+ QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
// Handle things like 'int (&&A)[4];' correctly.
// FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+ if (isa<ArrayType>(Inner))
OS << ')';
- printAfter(T->getPointeeTypeAsWritten(), OS);
+ printAfter(Inner, OS);
}
void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
Modified: cfe/trunk/test/SemaCXX/references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/references.cpp?rev=331137&r1=331136&r2=331137&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/references.cpp (original)
+++ cfe/trunk/test/SemaCXX/references.cpp Sat Apr 28 22:33:38 2018
@@ -154,3 +154,31 @@ namespace ExplicitRefInit {
struct A { explicit A(int); };
const A &a(0); // expected-error {{reference to type 'const ExplicitRefInit::A' could not bind to an rvalue of type 'int'}}
}
+
+namespace RefCollapseTypePrinting {
+ template<typename T> void add_lref() {
+ using X = int(T); // expected-note 4{{previous}}
+ using X = const volatile T&;
+ // expected-error at -1 {{'int &' vs 'int (int &)'}}
+ // expected-error at -2 {{'int &' vs 'int (int &&)'}}
+ // expected-error at -3 {{'const int &' vs 'int (const int &)'}}
+ // expected-error at -4 {{'const int &' vs 'int (const int &&)'}}
+ }
+ template void add_lref<int&>(); // expected-note {{instantiation of}}
+ template void add_lref<int&&>(); // expected-note {{instantiation of}}
+ template void add_lref<const int&>(); // expected-note {{instantiation of}}
+ template void add_lref<const int&&>(); // expected-note {{instantiation of}}
+
+ template<typename T> void add_rref() {
+ using X = int(T); // expected-note 4{{previous}}
+ using X = const volatile T&&;
+ // expected-error at -1 {{'int &' vs 'int (int &)'}}
+ // expected-error at -2 {{'int &&' vs 'int (int &&)'}}
+ // expected-error at -3 {{'const int &' vs 'int (const int &)'}}
+ // expected-error at -4 {{'const int &&' vs 'int (const int &&)'}}
+ }
+ template void add_rref<int&>(); // expected-note {{instantiation of}}
+ template void add_rref<int&&>(); // expected-note {{instantiation of}}
+ template void add_rref<const int&>(); // expected-note {{instantiation of}}
+ template void add_rref<const int&&>(); // expected-note {{instantiation of}}
+}
More information about the cfe-commits
mailing list