Skip to content

Commit

Permalink
feat: show operand of noexcept specifier
Browse files Browse the repository at this point in the history
  • Loading branch information
sdkrystian committed Nov 30, 2023
1 parent 35b4796 commit 3f83fd0
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 6 deletions.
2 changes: 2 additions & 0 deletions include/mrdocs/Metadata/Function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ struct FunctionInfo
FnFlags0 specs0{.raw{0}};
FnFlags1 specs1{.raw{0}};

NoexceptInfo Noexcept;

//--------------------------------------------

explicit FunctionInfo(SymbolID ID) noexcept
Expand Down
9 changes: 9 additions & 0 deletions include/mrdocs/Metadata/Specifiers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <mrdocs/Platform.hpp>
#include <mrdocs/Dom.hpp>
#include <string>
#include <string_view>

namespace clang {
Expand Down Expand Up @@ -96,6 +97,14 @@ enum class NoexceptKind
Unparsed
};

// KRYSTIAN FIXME: this needs to be improved (a lot)
struct NoexceptInfo
{
NoexceptKind Kind = NoexceptKind::None;

std::string Operand;
};

/** Operator kinds
*/
enum class OperatorKind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
{{~#if symbol.isConst}} const{{/if~}}
{{#if symbol.isVolatile}} volatile{{/if~}}
{{#if symbol.refQualifier}} {{symbol.refQualifier}}{{/if~}}
{{#if (eq symbol.exceptionSpec "noexcept")}} noexcept{{/if~}}
{{#if symbol.exceptionSpec}} {{symbol.exceptionSpec}}{{/if~}}
{{#if (eq symbol.class "normal")}}{{>declarator-after symbol.return}}{{/if~}}
{{#if symbol.hasOverrideAttr}} override{{/if~}}
{{#if symbol.isFinal}} final{{/if~}}
Expand Down
46 changes: 43 additions & 3 deletions src/lib/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,45 @@ class ASTVisitor
V.getZExtValue());
}

void
buildNoexceptInfo(
NoexceptInfo& I,
ExceptionSpecificationType Kind,
const Expr* E)
{
if(Kind == ExceptionSpecificationType::EST_None)
return;
I.Kind = convertToNoexceptKind(Kind);

if(! E)
return;
#if 0
I.Operand = getSourceCode(
E->getSourceRange());
#else

llvm::raw_string_ostream stream(I.Operand);
E->printPretty(stream, nullptr, context_.getPrintingPolicy());
#endif
}

void
buildNoexceptInfo(
NoexceptInfo& I,
FunctionDecl* FD)
{
auto Kind = FD->getExceptionSpecType();
if(Kind == ExceptionSpecificationType::EST_None)
return;
const Expr* E = nullptr;
if(auto FTL = FD->getFunctionTypeLoc())
{
if(auto* FPT = FTL.getAs<FunctionProtoTypeLoc>().getTypePtr())
E = FPT->getNoexceptExpr();
}
buildNoexceptInfo(I, Kind, E);
}

void
buildExprInfo(
ExprInfo& I,
Expand Down Expand Up @@ -2170,9 +2209,10 @@ class ASTVisitor
I.specs0.constexprKind |=
convertToConstexprKind(
D->getConstexprKind());
I.specs0.exceptionSpec |=
convertToNoexceptKind(
D->getExceptionSpecType());
buildNoexceptInfo(I.Noexcept, D);
// I.specs0.exceptionSpec |=
// convertToNoexceptKind(
// D->getExceptionSpecType());
I.specs0.overloadedOperator |=
convertToOperatorKind(
D->getOverloadedOperator());
Expand Down
39 changes: 39 additions & 0 deletions src/lib/AST/AnyBlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,40 @@ class FunctionParamBlock
}
};

//------------------------------------------------

class NoexceptBlock
: public BitcodeReader::AnyBlock
{
BitcodeReader& br_;
NoexceptInfo& I_;

public:
NoexceptBlock(
NoexceptInfo& I,
BitcodeReader& br) noexcept
: br_(br)
, I_(I)
{
}

Error
parseRecord(
Record const& R,
unsigned ID,
llvm::StringRef Blob) override
{
switch(ID)
{
case NOEXCEPT_KIND:
return decodeRecord(R, I_.Kind, Blob);
case NOEXCEPT_OPERAND:
return decodeRecord(R, I_.Operand, Blob);
default:
return AnyBlock::parseRecord(R, ID, Blob);
}
}
};

//------------------------------------------------

Expand Down Expand Up @@ -1454,6 +1488,11 @@ class FunctionBlock
TemplateBlock B(*I->Template, br_);
return br_.readBlock(B, ID);
}
case BI_NOEXCEPT_BLOCK_ID:
{
NoexceptBlock B(I->Noexcept, br_);
return br_.readBlock(B, ID);
}
default:
return TopLevelBlock::readSubBlock(ID);
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib/AST/BitcodeIDs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ enum BlockID
BI_TYPEINFO_PARAM_BLOCK_ID,
BI_TYPEDEF_BLOCK_ID,
BI_VARIABLE_BLOCK_ID,
BI_NOEXCEPT_BLOCK_ID,
BI_LAST,
BI_FIRST = BI_VERSION_BLOCK_ID
};
Expand Down Expand Up @@ -120,6 +121,8 @@ enum RecordID
FUNCTION_PARAM_NAME,
FUNCTION_PARAM_DEFAULT,
GUIDE_EXPLICIT,
NOEXCEPT_KIND,
NOEXCEPT_OPERAND,
JAVADOC_NODE_ADMONISH,
JAVADOC_NODE_HREF,
JAVADOC_NODE_KIND,
Expand Down
21 changes: 19 additions & 2 deletions src/lib/AST/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ BlockIdNameMap = []()
{BI_SPECIALIZATION_BLOCK_ID, "SpecializationBlock"},
{BI_FRIEND_BLOCK_ID, "FriendBlock"},
{BI_ENUMERATOR_BLOCK_ID, "EnumeratorBlock"},
{BI_VARIABLE_BLOCK_ID, "VarBlock"}
{BI_VARIABLE_BLOCK_ID, "VarBlock"},
{BI_NOEXCEPT_BLOCK_ID, "NoexceptBlock"}
};
MRDOCS_ASSERT(Inits.size() == BlockIdCount);
for (const auto& Init : Inits)
Expand Down Expand Up @@ -270,6 +271,8 @@ RecordIDNameMap = []()
{FUNCTION_PARAM_NAME, {"Name", &StringAbbrev}},
{FUNCTION_PARAM_DEFAULT, {"Default", &StringAbbrev}},
{GUIDE_EXPLICIT, {"Explicit", &Integer32Abbrev}},
{NOEXCEPT_KIND, {"NoexceptKind", &Integer32Abbrev}},
{NOEXCEPT_OPERAND, {"NoexceptOperand", &StringAbbrev}},
{INFO_PART_ACCESS, {"InfoAccess", &Integer32Abbrev}},
{INFO_PART_ID, {"InfoID", &SymbolIDAbbrev}},
{INFO_PART_IMPLICIT, {"InfoImplicit", &BoolAbbrev}},
Expand Down Expand Up @@ -414,7 +417,9 @@ RecordsByBlock{
// VariableInfo
{BI_VARIABLE_BLOCK_ID, {VARIABLE_BITS}},
// GuideInfo
{BI_GUIDE_BLOCK_ID, {GUIDE_EXPLICIT}}
{BI_GUIDE_BLOCK_ID, {GUIDE_EXPLICIT}},
// NoexceptInfo
{BI_NOEXCEPT_BLOCK_ID, {NOEXCEPT_KIND, NOEXCEPT_OPERAND}}
};

//------------------------------------------------
Expand Down Expand Up @@ -831,6 +836,16 @@ emitBlock(
emitBlock(P.Type);
}

void
BitcodeWriter::
emitBlock(
const NoexceptInfo& I)
{
StreamSubBlockGuard Block(Stream, BI_NOEXCEPT_BLOCK_ID);
emitRecord(I.Kind, NOEXCEPT_KIND);
emitRecord(I.Operand, NOEXCEPT_OPERAND);
}

void
BitcodeWriter::
emitBlock(
Expand All @@ -846,6 +861,8 @@ emitBlock(
emitBlock(I.ReturnType);
for (const auto& N : I.Params)
emitBlock(N);
if(I.Noexcept.Kind != NoexceptKind::None)
emitBlock(I.Noexcept);
}

void
Expand Down
1 change: 1 addition & 0 deletions src/lib/AST/BitcodeWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class BitcodeWriter
void emitBlock(FunctionInfo const& I);
void emitBlock(GuideInfo const& I);
void emitBlock(Param const& I);
void emitBlock(NoexceptInfo const& I);
void emitBlock(std::unique_ptr<Javadoc> const& jd);
void emitBlock(doc::Node const& I);
void emitBlock(NamespaceInfo const& I);
Expand Down
10 changes: 10 additions & 0 deletions src/lib/Metadata/DomMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,16 @@ DomInfo<T>::construct() const
{ "template", domCreate(I_.Template, domCorpus_) },
{ "overloadedOperator", I_.specs0.overloadedOperator.get() },
});

if(I_.Noexcept.Kind != NoexceptKind::None)
{
dom::String exceptSpec = "noexcept";
if(! I_.Noexcept.Operand.empty())
exceptSpec = fmt::format(
"noexcept({})",
I_.Noexcept.Operand);
entries.emplace_back("exceptionSpec", std::move(exceptSpec));
}
}
if constexpr(T::isTypedef())
{
Expand Down
2 changes: 2 additions & 0 deletions src/lib/Metadata/Reduce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ void merge(FunctionInfo& I, FunctionInfo&& Other)
I.Template = std::move(Other.Template);
I.specs0.raw.value |= Other.specs0.raw.value;
I.specs1.raw.value |= Other.specs1.raw.value;
if(I.Noexcept.Kind == NoexceptKind::None)
I.Noexcept = std::move(Other.Noexcept);
}

void merge(GuideInfo& I, GuideInfo&& Other)
Expand Down

0 comments on commit 3f83fd0

Please sign in to comment.