Skip to content

[WIP] add a mustache backend #108653

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 68 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
ac1c7b5
[clang-doc] add suport for clang-doc enum generation
PeterChou1 Jul 31, 2024
bcc4b0d
[clang-doc] remove useless code
PeterChou1 Jul 31, 2024
5fe47ca
[clang-doc] modify unittest
PeterChou1 Jul 31, 2024
28fb40f
[clang-doc] address pr comments
PeterChou1 Aug 12, 2024
0d150ea
[clang-doc] revert CommentInfo change
PeterChou1 Aug 12, 2024
e5e70b8
[clang-doc] fix test
PeterChou1 Aug 12, 2024
1c4f631
[clang-doc] fix unittest
PeterChou1 Aug 12, 2024
b8f3f9c
[clang-doc] address pr comments
PeterChou1 Aug 12, 2024
bb98aad
[clang-doc] clang-format
PeterChou1 Aug 12, 2024
c60e2b5
[llvm] implement support for mustache template language
PeterChou1 Aug 23, 2024
0a20de8
Merge branch 'main' into llvm-add-mustache
PeterChou1 Aug 23, 2024
8290c38
[llvm][Support] Finish implementation of Mustache
PeterChou1 Sep 6, 2024
07d31b4
Merge branch 'llvm-add-mustache' of https://github.com/PeterChou1/llv…
PeterChou1 Sep 6, 2024
6e893c0
[llvm][support] fix mustache test
PeterChou1 Sep 6, 2024
976593e
[llvm][support] add comments
PeterChou1 Sep 6, 2024
6a60eab
[llvm][support] add comments
PeterChou1 Sep 6, 2024
6a1fcc8
[llvm][support] use enumerate for loop
PeterChou1 Sep 6, 2024
f1c27af
Merge branch 'main' into llvm-add-mustache
PeterChou1 Sep 6, 2024
eb1e1a6
[llvm][support] clang-format
PeterChou1 Sep 6, 2024
8ff1100
Merge branch 'llvm-add-mustache' of https://github.com/PeterChou1/llv…
PeterChou1 Sep 6, 2024
f4b0520
[llvm][support] fix mustache test
PeterChou1 Sep 6, 2024
7ffaeec
[llvm][support] clang-format
PeterChou1 Sep 6, 2024
746fb97
[llvm][support] use llvm enumerate
PeterChou1 Sep 6, 2024
4944435
Merge branch 'main' into llvm-add-mustache
PeterChou1 Sep 6, 2024
bcc86fe
[llvm][support] fix unittest
PeterChou1 Sep 11, 2024
2ceb0b0
Merge branch 'llvm-add-mustache' of https://github.com/PeterChou1/llv…
PeterChou1 Sep 11, 2024
95ad7a6
[llvm][support] clang-format
PeterChou1 Sep 11, 2024
bb3b1ac
[llvm][support] address mustache comments
PeterChou1 Sep 12, 2024
d8aa85c
[llvm][support] clang-format
PeterChou1 Sep 12, 2024
0534a05
[llvm][support] clang-format
PeterChou1 Sep 12, 2024
06da7a5
[llvm][support] clang-format
PeterChou1 Sep 12, 2024
f713198
[llvm] mustache address comments
PeterChou1 Oct 8, 2024
6b4f5cd
[llvm] clang-format
PeterChou1 Oct 8, 2024
d400c29
[llvm] fix errors
PeterChou1 Oct 8, 2024
8fa5fd7
[llvm] fix more bugs
PeterChou1 Oct 8, 2024
fd7c106
[llvm] change mustache to pass by reference
PeterChou1 Oct 8, 2024
29bba68
[llvm] fix failing mustache regression test
PeterChou1 Oct 8, 2024
7eed82f
[llvm] format
PeterChou1 Oct 8, 2024
e73454d
[llvm] remove unused mustache member
PeterChou1 Oct 8, 2024
b58fbcb
[llvm] remove unused mustache member
PeterChou1 Oct 8, 2024
bb4ba40
[llvm] address more comments
PeterChou1 Oct 8, 2024
b0ce196
[llvm] address comments
PeterChou1 Oct 8, 2024
561c7eb
clang-format
PeterChou1 Oct 8, 2024
96f6990
clang-format
PeterChou1 Oct 8, 2024
a247423
[llvm] factor out internal classes
PeterChou1 Oct 10, 2024
a0e7d48
[llvm] clang-format
PeterChou1 Oct 10, 2024
4165fec
[llvm] refactor mustache to raw_ostream
PeterChou1 Oct 12, 2024
5b0a20a
[llvm] refactor to use os_stream
PeterChou1 Oct 12, 2024
ba4a6db
[llvm] clang-format
PeterChou1 Oct 12, 2024
362728f
[llvm] fix indentation bug
PeterChou1 Oct 12, 2024
dca40c5
[llvm] add mustache verification tool
PeterChou1 Oct 8, 2024
6fffeb2
[llvm] modify mustache tool
PeterChou1 Oct 12, 2024
7337a99
[llvm] add mustache verification tool
PeterChou1 Oct 8, 2024
439955b
[llvm] add mustache verification tool
PeterChou1 Oct 8, 2024
20045a9
[clang-doc] init mustache implementation
PeterChou1 Sep 13, 2024
adda08b
[clang-doc] add a mustache backend init implementation
PeterChou1 Sep 13, 2024
587bb02
[clang-doc] update
PeterChou1 Sep 24, 2024
ab1c3a6
[clang-doc] add more templates
PeterChou1 Oct 7, 2024
47c2d15
[clang-doc] init mustache implementation
PeterChou1 Sep 13, 2024
279ceee
[clang-doc] add a mustache backend init implementation
PeterChou1 Sep 13, 2024
9ab49b2
[clang-doc] update
PeterChou1 Sep 24, 2024
00830fe
[clang-doc] add more templates
PeterChou1 Oct 7, 2024
08a9f99
[clang-doc] init mustache implementation
PeterChou1 Sep 13, 2024
7e1399b
[clang-doc] add a mustache backend init implementation
PeterChou1 Sep 13, 2024
4e5109a
[clang-doc] add class template
PeterChou1 Oct 11, 2024
42d2995
clang-doc improve mustache output
PeterChou1 Oct 31, 2024
3778849
updated working copy
PeterChou1 Nov 1, 2024
2b490ed
add source ranges
PeterChou1 Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions clang-tools-extra/clang-doc/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ llvm::Error decodeRecord(const Record &R, std::optional<Location> &Field,
if (R[0] > INT_MAX)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"integer too large to parse");
Field.emplace((int)R[0], Blob, (bool)R[1]);
Field.emplace((int)R[0], (int)R[1], Blob, (bool)R[2]);
return llvm::Error::success();
}

