summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-doc/tool/ClangDocMain.cpp')
-rw-r--r--clang-tools-extra/clang-doc/tool/ClangDocMain.cpp82
1 files changed, 57 insertions, 25 deletions
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 9e89e8568be..6e4a92d7b06 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -121,9 +121,24 @@ bool DumpResultToFile(const Twine &DirName, const Twine &FileName,
return false;
}
+// A function to extract the appropriate path name for a given info's
+// documentation. The path returned is a composite of the parent namespaces as
+// directories plus the decl name as the filename.
+//
+// Example: Given the below, the <ext> path for class C will be <
+// root>/A/B/C.<ext>
+//
+// namespace A {
+// namesapce B {
+//
+// class C {};
+//
+// }
+// }
llvm::Expected<llvm::SmallString<128>>
-getPath(StringRef Root, StringRef Ext, StringRef Name,
- llvm::SmallVectorImpl<doc::Reference> &Namespaces) {
+getInfoOutputFile(StringRef Root,
+ llvm::SmallVectorImpl<doc::Reference> &Namespaces,
+ StringRef Name, StringRef Ext) {
std::error_code OK;
llvm::SmallString<128> Path;
llvm::sys::path::native(Root, Path);
@@ -134,6 +149,8 @@ getPath(StringRef Root, StringRef Ext, StringRef Name,
return llvm::make_error<llvm::StringError>("Unable to create directory.\n",
llvm::inconvertibleErrorCode());
+ if (Name.empty())
+ Name = "GlobalNamespace";
llvm::sys::path::append(Path, Name + Ext);
return Path;
}
@@ -146,6 +163,30 @@ std::string getFormatString(OutputFormatTy Ty) {
llvm_unreachable("Unknown OutputFormatTy");
}
+// Iterate through tool results and build string map of info vectors from the
+// encoded bitstreams.
+bool bitcodeResultsToInfos(
+ tooling::ToolResults &Results,
+ llvm::StringMap<std::vector<std::unique_ptr<doc::Info>>> &Output) {
+ bool Err = false;
+ Results.forEachResult([&](StringRef Key, StringRef Value) {
+ llvm::BitstreamCursor Stream(Value);
+ doc::ClangDocBitcodeReader Reader(Stream);
+ auto Infos = Reader.readBitcode();
+ if (!Infos) {
+ llvm::errs() << toString(Infos.takeError()) << "\n";
+ Err = true;
+ return;
+ }
+ for (auto &I : Infos.get()) {
+ auto R =
+ Output.try_emplace(Key, std::vector<std::unique_ptr<doc::Info>>());
+ R.first->second.emplace_back(std::move(I));
+ }
+ });
+ return Err;
+}
+
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
std::error_code OK;
@@ -196,30 +237,21 @@ int main(int argc, const char **argv) {
}
// Collect values into output by key.
- llvm::outs() << "Collecting infos...\n";
- llvm::StringMap<std::vector<std::unique_ptr<doc::Info>>> MapOutput;
-
// In ToolResults, the Key is the hashed USR and the value is the
// bitcode-encoded representation of the Info object.
- Exec->get()->getToolResults()->forEachResult([&](StringRef Key,
- StringRef Value) {
- llvm::BitstreamCursor Stream(Value);
- doc::ClangDocBitcodeReader Reader(Stream);
- auto Infos = Reader.readBitcode();
- for (auto &I : Infos) {
- auto R =
- MapOutput.try_emplace(Key, std::vector<std::unique_ptr<doc::Info>>());
- R.first->second.emplace_back(std::move(I));
- }
- });
+ llvm::outs() << "Collecting infos...\n";
+ llvm::StringMap<std::vector<std::unique_ptr<doc::Info>>> USRToInfos;
+ if (bitcodeResultsToInfos(*Exec->get()->getToolResults(), USRToInfos))
+ return 1;
- // Reducing and generation phases
- llvm::outs() << "Reducing " << MapOutput.size() << " infos...\n";
- llvm::StringMap<std::unique_ptr<doc::Info>> ReduceOutput;
- for (auto &Group : MapOutput) {
+ // First reducing phase (reduce all decls into one info per decl).
+ llvm::outs() << "Reducing " << USRToInfos.size() << " infos...\n";
+ for (auto &Group : USRToInfos) {
auto Reduced = doc::mergeInfos(Group.getValue());
- if (!Reduced)
+ if (!Reduced) {
llvm::errs() << llvm::toString(Reduced.takeError());
+ continue;
+ }
if (DumpIntermediateResult) {
SmallString<4096> Buffer;
@@ -230,10 +262,10 @@ int main(int argc, const char **argv) {
llvm::errs() << "Error dumping to bitcode.\n";
continue;
}
-
- // Create the relevant ostream and emit the documentation for this decl.
doc::Info *I = Reduced.get().get();
- auto InfoPath = getPath(OutDirectory, "." + Format, I->Name, I->Namespace);
+
+ auto InfoPath =
+ getInfoOutputFile(OutDirectory, I->Namespace, I->Name, "." + Format);
if (!InfoPath) {
llvm::errs() << toString(InfoPath.takeError()) << "\n";
continue;
@@ -241,7 +273,7 @@ int main(int argc, const char **argv) {
std::error_code FileErr;
llvm::raw_fd_ostream InfoOS(InfoPath.get(), FileErr, llvm::sys::fs::F_None);
if (FileErr != OK) {
- llvm::errs() << "Error opening index file: " << FileErr.message() << "\n";
+ llvm::errs() << "Error opening info file: " << FileErr.message() << "\n";
continue;
}
OpenPOWER on IntegriCloud