Recent Posts

Pages: 1 ... 8 9 [10]
91
Implementation Details / Re: LLVM/C gen
« Last post by lerno on November 29, 2018, 02:38:19 PM »
From Clang:

Code: [Select]
void CodeGenFunction::EmitForStmt(const ForStmt &S,
                                  ArrayRef<const Attr *> ForAttrs) {
  JumpDest LoopExit = getJumpDestInCurrentScope("for.end");

  LexicalScope ForScope(*this, S.getSourceRange());

  // Evaluate the first part before the loop.
  if (S.getInit())
    EmitStmt(S.getInit());

  // Start the loop with a block that tests the condition.
  // If there's an increment, the continue scope will be overwritten
  // later.
  JumpDest Continue = getJumpDestInCurrentScope("for.cond");
  llvm::BasicBlock *CondBlock = Continue.getBlock();
  EmitBlock(CondBlock);

  const SourceRange &R = S.getSourceRange();
  LoopStack.push(CondBlock, CGM.getContext(), ForAttrs,
                 SourceLocToDebugLoc(R.getBegin()),
                 SourceLocToDebugLoc(R.getEnd()));

  // If the for loop doesn't have an increment we can just use the
  // condition as the continue block.  Otherwise we'll need to create
  // a block for it (in the current scope, i.e. in the scope of the
  // condition), and that we will become our continue block.
  if (S.getInc())
    Continue = getJumpDestInCurrentScope("for.inc");

  // Store the blocks to use for break and continue.
  BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));

  // Create a cleanup scope for the condition variable cleanups.
  LexicalScope ConditionScope(*this, S.getSourceRange());

  if (S.getCond()) {
    // If the for statement has a condition scope, emit the local variable
    // declaration.
    if (S.getConditionVariable()) {
      EmitAutoVarDecl(*S.getConditionVariable());
    }

    llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
    // If there are any cleanups between here and the loop-exit scope,
    // create a block to stage a loop exit along.
    if (ForScope.requiresCleanups())
      ExitBlock = createBasicBlock("for.cond.cleanup");

    // As long as the condition is true, iterate the loop.
    llvm::BasicBlock *ForBody = createBasicBlock("for.body");

    // C99 6.8.5p2/p4: The first substatement is executed if the expression
    // compares unequal to 0.  The condition must be a scalar type.
    llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
    Builder.CreateCondBr(
        BoolCondVal, ForBody, ExitBlock,
        createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody())));

    if (ExitBlock != LoopExit.getBlock()) {
      EmitBlock(ExitBlock);
      EmitBranchThroughCleanup(LoopExit);
    }

    EmitBlock(ForBody);
  } else {
    // Treat it as a non-zero constant.  Don't even create a new block for the
    // body, just fall into it.
  }
  incrementProfileCounter(&S);

  {
    // Create a separate cleanup scope for the body, in case it is not
    // a compound statement.
    RunCleanupsScope BodyScope(*this);
    EmitStmt(S.getBody());
  }

  // If there is an increment, emit it next.
  if (S.getInc()) {
    EmitBlock(Continue.getBlock());
    EmitStmt(S.getInc());
  }

  BreakContinueStack.pop_back();

  ConditionScope.ForceCleanup();

  EmitStopPoint(&S);
  EmitBranch(CondBlock);

  ForScope.ForceCleanup();

  LoopStack.pop();

  // Emit the fall-through block.
  EmitBlock(LoopExit.getBlock(), true);
}

Here, "EmitStopPoint" is the part that emits debug information. It's in more places as well.

Code: [Select]
void CodeGenFunction::EmitStopPoint(const Stmt *S) {
  if (CGDebugInfo *DI = getDebugInfo()) {
    SourceLocation Loc;
    Loc = S->getLocStart();
    DI->EmitLocation(Builder, Loc);

    LastStopPoint = Loc;
  }
}
92
Implementation Details / Re: Code formatting of C2's c++
« Last post by lerno on November 29, 2018, 02:30:08 PM »
I'm just in favour for making the dangling else unambiguous always. Code like

