1//===--- SemaAPINotesInternal.h - API Notes Sema Internals ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_LIB_SEMA_SEMAAPINOTESINTERNAL_H
10#define LLVM_CLANG_LIB_SEMA_SEMAAPINOTESINTERNAL_H
11
12#include "clang/APINotes/Types.h"
13#include "clang/Basic/SourceLocation.h"
14#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/DenseMap.h"
16#include "llvm/ADT/STLFunctionalExtras.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/StringRef.h"
19#include <string>
20#include <utility>
21
22namespace clang {
23class Sema;
24struct APINotesParameterSelectorCandidates;
25namespace api_notes {
26class APINotesReader;
27} // namespace api_notes
28
29/// Source name and location for a declaration seen by Sema.
30struct APINotesSelectorDiagnosticName {
31 SourceLocation Loc;
32 std::string Name;
33};
34
35/// Tracks exact Where.Parameters selectors from one API notes reader.
36///
37/// Sema marks selectors as used when a visible declaration matches them. It
38/// also records broad/name-only declarations seen in the translation unit, so
39/// end-of-TU diagnostics can warn about exact selectors for known names that
40/// were never matched.
41struct APINotesSelectorDiagnosticReaderState {
42 /// Exact Where.Parameters selector keys stored by API notes. The bool is
43 /// true once Sema sees a declaration matching the exact selector.
44 llvm::DenseMap<api_notes::APINotesFunctionSelectorKey, bool> SelectorUsed;
45
46 /// Maps broad/name-only keys to a declaration location/name used for
47 /// diagnostics.
48 llvm::DenseMap<api_notes::APINotesFunctionSelectorKey,
49 APINotesSelectorDiagnosticName>
50 SeenNames;
51
52 void addSelector(const api_notes::APINotesFunctionSelectorKey &Key) {
53 SelectorUsed.try_emplace(Key, Args: false);
54 }
55
56 void addSelectors(
57 llvm::ArrayRef<api_notes::APINotesFunctionSelectorKey> Selectors) {
58 SelectorUsed.reserve(NumEntries: Selectors.size());
59 SeenNames.reserve(NumEntries: Selectors.size());
60 for (const auto &Selector : Selectors)
61 addSelector(Key: Selector);
62 }
63
64 void noteSeenDeclaration(const api_notes::APINotesFunctionSelectorKey &Key,
65 llvm::StringRef Name, SourceLocation Loc) {
66 SeenNames.insert(KV: {Key.getWithoutParameterSelector(), {.Loc: Loc, .Name: Name.str()}});
67 }
68
69 void markUsed(const api_notes::APINotesFunctionSelectorKey &Key) {
70 auto KnownSelector = SelectorUsed.find(Val: Key);
71 if (KnownSelector != SelectorUsed.end())
72 KnownSelector->second = true;
73 }
74
75 void markCandidatesUsed(
76 llvm::function_ref<std::optional<api_notes::APINotesFunctionSelectorKey>(
77 llvm::ArrayRef<std::string>)>
78 GetSelectorKey,
79 const APINotesParameterSelectorCandidates &Candidates);
80
81 void diagnoseUnused(Sema &S, api_notes::APINotesReader &Reader) const;
82};
83
84/// Selector diagnostic state for all API notes readers used by one Sema.
85struct APINotesSelectorDiagnosticState {
86 llvm::DenseMap<api_notes::APINotesReader *,
87 APINotesSelectorDiagnosticReaderState>
88 Readers;
89
90 APINotesSelectorDiagnosticReaderState &
91 getOrCreateReaderState(api_notes::APINotesReader &Reader);
92
93 void diagnoseUnused(Sema &S) const;
94};
95
96} // namespace clang
97
98#endif // LLVM_CLANG_LIB_SEMA_SEMAAPINOTESINTERNAL_H
99