Expand Down Expand Up @@ -135,7 +135,7 @@ llvm::Error decodeRecord(const Record &R,
if (R[0] > INT_MAX)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"integer too large to parse");
Field.emplace_back((int)R[0], Blob, (bool)R[1]);
Field.emplace_back((int)R[0], (int)R[1], Blob, (bool)R[2]);
return llvm::Error::success();
}

Expand Down Expand Up @@ -169,6 +169,8 @@ llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
return decodeRecord(R, I->USR, Blob);
case RECORD_NAME:
return decodeRecord(R, I->Name, Blob);
case RECORD_FULLNAME:
return decodeRecord(R, I->FullName, Blob);
case RECORD_PATH:
return decodeRecord(R, I->Path, Blob);
case RECORD_DEFLOCATION:
Expand Down Expand Up @@ -232,6 +234,8 @@ llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
switch (ID) {
case TYPEDEF_USR:
return decodeRecord(R, I->USR, Blob);
case TYPEDEF_DECLARATION:
return decodeRecord(R, I->TypeDeclaration, Blob);
case TYPEDEF_NAME:
return decodeRecord(R, I->Name, Blob);
case TYPEDEF_DEFLOCATION:
Expand Down Expand Up @@ -268,6 +272,8 @@ llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
return decodeRecord(R, I->Name, Blob);
case FUNCTION_DEFLOCATION:
return decodeRecord(R, I->DefLoc, Blob);
case FUNCTION_PROTOTYPE:
return decodeRecord(R, I->ProtoType, Blob);
case FUNCTION_LOCATION:
return decodeRecord(R, I->Loc, Blob);
case FUNCTION_ACCESS:
Expand All @@ -282,7 +288,15 @@ llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,

llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
TypeInfo *I) {
return llvm::Error::success();
switch (ID) {
case TYPE_IS_BUILTIN:
return decodeRecord(R, I->IsBuiltIn, Blob);
case TYPE_IS_TEMPLATE:
return decodeRecord(R, I->IsTemplate, Blob);
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid field for TypeInfo");
}
}

llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
Expand Down Expand Up @@ -468,6 +482,22 @@ template <> llvm::Error addTypeInfo(TypedefInfo *I, TypeInfo &&T) {
return llvm::Error::success();
}

template <> llvm::Error addTypeInfo(FieldTypeInfo *I, TypeInfo &&T) {
I->Type = std::move(T.Type);
I->IsTemplate = T.IsTemplate;
I->IsBuiltIn = T.IsBuiltIn;
return llvm::Error::success();
}

template <> llvm::Error addTypeInfo(MemberTypeInfo *I, FieldTypeInfo &&T) {
I->Type = std::move(T.Type);
I->IsTemplate = T.IsTemplate;
I->IsBuiltIn = T.IsBuiltIn;
I->Name = std::move(T.Name);
I->DefaultValue = std::move(T.DefaultValue);
return llvm::Error::success();
}

template <typename T> llvm::Error addReference(T I, Reference &&R, FieldId F) {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid type cannot contain Reference");
Expand Down
42 changes: 29 additions & 13 deletions clang-tools-extra/clang-doc/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,19 @@ static void StringAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
static void LocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
AbbrevGen(
Abbrev,
{// 0. Fixed-size integer (line number)
{// 0. Start fixed-size integer (line number)
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
BitCodeConstants::LineNumberSize),
// 1. Boolean (IsFileInRootDir)
// 1. End fixed-size integer (line number)
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
BitCodeConstants::LineNumberSize),
// 2. Boolean (IsFileInRootDir)
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
BitCodeConstants::BoolSize),
// 2. Fixed-size integer (length of the following string (filename))
// 3. Fixed-size integer (length of the following string (filename))
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
BitCodeConstants::StringLengthSize),
// 3. The string blob
// 4. The string blob
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
}