Code: [Select]
if (foo) if (bar) baz(); else foobar();


... should never ever be written. :D Requiring braces for if-else prevents ambiguous code.

Someone might write:
Code: [Select]
if (foo)
  if (bar) baz();
else
  foobar();


But what they get is:
Code: [Select]
if (foo)
  if (bar)
    baz();
  else
    foobar();


This is never ambiguous:
Code: [Select]
if (foo) {
  if (bar) baz();
} else {
  foobar();
}
// or
if (foo)
  if (bar) {
   baz();
  } else {
    foobar();
  }


if we allow if (foo) { ... } else ... / if (goo) ... else { ... } (that is, braces is needed for at least one part), then that would solve ambiguity as well.

We would be allowing if ( ... ) ...; so we're not locking down short ifs. Just preventing ambiguous if-else constructs.
93
Implementation Details / Re: Suppress warnings
« Last post by lerno on November 29, 2018, 02:13:23 PM »
Something like @(nocheck=unused_variable | implicit_conversion)?
94
Ideas / Re: Switch proposal
« Last post by lerno on November 29, 2018, 02:11:28 PM »
I think fallthrough automatically on empty is very inconsistent. Consider this, with impllcit break:

Code: [Select]
func void printTest(i32 foo) {
 switch (foo) {
   case 1:
     printf("A\n");
   case 2:
     printf("B\n");
   default:
     // Do nothing
  }
}
printTest(1);

Prints "A"

Now we decide to comment out printf("A\n");

Code: [Select]
func void printTest(i32 foo) {
 switch (foo) {
   case 1:
     // printf("A\n");
   case 2:
     printf("B\n");
   default:
     // Do nothing
  }
}
printTest(1);

Now this prints "B". Perhaps not what we expected... So I think case 1, is a better suggestion for empty fallthrough (version C)
95
General Discussion / Re: Overwriting fields in init struct.
« Last post by bas on November 29, 2018, 08:26:05 AM »
Which unit test?
96
will do..
97
Implementation Details / Re: LLVM/C gen
« Last post by bas on November 29, 2018, 08:18:50 AM »
What do you mean exactly? do you have a code reference for that?
98
Implementation Details / Re: Code formatting of C2's c++
« Last post by bas on November 29, 2018, 08:17:55 AM »
We could have the analyser check that if either the if or else body has braces, that they both have. If not, just give an error.

I wouldn't really want to prevent developers from writing a short if/else and always require braces. It's a matter of style at
some point. On the todo-list is a clang-format like style program that styles C2 code. That tool could be used to check/fix
this as well. That removes it from the language and puts it in the style part...
99
Implementation Details / Re: Suppress warnings
« Last post by bas on November 29, 2018, 08:13:29 AM »
The only warnings in C2 so far are unused decls/imports/etc, all other issues are just errors.

I don't like pragma's either, very ugly. But I also don't like abusing comments. I think all stuff related
to meta issues (like packed, etc) could just be attributes. So @(..). That way the language syntax
is still the same, but we just have to add some possible attribute points..
100
Ideas / Re: Switch proposal
« Last post by bas on November 29, 2018, 08:08:56 AM »
Wow, that's a lot of posts in one day..

The case of
Code: [Select]
case 3| looks quite nice, but it differs from the case where you have some code, but also a fall-through.
I want to simplify the language as much as possible, so I don't really want to change the current behavior too much. If you think
about the possible bugs that often occur is only that a develop forgets to add the break keyword. So the only needed option I
think is to add the fallthrough keyword and require that for all fallthroughs. So for example:

Code: [Select]
case 1:
   break;
case 2:
   fallthrough;
case 3:
   fallthrough:
default:
   // ...

or maybe even allow empty cases to fallthrough without keyword to make code with lots of fallthrough's better readable

Code: [Select]
case 1:
   break;
case 2:  // allowed because empty case
case 3:
   fallthrough;
default:
   // ..
Pages: 1 ... 8 9 [10]