Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 40 additions & 0 deletions clang-tools-extra/clang-doc/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ static llvm::Error decodeRecord(const Record &R, InfoType &Field,
case InfoType::IT_enum:
case InfoType::IT_typedef:
case InfoType::IT_concept:
case InfoType::IT_variable:
Field = IT;
return llvm::Error::success();
}
Expand Down Expand Up @@ -416,6 +417,23 @@ static llvm::Error parseRecord(const Record &R, unsigned ID,
"invalid field for ConstraintInfo");
}

static llvm::Error parseRecord(const Record &R, unsigned ID,
llvm::StringRef Blob, VarInfo *I) {
switch (ID) {
case VAR_USR:
return decodeRecord(R, I->USR, Blob);
case VAR_NAME:
return decodeRecord(R, I->Name, Blob);
case VAR_DEFLOCATION:
return decodeRecord(R, I->DefLoc, Blob);
case VAR_IS_STATIC:
return decodeRecord(R, I->IsStatic, Blob);
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid field for VarInfo");
}
}

template <typename T> static llvm::Expected<CommentInfo *> getCommentInfo(T I) {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid type cannot contain CommentInfo");
Expand Down Expand Up @@ -458,6 +476,10 @@ template <> llvm::Expected<CommentInfo *> getCommentInfo(ConceptInfo *I) {
return &I->Description.emplace_back();
}

template <> Expected<CommentInfo *> getCommentInfo(VarInfo *I) {
return &I->Description.emplace_back();
}

// When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on
// the parent block to set it. The template specializations define what to do
// for each supported parent block.
Expand Down Expand Up @@ -497,6 +519,11 @@ template <> llvm::Error addTypeInfo(TypedefInfo *I, TypeInfo &&T) {
return llvm::Error::success();
}

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

template <typename T>
static llvm::Error addReference(T I, Reference &&R, FieldId F) {
return llvm::createStringError(llvm::inconvertibleErrorCode(),
Expand Down Expand Up @@ -643,6 +670,9 @@ template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) {
template <> void addChild(NamespaceInfo *I, ConceptInfo &&R) {
I->Children.Concepts.emplace_back(std::move(R));
}
template <> void addChild(NamespaceInfo *I, VarInfo &&R) {
I->Children.Variables.emplace_back(std::move(R));
}

// Record children:
template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
Expand Down Expand Up @@ -887,6 +917,13 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
addChild(I, std::move(CI));
return llvm::Error::success();
}
case BI_VAR_BLOCK_ID: {
VarInfo VI;
if (auto Err = readBlock(ID, &VI))
return Err;
addChild(I, std::move(VI));
return llvm::Error::success();
}
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid subblock type");
Expand Down Expand Up @@ -996,6 +1033,8 @@ ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
return createInfo<ConceptInfo>(ID);
case BI_FUNCTION_BLOCK_ID:
return createInfo<FunctionInfo>(ID);
case BI_VAR_BLOCK_ID:
return createInfo<VarInfo>(ID);
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"cannot create info");
Expand Down Expand Up @@ -1035,6 +1074,7 @@ ClangDocBitcodeReader::readBitcode() {
case BI_ENUM_BLOCK_ID:
case BI_TYPEDEF_BLOCK_ID:
case BI_CONCEPT_BLOCK_ID:
case BI_VAR_BLOCK_ID:
case BI_FUNCTION_BLOCK_ID: {
auto InfoOrErr = readBlockToInfo(ID);
if (!InfoOrErr)
Expand Down
32 changes: 29 additions & 3 deletions clang-tools-extra/clang-doc/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ static const llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor>
{BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, "TemplateSpecializationBlock"},
{BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"},
{BI_CONSTRAINT_BLOCK_ID, "ConstraintBlock"},
{BI_CONCEPT_BLOCK_ID, "ConceptBlock"}};
{BI_CONCEPT_BLOCK_ID, "ConceptBlock"},
{BI_VAR_BLOCK_ID, "VarBlock"}};
assert(Inits.size() == BlockIdCount);
for (const auto &Init : Inits)
BlockIdNameMap[Init.first] = Init.second;
Expand Down Expand Up @@ -213,7 +214,12 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
{CONCEPT_IS_TYPE, {"IsType", &genBoolAbbrev}},
{CONCEPT_CONSTRAINT_EXPRESSION,
{"ConstraintExpression", &genStringAbbrev}},
{CONSTRAINT_EXPRESSION, {"Expression", &genStringAbbrev}}};
{CONSTRAINT_EXPRESSION, {"Expression", &genStringAbbrev}},
{VAR_USR, {"USR", &genSymbolIdAbbrev}},
{VAR_NAME, {"Name", &genStringAbbrev}},
{VAR_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
{VAR_IS_STATIC, {"IsStatic", &genBoolAbbrev}}};

assert(Inits.size() == RecordIdCount);
for (const auto &Init : Inits) {
RecordIdNameMap[Init.first] = Init.second;
Expand Down Expand Up @@ -277,7 +283,8 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
{CONCEPT_USR, CONCEPT_NAME, CONCEPT_IS_TYPE,
CONCEPT_CONSTRAINT_EXPRESSION}},
// Constraint Block
{BI_CONSTRAINT_BLOCK_ID, {CONSTRAINT_EXPRESSION}}};
{BI_CONSTRAINT_BLOCK_ID, {CONSTRAINT_EXPRESSION}},
{BI_VAR_BLOCK_ID, {VAR_NAME, VAR_USR, VAR_DEFLOCATION, VAR_IS_STATIC}}};

