mirror of https://github.com/libAthena/athena.git
More flexible DNA template support
This commit is contained in:
parent
9a7bee95c4
commit
24666aebdd
328
atdna/main.cpp
328
atdna/main.cpp
|
@ -226,10 +226,10 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
return propIdExpr;
|
return propIdExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetOpString(const std::string& fieldName, const std::string& propIdExpr, int64_t endianVal)
|
static std::string GetOpString(const std::string& fieldName, const std::string& propIdExpr, const std::string& endianExpr)
|
||||||
{
|
{
|
||||||
|
|
||||||
return "<Op, "s + (endianVal ? "Endian::Big" : "Endian::Little") + ">({" + propIdExpr + "}, " + fieldName + ", s)";
|
return "<Op, "s + endianExpr + ">({" + propIdExpr + "}, " + fieldName + ", s)";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetOpString(const std::string& fieldName, const std::string& propIdExpr)
|
static std::string GetOpString(const std::string& fieldName, const std::string& propIdExpr)
|
||||||
|
@ -238,9 +238,9 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
return "<Op>({" + propIdExpr + "}, " + fieldName + ", s)";
|
return "<Op>({" + propIdExpr + "}, " + fieldName + ", s)";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetVectorOpString(const std::string& fieldName, const std::string& propIdExpr, const std::string& sizeExpr, int64_t endianVal)
|
static std::string GetVectorOpString(const std::string& fieldName, const std::string& propIdExpr, const std::string& sizeExpr, const std::string& endianExpr)
|
||||||
{
|
{
|
||||||
return "<Op, "s + (endianVal ? "Endian::Big" : "Endian::Little") + ">({" + propIdExpr + "}, " + fieldName + ", " + sizeExpr + ", s)";
|
return "<Op, "s + endianExpr + ">({" + propIdExpr + "}, " + fieldName + ", " + sizeExpr + ", s)";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetVectorOpString(const std::string& fieldName, const std::string& propIdExpr, const std::string& sizeExpr)
|
static std::string GetVectorOpString(const std::string& fieldName, const std::string& propIdExpr, const std::string& sizeExpr)
|
||||||
|
@ -456,7 +456,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (!tsDecl->getName().compare("Value"))
|
if (!tsDecl->getName().compare("Value"))
|
||||||
{
|
{
|
||||||
llvm::APSInt endian(64, -1);
|
llvm::APSInt endian(64, -1);
|
||||||
const clang::Expr* endianExpr = nullptr;
|
std::string endianExprStr;
|
||||||
bool defaultEndian = true;
|
bool defaultEndian = true;
|
||||||
if (classParms->size() >= 2)
|
if (classParms->size() >= 2)
|
||||||
{
|
{
|
||||||
|
@ -464,15 +464,8 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
{
|
{
|
||||||
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
endianExpr = defArg;
|
nttParm->print(strStream, context.getPrintingPolicy());
|
||||||
if (!defArg->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,36 +474,12 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (arg.getKind() == clang::TemplateArgument::Expression)
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
{
|
{
|
||||||
const clang::Expr* expr = arg.getAsExpr();
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
endianExpr = expr;
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
|
expr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
defaultEndian = false;
|
defaultEndian = false;
|
||||||
if (!expr->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t endianVal = endian.getSExtValue();
|
|
||||||
if (endianVal != 0 && endianVal != 1)
|
|
||||||
{
|
|
||||||
if (endianExpr)
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ioOp;
|
std::string ioOp;
|
||||||
bool isDNAType = false;
|
bool isDNAType = false;
|
||||||
for (const clang::TemplateArgument& arg : *tsType)
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
@ -520,7 +489,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (defaultEndian)
|
if (defaultEndian)
|
||||||
ioOp = GetOpString(fieldName, propIdExpr);
|
ioOp = GetOpString(fieldName, propIdExpr);
|
||||||
else
|
else
|
||||||
ioOp = GetOpString(fieldName, propIdExpr, endianVal);
|
ioOp = GetOpString(fieldName, propIdExpr, endianExprStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,7 +506,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
else if (!tsDecl->getName().compare("Vector"))
|
else if (!tsDecl->getName().compare("Vector"))
|
||||||
{
|
{
|
||||||
llvm::APSInt endian(64, -1);
|
llvm::APSInt endian(64, -1);
|
||||||
const clang::Expr* endianExpr = nullptr;
|
std::string endianExprStr;
|
||||||
bool defaultEndian = true;
|
bool defaultEndian = true;
|
||||||
if (classParms->size() >= 3)
|
if (classParms->size() >= 3)
|
||||||
{
|
{
|
||||||
|
@ -545,21 +514,13 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
{
|
{
|
||||||
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
endianExpr = defArg;
|
nttParm->print(strStream, context.getPrintingPolicy());
|
||||||
if (!defArg->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sizeExpr;
|
std::string sizeExpr;
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
bool bad = false;
|
|
||||||
for (const clang::TemplateArgument& arg : *tsType)
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
{
|
{
|
||||||
if (arg.getKind() == clang::TemplateArgument::Expression)
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
@ -588,46 +549,19 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
llvm::raw_string_ostream strStream(sizeExpr);
|
llvm::raw_string_ostream strStream2(sizeExpr);
|
||||||
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
argExpr->printPretty(strStream2, nullptr, context.getPrintingPolicy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (idx == 2)
|
else if (idx == 2)
|
||||||
{
|
{
|
||||||
defaultEndian = false;
|
defaultEndian = false;
|
||||||
endianExpr = expr;
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
if (!expr->isIntegerConstantExpr(endian, context))
|
expr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
|
||||||
bad = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
if (bad)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int64_t endianVal = endian.getSExtValue();
|
|
||||||
if (endianVal != 0 && endianVal != 1)
|
|
||||||
{
|
|
||||||
if (endianExpr)
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
clang::QualType templateType;
|
clang::QualType templateType;
|
||||||
std::string ioOp;
|
std::string ioOp;
|
||||||
|
@ -640,7 +574,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (defaultEndian)
|
if (defaultEndian)
|
||||||
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExpr);
|
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExpr);
|
||||||
else
|
else
|
||||||
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExpr, endianVal);
|
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExpr, endianExprStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,7 +675,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
else if (!tsDecl->getName().compare("WString"))
|
else if (!tsDecl->getName().compare("WString"))
|
||||||
{
|
{
|
||||||
llvm::APSInt endian(64, -1);
|
llvm::APSInt endian(64, -1);
|
||||||
const clang::Expr* endianExpr = nullptr;
|
std::string endianExprStr;
|
||||||
bool defaultEndian = true;
|
bool defaultEndian = true;
|
||||||
if (classParms->size() >= 2)
|
if (classParms->size() >= 2)
|
||||||
{
|
{
|
||||||
|
@ -749,21 +683,13 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
{
|
{
|
||||||
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
endianExpr = defArg;
|
nttParm->print(strStream, context.getPrintingPolicy());
|
||||||
if (!defArg->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sizeExprStr;
|
std::string sizeExprStr;
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
bool bad = false;
|
|
||||||
for (const clang::TemplateArgument& arg : *tsType)
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
{
|
{
|
||||||
if (arg.getKind() == clang::TemplateArgument::Expression)
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
@ -779,8 +705,8 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
||||||
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
||||||
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
||||||
llvm::raw_string_ostream strStream(sizeExprStr);
|
llvm::raw_string_ostream strStream2(sizeExprStr);
|
||||||
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
argExpr->printPretty(strStream2, nullptr, context.getPrintingPolicy());
|
||||||
}
|
}
|
||||||
else if (expr->isIntegerConstantExpr(sizeLiteral, context))
|
else if (expr->isIntegerConstantExpr(sizeLiteral, context))
|
||||||
{
|
{
|
||||||
|
@ -790,39 +716,12 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
else if (idx == 1)
|
else if (idx == 1)
|
||||||
{
|
{
|
||||||
defaultEndian = false;
|
defaultEndian = false;
|
||||||
endianExpr = expr;
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
if (!expr->isIntegerConstantExpr(endian, context))
|
expr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
|
||||||
bad = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
if (bad)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int64_t endianVal = endian.getSExtValue();
|
|
||||||
if (endianVal != 0 && endianVal != 1)
|
|
||||||
{
|
|
||||||
if (endianExpr)
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ioOp;
|
std::string ioOp;
|
||||||
if (!sizeExprStr.empty())
|
if (!sizeExprStr.empty())
|
||||||
|
@ -830,14 +729,14 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (defaultEndian)
|
if (defaultEndian)
|
||||||
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExprStr);
|
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExprStr);
|
||||||
else
|
else
|
||||||
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExprStr, endianVal);
|
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExprStr, endianExprStr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (defaultEndian)
|
if (defaultEndian)
|
||||||
ioOp = GetOpString(fieldName, propIdExpr);
|
ioOp = GetOpString(fieldName, propIdExpr);
|
||||||
else
|
else
|
||||||
ioOp = GetOpString(fieldName, propIdExpr, endianVal);
|
ioOp = GetOpString(fieldName, propIdExpr, endianExprStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
outputNodes.emplace_back(NodeType::Do, fieldName, ioOp, false);
|
outputNodes.emplace_back(NodeType::Do, fieldName, ioOp, false);
|
||||||
|
@ -943,6 +842,16 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
outputNodes.emplace_back(NodeType::DoAlign, fieldName, "<Op>("s + align.toString(10, true) + ", s)", false);
|
outputNodes.emplace_back(NodeType::DoAlign, fieldName, "<Op>("s + align.toString(10, true) + ", s)", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const clang::NamedDecl* nd = tsDecl->getTemplatedDecl();
|
||||||
|
if (const clang::CXXRecordDecl* rd = clang::dyn_cast_or_null<clang::CXXRecordDecl>(nd))
|
||||||
|
{
|
||||||
|
std::string baseDNA;
|
||||||
|
if (isDNARecord(rd, baseDNA))
|
||||||
|
outputNodes.emplace_back(NodeType::Do, fieldName, GetOpString(fieldName, propIdExpr), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (regType->getTypeClass() == clang::Type::Record)
|
else if (regType->getTypeClass() == clang::Type::Record)
|
||||||
|
@ -1025,7 +934,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (!tsDecl->getName().compare("Value"))
|
if (!tsDecl->getName().compare("Value"))
|
||||||
{
|
{
|
||||||
llvm::APSInt endian(64, -1);
|
llvm::APSInt endian(64, -1);
|
||||||
const clang::Expr* endianExpr = nullptr;
|
std::string endianExprStr;
|
||||||
bool defaultEndian = true;
|
bool defaultEndian = true;
|
||||||
if (classParms->size() >= 2)
|
if (classParms->size() >= 2)
|
||||||
{
|
{
|
||||||
|
@ -1033,15 +942,8 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
{
|
{
|
||||||
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
endianExpr = defArg;
|
nttParm->print(strStream, context.getPrintingPolicy());
|
||||||
if (!defArg->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,36 +952,12 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (arg.getKind() == clang::TemplateArgument::Expression)
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
{
|
{
|
||||||
const clang::Expr* expr = arg.getAsExpr();
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
endianExpr = expr;
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
|
expr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
defaultEndian = false;
|
defaultEndian = false;
|
||||||
if (!expr->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t endianVal = endian.getSExtValue();
|
|
||||||
if (endianVal != 0 && endianVal != 1)
|
|
||||||
{
|
|
||||||
if (endianExpr)
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ioOp;
|
std::string ioOp;
|
||||||
bool isDNAType = false;
|
bool isDNAType = false;
|
||||||
for (const clang::TemplateArgument& arg : *tsType)
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
@ -1089,7 +967,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (defaultEndian)
|
if (defaultEndian)
|
||||||
ioOp = GetOpString(fieldName, propIdExpr);
|
ioOp = GetOpString(fieldName, propIdExpr);
|
||||||
else
|
else
|
||||||
ioOp = GetOpString(fieldName, propIdExpr, endianVal);
|
ioOp = GetOpString(fieldName, propIdExpr, endianExprStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,7 +987,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
else if (!tsDecl->getName().compare("Vector"))
|
else if (!tsDecl->getName().compare("Vector"))
|
||||||
{
|
{
|
||||||
llvm::APSInt endian(64, -1);
|
llvm::APSInt endian(64, -1);
|
||||||
const clang::Expr* endianExpr = nullptr;
|
std::string endianExprStr;
|
||||||
bool defaultEndian = true;
|
bool defaultEndian = true;
|
||||||
if (classParms->size() >= 3)
|
if (classParms->size() >= 3)
|
||||||
{
|
{
|
||||||
|
@ -1117,21 +995,13 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
{
|
{
|
||||||
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
endianExpr = defArg;
|
nttParm->print(strStream, context.getPrintingPolicy());
|
||||||
if (!defArg->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sizeExpr;
|
std::string sizeExpr;
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
bool bad = false;
|
|
||||||
for (const clang::TemplateArgument& arg : *tsType)
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
{
|
{
|
||||||
if (arg.getKind() == clang::TemplateArgument::Expression)
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
@ -1146,46 +1016,19 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
||||||
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
||||||
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
||||||
llvm::raw_string_ostream strStream(sizeExpr);
|
llvm::raw_string_ostream strStream2(sizeExpr);
|
||||||
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
argExpr->printPretty(strStream2, nullptr, context.getPrintingPolicy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (idx == 2)
|
else if (idx == 2)
|
||||||
{
|
{
|
||||||
endianExpr = expr;
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
|
expr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
defaultEndian = false;
|
defaultEndian = false;
|
||||||
if (!expr->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
|
||||||
bad = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
if (bad)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int64_t endianVal = endian.getSExtValue();
|
|
||||||
if (endianVal != 0 && endianVal != 1)
|
|
||||||
{
|
|
||||||
if (endianExpr)
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
clang::QualType templateType;
|
clang::QualType templateType;
|
||||||
std::string ioOp;
|
std::string ioOp;
|
||||||
|
@ -1198,7 +1041,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (defaultEndian)
|
if (defaultEndian)
|
||||||
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExpr);
|
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExpr);
|
||||||
else
|
else
|
||||||
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExpr, endianVal);
|
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExpr, endianExprStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1305,7 +1148,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
else if (!tsDecl->getName().compare("WString"))
|
else if (!tsDecl->getName().compare("WString"))
|
||||||
{
|
{
|
||||||
llvm::APSInt endian(64, -1);
|
llvm::APSInt endian(64, -1);
|
||||||
const clang::Expr* endianExpr = nullptr;
|
std::string endianExprStr;
|
||||||
bool defaultEndian = true;
|
bool defaultEndian = true;
|
||||||
if (classParms->size() >= 2)
|
if (classParms->size() >= 2)
|
||||||
{
|
{
|
||||||
|
@ -1313,21 +1156,13 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
{
|
{
|
||||||
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
endianExpr = defArg;
|
nttParm->print(strStream, context.getPrintingPolicy());
|
||||||
if (!defArg->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sizeExprStr;
|
std::string sizeExprStr;
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
bool bad = false;
|
|
||||||
for (const clang::TemplateArgument& arg : *tsType)
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
{
|
{
|
||||||
if (arg.getKind() == clang::TemplateArgument::Expression)
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
@ -1343,8 +1178,8 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
||||||
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
||||||
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
||||||
llvm::raw_string_ostream strStream(sizeExprStr);
|
llvm::raw_string_ostream strStream2(sizeExprStr);
|
||||||
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
argExpr->printPretty(strStream2, nullptr, context.getPrintingPolicy());
|
||||||
}
|
}
|
||||||
else if (expr->isIntegerConstantExpr(sizeLiteral, context))
|
else if (expr->isIntegerConstantExpr(sizeLiteral, context))
|
||||||
{
|
{
|
||||||
|
@ -1353,40 +1188,13 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
}
|
}
|
||||||
else if (idx == 1)
|
else if (idx == 1)
|
||||||
{
|
{
|
||||||
endianExpr = expr;
|
llvm::raw_string_ostream strStream(endianExprStr);
|
||||||
|
expr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
defaultEndian = false;
|
defaultEndian = false;
|
||||||
if (!expr->isIntegerConstantExpr(endian, context))
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
|
||||||
bad = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
if (bad)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int64_t endianVal = endian.getSExtValue();
|
|
||||||
if (endianVal != 0 && endianVal != 1)
|
|
||||||
{
|
|
||||||
if (endianExpr)
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
|
||||||
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ioOp;
|
std::string ioOp;
|
||||||
if (!sizeExprStr.empty())
|
if (!sizeExprStr.empty())
|
||||||
|
@ -1394,20 +1202,34 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
if (defaultEndian)
|
if (defaultEndian)
|
||||||
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExprStr);
|
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExprStr);
|
||||||
else
|
else
|
||||||
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExprStr, endianVal);
|
ioOp = GetVectorOpString(fieldName, propIdExpr, sizeExprStr, endianExprStr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (defaultEndian)
|
if (defaultEndian)
|
||||||
ioOp = GetOpString(fieldName, propIdExpr);
|
ioOp = GetOpString(fieldName, propIdExpr);
|
||||||
else
|
else
|
||||||
ioOp = GetOpString(fieldName, propIdExpr, endianVal);
|
ioOp = GetOpString(fieldName, propIdExpr, endianExprStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fileOut << " AT_PROP_CASE(" << propIdExpr << "):\n"
|
fileOut << " AT_PROP_CASE(" << propIdExpr << "):\n"
|
||||||
<< " Do" << ioOp << ";\n"
|
<< " Do" << ioOp << ";\n"
|
||||||
<< " return true;\n";
|
<< " return true;\n";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const clang::NamedDecl* nd = tsDecl->getTemplatedDecl();
|
||||||
|
if (const clang::CXXRecordDecl* rd = clang::dyn_cast_or_null<clang::CXXRecordDecl>(nd))
|
||||||
|
{
|
||||||
|
std::string baseDNA;
|
||||||
|
if (isDNARecord(rd, baseDNA))
|
||||||
|
{
|
||||||
|
fileOut << " AT_PROP_CASE(" << propIdExpr << "):\n"
|
||||||
|
<< " Do" << GetOpString(fieldName, propIdExpr) << ";\n"
|
||||||
|
<< " return true;\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (regType->getTypeClass() == clang::Type::Record)
|
else if (regType->getTypeClass() == clang::Type::Record)
|
||||||
|
@ -1462,7 +1284,7 @@ public:
|
||||||
bool isPropDNA = false;
|
bool isPropDNA = false;
|
||||||
for (const clang::Decl* d : decl->decls())
|
for (const clang::Decl* d : decl->decls())
|
||||||
if (const clang::FunctionTemplateDecl* m = clang::dyn_cast_or_null<clang::FunctionTemplateDecl>(d))
|
if (const clang::FunctionTemplateDecl* m = clang::dyn_cast_or_null<clang::FunctionTemplateDecl>(d))
|
||||||
if (!m->getName().compare(llvm::StringLiteral("Lookup")))
|
if (m->getDeclName().isIdentifier() && !m->getName().compare(llvm::StringLiteral("Lookup")))
|
||||||
{
|
{
|
||||||
isPropDNA = true;
|
isPropDNA = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -207,7 +207,7 @@ std::string& rtrim(std::string& s);
|
||||||
// trim from both ends
|
// trim from both ends
|
||||||
std::string& trim(std::string& s);
|
std::string& trim(std::string& s);
|
||||||
atUint64 fileSize(std::string_view filename);
|
atUint64 fileSize(std::string_view filename);
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
atUint64 fileSize(std::wstring_view filename);
|
atUint64 fileSize(std::wstring_view filename);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
RecordRAII() = default;
|
RecordRAII() = default;
|
||||||
public:
|
public:
|
||||||
operator bool() const { return m_r != nullptr; }
|
operator bool() const { return m_r != nullptr; }
|
||||||
|
void leave() { if (m_r) {m_r->_leaveSubRecord(); m_r = nullptr;} }
|
||||||
~RecordRAII() { if (m_r) m_r->_leaveSubRecord(); }
|
~RecordRAII() { if (m_r) m_r->_leaveSubRecord(); }
|
||||||
};
|
};
|
||||||
friend class RecordRAII;
|
friend class RecordRAII;
|
||||||
|
|
|
@ -169,7 +169,7 @@ atUint64 fileSize(std::string_view filename)
|
||||||
return st.st_size;
|
return st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
atUint64 fileSize(std::wstring_view filename)
|
atUint64 fileSize(std::wstring_view filename)
|
||||||
{
|
{
|
||||||
atStat64_t st;
|
atStat64_t st;
|
||||||
|
|
Loading…
Reference in New Issue