Skip to content

Commit e510a76

Browse files
committed
[clang] Distinguish unresolved templates in UnresolvedLookupExpr
1 parent f71e25b commit e510a76

File tree

13 files changed

+120
-6
lines changed

13 files changed

+120
-6
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
11161116
CanQualType BFloat16Ty;
11171117
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
11181118
CanQualType VoidPtrTy, NullPtrTy;
1119-
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
1119+
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy,
1120+
UnknownAnyTy;
11201121
CanQualType BuiltinFnTy;
11211122
CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
11221123
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;

clang/include/clang/AST/BuiltinTypes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ PLACEHOLDER_TYPE(Overload, OverloadTy)
285285
// x->foo # if only contains non-static members
286286
PLACEHOLDER_TYPE(BoundMember, BoundMemberTy)
287287

288+
PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy)
289+
288290
// The type of an expression which refers to a pseudo-object,
289291
// such as those introduced by Objective C's @property or
290292
// VS.NET's __property declarations. A placeholder type. The

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,8 @@ enum PredefinedTypeIDs {
10991099
// \brief WebAssembly reference types with auto numeration
11001100
#define WASM_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
11011101
#include "clang/Basic/WebAssemblyReferenceTypes.def"
1102+
1103+
PREDEF_TYPE_UNRESOLVED_TEMPLATE,
11021104
// Sentinel value. Considered a predefined type but not useable as one.
11031105
PREDEF_TYPE_LAST_ID
11041106
};
@@ -1108,7 +1110,7 @@ enum PredefinedTypeIDs {
11081110
///
11091111
/// Type IDs for non-predefined types will start at
11101112
/// NUM_PREDEF_TYPE_IDs.
1111-
const unsigned NUM_PREDEF_TYPE_IDS = 502;
1113+
const unsigned NUM_PREDEF_TYPE_IDS = 503;
11121114

11131115
// Ensure we do not overrun the predefined types we reserved
11141116
// in the enum PredefinedTypeIDs above.

clang/lib/AST/ASTContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
13061306
// Placeholder type for bound members.
13071307
InitBuiltinType(BoundMemberTy, BuiltinType::BoundMember);
13081308

1309+
// Placeholder type for unresolved templates.
1310+
InitBuiltinType(UnresolvedTemplateTy, BuiltinType::UnresolvedTemplate);
1311+
13091312
// Placeholder type for pseudo-objects.
13101313
InitBuiltinType(PseudoObjectTy, BuiltinType::PseudoObject);
13111314

clang/lib/AST/NSAPI.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
454454
#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
455455
#include "clang/Basic/WebAssemblyReferenceTypes.def"
456456
case BuiltinType::BoundMember:
457+
case BuiltinType::UnresolvedTemplate:
457458
case BuiltinType::Dependent:
458459
case BuiltinType::Overload:
459460
case BuiltinType::UnknownAny:

clang/lib/AST/Type.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3381,6 +3381,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
33813381
return "<overloaded function type>";
33823382
case BoundMember:
33833383
return "<bound member function type>";
3384+
case UnresolvedTemplate:
3385+
return "<unresolved template type>";
33843386
case PseudoObject:
33853387
return "<pseudo-object type>";
33863388
case Dependent:
@@ -4673,6 +4675,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
46734675
#include "clang/AST/BuiltinTypes.def"
46744676
return false;
46754677

4678+
case BuiltinType::UnresolvedTemplate:
46764679
// Dependent types that could instantiate to a pointer type.
46774680
case BuiltinType::Dependent:
46784681
case BuiltinType::Overload:

clang/lib/AST/TypeLoc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
399399
case BuiltinType::NullPtr:
400400
case BuiltinType::Overload:
401401
case BuiltinType::Dependent:
402+
case BuiltinType::UnresolvedTemplate:
402403
case BuiltinType::BoundMember:
403404
case BuiltinType::UnknownAny:
404405
case BuiltinType::ARCUnbridgedCast:

clang/lib/Sema/SemaExpr.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6349,6 +6349,7 @@ static bool isPlaceholderToRemoveAsArg(QualType type) {
63496349
#include "clang/AST/BuiltinTypes.def"
63506350
return false;
63516351

6352+
case BuiltinType::UnresolvedTemplate:
63526353
// We cannot lower out overload sets; they might validly be resolved
63536354
// by the call machinery.
63546355
case BuiltinType::Overload:
@@ -21234,6 +21235,24 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
2123421235
if (!placeholderType) return E;
2123521236

2123621237
switch (placeholderType->getKind()) {
21238+
case BuiltinType::UnresolvedTemplate: {
21239+
auto *ULE = cast<UnresolvedLookupExpr>(E);
21240+
const DeclarationNameInfo &NameInfo = ULE->getNameInfo();
21241+
NestedNameSpecifierLoc Loc = ULE->getQualifierLoc();
21242+
NamedDecl *Temp = *ULE->decls_begin();
21243+
bool IsTypeAliasTemplateDecl = isa<TypeAliasTemplateDecl>(Temp);
21244+
if (NestedNameSpecifier *NNS = Loc.getNestedNameSpecifier())
21245+
Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_type_template)
21246+
<< NNS << NameInfo.getName().getAsString() << Loc.getSourceRange()
21247+
<< IsTypeAliasTemplateDecl;
21248+
else
21249+
Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_type_template)
21250+
<< "" << NameInfo.getName().getAsString() << Loc.getSourceRange()
21251+
<< IsTypeAliasTemplateDecl;
21252+
Diag(Temp->getLocation(), diag::note_referenced_type_template)
21253+
<< IsTypeAliasTemplateDecl;
21254+
return CreateRecoveryExpr(NameInfo.getBeginLoc(), NameInfo.getEndLoc(), {});
21255+
}
2123721256

2123821257
// Overloaded expressions.
2123921258
case BuiltinType::Overload: {

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5553,7 +5553,7 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
55535553
R.getRepresentativeDecl(), TemplateKWLoc, TemplateArgs);
55545554
if (Res.isInvalid() || Res.isUsable())
55555555
return Res;
5556-
// Result is dependent. Carry on to build an UnresolvedLookupEpxr.
5556+
// Result is dependent. Carry on to build an UnresolvedLookupExpr.
55575557
KnownDependent = true;
55585558
}
55595559

