diff options
author | Brett Wilson <brettw@google.com> | 2022-09-19 21:52:24 +0000 |
---|---|---|
committer | Paul Kirth <paulkirth@google.com> | 2022-09-19 21:54:41 +0000 |
commit | eaa7b324d5a272dc640cfc4162b746ac5341ccbd (patch) | |
tree | 735794e5a4797eafbd136e92de5c93315c8ab720 /clang-tools-extra/clang-doc/BitcodeReader.cpp | |
parent | d518fc28b6dce9c2ab5db8575d401e7eaa203612 (diff) | |
download | llvm-eaa7b324d5a272dc640cfc4162b746ac5341ccbd.zip llvm-eaa7b324d5a272dc640cfc4162b746ac5341ccbd.tar.gz llvm-eaa7b324d5a272dc640cfc4162b746ac5341ccbd.tar.bz2 |
[clang-doc] Add support for explicitly typed enums
Add support for explicitly typed enums:
enum Foo : unsigned { ... };
to the internal representation and to the YAML output.
Add support for getting the value of an enum constant, as well as accessing the original expression that produced it. This changes the YAML output of enums from an array of strings for the enum members to an array of dictionaries. These dictionaries now report the name, value, and original expression.
The markdown and HTML outputs are unchanged, they still output the name from the new enhanced internal schema.
Reviewed By: paulkirth
Differential Revision: https://reviews.llvm.org/D134055
Diffstat (limited to 'clang-tools-extra/clang-doc/BitcodeReader.cpp')
-rw-r--r-- | clang-tools-extra/clang-doc/BitcodeReader.cpp | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 7736e3d..da7f624 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -17,12 +17,19 @@ namespace doc { using Record = llvm::SmallVector<uint64_t, 1024>; +// This implements decode for SmallString. llvm::Error decodeRecord(const Record &R, llvm::SmallVectorImpl<char> &Field, llvm::StringRef Blob) { Field.assign(Blob.begin(), Blob.end()); return llvm::Error::success(); } +llvm::Error decodeRecord(const Record &R, std::string &Field, + llvm::StringRef Blob) { + Field.assign(Blob.begin(), Blob.end()); + return llvm::Error::success(); +} + llvm::Error decodeRecord(const Record &R, SymbolID &Field, llvm::StringRef Blob) { if (R[0] != BitCodeConstants::USRHashSize) @@ -218,8 +225,6 @@ llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, return decodeRecord(R, I->DefLoc, Blob); case ENUM_LOCATION: return decodeRecord(R, I->Loc, Blob); - case ENUM_MEMBER: - return decodeRecord(R, I->Members, Blob); case ENUM_SCOPED: return decodeRecord(R, I->Scoped, Blob); default: @@ -229,6 +234,21 @@ llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, } llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, + EnumValueInfo *I) { + switch (ID) { + case ENUM_VALUE_NAME: + return decodeRecord(R, I->Name, Blob); + case ENUM_VALUE_VALUE: + return decodeRecord(R, I->Value, Blob); + case ENUM_VALUE_EXPR: + return decodeRecord(R, I->ValueExpr, Blob); + default: + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "invalid field for EnumValueInfo"); + } +} + +llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, FunctionInfo *I) { switch (ID) { case FUNCTION_USR: @@ -372,6 +392,9 @@ llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) { return getCommentInfo(I.get()); } +// 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. template <typename T, typename TTypeInfo> llvm::Error addTypeInfo(T I, TTypeInfo &&TI) { return llvm::createStringError(llvm::inconvertibleErrorCode(), @@ -398,6 +421,11 @@ template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) { return llvm::Error::success(); } +template <> llvm::Error addTypeInfo(EnumInfo *I, TypeInfo &&T) { + I->BaseType = std::move(T); + 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"); @@ -524,6 +552,10 @@ template <> void addChild(RecordInfo *I, EnumInfo &&R) { I->ChildEnums.emplace_back(std::move(R)); } +template <> void addChild(EnumInfo *I, EnumValueInfo &&R) { + I->Members.emplace_back(std::move(R)); +} + template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) { I->Bases.emplace_back(std::move(R)); } @@ -587,8 +619,7 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) { template <typename T> llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { switch (ID) { - // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or - // EnumInfo subblocks + // Blocks can only have certain types of sub blocks. case BI_COMMENT_BLOCK_ID: { auto Comment = getCommentInfo(I); if (!Comment) @@ -650,6 +681,13 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { addChild(I, std::move(E)); return llvm::Error::success(); } + case BI_ENUM_VALUE_BLOCK_ID: { + EnumValueInfo EV; + if (auto Err = readBlock(ID, &EV)) + return Err; + addChild(I, std::move(EV)); + return llvm::Error::success(); + } default: return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid subblock type"); |