[clang-doc] document global variables (#145070)
Visit and map VarDecls to document variables declared in namespace scope.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
@@ -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");
|
||||
@@ -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.
|
||||
@@ -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(),
|
||||
@@ -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) {
|
||||
@@ -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");
|
||||
@@ -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");
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -190,6 +195,7 @@ public:
|
||||
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 {
|
||||
|
||||
@@ -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(),
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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(),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
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);
|
||||
|
||||
@@ -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");
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -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)));
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -36,6 +36,7 @@ struct FunctionInfo;
|
||||
struct Info;
|
||||
struct TypedefInfo;
|
||||
struct ConceptInfo;
|
||||
struct VarInfo;
|
||||
|
||||
enum class InfoType {
|
||||
IT_default,
|
||||
@@ -44,7 +45,8 @@ enum class InfoType {
|
||||
IT_function,
|
||||
IT_enum,
|
||||
IT_typedef,
|
||||
IT_concept
|
||||
IT_concept,
|
||||
IT_variable
|
||||
};
|
||||
|
||||
enum class CommentKind {
|
||||
@@ -169,6 +171,7 @@ struct ScopeChildren {
|
||||
std::vector<EnumInfo> Enums;
|
||||
std::vector<TypedefInfo> Typedefs;
|
||||
std::vector<ConceptInfo> Concepts;
|
||||
std::vector<VarInfo> Variables;
|
||||
|
||||
void sort();
|
||||
};
|
||||
@@ -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 {
|
||||
|
||||
@@ -401,6 +401,8 @@ std::string serialize(std::unique_ptr<Info> &I) {
|
||||
return serialize(*static_cast<FunctionInfo *>(I.get()));
|
||||
case InfoType::IT_concept:
|
||||
return serialize(*static_cast<ConceptInfo *>(I.get()));
|
||||
case InfoType::IT_variable:
|
||||
return serialize(*static_cast<VarInfo *>(I.get()));
|
||||
case InfoType::IT_typedef:
|
||||
case InfoType::IT_default:
|
||||
return "";
|
||||
@@ -508,6 +510,10 @@ static void InsertChild(ScopeChildren &Scope, ConceptInfo Info) {
|
||||
Scope.Concepts.push_back(std::move(Info));
|
||||
}
|
||||
|
||||
static void InsertChild(ScopeChildren &Scope, VarInfo Info) {
|
||||
Scope.Variables.push_back(std::move(Info));
|
||||
}
|
||||
|
||||
// Creates a parent of the correct type for the given child and inserts it into
|
||||
// that parent.
|
||||
//
|
||||
@@ -549,6 +555,7 @@ static std::unique_ptr<Info> makeAndInsertIntoParent(ChildType Child) {
|
||||
case InfoType::IT_function:
|
||||
case InfoType::IT_typedef:
|
||||
case InfoType::IT_concept:
|
||||
case InfoType::IT_variable:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Invalid reference type for parent namespace");
|
||||
@@ -1164,6 +1171,26 @@ emitInfo(const ConceptDecl *D, const FullComment *FC, const Location &Loc,
|
||||
return {nullptr, makeAndInsertIntoParent<ConceptInfo &&>(std::move(Concept))};
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const VarDecl *D, const FullComment *FC, const Location &Loc,
|
||||
bool PublicOnly) {
|
||||
VarInfo Var;
|
||||
bool IsInAnonymousNamespace = false;
|
||||
populateSymbolInfo(Var, D, FC, Loc, IsInAnonymousNamespace);
|
||||
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
|
||||
return {};
|
||||
|
||||
if (D->getStorageClass() == StorageClass::SC_Static)
|
||||
Var.IsStatic = true;
|
||||
Var.Type =
|
||||
getTypeInfoForType(D->getType(), D->getASTContext().getPrintingPolicy());
|
||||
|
||||
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
|
||||
return {};
|
||||
|
||||
return {nullptr, makeAndInsertIntoParent<VarInfo &&>(std::move(Var))};
|
||||
}
|
||||
|
||||
} // namespace serialize
|
||||
} // namespace doc
|
||||
} // namespace clang
|
||||
|
||||
@@ -72,6 +72,10 @@ std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const ConceptDecl *D, const FullComment *FC, const Location &Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
|
||||
emitInfo(const VarDecl *D, const FullComment *FC, const Location &Loc,
|
||||
bool PublicOnly);
|
||||
|
||||
// Function to hash a given USR value for storage.
|
||||
// As USRs (Unified Symbol Resolution) could be large, especially for functions
|
||||
// with long type arguments, we use 160-bits SHA1(USR) values to
|
||||
|
||||
@@ -409,6 +409,7 @@ llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
|
||||
InfoYAML << *static_cast<clang::doc::TypedefInfo *>(I);
|
||||
break;
|
||||
case InfoType::IT_concept:
|
||||
case InfoType::IT_variable:
|
||||
break;
|
||||
case InfoType::IT_default:
|
||||
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
||||
|
||||
@@ -9,7 +9,6 @@ void myFunction(int Param);
|
||||
namespace NestedNamespace {
|
||||
} // namespace NestedNamespace
|
||||
|
||||
// FIXME: Global variables are not mapped or serialized.
|
||||
static int Global;
|
||||
|
||||
enum Color {
|
||||
@@ -25,7 +24,7 @@ typedef int MyTypedef;
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "Location": {
|
||||
// CHECK-NEXT: "Filename": "{{.*}}namespace.cpp",
|
||||
// CHECK-NEXT: "LineNumber": 15
|
||||
// CHECK-NEXT: "LineNumber": 14
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: "Members": [
|
||||
// CHECK-NEXT: {
|
||||
@@ -88,7 +87,7 @@ typedef int MyTypedef;
|
||||
// CHECK-NEXT: "IsUsing": false,
|
||||
// CHECK-NEXT: "Location": {
|
||||
// CHECK-NEXT: "Filename": "{{.*}}namespace.cpp",
|
||||
// CHECK-NEXT: "LineNumber": 21
|
||||
// CHECK-NEXT: "LineNumber": 20
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: "Name": "MyTypedef",
|
||||
// CHECK-NEXT: "TypeDeclaration": "",
|
||||
@@ -103,23 +102,23 @@ typedef int MyTypedef;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000"
|
||||
// CHECK-NOT: "Variables": [
|
||||
// CHECK-NOT: {
|
||||
// CHECK-NOT: "IsStatic": true,
|
||||
// CHECK-NOT: "Location": {
|
||||
// CHECK-NOT: "Filename": "{{.*}}namespace.cpp",
|
||||
// CHECK-NOT: "LineNumber": 13
|
||||
// CHECK-NOT: },
|
||||
// CHECK-NOT: "Name": "Global",
|
||||
// CHECK-NOT: "Type": {
|
||||
// CHECK-NEXT: "Variables": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "IsStatic": true,
|
||||
// CHECK-NEXT: "Location": {
|
||||
// CHECK-NEXT: "Filename": "{{.*}}namespace.cpp",
|
||||
// CHECK-NEXT: "LineNumber": 12
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: "Name": "Global",
|
||||
// CHECK-NEXT: "Type": {
|
||||
// COM: FIXME: IsBuiltIn emits as its default value
|
||||
// CHECK-NOT: "IsBuiltIn": false,
|
||||
// CHECK-NOT: "IsTemplate": false,
|
||||
// CHECK-NOT: "Name": "int",
|
||||
// CHECK-NOT: "QualName": "int",
|
||||
// CHECK-NOT: "USR": "0000000000000000000000000000000000000000"
|
||||
// CHECK-NOT: },
|
||||
// CHECK-NOT: "USR": "{{[0-9A-F]*}}"
|
||||
// CHECK-NOT: }
|
||||
// CHECK-NOT: ]
|
||||
// CHECK-NEXT: "IsBuiltIn": false,
|
||||
// CHECK-NEXT: "IsTemplate": false,
|
||||
// CHECK-NEXT: "Name": "int",
|
||||
// CHECK-NEXT: "QualName": "int",
|
||||
// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -39,6 +39,8 @@ static std::string writeInfo(Info *I) {
|
||||
return writeInfo(*static_cast<TypedefInfo *>(I));
|
||||
case InfoType::IT_concept:
|
||||
return writeInfo(*static_cast<ConceptInfo *>(I));
|
||||
case InfoType::IT_variable:
|
||||
return writeInfo(*static_cast<VarInfo *>(I));
|
||||
case InfoType::IT_default:
|
||||
return "";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user