mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 03:50:17 +08:00
[clang-doc] Add start and end line numbers (#137732)
This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This will be used by the mustache backend to generate line ranges. Based on the orginal patch in #135081. Co-author: Paul Kirth <paulkirth@google.com> Co-authored-by: PeterChou1 <peter.chou@mail.utoronto.ca>
This commit is contained in:
@@ -79,7 +79,8 @@ static 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(static_cast<int>(R[0]), Blob, static_cast<bool>(R[1]));
|
||||
Field.emplace(static_cast<int>(R[0]), static_cast<int>(R[1]), Blob,
|
||||
static_cast<bool>(R[2]));
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
@@ -130,7 +131,8 @@ static llvm::Error decodeRecord(const Record &R,
|
||||
if (R[0] > INT_MAX)
|
||||
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
||||
"integer too large to parse");
|
||||
Field.emplace_back(static_cast<int>(R[0]), Blob, static_cast<bool>(R[1]));
|
||||
Field.emplace_back(static_cast<int>(R[0]), static_cast<int>(R[1]), Blob,
|
||||
static_cast<bool>(R[2]));
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,13 +78,16 @@ static void genLocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
|
||||
{// 0. Fixed-size integer (line number)
|
||||
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
|
||||
BitCodeConstants::LineNumberSize),
|
||||
// 1. Boolean (IsFileInRootDir)
|
||||
// 1. Fixed-size integer (start 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)});
|
||||
}
|
||||
|
||||
@@ -357,7 +360,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());
|
||||
|
||||
@@ -455,7 +455,7 @@ static std::unique_ptr<TagNode> writeSourceFileRef(const ClangDocContext &CDCtx,
|
||||
|
||||
if (!L.IsFileInRootDir && !CDCtx.RepositoryUrl)
|
||||
return std::make_unique<TagNode>(
|
||||
HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) +
|
||||
HTMLTag::TAG_P, "Defined at line " + std::to_string(L.StartLineNumber) +
|
||||
" of file " + L.Filename);
|
||||
|
||||
SmallString<128> FileURL(CDCtx.RepositoryUrl.value_or(""));
|
||||
@@ -472,13 +472,14 @@ static std::unique_ptr<TagNode> writeSourceFileRef(const ClangDocContext &CDCtx,
|
||||
llvm::sys::path::Style::windows));
|
||||
auto Node = std::make_unique<TagNode>(HTMLTag::TAG_P);
|
||||
Node->Children.emplace_back(std::make_unique<TextNode>("Defined at line "));
|
||||
auto LocNumberNode =
|
||||
std::make_unique<TagNode>(HTMLTag::TAG_A, std::to_string(L.LineNumber));
|
||||
auto LocNumberNode = std::make_unique<TagNode>(
|
||||
HTMLTag::TAG_A, std::to_string(L.StartLineNumber));
|
||||
// The links to a specific line in the source code use the github /
|
||||
// googlesource notation so it won't work for all hosting pages.
|
||||
LocNumberNode->Attributes.emplace_back(
|
||||
"href", formatv("{0}#{1}{2}", FileURL,
|
||||
CDCtx.RepositoryLinePrefix.value_or(""), L.LineNumber));
|
||||
"href",
|
||||
formatv("{0}#{1}{2}", FileURL, CDCtx.RepositoryLinePrefix.value_or(""),
|
||||
L.StartLineNumber));
|
||||
Node->Children.emplace_back(std::move(LocNumberNode));
|
||||
Node->Children.emplace_back(std::make_unique<TextNode>(" of file "));
|
||||
auto LocFileNode = std::make_unique<TagNode>(
|
||||
|
||||
@@ -56,12 +56,12 @@ static void writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L,
|
||||
raw_ostream &OS) {
|
||||
|
||||
if (!CDCtx.RepositoryUrl) {
|
||||
OS << "*Defined at " << L.Filename << "#" << std::to_string(L.LineNumber)
|
||||
<< "*";
|
||||
OS << "*Defined at " << L.Filename << "#"
|
||||
<< std::to_string(L.StartLineNumber) << "*";
|
||||
} else {
|
||||
|
||||
OS << formatv("*Defined at [#{0}{1}{2}](#{0}{1}{3})*",
|
||||
CDCtx.RepositoryLinePrefix.value_or(""), L.LineNumber,
|
||||
CDCtx.RepositoryLinePrefix.value_or(""), L.StartLineNumber,
|
||||
L.Filename, *CDCtx.RepositoryUrl);
|
||||
}
|
||||
OS << "\n\n";
|
||||
|
||||
@@ -28,6 +28,17 @@ template <typename T> static bool isTypedefAnonRecord(const T *D) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Location MapASTVisitor::getDeclLocation(const NamedDecl *D) const {
|
||||
bool IsFileInRootDir;
|
||||
llvm::SmallString<128> File =
|
||||
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
|
||||
SourceManager &SM = D->getASTContext().getSourceManager();
|
||||
int Start = SM.getPresumedLoc(D->getBeginLoc()).getLine();
|
||||
int End = SM.getPresumedLoc(D->getEndLoc()).getLine();
|
||||
|
||||
return Location(Start, End, File, IsFileInRootDir);
|
||||
}
|
||||
|
||||
void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
|
||||
TraverseDecl(Context.getTranslationUnitDecl());
|
||||
}
|
||||
@@ -59,9 +70,9 @@ bool MapASTVisitor::mapDecl(const T *D, bool IsDefinition) {
|
||||
bool IsFileInRootDir;
|
||||
llvm::SmallString<128> File =
|
||||
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
|
||||
auto [Child, Parent] = serialize::emitInfo(
|
||||
D, getComment(D, D->getASTContext()), getLine(D, D->getASTContext()),
|
||||
File, IsFileInRootDir, CDCtx.PublicOnly);
|
||||
auto [Child, Parent] =
|
||||
serialize::emitInfo(D, getComment(D, D->getASTContext()),
|
||||
getDeclLocation(D), CDCtx.PublicOnly);
|
||||
|
||||
// A null in place of a valid Info indicates that the serializer is skipping
|
||||
// this decl for some reason (e.g. we're only reporting public decls).
|
||||
|
||||
@@ -46,6 +46,9 @@ private:
|
||||
template <typename T> bool mapDecl(const T *D, bool IsDefinition);
|
||||
|
||||
int getLine(const NamedDecl *D, const ASTContext &Context) const;
|
||||
|
||||
Location getDeclLocation(const NamedDecl *D) const;
|
||||
|
||||
llvm::SmallString<128> getFile(const NamedDecl *D, const ASTContext &Context,
|
||||
StringRef RootDir,
|
||||
bool &IsFileInRootDir) const;
|
||||
|
||||
@@ -241,31 +241,29 @@ struct MemberTypeInfo : public FieldTypeInfo {
|
||||
};
|
||||
|
||||
struct Location {
|
||||
Location(int LineNumber = 0, StringRef Filename = StringRef(),
|
||||
bool IsFileInRootDir = false)
|
||||
: LineNumber(LineNumber), Filename(Filename),
|
||||
IsFileInRootDir(IsFileInRootDir) {}
|
||||
Location(int StartLineNumber = 0, int EndLineNumber = 0,
|
||||
StringRef Filename = StringRef(), bool IsFileInRootDir = false)
|
||||
: StartLineNumber(StartLineNumber), EndLineNumber(EndLineNumber),
|
||||
Filename(Filename), IsFileInRootDir(IsFileInRootDir) {}
|
||||
|
||||
bool operator==(const Location &Other) const {
|
||||
return std::tie(LineNumber, Filename) ==
|
||||
std::tie(Other.LineNumber, Other.Filename);
|
||||
return std::tie(StartLineNumber, EndLineNumber, Filename) ==
|
||||
std::tie(Other.StartLineNumber, Other.EndLineNumber, Other.Filename);
|
||||
}
|
||||
|
||||
bool operator!=(const Location &Other) const {
|
||||
return std::tie(LineNumber, Filename) !=
|
||||
std::tie(Other.LineNumber, Other.Filename);
|
||||
}
|
||||
bool operator!=(const Location &Other) const { return !(*this == Other); }
|
||||
|
||||
// This operator is used to sort a vector of Locations.
|
||||
// No specific order (attributes more important than others) is required. Any
|
||||
// sort is enough, the order is only needed to call std::unique after sorting
|
||||
// the vector.
|
||||
bool operator<(const Location &Other) const {
|
||||
return std::tie(LineNumber, Filename) <
|
||||
std::tie(Other.LineNumber, Other.Filename);
|
||||
return std::tie(StartLineNumber, EndLineNumber, Filename) <
|
||||
std::tie(Other.StartLineNumber, Other.EndLineNumber, Other.Filename);
|
||||
}
|
||||
|
||||
int LineNumber = 0; // Line number of this Location.
|
||||
int StartLineNumber = 0; // Line number of this Location.
|
||||
int EndLineNumber = 0;
|
||||
SmallString<32> Filename; // File for this Location.
|
||||
bool IsFileInRootDir = false; // Indicates if file is inside root directory
|
||||
};
|
||||
|
||||
@@ -535,22 +535,18 @@ static void populateInfo(Info &I, const T *D, const FullComment *C,
|
||||
|
||||
template <typename T>
|
||||
static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
|
||||
int LineNumber, StringRef Filename,
|
||||
bool IsFileInRootDir,
|
||||
bool &IsInAnonymousNamespace) {
|
||||
Location Loc, bool &IsInAnonymousNamespace) {
|
||||
populateInfo(I, D, C, IsInAnonymousNamespace);
|
||||
if (D->isThisDeclarationADefinition())
|
||||
I.DefLoc.emplace(LineNumber, Filename, IsFileInRootDir);
|
||||
I.DefLoc = Loc;
|
||||
else
|
||||
I.Loc.emplace_back(LineNumber, Filename, IsFileInRootDir);
|
||||
I.Loc.emplace_back(Loc);
|
||||
}
|
||||
|
||||
static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
|
||||
const FullComment *FC, int LineNumber,
|
||||
StringRef Filename, bool IsFileInRootDir,
|
||||
const FullComment *FC, Location Loc,
|
||||
bool &IsInAnonymousNamespace) {
|
||||
populateSymbolInfo(I, D, FC, LineNumber, Filename, IsFileInRootDir,
|
||||
IsInAnonymousNamespace);
|
||||
populateSymbolInfo(I, D, FC, Loc, IsInAnonymousNamespace);
|
||||
auto &LO = D->getLangOpts();
|
||||
I.ReturnType = getTypeInfoForType(D->getReturnType(), LO);
|
||||
parseParameters(I, D);
|
||||
@@ -579,7 +575,7 @@ static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
|
||||
static void populateMemberTypeInfo(MemberTypeInfo &I, const Decl *D) {
|
||||
assert(D && "Expect non-null FieldDecl in populateMemberTypeInfo");
|
||||
|
||||
ASTContext& Context = D->getASTContext();
|
||||
ASTContext &Context = D->getASTContext();
|
||||
// TODO investigate whether we can use ASTContext::getCommentForDecl instead
|
||||
// of this logic. See also similar code in Mapper.cpp.
|
||||
RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
|
||||
@@ -643,8 +639,7 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
|
||||
// reference, its value is not relevant in here so it's not used
|
||||
// anywhere besides the function call.
|
||||
bool IsInAnonymousNamespace;
|
||||
populateFunctionInfo(FI, MD, /*FullComment=*/{}, /*LineNumber=*/{},
|
||||
/*FileName=*/{}, IsFileInRootDir,
|
||||
populateFunctionInfo(FI, MD, /*FullComment=*/{}, /*Location=*/{},
|
||||
IsInAnonymousNamespace);
|
||||
FI.Access =
|
||||
getFinalAccessSpecifier(BI.Access, MD->getAccessUnsafe());
|
||||
@@ -662,8 +657,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
|
||||
llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
|
||||
emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly) {
|
||||
auto NSI = std::make_unique<NamespaceInfo>();
|
||||
bool IsInAnonymousNamespace = false;
|
||||
populateInfo(*NSI, D, FC, IsInAnonymousNamespace);
|
||||
@@ -683,12 +678,11 @@ emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
|
||||
llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
|
||||
emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly) {
|
||||
auto RI = std::make_unique<RecordInfo>();
|
||||
bool IsInAnonymousNamespace = false;
|
||||
populateSymbolInfo(*RI, D, FC, LineNumber, File, IsFileInRootDir,
|
||||
IsInAnonymousNamespace);
|
||||
populateSymbolInfo(*RI, D, FC, Loc, IsInAnonymousNamespace);
|
||||
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
|
||||
return {};
|
||||
|
||||
@@ -701,7 +695,7 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
|
||||
}
|
||||
// TODO: remove first call to parseBases, that function should be deleted
|
||||
parseBases(*RI, C);
|
||||
parseBases(*RI, C, IsFileInRootDir, PublicOnly, true);
|
||||
parseBases(*RI, C, /*IsFileInRootDir=*/true, PublicOnly, /*IsParent=*/true);
|
||||
}
|
||||
RI->Path = getInfoRelativePath(RI->Namespace);
|
||||
|
||||
@@ -750,12 +744,11 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
|
||||
llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
|
||||
emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly) {
|
||||
FunctionInfo Func;
|
||||
bool IsInAnonymousNamespace = false;
|
||||
populateFunctionInfo(Func, D, FC, LineNumber, File, IsFileInRootDir,
|
||||
IsInAnonymousNamespace);
|
||||
populateFunctionInfo(Func, D, FC, Loc, IsInAnonymousNamespace);
|
||||
Func.Access = clang::AccessSpecifier::AS_none;
|
||||
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
|
||||
return {};
|
||||
@@ -765,12 +758,11 @@ emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
|
||||
llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
|
||||
emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly) {
|
||||
FunctionInfo Func;
|
||||
bool IsInAnonymousNamespace = false;
|
||||
populateFunctionInfo(Func, D, FC, LineNumber, File, IsFileInRootDir,
|
||||
IsInAnonymousNamespace);
|
||||
populateFunctionInfo(Func, D, FC, Loc, IsInAnonymousNamespace);
|
||||
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
|
||||
return {};
|
||||
|
||||
@@ -795,16 +787,15 @@ emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly) {
|
||||
emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly) {
|
||||
TypedefInfo Info;
|
||||
|
||||
bool IsInAnonymousNamespace = false;
|
||||
populateInfo(Info, D, FC, IsInAnonymousNamespace);
|
||||
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
|
||||
return {};
|
||||
|
||||
Info.DefLoc.emplace(LineNumber, File, IsFileInRootDir);
|
||||
Info.DefLoc = Loc;
|
||||
auto &LO = D->getLangOpts();
|
||||
Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
|
||||
if (Info.Underlying.Type.Name.empty()) {
|
||||
@@ -822,8 +813,8 @@ emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
|
||||
// A type alias is a C++ "using" declaration for a type. It gets mapped to a
|
||||
// TypedefInfo with the IsUsing flag set.
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly) {
|
||||
emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly) {
|
||||
TypedefInfo Info;
|
||||
|
||||
bool IsInAnonymousNamespace = false;
|
||||
@@ -831,7 +822,7 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
|
||||
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
|
||||
return {};
|
||||
|
||||
Info.DefLoc.emplace(LineNumber, File, IsFileInRootDir);
|
||||
Info.DefLoc = Loc;
|
||||
auto &LO = D->getLangOpts();
|
||||
Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
|
||||
Info.IsUsing = true;
|
||||
@@ -841,12 +832,12 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const EnumDecl *D, const FullComment *FC, int LineNumber,
|
||||
llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
|
||||
emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly) {
|
||||
EnumInfo Enum;
|
||||
bool IsInAnonymousNamespace = false;
|
||||
populateSymbolInfo(Enum, D, FC, LineNumber, File, IsFileInRootDir,
|
||||
IsInAnonymousNamespace);
|
||||
populateSymbolInfo(Enum, D, FC, Loc, IsInAnonymousNamespace);
|
||||
|
||||
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
|
||||
return {};
|
||||
|
||||
|
||||
@@ -37,36 +37,36 @@ namespace serialize {
|
||||
// its parent scope. For NamespaceDecl and RecordDecl both elements are not
|
||||
// nullptr.
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly);
|
||||
emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly);
|
||||
emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const EnumDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly);
|
||||
emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly);
|
||||
emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const VarDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly);
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly);
|
||||
emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly);
|
||||
emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
|
||||
StringRef File, bool IsFileInRootDir, bool PublicOnly);
|
||||
emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
// Function to hash a given USR value for storage.
|
||||
// As USRs (Unified Symbol Resolution) could be large, especially for functions
|
||||
|
||||
@@ -169,7 +169,7 @@ static void commentInfoMapping(IO &IO, CommentInfo &I) {
|
||||
|
||||
template <> struct MappingTraits<Location> {
|
||||
static void mapping(IO &IO, Location &Loc) {
|
||||
IO.mapOptional("LineNumber", Loc.LineNumber, 0);
|
||||
IO.mapOptional("LineNumber", Loc.StartLineNumber, 0);
|
||||
IO.mapOptional("Filename", Loc.Filename, SmallString<32>());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ template <typename T> static std::string writeInfo(T &I) {
|
||||
return Buffer.str().str();
|
||||
}
|
||||
|
||||
std::string writeInfo(Info *I) {
|
||||
static std::string writeInfo(Info *I) {
|
||||
switch (I->IT) {
|
||||
case InfoType::IT_namespace:
|
||||
return writeInfo(*static_cast<NamespaceInfo *>(I));
|
||||
@@ -42,8 +42,8 @@ std::string writeInfo(Info *I) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Info>> readInfo(StringRef Bitcode,
|
||||
size_t NumInfos) {
|
||||
static std::vector<std::unique_ptr<Info>> readInfo(StringRef Bitcode,
|
||||
size_t NumInfos) {
|
||||
llvm::BitstreamCursor Stream(Bitcode);
|
||||
doc::ClangDocBitcodeReader Reader(Stream);
|
||||
auto Infos = Reader.readBitcode();
|
||||
@@ -77,8 +77,8 @@ TEST(BitcodeTest, emitRecordInfoBitcode) {
|
||||
I.Name = "r";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
|
||||
I.TagType = TagTypeKind::Class;
|
||||
@@ -119,8 +119,8 @@ TEST(BitcodeTest, emitFunctionInfoBitcode) {
|
||||
I.Name = "f";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.ReturnType = TypeInfo("void");
|
||||
I.Params.emplace_back(TypeInfo("int"), "P");
|
||||
@@ -139,8 +139,8 @@ TEST(BitcodeTest, emitMethodInfoBitcode) {
|
||||
I.Name = "f";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.ReturnType = TypeInfo("void");
|
||||
I.Params.emplace_back(TypeInfo("int"), "P");
|
||||
@@ -161,8 +161,8 @@ TEST(BitcodeTest, emitEnumInfoBitcode) {
|
||||
I.Name = "e";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Members.emplace_back("X");
|
||||
I.Scoped = true;
|
||||
@@ -179,7 +179,7 @@ TEST(BitcodeTest, emitTypedefInfoBitcode) {
|
||||
I.Name = "MyInt";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Underlying = TypeInfo("unsigned");
|
||||
I.IsUsing = true;
|
||||
|
||||
@@ -216,7 +216,7 @@ TEST(SerializeTest, emitInfoWithCommentBitcode) {
|
||||
FunctionInfo F;
|
||||
F.Name = "F";
|
||||
F.ReturnType = TypeInfo("void");
|
||||
F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
F.DefLoc = Location(0, 0, "test.cpp");
|
||||
F.Params.emplace_back(TypeInfo("int"), "I");
|
||||
|
||||
CommentInfo Top;
|
||||
|
||||
@@ -118,7 +118,9 @@ void CheckSymbolInfo(SymbolInfo *Expected, SymbolInfo *Actual) {
|
||||
CheckBaseInfo(Expected, Actual);
|
||||
EXPECT_EQ(Expected->DefLoc.has_value(), Actual->DefLoc.has_value());
|
||||
if (Expected->DefLoc && Actual->DefLoc.has_value()) {
|
||||
EXPECT_EQ(Expected->DefLoc->LineNumber, Actual->DefLoc->LineNumber);
|
||||
EXPECT_EQ(Expected->DefLoc->StartLineNumber,
|
||||
Actual->DefLoc->StartLineNumber);
|
||||
EXPECT_EQ(Expected->DefLoc->EndLineNumber, Actual->DefLoc->EndLineNumber);
|
||||
EXPECT_EQ(Expected->DefLoc->Filename, Actual->DefLoc->Filename);
|
||||
}
|
||||
ASSERT_EQ(Expected->Loc.size(), Actual->Loc.size());
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "ClangDocTest.h"
|
||||
#include "Generators.h"
|
||||
#include "Representation.h"
|
||||
#include "Serialize.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@@ -19,14 +18,14 @@ namespace doc {
|
||||
static const std::string ClangDocVersion =
|
||||
clang::getClangToolFullVersion("clang-doc");
|
||||
|
||||
std::unique_ptr<Generator> getHTMLGenerator() {
|
||||
static std::unique_ptr<Generator> getHTMLGenerator() {
|
||||
auto G = doc::findGeneratorByName("html");
|
||||
if (!G)
|
||||
return nullptr;
|
||||
return std::move(G.get());
|
||||
}
|
||||
|
||||
ClangDocContext
|
||||
static ClangDocContext
|
||||
getClangDocContext(std::vector<std::string> UserStylesheets = {},
|
||||
StringRef RepositoryUrl = "",
|
||||
StringRef RepositoryLinePrefix = "", StringRef Base = "") {
|
||||
@@ -157,8 +156,8 @@ TEST(HTMLGeneratorTest, emitRecordHTML) {
|
||||
I.Path = "X/Y/Z";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"dir/test.cpp"}, true);
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "dir/test.cpp", true);
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
SmallString<16> PathTo;
|
||||
llvm::sys::path::native("path/to", PathTo);
|
||||
@@ -284,8 +283,8 @@ TEST(HTMLGeneratorTest, emitFunctionHTML) {
|
||||
I.Name = "f";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"dir/test.cpp"}, false);
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "dir/test.cpp", true);
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Access = AccessSpecifier::AS_none;
|
||||
|
||||
@@ -344,8 +343,8 @@ TEST(HTMLGeneratorTest, emitEnumHTML) {
|
||||
I.Name = "e";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"}, true);
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp", true);
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Members.emplace_back("X");
|
||||
I.Scoped = true;
|
||||
@@ -401,7 +400,7 @@ TEST(HTMLGeneratorTest, emitEnumHTML) {
|
||||
TEST(HTMLGeneratorTest, emitCommentHTML) {
|
||||
FunctionInfo I;
|
||||
I.Name = "f";
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp", true);
|
||||
I.ReturnType = TypeInfo("void");
|
||||
I.Params.emplace_back(TypeInfo("int"), "I");
|
||||
I.Params.emplace_back(TypeInfo("int"), "J");
|
||||
@@ -464,7 +463,12 @@ TEST(HTMLGeneratorTest, emitCommentHTML) {
|
||||
<div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
|
||||
<h3 id="0000000000000000000000000000000000000000">f</h3>
|
||||
<p>void f(int I, int J)</p>
|
||||
<p>Defined at line 10 of file test.cpp</p>
|
||||
<p>
|
||||
Defined at line
|
||||
<a href="test.cpp#10">10</a>
|
||||
of file
|
||||
<a href="test.cpp">test.cpp</a>
|
||||
</p>
|
||||
<div>
|
||||
<div>
|
||||
<p> Brief description.</p>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace clang {
|
||||
namespace doc {
|
||||
|
||||
std::unique_ptr<Generator> getMDGenerator() {
|
||||
static std::unique_ptr<Generator> getMDGenerator() {
|
||||
auto G = doc::findGeneratorByName("md");
|
||||
if (!G)
|
||||
return nullptr;
|
||||
@@ -82,8 +82,8 @@ TEST(MDGeneratorTest, emitRecordMD) {
|
||||
I.Name = "r";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
|
||||
I.TagType = TagTypeKind::Class;
|
||||
@@ -149,8 +149,8 @@ TEST(MDGeneratorTest, emitFunctionMD) {
|
||||
I.Name = "f";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Access = AccessSpecifier::AS_none;
|
||||
|
||||
@@ -181,8 +181,8 @@ TEST(MDGeneratorTest, emitEnumMD) {
|
||||
I.Name = "e";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Members.emplace_back("X");
|
||||
I.Scoped = true;
|
||||
@@ -210,7 +210,8 @@ TEST(MDGeneratorTest, emitEnumMD) {
|
||||
TEST(MDGeneratorTest, emitCommentMD) {
|
||||
FunctionInfo I;
|
||||
I.Name = "f";
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.ReturnType = TypeInfo("void");
|
||||
I.Params.emplace_back(TypeInfo("int"), "I");
|
||||
I.Params.emplace_back(TypeInfo("int"), "J");
|
||||
|
||||
@@ -81,7 +81,7 @@ TEST(MergeTest, mergeRecordInfos) {
|
||||
One.IsTypeDef = true;
|
||||
One.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
One.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
One.DefLoc = Location(10, 10, "test.cpp");
|
||||
|
||||
One.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
|
||||
One.TagType = TagTypeKind::Class;
|
||||
@@ -103,7 +103,7 @@ TEST(MergeTest, mergeRecordInfos) {
|
||||
Two.Name = "r";
|
||||
Two.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
Two.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
Two.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
Two.TagType = TagTypeKind::Class;
|
||||
|
||||
@@ -123,8 +123,8 @@ TEST(MergeTest, mergeRecordInfos) {
|
||||
Expected->IsTypeDef = true;
|
||||
Expected->Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
Expected->DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
Expected->Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
Expected->DefLoc = Location(10, 10, "test.cpp");
|
||||
Expected->Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
Expected->Members.emplace_back(TypeInfo("int"), "X",
|
||||
AccessSpecifier::AS_private);
|
||||
@@ -158,14 +158,14 @@ TEST(MergeTest, mergeFunctionInfos) {
|
||||
One.Name = "f";
|
||||
One.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
One.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
One.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
One.DefLoc = Location(10, 10, "test.cpp");
|
||||
One.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
One.IsMethod = true;
|
||||
One.Parent = Reference(EmptySID, "Parent", InfoType::IT_namespace);
|
||||
|
||||
One.Description.emplace_back();
|
||||
auto OneFullComment = &One.Description.back();
|
||||
auto *OneFullComment = &One.Description.back();
|
||||
OneFullComment->Kind = "FullComment";
|
||||
auto OneParagraphComment = std::make_unique<CommentInfo>();
|
||||
OneParagraphComment->Kind = "ParagraphComment";
|
||||
@@ -179,13 +179,13 @@ TEST(MergeTest, mergeFunctionInfos) {
|
||||
Two.Name = "f";
|
||||
Two.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
Two.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
Two.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
Two.ReturnType = TypeInfo("void");
|
||||
Two.Params.emplace_back(TypeInfo("int"), "P");
|
||||
|
||||
Two.Description.emplace_back();
|
||||
auto TwoFullComment = &Two.Description.back();
|
||||
auto *TwoFullComment = &Two.Description.back();
|
||||
TwoFullComment->Kind = "FullComment";
|
||||
auto TwoParagraphComment = std::make_unique<CommentInfo>();
|
||||
TwoParagraphComment->Kind = "ParagraphComment";
|
||||
@@ -203,8 +203,8 @@ TEST(MergeTest, mergeFunctionInfos) {
|
||||
Expected->Name = "f";
|
||||
Expected->Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
Expected->DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
Expected->Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
Expected->DefLoc = Location(10, 10, "test.cpp");
|
||||
Expected->Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
Expected->ReturnType = TypeInfo("void");
|
||||
Expected->Params.emplace_back(TypeInfo("int"), "P");
|
||||
@@ -212,7 +212,7 @@ TEST(MergeTest, mergeFunctionInfos) {
|
||||
Expected->Parent = Reference(EmptySID, "Parent", InfoType::IT_namespace);
|
||||
|
||||
Expected->Description.emplace_back();
|
||||
auto ExpectedFullComment = &Expected->Description.back();
|
||||
auto *ExpectedFullComment = &Expected->Description.back();
|
||||
ExpectedFullComment->Kind = "FullComment";
|
||||
auto ExpectedParagraphComment = std::make_unique<CommentInfo>();
|
||||
ExpectedParagraphComment->Kind = "ParagraphComment";
|
||||
@@ -233,8 +233,8 @@ TEST(MergeTest, mergeEnumInfos) {
|
||||
One.Name = "e";
|
||||
One.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
One.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
One.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
One.DefLoc = Location(10, 10, "test.cpp");
|
||||
One.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
One.Scoped = true;
|
||||
|
||||
@@ -242,7 +242,7 @@ TEST(MergeTest, mergeEnumInfos) {
|
||||
Two.Name = "e";
|
||||
Two.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
Two.Loc.emplace_back(20, llvm::SmallString<16>{"test.cpp"});
|
||||
Two.Loc.emplace_back(20, 20, "test.cpp");
|
||||
|
||||
Two.Members.emplace_back("X");
|
||||
Two.Members.emplace_back("Y");
|
||||
@@ -255,9 +255,9 @@ TEST(MergeTest, mergeEnumInfos) {
|
||||
Expected->Name = "e";
|
||||
Expected->Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
Expected->DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
Expected->Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
Expected->Loc.emplace_back(20, llvm::SmallString<16>{"test.cpp"});
|
||||
Expected->DefLoc = Location(10, 10, "test.cpp");
|
||||
Expected->Loc.emplace_back(12, 12, "test.cpp");
|
||||
Expected->Loc.emplace_back(20, 20, "test.cpp");
|
||||
|
||||
Expected->Members.emplace_back("X");
|
||||
Expected->Members.emplace_back("Y");
|
||||
|
||||
@@ -36,12 +36,12 @@ public:
|
||||
: EmittedInfos(EmittedInfos), Public(Public) {}
|
||||
|
||||
template <typename T> bool mapDecl(const T *D) {
|
||||
auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0,
|
||||
/*File=*/"test.cpp", true, Public);
|
||||
if (I.first)
|
||||
EmittedInfos.emplace_back(std::move(I.first));
|
||||
if (I.second)
|
||||
EmittedInfos.emplace_back(std::move(I.second));
|
||||
Location Loc(0, 0, "test.cpp");
|
||||
auto [Child, Parent] = serialize::emitInfo(D, getComment(D), Loc, Public);
|
||||
if (Child)
|
||||
EmittedInfos.emplace_back(std::move(Child));
|
||||
if (Parent)
|
||||
EmittedInfos.emplace_back(std::move(Parent));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ TEST(SerializeTest, emitNamespaceInfo) {
|
||||
FunctionInfo F;
|
||||
F.Name = "f";
|
||||
F.ReturnType = TypeInfo("void");
|
||||
F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
F.DefLoc = Location(0, 0, "test.cpp");
|
||||
F.Namespace.emplace_back(EmptySID, "B", InfoType::IT_namespace);
|
||||
F.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
F.Access = AccessSpecifier::AS_none;
|
||||
@@ -168,7 +168,7 @@ typedef struct {} G;)raw",
|
||||
ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedE.TagType = TagTypeKind::Class;
|
||||
ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedE.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedE.Members.emplace_back(TypeInfo("int"), "value",
|
||||
AccessSpecifier::AS_public);
|
||||
// TODO the data member should have the docstring on it:
|
||||
@@ -181,7 +181,7 @@ typedef struct {} G;)raw",
|
||||
EConstructor.Name = "E";
|
||||
EConstructor.Parent = Reference(EmptySID, "E", InfoType::IT_record);
|
||||
EConstructor.ReturnType = TypeInfo("void");
|
||||
EConstructor.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
EConstructor.DefLoc = Location(0, 0, "test.cpp");
|
||||
EConstructor.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record);
|
||||
EConstructor.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
@@ -197,7 +197,7 @@ typedef struct {} G;)raw",
|
||||
Method.Name = "ProtectedMethod";
|
||||
Method.Parent = Reference(EmptySID, "E", InfoType::IT_record);
|
||||
Method.ReturnType = TypeInfo("void");
|
||||
Method.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"});
|
||||
Method.Loc.emplace_back(0, 0, "test.cpp");
|
||||
Method.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record);
|
||||
Method.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
@@ -211,7 +211,7 @@ typedef struct {} G;)raw",
|
||||
ExpectedF.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedF.TagType = TagTypeKind::Struct;
|
||||
ExpectedF.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedF.DefLoc = Location(0, 0, "test.cpp");
|
||||
CheckRecordInfo(&ExpectedF, F);
|
||||
|
||||
RecordInfo *RecordWithTemplateMethod = InfoAsRecord(Infos[6].get());
|
||||
@@ -220,7 +220,7 @@ typedef struct {} G;)raw",
|
||||
TemplateMethod.Name = "TemplateMethod";
|
||||
TemplateMethod.Parent = Reference(EmptySID, "F", InfoType::IT_record);
|
||||
TemplateMethod.ReturnType = TypeInfo("void");
|
||||
TemplateMethod.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"});
|
||||
TemplateMethod.Loc.emplace_back(0, 0, "test.cpp");
|
||||
TemplateMethod.Namespace.emplace_back(EmptySID, "F", InfoType::IT_record);
|
||||
TemplateMethod.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
@@ -237,8 +237,7 @@ typedef struct {} G;)raw",
|
||||
SpecializedTemplateMethod.Parent =
|
||||
Reference(EmptySID, "F", InfoType::IT_record);
|
||||
SpecializedTemplateMethod.ReturnType = TypeInfo("void");
|
||||
SpecializedTemplateMethod.Loc.emplace_back(0,
|
||||
llvm::SmallString<16>{"test.cpp"});
|
||||
SpecializedTemplateMethod.Loc.emplace_back(0, 0, "test.cpp");
|
||||
SpecializedTemplateMethod.Namespace.emplace_back(EmptySID, "F",
|
||||
InfoType::IT_record);
|
||||
SpecializedTemplateMethod.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
@@ -254,7 +253,7 @@ typedef struct {} G;)raw",
|
||||
ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedG.TagType = TagTypeKind::Struct;
|
||||
ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedG.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedG.IsTypeDef = true;
|
||||
CheckRecordInfo(&ExpectedG, G);
|
||||
}
|
||||
@@ -269,7 +268,7 @@ TEST(SerializeTest, emitEnumInfo) {
|
||||
NamespaceInfo ExpectedNamespaceWithEnum(EmptySID);
|
||||
EnumInfo E;
|
||||
E.Name = "E";
|
||||
E.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
E.DefLoc = Location(0, 0, "test.cpp");
|
||||
E.Members.emplace_back("X", "0");
|
||||
E.Members.emplace_back("Y", "1");
|
||||
ExpectedNamespaceWithEnum.Children.Enums.emplace_back(std::move(E));
|
||||
@@ -280,7 +279,7 @@ TEST(SerializeTest, emitEnumInfo) {
|
||||
EnumInfo G;
|
||||
G.Name = "G";
|
||||
G.Scoped = true;
|
||||
G.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
G.DefLoc = Location(0, 0, "test.cpp");
|
||||
G.Members.emplace_back("A", "0");
|
||||
G.Members.emplace_back("B", "1");
|
||||
ExpectedNamespaceWithScopedEnum.Children.Enums.emplace_back(std::move(G));
|
||||
@@ -296,7 +295,7 @@ TEST(SerializeTest, emitUndefinedRecordInfo) {
|
||||
ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedE.TagType = TagTypeKind::Class;
|
||||
ExpectedE.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedE.Loc.emplace_back(0, 0, "test.cpp");
|
||||
CheckRecordInfo(&ExpectedE, E);
|
||||
}
|
||||
|
||||
@@ -309,7 +308,7 @@ TEST(SerializeTest, emitRecordMemberInfo) {
|
||||
ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedE.TagType = TagTypeKind::Struct;
|
||||
ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedE.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedE.Members.emplace_back(TypeInfo("int"), "I",
|
||||
AccessSpecifier::AS_public);
|
||||
CheckRecordInfo(&ExpectedE, E);
|
||||
@@ -323,7 +322,7 @@ TEST(SerializeTest, emitInternalRecordInfo) {
|
||||
RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace");
|
||||
ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedE.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedE.TagType = TagTypeKind::Class;
|
||||
CheckRecordInfo(&ExpectedE, E);
|
||||
|
||||
@@ -331,7 +330,7 @@ TEST(SerializeTest, emitInternalRecordInfo) {
|
||||
llvm::SmallString<128> ExpectedGPath("GlobalNamespace/E");
|
||||
llvm::sys::path::native(ExpectedGPath);
|
||||
RecordInfo ExpectedG(EmptySID, /*Name=*/"G", /*Path=*/ExpectedGPath);
|
||||
ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedG.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedG.TagType = TagTypeKind::Class;
|
||||
ExpectedG.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record);
|
||||
ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
@@ -354,7 +353,7 @@ TEST(SerializeTest, emitPublicFunctionInternalInfo) {
|
||||
FunctionInfo F;
|
||||
F.Name = "F";
|
||||
F.ReturnType = TypeInfo("int");
|
||||
F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
F.DefLoc = Location(0, 0, "test.cpp");
|
||||
F.Access = AccessSpecifier::AS_none;
|
||||
ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F));
|
||||
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
|
||||
@@ -369,7 +368,7 @@ TEST(SerializeTest, emitInlinedFunctionInfo) {
|
||||
FunctionInfo F;
|
||||
F.Name = "F";
|
||||
F.ReturnType = TypeInfo("void");
|
||||
F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
F.DefLoc = Location(0, 0, "test.cpp");
|
||||
F.Params.emplace_back(TypeInfo("int"), "I");
|
||||
F.Access = AccessSpecifier::AS_none;
|
||||
ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F));
|
||||
@@ -392,7 +391,7 @@ class J : public I<int> {} ;)raw",
|
||||
ExpectedF.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace, "");
|
||||
ExpectedF.TagType = TagTypeKind::Class;
|
||||
ExpectedF.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedF.DefLoc = Location(0, 0, "test.cpp");
|
||||
CheckRecordInfo(&ExpectedF, F);
|
||||
|
||||
RecordInfo *G = InfoAsRecord(Infos[3].get());
|
||||
@@ -400,7 +399,7 @@ class J : public I<int> {} ;)raw",
|
||||
ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedG.TagType = TagTypeKind::Class;
|
||||
ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedG.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedG.Members.emplace_back(TypeInfo("int"), "I",
|
||||
AccessSpecifier::AS_protected);
|
||||
CheckRecordInfo(&ExpectedG, G);
|
||||
@@ -445,7 +444,7 @@ class J : public I<int> {} ;)raw",
|
||||
std::move(FunctionGet));
|
||||
ExpectedE.Bases.back().Members.emplace_back(TypeInfo("int"), "I",
|
||||
AccessSpecifier::AS_private);
|
||||
ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedE.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedE.TagType = TagTypeKind::Class;
|
||||
CheckRecordInfo(&ExpectedE, E);
|
||||
|
||||
@@ -454,7 +453,7 @@ class J : public I<int> {} ;)raw",
|
||||
ExpectedH.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedH.TagType = TagTypeKind::Class;
|
||||
ExpectedH.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedH.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedH.Parents.emplace_back(EmptySID, /*Name=*/"E", InfoType::IT_record,
|
||||
/*QualName=*/"E", /*Path=*/"GlobalNamespace");
|
||||
ExpectedH.VirtualParents.emplace_back(EmptySID, /*Name=*/"G",
|
||||
@@ -501,7 +500,7 @@ class J : public I<int> {} ;)raw",
|
||||
ExpectedI.Namespace.emplace_back(EmptySID, "GlobalNamespace",
|
||||
InfoType::IT_namespace);
|
||||
ExpectedI.TagType = TagTypeKind::Class;
|
||||
ExpectedI.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedI.DefLoc = Location(0, 0, "test.cpp");
|
||||
CheckRecordInfo(&ExpectedI, I);
|
||||
|
||||
RecordInfo *J = InfoAsRecord(Infos[12].get());
|
||||
@@ -513,7 +512,7 @@ class J : public I<int> {} ;)raw",
|
||||
ExpectedJ.Bases.emplace_back(EmptySID, /*Name=*/"I<int>",
|
||||
/*Path=*/"GlobalNamespace", false,
|
||||
AccessSpecifier::AS_public, true);
|
||||
ExpectedJ.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExpectedJ.DefLoc = Location(0, 0, "test.cpp");
|
||||
ExpectedJ.TagType = TagTypeKind::Class;
|
||||
CheckRecordInfo(&ExpectedJ, J);
|
||||
}
|
||||
@@ -533,7 +532,7 @@ export double exportedModuleFunction(double y);)raw",
|
||||
FunctionInfo F;
|
||||
F.Name = "moduleFunction";
|
||||
F.ReturnType = TypeInfo("int");
|
||||
F.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"});
|
||||
F.Loc.emplace_back(0, 0, "test.cpp");
|
||||
F.Params.emplace_back(TypeInfo("int"), "x");
|
||||
F.Params.emplace_back(TypeInfo("double"), "d");
|
||||
F.Params.back().DefaultValue = "3.2 - 1.0";
|
||||
@@ -547,7 +546,7 @@ export double exportedModuleFunction(double y);)raw",
|
||||
ExportedF.Name = "exportedModuleFunction";
|
||||
ExportedF.ReturnType =
|
||||
TypeInfo(Reference(EmptySID, "double", InfoType::IT_default));
|
||||
ExportedF.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"});
|
||||
ExportedF.Loc.emplace_back(0, 0, "test.cpp");
|
||||
ExportedF.Params.emplace_back(TypeInfo("double"), "y");
|
||||
ExportedF.Access = AccessSpecifier::AS_none;
|
||||
ExpectedBWithExportedFunction.Children.Functions.emplace_back(
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
namespace clang {
|
||||
namespace doc {
|
||||
|
||||
std::unique_ptr<Generator> getYAMLGenerator() {
|
||||
static std::unique_ptr<Generator> getYAMLGenerator() {
|
||||
auto G = doc::findGeneratorByName("yaml");
|
||||
if (!G)
|
||||
return nullptr;
|
||||
@@ -84,8 +84,8 @@ TEST(YAMLGeneratorTest, emitRecordYAML) {
|
||||
I.IsTypeDef = true;
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
|
||||
|
||||
@@ -207,8 +207,8 @@ TEST(YAMLGeneratorTest, emitFunctionYAML) {
|
||||
I.Name = "f";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Access = AccessSpecifier::AS_none;
|
||||
|
||||
@@ -272,8 +272,8 @@ TEST(YAMLGeneratorTest, emitSimpleEnumYAML) {
|
||||
I.Name = "e";
|
||||
I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
|
||||
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.Loc.emplace_back(12, 12, "test.cpp");
|
||||
|
||||
I.Members.emplace_back("X");
|
||||
I.Scoped = false;
|
||||
@@ -368,7 +368,7 @@ IsUsing: true
|
||||
TEST(YAMLGeneratorTest, emitCommentYAML) {
|
||||
FunctionInfo I;
|
||||
I.Name = "f";
|
||||
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.ReturnType = TypeInfo("void");
|
||||
I.Params.emplace_back(TypeInfo("int"), "I");
|
||||
I.Params.emplace_back(TypeInfo("int"), "J");
|
||||
|
||||
Reference in New Issue
Block a user