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 
24 namespace clang {
25 class Decl;
26 class SourceMgr;
27 class Preprocessor;
28 
29 namespace comments {
30 class CommandTraits;
31 
32 class 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 
71 public:
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