Expand Down Expand Up @@ -154,6 +157,8 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
{COMMENT_ARG, {"Arg", &StringAbbrev}},
{FIELD_TYPE_NAME, {"Name", &StringAbbrev}},
{FIELD_DEFAULT_VALUE, {"DefaultValue", &StringAbbrev}},
{TYPE_IS_BUILTIN, {"IsBuiltIn", &BoolAbbrev}},
{TYPE_IS_TEMPLATE, {"IsTemplate", &BoolAbbrev}},
{MEMBER_TYPE_NAME, {"Name", &StringAbbrev}},
{MEMBER_TYPE_ACCESS, {"Access", &IntAbbrev}},
{NAMESPACE_USR, {"USR", &SymbolIDAbbrev}},
Expand All @@ -169,6 +174,7 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
{ENUM_VALUE_EXPR, {"Expr", &StringAbbrev}},
{RECORD_USR, {"USR", &SymbolIDAbbrev}},
{RECORD_NAME, {"Name", &StringAbbrev}},
{RECORD_FULLNAME, {"FullName", &StringAbbrev}},
{RECORD_PATH, {"Path", &StringAbbrev}},
{RECORD_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
{RECORD_LOCATION, {"Location", &LocationAbbrev}},
Expand All @@ -187,6 +193,7 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
{FUNCTION_LOCATION, {"Location", &LocationAbbrev}},
{FUNCTION_ACCESS, {"Access", &IntAbbrev}},
{FUNCTION_IS_METHOD, {"IsMethod", &BoolAbbrev}},
{FUNCTION_PROTOTYPE, {"ProtoType", &StringAbbrev}},
{REFERENCE_USR, {"USR", &SymbolIDAbbrev}},
{REFERENCE_NAME, {"Name", &StringAbbrev}},
{REFERENCE_QUAL_NAME, {"QualName", &StringAbbrev}},
Expand All @@ -196,6 +203,7 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
{TEMPLATE_PARAM_CONTENTS, {"Contents", &StringAbbrev}},
{TEMPLATE_SPECIALIZATION_OF, {"SpecializationOf", &SymbolIDAbbrev}},
{TYPEDEF_USR, {"USR", &SymbolIDAbbrev}},
{TYPEDEF_DECLARATION, {"Declaration", &StringAbbrev}},
{TYPEDEF_NAME, {"Name", &StringAbbrev}},
{TYPEDEF_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
{TYPEDEF_IS_USING, {"IsUsing", &BoolAbbrev}}};
Expand All @@ -218,7 +226,7 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
COMMENT_PARAMNAME, COMMENT_CLOSENAME, COMMENT_SELFCLOSING,
COMMENT_EXPLICIT, COMMENT_ATTRKEY, COMMENT_ATTRVAL, COMMENT_ARG}},
// Type Block
{BI_TYPE_BLOCK_ID, {}},
{BI_TYPE_BLOCK_ID, {TYPE_IS_BUILTIN, TYPE_IS_TEMPLATE}},
// FieldType Block
{BI_FIELD_TYPE_BLOCK_ID, {FIELD_TYPE_NAME, FIELD_DEFAULT_VALUE}},
// MemberType Block
Expand All @@ -231,13 +239,14 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
{ENUM_VALUE_NAME, ENUM_VALUE_VALUE, ENUM_VALUE_EXPR}},
// Typedef Block
{BI_TYPEDEF_BLOCK_ID,
{TYPEDEF_USR, TYPEDEF_NAME, TYPEDEF_DEFLOCATION, TYPEDEF_IS_USING}},
{TYPEDEF_USR, TYPEDEF_NAME, TYPEDEF_DECLARATION, TYPEDEF_DEFLOCATION,
TYPEDEF_IS_USING}},
// Namespace Block
{BI_NAMESPACE_BLOCK_ID,
{NAMESPACE_USR, NAMESPACE_NAME, NAMESPACE_PATH}},
// Record Block
{BI_RECORD_BLOCK_ID,
{RECORD_USR, RECORD_NAME, RECORD_PATH, RECORD_DEFLOCATION,
{RECORD_USR, RECORD_NAME, RECORD_FULLNAME, RECORD_PATH, RECORD_DEFLOCATION,
RECORD_LOCATION, RECORD_TAG_TYPE, RECORD_IS_TYPE_DEF}},
// BaseRecord Block
{BI_BASE_RECORD_BLOCK_ID,
Expand All @@ -246,11 +255,11 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
BASE_RECORD_IS_PARENT}},
// Function Block
{BI_FUNCTION_BLOCK_ID,
{FUNCTION_USR, FUNCTION_NAME, FUNCTION_DEFLOCATION, FUNCTION_LOCATION,
FUNCTION_ACCESS, FUNCTION_IS_METHOD}},
{FUNCTION_USR, FUNCTION_PROTOTYPE, FUNCTION_NAME, FUNCTION_DEFLOCATION,
FUNCTION_LOCATION, FUNCTION_ACCESS, FUNCTION_IS_METHOD}},
// Reference Block
{BI_REFERENCE_BLOCK_ID,
{REFERENCE_USR, REFERENCE_NAME, REFERENCE_QUAL_NAME, REFERENCE_TYPE,
{REFERENCE_USR, REFERENCE_NAME, REFERENCE_QUAL_NAME, REFERENCE_TYPE,
REFERENCE_PATH, REFERENCE_FIELD}},
// Template Blocks.
{BI_TEMPLATE_BLOCK_ID, {}},
Expand Down Expand Up @@ -352,7 +361,8 @@ void ClangDocBitcodeWriter::emitRecord(const Location &Loc, RecordId ID) {
if (!prepRecordData(ID, true))
return;
// FIXME: Assert that the line number is of the appropriate size.
Record.push_back(Loc.LineNumber);
Record.push_back(Loc.StartLineNumber);
Record.push_back(Loc.EndLineNumber);
assert(Loc.Filename.size() < (1U << BitCodeConstants::StringLengthSize));
Record.push_back(Loc.IsFileInRootDir);
Record.push_back(Loc.Filename.size());
Expand Down Expand Up @@ -425,6 +435,7 @@ void ClangDocBitcodeWriter::emitBlockInfo(BlockId BID,
void ClangDocBitcodeWriter::emitBlock(const Reference &R, FieldId Field) {
if (R.USR == EmptySID && R.Name.empty())
return;

StreamSubBlockGuard Block(Stream, BI_REFERENCE_BLOCK_ID);
emitRecord(R.USR, REFERENCE_USR);
emitRecord(R.Name, REFERENCE_NAME);
Expand All @@ -437,12 +448,15 @@ void ClangDocBitcodeWriter::emitBlock(const Reference &R, FieldId Field) {
void ClangDocBitcodeWriter::emitBlock(const TypeInfo &T) {
StreamSubBlockGuard Block(Stream, BI_TYPE_BLOCK_ID);
emitBlock(T.Type, FieldId::F_type);
emitRecord(T.IsBuiltIn, TYPE_IS_BUILTIN);
emitRecord(T.IsTemplate, TYPE_IS_TEMPLATE);
}

void ClangDocBitcodeWriter::emitBlock(const TypedefInfo &T) {
StreamSubBlockGuard Block(Stream, BI_TYPEDEF_BLOCK_ID);
emitRecord(T.USR, TYPEDEF_USR);
emitRecord(T.Name, TYPEDEF_NAME);
emitRecord(T.TypeDeclaration, TYPEDEF_DECLARATION);
for (const auto &N : T.Namespace)
emitBlock(N, FieldId::F_namespace);
for (const auto &CI : T.Description)
Expand All @@ -455,14 +469,14 @@ void ClangDocBitcodeWriter::emitBlock(const TypedefInfo &T) {

void ClangDocBitcodeWriter::emitBlock(const FieldTypeInfo &T) {
StreamSubBlockGuard Block(Stream, BI_FIELD_TYPE_BLOCK_ID);
emitBlock(T.Type, FieldId::F_type);
emitBlock(static_cast<TypeInfo>(T));
emitRecord(T.Name, FIELD_TYPE_NAME);
emitRecord(T.DefaultValue, FIELD_DEFAULT_VALUE);
}

void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) {
StreamSubBlockGuard Block(Stream, BI_MEMBER_TYPE_BLOCK_ID);
emitBlock(T.Type, FieldId::F_type);
emitBlock(static_cast<FieldTypeInfo>(T));
emitRecord(T.Name, MEMBER_TYPE_NAME);
emitRecord(T.Access, MEMBER_TYPE_ACCESS);
for (const auto &CI : T.Description)
Expand Down Expand Up @@ -544,6 +558,7 @@ void ClangDocBitcodeWriter::emitBlock(const RecordInfo &I) {
StreamSubBlockGuard Block(Stream, BI_RECORD_BLOCK_ID);
emitRecord(I.USR, RECORD_USR);
emitRecord(I.Name, RECORD_NAME);
emitRecord(I.FullName, RECORD_FULLNAME);
emitRecord(I.Path, RECORD_PATH);
for (const auto &N : I.Namespace)
emitBlock(N, FieldId::F_namespace);
Expand Down Expand Up @@ -593,6 +608,7 @@ void ClangDocBitcodeWriter::emitBlock(const BaseRecordInfo &I) {
void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) {
StreamSubBlockGuard Block(Stream, BI_FUNCTION_BLOCK_ID);
emitRecord(I.USR, FUNCTION_USR);
emitRecord(I.ProtoType, FUNCTION_PROTOTYPE);
emitRecord(I.Name, FUNCTION_NAME);
for (const auto &N : I.Namespace)
emitBlock(N, FieldId::F_namespace);
Expand Down
5 changes: 5 additions & 0 deletions clang-tools-extra/clang-doc/BitcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ enum RecordId {
VERSION = 1,
FUNCTION_USR,
FUNCTION_NAME,
FUNCTION_PROTOTYPE,
FUNCTION_DEFLOCATION,
FUNCTION_LOCATION,
FUNCTION_ACCESS,
Expand All @@ -94,6 +95,8 @@ enum RecordId {
COMMENT_ARG,
FIELD_TYPE_NAME,
FIELD_DEFAULT_VALUE,
TYPE_IS_BUILTIN,
TYPE_IS_TEMPLATE,
MEMBER_TYPE_NAME,
MEMBER_TYPE_ACCESS,
NAMESPACE_USR,
Expand All @@ -109,6 +112,7 @@ enum RecordId {
ENUM_VALUE_EXPR,
RECORD_USR,
RECORD_NAME,
RECORD_FULLNAME,
RECORD_PATH,
RECORD_DEFLOCATION,
RECORD_LOCATION,
Expand All @@ -131,6 +135,7 @@ enum RecordId {
TEMPLATE_SPECIALIZATION_OF,
TYPEDEF_USR,
TYPEDEF_NAME,
TYPEDEF_DECLARATION,
TYPEDEF_DEFLOCATION,
TYPEDEF_IS_USING,
RI_LAST,
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clang-doc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ add_clang_library(clangDoc
Representation.cpp
Serialize.cpp
YAMLGenerator.cpp
HTMLMustacheGenerator.cpp
FileHelpersClangDoc.cpp

DEPENDS
omp_gen
Expand Down
75 changes: 75 additions & 0 deletions clang-tools-extra/clang-doc/FileHelpersClangDoc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//===-- FileHelpersClangDoc.cpp - File Helpers -------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "FileHelpersClangDoc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"

namespace clang {
namespace doc {

llvm::Error
copyFile(llvm::StringRef FilePath, llvm::StringRef OutDirectory) {
llvm::SmallString<128> PathWrite;
llvm::sys::path::native(OutDirectory, PathWrite);
llvm::sys::path::append(PathWrite, llvm::sys::path::filename(FilePath));
llvm::SmallString<128> PathRead;
llvm::sys::path::native(FilePath, PathRead);
std::error_code OK;
std::error_code FileErr = llvm::sys::fs::copy_file(PathRead, PathWrite);
if (FileErr != OK) {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"error creating file " +
llvm::sys::path::filename(FilePath) +
": " + FileErr.message() + "\n");
}
return llvm::Error::success();
}


llvm::SmallString<128> computeRelativePath(llvm::StringRef Destination,
llvm::StringRef Origin) {
// If Origin is empty, the relative path to the Destination is its complete
// path.
if (Origin.empty())
return Destination;

// The relative path is an empty path if both directories are the same.
if (Destination == Origin)
return {};

// These iterators iterate through each of their parent directories
llvm::sys::path::const_iterator FileI = llvm::sys::path::begin(Destination);
llvm::sys::path::const_iterator FileE = llvm::sys::path::end(Destination);
llvm::sys::path::const_iterator DirI = llvm::sys::path::begin(Origin);
llvm::sys::path::const_iterator DirE = llvm::sys::path::end(Origin);
// Advance both iterators until the paths differ. Example:
// Destination = A/B/C/D
// Origin = A/B/E/F
// FileI will point to C and DirI to E. The directories behind them is the
// directory they share (A/B).
while (FileI != FileE && DirI != DirE && *FileI == *DirI) {
++FileI;
++DirI;
}
llvm::SmallString<128> Result; // This will hold the resulting path.
// Result has to go up one directory for each of the remaining directories in
// Origin
while (DirI != DirE) {
llvm::sys::path::append(Result, "..");
++DirI;
}
// Result has to append each of the remaining directories in Destination
while (FileI != FileE) {
llvm::sys::path::append(Result, *FileI);
++FileI;
}
return Result;
}

} // namespace doc
} // namespace clang
26 changes: 26 additions & 0 deletions clang-tools-extra/clang-doc/FileHelpersClangDoc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===-- FileHelpersClangDoc.h --- File Helpers -------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_FILEHELPER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_FILEHELPER_H

#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Error.h"

namespace clang {
namespace doc {

llvm::Error
copyFile(llvm::StringRef FilePath, llvm::StringRef OutDirectory);

llvm::SmallString<128>
computeRelativePath(llvm::StringRef Destination,llvm::StringRef Origin);

} // namespace doc
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_FILEHELPER_H
Loading
Loading