diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-01-16 00:38:09 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-01-16 00:38:09 +0000 |
commit | 1c846b0e861fc45c374391bc4ba43fabbaa331b4 (patch) | |
tree | c1133c250d8932d7d4bd9c61468eeec33897c1a1 /clang/lib/Sema/SemaInherit.cpp | |
parent | 76d190cf4ad3a96b30466475490b76bca9c9e031 (diff) | |
download | bcm5719-llvm-1c846b0e861fc45c374391bc4ba43fabbaa331b4.tar.gz bcm5719-llvm-1c846b0e861fc45c374391bc4ba43fabbaa331b4.zip |
Improve diagnostics for ambiguous name lookup results
llvm-svn: 62287
Diffstat (limited to 'clang/lib/Sema/SemaInherit.cpp')
-rw-r--r-- | clang/lib/Sema/SemaInherit.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaInherit.cpp b/clang/lib/Sema/SemaInherit.cpp index 0791ac21f88..43caa9286eb 100644 --- a/clang/lib/Sema/SemaInherit.cpp +++ b/clang/lib/Sema/SemaInherit.cpp @@ -49,6 +49,7 @@ void BasePaths::clear() { /// @brief Swaps the contents of this BasePaths structure with the /// contents of Other. void BasePaths::swap(BasePaths &Other) { + std::swap(Origin, Other.Origin); Paths.swap(Other.Paths); ClassSubobjects.swap(Other.ClassSubobjects); std::swap(FindAmbiguities, Other.FindAmbiguities); @@ -86,6 +87,7 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, BasePaths &Paths) { if (Derived == Base) return false; + Paths.setOrigin(Derived); return LookupInBases(cast<CXXRecordType>(Derived->getAsRecordType())->getDecl(), MemberLookupCriteria(Base), Paths); } @@ -240,6 +242,26 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, // 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 = getAmbiguousPathsDisplayString(Paths); + + Diag(Loc, diag::err_ambiguous_derived_to_base_conv) + << Derived << Base << PathDisplayStr << Range; + return true; +} + +/// @brief Builds a string representing ambiguous paths from a +/// specific derived class to different subobjects of the same base +/// class. +/// +/// This function builds a string that can be used in error messages +/// to show the different paths that one can take through the +/// inheritance hierarchy to go from the derived class to different +/// subobjects of a base class. The result looks something like this: +/// @code +/// struct D -> struct B -> struct A +/// struct D -> struct C -> struct A +/// @endcode +std::string Sema::getAmbiguousPathsDisplayString(BasePaths &Paths) { std::string PathDisplayStr; std::set<unsigned> DisplayedPaths; for (BasePaths::paths_iterator Path = Paths.begin(); @@ -248,14 +270,12 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, // We haven't displayed a path to this particular base // class subobject yet. PathDisplayStr += "\n "; - PathDisplayStr += Derived.getAsString(); + PathDisplayStr += Paths.getOrigin().getAsString(); for (BasePath::const_iterator Element = Path->begin(); Element != Path->end(); ++Element) PathDisplayStr += " -> " + Element->Base->getType().getAsString(); } } - - Diag(Loc, diag::err_ambiguous_derived_to_base_conv) - << Derived << Base << PathDisplayStr << Range; - return true; + + return PathDisplayStr; } |