1//===--- CommentSema.h - Doxygen comment semantic analysis ------*- 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// This file defines the semantic analysis class for Doxygen comments.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_COMMENTSEMA_H
14#define LLVM_CLANG_AST_COMMENTSEMA_H
15
16#include "clang/AST/Comment.h"
17#include "clang/Basic/Diagnostic.h"
18#include "clang/Basic/SourceLocation.h"
19#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/StringMap.h"
21#include "llvm/ADT/StringRef.h"
22#include "llvm/Support/Allocator.h"
23
24namespace clang {
25class Decl;
26class SourceMgr;
27class Preprocessor;
28
29namespace comments {
30class CommandTraits;
31
32class Sema {
33 Sema(const Sema &) = delete;
34 void operator=(const Sema &) = delete;
35
36 /// Allocator for AST nodes.
37 llvm::BumpPtrAllocator &Allocator;
38
39 /// Source manager for the comment being parsed.
40 const SourceManager &SourceMgr;
41
42 DiagnosticsEngine &Diags;
43
44 CommandTraits &Traits;
45
46 const Preprocessor *PP;
47
48 /// Information about the declaration this comment is attached to.
49 DeclInfo *ThisDeclInfo;
50
51 /// Comment AST nodes that correspond to parameter names in
52 /// \c TemplateParameters.
53 ///
54 /// Contains a valid value if \c DeclInfo->IsFilled is true.
55 llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
56
57 /// AST node for the \command and its aliases.
58 const BlockCommandComment *BriefCommand;
59
60 /// AST node for the \\headerfile command.
61 const BlockCommandComment *HeaderfileCommand;
62
63 DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
64 return Diags.Report(Loc, DiagID);
65 }
66
67 /// A stack of HTML tags that are currently open (not matched with closing
68 /// tags).
69 SmallVector<HTMLStartTagComment *, 8> HTMLOpenTags;
70
71public:
72 Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
73 DiagnosticsEngine &Diags, CommandTraits &Traits,
74 const Preprocessor *PP);
75
76 void setDecl(const Decl *D);
77
78 /// Returns a copy of array, owned by Sema's allocator.
79 template<typename T>
80 ArrayRef<T> copyArray(ArrayRef<T> Source) {
81 if (!Source.empty())
82 return Source.copy(Allocator);
83 return {};
84 }
85
86 ParagraphComment *actOnParagraphComment(
87 ArrayRef<InlineContentComment *> Content);
88
89 BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
90 SourceLocation LocEnd,
91 unsigned CommandID,
92 CommandMarkerKind CommandMarker);
93
94 void actOnBlockCommandArgs(BlockCommandComment *Command,
95 ArrayRef<BlockCommandComment::Argument> Args);
96
97 void actOnBlockCommandFinish(BlockCommandComment *Command,
98 ParagraphComment *Paragraph);
99
100 ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
101 SourceLocation LocEnd,
102 unsigned CommandID,
103 CommandMarkerKind CommandMarker);
104
105 void actOnParamCommandDirectionArg(ParamCommandComment *Command,
106 SourceLocation ArgLocBegin,
107 SourceLocation ArgLocEnd,
108 StringRef Arg);
109
110 void actOnParamCommandParamNameArg(ParamCommandComment *Command,
111 SourceLocation ArgLocBegin,
112 SourceLocation ArgLocEnd,
113 StringRef Arg);
114
115 void actOnParamCommandFinish(ParamCommandComment *Command,
116 ParagraphComment *Paragraph);
117
118 TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
119 SourceLocation LocEnd,
120 unsigned CommandID,
121 CommandMarkerKind CommandMarker);
122
123 void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
124 SourceLocation ArgLocBegin,
125 SourceLocation ArgLocEnd,
126 StringRef Arg);
127
128 void actOnTParamCommandFinish(TParamCommandComment *Command,
129 ParagraphComment *Paragraph);
130
131 InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
132 SourceLocation CommandLocEnd,
133 unsigned CommandID,
134 CommandMarkerKind CommandMarker,
135 ArrayRef<Comment::Argument> Args);
136
137 InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
138 SourceLocation LocEnd,
139 StringRef CommandName,
140 CommandMarkerKind CommandMarker);
141
142 InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
143 SourceLocation LocEnd,
144 unsigned CommandID,
145 CommandMarkerKind CommandMarker);
146
147 TextComment *actOnText(SourceLocation LocBegin,
148 SourceLocation LocEnd,
149 StringRef Text);
150
151 VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
152 unsigned CommandID);
153
154 VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
155 StringRef Text);
156
157 void actOnVerbatimBlockFinish(VerbatimBlockComment *Block,
158 SourceLocation CloseNameLocBegin,
159 StringRef CloseName,
160 ArrayRef<VerbatimBlockLineComment *> Lines);
161
162 VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
163 unsigned CommandID,
164 SourceLocation TextBegin,
165 StringRef Text);
166
167 HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin,
168 StringRef TagName);
169
170 void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag,
171 ArrayRef<HTMLStartTagComment::Attribute> Attrs,
172 SourceLocation GreaterLoc,
173 bool IsSelfClosing);
174
175 HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin,
176 SourceLocation LocEnd,
177 StringRef TagName);
178
179 FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
180
181private:
182 void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
183
184 void checkReturnsCommand(const BlockCommandComment *Command);
185
186 /// Emit diagnostics about duplicate block commands that should be
187 /// used only once per comment, e.g., \and \\returns.
188 void checkBlockCommandDuplicate(const BlockCommandComment *Command);
189
190 void checkDeprecatedCommand(const BlockCommandComment *Comment);
191
192 void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment);
193
194 void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment);
195
196 void checkContainerDecl(const BlockCommandComment *Comment);
197
198 /// Resolve parameter names to parameter indexes in function declaration.
199 /// Emit diagnostics about unknown parameters.
200 void resolveParamCommandIndexes(const FullComment *FC);
201
202 /// \returns \c true if the declaration that this comment is attached to
203 /// is a pointer to function/method/block type or has such a type.
204 bool involvesFunctionType();
205
206 bool isFunctionDecl();
207 bool isAnyFunctionDecl();
208
209 /// \returns \c true if declaration that this comment is attached to declares
210 /// a function pointer.
211 bool isFunctionPointerVarDecl();
212 bool isFunctionOrMethodVariadic();
213 bool isObjCMethodDecl();
214 bool isObjCPropertyDecl();
215 bool isTemplateOrSpecialization();
216 bool isExplicitFunctionTemplateInstantiation();
217 bool isRecordLikeDecl();
218 bool isClassOrStructDecl();
219 /// \return \c true if the declaration that this comment is attached to
220 /// declares either struct, class or tag typedef.
221 bool isClassOrStructOrTagTypedefDecl();
222 bool isUnionDecl();
223 bool isObjCInterfaceDecl();
224 bool isObjCProtocolDecl();
225 bool isClassTemplateDecl();
226 bool isFunctionTemplateDecl();
227
228 ArrayRef<const ParmVarDecl *> getParamVars();
229
230 /// Extract all important semantic information from
231 /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
232 void inspectThisDecl();
233
234 /// Returns index of a function parameter with a given name.
235 unsigned resolveParmVarReference(StringRef Name,
236 ArrayRef<const ParmVarDecl *> ParamVars);
237
238 /// Returns index of a function parameter with the name closest to a given
239 /// typo.
240 unsigned correctTypoInParmVarReference(StringRef Typo,
241 ArrayRef<const ParmVarDecl *> ParamVars);
242
243 bool resolveTParamReference(StringRef Name,
244 const TemplateParameterList *TemplateParameters,
245 SmallVectorImpl<unsigned> *Position);
246
247 StringRef correctTypoInTParamReference(
248 StringRef Typo,
249 const TemplateParameterList *TemplateParameters);
250
251 InlineCommandRenderKind getInlineCommandRenderKind(StringRef Name) const;
252};
253
254} // end namespace comments
255} // end namespace clang
256
257#endif
258
259