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 None;
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
135  InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
136                                           SourceLocation CommandLocEnd,
137                                           unsigned CommandID,
138                                           SourceLocation ArgLocBegin,
139                                           SourceLocation ArgLocEnd,
140                                           StringRef Arg);
141
142  InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
143                                            SourceLocation LocEnd,
144                                            StringRef CommandName);
145
146  InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
147                                            SourceLocation LocEnd,
148                                            unsigned CommandID);
149
150  TextComment *actOnText(SourceLocation LocBegin,
151                         SourceLocation LocEnd,
152                         StringRef Text);
153
154  VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
155                                                unsigned CommandID);
156
157  VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
158                                                   StringRef Text);
159
160  void actOnVerbatimBlockFinish(VerbatimBlockComment *Block,
161                                SourceLocation CloseNameLocBegin,
162                                StringRef CloseName,
163                                ArrayRef<VerbatimBlockLineComment *> Lines);
164
165  VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
166                                         unsigned CommandID,
167                                         SourceLocation TextBegin,
168                                         StringRef Text);
169
170  HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin,
171                                              StringRef TagName);
172
173  void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag,
174                               ArrayRef<HTMLStartTagComment::Attribute> Attrs,
175                               SourceLocation GreaterLoc,
176                               bool IsSelfClosing);
177
178  HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin,
179                                     SourceLocation LocEnd,
180                                     StringRef TagName);
181
182  FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
183
184  void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
185
186  void checkReturnsCommand(const BlockCommandComment *Command);
187
188  /// Emit diagnostics about duplicate block commands that should be
189  /// used only once per comment, e.g., \and \\returns.
190  void checkBlockCommandDuplicate(const BlockCommandComment *Command);
191
192  void checkDeprecatedCommand(const BlockCommandComment *Comment);
193
194  void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment);
195
196  void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment);
197
198  void checkContainerDecl(const BlockCommandComment *Comment);
199
200  /// Resolve parameter names to parameter indexes in function declaration.
201  /// Emit diagnostics about unknown parametrs.
202  void resolveParamCommandIndexes(const FullComment *FC);
203
204  bool isFunctionDecl();
205  bool isAnyFunctionDecl();
206
207  /// \returns \c true if declaration that this comment is attached to declares
208  /// a function pointer.
209  bool isFunctionPointerVarDecl();
210  /// \returns \c true if the declaration that this comment is attached to
211  /// declares a variable or a field whose type is a function or a block
212  /// pointer.
213  bool isFunctionOrBlockPointerVarLikeDecl();
214  bool isFunctionOrMethodVariadic();
215  bool isObjCMethodDecl();
216  bool isObjCPropertyDecl();
217  bool isTemplateOrSpecialization();
218  bool isRecordLikeDecl();
219  bool isClassOrStructDecl();
220  bool isUnionDecl();
221  bool isObjCInterfaceDecl();
222  bool isObjCProtocolDecl();
223  bool isClassTemplateDecl();
224  bool isFunctionTemplateDecl();
225
226  ArrayRef<const ParmVarDecl *> getParamVars();
227
228  /// Extract all important semantic information from
229  /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
230  void inspectThisDecl();
231
232  /// Returns index of a function parameter with a given name.
233  unsigned resolveParmVarReference(StringRef Name,
234                                   ArrayRef<const ParmVarDecl *> ParamVars);
235
236  /// Returns index of a function parameter with the name closest to a given
237  /// typo.
238  unsigned correctTypoInParmVarReference(StringRef Typo,
239                                         ArrayRef<const ParmVarDecl *> ParamVars);
240
241  bool resolveTParamReference(StringRef Name,
242                              const TemplateParameterList *TemplateParameters,
243                              SmallVectorImpl<unsigned> *Position);
244
245  StringRef correctTypoInTParamReference(
246                              StringRef Typo,
247                              const TemplateParameterList *TemplateParameters);
248
249  InlineCommandComment::RenderKind
250  getInlineCommandRenderKind(StringRef Name) const;
251};
252
253} // end namespace comments
254} // end namespace clang
255
256#endif
257
258