@@ -155,7 +155,7 @@ static inline void NompHandleError(unsigned DiagID, SourceLocation SL,
155
155
<< loc.getLineNumber () << loc.getColumnNumber ();
156
156
else
157
157
AST.getDiagnostics ().Report (loc, DiagID)
158
- << Arg << loc.getLineNumber () << loc.getColumnNumber ();
158
+ << loc.getLineNumber () << loc.getColumnNumber () << Arg ;
159
159
}
160
160
161
161
// ==============================================================================
@@ -240,17 +240,97 @@ void Parser::ParseNompExprListUntilRParen(llvm::SmallVector<Expr *, 16> &EL,
240
240
NompHandleError (diag::err_nomp_rparen_expected, Tok, *this , Pragma);
241
241
}
242
242
243
- static Expr *ExprToICE (Expr *E, const ASTContext &AST, QualType QT,
244
- CastKind CK) {
245
- if (IntegerLiteral *IL = dyn_cast_or_null<IntegerLiteral>(E)) {
246
- // FIXME: If it is a Literal, use as is. Need to add checks for
247
- // StringLiteral, FloatLiteral, etc.
248
- return IL;
243
+ static Expr *ExprToArgc (Expr *E, ASTContext &AST) {
244
+ const Type *T = E->getType ().getTypePtr ();
245
+ if (!T->isIntegerType () && !T->isFloatingType ()) {
246
+ NompHandleError (diag::err_nomp_function_arg_invalid, E->getExprLoc (), AST,
247
+ " Parameter `argc` of nomp_init() must be an Integer type." );
248
+ return nullptr ;
249
+ }
250
+
251
+ QualType QT = getIntType (AST);
252
+ Expr *Argc = nullptr ;
253
+
254
+ // If this is a DRE, we need to do LValueToRvalue cast. Otherwise, we just
255
+ // set the Argc to E.
256
+ if (DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
257
+ Argc = ImplicitCastExpr::Create (
258
+ AST, DRE->getType (), CastKind::CK_LValueToRValue, DRE, nullptr ,
259
+ ExprValueKind::VK_PRValue, FPOptionsOverride ());
249
260
} else {
250
- // If it is a Expr, do an ICE.
251
- return ImplicitCastExpr::Create (AST, QT, CK, E, nullptr , VK_PRValue,
261
+ Argc = E;
262
+ }
263
+
264
+ // If this is a floating type, we need to do FloatingToIntegral cast.
265
+ if (T->isFloatingType ()) {
266
+ Argc = ImplicitCastExpr::Create (AST, QT, CastKind::CK_FloatingToIntegral,
267
+ Argc, nullptr , ExprValueKind::VK_PRValue,
268
+ FPOptionsOverride ());
269
+ }
270
+
271
+ return Argc;
272
+ }
273
+
274
+ static Expr *ExprToArgv (Expr *E, ASTContext &AST) {
275
+ #define check_cond (cond ) \
276
+ { \
277
+ if (!cond) { \
278
+ NompHandleError (diag::err_nomp_function_arg_invalid, E->getExprLoc (), \
279
+ AST, \
280
+ " Parameter `argv` of nomp_init() must be an variable " \
281
+ " which reference an array of C-strings or " \
282
+ " pointer to an array of C-strings." ); \
283
+ return nullptr ; \
284
+ } \
285
+ }
286
+
287
+ // We should have a variable pointing to array of C-strings or a pointer to
288
+ // an array of C-strings as the argv.
289
+
290
+ // So, we first check if this is a DeclRefExpr since we are only accepting
291
+ // variables to pointer or array types.
292
+ bool isa_variable = false ;
293
+ if (DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
294
+ // If this is a DeclRefExpr, we need to check if it is a variable.
295
+ if (isa<VarDecl>(DRE->getDecl ()))
296
+ isa_variable = true ;
297
+ }
298
+ check_cond (isa_variable);
299
+
300
+ // Then, check if it is a variable of an array or a pointer type.
301
+ bool isa_array_or_pointer = false ;
302
+ const Type *T = E->getType ().getTypePtr ();
303
+ if (T->isPointerType () || T->isArrayType ())
304
+ isa_array_or_pointer = true ;
305
+ check_cond (isa_array_or_pointer);
306
+
307
+ // If it is an array or a pointer, then we check if the base type is a
308
+ // C-string.
309
+ bool isa_cstring = false ;
310
+ const Type *B = T->getPointeeOrArrayElementType ();
311
+ if (B->isPointerType () && B->getPointeeType ()->isCharType ())
312
+ isa_cstring = true ;
313
+ check_cond (isa_cstring);
314
+
315
+ QualType QT = AST.getPointerType (AST.getConstType (AST.CharTy ));
316
+ QT = AST.getPointerType (QT);
317
+ // If this is an array, we need to do ArrayToPointerDecay cast.
318
+ if (T->isArrayType ()) {
319
+ return ImplicitCastExpr::Create (AST, QT, CastKind::CK_ArrayToPointerDecay,
320
+ E, nullptr , ExprValueKind::VK_PRValue,
321
+ FPOptionsOverride ());
322
+ }
323
+
324
+ // If this is a pointer type, we do an LValueToRValue cast.
325
+ if (T->isPointerType ()) {
326
+ return ImplicitCastExpr::Create (AST, QT, CastKind::CK_LValueToRValue, E,
327
+ nullptr , ExprValueKind::VK_PRValue,
252
328
FPOptionsOverride ());
253
329
}
330
+
331
+ return nullptr ;
332
+
333
+ #undef check_cond
254
334
}
255
335
256
336
// ==============================================================================
@@ -279,10 +359,8 @@ StmtResult Parser::ParseNompInit(const SourceLocation &SL) {
279
359
// Conver Expr* to function arguments.
280
360
llvm::SmallVector<Expr *, 2 > FuncArgs;
281
361
Expr *Argv = InitArgs.pop_back_val (), *Argc = InitArgs.pop_back_val ();
282
- FuncArgs.push_back (
283
- ExprToICE (Argc, AST, getIntType (AST), CastKind::CK_LValueToRValue));
284
- FuncArgs.push_back (
285
- ExprToICE (Argv, AST, getIntType (AST), CastKind::CK_LValueToRValue));
362
+ FuncArgs.push_back (ExprToArgc (Argc, AST));
363
+ FuncArgs.push_back (ExprToArgv (Argv, AST));
286
364
287
365
ConsumeAnnotationToken (); // tok::annot_pragma_nomp_end
288
366
0 commit comments