diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-10-24 16:17:19 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-10-24 16:17:19 +0000 |
commit | 0575d4ab561b4b2905c6ef614a7f7a87be26e64f (patch) | |
tree | 27117b555c5ef9f177a87812643680008a4a33cb /lib/Sema/SemaInherit.cpp | |
parent | 2f639b9f3c6b081f076d2ac6d75115ce44bfa249 (diff) |
Some cleanups for the ambiguous derived-to-base conversion checks
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58096 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInherit.cpp')
-rw-r--r-- | lib/Sema/SemaInherit.cpp | 82 |
1 files changed, 40 insertions, 42 deletions
diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp index 256ee24e1c..a676b64ff8 100644 --- a/lib/Sema/SemaInherit.cpp +++ b/lib/Sema/SemaInherit.cpp @@ -24,13 +24,15 @@ #include <set> #include <string> -namespace clang { +using namespace clang; /// isAmbiguous - Determines whether the set of paths provided is /// ambiguous, i.e., there are two or more paths that refer to /// different base class subobjects of the same type. BaseType must be /// an unqualified, canonical class type. bool BasePaths::isAmbiguous(QualType BaseType) { + assert(BaseType->isCanonical() && "Base type must be the canonical type"); + assert(BaseType.getCVRQualifiers() == 0 && "Base type must be unqualified"); std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; return Subobjects.second + (Subobjects.first? 1 : 0) > 1; } @@ -141,8 +143,8 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, BasePaths &Paths) { /// if there is an error, and Range is the source range to highlight /// if there is an error. bool -Sema::CheckDerivedToBaseConversion(SourceLocation Loc, SourceRange Range, - QualType Derived, QualType Base) { +Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, + SourceLocation Loc, SourceRange Range) { // First, determine whether the path from Derived to Base is // ambiguous. This is slightly more expensive than checking whether // the Derived to Base conversion exists, because here we need to @@ -153,47 +155,43 @@ Sema::CheckDerivedToBaseConversion(SourceLocation Loc, SourceRange Range, if (!DerivationOkay) return true; - if (Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) { - // We know that the derived-to-base conversion is - // ambiguous. Perform the derived-to-base search just one more - // time to compute all of the possible paths so that we can print - // them out. This is more expensive than any of the previous - // derived-to-base checks we've done, but at this point we know - // we'll be issuing a diagnostic so performance isn't as much of - // an issue. - Paths.clear(); - Paths.setRecordingPaths(true); - bool StillOkay = IsDerivedFrom(Derived, Base, Paths); - assert(StillOkay && "Can only be used with a derived-to-base conversion"); - if (!StillOkay) - return true; - - // Build up a textual representation of the ambiguous paths, e.g., - // D -> B -> A, that will be used to illustrate the ambiguous - // conversions in the diagnostic. We only print one of the paths - // to each base class subobject. - std::string PathDisplayStr; - std::set<unsigned> DisplayedPaths; - for (BasePaths::paths_iterator Path = Paths.begin(); - Path != Paths.end(); ++Path) { - if (DisplayedPaths.insert(Path->back().SubobjectNumber).second) { - // We haven't displayed a path to this particular base - // class subobject yet. - PathDisplayStr += "\n "; - PathDisplayStr += Derived.getAsString(); - for (BasePath::const_iterator Element = Path->begin(); - Element != Path->end(); ++Element) - PathDisplayStr += " -> " + Element->Base->getType().getAsString(); - } - } + if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) + return false; - Diag(Loc, diag::err_ambiguous_derived_to_base_conv, - Derived.getAsString(), Base.getAsString(), PathDisplayStr, Range); + // We know that the derived-to-base conversion is ambiguous, and + // we're going to produce a diagnostic. Perform the derived-to-base + // search just one more time to compute all of the possible paths so + // that we can print them out. This is more expensive than any of + // the previous derived-to-base checks we've done, but at this point + // performance isn't as much of an issue. + Paths.clear(); + Paths.setRecordingPaths(true); + bool StillOkay = IsDerivedFrom(Derived, Base, Paths); + assert(StillOkay && "Can only be used with a derived-to-base conversion"); + if (!StillOkay) return true; + + // Build up a textual representation of the ambiguous paths, e.g., + // D -> B -> A, that will be used to illustrate the ambiguous + // conversions in the diagnostic. We only print one of the paths + // to each base class subobject. + std::string PathDisplayStr; + std::set<unsigned> DisplayedPaths; + for (BasePaths::paths_iterator Path = Paths.begin(); + Path != Paths.end(); ++Path) { + if (DisplayedPaths.insert(Path->back().SubobjectNumber).second) { + // We haven't displayed a path to this particular base + // class subobject yet. + PathDisplayStr += "\n "; + PathDisplayStr += Derived.getAsString(); + for (BasePath::const_iterator Element = Path->begin(); + Element != Path->end(); ++Element) + PathDisplayStr += " -> " + Element->Base->getType().getAsString(); + } } - - return false; + + Diag(Loc, diag::err_ambiguous_derived_to_base_conv, + Derived.getAsString(), Base.getAsString(), PathDisplayStr, Range); + return true; } -} // end namespace clang - |