r267453 - Refactor traversal of bases in deduction of template parameters from base
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 25 12:28:09 PDT 2016
Author: rsmith
Date: Mon Apr 25 14:28:08 2016
New Revision: 267453
URL: http://llvm.org/viewvc/llvm-project?rev=267453&view=rev
Log:
Refactor traversal of bases in deduction of template parameters from base
classes of an argument to use CXXRecordDecl::forallBases. Fix forallBases to
only visit each base class once.
Modified:
cfe/trunk/lib/AST/CXXInheritance.cpp
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
Modified: cfe/trunk/lib/AST/CXXInheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXInheritance.cpp?rev=267453&r1=267452&r2=267453&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CXXInheritance.cpp (original)
+++ cfe/trunk/lib/AST/CXXInheritance.cpp Mon Apr 25 14:28:08 2016
@@ -137,6 +137,7 @@ CXXRecordDecl::isCurrentInstantiation(co
bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches,
bool AllowShortCircuit) const {
SmallVector<const CXXRecordDecl*, 8> Queue;
+ llvm::SmallPtrSet<const CXXRecordDecl*, 8> Enqueued;
const CXXRecordDecl *Record = this;
bool AllMatches = true;
@@ -158,12 +159,14 @@ bool CXXRecordDecl::forallBases(ForallBa
AllMatches = false;
continue;
}
-
- Queue.push_back(Base);
- if (!BaseMatches(Base)) {
- if (AllowShortCircuit) return false;
- AllMatches = false;
- continue;
+
+ if (Enqueued.insert(Base).second) {
+ Queue.push_back(Base);
+ if (!BaseMatches(Base)) {
+ if (AllowShortCircuit) return false;
+ AllMatches = false;
+ continue;
+ }
}
}
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=267453&r1=267452&r2=267453&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Apr 25 14:28:08 2016
@@ -1454,54 +1454,35 @@ DeduceTemplateArgumentsByTypeMatch(Sema
// otherwise fail. If they yield more than one possible deduced A, the
// type deduction fails.
- // Reset the incorrectly deduced argument from above.
- Deduced = DeducedOrig;
-
- // Use data recursion to crawl through the list of base classes.
- // Visited contains the set of nodes we have already visited, while
- // ToVisit is our stack of records that we still need to visit.
- llvm::SmallPtrSet<const RecordType *, 8> Visited;
- SmallVector<const RecordType *, 8> ToVisit;
- ToVisit.push_back(RecordT);
bool Successful = false;
- while (!ToVisit.empty()) {
- // Retrieve the next class in the inheritance hierarchy.
- const RecordType *NextT = ToVisit.pop_back_val();
-
- // If we have already seen this type, skip it.
- if (!Visited.insert(NextT).second)
- continue;
-
- // If this is a base class, try to perform template argument
- // deduction from it.
- if (NextT != RecordT) {
- TemplateDeductionInfo BaseInfo(Info.getLocation());
- Sema::TemplateDeductionResult BaseResult =
- DeduceTemplateArguments(S, TemplateParams, SpecParam,
- QualType(NextT, 0), BaseInfo, Deduced);
-
- // If template argument deduction for this base was successful,
- // note that we had some success. Otherwise, ignore any deductions
- // from this base class.
- if (BaseResult == Sema::TDK_Success) {
- Successful = true;
- DeducedOrig.clear();
- DeducedOrig.append(Deduced.begin(), Deduced.end());
- Info.Param = BaseInfo.Param;
- Info.FirstArg = BaseInfo.FirstArg;
- Info.SecondArg = BaseInfo.SecondArg;
- } else
- Deduced = DeducedOrig;
+ RecordT->getAsCXXRecordDecl()->forallBases([&](
+ const CXXRecordDecl *Base) {
+ // Start with a fresh copy of the old deduced arguments.
+ SmallVector<DeducedTemplateArgument, 8> DeducedBase(DeducedOrig.begin(),
+ DeducedOrig.end());
+
+ TemplateDeductionInfo BaseInfo(Info.getLocation());
+ Sema::TemplateDeductionResult BaseResult =
+ DeduceTemplateArguments(S, TemplateParams, SpecParam,
+ S.Context.getRecordType(Base),
+ BaseInfo, DeducedBase);
+
+ // If template argument deduction for this base was successful,
+ // note that we had some success. Otherwise, ignore any deductions
+ // from this base class.
+ if (BaseResult == Sema::TDK_Success) {
+ // FIXME: If we've already been successful, deduction should fail
+ // due to ambiguity.
+ Successful = true;
+ Deduced.swap(DeducedBase);
+ Info.Param = BaseInfo.Param;
+ Info.FirstArg = BaseInfo.FirstArg;
+ Info.SecondArg = BaseInfo.SecondArg;
}
- // Visit base classes
- CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl());
- for (const auto &Base : Next->bases()) {
- assert(Base.getType()->isRecordType() &&
- "Base class that isn't a record?");
- ToVisit.push_back(Base.getType()->getAs<RecordType>());
- }
- }
+ // Keep going.
+ return true;
+ });
if (Successful)
return Sema::TDK_Success;
More information about the cfe-commits
mailing list