[PATCH] D127284: [clang-repl] Support statements on global scope in incremental mode.

Vassil Vassilev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 1 07:25:07 PDT 2022


v.g.vassilev added inline comments.


================
Comment at: clang/test/Interpreter/disambiguate-decl-stmt.cpp:28-33
+namespace Ns {namespace Ns { void Ns(); void Fs();}}
+void Ns::Ns::Ns() { printf("void Ns::Ns::Ns()\n"); }
+void Ns::Ns::Fs() {}
+
+Ns::Ns::Fs();
+Ns::Ns::Ns();
----------------
aaron.ballman wrote:
> v.g.vassilev wrote:
> > aaron.ballman wrote:
> > > This behavior is very confusing to me -- you cannot declare a namespace at function scope and you cannot call a function at file scope, so one of these two seems like it should not work.
> > > 
> > > (Same kinds of confusion happen elsewhere in the tests.)
> > The mental model has been that we have a mix of statements and declarations on the global scope. The sequence of statements are only considered to be as if they have been wrapped in a function body. For example:
> > 
> > ```
> > namespace Ns {namespace Ns { void Ns(); void Fs();}}
> > void Ns::Ns::Ns() { printf("void Ns::Ns::Ns()\n"); }
> > void Ns::Ns::Fs() {}
> > Ns::Ns::Fs();
> > Ns::Ns::Ns();
> > ```
> > 
> > should be semantically equivalent to:
> > 
> > ```
> > namespace Ns {namespace Ns { void Ns(); void Fs();}}
> > void Ns::Ns::Ns() { printf("void Ns::Ns::Ns()\n"); }
> > void Ns::Ns::Fs() {}
> > 
> > void stmt_block1() {
> >   Ns::Ns::Fs();
> >   Ns::Ns::Ns();
> > }
> > auto _ = (stmt_block1(), 1);
> > ```
> > 
> > Does that help in making it less confusing when thinking about it?
> > The mental model has been that we have a mix of statements and declarations on the global scope.
> 
> I don't understand that mental model because neither C nor C++ allow you to have statements at the global scope. So I'm not certain how to think about statements showing up there (and more importantly, the languages and the compiler wouldn't expect that anyway). For example, consider this:
> ```
> int n = 12;
> int array[n];
> ```
> This is valid at block scope and invalid at global scope: https://godbolt.org/z/8zxn3h79E
> 
> Similarly, consider this code:
> ```
> template <typename Ty>
> void func();
> ```
> This is valid at file scope but invalid at block scope.
> 
> My concern here is that it will be a game of whack-a-mole to identify all of these circumstances and try to get the semantics somewhat close to correct. What is the harm with the REPL always being a full TU, so if the user wants a block scope, they're responsible for writing a function and calling it from `main()`?
That was clarified in the off-list discussion. I will try to summarize it for having proper history:

Our new facility teaches the parser to recognize statements when they were not declarations. If they were declarations we prefer the language standard. If they were valid statements which are spelled out on the global scope we pretend they were written in block scope, form a function dedicated definition and order it for global initialization.

```
int n = 12;
int array[n];
```

is still invalid on global scope.

```
template <typename Ty>
void func();
```

is untouched. 



CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127284/new/

https://reviews.llvm.org/D127284



More information about the cfe-commits mailing list