forked from OSchip/llvm-project
When forming a fully-qualified type name, put any qualifiers outside/before the
nested-name-specifier. Patch by Sterling Augustine! llvm-svn: 268988
This commit is contained in:
parent
0a77dfad95
commit
57443fce3f
|
@ -383,10 +383,15 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx) {
|
|||
}
|
||||
|
||||
NestedNameSpecifier *Prefix = nullptr;
|
||||
Qualifiers PrefixQualifiers;
|
||||
// Local qualifiers are attached to the QualType outside of the
|
||||
// elaborated type. Retrieve them before descending into the
|
||||
// elaborated type.
|
||||
Qualifiers PrefixQualifiers = QT.getLocalQualifiers();
|
||||
QT = QualType(QT.getTypePtr(), 0);
|
||||
ElaboratedTypeKeyword Keyword = ETK_None;
|
||||
if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
|
||||
QT = ETypeInput->getNamedType();
|
||||
assert(!QT.hasLocalQualifiers());
|
||||
Keyword = ETypeInput->getKeyword();
|
||||
}
|
||||
// Create a nested name specifier if needed (i.e. if the decl context
|
||||
|
@ -394,28 +399,21 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx) {
|
|||
Prefix = createNestedNameSpecifierForScopeOf(Ctx, QT.getTypePtr(),
|
||||
true /*FullyQualified*/);
|
||||
|
||||
// move the qualifiers on the outer type (avoid 'std::const string'!)
|
||||
if (Prefix) {
|
||||
PrefixQualifiers = QT.getLocalQualifiers();
|
||||
QT = QualType(QT.getTypePtr(), 0);
|
||||
}
|
||||
|
||||
// In case of template specializations iterate over the arguments and
|
||||
// fully qualify them as well.
|
||||
if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
|
||||
isa<const RecordType>(QT.getTypePtr())) {
|
||||
// We are asked to fully qualify and we have a Record Type (which
|
||||
// may pont to a template specialization) or Template
|
||||
// may point to a template specialization) or Template
|
||||
// Specialization Type. We need to fully qualify their arguments.
|
||||
|
||||
Qualifiers Quals = QT.getLocalQualifiers();
|
||||
const Type *TypePtr = getFullyQualifiedTemplateType(Ctx, QT.getTypePtr());
|
||||
QT = Ctx.getQualifiedType(TypePtr, Quals);
|
||||
QT = QualType(TypePtr, 0);
|
||||
}
|
||||
if (Prefix || Keyword != ETK_None) {
|
||||
QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
|
||||
QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
|
||||
}
|
||||
QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
|
||||
return QT;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ TEST(QualTypeNameTest, getFullyQualifiedName) {
|
|||
"Foo<X>::non_dependent_type";
|
||||
Visitor.ExpectedQualTypeNames["AnEnumVar"] = "EnumScopeClass::AnEnum";
|
||||
Visitor.ExpectedQualTypeNames["AliasTypeVal"] = "A::B::C::InnerAlias<int>";
|
||||
Visitor.ExpectedQualTypeNames["CheckM"] = "const A::B::Class0 *";
|
||||
Visitor.ExpectedQualTypeNames["CheckN"] = "const X *";
|
||||
Visitor.runOver(
|
||||
"int CheckInt;\n"
|
||||
"template <typename T>\n"
|
||||
|
@ -108,6 +110,7 @@ TEST(QualTypeNameTest, getFullyQualifiedName) {
|
|||
" AnotherClass> CheckC);\n"
|
||||
" void Function2(Template0<Template1<C::MyInt, AnotherClass>,\n"
|
||||
" Template0<int, long> > CheckD);\n"
|
||||
" void Function3(const B::Class0* CheckM);\n"
|
||||
" }\n"
|
||||
"template<typename... Values> class Variadic {};\n"
|
||||
"Variadic<int, B::Template0<int, char>, "
|
||||
|
@ -123,6 +126,8 @@ TEST(QualTypeNameTest, getFullyQualifiedName) {
|
|||
"void f() {\n"
|
||||
" struct X {} CheckH;\n"
|
||||
"}\n"
|
||||
"struct X;\n"
|
||||
"void f(const ::X* CheckN) {}\n"
|
||||
"namespace {\n"
|
||||
" class aClass {};\n"
|
||||
" aClass CheckI;\n"
|
||||
|
|
Loading…
Reference in New Issue