// AbbreviationMap

Expand Down Expand Up @@ -540,6 +547,8 @@ void ClangDocBitcodeWriter::emitBlock(const NamespaceInfo &I) {
emitBlock(C);
for (const auto &C : I.Children.Concepts)
emitBlock(C);
for (const auto &C : I.Children.Variables)
emitBlock(C);
}

void ClangDocBitcodeWriter::emitBlock(const EnumInfo &I) {
Expand Down Expand Up @@ -682,6 +691,20 @@ void ClangDocBitcodeWriter::emitBlock(const ConstraintInfo &C) {
emitBlock(C.ConceptRef, FieldId::F_concept);
}

void ClangDocBitcodeWriter::emitBlock(const VarInfo &I) {
StreamSubBlockGuard Block(Stream, BI_VAR_BLOCK_ID);
emitRecord(I.USR, VAR_USR);
emitRecord(I.Name, VAR_NAME);
for (const auto &N : I.Namespace)
emitBlock(N, FieldId::F_namespace);
for (const auto &CI : I.Description)
emitBlock(CI);
if (I.DefLoc)
emitRecord(*I.DefLoc, VAR_DEFLOCATION);
emitRecord(I.IsStatic, VAR_IS_STATIC);
emitBlock(I.Type);
}

bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) {
switch (I->IT) {
case InfoType::IT_namespace:
Expand All @@ -702,6 +725,9 @@ bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) {
case InfoType::IT_concept:
emitBlock(*static_cast<clang::doc::ConceptInfo *>(I));
break;
case InfoType::IT_variable:
emitBlock(*static_cast<VarInfo *>(I));
break;
case InfoType::IT_default:
llvm::errs() << "Unexpected info, unable to write.\n";
return true;
Expand Down
6 changes: 6 additions & 0 deletions clang-tools-extra/clang-doc/BitcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum BlockId {
BI_CONSTRAINT_BLOCK_ID,
BI_TYPEDEF_BLOCK_ID,
BI_CONCEPT_BLOCK_ID,
BI_VAR_BLOCK_ID,
BI_LAST,
BI_FIRST = BI_VERSION_BLOCK_ID
};
Expand Down Expand Up @@ -142,6 +143,10 @@ enum RecordId {
CONCEPT_IS_TYPE,
CONCEPT_CONSTRAINT_EXPRESSION,
CONSTRAINT_EXPRESSION,
VAR_USR,
VAR_NAME,
VAR_DEFLOCATION,
VAR_IS_STATIC,
RI_LAST,
RI_FIRST = VERSION
};
Expand Down Expand Up @@ -190,6 +195,7 @@ class ClangDocBitcodeWriter {
void emitBlock(const ConceptInfo &T);
void emitBlock(const ConstraintInfo &T);
void emitBlock(const Reference &B, FieldId F);
void emitBlock(const VarInfo &B);

private:
class AbbreviationMap {
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clang-doc/HTMLGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,7 @@ llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
genHTML(*static_cast<clang::doc::TypedefInfo *>(I), CDCtx, InfoTitle);
break;
case InfoType::IT_concept:
case InfoType::IT_variable:
break;
case InfoType::IT_default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
Expand Down Expand Up @@ -1015,6 +1016,8 @@ static std::string getRefType(InfoType IT) {
return "typedef";
case InfoType::IT_concept:
return "concept";
case InfoType::IT_variable:
return "variable";
}
llvm_unreachable("Unknown InfoType");
}
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,8 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
break;
case InfoType::IT_concept:
break;
case InfoType::IT_variable:
break;
case InfoType::IT_default:
return createStringError(inconvertibleErrorCode(), "unexpected InfoType");
}
Expand Down
14 changes: 14 additions & 0 deletions clang-tools-extra/clang-doc/JSONGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,15 @@ static void serializeInfo(const RecordInfo &I, json::Object &Obj,
serializeCommonChildren(I.Children, Obj, RepositoryUrl);
}

static void serializeInfo(const VarInfo &I, json::Object &Obj,
std::optional<StringRef> RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
Obj["IsStatic"] = I.IsStatic;
auto TypeObj = Object();
serializeInfo(I.Type, TypeObj);
Obj["Type"] = std::move(TypeObj);
}

static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
std::optional<StringRef> RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
Expand Down Expand Up @@ -519,6 +528,10 @@ static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
if (!I.Children.Concepts.empty())
serializeArray(I.Children.Concepts, Obj, "Concepts", SerializeInfo);

if (!I.Children.Variables.empty()) {
serializeArray(I.Children.Variables, Obj, "Variables", SerializeInfo);
}

serializeCommonChildren(I.Children, Obj, RepositoryUrl);
}

Expand Down Expand Up @@ -573,6 +586,7 @@ Error JSONGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
case InfoType::IT_enum:
case InfoType::IT_function:
case InfoType::IT_typedef:
case InfoType::IT_variable:
break;
case InfoType::IT_default:
return createStringError(inconvertibleErrorCode(), "unexpected info type");
Expand Down
4 changes: 4 additions & 0 deletions clang-tools-extra/clang-doc/MDGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,9 @@ static llvm::Error genIndex(ClangDocContext &CDCtx) {
case InfoType::IT_concept:
Type = "Concept";
break;
case InfoType::IT_variable:
Type = "Variable";
break;
case InfoType::IT_default:
Type = "Other";
}
Expand Down Expand Up @@ -468,6 +471,7 @@ llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
genMarkdown(CDCtx, *static_cast<clang::doc::TypedefInfo *>(I), OS);
break;
case InfoType::IT_concept:
case InfoType::IT_variable:
break;
case InfoType::IT_default:
return createStringError(llvm::inconvertibleErrorCode(),
Expand Down
6 changes: 6 additions & 0 deletions clang-tools-extra/clang-doc/Mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ bool MapASTVisitor::VisitConceptDecl(const ConceptDecl *D) {
return mapDecl(D, true);
}

bool MapASTVisitor::VisitVarDecl(const VarDecl *D) {
if (D->isCXXClassMember())
return true;
return mapDecl(D, D->isThisDeclarationADefinition());
}

comments::FullComment *
MapASTVisitor::getComment(const NamedDecl *D, const ASTContext &Context) const {
RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-doc/Mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class MapASTVisitor : public clang::RecursiveASTVisitor<MapASTVisitor>,
bool VisitTypedefDecl(const TypedefDecl *D);
bool VisitTypeAliasDecl(const TypeAliasDecl *D);
bool VisitConceptDecl(const ConceptDecl *D);
bool VisitVarDecl(const VarDecl *D);

private:
template <typename T> bool mapDecl(const T *D, bool IsDefinition);
Expand Down
16 changes: 16 additions & 0 deletions clang-tools-extra/clang-doc/Representation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ mergeInfos(std::vector<std::unique_ptr<Info>> &Values) {
return reduce<TypedefInfo>(Values);
case InfoType::IT_concept:
return reduce<ConceptInfo>(Values);
case InfoType::IT_variable:
return reduce<VarInfo>(Values);
case InfoType::IT_default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"unexpected info type");
Expand Down Expand Up @@ -291,6 +293,7 @@ void NamespaceInfo::merge(NamespaceInfo &&Other) {
reduceChildren(Children.Enums, std::move(Other.Children.Enums));
reduceChildren(Children.Typedefs, std::move(Other.Children.Typedefs));
reduceChildren(Children.Concepts, std::move(Other.Children.Concepts));
reduceChildren(Children.Variables, std::move(Other.Children.Variables));
mergeBase(std::move(Other));
}

Expand Down Expand Up @@ -368,6 +371,15 @@ void ConceptInfo::merge(ConceptInfo &&Other) {
SymbolInfo::merge(std::move(Other));
}

void VarInfo::merge(VarInfo &&Other) {
assert(mergeable(Other));
if (!IsStatic)
IsStatic = Other.IsStatic;
if (Type.Type.USR == EmptySID && Type.Type.Name == "")
Type = std::move(Other.Type);
SymbolInfo::merge(std::move(Other));
}

BaseRecordInfo::BaseRecordInfo() : RecordInfo() {}

BaseRecordInfo::BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path,
Expand Down Expand Up @@ -407,6 +419,9 @@ llvm::SmallString<16> Info::extractName() const {
case InfoType::IT_concept:
return llvm::SmallString<16>("@nonymous_concept_" +
toHex(llvm::toStringRef(USR)));
case InfoType::IT_variable:
return llvm::SmallString<16>("@nonymous_variable_" +
toHex(llvm::toStringRef(USR)));
case InfoType::IT_default:
return llvm::SmallString<16>("@nonymous_" + toHex(llvm::toStringRef(USR)));
}
Expand Down Expand Up @@ -473,6 +488,7 @@ void ScopeChildren::sort() {
llvm::sort(Enums.begin(), Enums.end());
llvm::sort(Typedefs.begin(), Typedefs.end());
llvm::sort(Concepts.begin(), Concepts.end());
llvm::sort(Variables.begin(), Variables.end());
}
} // namespace doc
} // namespace clang
14 changes: 13 additions & 1 deletion clang-tools-extra/clang-doc/Representation.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct FunctionInfo;
struct Info;
struct TypedefInfo;
struct ConceptInfo;
struct VarInfo;

enum class InfoType {
IT_default,
Expand All @@ -44,7 +45,8 @@ enum class InfoType {
IT_function,
IT_enum,
IT_typedef,
IT_concept
IT_concept,
IT_variable
};

enum class CommentKind {
Expand Down Expand Up @@ -169,6 +171,7 @@ struct ScopeChildren {
std::vector<EnumInfo> Enums;
std::vector<TypedefInfo> Typedefs;
std::vector<ConceptInfo> Concepts;
std::vector<VarInfo> Variables;

void sort();
};
Expand Down Expand Up @@ -376,6 +379,15 @@ struct SymbolInfo : public Info {
bool IsStatic = false;
};

struct VarInfo : SymbolInfo {
VarInfo() : SymbolInfo(InfoType::IT_variable) {}
explicit VarInfo(SymbolID USR) : SymbolInfo(InfoType::IT_variable, USR) {}

void merge(VarInfo &&I);

TypeInfo Type;
};

// TODO: Expand to allow for documenting templating and default args.
// Info for functions.
struct FunctionInfo : public SymbolInfo {
Expand Down
Loading