-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SR-2402][ClangImporter] Import nullary function macros #6530
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
[SR-2402][ClangImporter] Import nullary function macros #6530
Conversation
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.
Great job! A couple quick comments.
lib/ClangImporter/ImportDecl.cpp
Outdated
|
||
// Finally, set the body. | ||
func->setBody(BraceStmt::create(C, SourceLoc(), | ||
ASTNode(ret), |
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: This should implicitly convert to ASTNode
. I think you want to make the array explicit
func->setBody(BraceStmt::create(C, SourceLoc(), { ret }, SourceLoc()));
return true; | ||
|
||
// Consult the blacklist of macros to suppress. | ||
// Consult the list of macros to suppress. |
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.
Any reason why this is changed?
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.
"Blacklist" is considered exclusionary in some contexts. Here it seems "list" conveys the same meaning without any unintended consequences. I was already modifying the body of this method, so I thought I'd include this comment change as well.
lib/ClangImporter/ImportDecl.cpp
Outdated
} | ||
|
||
ValueDecl * | ||
ClangImporter::Implementation::createFunction(Identifier name, DeclContext *dc, |
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.
Since this code is pulled from ClangImporter::Implementation::createConstant
, could you find a way to factor its body to call this?
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.
Will do, thanks!
Thanks for the review, @CodaFi! 🙇 |
This is pretty much the approach I was going with in my first attempt, so it looks good to me. The trouble you're having with functions chaining to macros is because of ClangImporter.cpp:390: "If it's an identifier that is itself a macro, look into that macro." That is, Also worried now we're going to run into the same kind of ambiguity issue as #6531—if people have been working around this in overlays, we're in trouble. I suppose we could limit this to Swift 4 mode and cross our fingers. Don't forget to add a test for function-like macros invoking function-like macros and object-like macros invoking function-like macros. |
Oh, I'm sorry if I duplicated your work here, @jrose-apple. Was your first attempt in a pull request somewhere? I'm sorry if I missed it.
Will do! |
Oh, no, I had a partial patch from a long time ago (over a year) that I never attached to the JIRA because it didn't apply cleanly. Actually, I vaguely remember there was a problem when you actually tried to IRGen a call to one of these macros, so please include at least one execution test as well! |
I did confirm locally that a call to a function-like macro succeeded in a running program, but I'll certainly add a test. Thanks for the suggestion! |
I wonder if we need a general solution to deal with potentially source-breaking clangimporter changes like these. |
Officially the Clang importer is part of the language and major changes should go through swift-evolution. Things like this are on the border of "major change", though. In that sense, limiting this to Swift 4 mode is probably the correct answer, but that doesn't help cross-language compilation (i.e. Swift 4 code trying to use both Swift 3 code and imported Objective-C code). |
@swift-ci Please test |
1 similar comment
@swift-ci Please test |
Build failed |
(Just FYI, I plan on making the changes Jordan suggested and then getting this merged before the end of this week. I haven't forgotten about it! 😅 ) |
I think given Doug's response to #6531 it's okay to leave this on even in Swift 3 mode. We'll handle conflicts if and when they happen, under the expectation that providing the same API in an overlay would be rare. |
@modocache Do you mind adding an entry to CHANGLEOG.md as well? We have several new ClangImporter features that might affect users so I'm following up with PR authors about documenting them. |
c850057
to
8761118
Compare
Uploaded some changes, but still more to come. TODO
|
@jrose-apple, I thought about this a bit more, and I wonder if it makes sense to punt this to a future pull request. I don't think the ClangImporter's macro code has any logic to handle a call expression, i.e.: Of course, I'd love to import any kind of macro, but I'm worried about biting off more than I can chew. If I can reduce the scope of this pull request I'd happily do so. Thoughts? 🙌 |
I think it's fine to save that feature for later, but I'd like the tests there to be sure we're not mis-importing them somehow. |
Sure thing. Right now we don't import them at all, I think the ClangImporter gives up because of the call expression on the right. I'll add a test case that demonstrates. |
6a4b455
to
7c1f4d1
Compare
@swift-ci please smoke test |
return importLiteral(impl, DC, macro, name, tok, ClangN, castType); | ||
return importLiteral( | ||
impl, DC, macro, name, tok, ClangN, castType, | ||
isOriginalMacroFunctionLike || macro->isFunctionLike()); |
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.
I think this is incorrect. It's only the original macro that matters, no?
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.
Absent any recursion, importLiteral
is called immediately. Since isOriginalMacroFunctionLike
is false
by default, this means that #define FOO() 1
would be imported as a global variable, not a Swift function. So I think this is correct as is. Modifying it to only use isOriginalMacroFunctionLike
causes the newly added function-like tests to fail.
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.
Hm, okay. I'm suspicious of cases like #define BAR FOO()
but we can wait until that actually happens to fix this.
// these can be used in executables, and don't crash at runtime. | ||
|
||
// RUN: rm -rf %t && mkdir -p %t | ||
// RUN: %target-swiftc_driver %s -import-objc-header %S/Inputs/macro-functions.h -o %t/macro-functions |
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.
Please use %target-swift-build
and %target-run
for this, so that it works properly on iOS, and please add REQUIRES: execution_test
so that it isn't run for cross-compilation cases. The test/Interpreter/ directory is probably a more appropriate place to put the test, too; we tend to cluster execution tests there.
7c1f4d1
to
e3eeb56
Compare
@swift-ci please smoke test |
@@ -0,0 +1,13 @@ | |||
// Other ClangImporter tests verify that function-like C macros are imported | |||
// into Swift so that identifiers are resolved correclty. This test verifies |
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.
Typo: "correclty".
I'm sure it's due to the changes I've made here, since this doesn't reproduce using
Same thing happens when I run: import Metal
foo I'm looking into why this might be happening. |
Those diagnostics about |
e3eeb56
to
4d4e6d8
Compare
Typo-correction is what brings them up at all, Sema not permitting use of deprecated/unavailable constructs in deprecated/unavailable contexts is why they get diagnosed. Just hasn't been a priority. |
Should I change the REPL tests in order to prevent the failures from occurring? I'm curious why my changes seem to have angered the beast. I'm double-checking at the moment, but I'm pretty sure these failures occur consistently on my branch, but not on master. |
I don't immediately see what your changes would have done. It seems like they'd only bring in more declarations (macros), not remove any existing ones. |
@swift-ci please smoke test |
Ping @jrose-apple -- what would you recommend I do here: change the test so that it doesn't happen to fail? Or dig in deeper to discover why my changes are causing the failure? If the latter, could you please share any relevant details from rdar://29715586? It's not on OpenRadar. |
I'm still surprised your changes have anything to do with the failing tests (which unfortunately have been wiped from the public bot), so yes, I think we need to figure out what's going on. The Radar just says that importing certain types in Metal results in us making variables like |
Well, I fixed the issue with unavailable aliases, so we won't see that particular problem anymore. I guess we can start over from there. |
Resolves SR-2402. Import function-like macros that take no arguments, assuming their bodies are something ClangImporter would otherwise be able to import. * Modify `shouldIgnoreMacro` such that it only ignores function-like macros if they take more than zero arguments. * ClangImporter's macro importing normally creates `VarDecl`. Modify that to create FuncDecl if the original macro is function-like.
4d4e6d8
to
8f7baa3
Compare
@swift-ci please test |
Sorry for letting this languish! |
Build failed |
Build failed |
Oh, maybe I angered @swift-ci by requesting a test after force pushing to my branch. I'll try again. |
@swift-ci please smoke test |
I let it languish just as much as you did. Glad to pick it up again now. |
Hmm, looks like the same problem test failed, I probably won't have a ton of time to work on this, at least for another week or so. Please feel free to grab this task from me if you'd like to make progress on it before then! |
I don't have a ton of time to work on this anymore. Still, it was a fun way to learn more about ClangImporter, so thank you! |
Resolves SR-2402.
Import function-like macros that take no arguments, assuming their bodies are something ClangImporter would otherwise be able to import.
shouldIgnoreMacro
such that it only ignores function-like macros if they take more than zero arguments.VarDecl
. Modify that to create FuncDecl if the original macro is function-like.The implementation might be gross, I'm not sure. Another problem: importing macros from another module doesn't really work. Does anyone know what I'm missing here?