@@ -361,3 +361,85 @@ public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
361361
362362 return s;
363363}
364+
365+ unittest
366+ {
367+ uint errors = global.startGagging();
368+
369+ // Immitates asmSemantic if version = IN_GCC.
370+ static int semanticAsm (Token * tokens)
371+ {
372+ scope gas = new GccAsmStatement(Loc.initial, tokens);
373+ scope p = new Parser! ASTCodegen(null , " ;" , false );
374+ p.token = * tokens;
375+ p.parseGccAsm(gas);
376+ return p.errors;
377+ }
378+
379+ // Immitates parseStatement for asm statements.
380+ static void parseAsm (string input, bool expectError)
381+ {
382+ // Generate tokens from input test.
383+ scope p = new Parser! ASTCodegen(null , input, false );
384+ p.nextToken();
385+ p.check(TOK .asm_);
386+ p.check(TOK .leftCurly);
387+
388+ Token * toklist = null ;
389+ Token ** ptoklist = &toklist;
390+ while (1 )
391+ {
392+ if (p.token.value == TOK .rightCurly || p.token.value == TOK .endOfFile)
393+ break ;
394+ * ptoklist = Token .alloc();
395+ memcpy(* ptoklist, &p.token, Token .sizeof);
396+ ptoklist = &(* ptoklist).next;
397+ * ptoklist = null ;
398+ p.nextToken();
399+ }
400+ p.check(TOK .rightCurly);
401+
402+ auto res = semanticAsm(toklist);
403+ assert (res == 0 || expectError);
404+ }
405+
406+ // / Assembly Tests, all should pass.
407+ // / Note: Frontend is not initialized, use only strings and identifiers.
408+ immutable string [] passAsmTests = [
409+ // Basic asm statement
410+ q{ asm { " nop" ;
411+ } },
412+
413+ // Extended asm statement
414+ q{ asm { " cpuid"
415+ : " =a" (a), " =b" (b), " =c" (c), " =d" (d)
416+ : " a" input;
417+ } },
418+
419+ // Assembly with symbolic names
420+ q{ asm { " bts %[base], %[offset]"
421+ : [base] " +rm" * ptr,
422+ : [offset] " Ir" bitnum;
423+ } },
424+
425+ // Assembly with clobbers
426+ q{ asm { " cpuid"
427+ : " =a" a
428+ : " a" input
429+ : " ebx" , " ecx" , " edx" ;
430+ } },
431+
432+ // Goto asm statement
433+ q{ asm { " jmp %l0"
434+ :
435+ :
436+ :
437+ : Ljmplabel;
438+ } },
439+ ];
440+
441+ foreach (test; passAsmTests)
442+ parseAsm(test, false );
443+
444+ global.endGagging(errors);
445+ }
0 commit comments