-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[modules] Handle friend function that was a definition but became only a declaration during AST deserialization #132214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
91e057b
adf6dfd
a564da2
2b42b4d
8d5ecfd
df9fd8b
d7234be
94efa55
a24e8db
b887050
0a99d89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1390,7 +1390,19 @@ class ASTReader | |
| /// predefines buffer may contain additional definitions. | ||
| std::string SuggestedPredefines; | ||
|
|
||
| llvm::DenseMap<const Decl *, bool> DefinitionSource; | ||
| struct DefinitionSourceFlags { | ||
| ExtKind HasExternalDefinitions : 2; | ||
|
|
||
| /// Indicates if given function declaration was a definition but its body | ||
| /// was removed due to declaration merging. | ||
| bool ThisDeclarationWasADefinition : 1; | ||
|
|
||
| DefinitionSourceFlags() | ||
| : HasExternalDefinitions(EK_ReplyHazy), | ||
| ThisDeclarationWasADefinition(false) {} | ||
| }; | ||
|
|
||
| llvm::DenseMap<const Decl *, DefinitionSourceFlags> DefinitionSource; | ||
|
||
|
|
||
| bool shouldDisableValidationForFile(const serialization::ModuleFile &M) const; | ||
|
|
||
|
|
@@ -2374,6 +2386,8 @@ class ASTReader | |
|
|
||
| ExtKind hasExternalDefinitions(const Decl *D) override; | ||
|
|
||
| bool wasThisDeclarationADefinition(const FunctionDecl *FD) override; | ||
|
|
||
| /// Retrieve a selector from the given module with its local ID | ||
| /// number. | ||
| Selector getLocalSelector(ModuleFile &M, unsigned LocalID); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // RUN: rm -fR %t | ||
| // RUN: split-file %s %t | ||
| // RUN: cd %t | ||
| // RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -xc++ -emit-module -fmodule-name=foo modules.map -o foo.pcm | ||
| // RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -O1 -emit-obj main.cc -verify -fmodule-file=foo.pcm | ||
|
|
||
| //--- modules.map | ||
| module "foo" { | ||
| export * | ||
| module "foo.h" { | ||
| export * | ||
| header "foo.h" | ||
| } | ||
| } | ||
|
|
||
| //--- foo.h | ||
| #pragma once | ||
|
|
||
| template <int> | ||
| void Create(const void* = nullptr); | ||
|
|
||
| template <int> | ||
| struct ObjImpl { | ||
| template <int> | ||
| friend void ::Create(const void*); | ||
| }; | ||
|
|
||
| template <int I> | ||
| void Create(const void*) { | ||
| (void) ObjImpl<I>{}; | ||
| } | ||
|
|
||
| //--- main.cc | ||
| // expected-no-diagnostics | ||
| #include "foo.h" | ||
|
|
||
| int main() { | ||
| Create<42>(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // RUN: %clang_cc1 -std=c++20 -verify -emit-llvm-only %s | ||
|
|
||
| template <int> | ||
| void Create(const void* = nullptr); | ||
|
|
||
| template <int> | ||
| struct ObjImpl { | ||
| template <int> | ||
| friend void ::Create(const void*); | ||
| }; | ||
|
|
||
| template <int I> | ||
| void Create(const void*) { | ||
| (void) ObjImpl<I>{}; | ||
| } | ||
|
|
||
| int main() { | ||
| Create<42>(); | ||
| } | ||
|
|
||
| // expected-no-diagnostics |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Personal taste
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done