@@ -5571,6 +5571,10 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
55715571
TemplateKWLoc, R.getLookupNameInfo(), RequiresADL, TemplateArgs,
55725572
R.begin(), R.end(), KnownDependent);
55735573

5574+
if (ULE->getType() == Context.OverloadTy && R.isSingleResult() &&
5575+
!R.getFoundDecl()->getAsFunction())
5576+
ULE->setType(Context.UnresolvedTemplateTy);
5577+
55745578
return ULE;
55755579
}
55765580

@@ -5609,8 +5613,9 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
56095613
Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_type_template)
56105614
<< SS.getScopeRep() << NameInfo.getName().getAsString() << SS.getRange()
56115615
<< isTypeAliasTemplateDecl;
5612-
Diag(Temp->getLocation(), diag::note_referenced_type_template) << 0;
5613-
return ExprError();
5616+
Diag(Temp->getLocation(), diag::note_referenced_type_template)
5617+
<< isTypeAliasTemplateDecl;
5618+
return CreateRecoveryExpr(NameInfo.getBeginLoc(), NameInfo.getEndLoc(), {});
56145619
};
56155620

56165621
if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>())

clang/lib/Serialization/ASTCommon.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
186186
case BuiltinType::Overload:
187187
ID = PREDEF_TYPE_OVERLOAD_ID;
188188
break;
189+
case BuiltinType::UnresolvedTemplate:
190+
ID = PREDEF_TYPE_UNRESOLVED_TEMPLATE;
191+
break;
189192
case BuiltinType::BoundMember:
190193
ID = PREDEF_TYPE_BOUND_MEMBER;
191194
break;

