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 private: 185 void checkBlockCommandEmptyParagraph(BlockCommandComment *Command); 186 187 void checkReturnsCommand(const BlockCommandComment *Command); 188 189 /// Emit diagnostics about duplicate block commands that should be 190 /// used only once per comment, e.g., \and \\returns. 191 void checkBlockCommandDuplicate(const BlockCommandComment *Command); 192 193 void checkDeprecatedCommand(const BlockCommandComment *Comment); 194 195 void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment); 196 197 void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment); 198 199 void checkContainerDecl(const BlockCommandComment *Comment); 200 201 /// Resolve parameter names to parameter indexes in function declaration. 202 /// Emit diagnostics about unknown parametrs. 203 void resolveParamCommandIndexes(const FullComment *FC); 204 205 /// \returns \c true if the declaration that this comment is attached to 206 /// is a pointer to function/method/block type or has such a type. 207 bool involvesFunctionType(); 208 209 bool isFunctionDecl(); 210 bool isAnyFunctionDecl(); 211 212 /// \returns \c true if declaration that this comment is attached to declares 213 /// a function pointer. 214 bool isFunctionPointerVarDecl(); 215 bool isFunctionOrMethodVariadic(); 216 bool isObjCMethodDecl(); 217 bool isObjCPropertyDecl(); 218 bool isTemplateOrSpecialization(); 219 bool isRecordLikeDecl(); 220 bool isClassOrStructDecl(); 221 /// \return \c true if the declaration that this comment is attached to 222 /// declares either struct, class or tag typedef. 223 bool isClassOrStructOrTagTypedefDecl(); 224 bool isUnionDecl(); 225 bool isObjCInterfaceDecl(); 226 bool isObjCProtocolDecl(); 227 bool isClassTemplateDecl(); 228 bool isFunctionTemplateDecl(); 229 230 ArrayRef<const ParmVarDecl *> getParamVars(); 231 232 /// Extract all important semantic information from 233 /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members. 234 void inspectThisDecl(); 235 236 /// Returns index of a function parameter with a given name. 237 unsigned resolveParmVarReference(StringRef Name, 238 ArrayRef<const ParmVarDecl *> ParamVars); 239 240 /// Returns index of a function parameter with the name closest to a given 241 /// typo. 242 unsigned correctTypoInParmVarReference(StringRef Typo, 243 ArrayRef<const ParmVarDecl *> ParamVars); 244 245 bool resolveTParamReference(StringRef Name, 246 const TemplateParameterList *TemplateParameters, 247 SmallVectorImpl<unsigned> *Position); 248 249 StringRef correctTypoInTParamReference( 250 StringRef Typo, 251 const TemplateParameterList *TemplateParameters); 252 253 InlineCommandComment::RenderKind 254 getInlineCommandRenderKind(StringRef Name) const; 255 }; 256 257 } // end namespace comments 258 } // end namespace clang 259 260 #endif 261 262