mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
Reland "[llvm] llvm-tapi-diff"
This is relanding commit d1d36f7ad2ae82bea8a6fcc40d6c42a72e21f096 . This patch additionally addresses failures found in buildbots due to unstable build ordering & post review comments. This patch introduces a new tool, llvm-tapi-diff, that compares and returns the diff of two TBD files. Reviewed By: ributzka, JDevlieghere Differential Revision: https://reviews.llvm.org/D101835
This commit is contained in:
parent
5c332a4b0a
commit
edcfd20e4e
@ -101,6 +101,8 @@ public:
|
|||||||
return make_range(begin_objects(), end_objects());
|
return make_range(begin_objects(), end_objects());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MachO::InterfaceFile &getInterfaceFile() { return *ParsedFile; }
|
||||||
|
|
||||||
uint32_t getNumberOfObjects() const { return Libraries.size(); }
|
uint32_t getNumberOfObjects() const { return Libraries.size(); }
|
||||||
|
|
||||||
static bool classof(const Binary *v) { return v->isTapiUniversal(); }
|
static bool classof(const Binary *v) { return v->isTapiUniversal(); }
|
||||||
|
@ -40,6 +40,8 @@ PlatformKind mapToPlatformKind(const Triple &Target);
|
|||||||
PlatformSet mapToPlatformSet(ArrayRef<Triple> Targets);
|
PlatformSet mapToPlatformSet(ArrayRef<Triple> Targets);
|
||||||
StringRef getPlatformName(PlatformKind Platform);
|
StringRef getPlatformName(PlatformKind Platform);
|
||||||
PlatformKind getPlatformFromName(StringRef Name);
|
PlatformKind getPlatformFromName(StringRef Name);
|
||||||
|
std::string getOSAndEnvironmentName(PlatformKind Platform,
|
||||||
|
std::string Version = "");
|
||||||
|
|
||||||
} // end namespace MachO.
|
} // end namespace MachO.
|
||||||
} // end namespace llvm.
|
} // end namespace llvm.
|
||||||
|
@ -105,12 +105,17 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool operator==(const Symbol &O) const {
|
bool operator==(const Symbol &O) const {
|
||||||
return (Kind == O.Kind) && (Name == O.Name) && (Targets == O.Targets) &&
|
return std::tie(Name, Kind, Targets, Flags) ==
|
||||||
(Flags == O.Flags);
|
std::tie(O.Name, O.Kind, O.Targets, O.Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Symbol &O) const { return !(*this == O); }
|
bool operator!=(const Symbol &O) const { return !(*this == O); }
|
||||||
|
|
||||||
|
bool operator<(const Symbol &O) const {
|
||||||
|
return std::tie(Name, Kind, Targets, Flags) <
|
||||||
|
std::tie(O.Name, O.Kind, O.Targets, O.Flags);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringRef Name;
|
StringRef Name;
|
||||||
TargetList Targets;
|
TargetList Targets;
|
||||||
|
@ -60,6 +60,8 @@ inline bool operator!=(const Target &LHS, const Architecture &RHS) {
|
|||||||
PlatformSet mapToPlatformSet(ArrayRef<Target> Targets);
|
PlatformSet mapToPlatformSet(ArrayRef<Target> Targets);
|
||||||
ArchitectureSet mapToArchitectureSet(ArrayRef<Target> Targets);
|
ArchitectureSet mapToArchitectureSet(ArrayRef<Target> Targets);
|
||||||
|
|
||||||
|
std::string getTargetTripleName(const Target &Targ);
|
||||||
|
|
||||||
raw_ostream &operator<<(raw_ostream &OS, const Target &Target);
|
raw_ostream &operator<<(raw_ostream &OS, const Target &Target);
|
||||||
|
|
||||||
} // namespace MachO
|
} // namespace MachO
|
||||||
|
@ -105,5 +105,34 @@ PlatformKind getPlatformFromName(StringRef Name) {
|
|||||||
.Default(PlatformKind::unknown);
|
.Default(PlatformKind::unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getOSAndEnvironmentName(PlatformKind Platform,
|
||||||
|
std::string Version) {
|
||||||
|
switch (Platform) {
|
||||||
|
case PlatformKind::unknown:
|
||||||
|
return "darwin" + Version;
|
||||||
|
case PlatformKind::macOS:
|
||||||
|
return "macos" + Version;
|
||||||
|
case PlatformKind::iOS:
|
||||||
|
return "ios" + Version;
|
||||||
|
case PlatformKind::tvOS:
|
||||||
|
return "tvos" + Version;
|
||||||
|
case PlatformKind::watchOS:
|
||||||
|
return "watchos" + Version;
|
||||||
|
case PlatformKind::bridgeOS:
|
||||||
|
return "bridgeos" + Version;
|
||||||
|
case PlatformKind::macCatalyst:
|
||||||
|
return "ios" + Version + "-macabi";
|
||||||
|
case PlatformKind::iOSSimulator:
|
||||||
|
return "ios" + Version + "-simulator";
|
||||||
|
case PlatformKind::tvOSSimulator:
|
||||||
|
return "tvos" + Version + "-simulator";
|
||||||
|
case PlatformKind::watchOSSimulator:
|
||||||
|
return "watchos" + Version + "-simulator";
|
||||||
|
case PlatformKind::driverKit:
|
||||||
|
return "driverkit" + Version;
|
||||||
|
}
|
||||||
|
llvm_unreachable("Unknown llvm::MachO::PlatformKind enum");
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace MachO.
|
} // end namespace MachO.
|
||||||
} // end namespace llvm.
|
} // end namespace llvm.
|
||||||
|
@ -72,5 +72,11 @@ ArchitectureSet mapToArchitectureSet(ArrayRef<Target> Targets) {
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getTargetTripleName(const Target &Targ) {
|
||||||
|
return (getArchitectureName(Targ.Arch) + "-apple-" +
|
||||||
|
getOSAndEnvironmentName(Targ.Platform))
|
||||||
|
.str();
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace MachO.
|
} // end namespace MachO.
|
||||||
} // end namespace llvm.
|
} // end namespace llvm.
|
||||||
|
@ -116,6 +116,7 @@ set(LLVM_TEST_DEPENDS
|
|||||||
llvm-strip
|
llvm-strip
|
||||||
llvm-symbolizer
|
llvm-symbolizer
|
||||||
llvm-tblgen
|
llvm-tblgen
|
||||||
|
llvm-tapi-diff
|
||||||
llvm-undname
|
llvm-undname
|
||||||
llvm-windres
|
llvm-windres
|
||||||
llvm-xray
|
llvm-xray
|
||||||
|
@ -164,7 +164,7 @@ tools.extend([
|
|||||||
'llvm-modextract', 'llvm-nm', 'llvm-objcopy', 'llvm-objdump', 'llvm-otool',
|
'llvm-modextract', 'llvm-nm', 'llvm-objcopy', 'llvm-objdump', 'llvm-otool',
|
||||||
'llvm-pdbutil', 'llvm-profdata', 'llvm-profgen', 'llvm-ranlib', 'llvm-rc', 'llvm-readelf',
|
'llvm-pdbutil', 'llvm-profdata', 'llvm-profgen', 'llvm-ranlib', 'llvm-rc', 'llvm-readelf',
|
||||||
'llvm-readobj', 'llvm-rtdyld', 'llvm-size', 'llvm-split', 'llvm-strings',
|
'llvm-readobj', 'llvm-rtdyld', 'llvm-size', 'llvm-split', 'llvm-strings',
|
||||||
'llvm-strip', 'llvm-tblgen', 'llvm-undname', 'llvm-windres',
|
'llvm-strip', 'llvm-tblgen', 'llvm-tapi-diff', 'llvm-undname', 'llvm-windres',
|
||||||
'llvm-c-test', 'llvm-cxxfilt',
|
'llvm-c-test', 'llvm-cxxfilt',
|
||||||
'llvm-xray', 'yaml2obj', 'obj2yaml', 'yaml-bench', 'verify-uselistorder',
|
'llvm-xray', 'yaml2obj', 'obj2yaml', 'yaml-bench', 'verify-uselistorder',
|
||||||
'bugpoint', 'llc', 'llvm-symbolizer', 'opt', 'sancov', 'sanstats'])
|
'bugpoint', 'llc', 'llvm-symbolizer', 'opt', 'sancov', 'sanstats'])
|
||||||
|
141
test/tools/llvm-tapi-diff/Inputs/macho.yaml
Normal file
141
test/tools/llvm-tapi-diff/Inputs/macho.yaml
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
--- !mach-o
|
||||||
|
FileHeader:
|
||||||
|
magic: 0xFEEDFACF
|
||||||
|
cputype: 0x1000007
|
||||||
|
cpusubtype: 0x3
|
||||||
|
filetype: 0x6
|
||||||
|
ncmds: 13
|
||||||
|
sizeofcmds: 584
|
||||||
|
flags: 0x100085
|
||||||
|
reserved: 0x0
|
||||||
|
LoadCommands:
|
||||||
|
- cmd: LC_SEGMENT_64
|
||||||
|
cmdsize: 152
|
||||||
|
segname: __TEXT
|
||||||
|
vmaddr: 0
|
||||||
|
vmsize: 4096
|
||||||
|
fileoff: 0
|
||||||
|
filesize: 4096
|
||||||
|
maxprot: 7
|
||||||
|
initprot: 5
|
||||||
|
nsects: 1
|
||||||
|
flags: 0
|
||||||
|
Sections:
|
||||||
|
- sectname: __text
|
||||||
|
segname: __TEXT
|
||||||
|
addr: 0x1000
|
||||||
|
size: 0
|
||||||
|
offset: 0x1000
|
||||||
|
align: 0
|
||||||
|
reloff: 0x0
|
||||||
|
nreloc: 0
|
||||||
|
flags: 0x80000400
|
||||||
|
reserved1: 0x0
|
||||||
|
reserved2: 0x0
|
||||||
|
reserved3: 0x0
|
||||||
|
content: ''
|
||||||
|
- cmd: LC_SEGMENT_64
|
||||||
|
cmdsize: 72
|
||||||
|
segname: __LINKEDIT
|
||||||
|
vmaddr: 4096
|
||||||
|
vmsize: 4096
|
||||||
|
fileoff: 4096
|
||||||
|
filesize: 112
|
||||||
|
maxprot: 7
|
||||||
|
initprot: 1
|
||||||
|
nsects: 0
|
||||||
|
flags: 0
|
||||||
|
- cmd: LC_ID_DYLIB
|
||||||
|
cmdsize: 48
|
||||||
|
dylib:
|
||||||
|
name: 24
|
||||||
|
timestamp: 1
|
||||||
|
current_version: 65536
|
||||||
|
compatibility_version: 65536
|
||||||
|
PayloadString: macho-no-exports.dylib
|
||||||
|
ZeroPadBytes: 2
|
||||||
|
- cmd: LC_DYLD_INFO_ONLY
|
||||||
|
cmdsize: 48
|
||||||
|
rebase_off: 0
|
||||||
|
rebase_size: 0
|
||||||
|
bind_off: 0
|
||||||
|
bind_size: 0
|
||||||
|
weak_bind_off: 0
|
||||||
|
weak_bind_size: 0
|
||||||
|
lazy_bind_off: 0
|
||||||
|
lazy_bind_size: 0
|
||||||
|
export_off: 0
|
||||||
|
export_size: 0
|
||||||
|
- cmd: LC_SYMTAB
|
||||||
|
cmdsize: 24
|
||||||
|
symoff: 4168
|
||||||
|
nsyms: 1
|
||||||
|
stroff: 4184
|
||||||
|
strsize: 24
|
||||||
|
- cmd: LC_DYSYMTAB
|
||||||
|
cmdsize: 80
|
||||||
|
ilocalsym: 0
|
||||||
|
nlocalsym: 0
|
||||||
|
iextdefsym: 0
|
||||||
|
nextdefsym: 0
|
||||||
|
iundefsym: 0
|
||||||
|
nundefsym: 1
|
||||||
|
tocoff: 0
|
||||||
|
ntoc: 0
|
||||||
|
modtaboff: 0
|
||||||
|
nmodtab: 0
|
||||||
|
extrefsymoff: 0
|
||||||
|
nextrefsyms: 0
|
||||||
|
indirectsymoff: 0
|
||||||
|
nindirectsyms: 0
|
||||||
|
extreloff: 0
|
||||||
|
nextrel: 0
|
||||||
|
locreloff: 0
|
||||||
|
nlocrel: 0
|
||||||
|
- cmd: LC_UUID
|
||||||
|
cmdsize: 24
|
||||||
|
uuid: A24CBA21-865D-372D-B267-4964F4ADCDFC
|
||||||
|
- cmd: LC_VERSION_MIN_MACOSX
|
||||||
|
cmdsize: 16
|
||||||
|
version: 657920
|
||||||
|
sdk: 657920
|
||||||
|
- cmd: LC_SOURCE_VERSION
|
||||||
|
cmdsize: 16
|
||||||
|
version: 0
|
||||||
|
- cmd: LC_LOAD_DYLIB
|
||||||
|
cmdsize: 56
|
||||||
|
dylib:
|
||||||
|
name: 24
|
||||||
|
timestamp: 2
|
||||||
|
current_version: 79495168
|
||||||
|
compatibility_version: 65536
|
||||||
|
PayloadString: '/usr/lib/libSystem.B.dylib'
|
||||||
|
ZeroPadBytes: 6
|
||||||
|
- cmd: LC_FUNCTION_STARTS
|
||||||
|
cmdsize: 16
|
||||||
|
dataoff: 4096
|
||||||
|
datasize: 8
|
||||||
|
- cmd: LC_DATA_IN_CODE
|
||||||
|
cmdsize: 16
|
||||||
|
dataoff: 4104
|
||||||
|
datasize: 0
|
||||||
|
- cmd: LC_DYLIB_CODE_SIGN_DRS
|
||||||
|
cmdsize: 16
|
||||||
|
dataoff: 4104
|
||||||
|
datasize: 64
|
||||||
|
LinkEditData:
|
||||||
|
NameList:
|
||||||
|
- n_strx: 2
|
||||||
|
n_type: 0x1
|
||||||
|
n_sect: 0
|
||||||
|
n_desc: 256
|
||||||
|
n_value: 0
|
||||||
|
StringTable:
|
||||||
|
- ' '
|
||||||
|
- dyld_stub_binder
|
||||||
|
- ''
|
||||||
|
- ''
|
||||||
|
- ''
|
||||||
|
- ''
|
||||||
|
- ''
|
||||||
|
...
|
49
test/tools/llvm-tapi-diff/Inputs/v4A.tbd
Normal file
49
test/tools/llvm-tapi-diff/Inputs/v4A.tbd
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-macos, x86_64-ios ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-macos
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
- target: x86_64-ios
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
flags: [ flat_namespace, installapi ]
|
||||||
|
install-name: Umbrella.framework/Umbrella
|
||||||
|
current-version: 1.2.3
|
||||||
|
compatibility-version: 1.2
|
||||||
|
swift-abi-version: 5
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-macos, x86_64-ios ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos, x86_64-macos, x86_64-ios ]
|
||||||
|
clients: [ ClientA ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symA ]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
||||||
|
- targets: [ x86_64-ios ]
|
||||||
|
symbols: [_symB]
|
||||||
|
- targets: [ x86_64-macos, x86_64-ios ]
|
||||||
|
symbols: [_symAB]
|
||||||
|
reexports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [_symC]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
||||||
|
undefineds:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symD ]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
55
test/tools/llvm-tapi-diff/Inputs/v4B.tbd
Normal file
55
test/tools/llvm-tapi-diff/Inputs/v4B.tbd
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-ios-simulator
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
flags: [ installapi ]
|
||||||
|
install-name: 'Umbrella.framework/Umbrella'
|
||||||
|
current-version: 1.2.3
|
||||||
|
compatibility-version: 0
|
||||||
|
swift-abi-version: 5
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
clients: [ ClientA ]
|
||||||
|
reexported-libraries:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
libraries: [ 'Alpine.framework/Alpine' ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symA ]
|
||||||
|
objc-classes: [ Class1 ]
|
||||||
|
weak-symbols: [ _symC ]
|
||||||
|
- targets: [ x86_64-ios-simulator ]
|
||||||
|
symbols: [ _symB ]
|
||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-ios-simulator
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
flags: []
|
||||||
|
install-name: 'Alpine.framework/Alpine'
|
||||||
|
current-version: 1.2.3
|
||||||
|
compatibility-version: 0
|
||||||
|
swift-abi-version: 5
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
clients: [ ClientD ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symA ]
|
||||||
|
objc-classes: [ Class1 ]
|
||||||
|
weak-symbols: [ _symC ]
|
||||||
|
- targets: [ x86_64-ios-simulator ]
|
||||||
|
symbols: [ _symB ]
|
49
test/tools/llvm-tapi-diff/Inputs/v4C.tbd
Normal file
49
test/tools/llvm-tapi-diff/Inputs/v4C.tbd
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-ios ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-macos
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
- target: x86_64-ios
|
||||||
|
value: 22222222-2222-2222-2222-222222222222
|
||||||
|
flags: [ installapi ]
|
||||||
|
install-name: Umbrella.framework/Umbrella
|
||||||
|
current-version: 1.3.3
|
||||||
|
compatibility-version: 1.2
|
||||||
|
swift-abi-version: 3
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-ios ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos, x86_64-ios ]
|
||||||
|
clients: [ ClientA ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symA ]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
||||||
|
- targets: [ x86_64-ios ]
|
||||||
|
symbols: [_symB]
|
||||||
|
- targets: [ x86_64-ios ]
|
||||||
|
symbols: [_symAB]
|
||||||
|
reexports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [_symC]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
||||||
|
undefineds:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symD ]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
104
test/tools/llvm-tapi-diff/Inputs/v4D.tbd
Normal file
104
test/tools/llvm-tapi-diff/Inputs/v4D.tbd
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-ios-simulator
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
flags: [ installapi ]
|
||||||
|
install-name: 'Umbrella.framework/Umbrella'
|
||||||
|
current-version: 1.2.3
|
||||||
|
compatibility-version: 0
|
||||||
|
swift-abi-version: 5
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
clients: [ ClientA ]
|
||||||
|
reexported-libraries:
|
||||||
|
- targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
libraries: [ 'Alpine.framework/Alpine', 'System.framework/System' ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symA ]
|
||||||
|
objc-classes: [ Class1 ]
|
||||||
|
weak-symbols: [ _symC ]
|
||||||
|
- targets: [ x86_64-ios-simulator ]
|
||||||
|
symbols: [ _symB ]
|
||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-ios-simulator
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
flags: []
|
||||||
|
install-name: 'Alpine.framework/Alpine'
|
||||||
|
current-version: 1.2.3
|
||||||
|
compatibility-version: 0
|
||||||
|
swift-abi-version: 5
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
clients: [ ClientD ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symA ]
|
||||||
|
objc-classes: [ Class1 ]
|
||||||
|
weak-symbols: [ _symC ]
|
||||||
|
- targets: [ x86_64-ios-simulator ]
|
||||||
|
symbols: [ _symB ]
|
||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-ios ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-macos
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
- target: x86_64-ios
|
||||||
|
value: 22222222-2222-2222-2222-222222222222
|
||||||
|
flags: []
|
||||||
|
install-name: 'System.framework/System'
|
||||||
|
current-version: 1.3.3
|
||||||
|
compatibility-version: 1.2
|
||||||
|
swift-abi-version: 3
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-ios ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos, x86_64-ios ]
|
||||||
|
clients: [ ClientA ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symA ]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
||||||
|
- targets: [ x86_64-ios ]
|
||||||
|
symbols: [_symB]
|
||||||
|
- targets: [ x86_64-ios ]
|
||||||
|
symbols: [_symAB]
|
||||||
|
reexports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [_symC]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
||||||
|
undefineds:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symD ]
|
||||||
|
objc-classes: []
|
||||||
|
objc-eh-types: []
|
||||||
|
objc-ivars: []
|
||||||
|
weak-symbols: []
|
||||||
|
thread-local-symbols: []
|
55
test/tools/llvm-tapi-diff/Inputs/v4E.tbd
Normal file
55
test/tools/llvm-tapi-diff/Inputs/v4E.tbd
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-ios-simulator
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
flags: [ installapi ]
|
||||||
|
install-name: 'Umbrella.framework/Umbrella'
|
||||||
|
current-version: 1.2.3
|
||||||
|
compatibility-version: 0
|
||||||
|
swift-abi-version: 4
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
clients: [ ClientC ]
|
||||||
|
reexported-libraries:
|
||||||
|
- targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
libraries: [ Alpine.framework/Alpine ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symA ]
|
||||||
|
objc-classes: [ Class1 ]
|
||||||
|
weak-symbols: [ _symQ ]
|
||||||
|
- targets: [ x86_64-ios-simulator ]
|
||||||
|
symbols: [ _symB ]
|
||||||
|
--- !tapi-tbd
|
||||||
|
tbd-version: 4
|
||||||
|
targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
uuids:
|
||||||
|
- target: i386-macos
|
||||||
|
value: 00000000-0000-0000-0000-000000000000
|
||||||
|
- target: x86_64-ios-simulator
|
||||||
|
value: 11111111-1111-1111-1111-111111111111
|
||||||
|
flags: []
|
||||||
|
install-name: 'Alpine.framework/Alpine'
|
||||||
|
current-version: 1.4.3
|
||||||
|
compatibility-version: 0
|
||||||
|
swift-abi-version: 3
|
||||||
|
parent-umbrella:
|
||||||
|
- targets: [ i386-macos, x86_64-ios-simulator ]
|
||||||
|
umbrella: System
|
||||||
|
allowable-clients:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
clients: [ ClientB ]
|
||||||
|
exports:
|
||||||
|
- targets: [ i386-macos ]
|
||||||
|
symbols: [ _symE ]
|
||||||
|
objc-classes: [ Class1 ]
|
||||||
|
weak-symbols: [ _symC ]
|
||||||
|
- targets: [ x86_64-ios-simulator ]
|
||||||
|
symbols: [ _symB ]
|
@ -0,0 +1,7 @@
|
|||||||
|
; RUN: mkdir -p %t
|
||||||
|
; RUN: yaml2obj %S/Inputs/macho.yaml -o %t/macho.dylib
|
||||||
|
; RUN: not llvm-tapi-diff %S/Inputs/v4A.tbd %t/macho.dylib 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: {{.*}}: error: {{.*}}macho.dylib: Error when parsing file, unsupported file format
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
4
test/tools/llvm-tapi-diff/tapi-diff-matching-tbd.test
Normal file
4
test/tools/llvm-tapi-diff/tapi-diff-matching-tbd.test
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
; RUN: llvm-tapi-diff %S/Inputs/v4A.tbd %S/Inputs/v4A.tbd 2>&1 | FileCheck %s --allow-empty
|
||||||
|
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
@ -0,0 +1,46 @@
|
|||||||
|
; RUN: not llvm-tapi-diff %S/Inputs/v4B.tbd %S/Inputs/v4D.tbd 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK:< {{.*}}/Inputs/v4B.tbd
|
||||||
|
; CHECK:> {{.*}}/Inputs/v4D.tbd
|
||||||
|
|
||||||
|
; CHECK: Reexported Libraries
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > System.framework/System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT: > System.framework/System
|
||||||
|
; CHECK-NEXT:Inlined Reexported Frameworks/Libraries
|
||||||
|
; CHECK-NEXT: System.framework/System
|
||||||
|
; CHECK-NEXT: Current Version
|
||||||
|
; CHECK-NEXT: > 1.3.3
|
||||||
|
; CHECK-NEXT: Compatibility Version
|
||||||
|
; CHECK-NEXT: > 1.2
|
||||||
|
; CHECK-NEXT: Swift ABI Version
|
||||||
|
; CHECK-NEXT: > 3
|
||||||
|
; CHECK-NEXT: InstallAPI
|
||||||
|
; CHECK-NEXT: > false
|
||||||
|
; CHECK-NEXT: Two Level Namespace
|
||||||
|
; CHECK-NEXT: > true
|
||||||
|
; CHECK-NEXT: Application Extension Safe
|
||||||
|
; CHECK-NEXT: > true
|
||||||
|
; CHECK-NEXT: Allowable Clients
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > ClientA
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > ClientA
|
||||||
|
; CHECK-NEXT: Parent Umbrellas
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > _symA
|
||||||
|
; CHECK-NEXT: > _symC - Reexported
|
||||||
|
; CHECK-NEXT: > _symD - Undefined
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > _symB
|
||||||
|
; CHECK-NEXT: > _symAB
|
||||||
|
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
5
test/tools/llvm-tapi-diff/tapi-diff-misspelled-tbd.test
Normal file
5
test/tools/llvm-tapi-diff/tapi-diff-misspelled-tbd.test
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
; RUN: not llvm-tapi-diff %S/Inputs/v4A.tbd %S/Inputs/v4.tbd 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: {{.*}}: error: {{.*}}v4.tbd: {{[Nn]}}o such file or directory
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
26
test/tools/llvm-tapi-diff/tapi-diff-no-inlines.test
Normal file
26
test/tools/llvm-tapi-diff/tapi-diff-no-inlines.test
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: not llvm-tapi-diff %S/Inputs/v4A.tbd %S/Inputs/v4C.tbd 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK:< {{.*}}/Inputs/v4A.tbd
|
||||||
|
; CHECK:> {{.*}}/Inputs/v4C.tbd
|
||||||
|
|
||||||
|
; CHECK:Current Version
|
||||||
|
; CHECK-NEXT:< 1.2.3
|
||||||
|
; CHECK-NEXT:> 1.3.3
|
||||||
|
; CHECK-NEXT:Swift ABI Version
|
||||||
|
; CHECK-NEXT:< 5
|
||||||
|
; CHECK-NEXT:> 3
|
||||||
|
; CHECK-NEXT:Two Level Namespace
|
||||||
|
; CHECK-NEXT:< false
|
||||||
|
; CHECK-NEXT:> true
|
||||||
|
; CHECK-NEXT:Allowable Clients
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK-NEXT: < ClientA
|
||||||
|
; CHECK-NEXT:Parent Umbrellas
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK-NEXT: < System
|
||||||
|
; CHECK-NEXT:Symbols
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK: < _symAB
|
||||||
|
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
@ -0,0 +1,38 @@
|
|||||||
|
; RUN: not llvm-tapi-diff %S/Inputs/v4B.tbd %S/Inputs/v4E.tbd 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK:< {{.*}}/Inputs/v4B.tbd
|
||||||
|
; CHECK:> {{.*}}/Inputs/v4E.tbd
|
||||||
|
|
||||||
|
; CHECK:Swift ABI Version
|
||||||
|
; CHECK-NEXT:< 5
|
||||||
|
; CHECK-NEXT:> 4
|
||||||
|
; CHECK-NEXT:Reexported Libraries
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT:Allowable Clients
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < ClientA
|
||||||
|
; CHECK-NEXT: > ClientC
|
||||||
|
; CHECK-NEXT:Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < _symC - Weak-Defined
|
||||||
|
; CHECK-NEXT: > _symQ - Weak-Defined
|
||||||
|
; CHECK-NEXT:Inlined Reexported Frameworks/Libraries
|
||||||
|
; CHECK-NEXT: Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT: Current Version
|
||||||
|
; CHECK-NEXT: < 1.2.3
|
||||||
|
; CHECK-NEXT: > 1.4.3
|
||||||
|
; CHECK-NEXT: Swift ABI Version
|
||||||
|
; CHECK-NEXT: < 5
|
||||||
|
; CHECK-NEXT: > 3
|
||||||
|
; CHECK-NEXT: Allowable Clients
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < ClientD
|
||||||
|
; CHECK-NEXT: > ClientB
|
||||||
|
; CHECK-NEXT: Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < _symA
|
||||||
|
; CHECK-NEXT: > _symE
|
||||||
|
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
@ -0,0 +1,106 @@
|
|||||||
|
; RUN: not llvm-tapi-diff %S/Inputs/v4A.tbd %S/Inputs/v4D.tbd 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK:< {{.*}}/Inputs/v4A.tbd
|
||||||
|
; CHECK:> {{.*}}/Inputs/v4D.tbd
|
||||||
|
|
||||||
|
; CHECK:Compatibility Version
|
||||||
|
; CHECK-NEXT:< 1.2
|
||||||
|
; CHECK-NEXT:> 0
|
||||||
|
; CHECK-NEXT:Two Level Namespace
|
||||||
|
; CHECK-NEXT:< false
|
||||||
|
; CHECK-NEXT:> true
|
||||||
|
; CHECK-NEXT:Reexported Libraries
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT: > System.framework/System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT: > System.framework/System
|
||||||
|
; CHECK-NEXT:Allowable Clients
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK-NEXT: < ClientA
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: < ClientA
|
||||||
|
; CHECK-NEXT:Parent Umbrellas
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK-NEXT: < System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: < System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT:Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < _symC - Reexported
|
||||||
|
; CHECK-NEXT: < _symD - Undefined
|
||||||
|
; CHECK-NEXT: > .objc_class_name_Class1
|
||||||
|
; CHECK-NEXT: > _symC - Weak-Defined
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK-NEXT: < _symAB
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: < _symB
|
||||||
|
; CHECK-NEXT: < _symAB
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > _symB
|
||||||
|
; CHECK-NEXT:Inlined Reexported Frameworks/Libraries
|
||||||
|
; CHECK-NEXT: Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT: Current Version
|
||||||
|
; CHECK-NEXT: > 1.2.3
|
||||||
|
; CHECK-NEXT: Compatibility Version
|
||||||
|
; CHECK-NEXT: > 0
|
||||||
|
; CHECK-NEXT: Swift ABI Version
|
||||||
|
; CHECK-NEXT: > 5
|
||||||
|
; CHECK-NEXT: InstallAPI
|
||||||
|
; CHECK-NEXT: > false
|
||||||
|
; CHECK-NEXT: Two Level Namespace
|
||||||
|
; CHECK-NEXT: > true
|
||||||
|
; CHECK-NEXT: Application Extension Safe
|
||||||
|
; CHECK-NEXT: > true
|
||||||
|
; CHECK-NEXT: Allowable Clients
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > ClientD
|
||||||
|
; CHECK-NEXT: Parent Umbrellas
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > _symA
|
||||||
|
; CHECK-NEXT: > .objc_class_name_Class1
|
||||||
|
; CHECK-NEXT: > _symC - Weak-Defined
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > _symB
|
||||||
|
; CHECK-NEXT: System.framework/System
|
||||||
|
; CHECK-NEXT: Current Version
|
||||||
|
; CHECK-NEXT: > 1.3.3
|
||||||
|
; CHECK-NEXT: Compatibility Version
|
||||||
|
; CHECK-NEXT: > 1.2
|
||||||
|
; CHECK-NEXT: Swift ABI Version
|
||||||
|
; CHECK-NEXT: > 3
|
||||||
|
; CHECK-NEXT: InstallAPI
|
||||||
|
; CHECK-NEXT: > false
|
||||||
|
; CHECK-NEXT: Two Level Namespace
|
||||||
|
; CHECK-NEXT: > true
|
||||||
|
; CHECK-NEXT: Application Extension Safe
|
||||||
|
; CHECK-NEXT: > true
|
||||||
|
; CHECK-NEXT: Allowable Clients
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > ClientA
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > ClientA
|
||||||
|
; CHECK-NEXT: Parent Umbrellas
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > _symA
|
||||||
|
; CHECK-NEXT: > _symC - Reexported
|
||||||
|
; CHECK-NEXT: > _symD - Undefined
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > _symB
|
||||||
|
; CHECK-NEXT: > _symAB
|
||||||
|
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
@ -0,0 +1,73 @@
|
|||||||
|
; RUN: not llvm-tapi-diff %S/Inputs/v4A.tbd %S/Inputs/v4B.tbd 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK:< {{.*}}/Inputs/v4A.tbd
|
||||||
|
; CHECK:> {{.*}}/Inputs/v4B.tbd
|
||||||
|
|
||||||
|
; CHECK:Compatibility Version
|
||||||
|
; CHECK-NEXT:< 1.2
|
||||||
|
; CHECK-NEXT:> 0
|
||||||
|
; CHECK-NEXT:Two Level Namespace
|
||||||
|
; CHECK-NEXT:< false
|
||||||
|
; CHECK-NEXT:> true
|
||||||
|
; CHECK-NEXT:Reexported Libraries
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT:Allowable Clients
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK-NEXT: < ClientA
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: < ClientA
|
||||||
|
; CHECK-NEXT:Parent Umbrellas
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK-NEXT: < System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: < System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT:Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < _symC - Reexported
|
||||||
|
; CHECK-NEXT: < _symD - Undefined
|
||||||
|
; CHECK-NEXT: > .objc_class_name_Class1
|
||||||
|
; CHECK-NEXT: > _symC - Weak-Defined
|
||||||
|
; CHECK-NEXT: x86_64-apple-macos
|
||||||
|
; CHECK-NEXT: < _symAB
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: < _symB
|
||||||
|
; CHECK-NEXT: < _symAB
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > _symB
|
||||||
|
; CHECK-NEXT:Inlined Reexported Frameworks/Libraries
|
||||||
|
; CHECK-NEXT: Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT: Current Version
|
||||||
|
; CHECK-NEXT: > 1.2.3
|
||||||
|
; CHECK-NEXT: Compatibility Version
|
||||||
|
; CHECK-NEXT: > 0
|
||||||
|
; CHECK-NEXT: Swift ABI Version
|
||||||
|
; CHECK-NEXT: > 5
|
||||||
|
; CHECK-NEXT: InstallAPI
|
||||||
|
; CHECK-NEXT: > false
|
||||||
|
; CHECK-NEXT: Two Level Namespace
|
||||||
|
; CHECK-NEXT: > true
|
||||||
|
; CHECK-NEXT: Application Extension Safe
|
||||||
|
; CHECK-NEXT: > true
|
||||||
|
; CHECK-NEXT: Allowable Clients
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > ClientD
|
||||||
|
; CHECK-NEXT: Parent Umbrellas
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: > _symA
|
||||||
|
; CHECK-NEXT: > .objc_class_name_Class1
|
||||||
|
; CHECK-NEXT: > _symC - Weak-Defined
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: > _symB
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
@ -0,0 +1,68 @@
|
|||||||
|
; RUN: not llvm-tapi-diff %S/Inputs/v4B.tbd %S/Inputs/v4C.tbd 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK:< {{.*}}/Inputs/v4B.tbd
|
||||||
|
; CHECK:> {{.*}}/Inputs/v4C.tbd
|
||||||
|
|
||||||
|
; CHECK:Current Version
|
||||||
|
; CHECK-NEXT:< 1.2.3
|
||||||
|
; CHECK-NEXT:> 1.3.3
|
||||||
|
; CHECK-NEXT:Compatibility Version
|
||||||
|
; CHECK-NEXT:< 0
|
||||||
|
; CHECK-NEXT:> 1.2
|
||||||
|
; CHECK-NEXT:Swift ABI Version
|
||||||
|
; CHECK-NEXT:< 5
|
||||||
|
; CHECK-NEXT:> 3
|
||||||
|
; CHECK-NEXT:Reexported Libraries
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT:Allowable Clients
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > ClientA
|
||||||
|
; CHECK-NEXT:Parent Umbrellas
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: < System
|
||||||
|
; CHECK-NEXT:Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < .objc_class_name_Class1
|
||||||
|
; CHECK-NEXT: < _symC - Weak-Defined
|
||||||
|
; CHECK-NEXT: > _symC - Reexported
|
||||||
|
; CHECK-NEXT: > _symD - Undefined
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios
|
||||||
|
; CHECK-NEXT: > _symB
|
||||||
|
; CHECK-NEXT: > _symAB
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: < _symB
|
||||||
|
; CHECK-NEXT:Inlined Reexported Frameworks/Libraries
|
||||||
|
; CHECK-NEXT: Alpine.framework/Alpine
|
||||||
|
; CHECK-NEXT: Current Version
|
||||||
|
; CHECK-NEXT: < 1.2.3
|
||||||
|
; CHECK-NEXT: Compatibility Version
|
||||||
|
; CHECK-NEXT: < 0
|
||||||
|
; CHECK-NEXT: Swift ABI Version
|
||||||
|
; CHECK-NEXT: < 5
|
||||||
|
; CHECK-NEXT: InstallAPI
|
||||||
|
; CHECK-NEXT: < false
|
||||||
|
; CHECK-NEXT: Two Level Namespace
|
||||||
|
; CHECK-NEXT: < true
|
||||||
|
; CHECK-NEXT: Application Extension Safe
|
||||||
|
; CHECK-NEXT: < true
|
||||||
|
; CHECK-NEXT: Allowable Clients
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < ClientD
|
||||||
|
; CHECK-NEXT: Parent Umbrellas
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < System
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: < System
|
||||||
|
; CHECK-NEXT: Symbols
|
||||||
|
; CHECK-NEXT: i386-apple-macos
|
||||||
|
; CHECK-NEXT: < _symA
|
||||||
|
; CHECK-NEXT: < .objc_class_name_Class1
|
||||||
|
; CHECK-NEXT: < _symC - Weak-Defined
|
||||||
|
; CHECK-NEXT: x86_64-apple-ios-simulator
|
||||||
|
; CHECK-NEXT: < _symB
|
||||||
|
|
||||||
|
; CHECK-NOT: error:
|
||||||
|
; CHECK-NOT: warning:
|
10
tools/llvm-tapi-diff/CMakeLists.txt
Normal file
10
tools/llvm-tapi-diff/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
set(LLVM_LINK_COMPONENTS
|
||||||
|
Object
|
||||||
|
Support
|
||||||
|
TextAPI
|
||||||
|
)
|
||||||
|
|
||||||
|
add_llvm_tool(llvm-tapi-diff
|
||||||
|
llvm-tapi-diff.cpp
|
||||||
|
DiffEngine.cpp
|
||||||
|
)
|
554
tools/llvm-tapi-diff/DiffEngine.cpp
Normal file
554
tools/llvm-tapi-diff/DiffEngine.cpp
Normal file
@ -0,0 +1,554 @@
|
|||||||
|
//===-- DiffEngine.cpp - Structural file comparison -----------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file defines the implementation of the llvm-tapi difference
|
||||||
|
// engine, which structurally compares two tbd files.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===/
|
||||||
|
#include "DiffEngine.h"
|
||||||
|
#include "llvm/Support/Casting.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/TextAPI/InterfaceFile.h"
|
||||||
|
#include "llvm/TextAPI/Target.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace MachO;
|
||||||
|
using namespace object;
|
||||||
|
|
||||||
|
StringRef setOrderIndicator(InterfaceInputOrder Order) {
|
||||||
|
return ((Order == lhs) ? "< " : "> ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following template specialization implementations
|
||||||
|
// need to be explicitly placed into the llvm namespace
|
||||||
|
// to work around a GCC 4.8 bug.
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
template <typename T, DiffAttrKind U>
|
||||||
|
inline void DiffScalarVal<T, U>::print(raw_ostream &OS, std::string Indent) {
|
||||||
|
OS << Indent << "\t" << setOrderIndicator(Order) << Val << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void
|
||||||
|
DiffScalarVal<StringRef, AD_Diff_Scalar_Str>::print(raw_ostream &OS,
|
||||||
|
std::string Indent) {
|
||||||
|
OS << Indent << "\t\t" << setOrderIndicator(Order) << Val << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void
|
||||||
|
DiffScalarVal<uint8_t, AD_Diff_Scalar_Unsigned>::print(raw_ostream &OS,
|
||||||
|
std::string Indent) {
|
||||||
|
OS << Indent << "\t" << setOrderIndicator(Order) << std::to_string(Val)
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void
|
||||||
|
DiffScalarVal<bool, AD_Diff_Scalar_Bool>::print(raw_ostream &OS,
|
||||||
|
std::string Indent) {
|
||||||
|
OS << Indent << "\t" << setOrderIndicator(Order)
|
||||||
|
<< ((Val == true) ? "true" : "false") << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
std::string SymScalar::stringifySymbolKind(MachO::SymbolKind Kind) {
|
||||||
|
switch (Kind) {
|
||||||
|
case MachO::SymbolKind::GlobalSymbol:
|
||||||
|
return "";
|
||||||
|
case MachO::SymbolKind::ObjectiveCClass:
|
||||||
|
return "_OBJC_METACLASS_$_";
|
||||||
|
case MachO::SymbolKind ::ObjectiveCClassEHType:
|
||||||
|
return "_OBJC_EHTYPE_$_";
|
||||||
|
case MachO::SymbolKind ::ObjectiveCInstanceVariable:
|
||||||
|
return "_OBJC_IVAR_$_";
|
||||||
|
}
|
||||||
|
llvm_unreachable("Unknown llvm::MachO::SymbolKind enum");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SymScalar::stringifySymbolFlag(MachO::SymbolFlags Flag) {
|
||||||
|
switch (Flag) {
|
||||||
|
case MachO::SymbolFlags::None:
|
||||||
|
return "";
|
||||||
|
case MachO::SymbolFlags::ThreadLocalValue:
|
||||||
|
return "Thread-Local";
|
||||||
|
case MachO::SymbolFlags::WeakDefined:
|
||||||
|
return "Weak-Defined";
|
||||||
|
case MachO::SymbolFlags::WeakReferenced:
|
||||||
|
return "Weak-Referenced";
|
||||||
|
case MachO::SymbolFlags::Undefined:
|
||||||
|
return "Undefined";
|
||||||
|
case MachO::SymbolFlags::Rexported:
|
||||||
|
return "Reexported";
|
||||||
|
}
|
||||||
|
llvm_unreachable("Unknown llvm::MachO::SymbolFlags enum");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymScalar::print(raw_ostream &OS, std::string Indent, MachO::Target Targ) {
|
||||||
|
if (Val->getKind() == MachO::SymbolKind::ObjectiveCClass) {
|
||||||
|
if (Targ.Arch == MachO::AK_i386 &&
|
||||||
|
Targ.Platform == MachO::PlatformKind::macOS) {
|
||||||
|
OS << Indent << "\t\t" << ((Order == lhs) ? "< " : "> ")
|
||||||
|
<< ".objc_class_name_" << Val->getName()
|
||||||
|
<< getFlagString(Val->getFlags()) << "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OS << Indent << "\t\t" << ((Order == lhs) ? "< " : "> ") << "_OBJC_CLASS_$_"
|
||||||
|
<< Val->getName() << getFlagString(Val->getFlags()) << "\n";
|
||||||
|
}
|
||||||
|
OS << Indent << "\t\t" << ((Order == lhs) ? "< " : "> ")
|
||||||
|
<< stringifySymbolKind(Val->getKind()) << Val->getName()
|
||||||
|
<< getFlagString(Val->getFlags()) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkSymbolEquality(llvm::MachO::InterfaceFile::const_symbol_range LHS,
|
||||||
|
llvm::MachO::InterfaceFile::const_symbol_range RHS) {
|
||||||
|
return std::equal(LHS.begin(), LHS.end(), RHS.begin(),
|
||||||
|
[&](auto LHS, auto RHS) { return *LHS == *RHS; });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TargetVecT, typename ValTypeT, typename V>
|
||||||
|
void addDiffForTargSlice(V Val, Target Targ, DiffOutput &Diff,
|
||||||
|
InterfaceInputOrder Order) {
|
||||||
|
auto TargetVector = llvm::find_if(
|
||||||
|
Diff.Values, [&](const std::unique_ptr<AttributeDiff> &RawTVec) {
|
||||||
|
if (TargetVecT *TVec = dyn_cast<TargetVecT>(RawTVec.get()))
|
||||||
|
return TVec->Targ == Targ;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if (TargetVector != Diff.Values.end()) {
|
||||||
|
ValTypeT NewVal(Order, Val);
|
||||||
|
cast<TargetVecT>(TargetVector->get())->TargValues.push_back(NewVal);
|
||||||
|
} else {
|
||||||
|
auto NewTargetVec = std::make_unique<TargetVecT>(Targ);
|
||||||
|
ValTypeT NewVal(Order, Val);
|
||||||
|
NewTargetVec->TargValues.push_back(NewVal);
|
||||||
|
Diff.Values.push_back(std::move(NewTargetVec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DiffOutput getSingleAttrDiff(const std::vector<InterfaceFileRef> &IRefVec,
|
||||||
|
std::string Name, InterfaceInputOrder Order) {
|
||||||
|
DiffOutput Diff(Name);
|
||||||
|
Diff.Kind = AD_Str_Vec;
|
||||||
|
for (const auto &IRef : IRefVec)
|
||||||
|
for (auto Targ : IRef.targets())
|
||||||
|
addDiffForTargSlice<DiffStrVec,
|
||||||
|
DiffScalarVal<StringRef, AD_Diff_Scalar_Str>>(
|
||||||
|
IRef.getInstallName(), Targ, Diff, Order);
|
||||||
|
return Diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiffOutput
|
||||||
|
getSingleAttrDiff(const std::vector<std::pair<Target, std::string>> &PairVec,
|
||||||
|
std::string Name, InterfaceInputOrder Order) {
|
||||||
|
DiffOutput Diff(Name);
|
||||||
|
Diff.Kind = AD_Str_Vec;
|
||||||
|
for (const auto &Pair : PairVec)
|
||||||
|
addDiffForTargSlice<DiffStrVec,
|
||||||
|
DiffScalarVal<StringRef, AD_Diff_Scalar_Str>>(
|
||||||
|
StringRef(Pair.second), Pair.first, Diff, Order);
|
||||||
|
return Diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiffOutput getSingleAttrDiff(InterfaceFile::const_symbol_range SymRange,
|
||||||
|
std::string Name, InterfaceInputOrder Order) {
|
||||||
|
DiffOutput Diff(Name);
|
||||||
|
Diff.Kind = AD_Sym_Vec;
|
||||||
|
for (const auto *Sym : SymRange)
|
||||||
|
for (auto Targ : Sym->targets())
|
||||||
|
addDiffForTargSlice<DiffSymVec, SymScalar>(Sym, Targ, Diff, Order);
|
||||||
|
return Diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DiffOutput getSingleAttrDiff(T SingleAttr, std::string Attribute) {
|
||||||
|
DiffOutput Diff(Attribute);
|
||||||
|
Diff.Kind = SingleAttr.getKind();
|
||||||
|
Diff.Values.push_back(std::make_unique<T>(SingleAttr));
|
||||||
|
return Diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, DiffAttrKind U>
|
||||||
|
void diffAttribute(std::string Name, std::vector<DiffOutput> &Output,
|
||||||
|
DiffScalarVal<T, U> Attr) {
|
||||||
|
Output.push_back(getSingleAttrDiff(Attr, Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void diffAttribute(std::string Name, std::vector<DiffOutput> &Output,
|
||||||
|
const T &Val, InterfaceInputOrder Order) {
|
||||||
|
Output.push_back(getSingleAttrDiff(Val, Name, Order));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DiffOutput> getSingleIF(InterfaceFile *Interface,
|
||||||
|
InterfaceInputOrder Order) {
|
||||||
|
std::vector<DiffOutput> Output;
|
||||||
|
diffAttribute("Install Name", Output,
|
||||||
|
DiffScalarVal<StringRef, AD_Diff_Scalar_Str>(
|
||||||
|
Order, Interface->getInstallName()));
|
||||||
|
diffAttribute("Current Version", Output,
|
||||||
|
DiffScalarVal<PackedVersion, AD_Diff_Scalar_PackedVersion>(
|
||||||
|
Order, Interface->getCurrentVersion()));
|
||||||
|
diffAttribute("Compatibility Version", Output,
|
||||||
|
DiffScalarVal<PackedVersion, AD_Diff_Scalar_PackedVersion>(
|
||||||
|
Order, Interface->getCompatibilityVersion()));
|
||||||
|
diffAttribute("Swift ABI Version", Output,
|
||||||
|
DiffScalarVal<uint8_t, AD_Diff_Scalar_Unsigned>(
|
||||||
|
Order, Interface->getSwiftABIVersion()));
|
||||||
|
diffAttribute("InstallAPI", Output,
|
||||||
|
DiffScalarVal<bool, AD_Diff_Scalar_Bool>(
|
||||||
|
Order, Interface->isInstallAPI()));
|
||||||
|
diffAttribute("Two Level Namespace", Output,
|
||||||
|
DiffScalarVal<bool, AD_Diff_Scalar_Bool>(
|
||||||
|
Order, Interface->isTwoLevelNamespace()));
|
||||||
|
diffAttribute("Application Extension Safe", Output,
|
||||||
|
DiffScalarVal<bool, AD_Diff_Scalar_Bool>(
|
||||||
|
Order, Interface->isApplicationExtensionSafe()));
|
||||||
|
diffAttribute("Reexported Libraries", Output,
|
||||||
|
Interface->reexportedLibraries(), Order);
|
||||||
|
diffAttribute("Allowable Clients", Output, Interface->allowableClients(),
|
||||||
|
Order);
|
||||||
|
diffAttribute("Parent Umbrellas", Output, Interface->umbrellas(), Order);
|
||||||
|
diffAttribute("Symbols", Output, Interface->symbols(), Order);
|
||||||
|
for (auto Doc : Interface->documents()) {
|
||||||
|
DiffOutput Documents("Inlined Reexported Frameworks/Libraries");
|
||||||
|
Documents.Kind = AD_Inline_Doc;
|
||||||
|
Documents.Values.push_back(std::make_unique<InlineDoc>(
|
||||||
|
InlineDoc(Doc->getInstallName(), getSingleIF(Doc.get(), Order))));
|
||||||
|
Output.push_back(std::move(Documents));
|
||||||
|
}
|
||||||
|
return Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void findAndAddDiff(const std::vector<InterfaceFileRef> &CollectedIRefVec,
|
||||||
|
const std::vector<InterfaceFileRef> &LookupIRefVec,
|
||||||
|
DiffOutput &Result, InterfaceInputOrder Order) {
|
||||||
|
Result.Kind = AD_Str_Vec;
|
||||||
|
for (const auto &IRef : CollectedIRefVec)
|
||||||
|
for (auto Targ : IRef.targets()) {
|
||||||
|
auto FoundIRef = llvm::find_if(LookupIRefVec, [&](const auto LIRef) {
|
||||||
|
auto FoundTarg = llvm::find(LIRef.targets(), Targ);
|
||||||
|
return (FoundTarg != LIRef.targets().end() &&
|
||||||
|
IRef.getInstallName() == LIRef.getInstallName());
|
||||||
|
});
|
||||||
|
if (FoundIRef == LookupIRefVec.end())
|
||||||
|
addDiffForTargSlice<DiffStrVec,
|
||||||
|
DiffScalarVal<StringRef, AD_Diff_Scalar_Str>>(
|
||||||
|
IRef.getInstallName(), Targ, Result, Order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void findAndAddDiff(
|
||||||
|
const std::vector<std::pair<Target, std::string>> &CollectedPairs,
|
||||||
|
const std::vector<std::pair<Target, std::string>> &LookupPairs,
|
||||||
|
DiffOutput &Result, InterfaceInputOrder Order) {
|
||||||
|
Result.Kind = AD_Str_Vec;
|
||||||
|
for (const auto &Pair : CollectedPairs) {
|
||||||
|
auto FoundPair = llvm::find(LookupPairs, Pair);
|
||||||
|
if (FoundPair == LookupPairs.end())
|
||||||
|
addDiffForTargSlice<DiffStrVec,
|
||||||
|
DiffScalarVal<StringRef, AD_Diff_Scalar_Str>>(
|
||||||
|
StringRef(Pair.second), Pair.first, Result, Order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void findAndAddDiff(InterfaceFile::const_symbol_range CollectedSyms,
|
||||||
|
InterfaceFile::const_symbol_range LookupSyms,
|
||||||
|
DiffOutput &Result, InterfaceInputOrder Order) {
|
||||||
|
Result.Kind = AD_Sym_Vec;
|
||||||
|
for (const auto *Sym : CollectedSyms)
|
||||||
|
for (const auto Targ : Sym->targets()) {
|
||||||
|
auto FoundSym = llvm::find_if(LookupSyms, [&](const auto LSym) {
|
||||||
|
auto FoundTarg = llvm::find(LSym->targets(), Targ);
|
||||||
|
return (Sym->getName() == LSym->getName() &&
|
||||||
|
Sym->getKind() == LSym->getKind() &&
|
||||||
|
Sym->getFlags() == LSym->getFlags() &&
|
||||||
|
FoundTarg != LSym->targets().end());
|
||||||
|
});
|
||||||
|
if (FoundSym == LookupSyms.end())
|
||||||
|
addDiffForTargSlice<DiffSymVec, SymScalar>(Sym, Targ, Result, Order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DiffOutput recordDifferences(T LHS, T RHS, std::string Attr) {
|
||||||
|
DiffOutput Diff(Attr);
|
||||||
|
if (LHS.getKind() == RHS.getKind()) {
|
||||||
|
Diff.Kind = LHS.getKind();
|
||||||
|
Diff.Values.push_back(std::make_unique<T>(LHS));
|
||||||
|
Diff.Values.push_back(std::make_unique<T>(RHS));
|
||||||
|
}
|
||||||
|
return Diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DiffOutput recordDifferences(const std::vector<T> &LHS,
|
||||||
|
const std::vector<T> &RHS, std::string Attr) {
|
||||||
|
DiffOutput Diff(Attr);
|
||||||
|
Diff.Kind = AD_Str_Vec;
|
||||||
|
findAndAddDiff(LHS, RHS, Diff, lhs);
|
||||||
|
findAndAddDiff(RHS, LHS, Diff, rhs);
|
||||||
|
return Diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiffOutput recordDifferences(llvm::MachO::InterfaceFile::const_symbol_range LHS,
|
||||||
|
llvm::MachO::InterfaceFile::const_symbol_range RHS,
|
||||||
|
std::string Attr) {
|
||||||
|
DiffOutput Diff(Attr);
|
||||||
|
Diff.Kind = AD_Sym_Vec;
|
||||||
|
findAndAddDiff(LHS, RHS, Diff, lhs);
|
||||||
|
findAndAddDiff(RHS, LHS, Diff, rhs);
|
||||||
|
return Diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DiffOutput>
|
||||||
|
DiffEngine::findDifferences(const InterfaceFile *IFLHS,
|
||||||
|
const InterfaceFile *IFRHS) {
|
||||||
|
std::vector<DiffOutput> Output;
|
||||||
|
if (IFLHS->getInstallName() != IFRHS->getInstallName())
|
||||||
|
Output.push_back(recordDifferences(
|
||||||
|
DiffScalarVal<StringRef, AD_Diff_Scalar_Str>(lhs,
|
||||||
|
IFLHS->getInstallName()),
|
||||||
|
DiffScalarVal<StringRef, AD_Diff_Scalar_Str>(rhs,
|
||||||
|
IFRHS->getInstallName()),
|
||||||
|
"Install Name"));
|
||||||
|
|
||||||
|
if (IFLHS->getCurrentVersion() != IFRHS->getCurrentVersion())
|
||||||
|
Output.push_back(recordDifferences(
|
||||||
|
DiffScalarVal<PackedVersion, AD_Diff_Scalar_PackedVersion>(
|
||||||
|
lhs, IFLHS->getCurrentVersion()),
|
||||||
|
DiffScalarVal<PackedVersion, AD_Diff_Scalar_PackedVersion>(
|
||||||
|
rhs, IFRHS->getCurrentVersion()),
|
||||||
|
"Current Version"));
|
||||||
|
if (IFLHS->getCompatibilityVersion() != IFRHS->getCompatibilityVersion())
|
||||||
|
Output.push_back(recordDifferences(
|
||||||
|
DiffScalarVal<PackedVersion, AD_Diff_Scalar_PackedVersion>(
|
||||||
|
lhs, IFLHS->getCompatibilityVersion()),
|
||||||
|
DiffScalarVal<PackedVersion, AD_Diff_Scalar_PackedVersion>(
|
||||||
|
rhs, IFRHS->getCompatibilityVersion()),
|
||||||
|
"Compatibility Version"));
|
||||||
|
if (IFLHS->getSwiftABIVersion() != IFRHS->getSwiftABIVersion())
|
||||||
|
Output.push_back(
|
||||||
|
recordDifferences(DiffScalarVal<uint8_t, AD_Diff_Scalar_Unsigned>(
|
||||||
|
lhs, IFLHS->getSwiftABIVersion()),
|
||||||
|
DiffScalarVal<uint8_t, AD_Diff_Scalar_Unsigned>(
|
||||||
|
rhs, IFRHS->getSwiftABIVersion()),
|
||||||
|
"Swift ABI Version"));
|
||||||
|
if (IFLHS->isInstallAPI() != IFRHS->isInstallAPI())
|
||||||
|
Output.push_back(recordDifferences(
|
||||||
|
DiffScalarVal<bool, AD_Diff_Scalar_Bool>(lhs, IFLHS->isInstallAPI()),
|
||||||
|
DiffScalarVal<bool, AD_Diff_Scalar_Bool>(rhs, IFRHS->isInstallAPI()),
|
||||||
|
"InstallAPI"));
|
||||||
|
|
||||||
|
if (IFLHS->isTwoLevelNamespace() != IFRHS->isTwoLevelNamespace())
|
||||||
|
Output.push_back(recordDifferences(DiffScalarVal<bool, AD_Diff_Scalar_Bool>(
|
||||||
|
lhs, IFLHS->isTwoLevelNamespace()),
|
||||||
|
DiffScalarVal<bool, AD_Diff_Scalar_Bool>(
|
||||||
|
rhs, IFRHS->isTwoLevelNamespace()),
|
||||||
|
"Two Level Namespace"));
|
||||||
|
|
||||||
|
if (IFLHS->isApplicationExtensionSafe() !=
|
||||||
|
IFRHS->isApplicationExtensionSafe())
|
||||||
|
Output.push_back(
|
||||||
|
recordDifferences(DiffScalarVal<bool, AD_Diff_Scalar_Bool>(
|
||||||
|
lhs, IFLHS->isApplicationExtensionSafe()),
|
||||||
|
DiffScalarVal<bool, AD_Diff_Scalar_Bool>(
|
||||||
|
rhs, IFRHS->isApplicationExtensionSafe()),
|
||||||
|
"Application Extension Safe"));
|
||||||
|
|
||||||
|
if (IFLHS->reexportedLibraries() != IFRHS->reexportedLibraries())
|
||||||
|
Output.push_back(recordDifferences(IFLHS->reexportedLibraries(),
|
||||||
|
IFRHS->reexportedLibraries(),
|
||||||
|
"Reexported Libraries"));
|
||||||
|
|
||||||
|
if (IFLHS->allowableClients() != IFRHS->allowableClients())
|
||||||
|
Output.push_back(recordDifferences(IFLHS->allowableClients(),
|
||||||
|
IFRHS->allowableClients(),
|
||||||
|
"Allowable Clients"));
|
||||||
|
|
||||||
|
if (IFLHS->umbrellas() != IFRHS->umbrellas())
|
||||||
|
Output.push_back(recordDifferences(IFLHS->umbrellas(), IFRHS->umbrellas(),
|
||||||
|
"Parent Umbrellas"));
|
||||||
|
|
||||||
|
if (!checkSymbolEquality(IFLHS->symbols(), IFRHS->symbols()))
|
||||||
|
Output.push_back(
|
||||||
|
recordDifferences(IFLHS->symbols(), IFRHS->symbols(), "Symbols"));
|
||||||
|
|
||||||
|
if (IFLHS->documents() != IFRHS->documents()) {
|
||||||
|
DiffOutput Docs("Inlined Reexported Frameworks/Libraries");
|
||||||
|
Docs.Kind = AD_Inline_Doc;
|
||||||
|
std::vector<StringRef> DocsInserted;
|
||||||
|
// Iterate through inline frameworks/libraries from interface file and find
|
||||||
|
// match based on install name.
|
||||||
|
for (auto DocLHS : IFLHS->documents()) {
|
||||||
|
auto Pair = llvm::find_if(IFRHS->documents(), [&](const auto &DocRHS) {
|
||||||
|
return (DocLHS->getInstallName() == DocRHS->getInstallName());
|
||||||
|
});
|
||||||
|
// If a match found, recursively get differences between the pair.
|
||||||
|
if (Pair != IFRHS->documents().end()) {
|
||||||
|
InlineDoc PairDiff =
|
||||||
|
InlineDoc(DocLHS->getInstallName(),
|
||||||
|
findDifferences(DocLHS.get(), Pair->get()));
|
||||||
|
if (!PairDiff.DocValues.empty())
|
||||||
|
Docs.Values.push_back(
|
||||||
|
std::make_unique<InlineDoc>(std::move(PairDiff)));
|
||||||
|
}
|
||||||
|
// If a match is not found, get attributes from single item.
|
||||||
|
else
|
||||||
|
Docs.Values.push_back(std::make_unique<InlineDoc>(InlineDoc(
|
||||||
|
DocLHS->getInstallName(), getSingleIF(DocLHS.get(), lhs))));
|
||||||
|
DocsInserted.push_back(DocLHS->getInstallName());
|
||||||
|
}
|
||||||
|
for (auto DocRHS : IFRHS->documents()) {
|
||||||
|
auto WasGathered =
|
||||||
|
llvm::find_if(DocsInserted, [&](const auto &GatheredDoc) {
|
||||||
|
return (GatheredDoc == DocRHS->getInstallName());
|
||||||
|
});
|
||||||
|
if (WasGathered == DocsInserted.end())
|
||||||
|
Docs.Values.push_back(std::make_unique<InlineDoc>(InlineDoc(
|
||||||
|
DocRHS->getInstallName(), getSingleIF(DocRHS.get(), rhs))));
|
||||||
|
}
|
||||||
|
if (!Docs.Values.empty())
|
||||||
|
Output.push_back(std::move(Docs));
|
||||||
|
}
|
||||||
|
return Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void printSingleVal(std::string Indent, const DiffOutput &Attr,
|
||||||
|
raw_ostream &OS) {
|
||||||
|
if (Attr.Values.empty())
|
||||||
|
return;
|
||||||
|
OS << Indent << Attr.Name << "\n";
|
||||||
|
for (auto &RawItem : Attr.Values)
|
||||||
|
if (T *Item = dyn_cast<T>(RawItem.get()))
|
||||||
|
Item->print(OS, Indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T *castValues(const std::unique_ptr<AttributeDiff> &RawAttr) {
|
||||||
|
T *CastAttr = cast<T>(RawAttr.get());
|
||||||
|
return CastAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void sortTargetValues(std::vector<T> &TargValues) {
|
||||||
|
llvm::stable_sort(TargValues, [](const auto &ValA, const auto &ValB) {
|
||||||
|
return ValA.getOrder() < ValB.getOrder();
|
||||||
|
});
|
||||||
|
llvm::stable_sort(TargValues, [](const auto &ValA, const auto &ValB) {
|
||||||
|
return ValA.getOrder() == ValB.getOrder() && ValA.getVal() < ValB.getVal();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void printVecVal(std::string Indent, const DiffOutput &Attr, raw_ostream &OS) {
|
||||||
|
if (Attr.Values.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
OS << Indent << Attr.Name << "\n";
|
||||||
|
|
||||||
|
std::vector<T *> SortedAttrs;
|
||||||
|
|
||||||
|
llvm::transform(Attr.Values, std::back_inserter(SortedAttrs), castValues<T>);
|
||||||
|
|
||||||
|
llvm::sort(SortedAttrs, [&](const auto &ValA, const auto &ValB) {
|
||||||
|
return ValA->Targ < ValB->Targ;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto *Vec : SortedAttrs) {
|
||||||
|
sortTargetValues<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>>(
|
||||||
|
Vec->TargValues);
|
||||||
|
OS << Indent << "\t" << getTargetTripleName(Vec->Targ) << "\n";
|
||||||
|
for (auto &Item : Vec->TargValues)
|
||||||
|
Item.print(OS, Indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void printVecVal<DiffSymVec>(std::string Indent, const DiffOutput &Attr,
|
||||||
|
raw_ostream &OS) {
|
||||||
|
if (Attr.Values.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
OS << Indent << Attr.Name << "\n";
|
||||||
|
|
||||||
|
std::vector<DiffSymVec *> SortedAttrs;
|
||||||
|
|
||||||
|
llvm::transform(Attr.Values, std::back_inserter(SortedAttrs),
|
||||||
|
castValues<DiffSymVec>);
|
||||||
|
|
||||||
|
llvm::sort(SortedAttrs, [&](const auto &ValA, const auto &ValB) {
|
||||||
|
return ValA->Targ < ValB->Targ;
|
||||||
|
});
|
||||||
|
for (auto *SymVec : SortedAttrs) {
|
||||||
|
sortTargetValues<SymScalar>(SymVec->TargValues);
|
||||||
|
OS << Indent << "\t" << getTargetTripleName(SymVec->Targ) << "\n";
|
||||||
|
for (auto &Item : SymVec->TargValues)
|
||||||
|
Item.print(OS, Indent, SymVec->Targ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiffEngine::printDifferences(raw_ostream &OS,
|
||||||
|
const std::vector<DiffOutput> &Diffs,
|
||||||
|
int IndentCounter) {
|
||||||
|
std::string Indent = std::string(IndentCounter, '\t');
|
||||||
|
for (auto &Attr : Diffs) {
|
||||||
|
switch (Attr.Kind) {
|
||||||
|
case AD_Diff_Scalar_Str:
|
||||||
|
if (IndentCounter == 0)
|
||||||
|
printSingleVal<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>>(Indent,
|
||||||
|
Attr, OS);
|
||||||
|
break;
|
||||||
|
case AD_Diff_Scalar_PackedVersion:
|
||||||
|
printSingleVal<
|
||||||
|
DiffScalarVal<PackedVersion, AD_Diff_Scalar_PackedVersion>>(Indent,
|
||||||
|
Attr, OS);
|
||||||
|
break;
|
||||||
|
case AD_Diff_Scalar_Unsigned:
|
||||||
|
printSingleVal<DiffScalarVal<uint8_t, AD_Diff_Scalar_Unsigned>>(Indent,
|
||||||
|
Attr, OS);
|
||||||
|
break;
|
||||||
|
case AD_Diff_Scalar_Bool:
|
||||||
|
printSingleVal<DiffScalarVal<bool, AD_Diff_Scalar_Bool>>(Indent, Attr,
|
||||||
|
OS);
|
||||||
|
break;
|
||||||
|
case AD_Str_Vec:
|
||||||
|
printVecVal<DiffStrVec>(Indent, Attr, OS);
|
||||||
|
break;
|
||||||
|
case AD_Sym_Vec:
|
||||||
|
printVecVal<DiffSymVec>(Indent, Attr, OS);
|
||||||
|
break;
|
||||||
|
case AD_Inline_Doc:
|
||||||
|
if (!Attr.Values.empty()) {
|
||||||
|
OS << Indent << Attr.Name << "\n";
|
||||||
|
for (auto &Item : Attr.Values)
|
||||||
|
if (InlineDoc *Doc = dyn_cast<InlineDoc>(Item.get()))
|
||||||
|
if (!Doc->DocValues.empty()) {
|
||||||
|
OS << Indent << "\t" << Doc->InstallName << "\n";
|
||||||
|
printDifferences(OS, std::move(Doc->DocValues), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiffEngine::compareFiles(raw_ostream &OS) {
|
||||||
|
const auto *IFLHS = &(FileLHS->getInterfaceFile());
|
||||||
|
const auto *IFRHS = &(FileRHS->getInterfaceFile());
|
||||||
|
if (*IFLHS == *IFRHS)
|
||||||
|
return false;
|
||||||
|
OS << "< " << std::string(IFLHS->getPath().data()) << "\n> "
|
||||||
|
<< std::string(IFRHS->getPath().data()) << "\n\n";
|
||||||
|
std::vector<DiffOutput> Diffs = findDifferences(IFLHS, IFRHS);
|
||||||
|
printDifferences(OS, Diffs, 0);
|
||||||
|
return true;
|
||||||
|
}
|
169
tools/llvm-tapi-diff/DiffEngine.h
Normal file
169
tools/llvm-tapi-diff/DiffEngine.h
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
//===-- DiffEngine.h - File comparator --------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This header defines the interface to the llvm-tapi difference engine,
|
||||||
|
// which structurally compares two tbd files.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===/
|
||||||
|
#ifndef LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H
|
||||||
|
#define LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
|
#include "llvm/Object/TapiUniversal.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/TextAPI/Symbol.h"
|
||||||
|
#include "llvm/TextAPI/Target.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/// InterfaceInputOrder determines from which file the diff attribute belongs
|
||||||
|
/// to.
|
||||||
|
enum InterfaceInputOrder { lhs, rhs };
|
||||||
|
|
||||||
|
/// DiffAttrKind is the enum that holds the concrete bases for RTTI.
|
||||||
|
enum DiffAttrKind {
|
||||||
|
AD_Diff_Scalar_PackedVersion,
|
||||||
|
AD_Diff_Scalar_Unsigned,
|
||||||
|
AD_Diff_Scalar_Bool,
|
||||||
|
AD_Diff_Scalar_Str,
|
||||||
|
AD_Str_Vec,
|
||||||
|
AD_Sym_Vec,
|
||||||
|
AD_Inline_Doc,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// AttributeDiff is the abstract class for RTTI.
|
||||||
|
class AttributeDiff {
|
||||||
|
public:
|
||||||
|
AttributeDiff(DiffAttrKind Kind) : Kind(Kind){};
|
||||||
|
virtual ~AttributeDiff(){};
|
||||||
|
DiffAttrKind getKind() const { return Kind; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
DiffAttrKind Kind;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// DiffOutput is the representation of a diff for a single attribute.
|
||||||
|
struct DiffOutput {
|
||||||
|
/// The name of the attribute.
|
||||||
|
std::string Name;
|
||||||
|
/// The kind for RTTI
|
||||||
|
DiffAttrKind Kind;
|
||||||
|
/// Different values for the attribute
|
||||||
|
/// from each file where a diff is present.
|
||||||
|
std::vector<std::unique_ptr<AttributeDiff>> Values;
|
||||||
|
DiffOutput(std::string Name) : Name(Name){};
|
||||||
|
};
|
||||||
|
|
||||||
|
/// DiffScalarVal is a template class for the different types of scalar values.
|
||||||
|
template <class T, DiffAttrKind U> class DiffScalarVal : public AttributeDiff {
|
||||||
|
public:
|
||||||
|
DiffScalarVal(InterfaceInputOrder Order, T Val)
|
||||||
|
: AttributeDiff(U), Order(Order), Val(Val){};
|
||||||
|
|
||||||
|
static bool classof(const AttributeDiff *A) { return A->getKind() == U; }
|
||||||
|
|
||||||
|
void print(raw_ostream &, std::string);
|
||||||
|
|
||||||
|
T getVal() const { return Val; }
|
||||||
|
InterfaceInputOrder getOrder() const { return Order; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// The order is the file from which the diff is found.
|
||||||
|
InterfaceInputOrder Order;
|
||||||
|
T Val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// SymScalar is the diff symbol and the order.
|
||||||
|
class SymScalar {
|
||||||
|
public:
|
||||||
|
SymScalar(InterfaceInputOrder Order, const MachO::Symbol *Sym)
|
||||||
|
: Order(Order), Val(Sym){};
|
||||||
|
|
||||||
|
std::string getFlagString(MachO::SymbolFlags Flags) {
|
||||||
|
return Flags != MachO::SymbolFlags::None
|
||||||
|
? " - " + stringifySymbolFlag(Flags)
|
||||||
|
: stringifySymbolFlag(Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(raw_ostream &OS, std::string Indent, MachO::Target Targ);
|
||||||
|
|
||||||
|
const MachO::Symbol *getVal() const { return Val; }
|
||||||
|
InterfaceInputOrder getOrder() const { return Order; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// The order is the file from which the diff is found.
|
||||||
|
InterfaceInputOrder Order;
|
||||||
|
const MachO::Symbol *Val;
|
||||||
|
std::string stringifySymbolKind(MachO::SymbolKind Kind);
|
||||||
|
std::string stringifySymbolFlag(MachO::SymbolFlags Flag);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DiffStrVec : public AttributeDiff {
|
||||||
|
public:
|
||||||
|
MachO::Target Targ;
|
||||||
|
/// Values is a vector of StringRef values associated with the target.
|
||||||
|
std::vector<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>> TargValues;
|
||||||
|
DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){};
|
||||||
|
|
||||||
|
static bool classof(const AttributeDiff *A) {
|
||||||
|
return A->getKind() == AD_Str_Vec;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DiffSymVec : public AttributeDiff {
|
||||||
|
public:
|
||||||
|
MachO::Target Targ;
|
||||||
|
/// Values is a vector of symbol values associated with the target.
|
||||||
|
std::vector<SymScalar> TargValues;
|
||||||
|
DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){};
|
||||||
|
|
||||||
|
static bool classof(const AttributeDiff *A) {
|
||||||
|
return A->getKind() == AD_Sym_Vec;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// InlineDoc represents an inlined framework/library in a TBD File.
|
||||||
|
class InlineDoc : public AttributeDiff {
|
||||||
|
public:
|
||||||
|
/// Install name of the framework/library.
|
||||||
|
std::string InstallName;
|
||||||
|
/// Differences found from each file.
|
||||||
|
std::vector<DiffOutput> DocValues;
|
||||||
|
InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff)
|
||||||
|
: AttributeDiff(AD_Inline_Doc), InstallName(InstName),
|
||||||
|
DocValues(std::move(Diff)){};
|
||||||
|
|
||||||
|
static bool classof(const AttributeDiff *A) {
|
||||||
|
return A->getKind() == AD_Inline_Doc;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// DiffEngine contains the methods to compare the input files and print the
|
||||||
|
/// output of the differences found in the files.
|
||||||
|
class DiffEngine {
|
||||||
|
public:
|
||||||
|
DiffEngine(object::TapiUniversal *InputFileNameLHS,
|
||||||
|
object::TapiUniversal *InputFileNameRHS)
|
||||||
|
: FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){};
|
||||||
|
bool compareFiles(raw_ostream &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
object::TapiUniversal *FileLHS;
|
||||||
|
object::TapiUniversal *FileRHS;
|
||||||
|
|
||||||
|
/// Function that prints the differences found in the files.
|
||||||
|
void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int);
|
||||||
|
/// Function that does the comparison of the TBD files and returns the
|
||||||
|
/// differences.
|
||||||
|
std::vector<DiffOutput> findDifferences(const MachO::InterfaceFile *,
|
||||||
|
const MachO::InterfaceFile *);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
89
tools/llvm-tapi-diff/llvm-tapi-diff.cpp
Normal file
89
tools/llvm-tapi-diff/llvm-tapi-diff.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
//===-- llvm-tapi-diff.cpp - tbd comparator command-line driver ---*-
|
||||||
|
// C++
|
||||||
|
//-*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file defines the command-line driver for the llvm-tapi difference
|
||||||
|
// engine.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
#include "DiffEngine.h"
|
||||||
|
#include "llvm/Object/TapiUniversal.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include "llvm/Support/InitLLVM.h"
|
||||||
|
#include "llvm/Support/WithColor.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace MachO;
|
||||||
|
using namespace object;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
cl::OptionCategory NMCat("llvm-tapi-diff Options");
|
||||||
|
cl::opt<std::string> InputFileNameLHS(cl::Positional, cl::desc("<first file>"),
|
||||||
|
cl::cat(NMCat));
|
||||||
|
cl::opt<std::string> InputFileNameRHS(cl::Positional, cl::desc("<second file>"),
|
||||||
|
cl::cat(NMCat));
|
||||||
|
|
||||||
|
std::string ToolName;
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
ExitOnError ExitOnErr;
|
||||||
|
|
||||||
|
void setErrorBanner(ExitOnError &ExitOnErr, std::string InputFile) {
|
||||||
|
ExitOnErr.setBanner(ToolName + ": error: " + InputFile + ": ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Expected<std::unique_ptr<Binary>> convertFileToBinary(std::string &Filename) {
|
||||||
|
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
|
||||||
|
MemoryBuffer::getFileOrSTDIN(Filename);
|
||||||
|
if (BufferOrErr.getError())
|
||||||
|
return errorCodeToError(BufferOrErr.getError());
|
||||||
|
return createBinary(BufferOrErr.get()->getMemBufferRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int Argc, char **Argv) {
|
||||||
|
InitLLVM X(Argc, Argv);
|
||||||
|
cl::HideUnrelatedOptions(NMCat);
|
||||||
|
cl::ParseCommandLineOptions(
|
||||||
|
Argc, Argv,
|
||||||
|
"This tool will compare two tbd files and return the "
|
||||||
|
"differences in those files.");
|
||||||
|
if (InputFileNameLHS.empty() || InputFileNameRHS.empty()) {
|
||||||
|
cl::PrintHelpMessage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolName = Argv[0];
|
||||||
|
|
||||||
|
setErrorBanner(ExitOnErr, InputFileNameLHS);
|
||||||
|
auto BinLHS = ExitOnErr(convertFileToBinary(InputFileNameLHS));
|
||||||
|
|
||||||
|
TapiUniversal *FileLHS = dyn_cast<TapiUniversal>(BinLHS.get());
|
||||||
|
if (!FileLHS) {
|
||||||
|
ExitOnErr(
|
||||||
|
createStringError(std::errc::executable_format_error,
|
||||||
|
"Error when parsing file, unsupported file format"));
|
||||||
|
}
|
||||||
|
|
||||||
|
setErrorBanner(ExitOnErr, InputFileNameRHS);
|
||||||
|
auto BinRHS = ExitOnErr(convertFileToBinary(InputFileNameRHS));
|
||||||
|
|
||||||
|
TapiUniversal *FileRHS = dyn_cast<TapiUniversal>(BinRHS.get());
|
||||||
|
if (!FileRHS) {
|
||||||
|
ExitOnErr(
|
||||||
|
createStringError(std::errc::executable_format_error,
|
||||||
|
"Error when parsing file, unsupported file format"));
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_ostream &OS = outs();
|
||||||
|
|
||||||
|
return DiffEngine(FileLHS, FileRHS).compareFiles(OS);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user