Skip to content

Commit d226c8d

Browse files
committed
WIP: [clang] Template Specialization Resugaring - Expressions
This adds some additional users of the resugaring transform, around expressions. This makes function calls work for example. While probably not the largest patch in the series, this could use some further splitting up. Differential Revision: https://reviews.llvm.org/D137200
1 parent abefb0c commit d226c8d

27 files changed

+635
-173
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8756,7 +8756,8 @@ class Sema final : public SemaBase {
87568756

87578757
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
87588758
SourceLocation OpLoc,
8759-
const CXXScopeSpec &SS, FieldDecl *Field,
8759+
const NestedNameSpecifierLoc &NNS,
8760+
FieldDecl *Field, QualType FieldType,
87608761
DeclAccessPair FoundDecl,
87618762
const DeclarationNameInfo &MemberNameInfo);
87628763

@@ -8767,7 +8768,8 @@ class Sema final : public SemaBase {
87678768
const CXXScopeSpec &SS, SourceLocation nameLoc,
87688769
IndirectFieldDecl *indirectField,
87698770
DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_none),
8770-
Expr *baseObjectExpr = nullptr, SourceLocation opLoc = SourceLocation());
8771+
Expr *baseObjectExpr = nullptr, const Type *BaseType = nullptr,
8772+
SourceLocation opLoc = SourceLocation());
87718773

87728774
private:
87738775
void CheckMemberAccessOfNoDeref(const MemberExpr *E);
@@ -13999,6 +14001,16 @@ class Sema final : public SemaBase {
1399914001
FunctionDecl *Spaceship);
1400014002

1400114003
QualType resugar(const NestedNameSpecifier *NNS, QualType T);
14004+
QualType resugar(const NestedNameSpecifier *NNS, NamedDecl *ND,
14005+
ArrayRef<TemplateArgument> Args, QualType T);
14006+
QualType resugar(NamedDecl *ND, ArrayRef<TemplateArgument> Args, QualType T);
14007+
QualType resugar(const Type *Base, const NestedNameSpecifier *FieldNNS,
14008+
QualType T);
14009+
QualType resugar(const Type *Base, const NestedNameSpecifier *FieldNNS,
14010+
NamedDecl *ND, ArrayRef<TemplateArgument> Args, QualType T);
14011+
QualType resugar(const Type *Base, QualType T);
14012+
QualType resugar(const Type *Base, NamedDecl *ND,
14013+
ArrayRef<TemplateArgument> Args, QualType T);
1400214014

1400314015
/// Performs template instantiation for all implicit template
1400414016
/// instantiations we have seen until this point.

clang/lib/Sema/SemaChecking.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,11 @@ struct BuiltinDumpStructGenerator {
649649
if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
650650
continue;
651651

652+
QualType FieldType = FD->getType();
653+
652654
llvm::SmallString<20> Format = llvm::StringRef("%s%s %s ");
653655
llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
654-
getTypeString(FD->getType()),
656+
getTypeString(FieldType),
655657
getStringLiteral(FD->getName())};
656658

657659
if (FD->isBitField()) {
@@ -667,15 +669,16 @@ struct BuiltinDumpStructGenerator {
667669
ExprResult Field =
668670
IFD ? S.BuildAnonymousStructUnionMemberReference(
669671
CXXScopeSpec(), Loc, IFD,
670-
DeclAccessPair::make(IFD, AS_public), RecordArg, Loc)
672+
DeclAccessPair::make(IFD, AS_public), RecordArg, nullptr,
673+
Loc)
671674
: S.BuildFieldReferenceExpr(
672-
RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
673-
DeclAccessPair::make(FD, AS_public),
675+
RecordArg, RecordArgIsPtr, Loc, NestedNameSpecifierLoc(),
676+
FD, FieldType, DeclAccessPair::make(FD, AS_public),
674677
DeclarationNameInfo(FD->getDeclName(), Loc));
675678
if (Field.isInvalid())
676679
return true;
677680

678-
auto *InnerRD = FD->getType()->getAsRecordDecl();
681+
auto *InnerRD = FieldType->getAsRecordDecl();
679682
auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
680683
if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
681684
// Recursively print the values of members of aggregate record type.
@@ -684,7 +687,7 @@ struct BuiltinDumpStructGenerator {
684687
return true;
685688
} else {
686689
Format += " ";
687-
if (appendFormatSpecifier(FD->getType(), Format)) {
690+
if (appendFormatSpecifier(FieldType, Format)) {
688691
// We know how to print this field.
689692
Args.push_back(Field.get());
690693
} else {

clang/lib/Sema/SemaCoroutine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType,
286286
S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false);
287287
if (FromAddr.isInvalid())
288288
return ExprError();
289-
289+
// FIXME: resugar
290290
return S.BuildCallExpr(nullptr, FromAddr.get(), Loc, FramePtr, Loc);
291291
}
292292

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13122,6 +13122,7 @@ bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
1312213122
return true;
1312313123
}
1312413124

13125+
// FIXME: Set TypeSourceInfo?
1312513126
VDecl->setType(DeducedType);
1312613127
assert(VDecl->isLinkageValid());
1312713128

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3640,6 +3640,7 @@ static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
36403640

36413641
// We're currently more strict than GCC about what function types we accept.
36423642
// If this ever proves to be a problem it should be easy to fix.
3643+
// FIXME: resugar
36433644
QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType());
36443645
QualType ParamTy = FD->getParamDecl(0)->getType();
36453646
if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,9 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,
15541554
if (FD->isUnnamedBitField())
15551555
continue;
15561556

