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