Skip to content

Commit f2794cc

Browse files
authored
[InstallAPI] Introduce Basic Verifier (#85106)
This adds basic support for calling the verifier on global declarations that are expected to represent symbol exports. The driver now exclusively uses this for knowing what symbols make up a TBD file. Future patches will check against the dylib's symbol table.
1 parent c51095f commit f2794cc

File tree

14 files changed

+524
-97
lines changed

14 files changed

+524
-97
lines changed

clang/include/clang/AST/Availability.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ struct AvailabilityInfo {
7575
/// Determine if this AvailabilityInfo represents the default availability.
7676
bool isDefault() const { return *this == AvailabilityInfo(); }
7777

78+
/// Check if the symbol has been obsoleted.
79+
bool isObsoleted() const { return !Obsoleted.empty(); }
80+
7881
/// Check if the symbol is unconditionally deprecated.
7982
///
8083
/// i.e. \code __attribute__((deprecated)) \endcode

clang/include/clang/InstallAPI/Context.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "clang/Basic/Diagnostic.h"
1313
#include "clang/Basic/FileManager.h"
14+
#include "clang/InstallAPI/DylibVerifier.h"
1415
#include "clang/InstallAPI/HeaderFile.h"
1516
#include "clang/InstallAPI/MachO.h"
1617
#include "llvm/ADT/DenseMap.h"
@@ -45,6 +46,9 @@ struct InstallAPIContext {
4546
/// DiagnosticsEngine for all error reporting.
4647
DiagnosticsEngine *Diags = nullptr;
4748

49+
/// Verifier when binary dylib is passed as input.
50+
std::unique_ptr<DylibVerifier> Verifier = nullptr;
51+
4852
/// File Path of output location.
4953
llvm::StringRef OutputLoc{};
5054

clang/include/clang/InstallAPI/DylibVerifier.h

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
#ifndef LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H
1010
#define LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H
1111

12-
#include "llvm/TextAPI/Target.h"
12+
#include "clang/Basic/Diagnostic.h"
13+
#include "clang/InstallAPI/MachO.h"
1314

1415
namespace clang {
1516
namespace installapi {
17+
struct FrontendAttrs;
1618

1719
/// A list of InstallAPI verification modes.
1820
enum class VerificationMode {
@@ -22,6 +24,81 @@ enum class VerificationMode {
2224
Pedantic,
2325
};
2426

27+
/// Service responsible to tracking state of verification across the
28+
/// lifetime of InstallAPI.
29+
/// As declarations are collected during AST traversal, they are
30+
/// compared as symbols against what is available in the binary dylib.
31+
class DylibVerifier {
32+
private:
33+
struct SymbolContext;
34+
35+
public:
36+
enum class Result { NoVerify, Ignore, Valid, Invalid };
37+
struct VerifierContext {
38+
// Current target being verified against the AST.
39+
llvm::MachO::Target Target;
40+
41+
// Query state of verification after AST has been traversed.
42+
Result FrontendState;
43+
44+
// First error for AST traversal, which is tied to the target triple.
45+
bool DiscoveredFirstError;
46+
};
47+
48+
DylibVerifier() = default;
49+
50+
DylibVerifier(llvm::MachO::Records &&Dylib, DiagnosticsEngine *Diag,
51+
VerificationMode Mode, bool Demangle)
52+
: Dylib(std::move(Dylib)), Diag(Diag), Mode(Mode), Demangle(Demangle),
53+
Exports(std::make_unique<SymbolSet>()) {}
54+
55+
Result verify(GlobalRecord *R, const FrontendAttrs *FA);
56+
Result verify(ObjCInterfaceRecord *R, const FrontendAttrs *FA);
57+
Result verify(ObjCIVarRecord *R, const FrontendAttrs *FA,
58+
const StringRef SuperClass);
59+
60+
/// Initialize target for verification.
61+
void setTarget(const Target &T);
62+
63+
/// Release ownership over exports.
64+
std::unique_ptr<SymbolSet> getExports() { return std::move(Exports); }
65+
66+
/// Get result of verification.
67+
Result getState() const { return Ctx.FrontendState; }
68+
69+
private:
70+
/// Determine whether to compare declaration to symbol in binary.
71+
bool canVerify();
72+
73+
/// Shared implementation for verifying exported symbols.
74+
Result verifyImpl(Record *R, SymbolContext &SymCtx);
75+
76+
/// Update result state on each call to `verify`.
77+
void updateState(Result State);
78+
79+
/// Add verified exported symbol.
80+
void addSymbol(const Record *R, SymbolContext &SymCtx,
81+
TargetList &&Targets = {});
82+
83+
// Symbols in dylib.
84+
llvm::MachO::Records Dylib;
85+
86+
// Engine for reporting violations.
87+
[[maybe_unused]] DiagnosticsEngine *Diag = nullptr;
88+
89+
// Controls what class of violations to report.
90+
[[maybe_unused]] VerificationMode Mode = VerificationMode::Invalid;
91+
92+
// Attempt to demangle when reporting violations.
93+
bool Demangle = false;
94+
95+
// Valid symbols in final text file.
96+
std::unique_ptr<SymbolSet> Exports = std::make_unique<SymbolSet>();
97+
98+
// Track current state of verification while traversing AST.
99+
VerifierContext Ctx;
100+
};
101+
25102
} // namespace installapi
26103
} // namespace clang
27104
#endif // LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H

clang/include/clang/InstallAPI/Frontend.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#define LLVM_CLANG_INSTALLAPI_FRONTEND_H
1515

1616
#include "clang/AST/ASTConsumer.h"
17-
#include "clang/AST/Availability.h"
1817
#include "clang/Frontend/CompilerInstance.h"
1918
#include "clang/Frontend/FrontendActions.h"
2019
#include "clang/InstallAPI/Context.h"

clang/include/clang/InstallAPI/FrontendRecords.h

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
4343
/// \param Flags The flags that describe attributes of the symbol.
4444
/// \param Inlined Whether declaration is inlined, only applicable to
4545
/// functions.
46-
/// \return The non-owning pointer to added record in slice.
47-
GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage,
48-
GlobalRecord::Kind GV,
49-
const clang::AvailabilityInfo Avail, const Decl *D,
50-
const HeaderType Access,
51-
SymbolFlags Flags = SymbolFlags::None,
52-
bool Inlined = false);
46+
/// \return The non-owning pointer to added record in slice with it's frontend
47+
/// attributes.
48+
std::pair<GlobalRecord *, FrontendAttrs *>
49+
addGlobal(StringRef Name, RecordLinkage Linkage, GlobalRecord::Kind GV,
50+
const clang::AvailabilityInfo Avail, const Decl *D,
51+
const HeaderType Access, SymbolFlags Flags = SymbolFlags::None,
52+
bool Inlined = false);
5353

5454
/// Add ObjC Class record with attributes from AST.
5555
///
@@ -60,11 +60,12 @@ class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
6060
/// \param D The pointer to the declaration from traversing AST.
6161
/// \param Access The intended access level of symbol.
6262
/// \param IsEHType Whether declaration has an exception attribute.
63-
/// \return The non-owning pointer to added record in slice.
64-
ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage,
65-
const clang::AvailabilityInfo Avail,
66-
const Decl *D, HeaderType Access,
67-
bool IsEHType);
63+
/// \return The non-owning pointer to added record in slice with it's frontend
64+
/// attributes.
65+
std::pair<ObjCInterfaceRecord *, FrontendAttrs *>
66+
addObjCInterface(StringRef Name, RecordLinkage Linkage,
67+
const clang::AvailabilityInfo Avail, const Decl *D,
68+
HeaderType Access, bool IsEHType);
6869

6970
/// Add ObjC Category record with attributes from AST.
7071
///
@@ -75,11 +76,12 @@ class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
7576
/// to the active target triple.
7677
/// \param D The pointer to the declaration from traversing AST.
7778
/// \param Access The intended access level of symbol.
78-
/// \return The non-owning pointer to added record in slice.
79-
ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend,
80-
StringRef CategoryName,
81-
const clang::AvailabilityInfo Avail,
82-
const Decl *D, HeaderType Access);
79+
/// \return The non-owning pointer to added record in slice with it's frontend
80+
/// attributes.
81+
std::pair<ObjCCategoryRecord *, FrontendAttrs *>
82+
addObjCCategory(StringRef ClassToExtend, StringRef CategoryName,
83+
const clang::AvailabilityInfo Avail, const Decl *D,
84+
HeaderType Access);
8385

8486
/// Add ObjC IVar record with attributes from AST.
8587
///
@@ -91,12 +93,13 @@ class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
9193
/// \param D The pointer to the declaration from traversing AST.
9294
/// \param Access The intended access level of symbol.
9395
/// \param AC The access control tied to the ivar declaration.
94-
/// \return The non-owning pointer to added record in slice.
95-
ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container,
96-
StringRef IvarName, RecordLinkage Linkage,
97-
const clang::AvailabilityInfo Avail,
98-
const Decl *D, HeaderType Access,
99-
const clang::ObjCIvarDecl::AccessControl AC);
96+
/// \return The non-owning pointer to added record in slice with it's frontend
97+
/// attributes.
98+
std::pair<ObjCIVarRecord *, FrontendAttrs *>
99+
addObjCIVar(ObjCContainerRecord *Container, StringRef IvarName,
100+
RecordLinkage Linkage, const clang::AvailabilityInfo Avail,
101+
const Decl *D, HeaderType Access,
102+
const clang::ObjCIvarDecl::AccessControl AC);
100103

