-
Notifications
You must be signed in to change notification settings - Fork 332
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
NFC: Refactor clang extra args addition #1444
NFC: Refactor clang extra args addition #1444
Conversation
@adrian-prantl please review |
bool AddClangArgument(std::string arg, bool unique = true); | ||
|
||
bool AddClangArgumentPair(llvm::StringRef arg1, llvm::StringRef arg2); | ||
|
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.
This looks good!
}; | ||
|
||
inline bool IsMultiArgClangFlag(const StringRef& arg) { | ||
return arg == "-D" || arg == "-U" || arg == "-working-directory"; |
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.
Previously we only had to check for multi-arg flags in the 3 cases we actually were doing something special to it. But with uniquing, do we need to check for more cases?
I guess we are still only uniquing the arguments which we recognize in GetClangArgCategory
, right?
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.
For now that's true (except that it would be (GetClangArgCategory(arg) & ClangArgCategoryUnique) || arg == "-working-directory"
as we use -working-directory
only to apply to paths to make them absolute). In future there'll be at least -fmodule-map-file=
which is single-arg by design, although it wouldn't break this method logic anyway. I could change this code to use output of GetClangArgCategory
if you're okay with single-arg case.
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.
Actually, I've forgot to mention that there're different conditions: ==
vs startswith
. Would you advise to separate some list of constants to unify lists of args to join/unique? I think of something like this:
const StringRef kMacroFlags[] = { "-D", "-U" };
const StringRef kUniqueMultiArgFlags[] = { "-I", "-F" }; // this would appear in the next PR, need an elegant way to append kMacroFlags here (using macro? :) )
And then just use these arrays to check for ==
or startswith
where needed
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.
@adrian-prantl what do you think about 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.
Sure, that seems reasonable. The naming should follow the LLDB style though:
std::array<StringRef> macro_flags = {...};
std::array<StringRef> contractable_multiword_flags = {..};
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.
Ok, will add macro_flags then
} // namespace | ||
|
||
void SwiftASTContext::AddExtraClangArgs(std::vector<std::string> ExtraArgs) { | ||
swift::ClangImporterOptions &importer_options = GetClangImporterOptions(); |
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.
This function has very few dependencies. I previously recommended writing an end-to-end test for the uniquing, but I wonder if we could write a unit test for it. That seems like a better fit.
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.
There's a test for -Werror
skipping in this method, so I was hoping that it's possible to write more tests for logic here :)
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.
That would certainly work (we'd need to rename the test to be more generic), I just thought that this is such a nice and small piece of functionality that a unit test is a better fit. In the end, both variants are reasonable.
ec0ec92
to
13caaf9
Compare
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.
LGTM with inline comments addressed. Please do not forget to cherry-pick this to master-next!
13caaf9
to
3ed20f1
Compare
@swift-ci test |
60fc04a
to
02cb77e
Compare
@swift-ci test |
|
||
std::array<StringRef> macro_flags = { "-D", "-U" }; | ||
|
||
bool IsMultiArgClangFlag(const StringRef& arg) { |
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 StringRef instead. StringRef only has a size of two pointers; it's designed to be passed by value.
|
||
bool IsMacroDefinition(const StringRef& arg) { | ||
for (auto &flag : macro_flags) | ||
if (args.starswith(flag)) |
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.
startswith
02cb77e
to
1fed12a
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
ecde483
to
fbbd0ef
Compare
@swift-ci test |
Did you build this prior to uploading? |
Oh, sorry for that, I was too impatient for the last pushes, and incremental build doesn't work on my local checkout, so I have to wait about an hour to check compilation :( I'll make final push afther checking |
fbbd0ef
to
155380d
Compare
@swift-ci test |
Sure! |
155380d
to
5484364
Compare
@swift-ci test |
Thanks! |
Seems like you've made cherry-pick yourself, thanks! |
@DeeSee It looks like this patch introduced a use-after-free. Would you mind taking a look? https://ci.swift.org/view/LLDB/job/oss-lldb-asan-osx/6947/consoleText |
|
|
||
auto clang_arg_str = clang_argument.str(); | ||
if (!ShouldUnique(clang_argument) || !unique_flags.count(clang_arg_str)) { | ||
importer_options.ExtraArgs.push_back(clang_arg_str); |
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.
@DeeSee doing importer_options.ExtraArgs.push_back
invalidates all the references inside of llvm::DenseSet<StringRef> unique_flags
. You might consider using llvm::StringSet.
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.
Thanks! I'll make a fix right away.
Just asking — why not std::unordered_set<std::string>
? (I'm not very familiar with historical causes of why there are custom types for hashmap and hashset in llvm, and using types from std looks less error-prone to me)
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.
One (historical) reason is that LLVM predates std::unordered_set
. However, in this concrete case llvm::StringSet
will be more efficient than std::unordered_set<std::string>
because it allocates the strings in the same memory as the set, so you don't have to pay extra memory management overhead for allocating the contents of the individual std::strings.
AddClangArgumentPair
methodAddClangArgument
method (not used anywhere outsideSwiftASTContext.cpp
)