versioner: fix false positive with functions only available as inlines.
Change-Id: I09cc335b4006c6ceafcbd1bec9e50161f8262942
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index fcef6b1..bfee6b9 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -272,6 +272,8 @@
static bool sanityCheck(const std::set<CompilationType>& types,
const DeclarationDatabase& database) {
bool error = false;
+ std::string cwd = getWorkingDir() + "/";
+
for (auto outer : database) {
const std::string& symbol_name = outer.first;
CompilationType last_type;
@@ -290,7 +292,7 @@
bool availability_mismatch = false;
DeclarationAvailability current_availability;
- // Make sure that all of the availability declarations for this symbol match.
+ // Ensure that all of the availability declarations for this symbol match.
for (const DeclarationLocation& location : declaration.locations) {
if (!found_availability) {
found_availability = true;
@@ -306,7 +308,7 @@
if (availability_mismatch) {
printf("%s: availability mismatch for %s\n", symbol_name.c_str(), type.describe().c_str());
- declaration.dump(getWorkingDir() + "/");
+ declaration.dump(cwd);
}
if (type.arch != last_type.arch) {
@@ -315,7 +317,7 @@
continue;
}
- // Make sure that availability declarations are consistent across API levels for a given arch.
+ // Ensure that availability declarations are consistent across API levels for a given arch.
if (last_availability != current_availability) {
error = true;
printf("%s: availability mismatch between %s and %s: [%s] before, [%s] after\n",
@@ -323,6 +325,23 @@
last_availability.describe().c_str(), current_availability.describe().c_str());
}
+ // Ensure that at most one inline definition of a function exists.
+ std::set<DeclarationLocation> inline_definitions;
+
+ for (const DeclarationLocation& location : declaration.locations) {
+ if (location.is_definition) {
+ inline_definitions.insert(location);
+ }
+ }
+
+ if (inline_definitions.size() > 1) {
+ error = true;
+ printf("%s: multiple inline definitions found:\n", symbol_name.c_str());
+ for (const DeclarationLocation& location : declaration.locations) {
+ location.dump(cwd);
+ }
+ }
+
last_type = type;
}
}
@@ -378,13 +397,13 @@
bool symbol_available = symbol_availability_it != platform_availability.end();
if (decl_available) {
if (!symbol_available) {
- // Make sure that either it exists in the platform, or an inline definition is visible.
+ // Ensure that either it exists in the platform, or an inline definition is visible.
if (!declaration.hasDefinition()) {
missing_symbol.insert(type);
continue;
}
} else {
- // Make sure that symbols declared as functions/variables actually are.
+ // Ensure that symbols declared as functions/variables actually are.
switch (declaration.type()) {
case DeclarationType::inconsistent:
printf("%s: inconsistent declaration type\n", symbol_name.c_str());
@@ -409,7 +428,7 @@
}
}
} else {
- // Make sure it's not available in the platform.
+ // Ensure that it's not available in the platform.
if (symbol_availability_it != platform_availability.end()) {
printf("%s: symbol should be unavailable in %s (declared with availability %s)\n",
symbol_name.c_str(), type.describe().c_str(), availability.describe().c_str());
@@ -472,11 +491,27 @@
break;
}
- // Check to see if the symbol is tagged with __INTRODUCED_IN_FUTURE.
+ bool found_inline_definition = false;
+ bool future = false;
+
auto symbol_it = declaration_database.find(symbol_name);
- const Declaration& declaration = symbol_it->second.begin()->second;
- DeclarationAvailability availability = declaration.locations.begin()->availability;
- if (availability.introduced >= 10000) {
+
+ // Ignore inline functions and functions that are tagged as __INTRODUCED_IN_FUTURE.
+ // Ensure that all of the declarations of that function satisfy that.
+ for (const auto& declaration_pair : symbol_it->second) {
+ const Declaration& declaration = declaration_pair.second;
+ DeclarationAvailability availability = declaration.locations.begin()->availability;
+
+ if (availability.introduced >= 10000) {
+ future = true;
+ }
+
+ if (declaration.hasDefinition()) {
+ found_inline_definition = true;
+ }
+ }
+
+ if (future || found_inline_definition) {
continue;
}