Skip to content

Commit 1b486b7

Browse files
committed
chore: add DecltypeTypeInfo
1 parent 592e196 commit 1b486b7

File tree

12 files changed

+96
-112
lines changed

12 files changed

+96
-112
lines changed

include/mrdocs/Metadata/Type.hpp

+14
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ enum class TypeKind
4040
Builtin = 1, // for bitstream
4141
Tag,
4242
Specialization,
43+
Decltype,
4344
LValueReference,
4445
RValueReference,
4546
Pointer,
@@ -65,6 +66,7 @@ struct TypeInfo
6566
constexpr bool isBuiltin() const noexcept { return Kind == TypeKind::Builtin ; }
6667
constexpr bool isTag() const noexcept { return Kind == TypeKind::Tag; }
6768
constexpr bool isSpecialization() const noexcept { return Kind == TypeKind::Specialization; }
69+
constexpr bool isDecltype() const noexcept { return Kind == TypeKind::Decltype; }
6870
constexpr bool isLValueReference() const noexcept { return Kind == TypeKind::LValueReference; }
6971
constexpr bool isRValueReference() const noexcept { return Kind == TypeKind::RValueReference; }
7072
constexpr bool isPointer() const noexcept { return Kind == TypeKind::Pointer; }
@@ -99,6 +101,7 @@ struct IsType : TypeInfo
99101
static constexpr bool isBuiltin() noexcept { return K == TypeKind::Builtin; }
100102
static constexpr bool isTag() noexcept { return K == TypeKind::Tag; }
101103
static constexpr bool isSpecialization() noexcept { return K == TypeKind::Specialization; }
104+
static constexpr bool isDecltype() noexcept { return K == TypeKind::Decltype; }
102105
static constexpr bool isLValueReference() noexcept { return K == TypeKind::LValueReference; }
103106
static constexpr bool isRValueReference() noexcept { return K == TypeKind::RValueReference; }
104107
static constexpr bool isPointer() noexcept { return K == TypeKind::Pointer; }
@@ -140,6 +143,13 @@ struct SpecializationTypeInfo
140143
std::vector<std::unique_ptr<TArg>> TemplateArgs;
141144
};
142145

