From ade6a171b81326398f092a851a4f48c82b9862ac Mon Sep 17 00:00:00 2001 From: Thilina Ratnayaka Date: Wed, 20 Sep 2023 00:53:04 -0500 Subject: [PATCH 1/3] [nomp] Fix parsing errors in nomp_init() --- .../clang/Basic/DiagnosticParseKinds.td | 2 +- clang/lib/Parse/ParseNomp.cpp | 104 +++++++++++++++--- 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 8aae97305103..ebdd606bb56e 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1528,7 +1528,7 @@ def err_nomp_eod_expected: Error< def err_nomp_identifier_expected: Error< "Expected a variable name at line %0, column %1">; def err_nomp_function_arg_invalid: Error< - "Invalid argument type at line %0, column %1">; + "Invalid argument type at line %0, column %1: %2">; def err_nomp_pointer_type_expected: Error< "Expected a pointer in the nomp directive '%0' at line %1, column %2">; def err_nomp_for_expected: Error< diff --git a/clang/lib/Parse/ParseNomp.cpp b/clang/lib/Parse/ParseNomp.cpp index 24af38c9e3e1..dfd47d5c5a37 100644 --- a/clang/lib/Parse/ParseNomp.cpp +++ b/clang/lib/Parse/ParseNomp.cpp @@ -155,7 +155,7 @@ static inline void NompHandleError(unsigned DiagID, SourceLocation SL, << loc.getLineNumber() << loc.getColumnNumber(); else AST.getDiagnostics().Report(loc, DiagID) - << Arg << loc.getLineNumber() << loc.getColumnNumber(); + << loc.getLineNumber() << loc.getColumnNumber() << Arg; } //============================================================================== @@ -240,17 +240,97 @@ void Parser::ParseNompExprListUntilRParen(llvm::SmallVector &EL, NompHandleError(diag::err_nomp_rparen_expected, Tok, *this, Pragma); } -static Expr *ExprToICE(Expr *E, const ASTContext &AST, QualType QT, - CastKind CK) { - if (IntegerLiteral *IL = dyn_cast_or_null(E)) { - // FIXME: If it is a Literal, use as is. Need to add checks for - // StringLiteral, FloatLiteral, etc. - return IL; +static Expr *ExprToArgc(Expr *E, ASTContext &AST) { + const Type *T = E->getType().getTypePtr(); + if (!T->isIntegerType() && !T->isFloatingType()) { + NompHandleError(diag::err_nomp_function_arg_invalid, E->getExprLoc(), AST, + "Parameter `argc` of nomp_init() must be an Integer type."); + return nullptr; + } + + QualType QT = getIntType(AST); + Expr *Argc = nullptr; + + // If this is a DRE, we need to do LValueToRvalue cast. Otherwise, we just + // set the Argc to E. + if (DeclRefExpr *DRE = dyn_cast_or_null(E)) { + Argc = ImplicitCastExpr::Create( + AST, DRE->getType(), CastKind::CK_LValueToRValue, DRE, nullptr, + ExprValueKind::VK_PRValue, FPOptionsOverride()); } else { - // If it is a Expr, do an ICE. - return ImplicitCastExpr::Create(AST, QT, CK, E, nullptr, VK_PRValue, + Argc = E; + } + + // If this is a floating type, we need to do FloatingToIntegral cast. + if (T->isFloatingType()) { + Argc = ImplicitCastExpr::Create(AST, QT, CastKind::CK_FloatingToIntegral, + Argc, nullptr, ExprValueKind::VK_PRValue, + FPOptionsOverride()); + } + + return Argc; +} + +static Expr *ExprToArgv(Expr *E, ASTContext &AST) { +#define check_cond(cond) \ + { \ + if (!cond) { \ + NompHandleError(diag::err_nomp_function_arg_invalid, E->getExprLoc(), \ + AST, \ + "Parameter `argv` of nomp_init() must be an variable " \ + "which reference an array of C-strings or " \ + "pointer to an array of C-strings."); \ + return nullptr; \ + } \ + } + + // We should have a variable pointing to array of C-strings or a pointer to + // an array of C-strings as the argv. + + // So, we first check if this is a DeclRefExpr since we are only accepting + // variables to pointer or array types. + bool isa_variable = false; + if (DeclRefExpr *DRE = dyn_cast_or_null(E)) { + // If this is a DeclRefExpr, we need to check if it is a variable. + if (isa(DRE->getDecl())) + isa_variable = true; + } + check_cond(isa_variable); + + // Then, check if it is a variable of an array or a pointer type. + bool isa_array_or_pointer = false; + const Type *T = E->getType().getTypePtr(); + if (T->isPointerType() || T->isArrayType()) + isa_array_or_pointer = true; + check_cond(isa_array_or_pointer); + + // If it is an array or a pointer, then we check if the base type is a + // C-string. + bool isa_cstring = false; + const Type *B = T->getPointeeOrArrayElementType(); + if (B->isPointerType() && B->getPointeeType()->isCharType()) + isa_cstring = true; + check_cond(isa_cstring); + + QualType QT = AST.getPointerType(AST.getConstType(AST.CharTy)); + QT = AST.getPointerType(QT); + // If this is an array, we need to do ArrayToPointerDecay cast. + if (T->isArrayType()) { + return ImplicitCastExpr::Create(AST, QT, CastKind::CK_ArrayToPointerDecay, + E, nullptr, ExprValueKind::VK_PRValue, + FPOptionsOverride()); + } + + // If this is a pointer type, we do an LValueToRValue cast. + if (T->isPointerType()) { + return ImplicitCastExpr::Create(AST, QT, CastKind::CK_LValueToRValue, E, + nullptr, ExprValueKind::VK_PRValue, FPOptionsOverride()); } + + return nullptr; + +#undef check_cond } //============================================================================== @@ -279,10 +359,8 @@ StmtResult Parser::ParseNompInit(const SourceLocation &SL) { // Conver Expr* to function arguments. llvm::SmallVector FuncArgs; Expr *Argv = InitArgs.pop_back_val(), *Argc = InitArgs.pop_back_val(); - FuncArgs.push_back( - ExprToICE(Argc, AST, getIntType(AST), CastKind::CK_LValueToRValue)); - FuncArgs.push_back( - ExprToICE(Argv, AST, getIntType(AST), CastKind::CK_LValueToRValue)); + FuncArgs.push_back(ExprToArgc(Argc, AST)); + FuncArgs.push_back(ExprToArgv(Argv, AST)); ConsumeAnnotationToken(); // tok::annot_pragma_nomp_end From a2997e35ff8f30cc043de8a4fe09e33948802f74 Mon Sep 17 00:00:00 2001 From: Thilina Ratnayaka Date: Wed, 20 Sep 2023 16:37:01 -0500 Subject: [PATCH 2/3] [nomp] Print canonical types to expand typedefs --- clang/lib/Parse/ParseNomp.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/clang/lib/Parse/ParseNomp.cpp b/clang/lib/Parse/ParseNomp.cpp index dfd47d5c5a37..7c94dfbb44b2 100644 --- a/clang/lib/Parse/ParseNomp.cpp +++ b/clang/lib/Parse/ParseNomp.cpp @@ -577,6 +577,7 @@ static void GetExtVarsAndKnl(std::set &EV, std::string &KnlStr, clang::PrintingPolicy Policy(Opts); Policy.SuppressInitializers = true; + Policy.PrintCanonicalTypes = true; llvm::raw_string_ostream KnlStream(KnlStr); KnlStream << "void " << KnlName << "("; @@ -592,12 +593,8 @@ static void GetExtVarsAndKnl(std::set &EV, std::string &KnlStr, } KnlStream << " {\n"; - SourceLocation BL = FS->getBeginLoc(), EL = FS->getEndLoc(); - llvm::StringRef bfr = SM.getBufferData(SM.getFileID(BL)); - unsigned s = SM.getFileOffset(BL), e = SM.getFileOffset(EL), n = e; - for (; n < bfr.size() && bfr[n] != ';' && bfr[n] != '}'; n++) - ; - KnlStream << std::string(bfr.data() + s, n - s + 2) << "}"; + FS->printPretty(KnlStream, nullptr, Policy, 0); + KnlStream << "}"; } static void CreateNompJitCall(llvm::SmallVector &Stmts, From d79c747a838fed72aec56f1ee5897a5bee110877 Mon Sep 17 00:00:00 2001 From: Thilina Ratnayaka Date: Wed, 20 Sep 2023 17:51:18 -0500 Subject: [PATCH 3/3] [nomp] Don't suppress initializers in printPretty() --- clang/lib/Parse/ParseNomp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseNomp.cpp b/clang/lib/Parse/ParseNomp.cpp index 7c94dfbb44b2..b7dff712af6c 100644 --- a/clang/lib/Parse/ParseNomp.cpp +++ b/clang/lib/Parse/ParseNomp.cpp @@ -576,7 +576,7 @@ static void GetExtVarsAndKnl(std::set &EV, std::string &KnlStr, ExtVars.GetExternalVarDecls(EV); clang::PrintingPolicy Policy(Opts); - Policy.SuppressInitializers = true; + Policy.SuppressInitializers = false; Policy.PrintCanonicalTypes = true; llvm::raw_string_ostream KnlStream(KnlStr);