clang/lib/Serialization/ASTReader.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7311,6 +7311,9 @@ QualType ASTReader::GetType(TypeID ID) {
73117311
case PREDEF_TYPE_OVERLOAD_ID:
73127312
T = Context.OverloadTy;
73137313
break;
7314+
case PREDEF_TYPE_UNRESOLVED_TEMPLATE:
7315+
T = Context.UnresolvedTemplateTy;
7316+
break;
73147317
case PREDEF_TYPE_BOUND_MEMBER:
73157318
T = Context.BoundMemberTy;
73167319
break;

clang/test/SemaCXX/PR62533.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
template<typename T>
44
struct test {
5-
template<typename> using fun_diff = char; // expected-note 2{{class template declared here}}
5+
template<typename> using fun_diff = char; // expected-note 2{{type alias template declared here}}
66
};
77

88
template<typename T, typename V>

clang/test/SemaTemplate/template-id-expr.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,74 @@ class E {
186186
#endif
187187
template<typename T> using D = int; // expected-note {{declared here}}
188188
E<D> ed; // expected-note {{instantiation of}}
189+
190+
namespace non_functions {
191+
192+
#if __cplusplus >= 201103L
193+
namespace PR88832 {
194+
template <typename T> struct O {
195+
static const T v = 0;
196+
};
197+
198+
struct P {
199+
template <typename T> using I = typename O<T>::v; // #TypeAlias
200+
};
201+
202+
struct Q {
203+
template <typename T> int foo() {
204+
return T::template I<int>; // expected-error {{'P::I' is expected to be a non-type template, but instantiated to a type alias template}}
205+
// expected-note@#TypeAlias {{type alias template declared here}}
206+
}
207+
};
208+
209+
int bar() {
210+
return Q().foo<P>(); // expected-note-re {{function template specialization {{.*}} requested here}}
211+
}
212+
213+
} // namespace PR88832
214+
#endif
215+
216+
namespace PR63243 {
217+
218+
namespace std {
219+
template <class T> struct add_pointer { // #add_pointer
220+
};
221+
} // namespace std
222+
223+
class A {};
224+
225+
int main() {
226+
std::__add_pointer<A>::type ptr; // #ill-formed-decl
227+
// expected-error@#ill-formed-decl {{no template named '__add_pointer'}}
228+
// expected-note@#add_pointer {{'add_pointer' declared here}}
229+
// expected-error@#ill-formed-decl {{expected ';' after expression}}
230+
// expected-error@#ill-formed-decl {{no type named 'type' in the global namespace}}
231+
// expected-error@#ill-formed-decl {{'std::add_pointer' is expected to be a non-type template, but instantiated to a class template}}
232+
// expected-note@#add_pointer {{class template declared here}}
233+
234+
// expected-warning@#ill-formed-decl {{keyword '__add_pointer' will be made available as an identifier here}}
235+
}
236+
237+
} // namespace PR63243
238+
239+
namespace PR48673 {
240+
241+
template <typename T> struct C {
242+
template <int TT> class Type {}; // #ClassTemplate
243+
};
244+
245+
template <typename T1> struct A {
246+
void foo() {
247+
C<T1>::template Type<2>; // #templated-decl-as-expression
248+
// expected-error@#templated-decl-as-expression {{'C<float>::Type' is expected to be a non-type template, but instantiated to a class template}}}
249+
// expected-note@#ClassTemplate {{class template declared here}}
250+
}
251+
};
252+
253+
void test() {
254+
A<float>().foo(); // expected-note-re {{instantiation of member function {{.*}} requested here}}
255+
}
256+
257+
} // namespace PR48673
258+
259+
}

0 commit comments

Comments
 (0)