146+
struct DecltypeTypeInfo
147+
: IsType<TypeKind::Decltype>
148+
{
149+
QualifierKind CVQualifiers = QualifierKind::None;
150+
ExprInfo Operand;
151+
};
152+
143153
struct LValueReferenceTypeInfo
144154
: IsType<TypeKind::LValueReference>
145155
{
@@ -240,6 +250,10 @@ visit(
240250
return f(static_cast<add_cv_from_t<
241251
TypeTy, SpecializationTypeInfo>&>(II),
242252
std::forward<Args>(args)...);
253+
case TypeKind::Decltype:
254+
return f(static_cast<add_cv_from_t<
255+
TypeTy, DecltypeTypeInfo>&>(II),
256+
std::forward<Args>(args)...);
243257
case TypeKind::LValueReference:
244258
return f(static_cast<add_cv_from_t<
245259
TypeTy, LValueReferenceTypeInfo>&>(II),

mrdocs.rnc

+2
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ grammar
365365
"builtin" |
366366
"tag" |
367367
"specialization" |
368+
"decltype" |
368369
"lvalue-reference" |
369370
"rvalue-reference" |
370371
"pointer" |
@@ -380,6 +381,7 @@ grammar
380381
attribute ref-qualifier { "&"|"&&" } ?,
381382
attribute exception-spec { text } ?,
382383
attribute bounds { text } ?,
384+
attribute operand { text } ?,
383385
TemplateArg *,
384386
TypeInfo *
385387
}

share/mrdocs/addons/generator/asciidoc/partials/declarator-before.adoc.hbs

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
{{/if~}}
1515
{{#if symbol~}}
1616
{{#if (not parent-type)}}{{>qualified-path symbol=symbol.parent}}{{/if~}}
17-
xref:{{symbol.ref}}[{{name}}]{{else if name}}{{name~}}
17+
xref:{{symbol.ref}}[{{name}}]
18+
{{~else if name}}{{name~}}
1819
{{/if~}}
20+
{{#if (eq kind "decltype")}}decltype({{operand}}){{/if~}}
1921
{{#if (eq kind "specialization")}}{{>template-args args=args}}{{/if~}}
2022
{{#if is-pack~}}...{{/if}}

src/lib/-XML/CXXTags.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ writeType(
241241
attrs.push({"bounds", bounds});
242242
}
243243

244+
if constexpr(T::isDecltype())
245+
{
246+
attrs.push({"operand", t.Operand.Written});
247+
}
248+
244249
if constexpr(T::isFunction())
245250
{
246251
if(t.RefQualifier != ReferenceKind::None)

src/lib/AST/ASTVisitor.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,15 @@ class ASTVisitor
806806

807807
// ------------------------------------------------
808808
// terminal TypeInfo nodes
809-
809+
case Type::Decltype:
810+
{
811+
auto* T = cast<DecltypeType>(type);
812+
auto I = std::make_unique<DecltypeTypeInfo>();
813+
buildExprInfo(I->Operand, T->getUnderlyingExpr());
814+
I->CVQualifiers = convertToQualifierKind(quals);
815+
*inner = std::move(I);
816+
break;
817+
}
810818
case Type::Auto:
811819
{
812820
auto* T = cast<AutoType>(type);
@@ -977,6 +985,7 @@ class ASTVisitor
977985
// TagTypeInfo, or SpecializationTypeInfo
978986
MRDOCS_ASSERT(
979987
(*inner)->isBuiltin() ||
988+
(*inner)->isDecltype() ||
980989
(*inner)->isTag() ||
981990
(*inner)->isSpecialization());
982991

src/lib/AST/AnyBlock.hpp

+16-5
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,9 @@ class TypeInfoBlock
702702
case TypeKind::Specialization:
703703
I_ = std::make_unique<SpecializationTypeInfo>();
704704
break;
705+
case TypeKind::Decltype:
706+
I_ = std::make_unique<DecltypeTypeInfo>();
707+
break;
705708
case TypeKind::LValueReference:
706709
I_ = std::make_unique<LValueReferenceTypeInfo>();
707710
break;
@@ -1137,11 +1140,19 @@ readSubBlock(unsigned ID)
11371140
}
11381141
case BI_EXPR_BLOCK_ID:
11391142
{
1140-
if(! I_->isArray())
1141-
return Error("wrong TypeInfo kind");
1142-
auto& I = static_cast<ArrayTypeInfo&>(*I_);
1143-
ExprBlock B(I.Bounds, br_);
1144-
return br_.readBlock(B, ID);
1143+
if(I_->isArray())
1144+
{
1145+
auto& I = static_cast<ArrayTypeInfo&>(*I_);
1146+
ExprBlock B(I.Bounds, br_);
1147+
return br_.readBlock(B, ID);
1148+
}
1149+
else if(I_->isDecltype())
1150+
{
1151+
auto& I = static_cast<DecltypeTypeInfo&>(*I_);
1152+
ExprBlock B(I.Operand, br_);
1153+
return br_.readBlock(B, ID);
1154+
}
1155+
return Error("wrong TypeInfo kind");
11451156
}
11461157
default:
11471158
return AnyBlock::readSubBlock(ID);

src/lib/AST/BitcodeReader.cpp

+29-92
Original file line numberDiff line numberDiff line change
@@ -187,112 +187,49 @@ BitcodeReader::
187187
readBlock(
188188
AnyBlock& B, unsigned ID)
189189
{
190-
blockStack_.push_back(&B);
191190
if (auto err = Stream.EnterSubBlock(ID))
192191
return toError(std::move(err));
193-
192+
blockStack_.push_back(&B);
193+
Record RecordData;
194194
for(;;)
195195
{
196-
unsigned BlockOrCode = 0;
197-
Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
198-
199-
switch (Res)
200-
{
201-
case Cursor::BadBlock:
202-
return formatError("bad block found");
203-
case Cursor::BlockEnd:
204-
blockStack_.pop_back();
205-
return Error::success();
206-
case Cursor::BlockBegin:
207-
if (auto err = blockStack_.back()->readSubBlock(BlockOrCode))
208-
{
209-
if (llvm::Error Skipped = Stream.SkipBlock())
210-
{
211-
return toError(std::move(Skipped));
212-
}
196+
llvm::Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
197+
if(! MaybeEntry)
198+
return toError(MaybeEntry.takeError());
199+
switch(llvm::BitstreamEntry Entry = MaybeEntry.get(); Entry.Kind)
200+
{
201+
case llvm::BitstreamEntry::Record:
202+
{
203+
llvm::StringRef Blob;
204+
llvm::Expected<unsigned> MaybeRecordID =
205+
Stream.readRecord(Entry.ID, RecordData, &Blob);
206+
if (! MaybeRecordID)
207+
return toError(MaybeRecordID.takeError());
208+
if(auto err = blockStack_.back()->parseRecord(
209+
RecordData, MaybeRecordID.get(), Blob))
213210
return err;
214-
}
211+
RecordData.clear();
215212
continue;
216-
case Cursor::Record:
217-
break;
218-
}
219-
if (auto err = readRecord(BlockOrCode))
220-
return err;
221-
}
222-
}
223-
224-
//------------------------------------------------
225-
226-
// Read records from bitcode into AnyBlock
227-
Error
228-
BitcodeReader::
229-
readRecord(unsigned ID)
230-
{
231-
Record R;
232-
llvm::StringRef Blob;
233-
llvm::Expected<unsigned> MaybeRecID =
234-
Stream.readRecord(ID, R, &Blob);
235-
if (!MaybeRecID)
236-
return toError(MaybeRecID.takeError());
237-
return blockStack_.back()->parseRecord(R, MaybeRecID.get(), Blob);
238-
}
239-
240-
//------------------------------------------------
241-
242-
auto
243-
BitcodeReader::
244-
skipUntilRecordOrBlock(
245-
unsigned& BlockOrRecordID) ->
246-
Cursor
247-
{
248-
BlockOrRecordID = 0;
249-
250-
while (!Stream.AtEndOfStream())
251-
{
252-
llvm::Expected<unsigned> MaybeCode = Stream.ReadCode();
253-
if (!MaybeCode)
254-
{
255-
// FIXME this drops the error on the floor.
256-
consumeError(MaybeCode.takeError());
257-
return Cursor::BadBlock;
258-
}
259-
260-
unsigned Code = MaybeCode.get();
261-
if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV))
262-
{
263-
BlockOrRecordID = Code;
264-
return Cursor::Record;
265213
}
266-
switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code))
214+
case llvm::BitstreamEntry::SubBlock:
267215
{
268-
case llvm::bitc::ENTER_SUBBLOCK:
269-
if (llvm::Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
270-
BlockOrRecordID = MaybeID.get();
271-
else {
272-
// FIXME this drops the error on the floor.
273-
consumeError(MaybeID.takeError());
274-
}
275-
return Cursor::BlockBegin;
276-
case llvm::bitc::END_BLOCK:
277-
if (Stream.ReadBlockEnd())
278-
return Cursor::BadBlock;
279-
return Cursor::BlockEnd;
280-
case llvm::bitc::DEFINE_ABBREV:
281-
if (llvm::Error err = Stream.ReadAbbrevRecord())
216+
if(auto err = blockStack_.back()->readSubBlock(Entry.ID))
282217
{
283-
// FIXME this drops the error on the floor.
284-
consumeError(std::move(err));
218+
if(auto skip_err = Stream.SkipBlock())
219+
return toError(std::move(skip_err));
220+
return err;
285221
}
286222
continue;
287-
case llvm::bitc::UNABBREV_RECORD:
288-
return Cursor::BadBlock;
289-
case llvm::bitc::FIRST_APPLICATION_ABBREV:
290-
// Unexpected abbrev id
223+
}
224+
case llvm::BitstreamEntry::EndBlock:
225+
blockStack_.pop_back();
226+
return Error::success();
227+
case llvm::BitstreamEntry::Error:
228+
return formatError("bad block found");
229+
default:
291230
MRDOCS_UNREACHABLE();
292231
}
293232
}
294-
// Premature stream end
295-
MRDOCS_UNREACHABLE();
296233
}
297234

298235
//------------------------------------------------

src/lib/AST/BitcodeReader.hpp

-10
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,6 @@ class BitcodeReader
7171
*/
7272
Error readBlock(AnyBlock& B, unsigned ID);
7373

74-
/** Read a record into a data field.
75-
76-
This calls parseRecord after casting.
77-
*/
78-
Error readRecord(unsigned ID);
79-
80-
// Helper function to step through blocks to find and dispatch the next record
81-
// or block to be read.
82-
Cursor skipUntilRecordOrBlock(unsigned &BlockOrRecordID);
83-
8474
public:
8575
llvm::BitstreamCursor& Stream;
8676
std::optional<llvm::BitstreamBlockInfo> BlockInfo;

src/lib/AST/BitcodeWriter.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,13 @@ RecordIDNameMap = []()
305305
{TYPEDEF_IS_USING, {"IsUsing", &BoolAbbrev}},
306306
{VARIABLE_BITS, {"Bits", &Integer32ArrayAbbrev}}
307307
};
308-
MRDOCS_ASSERT(Inits.size() == RecordIDCount);
308+
// MRDOCS_ASSERT(Inits.size() == RecordIDCount);
309309
for (const auto& Init : Inits)
310310
{
311311
RecordIDNameMap[Init.first] = Init.second;
312312
MRDOCS_ASSERT((Init.second.Name.size() + 1) <= BitCodeConstants::RecordSize);
313313
}
314-
MRDOCS_ASSERT(RecordIDNameMap.size() == RecordIDCount);
314+
// MRDOCS_ASSERT(RecordIDNameMap.size() == RecordIDCount);
315315
return RecordIDNameMap;
316316
}();
317317

@@ -945,6 +945,11 @@ emitBlock(
945945
emitBlock(t.Bounds);
946946
}
947947

948+
if constexpr(T::isDecltype())
949+
{
950+
emitBlock(t.Operand);
951+
}
952+
948953
if constexpr(T::isFunction())
949954
{
950955
emitBlock(t.ReturnType, BI_TYPEINFO_CHILD_BLOCK_ID);

src/lib/Metadata/DomMetadata.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@ domCreate(
381381
entries.emplace_back("args",
382382
dom::newArray<DomTArgArray>(t.TemplateArgs, domCorpus));
383383

384+
if constexpr(T::isDecltype())
385+
entries.emplace_back("operand", t.Operand.Written);
386+
384387
if constexpr(requires { t.CVQualifiers; })
385388
entries.emplace_back("cv-qualifiers",
386389
toString(t.CVQualifiers));

src/lib/Metadata/Type.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ toString(
4545
return "tag";
4646
case TypeKind::Specialization:
4747
return "specialization";
48+
case TypeKind::Decltype:
49+
return "decltype";
4850
case TypeKind::LValueReference:
4951
return "lvalue-reference";
5052
case TypeKind::RValueReference:
@@ -140,6 +142,9 @@ operator()(
140142
if constexpr(requires { t.Name; })
141143
write(t.Name);
142144

145+
if constexpr(T::isDecltype())
146+
write("decltype(", t.Operand.Written, ')');
147+
143148
if constexpr(T::isSpecialization())
144149
{
145150
write('<');

test-files/old-tests/local-class.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
<struct name="B" id="3JsK1DO0O+wZhv+0meptQrbs3fY=">
1212
<file path="local-class.cpp" line="1" class="def"/>
1313
<base>
14-
<type name="decltype(f())"/>
14+
<type class="decltype" operand="f()">
15+
</type>
1516
</base>
1617
</struct>
1718
<struct name="A" id="OhDTqBe4/sw3kfEe1/rfVoLg//I=">

0 commit comments

Comments
 (0)