16
16
#include " clang/AST/ExprCXX.h"
17
17
#include " clang/AST/ExprObjC.h"
18
18
#include " clang/AST/QualTypeNames.h"
19
+ #include " clang/AST/Type.h"
19
20
#include " clang/Basic/CharInfo.h"
21
+ #include " clang/Basic/Specifiers.h"
20
22
#include " clang/Lex/HeaderSearch.h"
21
23
#include " clang/Lex/MacroInfo.h"
22
24
#include " clang/Lex/Preprocessor.h"
@@ -152,9 +154,16 @@ class ResultBuilder {
152
154
// / different levels of, e.g., the inheritance hierarchy.
153
155
std::list<ShadowMap> ShadowMaps;
154
156
157
+ // / Overloaded C++ member functions found by SemaLookup.
158
+ // / Used to determine when one overload is dominated by another.
159
+ llvm::DenseMap<std::pair<DeclContext *, /* Name*/ uintptr_t >, ShadowMapEntry>
160
+ OverloadMap;
161
+
155
162
// / If we're potentially referring to a C++ member function, the set
156
163
// / of qualifiers applied to the object type.
157
164
Qualifiers ObjectTypeQualifiers;
165
+ // / The kind of the object expression, for rvalue/lvalue overloads.
166
+ ExprValueKind ObjectKind;
158
167
159
168
// / Whether the \p ObjectTypeQualifiers field is active.
160
169
bool HasObjectTypeQualifiers;
@@ -230,8 +239,9 @@ class ResultBuilder {
230
239
// / out member functions that aren't available (because there will be a
231
240
// / cv-qualifier mismatch) or prefer functions with an exact qualifier
232
241
// / match.
233
- void setObjectTypeQualifiers (Qualifiers Quals) {
242
+ void setObjectTypeQualifiers (Qualifiers Quals, ExprValueKind Kind ) {
234
243
ObjectTypeQualifiers = Quals;
244
+ ObjectKind = Kind;
235
245
HasObjectTypeQualifiers = true ;
236
246
}
237
247
@@ -1157,6 +1167,53 @@ static void setInBaseClass(ResultBuilder::Result &R) {
1157
1167
R.InBaseClass = true ;
1158
1168
}
1159
1169
1170
+ enum class OverloadCompare { BothViable, Dominates, Dominated };
1171
+ // Will Candidate ever be called on the object, when overloaded with Incumbent?
1172
+ // Returns Dominates if Candidate is always called, Dominated if Incumbent is
1173
+ // always called, BothViable if either may be called dependending on arguments.
1174
+ // Precondition: must actually be overloads!
1175
+ static OverloadCompare compareOverloads (const CXXMethodDecl &Candidate,
1176
+ const CXXMethodDecl &Incumbent,
1177
+ const Qualifiers &ObjectQuals,
1178
+ ExprValueKind ObjectKind) {
1179
+ if (Candidate.isVariadic () != Incumbent.isVariadic () ||
1180
+ Candidate.getNumParams () != Incumbent.getNumParams () ||
1181
+ Candidate.getMinRequiredArguments () !=
1182
+ Incumbent.getMinRequiredArguments ())
1183
+ return OverloadCompare::BothViable;
1184
+ for (unsigned I = 0 , E = Candidate.getNumParams (); I != E; ++I)
1185
+ if (Candidate.parameters ()[I]->getType ().getCanonicalType () !=
1186
+ Incumbent.parameters ()[I]->getType ().getCanonicalType ())
1187
+ return OverloadCompare::BothViable;
1188
+ if (!llvm::empty (Candidate.specific_attrs <EnableIfAttr>()) ||
1189
+ !llvm::empty (Incumbent.specific_attrs <EnableIfAttr>()))
1190
+ return OverloadCompare::BothViable;
1191
+ // At this point, we know calls can't pick one or the other based on
1192
+ // arguments, so one of the two must win. (Or both fail, handled elsewhere).
1193
+ RefQualifierKind CandidateRef = Candidate.getRefQualifier ();
1194
+ RefQualifierKind IncumbentRef = Incumbent.getRefQualifier ();
1195
+ if (CandidateRef != IncumbentRef) {
1196
+ // If the object kind is LValue/RValue, there's one acceptable ref-qualifier
1197
+ // and it can't be mixed with ref-unqualified overloads (in valid code).
1198
+
1199
+ // For xvalue objects, we prefer the rvalue overload even if we have to
1200
+ // add qualifiers (which is rare, because const&& is rare).
1201
+ if (ObjectKind == clang::VK_XValue)
1202
+ return CandidateRef == RQ_RValue ? OverloadCompare::Dominates
1203
+ : OverloadCompare::Dominated;
1204
+ }
1205
+ // Now the ref qualifiers are the same (or we're in some invalid state).
1206
+ // So make some decision based on the qualifiers.
1207
+ Qualifiers CandidateQual = Candidate.getMethodQualifiers ();
1208
+ Qualifiers IncumbentQual = Incumbent.getMethodQualifiers ();
1209
+ bool CandidateSuperset = CandidateQual.compatiblyIncludes (IncumbentQual);
1210
+ bool IncumbentSuperset = IncumbentQual.compatiblyIncludes (CandidateQual);
1211
+ if (CandidateSuperset == IncumbentSuperset)
1212
+ return OverloadCompare::BothViable;
1213
+ return IncumbentSuperset ? OverloadCompare::Dominates
1214
+ : OverloadCompare::Dominated;
1215
+ }
1216
+
1160
1217
void ResultBuilder::AddResult (Result R, DeclContext *CurContext,
1161
1218
NamedDecl *Hiding, bool InBaseClass = false ) {
1162
1219
if (R.Kind != Result::RK_Declaration) {
@@ -1233,6 +1290,44 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
1233
1290
// qualifiers.
1234
1291
return ;
1235
1292
}
1293
+ // Detect cases where a ref-qualified method cannot be invoked.
1294
+ switch (Method->getRefQualifier ()) {
1295
+ case RQ_LValue:
1296
+ if (ObjectKind != VK_LValue && !MethodQuals.hasConst ())
1297
+ return ;
1298
+ break ;
1299
+ case RQ_RValue:
1300
+ if (ObjectKind == VK_LValue)
1301
+ return ;
1302
+ break ;
1303
+ case RQ_None:
1304
+ break ;
1305
+ }
1306
+
1307
+ // / Check whether this dominates another overloaded method, which should
1308
+ // / be suppressed (or vice versa).
1309
+ // / Motivating case is const_iterator begin() const vs iterator begin().
1310
+ auto &OverloadSet = OverloadMap[std::make_pair (
1311
+ CurContext, Method->getDeclName ().getAsOpaqueInteger ())];
1312
+ for (const DeclIndexPair& Entry : OverloadSet) {
1313
+ Result &Incumbent = Results[Entry.second ];
1314
+ switch (compareOverloads (*Method,
1315
+ *cast<CXXMethodDecl>(Incumbent.Declaration ),
1316
+ ObjectTypeQualifiers, ObjectKind)) {
1317
+ case OverloadCompare::Dominates:
1318
+ // Replace the dominated overload with this one.
1319
+ // FIXME: if the overload dominates multiple incumbents then we
1320
+ // should remove all. But two overloads is by far the common case.
1321
+ Incumbent = std::move (R);
1322
+ return ;
1323
+ case OverloadCompare::Dominated:
1324
+ // This overload can't be called, drop it.
1325
+ return ;
1326
+ case OverloadCompare::BothViable:
1327
+ break ;
1328
+ }
1329
+ }
1330
+ OverloadSet.Add (Method, Results.size ());
1236
1331
}
1237
1332
1238
1333
// Insert this result into the set of results.
@@ -3997,7 +4092,8 @@ void Sema::CodeCompleteOrdinaryName(Scope *S,
3997
4092
// the member function to filter/prioritize the results list.
3998
4093
auto ThisType = getCurrentThisType ();
3999
4094
if (!ThisType.isNull ())
4000
- Results.setObjectTypeQualifiers (ThisType->getPointeeType ().getQualifiers ());
4095
+ Results.setObjectTypeQualifiers (ThisType->getPointeeType ().getQualifiers (),
4096
+ VK_LValue);
4001
4097
4002
4098
CodeCompletionDeclConsumer Consumer (Results, CurContext);
4003
4099
LookupVisibleDecls (S, LookupOrdinaryName, Consumer,
@@ -4551,13 +4647,12 @@ AddObjCProperties(const CodeCompletionContext &CCContext,
4551
4647
}
4552
4648
}
4553
4649
4554
- static void
4555
- AddRecordMembersCompletionResults (Sema &SemaRef, ResultBuilder &Results,
4556
- Scope *S, QualType BaseType, RecordDecl *RD,
4557
- Optional<FixItHint> AccessOpFixIt) {
4650
+ static void AddRecordMembersCompletionResults (
4651
+ Sema &SemaRef, ResultBuilder &Results, Scope *S, QualType BaseType,
4652
+ ExprValueKind BaseKind, RecordDecl *RD, Optional<FixItHint> AccessOpFixIt) {
4558
4653
// Indicate that we are performing a member access, and the cv-qualifiers
4559
4654
// for the base object type.
4560
- Results.setObjectTypeQualifiers (BaseType.getQualifiers ());
4655
+ Results.setObjectTypeQualifiers (BaseType.getQualifiers (), BaseKind );
4561
4656
4562
4657
// Access to a C/C++ class, struct, or union.
4563
4658
Results.allowNestedNameSpecifiers ();
@@ -4638,18 +4733,20 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
4638
4733
Base = ConvertedBase.get ();
4639
4734
4640
4735
QualType BaseType = Base->getType ();
4736
+ ExprValueKind BaseKind = Base->getValueKind ();
4641
4737
4642
4738
if (IsArrow) {
4643
- if (const PointerType *Ptr = BaseType->getAs <PointerType>())
4739
+ if (const PointerType *Ptr = BaseType->getAs <PointerType>()) {
4644
4740
BaseType = Ptr ->getPointeeType ();
4645
- else if (BaseType->isObjCObjectPointerType ())
4741
+ BaseKind = VK_LValue;
4742
+ } else if (BaseType->isObjCObjectPointerType ())
4646
4743
/* Do nothing*/ ;
4647
4744
else
4648
4745
return false ;
4649
4746
}
4650
4747
4651
4748
if (const RecordType *Record = BaseType->getAs <RecordType>()) {
4652
- AddRecordMembersCompletionResults (*this , Results, S, BaseType,
4749
+ AddRecordMembersCompletionResults (*this , Results, S, BaseType, BaseKind,
4653
4750
Record->getDecl (),
4654
4751
std::move (AccessOpFixIt));
4655
4752
} else if (const auto *TST =
@@ -4658,13 +4755,13 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
4658
4755
if (const auto *TD =
4659
4756
dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl ())) {
4660
4757
CXXRecordDecl *RD = TD->getTemplatedDecl ();
4661
- AddRecordMembersCompletionResults (*this , Results, S, BaseType, RD ,
4662
- std::move (AccessOpFixIt));
4758
+ AddRecordMembersCompletionResults (*this , Results, S, BaseType, BaseKind ,
4759
+ RD, std::move (AccessOpFixIt));
4663
4760
}
4664
4761
} else if (const auto *ICNT = BaseType->getAs <InjectedClassNameType>()) {
4665
4762
if (auto *RD = ICNT->getDecl ())
4666
- AddRecordMembersCompletionResults (*this , Results, S, BaseType, RD ,
4667
- std::move (AccessOpFixIt));
4763
+ AddRecordMembersCompletionResults (*this , Results, S, BaseType, BaseKind ,
4764
+ RD, std::move (AccessOpFixIt));
4668
4765
} else if (!IsArrow && BaseType->isObjCObjectPointerType ()) {
4669
4766
// Objective-C property reference.
4670
4767
AddedPropertiesSet AddedProperties;
0 commit comments