summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateDeduction.cpp
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2016-05-19 02:28:21 +0000
committerFaisal Vali <faisalv@yahoo.com>2016-05-19 02:28:21 +0000
commit683b0742099ce1eb34fb3031f4cd5282262cadbe (patch)
tree6b3d3fdda0b8bf0f787a7c7209552afd2b8c9202 /clang/lib/Sema/SemaTemplateDeduction.cpp
parent1fec404da0eadd11dcd2cff11d204722f57a9401 (diff)
downloadbcm5719-llvm-683b0742099ce1eb34fb3031f4cd5282262cadbe.tar.gz
bcm5719-llvm-683b0742099ce1eb34fb3031f4cd5282262cadbe.zip
Fix PR27601 by reverting [r267453] - Refactor traversal of bases in deduction of template parameters from base
This reversal is being done with r267453's author's (i.e. Richard Smith's) permission. This fixes https://llvm.org/bugs/show_bug.cgi?id=27601 Also, per Richard's request the examples from the bug report have been added to our test suite. llvm-svn: 270016
Diffstat (limited to 'clang/lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp71
1 files changed, 45 insertions, 26 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index f35dc30906e..59dc1da49ac 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -1454,35 +1454,54 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
// 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;
- 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;
+ 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;
}
- // Keep going.
- return true;
- });
+ // 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>());
+ }
+ }
if (Successful)
return Sema::TDK_Success;
OpenPOWER on IntegriCloud