This is an archive of the discontinued LLVM Phabricator instance.

[C++2a] P0634r3: Down with typename!
ClosedPublic

Authored by ayzhao on Oct 29 2018, 4:16 PM.

Details

Summary

This patch implements P0634r3 that removes the need for 'typename' in certain contexts.

For example,

template <typename T>
using foo = T::type; // ok

This is also allowed in previous language versions as an extension, because I think it's pretty useful. :)

Diff Detail

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
rsmith added inline comments.May 21 2019, 5:24 PM
clang/lib/Sema/SemaTemplate.cpp
3377–3379 ↗(On Diff #200440)

This FIXME is concerning. Is this a problem with this patch? (Is the FIXME wrong now?)

clang/test/CXX/drs/dr5xx.cpp
485 ↗(On Diff #200440)

A comment here explaining that A and B stop being aggregates in C++20 would be nice. (Nicer would be changing the testcase so it still tests the relevant rule in C++20 mode, if that's possible...)

clang/test/CXX/temp/temp.res/p5.cpp
1 ↗(On Diff #200440)

Please add tests for enum-base and conversion-type-id:

template<typename T> struct A {
  enum E : T::type {};
  operator T::type() {}
  void f() { this->operator T::type(); }
};

... which should currently be rejected.

Rakete1111 marked 11 inline comments as done.
  • rebased
  • addressed review comments
clang/lib/Parse/ParseDecl.cpp
4321 ↗(On Diff #200440)

Do you know why this isn't allowed in operator ids?

5100–5101 ↗(On Diff #200440)

Yeah it does the break the second. Would just checking whether a friend is there be good enough? clang doesn't seem to actively propose to add a friend if there's one missing, so if we add a IsFriend parameter and then check if it is set than always return false, it should work. Is that acceptable? It would break the nice error message you get if you write friend C(int);, but if we restrict it when isDeclarationSpecifier return false (with Never) would that be better (that's what I'm doing right now)?

Another solution would be to tentatively parse the whole thing, but that can be pretty expensive I believe.

clang/lib/Sema/SemaTemplate.cpp
3377–3379 ↗(On Diff #200440)

Yes you're right, I believe it not longer applies due to the change in ParseDecl.cpp in ParseDeclarationSpecifiers.

Rakete1111 marked an inline comment as done.May 22 2019, 8:54 AM
Rakete1111 added inline comments.
clang/lib/Sema/SemaTemplate.cpp
3377–3379 ↗(On Diff #200440)

Although I'm not that sure I fully understand what that comments alludes to.

rsmith marked 2 inline comments as done.May 22 2019, 2:52 PM
rsmith added inline comments.
clang/lib/Parse/ParseDecl.cpp
4321 ↗(On Diff #200440)

There's already been discussion of that on the core reflector, and people seem to agree it's an oversight in the wording. If you want to accept that here, I think that's fine, under the assumption that this will be fixed by DR. (If you want to follow the wording-as-moved, that's fine too.)

5100–5101 ↗(On Diff #200440)

This seems a little fragile against future grammar changes, but I think the IsFriend check is correct -- I *think* the only way we can see a qualified-id here in a valid non-constructor, non-nested-name-specifier case is in a friend declaration.

clang/lib/Sema/SemaTemplate.cpp
3377–3379 ↗(On Diff #200440)

The example would be something like this:

template<typename T> struct X {
  template<typename U> struct Y { Y(); using V = int; };
  template<typename U> typename Y<U>::V f();
};
template<typename T> template<typename U>
X<T>::Y<U>::V X<T>::f() {}

Clang trunk today points out that the typename keyword is missing on the final line, but fails to point out that the template keyword is also missing. The reason is that in the case where that construct is valid:

template<typename T> template<typename U>
X<T>::Y<U>::Y() {}

... we are "entering the context" of the nested-name-specifier, which means we don't need a template keyword.

If the FIXME is fixed, then we should diagnose the missing template in the above program.

Also, because we don't rebuild the nested-name-specifier as a dependent nested name specifier in this case, we fail to match it against the declaration in the class, so in my example above, we also produce an "out-of-line definition does not match" error.

A closely-related issue can be seen in an example such as:

template<typename T> struct X {
  template<typename U> struct Y { Y(); typedef void V; }; 
  template<typename U> typename Y<U>::V::W f();
};
template<typename T> template<typename U>
X<T>::template Y<U>::V::W X<T>::f() { return 0; }

Here, we produce a completely bogus error:

<stdin>:6:13: error: 'X::Y::V' (aka 'void') is not a class, namespace, or enumeration
X<T>::template Y<U>::V::W X<T>::f() { return 0; } 
            ^

... because we parse this in "entering context" mode and so resolve X<T>::Y<U>::V to the type in the primary template (that is, void). That's wrong: we should defer resolving this name to a type until we know what T and U are, or until we know that we're *actually* entering the context. Specifically, the above program can be extended as follows:

template<> template<> struct X<int>::Y<int> {
  struct V { using W = int; };
};
void call(X<int> x) { x.f<int>(); } // OK, f returns int

The above program should be accepted by this patch, if the FIXME is indeed now fixed. Please add it as a testcase :)

Rakete1111 marked an inline comment as done.May 27 2019, 1:50 AM
Rakete1111 added inline comments.
clang/lib/Sema/SemaTemplate.cpp
3377–3379 ↗(On Diff #200440)

Oh ok, got it thanks. So no, the program is still not accepted in clang, and a pretty dumb side effect of it is that

template<typename T> struct X {
  template<typename U> struct Y { Y(); using V = int; };
  template<typename U> typename Y<U>::V f();
};
template<typename T> template<typename U>
X<T>::Y<U>::V X<T>::f() {}

is accepted without the diagnostic for the missing template. :(

Minor suggestion, you may want to update http://clang.llvm.org/cxx_status.html page for "typename optional in more contexts" with in this change.

cjdb added a subscriber: cjdb.Jan 18 2022, 1:28 PM

What's the status of this patch?

What's the status of this patch?

It appears to me that the 'delta' right now is a couple of cases where this patch doesn't properly diagnose/warn (see the convo in SemaTemplate.cpp )

Herald added a project: Restricted Project. · View Herald TranscriptMar 2 2022, 8:52 AM
MoritzS added a subscriber: MoritzS.Apr 6 2022, 3:18 AM
cor3ntin added a reviewer: Restricted Project.Jul 3 2022, 12:13 PM

Hey! Also wondering what's the status of this.
@Rakete1111 do you plan to finish the patch? Or would it be ok if someone takes it over?

Hey! Also wondering what's the status of this.
@Rakete1111 do you plan to finish the patch? Or would it be ok if someone takes it over?

Note that this would also let us mark P2324 as complete as well. @ilya-biryukov : Since there is no response, I suspect the answer here is someone should take this over. Were you going to?

Note that this would also let us mark P2324 as complete as well. @ilya-biryukov : Since there is no response, I suspect the answer here is someone should take this over. Were you going to?

I could, but also busy with other things and happy to give this one away.
Would you be interested to take it over instead?

Note that this would also let us mark P2324 as complete as well. @ilya-biryukov : Since there is no response, I suspect the answer here is someone should take this over. Were you going to?

I could, but also busy with other things and happy to give this one away.
Would you be interested to take it over instead?

Also very busy with other things, but was sorta looking into closing the partial P2324. I haven't dug into this one much in a while, but I was sort of wondering if this is a candidate for being 'split up' into smaller patches/handle 1 case at a time. If i have time next week, I might just start looking into making this work for single-examples, rather than everything.

Note that this would also let us mark P2324 as complete as well. @ilya-biryukov : Since there is no response, I suspect the answer here is someone should take this over. Were you going to?

I could, but also busy with other things and happy to give this one away.
Would you be interested to take it over instead?

Also very busy with other things, but was sorta looking into closing the partial P2324. I haven't dug into this one much in a while, but I was sort of wondering if this is a candidate for being 'split up' into smaller patches/handle 1 case at a time. If i have time next week, I might just start looking into making this work for single-examples, rather than everything.

Welp, spoke too soon, my concepts stuff got reverted again, so I'll be workingon that for a while now, so I wont' have time to jump on this today.

I looked at this a bit about a week ago and got it down to 3-4 tests failing, but I'm not sure how much time I'll have to continue working on it. If one of you wants to take over I'll be happy to send you what I've currently got. @erichkeane @ilya-biryukov

Also, do you know if having posted this patch is agreement for licensing this code? Or do we need to get explicit agreement from the original author before committing a version of this?

I looked at this a bit about a week ago and got it down to 3-4 tests failing, but I'm not sure how much time I'll have to continue working on it. If one of you wants to take over I'll be happy to send you what I've currently got. @erichkeane @ilya-biryukov

Also, do you know if having posted this patch is agreement for licensing this code? Or do we need to get explicit agreement from the original author before committing a version of this?

I've never seen that be an issue before, and I don't see enough in https://llvm.org/docs/DeveloperPolicy.html#copyright-license-and-patents to be clear about the answer to that. @tstellar could perhaps answer.

ayzhao added a subscriber: ayzhao.Sep 2 2022, 3:32 PM
ayzhao added a comment.Sep 2 2022, 4:00 PM

I looked at this a bit about a week ago and got it down to 3-4 tests failing, but I'm not sure how much time I'll have to continue working on it. If one of you wants to take over I'll be happy to send you what I've currently got. @erichkeane @ilya-biryukov

Also, do you know if having posted this patch is agreement for licensing this code? Or do we need to get explicit agreement from the original author before committing a version of this?

I'm currently looking at this patch; please do send me what you have.

ayzhao commandeered this revision.Sep 6 2022, 5:35 PM
ayzhao added a reviewer: Rakete1111.
ayzhao updated this revision to Diff 458329.Sep 6 2022, 5:36 PM

Update commit with contributions from @royjacobson

Also, do you know if having posted this patch is agreement for licensing this code? Or do we need to get explicit agreement from the original author before committing a version of this?

I've never seen that be an issue before, and I don't see enough in https://llvm.org/docs/DeveloperPolicy.html#copyright-license-and-patents to be clear about the answer to that. @tstellar could perhaps answer.

Contributing the patch to phab was agreement to contribute to llvm under the llvm license, you do not need further permission to take over and finish and commit a patch from phab. Per the standard apache2 terms in the llvm license, "Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions."

shafik added a subscriber: shafik.Sep 7 2022, 2:31 PM

First set of comments.

clang/include/clang/Parse/Parser.h
2418 ↗(On Diff #458329)

Why don't we just have isImplicitTypenameContext(...) return an ImplicitTypenameContext?

clang/include/clang/Sema/DeclSpec.h
1809 ↗(On Diff #458329)

Since you use Yes for the positive option how about No for the negative option? Yes/Never feel like an odd pair.

clang/lib/Parse/ParseDecl.cpp
3608 ↗(On Diff #458329)
3609 ↗(On Diff #458329)
clang/lib/Parse/ParseDeclCXX.cpp
1248 ↗(On Diff #458329)
1290 ↗(On Diff #458329)
1311 ↗(On Diff #458329)
clang/lib/Parse/ParseTentative.cpp
446 ↗(On Diff #458329)
clang/lib/Parse/Parser.cpp
2035 ↗(On Diff #458329)
2036 ↗(On Diff #458329)
clang/lib/Sema/DeclSpec.cpp
27 ↗(On Diff #458329)

Duplicate include.

1474 ↗(On Diff #458329)

Dead code?

ayzhao updated this revision to Diff 458580.Sep 7 2022, 3:16 PM
ayzhao marked 12 inline comments as done.

address code review comments from shafik@

ayzhao marked an inline comment as done.Sep 7 2022, 4:46 PM
ayzhao added inline comments.
clang/lib/Parse/ParseDecl.cpp
5100–5101 ↗(On Diff #200440)

I _think_ the first comment in this chain can be marked as done given that the test cases are now in p5.cpp and Clang compiles them without errors with the help of the IsFriend check.

shafik added a comment.Sep 7 2022, 6:37 PM

Maybe I missed it but I don't see a test that covers temp.res p5 e.g.:

template <class T> void f(int i) {
  T::x * i;  // This will be assumed to be the expression
             //   T::x multiplied by i
             // Not a declaration of variable i of 
             //   type pointer to T::x?
}

struct Foo {
 typedef int x;
};

struct Bar {
  static int const x = 5;
};

int main() {
  f<Bar>(1);          // OK
  f<Foo>(1);          // error: Foo::x is a type
}
clang/include/clang/Sema/DeclSpec.h
1918 ↗(On Diff #458580)

Why do we need this one shot previous lookup result? I am struggling to see the connection between isDeclaratorFunctionLike(...) and where we check hasPrevLookupResult(...) and why it matter.

clang/lib/Parse/ParseDecl.cpp
6479 ↗(On Diff #458580)

Looks like there are a few of these left over as debugging lines, the should removed.

clang/lib/Sema/DeclSpec.cpp
1502–1504 ↗(On Diff #458580)
clang/test/CXX/temp/temp.res/p5.cpp
1 ↗(On Diff #458580)

It looks like this is temp.res p4 now

ayzhao updated this revision to Diff 458900.Sep 8 2022, 3:38 PM

Fix failing test in p5.cpp where typename should be required for enum-base

(N.B. due to https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7, the correct error should now be missing 'typename' rather than forbidden enum forward references)

ayzhao updated this revision to Diff 458901.Sep 8 2022, 3:39 PM

remove obsolete FIXME

ayzhao marked an inline comment as done.Sep 8 2022, 3:53 PM
ayzhao added inline comments.
clang/lib/Parse/ParseDecl.cpp
4321 ↗(On Diff #200440)

It seems like a wording oversight that we don't assume typename in an enum-base. Probably would be good to raise this on the core reflector.

Marking this as done for now; this patch currently returns an error if typename is assumed in an enum-base.

ayzhao updated this revision to Diff 458930.Sep 8 2022, 5:36 PM
ayzhao marked 2 inline comments as done.

p5.cpp -> p4.cpp, removed debug statements

haven't yet fully grokked this patch. still looking into fixing test failures and PrevLookupResult.

ayzhao updated this revision to Diff 459205.Sep 9 2022, 2:34 PM

Fix typename-specifier-3.cpp test

Things done:

  • the warning should also include a check that C++20 is required
  • the warning should only show up for precxx17, as %std_cxx17- translates to -std=c++2b
ayzhao added inline comments.Sep 15 2022, 10:22 AM
clang/lib/Sema/SemaDecl.cpp
362 ↗(On Diff #459205)

Status update:

This line is currently causing p2-2.cpp to fail with the following error:

FAIL: Clang :: CXX/module/module.interface/p2-2.cpp (2 of 17555)
******************** TEST 'Clang :: CXX/module/module.interface/p2-2.cpp' FAILED ********************
Script:
--
: 'RUN: at line 3';   /dev/shm/ayzhao_llvm/llvm-project/build/bin/clang -cc1 -internal-isystem /dev/shm/ayzhao_llvm/llvm-project/build/lib/clang/16.0.0/include -nostdsysteminc -std=c++20 /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp -verify
--
Exit Code: 1
 
Command Output (stderr):
--
error: 'error' diagnostics expected but not seen:
  File /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp Line 17: cannot export 'iterator' as it is not at namespace scope
  File /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp Line 35: cannot export 'iterator' as it is not at namespace scope
error: 'error' diagnostics seen but not expected:
  File /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp Line 17: declaration does not declare anything
  File /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp Line 35: declaration does not declare anything
4 errors generated.
 
--
 
********************

A reduced repro is here:

export module X;

export template <typename T>
struct X {
  struct iterator {
    T node;
  };
};

export template <typename T> X<T>::iterator;

Sema::getTypeName(...) is called from these lines, with the result being that TypeRep is null in main but not null in this patch.

I'm still in the process of trying to figure out how to resolve this, but any suggestions/insights would be very welcome.

Maybe @ChuanqiXu Can help as it seems module related

ayzhao added inline comments.Sep 15 2022, 3:04 PM
clang/lib/Sema/SemaDecl.cpp
362 ↗(On Diff #459205)

I fixed this with the following diff:

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1375431d8998..dacba4d18021 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -362,6 +362,11 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
         if (AllowImplicitTypename == ImplicitTypenameContext::No &&
             !isClassName && !IsCtorOrDtorName)
           return nullptr;
+        // FIXME: This hack is required in order to make the test
+        // CXX/module/module.interface/p2-2.cpp pass. Can we get this working
+        // with this method returning a non-null ParsedType?
+        if (isa<ExportDecl>(CurContext))
+          return nullptr;
         bool IsImplicitTypename = !isClassName && !IsCtorOrDtorName;
         if (IsImplicitTypename) {
           SourceLocation QualifiedLoc = SS->getRange().getBegin();

It's very hacky, but it works (for now)

ayzhao updated this revision to Diff 460514.Sep 15 2022, 3:04 PM

hacky fix for the test CXX/module/module.interface/p2-2.cpp

If anyone has a better idea on how to fix this test, feedback is very welcome.

ayzhao added inline comments.Sep 16 2022, 4:40 PM
clang/lib/Sema/SemaTemplate.cpp
3377–3379 ↗(On Diff #200440)

Currently looking into this.

It is interesting to note that for the following example in one of the parent comments:

template<typename T> struct X {
  template<typename U> struct Y { Y(); typedef void V; }; 
  template<typename U> typename Y<U>::V::W f();
};
template<typename T> template<typename U>
X<T>::template Y<U>::V::W X<T>::f() { return 0; }

GCC doesn't like the fact that the template keyword is on the final line if compiled with -pedantic [0]:

<source>:6:16: warning: keyword 'template' not allowed in declarator-id [-Wpedantic]
    6 | X<T>::template Y<U>::V::W X<T>::f() { return 0; }
      |                ^~~~
Compiler returned: 0

[0]: https://godbolt.org/z/dYddW3ErY

ayzhao updated this revision to Diff 461401.Sep 19 2022, 4:08 PM

fix typo

ayzhao updated this revision to Diff 461403.Sep 19 2022, 4:15 PM

remove extra blank line

cjdb removed a subscriber: cjdb.Sep 19 2022, 5:04 PM
ayzhao marked an inline comment as done.Sep 20 2022, 11:15 AM
ayzhao added inline comments.
clang/lib/Sema/SemaTemplate.cpp
3377–3379 ↗(On Diff #200440)

This is starting to feel like a separate issue. I filed https://github.com/llvm/llvm-project/issues/57853 to track it.

ayzhao updated this revision to Diff 461699.Sep 20 2022, 2:02 PM

rebase + clang-format

ayzhao updated this revision to Diff 461729.Sep 20 2022, 3:23 PM
ayzhao marked 2 inline comments as done.

remove PrevLookupResult + put Declarator(...) and ~Declarator() definitions back in the header files to reduce the diff since we're no longer overloading the constructor.

ayzhao added inline comments.Sep 20 2022, 3:24 PM
clang/include/clang/Sema/DeclSpec.h
1918 ↗(On Diff #458580)

Removed

clang/lib/Sema/DeclSpec.cpp
1502–1504 ↗(On Diff #458580)

Ended up removing PrevLookupResult per my other comment.

ayzhao updated this revision to Diff 462032.Sep 21 2022, 3:46 PM

rebase + upload; also friendly ping!

I made mostly small comments but I think @aaron.ballman and/or @erichkeane should take a look as well.

clang/lib/Parse/ParseDecl.cpp
3434–3435 ↗(On Diff #462032)
5592 ↗(On Diff #462032)

Instead of adding yet another bool flag maybe we can consider using something like enum isFriend : bool {No, Yes}.

I am sure @aaron.ballman will want to chime in here as well.

clang/lib/Parse/ParseTemplate.cpp
20 ↗(On Diff #462032)

Do we still need this?

1450 ↗(On Diff #462032)
clang/lib/Sema/Sema.cpp
51 ↗(On Diff #462032)

Do we need this?

I think this is on the right track, but would like to see more work done on that fixme before we commit (or at least better understand what is causing this). I'm afraid of what else can get us into that situation besides the export-decl.

clang/lib/Sema/SemaDecl.cpp
367 ↗(On Diff #462032)

Hmm... this scares me quite a bit, I don't really know what other fallout results from this, or other code that would hit here.

We should probably spend more time making sure we understand this better.

ayzhao updated this revision to Diff 462222.Sep 22 2022, 10:08 AM
ayzhao marked 2 inline comments as done.

address some review comments

aaron.ballman added inline comments.Sep 22 2022, 10:33 AM
clang/include/clang/Parse/Parser.h
2343 ↗(On Diff #462222)

Starting with is implies contextual conversion to bool (generally), so I'd suggest renaming.

clang/include/clang/Sema/DeclSpec.h
1806 ↗(On Diff #462222)

Not opposed to this construct, but I am worried about how well it will scale. I don't know that we want to add a bunch of named enums that all boil down to a bool. (If someone thinks they have good ideas here, that'd be a good RFC topic for Discourse because we have a ton of interfaces that take a bunch of bools.)

clang/lib/Parse/ParseDecl.cpp
5592 ↗(On Diff #462032)

Heh, so this is where I get worried about the scalability of using enums for these. We really want to use three different enums here, but do we really want to *add* three different enums? I'm unconvinced.

However, if we can come up with some template magic to allow for named bool parameters as a generic interface, that would be valuable to use.

erichkeane added inline comments.Sep 22 2022, 10:44 AM
clang/lib/Parse/ParseDecl.cpp
5592 ↗(On Diff #462032)

I prefer enums over bools TBH, even if we end up with a million of then somewhere.

That said, what about:

https://godbolt.org/z/Kz6jdjobj

template<typename SpecificThing>
class Is {
    Is(bool v) : value(v){}
  public:
  bool value;
  static const Is Yes() { return Is{true};}
  static const Is No() { return Is{false};}

  operator bool() { return value; }
};

class Friend{}; // #1
 
void foo(Is<Friend> f) {
    if (f) {
        ///...
    }
}

void baz() {
    foo(Is<Friend>::Yes());
}

Adding a 'new' thing is as simple as just adding #1 for anything we care about. We might want to put them in a namespace of some sort, but perhaps not awful?

aaron.ballman added inline comments.Sep 22 2022, 10:49 AM
clang/lib/Parse/ParseDecl.cpp
5592 ↗(On Diff #462032)

Yeah, this is along the lines of what I was thinking of! However, I'm still concerned about that approach because it involves adding a new type for every situation we have a bool. Empty classes to use as a tag definitely works, but I was hoping we could use a string literal rather than a tag type so that we don't have the extra compile time overhead of adding hundreds of new empty classes. e.g.,

void foo(Is<"Friend"> f) {
  if (f) {
     // ...
  }
}

void baz() {
  foo(Is<"Friend">::Yes); // Yay
  foo(Is<"Enemy">::Yes); // Error for type mismatch with Is<"Friend">
}

However, that might require compiling with C++20 (I don't recall), so it may not be a viable idea.

ayzhao updated this revision to Diff 462239.Sep 22 2022, 10:51 AM
ayzhao marked 2 inline comments as done.

address some comments

ayzhao added inline comments.Sep 22 2022, 10:53 AM
clang/include/clang/Sema/DeclSpec.h
1806 ↗(On Diff #462222)

Ack. IIRC this enum was created as a result of this comment by @rsmith expressing concern over adding an additional bool parameter to a function with a lot of preexisting bool args.

erichkeane added inline comments.Sep 22 2022, 10:54 AM
clang/lib/Parse/ParseDecl.cpp
5592 ↗(On Diff #462032)

Yeah, referring to stringliterals is troublesome in C++17. However, we COULD do that like:

void foo(Is<"Friend"_Is> f) {
  if (f) {
     // ...
  }
}

void baz() {
  foo(Is<"Friend"_Is>::Yes); // Yay
  foo(Is<"Enemy"_Is>::Yes); // Error for type mismatch with Is<"Friend">
}

by making operator _Is return an integer_sequence.

aaron.ballman added inline comments.Sep 22 2022, 11:02 AM
clang/include/clang/Sema/DeclSpec.h
1806 ↗(On Diff #462222)

Ack. IIRC this enum was created as a result of this comment by @rsmith expressing concern over adding an additional bool parameter to a function with a lot of preexisting bool args.

Yeah, I spotted his suggestion (and am totally fine with implementing it here as you've done). I was mostly thinking about the future when someone tries to do this for every set of 2 or more bool parameters. :-D

clang/lib/Parse/ParseDecl.cpp
5592 ↗(On Diff #462032)

That's a really neat idea! If you want to work it up into something that could be plausible to add to ADT, I think it's worth an RFC to add the interface. I'm guessing the diagnostic behavior of that would be kind of gross, but once we move to C++20 we'd be able to use string literal template arguments directly and get better diagnostic behavior. The critical part is that the code is readable and we get diagnostics when passing an argument to the wrong parameter.

ayzhao updated this revision to Diff 462315.Sep 22 2022, 3:17 PM

Add FriendSpecified enum

ayzhao updated this revision to Diff 462317.Sep 22 2022, 3:18 PM

fix spacing

ayzhao marked 4 inline comments as done.Sep 22 2022, 3:25 PM
ayzhao added inline comments.
clang/lib/Parse/ParseDecl.cpp
5592 ↗(On Diff #462032)

I added a FriendSpecified enum for now.

I'm going to mark the comment chain as done so that they don't unnecessarily block the review.

I agree with the idea of a generic type to represent boolean arguments, but I think it would be out of scope of this patch and that Discourse would be a more appropriate place to discuss this.

ayzhao marked 2 inline comments as done.Sep 23 2022, 2:11 PM
ayzhao updated this revision to Diff 462587.Sep 23 2022, 2:15 PM
ayzhao marked an inline comment as done.

address some more review comments + rebase

ayzhao added inline comments.Sep 23 2022, 4:29 PM
clang/lib/Sema/SemaDecl.cpp
367 ↗(On Diff #462032)

Following up with my previous comment about the failing test that this hack was supposed to fix:

I added the typename keyword to the export template statement and lo and behold, Clang emits the same "declaration does not declare anything" diagnostic instead of the namespace scope diagnostic [0].

To me, this feels like that the original test case was wrong:

  1. There should've been a typename keyword in the export statement. Perhaps the author of the test wasn't aware that the typename keyword was required, or perhaps the author already assumed that P0634r3 was already implemented in clang.
  2. The test currently passing (with Clang emitting the namespace diagnostic instead of the declaration diagnostic) seems to be a freak coincidence.

I'm not familiar at all with C++ modules - is this a bug with exporting types?

[0]: https://godbolt.org/z/PYvh68Tq7

ayzhao marked 2 inline comments as done.Sep 23 2022, 4:39 PM
ayzhao added inline comments.
clang/lib/Sema/SemaDecl.cpp
367 ↗(On Diff #462032)

small fix: I linked to the wrong line when referencing the original test case. The link should be https://github.com/llvm/llvm-project/blob/a707675dbba9ca3ec6e668f86fea2240a85ca171/clang/test/CXX/module/module.interface/p2-2.cpp#L17

ayzhao updated this revision to Diff 462633.Sep 23 2022, 5:47 PM

remove the hack for the test p2-2.cpp and patch in patch in D134578 which fixes the test

ayzhao marked an inline comment as done.Sep 23 2022, 5:50 PM
ayzhao added inline comments.
clang/lib/Sema/SemaDecl.cpp
367 ↗(On Diff #462032)

So my belief now is that the test p2-2.cpp is broken. I've removed the FIXME hack, and I created D134578 to fix the test. To keep the bots happy, I also cherry-picked D134578 into this patch.

I think this is on the right track, but would like to see more work done on that fixme before we commit (or at least better understand what is causing this). I'm afraid of what else can get us into that situation besides the export-decl.

The FIXME has been removed; the problem seems to be that the test is broken. See https://reviews.llvm.org/D53847?id=462032#inline-1297092

erichkeane accepted this revision.Sep 26 2022, 6:21 AM

Thanks for looking into it. I think you're right that it is a mistake that we accepted that without the 'struct' keyword after a quick look, so I think I am OK with this. Please give @aaron.ballman a day or so to take a look if he wishes.

This revision is now accepted and ready to land.Sep 26 2022, 6:21 AM
ayzhao updated this revision to Diff 462969.Sep 26 2022, 11:01 AM

clang-format + rebase

It's great to see this make progress.
Can you update cxx_status.html and ReleaseNotes.txt?

ayzhao updated this revision to Diff 463334.Sep 27 2022, 1:59 PM

update cxx_status.html and ReleaseNotes.rst + rebase

It's great to see this make progress.
Can you update cxx_status.html and ReleaseNotes.txt?

Done.

I also saw that P2092R0 was marked as partially supported in cxx_status.html due to missing support for P0634R3, but I'm not familiar enough with P2092R0 to update that entry.

Good catch

template<typename T>
concept K = requires (typename T::Type X) { // (3)
X.next();
}

That typename should be optional. Can you add a test for that? If it works you can mark P2092 as fully supported.

Good catch

template<typename T>
concept K = requires (typename T::Type X) { // (3)
X.next();
}

That typename should be optional. Can you add a test for that? If it works you can mark P2092 as fully supported.

Done.

The test originally failed, but it was a simple fix to get it to work.

ayzhao updated this revision to Diff 463351.Sep 27 2022, 3:42 PM

add test and fix for P2092

add test and fix for P2092

These changes look good to me, thanks

erichkeane accepted this revision.Sep 28 2022, 6:12 AM
This revision was landed with ongoing or failed builds.Sep 28 2022, 9:50 AM
This revision was automatically updated to reflect the committed changes.