1557+
// FIXME: Avoid having to recreate the naming context for every field.
1558+
QualType FieldType = S.resugar(DecompType.getTypePtr(), FD->getType());
1559+
15571560
// We have a real field to bind.
15581561
assert(FlatBindingsItr != FlatBindings.end());
15591562
BindingDecl *B = *(FlatBindingsItr++);
@@ -1568,7 +1571,7 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,
15681571
if (E.isInvalid())
15691572
return true;
15701573
E = S.BuildFieldReferenceExpr(E.get(), /*IsArrow*/ false, Loc,
1571-
CXXScopeSpec(), FD,
1574+
NestedNameSpecifierLoc(), FD, FieldType,
15721575
DeclAccessPair::make(FD, FD->getAccess()),
15731576
DeclarationNameInfo(FD->getDeclName(), Loc));
15741577
if (E.isInvalid())
@@ -1582,7 +1585,7 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,
15821585
Qualifiers Q = DecompType.getQualifiers();
15831586
if (FD->isMutable())
15841587
Q.removeConst();
1585-
B->setBinding(S.BuildQualifiedType(FD->getType(), Loc, Q), E.get());
1588+
B->setBinding(S.BuildQualifiedType(FieldType, Loc, Q), E.get());
15861589
}
15871590

15881591
return false;
@@ -8606,10 +8609,13 @@ class DefaultedComparisonSynthesizer
86068609

86078610
DeclAccessPair Found = DeclAccessPair::make(Field, Field->getAccess());
86088611
DeclarationNameInfo NameInfo(Field->getDeclName(), Loc);
8612+
QualType FieldType = Field->getType();
86098613
return {S.BuildFieldReferenceExpr(Obj.first.get(), /*IsArrow=*/false, Loc,
8610-
CXXScopeSpec(), Field, Found, NameInfo),
8614+
NestedNameSpecifierLoc(), Field,
8615+
FieldType, Found, NameInfo),
86118616
S.BuildFieldReferenceExpr(Obj.second.get(), /*IsArrow=*/false, Loc,
8612-
CXXScopeSpec(), Field, Found, NameInfo)};
8617+
NestedNameSpecifierLoc(), Field,
8618+
FieldType, Found, NameInfo)};
86138619
}
86148620

86158621
// FIXME: When expanding a subobject, register a note in the code synthesis

clang/lib/Sema/SemaExpr.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3224,6 +3224,7 @@ ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
32243224
if (!NeedsADL && R.isSingleResult() &&
32253225
!R.getAsSingle<FunctionTemplateDecl>() &&
32263226
!ShouldLookupResultBeMultiVersionOverload(R))
3227+
// FIXME: get ConvertedArgs
32273228
return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), R.getFoundDecl(),
32283229
R.getRepresentativeDecl(), nullptr, nullptr,
32293230
AcceptInvalidDecl);
@@ -3308,6 +3309,10 @@ ExprResult Sema::BuildDeclarationNameExpr(
33083309
QualType type = VD->getType();
33093310
if (type.isNull())
33103311
return ExprError();
3312+
assert(!TemplateArgs || ConvertedArgs);
3313+
type = ConvertedArgs
3314+
? resugar(SS.getScopeRep(), VD, ConvertedArgs->asArray(), type)
3315+
: resugar(SS.getScopeRep(), type);
33113316
ExprValueKind valueKind = VK_PRValue;
33123317

33133318
// In 'T ...V;', the type of the declaration 'V' is 'T...', but the type of
@@ -19895,10 +19900,30 @@ static void DoMarkVarDeclReferenced(
1989519900

1989619901
// Re-set the member to trigger a recomputation of the dependence bits
1989719902
// for the expression.
19898-
if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E))
19903+
CXXScopeSpec SS;
19904+
if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
1989919905
DRE->setDecl(DRE->getDecl());
19900-
else if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
19906+
SS.Adopt(DRE->getQualifierLoc());
19907+
assert(DRE->template_arguments().size() == 0 ||
19908+
DRE->getConvertedArgs() != nullptr);
19909+
QualType T = DRE->getConvertedArgs()
19910+
? SemaRef.resugar(SS.getScopeRep(), DRE->getDecl(),
19911+
DRE->getConvertedArgs()->asArray(),
19912+
DRE->getType())
19913+
: SemaRef.resugar(SS.getScopeRep(), DRE->getType());
19914+
DRE->setType(T);
19915+
} else if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) {
1990119916
ME->setMemberDecl(ME->getMemberDecl());
19917+
SS.Adopt(ME->getQualifierLoc());
19918+
assert(ME->template_arguments().size() == 0 ||
19919+
ME->getDeduced() != nullptr);
19920+
QualType T =
19921+
ME->getDeduced()
19922+
? SemaRef.resugar(SS.getScopeRep(), ME->getMemberDecl(),
19923+
ME->getDeduced()->asArray(), ME->getType())
19924+
: SemaRef.resugar(SS.getScopeRep(), ME->getType());
19925+
ME->setType(T);
19926+
}
1990219927
} else if (FirstInstantiation) {
1990319928
SemaRef.PendingInstantiations
1990419929
.push_back(std::make_pair(Var, PointOfInstantiation));
@@ -21200,6 +21225,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
2120021225
SS.Adopt(DRE->getQualifierLoc());
2120121226
TemplateArgumentListInfo TemplateArgs;
2120221227
DRE->copyTemplateArgumentsInto(TemplateArgs);
21228+
// FIXME: resugar
2120321229
return BuildDeclRefExpr(
2120421230
FD, FD->getType(), VK_LValue, DRE->getNameInfo(),
2120521231
DRE->hasQualifier() ? &SS : nullptr, DRE->getFoundDecl(),

0 commit comments

Comments
 (0)