versioner: allow static inlines that don't conflict.
Bug: http://b/32664285
Test: python run_test.py
Change-Id: I9d050e545390eccd82661325c0ec58055f5f28a3
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 74650d5..2f0656c 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -276,6 +276,21 @@
return result;
}
+static std::set<CompilationType> getCompilationTypes(const Declaration* decl) {
+ std::set<CompilationType> result;
+ for (const auto& it : decl->availability) {
+ result.insert(it.first);
+ }
+ return result;
+}
+
+template<typename T>
+static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
+ std::vector<T> intersection;
+ std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(intersection));
+ return intersection;
+}
+
// Perform a sanity check on a symbol's declarations, enforcing the following invariants:
// 1. At most one inline definition of the function exists.
// 2. All of the availability declarations for a symbol are compatible.
@@ -287,18 +302,23 @@
static bool checkSymbol(const Symbol& symbol) {
std::string cwd = getWorkingDir() + "/";
- const Declaration* inline_definition = nullptr;
+ std::unordered_map<const Declaration*, std::set<CompilationType>> inline_definitions;
for (const auto& decl_it : symbol.declarations) {
const Declaration* decl = &decl_it.second;
if (decl->is_definition) {
- if (inline_definition) {
- fprintf(stderr, "versioner: multiple definitions of symbol %s\n", symbol.name.c_str());
- symbol.dump(cwd);
- inline_definition->dump(cwd);
- return false;
+ std::set<CompilationType> compilation_types = getCompilationTypes(decl);
+ for (const auto& inline_def_it : inline_definitions) {
+ auto intersection = Intersection(compilation_types, inline_def_it.second);
+ if (!intersection.empty()) {
+ fprintf(stderr, "versioner: conflicting inline definitions:\n");
+ fprintf(stderr, " declarations visible in: %s\n", Join(intersection, ", ").c_str());
+ decl->dump(cwd, stderr, 4);
+ inline_def_it.first->dump(cwd, stderr, 4);
+ return false;
+ }
}
- inline_definition = decl;
+ inline_definitions[decl] = std::move(compilation_types);
}
DeclarationAvailability availability;