Skip to content

Commit a975bff

Browse files
committed
[InstallAPI] Introduce Basic Verifier
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 actually check against the dylib's symbol table.
1 parent a71d8d3 commit a975bff

File tree

14 files changed

+525
-97
lines changed

14 files changed

+525
-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
@@ -18,6 +18,7 @@
1818
namespace clang {
1919
namespace installapi {
2020
class FrontendRecordsSlice;
21+
class DylibVerifier;
2122

2223
/// Struct used for generating validating InstallAPI.
2324
/// The attributes captured represent all necessary information
@@ -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: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "clang/AST/Availability.h"
1313
#include "clang/AST/DeclObjC.h"
14+
#include "clang/InstallAPI/HeaderFile.h"
1415
#include "clang/InstallAPI/MachO.h"
1516

1617
namespace clang {
@@ -42,13 +43,13 @@ class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
4243
/// \param Flags The flags that describe attributes of the symbol.
4344
/// \param Inlined Whether declaration is inlined, only applicable to
4445
/// functions.
45-
/// \return The non-owning pointer to added record in slice.
46-
GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage,
47-
GlobalRecord::Kind GV,
48-
const clang::AvailabilityInfo Avail, const Decl *D,
49-
const HeaderType Access,
50-
SymbolFlags Flags = SymbolFlags::None,
51-
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);
5253

5354
/// Add ObjC Class record with attributes from AST.
5455
///
@@ -59,11 +60,12 @@ class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
5960
/// \param D The pointer to the declaration from traversing AST.
6061
/// \param Access The intended access level of symbol.
6162
/// \param IsEHType Whether declaration has an exception attribute.
62-
/// \return The non-owning pointer to added record in slice.
63-
ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage,
64-
const clang::AvailabilityInfo Avail,
65-
const Decl *D, HeaderType Access,
66-
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);
6769

6870
/// Add ObjC Category record with attributes from AST.
6971
///
@@ -74,11 +76,12 @@ class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
7476
/// to the active target triple.
7577
/// \param D The pointer to the declaration from traversing AST.
7678
/// \param Access The intended access level of symbol.
77-
/// \return The non-owning pointer to added record in slice.
78-
ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend,
79-
StringRef CategoryName,
80-
const clang::AvailabilityInfo Avail,
81-
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);
8285

8386
/// Add ObjC IVar record with attributes from AST.
8487
///
@@ -90,12 +93,13 @@ class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
9093
/// \param D The pointer to the declaration from traversing AST.
9194
/// \param Access The intended access level of symbol.
9295
/// \param AC The access control tied to the ivar declaration.
93-
/// \return The non-owning pointer to added record in slice.
94-
ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container,
95-
StringRef IvarName, RecordLinkage Linkage,
96-
const clang::AvailabilityInfo Avail,
97-
const Decl *D, HeaderType Access,
98-
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);
99103

100104
private:
101105
/// 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)