101104
private:
102105
/// Mapping of records stored in slice to their frontend attributes.

clang/include/clang/InstallAPI/MachO.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/TextAPI/PackedVersion.h"
1919
#include "llvm/TextAPI/Platform.h"
2020
#include "llvm/TextAPI/RecordVisitor.h"
21+
#include "llvm/TextAPI/Symbol.h"
2122
#include "llvm/TextAPI/Target.h"
2223
#include "llvm/TextAPI/TextAPIWriter.h"
2324
#include "llvm/TextAPI/Utils.h"
@@ -33,8 +34,10 @@ using ObjCIVarRecord = llvm::MachO::ObjCIVarRecord;
3334
using Records = llvm::MachO::Records;
3435
using BinaryAttrs = llvm::MachO::RecordsSlice::BinaryAttrs;
3536
using SymbolSet = llvm::MachO::SymbolSet;
37+
using SimpleSymbol = llvm::MachO::SimpleSymbol;
3638
using FileType = llvm::MachO::FileType;
3739
using PackedVersion = llvm::MachO::PackedVersion;
3840
using Target = llvm::MachO::Target;
41+
using TargetList = llvm::MachO::TargetList;
3942

4043
#endif // LLVM_CLANG_INSTALLAPI_MACHO_H

clang/lib/InstallAPI/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
set(LLVM_LINK_COMPONENTS
22
Support
33
TextAPI
4+
Demangle
45
Core
56
)
67

78
add_clang_library(clangInstallAPI
9+
DylibVerifier.cpp
810
FileList.cpp
911
Frontend.cpp
1012
HeaderFile.cpp

0 commit comments

Comments
 (0)