diff options
| author | John Thompson <John.Thompson.JTSoftware@gmail.com> | 2013-03-28 01:20:19 +0000 |
|---|---|---|
| committer | John Thompson <John.Thompson.JTSoftware@gmail.com> | 2013-03-28 01:20:19 +0000 |
| commit | 8a2f7a8e0dc6242d1bfd4004555f81834d4a1b95 (patch) | |
| tree | f2d8cedbcdfd6c93b6d20244ebb920f23467894f | |
| parent | 8668703d3dbfc37ce2d49e430c37aec79d8fba42 (diff) | |
modularize - revised to group duplicate symbols together in the error output.
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@178207 91177308-0d34-0410-b5e6-96231b3b80d8
| -rw-r--r-- | modularize/Modularize.cpp | 85 | ||||
| -rw-r--r-- | test/modularize/ProblemsDuplicate.modularize | 4 | ||||
| -rw-r--r-- | test/modularize/ProblemsInconsistent.modularize | 4 |
3 files changed, 66 insertions, 27 deletions
diff --git a/modularize/Modularize.cpp b/modularize/Modularize.cpp index 579252d3..c30bff76 100644 --- a/modularize/Modularize.cpp +++ b/modularize/Modularize.cpp @@ -209,15 +209,35 @@ struct Location { }; struct Entry { - enum Kind { + enum KindType { Tag, Value, Macro } Kind; + static const int NumberOfKinds = 3; Location Loc; + + StringRef getKindName() { return getKindName(Kind); } + static StringRef getKindName(KindType kind); }; +// Return a string representing the given kind. +StringRef Entry::getKindName(Entry::KindType kind) { + switch (kind) { + case Tag: + return "tag"; + case Value: + return "value"; + break; + case Macro: + return "macro"; + break; + default: + return "unknown"; + } +} + struct HeaderEntry { std::string Name; Location Loc; @@ -248,7 +268,7 @@ class EntityMap : public StringMap<SmallVector<Entry, 2> > { public: DenseMap<const FileEntry *, HeaderContents> HeaderContentMismatches; - void add(const std::string &Name, enum Entry::Kind Kind, Location Loc) { + void add(const std::string &Name, enum Entry::KindType Kind, Location Loc) { // Record this entity in its header. HeaderEntry HE = { Name, Loc }; CurHeaderContents[Loc.File].push_back(HE); @@ -444,35 +464,50 @@ int main(int argc, const char **argv) { ClangTool Tool(*Compilations, Headers); int HadErrors = Tool.run(new ModularizeFrontendActionFactory(Entities)); + // Create a place to save duplicate entity locations, separate bins per kind. + typedef SmallVector<Location, 8> LocationArray; + typedef SmallVector<LocationArray *, Entry::NumberOfKinds> EntryBinArray; + EntryBinArray EntryBins; + Entry::KindType kind; + int kindIndex; + for (kindIndex = 0; kindIndex < Entry::NumberOfKinds; ++kindIndex) { + EntryBins.push_back(new LocationArray); + } + // Check for the same entity being defined in multiple places. - // FIXME: Could they be grouped into a list? for (EntityMap::iterator E = Entities.begin(), EEnd = Entities.end(); E != EEnd; ++E) { - Location Tag, Value, Macro; + // If only one occurance, exit early. + if (E->second.size() == 1) + continue; + // Clear entity locations. + for (EntryBinArray::iterator CI = EntryBins.begin(), CE = EntryBins.end(); + CI != CE; ++CI) { + (**CI).clear(); + } + // Walk the entities of a single name, collecting the locations, + // separated into separate bins. for (unsigned I = 0, N = E->second.size(); I != N; ++I) { - Location *Which; - switch (E->second[I].Kind) { - case Entry::Tag: - Which = &Tag; - break; - case Entry::Value: - Which = &Value; - break; - case Entry::Macro: - Which = &Macro; - break; - } - - if (!Which->File) { - *Which = E->second[I].Loc; + kind = E->second[I].Kind; + LocationArray *locationArray = EntryBins[kind]; + locationArray->push_back(E->second[I].Loc); + } + // Report any duplicate entity definition errors. + int kindIndex = 0; + for (EntryBinArray::iterator DI = EntryBins.begin(), DE = EntryBins.end(); + DI != DE; ++DI, ++kindIndex) { + int eCount = (**DI).size(); + // If only 1 occurance, skip; + if (eCount <= 1) continue; + LocationArray::iterator FI = (**DI).begin(); + StringRef kindName = Entry::getKindName((Entry::KindType) kindIndex); + errs() << "error: " << kindName << " '" << E->first() + << "' defined at multiple locations:\n"; + for (LocationArray::iterator FE = (**DI).end(); FI != FE; ++FI) { + errs() << " " << FI->File->getName() << ":" << FI->Line << ":" + << FI->Column << "\n"; } - - errs() << "error: '" << E->first() << "' defined at both " - << Which->File->getName() << ":" << Which->Line << ":" - << Which->Column << " and " << E->second[I].Loc.File->getName() - << ":" << E->second[I].Loc.Line << ":" << E->second[I].Loc.Column - << "\n"; HadErrors = 1; } } diff --git a/test/modularize/ProblemsDuplicate.modularize b/test/modularize/ProblemsDuplicate.modularize index 43469e08..e53657ca 100644 --- a/test/modularize/ProblemsDuplicate.modularize +++ b/test/modularize/ProblemsDuplicate.modularize @@ -3,4 +3,6 @@ Inputs/DuplicateHeader1.h Inputs/DuplicateHeader2.h -# CHECK: error: 'TypeInt' defined at both {{.*}}{{[/\\]}}Inputs{{[/\\]}}DuplicateHeader1.h:2:13 and {{.*}}{{[/\\]}}Inputs{{[/\\]}}DuplicateHeader2.h:2:13 +# CHECK: error: value 'TypeInt' defined at multiple locations: +# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}DuplicateHeader1.h:2:13 +# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}DuplicateHeader2.h:2:13
\ No newline at end of file diff --git a/test/modularize/ProblemsInconsistent.modularize b/test/modularize/ProblemsInconsistent.modularize index dfe03208..fe907b16 100644 --- a/test/modularize/ProblemsInconsistent.modularize +++ b/test/modularize/ProblemsInconsistent.modularize @@ -3,7 +3,9 @@ Inputs/InconsistentHeader1.h Inputs/InconsistentHeader2.h -# CHECK: error: 'SYMBOL' defined at both {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:3:9 and {{.*}}{{[/\\]}}Inputs/InconsistentSubHeader.h:6:9 +# CHECK: error: macro 'SYMBOL' defined at multiple locations: +# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:3:9 +# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:6:9 # CHECK-NEXT: error: header '{{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h' has different contents dependening on how it was included # CHECK-NEXT: note: 'SYMBOL' in {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h at 3:9 not always provided # CHECK-NEXT: note: 'SYMBOL' in {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h at 6:9 not always provided |
